Skip to content

Commit

Permalink
Added a couple of tests
Browse files Browse the repository at this point in the history
  • Loading branch information
tpanum committed Jul 15, 2021
1 parent b648db2 commit 58a3b50
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 51 deletions.
4 changes: 2 additions & 2 deletions api.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ func NewServer(db *gorm.DB) *server {
}

type server struct {
dc *DawaCacher
bc *BoligaCacher
dc DawaCacher
bc BoligaCacher
}

func (s *server) handleLookup() http.HandlerFunc {
Expand Down
81 changes: 47 additions & 34 deletions boliga.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,17 @@ type BoligaCacherResp struct {
err error
}

type BoligaCacher struct {
type BoligaCacher interface {
io.Closer
FetchSales([]*Address) ([][]Sale, error)
}

type boligaCacher struct {
db *gorm.DB
in chan BoligaCacherTask
}

func NewBoligaCacher(db *gorm.DB, n int) *BoligaCacher {
func NewBoligaCacher(db *gorm.DB, n int) *boligaCacher {
in := make(chan BoligaCacherTask)

for i := 0; i < n; i++ {
Expand All @@ -69,16 +74,17 @@ func NewBoligaCacher(db *gorm.DB, n int) *BoligaCacher {

db.AutoMigrate(&Sale{})

return &BoligaCacher{db, in}
return &boligaCacher{db, in}
}

func (bc *BoligaCacher) Close() {
func (bc *boligaCacher) Close() error {
close(bc.in)
return nil
}

const oneMonth time.Duration = time.Hour * 24 * 31

func (bc *BoligaCacher) FetchSales(addrs []*Address) ([][]Sale, error) {
func (bc *boligaCacher) FetchSales(addrs []*Address) ([][]Sale, error) {
cachedAddrs := map[int]*Address{}
fetchAddrs := map[int]*Address{}
var salesExpired []uint
Expand Down Expand Up @@ -366,7 +372,7 @@ func (r BoligaPropertyRequest) Fetch() ([]BoligaSaleItem, error) {
req.URL.RawQuery = q.Encode()

var sr BoligaSalesResponse
resp, err := http.DefaultClient.Do(req)
resp, err := DefaultClient.Do(req)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -394,7 +400,7 @@ func PropertyFromBoligaItem(si BoligaSaleItem) (*BoligaProperty, error) {
si.EstateCode,
si.Guid,
)
resp, err := http.Get(query)
resp, err := DefaultClient.Get(query)
if err != nil {
return nil, err
}
Expand All @@ -414,7 +420,7 @@ func PropertyFromBoligaItem(si BoligaSaleItem) (*BoligaProperty, error) {
path, ok := doc.Find(".sales-overview-table.h-100 .table-row").Find("a").Attr("href")
if ok {
query = "https://www.boliga.dk" + path
resp, err = http.Get(query)
resp, err = DefaultClient.Get(query)
if err != nil {
return nil, err
}
Expand All @@ -434,7 +440,7 @@ func PropertyFromBoligaItem(si BoligaSaleItem) (*BoligaProperty, error) {
amount, _ := DirtyStringToInt(cols.Eq(1).Find("span").Eq(1).Text())
timestr := cols.Eq(2).Find("span").Eq(1).Text()

saleDate := DanishDateToTime(timestr, "2 1 2006")
saleDate, _ := DanishDateToTime("2. jan. 2006", timestr)
uniqueSales[Sale{
AmountDKK: amount,
Date: saleDate,
Expand Down Expand Up @@ -522,44 +528,51 @@ func DirtyStringToInt(s string) (int, error) {
s = strings.Replace(s, ".", "", -1)
matches := numbersOnlyRegexp.FindAllString(s, 1)
if len(matches) == 0 {
return 0, fmt.Errorf("unable to locate number")
return 0, &strconv.NumError{
Func: "DirtyStringToInt",
Num: s,
Err: strconv.ErrSyntax,
}
}

return strconv.Atoi(matches[0])
}

var (
daToEn = map[string]int{
"jan": 1,
"feb": 2,
"mar": 3,
"apr": 4,
"maj": 5,
"jun": 6,
"jul": 7,
"aug": 8,
"sep": 9,
"okt": 10,
"nov": 11,
"dec": 12,
daToEn = map[string]string{
"feb": "Feb",
"mar": "Mar",
"apr": "Apr",
"maj": "May",
"jun": "Jun",
"jul": "Jul",
"aug": "Aug",
"sep": "Sep",
"okt": "Oct",
"nov": "Nov",
"dec": "Dec",
}
)

func DanishDateToTime(s string, format string) time.Time {
s = strings.TrimSpace(s)
s = strings.ToLower(s)

for from, to := range daToEn {
s = strings.Replace(s, from, strconv.Itoa(to), -1)
func DanishDateToTime(format string, s string) (time.Time, error) {
clean := func(s string) string {
s = strings.TrimSpace(s)
s = strings.Replace(s, ".", "", -1)
s = strings.Replace(s, "jan", "Jan", -1)
return s
}
s = strings.Replace(s, ".", "", -1)

t, err := time.Parse(format, s)
if err != nil {
fmt.Println("Date Parsing Problem:", err)
s = clean(s)
format = clean(format)

for from, to := range daToEn {
if strings.Contains(s, from) {
s = strings.Replace(s, from, to, -1)
break
}
}

return t
return time.Parse(format, s)
}

func FilterAddressesByProperty(pt PropertyType, addrs []*Address, sales [][]Sale) ([]*Address, [][]Sale) {
Expand Down
80 changes: 80 additions & 0 deletions boliga_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package hjem

import (
"strings"
"testing"
"time"
)

func TestDirtyStringToInt(t *testing.T) {
tt := []struct {
name string
in string
out int
err string
}{
{name: "with dot", in: "10.000", out: 10000},
{name: "multiple dots", in: "88.299.199", out: 88299199},
{name: "additional spaces", in: " 999 ", out: 999},
{name: "with unit", in: "64kr", out: 64},
{name: "zero", in: "0", out: 0},
{name: "letters only", in: "absc", err: "invalid syntax"},
}

for _, tc := range tt {
t.Run(tc.name, func(t *testing.T) {
o, err := DirtyStringToInt(tc.in)
if err != nil {
if tc.err != "" {
if strings.Contains(err.Error(), tc.err) {
return
}

t.Fatalf("unexpected error: %s (expected: %s)", err, tc.err)
}

t.Fatalf("received unexpected error: %s", err)
}

if o != tc.out {
t.Fatalf("unexpected output: %d (expected: %d)", o, tc.out)
}
})
}
}

func TestDanishDateToTime(t *testing.T) {
tt := []struct {
name string
in string
format string
out time.Time
err string
}{
{name: "basic", in: "10. jan. 2018", format: "2. jan. 2006", out: time.Date(2018, 1, 10, 0, 0, 0, 0, time.UTC)},
{name: "basic (maj)", in: "12. maj. 2021", format: "2. jan. 2006", out: time.Date(2021, 5, 12, 0, 0, 0, 0, time.UTC)},
{name: "basic (okt)", in: "28. okt. 2021", format: "2. jan. 2006", out: time.Date(2021, 10, 28, 0, 0, 0, 0, time.UTC)},
{name: "syntax issue", in: "28-okt-2021", format: "2. jan. 2006", out: time.Date(2021, 10, 28, 0, 0, 0, 0, time.UTC), err: "cannot parse"},
}

for _, tc := range tt {
t.Run(tc.name, func(t *testing.T) {
o, err := DanishDateToTime(tc.format, tc.in)
if err != nil {
if tc.err != "" {
if strings.Contains(err.Error(), tc.err) {
return
}

t.Fatalf("unexpected error: %s (expected: %s)", err, tc.err)
}

t.Fatalf("received unexpected error: %s", err)
}

if o != tc.out {
t.Fatalf("unexpected output: %v (expected: %v)", o, tc.out)
}
})
}
}
34 changes: 19 additions & 15 deletions dawa.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,9 @@ func (a Address) Headers() []string {
}
}

type DawaCacher struct {
db *gorm.DB
type dawaCacher struct {
db *gorm.DB
maxAmount float64
}

type DawaQueryCache struct {
Expand Down Expand Up @@ -148,16 +149,21 @@ func (dqc DawaQueryCache) Identifiers() []int {
return uids
}

func NewDawaCacher(db *gorm.DB) *DawaCacher {
type DawaCacher interface {
Do(DawaRequest) ([]*Address, error)
}

func NewDawaCacher(db *gorm.DB) *dawaCacher {
db.AutoMigrate(&DawaQueryCache{})
db.AutoMigrate(&Address{})

return &DawaCacher{
db: db,
return &dawaCacher{
maxAmount: 50.0,
db: db,
}
}

func (c DawaCacher) Do(req DawaRequest) ([]*Address, error) {
func (c dawaCacher) Do(req DawaRequest) ([]*Address, error) {
reqStr := fmt.Sprintf("%s", req.Request().URL)

var cache DawaQueryCache
Expand Down Expand Up @@ -192,11 +198,10 @@ func (c DawaCacher) Do(req DawaRequest) ([]*Address, error) {

var addrs []*Address
ids := cache.Identifiers()
maxAmount := 50.0
r := int(math.Ceil(float64(len(ids)) / maxAmount))
r := int(math.Ceil(float64(len(ids)) / c.maxAmount))
for i := 0; i < r; i++ {
var tempAddrs []*Address
start, end := int(maxAmount)*i, int(maxAmount)*(i+1)
start, end := int(c.maxAmount)*i, int(c.maxAmount)*(i+1)
end = int(math.Min(float64(len(ids)), float64(end)))
if err := c.db.Find(&tempAddrs, ids[start:end]).Error; err != nil {
return nil, err
Expand All @@ -208,14 +213,13 @@ func (c DawaCacher) Do(req DawaRequest) ([]*Address, error) {
return addrs, nil
}

func (c DawaCacher) safeCreateOrGetAddrs(addrs []*Address) error {
maxAmount := 50.0
func (c dawaCacher) safeCreateOrGetAddrs(addrs []*Address) error {
n := float64(len(addrs))
r := int(math.Ceil(n / maxAmount))
r := int(math.Ceil(n / c.maxAmount))

m := map[string]*Address{}
for i := 0; i < r; i++ {
start, end := int(maxAmount)*i, int(maxAmount)*(i+1)
start, end := int(c.maxAmount)*i, int(c.maxAmount)*(i+1)
end = int(math.Min(n, float64(end)))

var tempAddrs []*Address
Expand Down Expand Up @@ -246,7 +250,7 @@ func (c DawaCacher) safeCreateOrGetAddrs(addrs []*Address) error {
addrs[i] = exsts
}

if err := c.db.CreateInBatches(&createAddrs, int(maxAmount)).Error; err != nil {
if err := c.db.CreateInBatches(&createAddrs, int(c.maxAmount)).Error; err != nil {
return err
}

Expand All @@ -264,7 +268,7 @@ func reqToAddrs(req *http.Request) ([]*Address, error) {
q.Add("struktur", "mini")
req.URL.RawQuery = q.Encode()

resp, err := http.DefaultClient.Do(req)
resp, err := DefaultClient.Do(req)
if err != nil {
return nil, err
}
Expand Down

0 comments on commit 58a3b50

Please sign in to comment.