Skip to content

Commit 88b81dd

Browse files
test: add impl-level filter tests for coverage
- Add tests for dep, tech, pat, prep, style filter matching - Add test for impl_not_in_lookup case - Add test for global_counts with impl_tags - Add test for contextual_counts with impl_tags 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent fa7dc5f commit 88b81dd

File tree

1 file changed

+115
-0
lines changed

1 file changed

+115
-0
lines changed

tests/unit/api/test_routers.py

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -893,6 +893,55 @@ def test_image_matches_groups_spec_not_in_lookup(self) -> None:
893893
spec_lookup = {}
894894
assert _image_matches_groups("unknown", "matplotlib", [], spec_lookup, {}) is False
895895

896+
def test_image_matches_groups_dep_match(self) -> None:
897+
"""Dependencies filter should match impl_tags."""
898+
spec_lookup = {"scatter-basic": {"tags": {}}}
899+
impl_lookup = {("scatter-basic", "matplotlib"): {"dependencies": ["scipy", "sklearn"]}}
900+
groups = [{"category": "dep", "values": ["scipy"]}]
901+
assert _image_matches_groups("scatter-basic", "matplotlib", groups, spec_lookup, impl_lookup) is True
902+
903+
def test_image_matches_groups_dep_no_match(self) -> None:
904+
"""Dependencies filter should not match if not in impl_tags."""
905+
spec_lookup = {"scatter-basic": {"tags": {}}}
906+
impl_lookup = {("scatter-basic", "matplotlib"): {"dependencies": ["scipy"]}}
907+
groups = [{"category": "dep", "values": ["networkx"]}]
908+
assert _image_matches_groups("scatter-basic", "matplotlib", groups, spec_lookup, impl_lookup) is False
909+
910+
def test_image_matches_groups_tech_match(self) -> None:
911+
"""Techniques filter should match impl_tags."""
912+
spec_lookup = {"scatter-basic": {"tags": {}}}
913+
impl_lookup = {("scatter-basic", "matplotlib"): {"techniques": ["annotations", "colorbar"]}}
914+
groups = [{"category": "tech", "values": ["annotations"]}]
915+
assert _image_matches_groups("scatter-basic", "matplotlib", groups, spec_lookup, impl_lookup) is True
916+
917+
def test_image_matches_groups_pat_match(self) -> None:
918+
"""Patterns filter should match impl_tags."""
919+
spec_lookup = {"scatter-basic": {"tags": {}}}
920+
impl_lookup = {("scatter-basic", "matplotlib"): {"patterns": ["data-generation", "iteration-over-groups"]}}
921+
groups = [{"category": "pat", "values": ["data-generation"]}]
922+
assert _image_matches_groups("scatter-basic", "matplotlib", groups, spec_lookup, impl_lookup) is True
923+
924+
def test_image_matches_groups_prep_match(self) -> None:
925+
"""Dataprep filter should match impl_tags."""
926+
spec_lookup = {"scatter-basic": {"tags": {}}}
927+
impl_lookup = {("scatter-basic", "matplotlib"): {"dataprep": ["kde", "binning"]}}
928+
groups = [{"category": "prep", "values": ["kde"]}]
929+
assert _image_matches_groups("scatter-basic", "matplotlib", groups, spec_lookup, impl_lookup) is True
930+
931+
def test_image_matches_groups_style_match(self) -> None:
932+
"""Styling filter should match impl_tags."""
933+
spec_lookup = {"scatter-basic": {"tags": {}}}
934+
impl_lookup = {("scatter-basic", "matplotlib"): {"styling": ["alpha-blending", "minimal-chrome"]}}
935+
groups = [{"category": "style", "values": ["alpha-blending"]}]
936+
assert _image_matches_groups("scatter-basic", "matplotlib", groups, spec_lookup, impl_lookup) is True
937+
938+
def test_image_matches_groups_impl_not_in_lookup(self) -> None:
939+
"""Impl not in lookup should not match impl-level filters."""
940+
spec_lookup = {"scatter-basic": {"tags": {}}}
941+
impl_lookup = {} # Empty - no impl data
942+
groups = [{"category": "dep", "values": ["scipy"]}]
943+
assert _image_matches_groups("scatter-basic", "matplotlib", groups, spec_lookup, impl_lookup) is False
944+
896945
def test_calculate_global_counts(self) -> None:
897946
"""Global counts should tally all implementations."""
898947
mock_impl = MagicMock()
@@ -910,6 +959,36 @@ def test_calculate_global_counts(self) -> None:
910959
assert counts["plot"]["scatter"] == 1
911960
assert counts["dom"]["statistics"] == 1
912961

962+
def test_calculate_global_counts_with_impl_tags(self) -> None:
963+
"""Global counts should include impl-level tags."""
964+
mock_impl = MagicMock()
965+
mock_impl.library_id = "matplotlib"
966+
mock_impl.preview_url = TEST_IMAGE_URL
967+
mock_impl.impl_tags = {
968+
"dependencies": ["scipy", "sklearn"],
969+
"techniques": ["annotations"],
970+
"patterns": ["data-generation"],
971+
"dataprep": ["kde"],
972+
"styling": ["alpha-blending"],
973+
}
974+
975+
mock_spec = MagicMock()
976+
mock_spec.id = "scatter-basic"
977+
mock_spec.tags = {"plot_type": ["scatter"]}
978+
mock_spec.impls = [mock_impl]
979+
980+
counts = _calculate_global_counts([mock_spec])
981+
# Spec-level counts
982+
assert counts["lib"]["matplotlib"] == 1
983+
assert counts["plot"]["scatter"] == 1
984+
# Impl-level counts
985+
assert counts["dep"]["scipy"] == 1
986+
assert counts["dep"]["sklearn"] == 1
987+
assert counts["tech"]["annotations"] == 1
988+
assert counts["pat"]["data-generation"] == 1
989+
assert counts["prep"]["kde"] == 1
990+
assert counts["style"]["alpha-blending"] == 1
991+
913992
def test_calculate_global_counts_no_impls(self) -> None:
914993
"""Spec without impls should not be counted."""
915994
mock_spec = MagicMock()
@@ -948,6 +1027,42 @@ def test_calculate_contextual_counts(self) -> None:
9481027
assert counts["spec"]["scatter-basic"] == 2
9491028
assert counts["plot"]["scatter"] == 2
9501029

1030+
def test_calculate_contextual_counts_with_impl_tags(self) -> None:
1031+
"""Contextual counts should include impl-level tags."""
1032+
images = [
1033+
{"spec_id": "scatter-basic", "library": "matplotlib"},
1034+
{"spec_id": "scatter-basic", "library": "seaborn"},
1035+
]
1036+
spec_tags = {"scatter-basic": {"plot_type": ["scatter"]}}
1037+
impl_lookup = {
1038+
("scatter-basic", "matplotlib"): {
1039+
"dependencies": ["scipy"],
1040+
"techniques": ["annotations"],
1041+
"patterns": ["data-generation"],
1042+
"dataprep": ["kde"],
1043+
"styling": ["alpha-blending"],
1044+
},
1045+
("scatter-basic", "seaborn"): {
1046+
"dependencies": ["scipy", "sklearn"],
1047+
"techniques": ["colorbar"],
1048+
"patterns": ["data-generation"],
1049+
"dataprep": [],
1050+
"styling": [],
1051+
},
1052+
}
1053+
1054+
counts = _calculate_contextual_counts(images, spec_tags, impl_lookup)
1055+
# Spec-level counts
1056+
assert counts["plot"]["scatter"] == 2
1057+
# Impl-level counts
1058+
assert counts["dep"]["scipy"] == 2
1059+
assert counts["dep"]["sklearn"] == 1
1060+
assert counts["tech"]["annotations"] == 1
1061+
assert counts["tech"]["colorbar"] == 1
1062+
assert counts["pat"]["data-generation"] == 2
1063+
assert counts["prep"]["kde"] == 1
1064+
assert counts["style"]["alpha-blending"] == 1
1065+
9511066
def test_calculate_or_counts_empty_groups(self) -> None:
9521067
"""Empty groups should return empty or_counts."""
9531068
counts = _calculate_or_counts([], [], {}, {}, {})

0 commit comments

Comments
 (0)