4646
4747from 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
5166if 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
299380def 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
353434def fixturefile_normname (relative_path , prefix = '' ):
0 commit comments