From 2b6ff37ce7369bed8a2cfd70494b72df03c13324 Mon Sep 17 00:00:00 2001 From: Lukas Plank Date: Wed, 23 Oct 2024 11:29:55 +0200 Subject: [PATCH] refactor(tests): refactor test folder structure This branch implements a restructuring of the test suite. Rationale: Over-modularization of test parameter definitions clutters up the test suite and leads to lengthy/repetitive import statements. For now, the structure of the test suite should only differentiate 1. unit tests and 2. all other tests. Additional test categories may be introduced at a later point. The test category should be indicated in the test module doc string. Closes #100 --- tests/data/models/dummy_model.py | 11 + ...uthor_array_collection_model_parameters.py | 87 ------- .../author_work_title_model_parameters.py | 28 --- .../data/parameters/basic_model_parameters.py | 49 ---- .../data/parameters/count_query_parameters.py | 94 ++++++++ .../parameters/grouping_model_parameters.py | 42 ---- .../model_bindings_mapper_parameters.py | 224 ++++++++++++++++++ .../nested_grouping_model_parameters.py | 27 --- tests/test_construct_count_query.py | 46 ---- tests/test_instantiate_model_from_bindings.py | 32 --- .../test_model_bindings_mapper.py | 34 +++ tests/unit/test_construct_count_query.py | 36 +++ tests/utils/_types.py | 19 +- 13 files changed, 416 insertions(+), 313 deletions(-) create mode 100644 tests/data/models/dummy_model.py delete mode 100644 tests/data/parameters/author_array_collection_model_parameters.py delete mode 100644 tests/data/parameters/author_work_title_model_parameters.py delete mode 100644 tests/data/parameters/basic_model_parameters.py create mode 100644 tests/data/parameters/count_query_parameters.py delete mode 100644 tests/data/parameters/grouping_model_parameters.py create mode 100644 tests/data/parameters/model_bindings_mapper_parameters.py delete mode 100644 tests/data/parameters/nested_grouping_model_parameters.py delete mode 100644 tests/test_construct_count_query.py delete mode 100644 tests/test_instantiate_model_from_bindings.py create mode 100644 tests/tests_mapper/test_model_bindings_mapper.py create mode 100644 tests/unit/test_construct_count_query.py diff --git a/tests/data/models/dummy_model.py b/tests/data/models/dummy_model.py new file mode 100644 index 0000000..2cab0d9 --- /dev/null +++ b/tests/data/models/dummy_model.py @@ -0,0 +1,11 @@ +"""Simple dummy models e.g. for count query constructor testing.""" + +from pydantic import BaseModel, ConfigDict + + +class Dummy(BaseModel): + pass + + +class GroupedDummy(BaseModel): + model_config = ConfigDict(group_by="x") diff --git a/tests/data/parameters/author_array_collection_model_parameters.py b/tests/data/parameters/author_array_collection_model_parameters.py deleted file mode 100644 index 2c0f9c5..0000000 --- a/tests/data/parameters/author_array_collection_model_parameters.py +++ /dev/null @@ -1,87 +0,0 @@ -from tests.data.models.author_array_collection_model import Author -from tests.utils._types import Parameter - - -author_array_collection_parameters = [ - Parameter( - model=Author, - bindings=[ - { - "work": "http://www.wikidata.org/entity/Q1497409", - "gnd": "119359464", - "work_name": "Geb\u00fcrtig", - "nameLabel": "Schindel", - }, - { - "work": "http://www.wikidata.org/entity/Q15805238", - "gnd": "115612815", - "work_name": "Der alte K\u00f6nig in seinem Exil", - "nameLabel": "Geiger", - "viaf": "299260555", - "educated_atLabel": "University of Vienna", - }, - { - "work": "http://www.wikidata.org/entity/Q15805238", - "gnd": "115612815", - "work_name": "Der alte K\u00f6nig in seinem Exil", - "nameLabel": "Geiger", - "viaf": "6762154387354230970008", - "educated_atLabel": "University of Vienna", - }, - { - "work": "http://www.wikidata.org/entity/Q58038819", - "gnd": "115612815", - "work_name": "Unter der Drachenwand", - "nameLabel": "Geiger", - "viaf": "2277151717053313900002", - "educated_atLabel": "University of Vienna", - }, - { - "work": "http://www.wikidata.org/entity/Q100266054", - "gnd": "1136992030", - "work_name": "Das fl\u00fcssige Land", - "nameLabel": "Edelbauer", - "educated_atLabel": "University of Vienna", - }, - { - "work": "http://www.wikidata.org/entity/Q100266054", - "gnd": "1136992030", - "work_name": "Das fl\u00fcssige Land", - "nameLabel": "Edelbauer", - "educated_atLabel": "University of Applied Arts Vienna", - }, - ], - expected=[ - { - "gnd": "119359464", - "surname": "Schindel", - "works": [{"name": "Geb\u00fcrtig", "viafs": []}], - "education": [], - }, - { - "gnd": "115612815", - "surname": "Geiger", - "works": [ - { - "name": "Der alte K\u00f6nig in seinem Exil", - "viafs": ["299260555", "6762154387354230970008"], - }, - { - "name": "Unter der Drachenwand", - "viafs": ["2277151717053313900002"], - }, - ], - "education": ["University of Vienna"], - }, - { - "gnd": "1136992030", - "surname": "Edelbauer", - "works": [{"name": "Das fl\u00fcssige Land", "viafs": []}], - "education": [ - "University of Vienna", - "University of Applied Arts Vienna", - ], - }, - ], - ) -] diff --git a/tests/data/parameters/author_work_title_model_parameters.py b/tests/data/parameters/author_work_title_model_parameters.py deleted file mode 100644 index f3349fc..0000000 --- a/tests/data/parameters/author_work_title_model_parameters.py +++ /dev/null @@ -1,28 +0,0 @@ -from tests.data.models.author_work_title_model import Author -from tests.utils._types import Parameter - - -author_work_title_parameters = [ - Parameter( - model=Author, - bindings=[ - {"author": "Author 1", "work": "Work 1", "year": 2000}, - {"author": "Author 2", "work": "Work 4", "year": 2000}, - {"author": "Author 1", "work": "Work 2", "year": 2000}, - {"author": "Author 1", "work": "Work 3", "year": 2001}, - ], - expected=[ - { - "name": "Author 1", - "works": [ - {"year": 2000, "titles": [{"name": "Work 1"}, {"name": "Work 2"}]}, - {"year": 2001, "titles": [{"name": "Work 3"}]}, - ], - }, - { - "name": "Author 2", - "works": [{"year": 2000, "titles": [{"name": "Work 4"}]}], - }, - ], - ) -] diff --git a/tests/data/parameters/basic_model_parameters.py b/tests/data/parameters/basic_model_parameters.py deleted file mode 100644 index c24d926..0000000 --- a/tests/data/parameters/basic_model_parameters.py +++ /dev/null @@ -1,49 +0,0 @@ -"""Parameters for instantiate_model_from_bindings with basic models tests.""" - -from tests.data.models.basic_model import ( - BasicComplexModel, - BasicNestedModel, - BasicSimpleModel, -) -from tests.utils._types import Parameter - - -basic_parameters = [ - Parameter( - model=BasicSimpleModel, bindings=[{"x": 1, "y": 2}], expected=[{"x": 1, "y": 2}] - ), - Parameter( - model=BasicSimpleModel, - bindings=[{"x": 3, "y": 4}, {"x": 5, "y": 6}], - expected=[{"x": 3, "y": 4}, {"x": 5, "y": 6}], - ), - Parameter( - model=BasicNestedModel, - bindings=[{"a": "a value", "x": 1, "y": 2}], - expected=[{"a": "a value", "b": {"x": 1, "y": 2}}], - ), - Parameter( - model=BasicNestedModel, - bindings=[{"a": "a value", "x": 1, "y": 2}, {"a": "a value", "x": 3, "y": 4}], - expected=[ - {"a": "a value", "b": {"x": 1, "y": 2}}, - {"a": "a value", "b": {"x": 3, "y": 4}}, - ], - ), - Parameter( - model=BasicComplexModel, - bindings=[{"a": "a value", "x": 1, "y": 2, "p": "p value"}], - expected=[{"p": "p value", "q": {"a": "a value", "b": {"x": 1, "y": 2}}}], - ), - Parameter( - model=BasicComplexModel, - bindings=[ - {"a": "a value", "x": 1, "y": 2, "p": "p value"}, - {"a": "a value", "x": 3, "y": 4, "p": "p value"}, - ], - expected=[ - {"p": "p value", "q": {"a": "a value", "b": {"x": 1, "y": 2}}}, - {"p": "p value", "q": {"a": "a value", "b": {"x": 3, "y": 4}}}, - ], - ), -] diff --git a/tests/data/parameters/count_query_parameters.py b/tests/data/parameters/count_query_parameters.py new file mode 100644 index 0000000..e7aa9ad --- /dev/null +++ b/tests/data/parameters/count_query_parameters.py @@ -0,0 +1,94 @@ +from tests.data.models.dummy_model import Dummy, GroupedDummy +from tests.utils._types import CountQueryParameter + + +construct_count_query_parameters = [ + CountQueryParameter( + query=""" + select ?x ?y ?z + where { + values (?x ?y ?z) { + (1 2 3) + (1 22 33) + (2 222 333) + } + } + """, + model=Dummy, + expected=3, + ), + CountQueryParameter( + query=""" + select ?x ?y ?z + where { + values (?x ?y ?z) { + (1 2 3) + (1 22 33) + (2 222 333) + } + } + """, + model=GroupedDummy, + expected=2, + ), + CountQueryParameter( + query=""" + select ?x ?y ?z + where { + values (?x ?y ?z) { + (1 2 3) + (1 22 33) + (1 22 33) + (2 222 333) + } + } + """, + model=Dummy, + expected=4, + ), + CountQueryParameter( + query=""" + select ?x ?y ?z + where { + values (?x ?y ?z) { + (1 2 3) + (1 22 33) + (1 22 33) + (2 222 333) + } + } + """, + model=GroupedDummy, + expected=2, + ), + CountQueryParameter( + query=""" + select ?x ?y ?z + where { + values (?x ?y ?z) { + (1 2 3) + (1 22 33) + (2 222 333) + (2 222 333) + } + } + """, + model=Dummy, + expected=4, + ), + CountQueryParameter( + query=""" + select ?x ?y ?z + where { + values (?x ?y ?z) { + (1 2 3) + (1 22 33) + (2 222 333) + (2 222 333) + } + } + """, + model=GroupedDummy, + expected=2, + ), +] diff --git a/tests/data/parameters/grouping_model_parameters.py b/tests/data/parameters/grouping_model_parameters.py deleted file mode 100644 index 6a5a407..0000000 --- a/tests/data/parameters/grouping_model_parameters.py +++ /dev/null @@ -1,42 +0,0 @@ -"""Parameters for instantiate_model_from_bindings with grouping models tests.""" - -from tests.data.models.grouping_model import GroupingComplexModel -from tests.utils._types import Parameter - - -grouping_parameters = [ - Parameter( - model=GroupingComplexModel, - bindings=[{"a": "a value", "x": 1, "y": 2, "p": "p value"}], - expected=[{"p": "p value", "q": [{"a": "a value", "b": {"x": 1, "y": 2}}]}], - ), - Parameter( - model=GroupingComplexModel, - bindings=[ - {"a": "a value", "x": 1, "y": 2, "p": "p value"}, - {"a": "a value", "x": 3, "y": 4, "p": "p value"}, - ], - expected=[ - {"p": "p value", "q": [{"a": "a value", "b": {"x": 1, "y": 2}}]}, - {"p": "p value", "q": [{"a": "a value", "b": {"x": 3, "y": 4}}]}, - ], - ), - Parameter( - model=GroupingComplexModel, - bindings=[ - {"a": "a value", "x": 1, "y": 2, "p": "p value"}, - {"a": "a value", "x": 3, "y": 4, "p": "p value"}, - {"a": "a value", "x": 1, "y": 4, "p": "p value"}, - ], - expected=[ - { - "p": "p value", - "q": [ - {"a": "a value", "b": {"x": 1, "y": 2}}, - {"a": "a value", "b": {"x": 1, "y": 4}}, - ], - }, - {"p": "p value", "q": [{"a": "a value", "b": {"x": 3, "y": 4}}]}, - ], - ), -] diff --git a/tests/data/parameters/model_bindings_mapper_parameters.py b/tests/data/parameters/model_bindings_mapper_parameters.py new file mode 100644 index 0000000..5d04fd4 --- /dev/null +++ b/tests/data/parameters/model_bindings_mapper_parameters.py @@ -0,0 +1,224 @@ +from tests.data.models.author_array_collection_model import Author as ArrayAuthor +from tests.data.models.author_work_title_model import Author +from tests.data.models.basic_model import ( + BasicComplexModel, + BasicNestedModel, + BasicSimpleModel, +) +from tests.data.models.grouping_model import GroupingComplexModel +from tests.data.models.nested_grouping_model import NestedGroupingComplexModel +from tests.utils._types import ModelBindingsMapperParameter + + +author_array_collection_parameters = [ + ModelBindingsMapperParameter( + model=ArrayAuthor, + bindings=[ + { + "work": "http://www.wikidata.org/entity/Q1497409", + "gnd": "119359464", + "work_name": "Geb\u00fcrtig", + "nameLabel": "Schindel", + }, + { + "work": "http://www.wikidata.org/entity/Q15805238", + "gnd": "115612815", + "work_name": "Der alte K\u00f6nig in seinem Exil", + "nameLabel": "Geiger", + "viaf": "299260555", + "educated_atLabel": "University of Vienna", + }, + { + "work": "http://www.wikidata.org/entity/Q15805238", + "gnd": "115612815", + "work_name": "Der alte K\u00f6nig in seinem Exil", + "nameLabel": "Geiger", + "viaf": "6762154387354230970008", + "educated_atLabel": "University of Vienna", + }, + { + "work": "http://www.wikidata.org/entity/Q58038819", + "gnd": "115612815", + "work_name": "Unter der Drachenwand", + "nameLabel": "Geiger", + "viaf": "2277151717053313900002", + "educated_atLabel": "University of Vienna", + }, + { + "work": "http://www.wikidata.org/entity/Q100266054", + "gnd": "1136992030", + "work_name": "Das fl\u00fcssige Land", + "nameLabel": "Edelbauer", + "educated_atLabel": "University of Vienna", + }, + { + "work": "http://www.wikidata.org/entity/Q100266054", + "gnd": "1136992030", + "work_name": "Das fl\u00fcssige Land", + "nameLabel": "Edelbauer", + "educated_atLabel": "University of Applied Arts Vienna", + }, + ], + expected=[ + { + "gnd": "119359464", + "surname": "Schindel", + "works": [{"name": "Geb\u00fcrtig", "viafs": []}], + "education": [], + }, + { + "gnd": "115612815", + "surname": "Geiger", + "works": [ + { + "name": "Der alte K\u00f6nig in seinem Exil", + "viafs": ["299260555", "6762154387354230970008"], + }, + { + "name": "Unter der Drachenwand", + "viafs": ["2277151717053313900002"], + }, + ], + "education": ["University of Vienna"], + }, + { + "gnd": "1136992030", + "surname": "Edelbauer", + "works": [{"name": "Das fl\u00fcssige Land", "viafs": []}], + "education": [ + "University of Vienna", + "University of Applied Arts Vienna", + ], + }, + ], + ) +] + + +author_work_title_parameters = [ + ModelBindingsMapperParameter( + model=Author, + bindings=[ + {"author": "Author 1", "work": "Work 1", "year": 2000}, + {"author": "Author 2", "work": "Work 4", "year": 2000}, + {"author": "Author 1", "work": "Work 2", "year": 2000}, + {"author": "Author 1", "work": "Work 3", "year": 2001}, + ], + expected=[ + { + "name": "Author 1", + "works": [ + {"year": 2000, "titles": [{"name": "Work 1"}, {"name": "Work 2"}]}, + {"year": 2001, "titles": [{"name": "Work 3"}]}, + ], + }, + { + "name": "Author 2", + "works": [{"year": 2000, "titles": [{"name": "Work 4"}]}], + }, + ], + ) +] + + +basic_parameters = [ + ModelBindingsMapperParameter( + model=BasicSimpleModel, bindings=[{"x": 1, "y": 2}], expected=[{"x": 1, "y": 2}] + ), + ModelBindingsMapperParameter( + model=BasicSimpleModel, + bindings=[{"x": 3, "y": 4}, {"x": 5, "y": 6}], + expected=[{"x": 3, "y": 4}, {"x": 5, "y": 6}], + ), + ModelBindingsMapperParameter( + model=BasicNestedModel, + bindings=[{"a": "a value", "x": 1, "y": 2}], + expected=[{"a": "a value", "b": {"x": 1, "y": 2}}], + ), + ModelBindingsMapperParameter( + model=BasicNestedModel, + bindings=[{"a": "a value", "x": 1, "y": 2}, {"a": "a value", "x": 3, "y": 4}], + expected=[ + {"a": "a value", "b": {"x": 1, "y": 2}}, + {"a": "a value", "b": {"x": 3, "y": 4}}, + ], + ), + ModelBindingsMapperParameter( + model=BasicComplexModel, + bindings=[{"a": "a value", "x": 1, "y": 2, "p": "p value"}], + expected=[{"p": "p value", "q": {"a": "a value", "b": {"x": 1, "y": 2}}}], + ), + ModelBindingsMapperParameter( + model=BasicComplexModel, + bindings=[ + {"a": "a value", "x": 1, "y": 2, "p": "p value"}, + {"a": "a value", "x": 3, "y": 4, "p": "p value"}, + ], + expected=[ + {"p": "p value", "q": {"a": "a value", "b": {"x": 1, "y": 2}}}, + {"p": "p value", "q": {"a": "a value", "b": {"x": 3, "y": 4}}}, + ], + ), +] + + +grouping_parameters = [ + ModelBindingsMapperParameter( + model=GroupingComplexModel, + bindings=[{"a": "a value", "x": 1, "y": 2, "p": "p value"}], + expected=[{"p": "p value", "q": [{"a": "a value", "b": {"x": 1, "y": 2}}]}], + ), + ModelBindingsMapperParameter( + model=GroupingComplexModel, + bindings=[ + {"a": "a value", "x": 1, "y": 2, "p": "p value"}, + {"a": "a value", "x": 3, "y": 4, "p": "p value"}, + ], + expected=[ + {"p": "p value", "q": [{"a": "a value", "b": {"x": 1, "y": 2}}]}, + {"p": "p value", "q": [{"a": "a value", "b": {"x": 3, "y": 4}}]}, + ], + ), + ModelBindingsMapperParameter( + model=GroupingComplexModel, + bindings=[ + {"a": "a value", "x": 1, "y": 2, "p": "p value"}, + {"a": "a value", "x": 3, "y": 4, "p": "p value"}, + {"a": "a value", "x": 1, "y": 4, "p": "p value"}, + ], + expected=[ + { + "p": "p value", + "q": [ + {"a": "a value", "b": {"x": 1, "y": 2}}, + {"a": "a value", "b": {"x": 1, "y": 4}}, + ], + }, + {"p": "p value", "q": [{"a": "a value", "b": {"x": 3, "y": 4}}]}, + ], + ), +] + +nested_grouping_parameters = [ + ModelBindingsMapperParameter( + model=NestedGroupingComplexModel, + bindings=[ + {"x": 1, "y": 2, "a": "a value 1", "p": "p value 1"}, + {"x": 1, "y": 2, "a": "a value 2", "p": "p value 2"}, + {"x": 1, "y": 3, "a": "a value 3", "p": "p value 3"}, + {"x": 2, "y": 2, "a": "a value 1", "p": "p value 4"}, + ], + expected=[ + { + "p": "p value 1", + "q": [{"a": "a value 1", "b": [{"x": 1, "y": 2}, {"x": 2, "y": 2}]}], + }, + {"p": "p value 2", "q": [{"a": "a value 2", "b": [{"x": 1, "y": 2}]}]}, + {"p": "p value 3", "q": [{"a": "a value 3", "b": [{"x": 1, "y": 3}]}]}, + { + "p": "p value 4", + "q": [{"a": "a value 1", "b": [{"x": 1, "y": 2}, {"x": 2, "y": 2}]}], + }, + ], + ) +] diff --git a/tests/data/parameters/nested_grouping_model_parameters.py b/tests/data/parameters/nested_grouping_model_parameters.py deleted file mode 100644 index f35545f..0000000 --- a/tests/data/parameters/nested_grouping_model_parameters.py +++ /dev/null @@ -1,27 +0,0 @@ -from tests.data.models.nested_grouping_model import NestedGroupingComplexModel -from tests.utils._types import Parameter - - -nested_grouping_parameters = [ - Parameter( - model=NestedGroupingComplexModel, - bindings=[ - {"x": 1, "y": 2, "a": "a value 1", "p": "p value 1"}, - {"x": 1, "y": 2, "a": "a value 2", "p": "p value 2"}, - {"x": 1, "y": 3, "a": "a value 3", "p": "p value 3"}, - {"x": 2, "y": 2, "a": "a value 1", "p": "p value 4"}, - ], - expected=[ - { - "p": "p value 1", - "q": [{"a": "a value 1", "b": [{"x": 1, "y": 2}, {"x": 2, "y": 2}]}], - }, - {"p": "p value 2", "q": [{"a": "a value 2", "b": [{"x": 1, "y": 2}]}]}, - {"p": "p value 3", "q": [{"a": "a value 3", "b": [{"x": 1, "y": 3}]}]}, - { - "p": "p value 4", - "q": [{"a": "a value 1", "b": [{"x": 1, "y": 2}, {"x": 2, "y": 2}]}], - }, - ], - ) -] diff --git a/tests/test_construct_count_query.py b/tests/test_construct_count_query.py deleted file mode 100644 index 94f6e2d..0000000 --- a/tests/test_construct_count_query.py +++ /dev/null @@ -1,46 +0,0 @@ -"""Pytest entry point for rdfproxy.utils.sparql_utils.construct_count_query tests.""" - -from pydantic import BaseModel, ConfigDict -from rdflib import Graph -from rdflib.plugins.sparql.processor import SPARQLResult -from rdfproxy.utils.sparql_utils import construct_count_query - - -query = """ -select ?x ?y ?z -where { - values (?x ?y ?z) { - (1 2 3) - (1 22 33) - (2 222 333) - } -} -""" - -graph: Graph = Graph() - - -class Dummy(BaseModel): - pass - - -class GroupedDummy(BaseModel): - model_config = ConfigDict(group_by="x") - - -count_query_dummy = construct_count_query(query=query, model=Dummy) -count_query_grouped_dummy = construct_count_query(query=query, model=GroupedDummy) - - -def _get_cnt_value_from_sparql_result( - result: SPARQLResult, count_var: str = "cnt" -) -> int: - return int(result.bindings[0][count_var]) - - -def test_basic_construct_count_query(): - result_dummy: SPARQLResult = graph.query(count_query_dummy) - result_grouped_dummy: SPARQLResult = graph.query(count_query_grouped_dummy) - - assert _get_cnt_value_from_sparql_result(result_dummy) == 3 - assert _get_cnt_value_from_sparql_result(result_grouped_dummy) == 2 diff --git a/tests/test_instantiate_model_from_bindings.py b/tests/test_instantiate_model_from_bindings.py deleted file mode 100644 index 89d25cb..0000000 --- a/tests/test_instantiate_model_from_bindings.py +++ /dev/null @@ -1,32 +0,0 @@ -"""Pytest entry point for rdfproxy.utils.utils.instantiate_model_from_bindings tests.""" - -import pytest - -from rdfproxy.mapper import ModelBindingsMapper -from tests.data.parameters.author_array_collection_model_parameters import ( - author_array_collection_parameters, -) -from tests.data.parameters.author_work_title_model_parameters import ( - author_work_title_parameters, -) -from tests.data.parameters.basic_model_parameters import basic_parameters -from tests.data.parameters.grouping_model_parameters import grouping_parameters -from tests.data.parameters.nested_grouping_model_parameters import ( - nested_grouping_parameters, -) - - -@pytest.mark.parametrize( - ["model", "bindings", "expected"], - [ - *basic_parameters, - *grouping_parameters, - *nested_grouping_parameters, - *author_work_title_parameters, - *author_array_collection_parameters, - ], -) -def test_basic_instantiate_model_from_bindings(model, bindings, expected): - mapper = ModelBindingsMapper(model, *bindings) - models = mapper.get_models() - assert [model.model_dump() for model in models] == expected diff --git a/tests/tests_mapper/test_model_bindings_mapper.py b/tests/tests_mapper/test_model_bindings_mapper.py new file mode 100644 index 0000000..4824674 --- /dev/null +++ b/tests/tests_mapper/test_model_bindings_mapper.py @@ -0,0 +1,34 @@ +"""Pytest entry point for basic rdfproxy.mapper.ModelBindingsMapper.""" + +from pydantic import BaseModel +import pytest +from rdfproxy.mapper import ModelBindingsMapper + +from tests.data.parameters.model_bindings_mapper_parameters import ( + author_array_collection_parameters, + author_work_title_parameters, + basic_parameters, + grouping_parameters, + nested_grouping_parameters, +) + + +@pytest.mark.parametrize( + ["model", "bindings", "expected"], + [ + *basic_parameters, + *grouping_parameters, + *nested_grouping_parameters, + *author_work_title_parameters, + *author_array_collection_parameters, + ], +) +def test_basic_model_bindings_mapper(model, bindings, expected): + """Basic test for rdfproxy.ModelBindingsMapper. + + Given a model and a set of bindings, run the BindingsModelMapper logic + and compare the result against the expected shape. + """ + mapper: ModelBindingsMapper = ModelBindingsMapper(model, *bindings) + models: list[BaseModel] = mapper.get_models() + assert [model.model_dump() for model in models] == expected diff --git a/tests/unit/test_construct_count_query.py b/tests/unit/test_construct_count_query.py new file mode 100644 index 0000000..94f7d10 --- /dev/null +++ b/tests/unit/test_construct_count_query.py @@ -0,0 +1,36 @@ +"""Unit tests for rdfproxy.utils.sparql_utils.construct_count_query.""" + +import pytest + +from rdflib import Graph +from rdflib.plugins.sparql.processor import SPARQLResult +from rdfproxy.utils.sparql_utils import construct_count_query +from tests.data.parameters.count_query_parameters import ( + construct_count_query_parameters, +) + + +def _get_cnt_value_from_sparql_result( + result: SPARQLResult, count_var: str = "cnt" +) -> int: + """Get the 'cnt' binding of a count query from a SPARQLResult object.""" + return int(result.bindings[0][count_var]) + + +@pytest.mark.parametrize( + ["query", "model", "expected"], construct_count_query_parameters +) +def test_basic_construct_count_query(query, model, expected): + """Check the count of a grouped model. + + The count query constructed based on a grouped value must only count + distinct values according to the grouping specified in the model. + """ + + graph: Graph = Graph() + count_query: str = construct_count_query(query, model) + query_result: SPARQLResult = graph.query(count_query) + + cnt: int = _get_cnt_value_from_sparql_result(query_result) + + assert cnt == expected diff --git a/tests/utils/_types.py b/tests/utils/_types.py index 292c668..d51993d 100644 --- a/tests/utils/_types.py +++ b/tests/utils/_types.py @@ -1,6 +1,21 @@ """Types for testing.""" -from collections import namedtuple +from typing import NamedTuple +from pydantic import BaseModel -Parameter = namedtuple("Parameter", ["model", "bindings", "expected"]) + +class ModelBindingsMapperParameter(NamedTuple): + """Parameter type for rdfproxy.ModelBindingsMapper tests.""" + + model: type[BaseModel] + bindings: list[dict] + expected: list[dict] + + +class CountQueryParameter(NamedTuple): + """Parameter type for rdfproxy.utils.sparql_utils.construct_count_query tests.""" + + query: str + model: type[BaseModel] + expected: int