package seed import ( "strings" "testing" "git.totmin.ru/en2zmax/addrkit/internal/domain/address" ) func TestReadBulkNDJSON(t *testing.T) { input := `{"index": {"_index": "address_registry", "_id": "a1"}} {"address": "Станционная улица 1/1", "district_name": "Ленинский", "city": "Новосибирск"} {"index": {"_id": "a2"}} {"address": "Искитимская улица 5", "district_name": "Кировский"} {"address": "Третья улица 7"} ` src, err := ReadBulkNDJSON(strings.NewReader(input)) if err != nil { t.Fatalf("ReadBulkNDJSON: %v", err) } if len(src) != 3 { t.Fatalf("got %d sources, want 3", len(src)) } if src[0].ID != "a1" || src[0].District != "Ленинский" || src[0].City != "Новосибирск" { t.Errorf("first source = %+v", src[0]) } if src[2].Address != "Третья улица 7" { t.Errorf("bare source not read: %+v", src[2]) } } func TestBuild(t *testing.T) { sources := []Source{ {ID: "1", Address: "Станционная улица 1/1"}, {ID: "2", Address: "Искитимская улица 5"}, {ID: "3", Address: "Станционная улица"}, // no house -> unparsed } entries, stats := Build(sources, BuildOptions{}) if stats.Total != 3 { t.Errorf("Total = %d, want 3", stats.Total) } if stats.Parsed != 2 { t.Errorf("Parsed = %d, want 2", stats.Parsed) } if stats.Unparsed != 1 { t.Errorf("Unparsed = %d, want 1", stats.Unparsed) } if len(entries) != 3 { t.Errorf("entries = %d, want 3", len(entries)) } // Two distinct streets: "станционная" and "искитимская". if stats.DistinctStreets != 2 { t.Errorf("DistinctStreets = %d, want 2", stats.DistinctStreets) } } func TestBuildKeepsCitiesApart(t *testing.T) { sources := []Source{ {ID: "1", Address: "Ленина улица 5", City: "Новосибирск"}, {ID: "1", Address: "Ленина улица 5", City: "Бердск"}, {ID: "2", Address: "Ленина улица 7", City: "Новосибирск"}, } entries, stats := Build(sources, BuildOptions{}) if len(entries) != 3 { t.Fatalf("entries = %d, want 3: %+v", len(entries), entries) } if stats.DistinctStreets != 2 { t.Errorf("DistinctStreets = %d, want 2 (same street in two cities)", stats.DistinctStreets) } if entries[0].StreetKey == entries[1].StreetKey { t.Errorf("streets from different cities share a key: %q", entries[0].StreetKey) } if entries[0].ID == entries[1].ID { t.Errorf("source ids collided across cities: %q", entries[0].ID) } if stats.Cities["Новосибирск"] != 2 || stats.Cities["Бердск"] != 1 { t.Errorf("city stats = %v", stats.Cities) } } func TestBuildAppliesDefaultCity(t *testing.T) { sources := []Source{{ID: "1", Address: "Станционная улица 1/1"}} entries, _ := Build(sources, BuildOptions{DefaultCity: "Новосибирск"}) if len(entries) != 1 { t.Fatalf("entries = %d", len(entries)) } if entries[0].City != "Новосибирск" || entries[0].CityKey != "новосибирск" { t.Errorf("city = %q / %q", entries[0].City, entries[0].CityKey) } } func TestBuildKeepsStructuresDistinct(t *testing.T) { sources := []Source{ {ID: "1", Address: "Станционная улица 1"}, {ID: "2", Address: "Станционная улица 1 стр. 2"}, } entries, stats := Build(sources, BuildOptions{}) if len(entries) != 2 { t.Fatalf("entries = %d, want 2 (structure is part of identity)", len(entries)) } if stats.Duplicates != 0 { t.Errorf("Duplicates = %d, want 0", stats.Duplicates) } if entries[0].Structure == entries[1].Structure { t.Errorf("structures collapsed: %+v", entries) } } func TestBuildParsesCityFromAddress(t *testing.T) { parser := address.NewParser(address.NewDictionary([]address.City{ {Name: "Новосибирск", Aliases: []string{"нск", "новосибирская область"}}, }), "") sources := []Source{{ID: "1", Address: "нск, Станционная улица 1/1"}} entries, _ := Build(sources, BuildOptions{Parser: parser}) if len(entries) != 1 { t.Fatalf("entries = %d", len(entries)) } if entries[0].City != "Новосибирск" || entries[0].NameKey != "станционная" { t.Errorf("entry = %+v", entries[0]) } }