Skip to content

Commit 8d090b8

Browse files
committed
Embellish fixture assertions with the path.
1 parent 489d4d2 commit 8d090b8

File tree

3 files changed

+93
-14
lines changed

3 files changed

+93
-14
lines changed

tests/support/__init__.py

Lines changed: 83 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,21 @@
4646

4747
from tests.support._env import MIG_ENV, PY2
4848

49+
# Alow the use of SimpleNamespace on PY2.
50+
51+
if PY2:
52+
class SimpleNamespace(dict):
53+
"""Bare minimum SimpleNamespace for Python 2."""
54+
55+
def __getattribute__(self, name):
56+
if name == '__dict__':
57+
return dict(**self)
58+
59+
return self[name]
60+
else:
61+
from types import SimpleNamespace
62+
63+
4964
# Provide access to a configuration file for the active environment.
5065

5166
if MIG_ENV in ('local', 'docker'):
@@ -237,6 +252,9 @@ def assert_over(self, values=None, _AssertOver=AssertOver):
237252
self._register_check(check_callable)
238253
return assert_over
239254

255+
def temppath(self, relative_path, **kwargs):
256+
return temppath(relative_path, self, **kwargs)
257+
240258
# custom assertions available for common use
241259

242260
def assertFileContentIdentical(self, file_actual, file_expected):
@@ -295,6 +313,69 @@ def pretty_display_path(absolute_path):
295313
assert not relative_path.startswith('..')
296314
return relative_path
297315

316+
def prepareFixtureAssert(self, fixture_relpath, fixture_format=None):
317+
"""Prepare to assert a value against a fixture."""
318+
319+
fixture_data, fixture_path = fixturefile(
320+
fixture_relpath, fixture_format)
321+
return SimpleNamespace(
322+
assertAgainstFixture=lambda val: MigTestCase._assertAgainstFixture(
323+
self,
324+
fixture_format,
325+
fixture_data,
326+
fixture_path,
327+
value=val
328+
),
329+
copy_as_temp=lambda prefix: self._fixture_copy_as_temp(
330+
self,
331+
fixture_format,
332+
fixture_data,
333+
fixture_path,
334+
prefix=prefix
335+
)
336+
)
337+
338+
@staticmethod
339+
def _assertAgainstFixture(testcase, fixture_format, fixture_data, fixture_path, value=None):
340+
"""Compare a value against fixture data ensuring that in the case of
341+
failure the location of the fixture is prepended to the diff."""
342+
343+
assert value is not None
344+
originalMaxDiff = testcase.maxDiff
345+
testcase.maxDiff = None
346+
347+
raised_exception = None
348+
try:
349+
testcase.assertEqual(value, fixture_data)
350+
except AssertionError as diffexc:
351+
raised_exception = diffexc
352+
finally:
353+
testcase.maxDiff = originalMaxDiff
354+
if raised_exception:
355+
message = "value differed from fixture stored at %s\n\n%s" % (
356+
_to_display_path(fixture_path), raised_exception)
357+
raise AssertionError(message)
358+
359+
@staticmethod
360+
def _fixture_copy_as_temp(testcase, fixture_format, fixture_data, fixture_path, prefix=None):
361+
"""Copy a fixture to temporary file at the given path prefix."""
362+
363+
assert prefix is not None
364+
fixture_basename = os.path.basename(fixture_path)
365+
fixture_name = fixture_basename[0:-len(fixture_format) - 1]
366+
normalised_path = fixturefile_normname(fixture_name, prefix=prefix)
367+
copied_fixture_file = testcase.temppath(normalised_path)
368+
shutil.copyfile(fixture_path, copied_fixture_file)
369+
return copied_fixture_file
370+
371+
372+
def _to_display_path(value):
373+
"""Convert a relative path to one to be shown as part of test output."""
374+
display_path = os.path.relpath(value, MIG_BASE)
375+
if not display_path.startswith('.'):
376+
return "./" + display_path
377+
return display_path
378+
298379

299380
def is_path_within(path, start=None, _msg=None):
300381
"""Check if path is within start directory"""
@@ -316,7 +397,7 @@ def ensure_dirs_exist(absolute_dir):
316397
return absolute_dir
317398

318399

319-
def fixturefile(relative_path, fixture_format=None, include_path=False):
400+
def fixturefile(relative_path, fixture_format=None):
320401
"""Support function for loading fixtures from their serialised format.
321402
322403
Doing so is a little more involved than it may seem because serialisation
@@ -347,7 +428,7 @@ def fixturefile(relative_path, fixture_format=None, include_path=False):
347428
raise AssertionError(
348429
"unsupported fixture format: %s" % (fixture_format,))
349430

350-
return (data, tmp_path) if include_path else data
431+
return data, tmp_path
351432

352433

353434
def fixturefile_normname(relative_path, prefix=''):

tests/test_mig_shared_configuration.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
import os
3232
import unittest
3333

34-
from tests.support import MigTestCase, TEST_DATA_DIR, PY2, testmain, fixturefile
34+
from tests.support import MigTestCase, TEST_DATA_DIR, PY2, testmain
3535
from mig.shared.configuration import Configuration
3636

3737

@@ -71,7 +71,7 @@ def test_argument_wwwserve_max_bytes(self):
7171

7272
@unittest.skipIf(PY2, "Python 3 only")
7373
def test_default_object(self):
74-
expected_values = fixturefile(
74+
prepared_fixture = self.prepareFixtureAssert(
7575
'mig_shared_configuration--new', fixture_format='json')
7676

7777
configuration = Configuration(None)
@@ -84,8 +84,7 @@ def test_default_object(self):
8484

8585
actual_values = _to_dict(configuration)
8686

87-
self.maxDiff = None
88-
self.assertEqual(actual_values, expected_values)
87+
prepared_fixture.assertAgainstFixture(actual_values)
8988

9089
def test_object_isolation(self):
9190
configuration_1 = Configuration(None)

tests/test_mig_shared_functionality_cat.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
import unittest
3636

3737
from tests.support import MIG_BASE, PY2, TEST_DATA_DIR, MigTestCase, testmain, \
38-
fixturefile, fixturefile_normname, ensure_dirs_exist, temppath
38+
temppath, ensure_dirs_exist
3939

4040
from mig.shared.base import client_id_dir
4141
from mig.shared.functionality.cat import _main as submain, main as realmain
@@ -78,13 +78,12 @@ def before_each(self):
7878

7979
conf_user_db_home = ensure_dirs_exist(self.configuration.user_db_home)
8080
temppath(conf_user_db_home, self)
81-
db_fixture, db_fixture_file = fixturefile('MiG-users.db--example',
82-
fixture_format='binary',
83-
include_path=True)
84-
test_db_file = temppath(fixturefile_normname('MiG-users.db--example',
85-
prefix=conf_user_db_home),
86-
self)
87-
shutil.copyfile(db_fixture_file, test_db_file)
81+
prepared_fixture = self.prepareFixtureAssert(
82+
'MiG-users.db--example',
83+
fixture_format='binary',
84+
)
85+
86+
test_db_file = prepared_fixture.copy_as_temp(prefix=conf_user_db_home)
8887

8988
# create the test user home directory
9089
self.test_user_dir = ensure_dirs_exist(test_user_dir)

0 commit comments

Comments
 (0)