[GRASS-SVN] r64662 - in grass/trunk/lib/python/gunittest: . testsuite
svn_grass at osgeo.org
svn_grass at osgeo.org
Tue Feb 17 08:42:58 PST 2015
Author: wenzeslaus
Date: 2015-02-17 08:42:58 -0800 (Tue, 17 Feb 2015)
New Revision: 64662
Modified:
grass/trunk/lib/python/gunittest/case.py
grass/trunk/lib/python/gunittest/main.py
grass/trunk/lib/python/gunittest/testsuite/test_assertions.py
Log:
gunittest: improvements to make it work better on MS Windows
* use short, although unreadable, map and file names to overcome problems with 260 character limit (MAX_PATH) of Win32 API (GPATH_MAX is 4096)
* override assertMultiLineEqual() to replace CRLF by LF, so that test authors can just use unix line endings
* register assertMultiLineEqual() for strings so that the CRLF replacement happens for assertEqual() as expected
* explicitly check for existence of a provided Location
Modified: grass/trunk/lib/python/gunittest/case.py
===================================================================
--- grass/trunk/lib/python/gunittest/case.py 2015-02-17 14:37:57 UTC (rev 64661)
+++ grass/trunk/lib/python/gunittest/case.py 2015-02-17 16:42:58 UTC (rev 64662)
@@ -12,7 +12,8 @@
import os
import subprocess
import StringIO
-
+import hashlib
+import uuid
import unittest
from grass.pygrass.modules import Module
@@ -39,11 +40,16 @@
maxDiff = None # we can afford long diffs
_temp_region = None # to control the temporary region
html_reports = False # output additional HTML files with failure details
+ readable_names = False # prefer shorter but unreadable map and file names
def __init__(self, methodName):
super(TestCase, self).__init__(methodName)
self.grass_modules = []
self.supplementary_files = []
+ # Python unittest doc is saying that strings use assertMultiLineEqual
+ # but only unicode type is registered
+ # TODO: report this as a bug? is this in Python 3.x?
+ self.addTypeEqualityFunc(str, 'assertMultiLineEqual')
def _formatMessage(self, msg, standardMsg):
"""Honor the longMessage attribute when generating failure messages.
@@ -129,6 +135,28 @@
# but we have zero chance of infuencing another test class
# since we use class-specific name for temporary region
+ def assertMultiLineEqual(self, first, second, msg=None):
+ r"""Test that the multiline string first is equal to the string second.
+
+ When not equal a diff of the two strings highlighting the differences
+ will be included in the error message. This method is used by default
+ when comparing strings with assertEqual().
+
+ This method replaces ``\r\n`` by ``\n`` in both parameters. This is
+ different from the same method implemented in Python ``unittest``
+ package which preserves the original line endings. This removes the
+ burden of getting the line endings right on each platfrom. You can
+ just use ``\n`` everywhere. However, note that ``\r`` is not supported.
+
+ .. warning::
+ If you need to test the actual line endings, use the standard
+ string comparison and functions such as ``find()``.
+ """
+ return super(TestCase, self).assertMultiLineEqual(
+ first=first.replace('\r\n', '\n'),
+ second=second.replace('\r\n', '\n'),
+ msg=None)
+
def assertLooksLike(self, actual, reference, msg=None):
"""Test that ``actual`` text is the same as ``referece`` with ellipses.
@@ -548,6 +576,26 @@
reference)
self.fail(self._formatMessage(msg, stdmsg))
+ def _get_unique_name(self, name):
+ """Create standardized map or file name which is unique
+
+ If ``readable_names`` attribute is `True`, it uses the *name* string
+ to create the unique name. Otherwise, it creates a unique name.
+ Even if you expect ``readable_names`` to be `True`, provide *name*
+ which is unique
+
+ The *name* parameter should be valid raster name, vector name and file
+ name and should be always provided.
+ """
+ # TODO: possible improvement is to require some descriptive name
+ # and ensure uniqueness by add UUID
+ if self.readable_names:
+ return 'tmp_' + self.id().replace('.', '_') + '_' + name
+ else:
+ # UUID might be overkill (and expensive) but it's safe and simple
+ # alternative is to create hash from the readable name
+ return 'tmp_' + str(uuid.uuid4()).replace('-', '')
+
def _compute_difference_raster(self, first, second, name_part):
"""Compute difference of two rasters (first - second)
@@ -560,8 +608,8 @@
:returns: name of a new raster
"""
- diff = ('tmp_' + self.id() + '_compute_difference_raster_'
- + name_part + '_' + first + '_minus_' + second)
+ diff = self._get_unique_name('compute_difference_raster_' + name_part
+ + '_' + first + '_minus_' + second)
call_module('r.mapcalc',
stdin='"{d}" = "{f}" - "{s}"'.format(d=diff,
f=first,
@@ -582,8 +630,9 @@
:returns: name of a new raster
"""
- diff = ('tmp_' + self.id() + '_compute_difference_raster_'
- + name_part + '_' + first + '_minus_' + second)
+ diff = self._get_unique_name('compute_difference_raster_' + name_part
+ + '_' + first + '_minus_' + second)
+
call_module('r3.mapcalc',
stdin='"{d}" = "{f}" - "{s}"'.format(d=diff,
f=first,
@@ -595,9 +644,9 @@
:returns: name of a new vector
"""
- diff = ('tmp_' + self.id() + '_compute_difference_vector_'
- + name_part + '_' + ainput + '_' + alayer
- + '_minus_' + binput + '_' + blayer)
+ diff = self._get_unique_name('compute_difference_vector_' + name_part
+ + '_' + ainput + '_' + alayer + '_minus_'
+ + binput + '_' + blayer)
call_module('v.overlay', operator='xor', ainput=ainput, binput=binput,
alayer=alayer, blayer=blayer,
output=diff, atype='area', btype='area', olayer='')
@@ -612,15 +661,13 @@
:returns: name of a new vector
"""
- import hashlib
# hash is the easiest way how to get a valied vector name
# TODO: introduce some function which will make file valid
hasher = hashlib.md5()
hasher.update(filename)
namehash = hasher.hexdigest()
- vector = ('tmp_' + self.id().replace('.', '_')
- + '_import_ascii_vector_'
- + name_part + '_' + namehash)
+ vector = self._get_unique_name('import_ascii_vector_' + name_part
+ + '_' + namehash)
call_module('v.in.ascii', input=filename,
output=vector, format='standard')
return vector
@@ -632,10 +679,11 @@
:returns: name of a new vector
"""
# TODO: perhaps we can afford just simple file name
- filename = ('tmp_' + self.id() + '_export_ascii_vector_'
- + name_part + '_' + vector)
+ filename = self._get_unique_name('export_ascii_vector_'
+ + name_part + '_' + vector)
call_module('v.out.ascii', input=vector,
- output=filename, format='standard', layer='-1', dp=digits)
+ output=filename, format='standard', layer='-1',
+ precision=digits)
return filename
def assertRastersNoDifference(self, actual, reference,
Modified: grass/trunk/lib/python/gunittest/main.py
===================================================================
--- grass/trunk/lib/python/gunittest/main.py 2015-02-17 14:37:57 UTC (rev 64661)
+++ grass/trunk/lib/python/gunittest/main.py 2015-02-17 16:42:58 UTC (rev 64662)
@@ -151,6 +151,11 @@
sys.stderr.write("GISDBASE (grassdata directory) <%s>"
" does not exist\n" % gisdbase)
sys.exit(1)
+ if not os.path.exists(os.path.join(gisdbase, location)):
+ sys.stderr.write("GRASS Location <{loc}>"
+ " does not exist in GRASS Database <{db}>\n".format(
+ location, gisdbase))
+ sys.exit(1)
results_dir = args.output
silent_rmtree(results_dir) # TODO: too brute force?
Modified: grass/trunk/lib/python/gunittest/testsuite/test_assertions.py
===================================================================
--- grass/trunk/lib/python/gunittest/testsuite/test_assertions.py 2015-02-17 14:37:57 UTC (rev 64661)
+++ grass/trunk/lib/python/gunittest/testsuite/test_assertions.py 2015-02-17 16:42:58 UTC (rev 64662)
@@ -44,7 +44,36 @@
"abc = 689.159589",
"abc = 689....")
+ def do_all_combidnations(self, first, second):
+ self.assertMultiLineEqual(first, first)
+ self.assertMultiLineEqual(first, second)
+ self.assertMultiLineEqual(second, first)
+ self.assertMultiLineEqual(second, second)
+ def test_assertMultiLineEqual(self):
+ unix_end = "aaa\nbbb\n"
+ mswindows_end = "aaa\r\nbbb\r\n"
+ self.do_all_combidnations(unix_end, mswindows_end)
+
+ def test_assertMultiLineEqual_raises(self):
+ """Test mixed line endings"""
+ self.assertRaises(self.failureException,
+ self.assertMultiLineEqual,
+ "aaa\n\rbbb\r",
+ "aaa\nbbb\n")
+
+ def test_assertEqual(self):
+ """Test for strings (uses overwritten assertMultiLineEqual())"""
+ unix_end = "aaa\nbbb\n"
+ mswindows_end = "aaa\r\nbbb\r\n"
+ self.do_all_combidnations(unix_end, mswindows_end)
+
+ self.assertRaises(self.failureException,
+ self.assertEqual,
+ "aaa\n\rbbb\r",
+ "aaa\nbbb\n")
+
+
R_UNIVAR_ELEVATION_SUBSET = """n=2025000
null_cells=0
min=55.5787925720215
More information about the grass-commit
mailing list