Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
aaxelb committed Mar 6, 2024
1 parent a48fbc6 commit 028c0cc
Show file tree
Hide file tree
Showing 5 changed files with 452 additions and 441 deletions.
119 changes: 39 additions & 80 deletions tests/trove/derive/_base.py
Original file line number Diff line number Diff line change
@@ -1,94 +1,53 @@
from trove.derive._base import IndexcardDeriver
from unittest import mock

from tests import factories
from ._inputs import DERIVER_TEST_INPUTS
from ._inputs import DERIVER_TEST_DOCS


class BaseIndexcardDeriverTest(SimpleTestCase):
SHOULD_SKIP = object() # for deriver inputs that should be skipped

####### override these things #######

# formatter key, as registered in setup.py
deriver_iri = None
class BaseIndexcardDeriverTest:

# dictionary with the same keys as `DERIVER_TEST_INPUTS`, mapping to values
# that `assert_formatter_outputs_equal` will understand
expected_outputs: dict = {}
#######
# implement these things:

def assert_formatter_outputs_equal(self, actual_output, expected_output):
"""raise AssertionError if the two outputs aren't equal
# a subclass of IndexcardDeriver
deriver_class: type

@param actual_output (str): return value of the formatter's `.format()` method
@param expected_output: corresponding value from this class's `expected_outputs` dictionary
"""
raise NotImplementedError
# dictionary with the same keys as `DERIVER_TEST_DOCS` and values that
# are either `SHOULD_SKIP` (above) or strings that will be passed as
# `expected_text` to `derived_texts_equal`
expected_outputs: dict

####### don't override anything else #######
# (optional override, for when equality isn't so easy)
def derived_texts_equal(self, expected_text: str, actual_text: str) -> bool:
return (expected_text == actual_text)

@classmethod
def setUpClass(cls):
assert DERIVER_TEST_INPUTS.keys() == cls.expected_outputs.keys(), f'check the test class\'s `expected_outputs` matches {__name__}.DERIVER_TEST_INPUTS'
#######
# don't override anything else

def setUp(self):
pass
def test_should_skip(self):
for _input_key, _deriver, _expected_output in self._iter_test_cases():
self.assertEqual(
bool(_expected_output is SHOULD_SKIP),
_deriver.should_skip(),
)

def test_outputs_for_inputs(self):
for _input_key, _expected_output in self.expected_outputs.items():
_input = DERIVER_TEST_INPUTS[_input_key]
with self.subTest(input_key=_input_key):
_actual_output = self._derive(_input)
self.assertEqual(_expected_output, _actual_output)

@pytest.fixture(scope='class')
def source_config(self, source, formatter_test_input, class_scoped_django_db):
return factories.SourceConfigFactory(
label=formatter_test_input['source_config_label'],
source=source,
)

@pytest.fixture(scope='class')
def suid(self, source_config, formatter_test_input, class_scoped_django_db):
return factories.SourceUniqueIdentifierFactory(
id=formatter_test_input['suid_id'],
identifier=formatter_test_input['suid_value'],
source_config=source_config,
)

@pytest.fixture(scope='class')
def normalized_datum(self, suid, source, formatter_test_input, class_scoped_django_db):
return factories.NormalizedDataFactory(
raw=factories.RawDatumFactory(
**formatter_test_input['raw_datum_kwargs'],
suid=suid,
),
**formatter_test_input['normalized_datum_kwargs'],
source__source=source,
)

def test_formatter(self, formatter, normalized_datum, expected_output):
actual_output = formatter.format(normalized_datum)
self.assert_formatter_outputs_equal(actual_output, expected_output)
def test_derive_card_as_text(self):
for _input_key, _deriver, _expected_output in self._iter_test_cases():
if _expected_output is not SHOULD_SKIP:
_output = _deriver.derive_card_as_text()
self.assertTrue(self.derived_texts_equal(_expected_output, _output))

def test_save_formatted_records(self, normalized_datum, expected_output):
saved_records = FormattedMetadataRecord.objects.save_formatted_records(
suid=normalized_datum.raw.suid,
record_formats=[self.deriver_iri],
normalized_datum=normalized_datum,
)
if expected_output is None:
assert len(saved_records) == 0
else:
assert len(saved_records) == 1
actual_output = saved_records[0].formatted_metadata
self.assert_formatter_outputs_equal(actual_output, expected_output)


@pytest.fixture(scope='module', params=FORMATTER_TEST_INPUTS.keys())
def _test_key(request):
return request.param


@pytest.fixture(scope='module')
def formatter_test_input(_test_key):
return FORMATTER_TEST_INPUTS[_test_key]
def _get_deriver(self, input_doc):
_mock_indexcard_rdf = mock.Mock()
_mock_indexcard_rdf.as_rdf_tripledict.return_value = input_doc
return self.deriver_class(_mock_indexcard_rdf)

def _iter_test_cases(self):
for _input_key, _input_doc in DERIVER_TEST_DOCS.items():
_expected_output = self.expected_outputs.get(_input_key)
if _expected_output is None:
raise NotImplementedError(f'{self.__class__.__qualname__}.expected_outputs["{_input_key}"]')
with self.subTest(input_key=_input_key):
yield (_input_key, self._get_deriver(_input_doc), _expected_output)
Loading

0 comments on commit 028c0cc

Please sign in to comment.