Spaces:
Running
Running
File size: 7,184 Bytes
8429e5e ad8201c 8429e5e 61f1033 8429e5e 61f1033 8429e5e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 | """Tests for gazet.search — fuzzy search and ID lookup against real parquet data."""
import pandas as pd
from gazet.schemas import Place
from gazet.search import (
get_by_id,
get_division_by_id,
get_natural_earth_by_id,
search_candidates,
search_divisions_area,
search_natural_earth,
)
class TestSearchDivisionsArea:
def test_returns_dataframe(self, con):
df = search_divisions_area(con, Place(place="India"))
assert isinstance(df, pd.DataFrame)
assert "source" in df.columns
assert "id" in df.columns
def test_matches_known_country(self, con):
df = search_divisions_area(con, Place(place="India"))
assert not df.empty
# At least one result should be India
names = df["name"].str.lower().tolist()
assert any("india" in name for name in names)
def test_limits_results(self, con):
df = search_divisions_area(con, Place(place="a"), limit=3)
assert len(df) <= 3
def test_empty_result(self, con):
# Extremely unlikely string — Jaro-Winkler always returns top N,
# but similarity should be very low
df = search_divisions_area(con, Place(place="Xyzz98765"))
# Results may still be returned (always top-5) but with low similarity
assert len(df) <= 5
def test_source_column(self, con):
df = search_divisions_area(con, Place(place="India"))
if not df.empty:
assert (df["source"] == "divisions_area").all()
def test_case_insensitive(self, con):
df_upper = search_divisions_area(con, Place(place="INDIA"))
df_lower = search_divisions_area(con, Place(place="india"))
# Both should return results (even if different similarity scores)
assert not df_upper.empty
assert not df_lower.empty
def test_with_country_filter(self, con):
df = search_divisions_area(con, Place(place="Loja", country="EC"))
# Should find Loja in Ecuador
if not df.empty:
assert "source" in df.columns
def test_similar_names_different_country(self, con):
df = search_divisions_area(con, Place(place="Manchester"))
# Should return results (multiple Manchesters exist)
assert isinstance(df, pd.DataFrame)
def test_include_geometry_flag(self, con):
df = search_divisions_area(
con, Place(place="India"), include_geometry=True, limit=1
)
if not df.empty:
assert "geometry" in df.columns
def test_include_bbox_flag(self, con):
df = search_divisions_area(
con, Place(place="India"), include_bbox=True, limit=1
)
if not df.empty:
assert "bbox" in df.columns
def test_column_presence(self, con):
df = search_divisions_area(con, Place(place="India"), limit=1)
if not df.empty:
expected_cols = ["source", "id", "name", "country", "subtype", "similarity"]
for col in expected_cols:
assert col in df.columns
class TestSearchNaturalEarth:
def test_returns_dataframe(self, con):
df = search_natural_earth(con, Place(place="Nile"))
assert isinstance(df, pd.DataFrame)
def test_searches_ocean(self, con):
df = search_natural_earth(con, Place(place="Pacific"))
assert isinstance(df, pd.DataFrame)
def test_source_column(self, con):
df = search_natural_earth(con, Place(place="Nile"))
if not df.empty:
assert (df["source"] == "natural_earth").all()
def test_empty_result(self, con):
df = search_natural_earth(con, Place(place="Xyzz98765"))
# Jaro-Winkler always returns top 5, similarity is very low
assert len(df) <= 5
def test_limits_results(self, con):
df = search_natural_earth(con, Place(place="a"), limit=2)
assert len(df) <= 2
def test_include_geometry(self, con):
df = search_natural_earth(con, Place(place="Nile"), include_geometry=True)
if not df.empty:
assert "geometry" in df.columns
class TestSearchCandidates:
def test_searches_both_sources(self, con):
results = search_candidates(con, Place(place="India"))
# Should get at least one source
assert len(results) >= 1
sources = {df["source"].iloc[0] for df in results if not df.empty}
assert "divisions_area" in sources
def test_restricts_to_single_source(self, con):
results = search_candidates(
con,
Place(place="Nile"),
sources=("natural_earth",),
)
for df in results:
if not df.empty:
assert df["source"].iloc[0] == "natural_earth"
def test_empty_place(self, con):
# Even random strings get fuzzy matches — check results exist
# but have low similarity
results = search_candidates(con, Place(place="Xyzz98765"))
# Results may be non-empty due to fuzzy matching, but similarity low
for df in results:
assert len(df) <= 5
def test_combine_multiple_places(self, con):
# Search for a place that exists in both sources
results = search_candidates(
con,
Place(place="Brazil"),
sources=("divisions_area", "natural_earth"),
)
for df in results:
assert isinstance(df, pd.DataFrame)
class TestGetById:
def test_get_division_by_id(self, con):
# First get a valid ID from search
df = search_divisions_area(con, Place(place="India"), limit=1)
if not df.empty:
rid = df["id"].iloc[0]
result = get_division_by_id(con, rid)
assert not result.empty
assert result["id"].iloc[0] == rid
def test_get_natural_earth_by_id(self, con):
df = search_natural_earth(con, Place(place="Nile"), limit=1)
if not df.empty:
rid = df["id"].iloc[0]
result = get_natural_earth_by_id(con, rid)
assert not result.empty
assert result["id"].iloc[0] == rid
def test_get_by_id_auto_infer_divisions(self, con):
df = search_divisions_area(con, Place(place="India"), limit=1)
if not df.empty:
rid = df["id"].iloc[0]
result = get_by_id(con, rid)
assert not result.empty
def test_get_by_id_auto_infer_natural_earth(self, con):
df = search_natural_earth(con, Place(place="Nile"), limit=1)
if not df.empty:
rid = df["id"].iloc[0]
# NE IDs start with "ne_"
assert rid.startswith("ne_")
result = get_by_id(con, rid)
assert not result.empty
def test_get_by_id_invalid(self, con):
result = get_by_id(con, "nonexistent_id_999")
assert result.empty
def test_get_by_id_with_source(self, con):
df = search_divisions_area(con, Place(place="India"), limit=1)
if not df.empty:
rid = df["id"].iloc[0]
result = get_by_id(con, rid, source="divisions_area")
assert not result.empty
assert result["source"].iloc[0] == "divisions_area"
|