[GRASS-SVN] r61200 - in sandbox/wenzeslaus/gunittest: . testsuite

svn_grass at osgeo.org svn_grass at osgeo.org
Tue Jul 8 14:33:46 PDT 2014


Author: wenzeslaus
Date: 2014-07-08 14:33:46 -0700 (Tue, 08 Jul 2014)
New Revision: 61200

Modified:
   sandbox/wenzeslaus/gunittest/case.py
   sandbox/wenzeslaus/gunittest/gmodules.py
   sandbox/wenzeslaus/gunittest/testsuite/test_doctests.py
   sandbox/wenzeslaus/gunittest/testsuite/test_gmodules.py
Log:
gunittest: add class for convenient PyGRASS module creation (right parameters set), remove run module functions covered by call_module

Modified: sandbox/wenzeslaus/gunittest/case.py
===================================================================
--- sandbox/wenzeslaus/gunittest/case.py	2014-07-08 19:16:04 UTC (rev 61199)
+++ sandbox/wenzeslaus/gunittest/case.py	2014-07-08 21:33:46 UTC (rev 61200)
@@ -18,8 +18,9 @@
 from unittest.util import safe_repr
 
 from grass.pygrass.modules import Module
+from grass.exceptions import CalledModuleError
 
-from .gmodules import call_module, CalledModuleError
+from .gmodules import call_module
 from .checkers import (check_text_ellipsis,
                        text_to_keyvalue, compare_keyvalue, diff_keyvalue,
                        file_md5, files_equal_md5)
@@ -35,6 +36,7 @@
     the firt two, it is recommened to use keyword arguments but not required.
     """
     longMessage = True  # to get both standard and custom message
+    maxDiff = None  # we can afford long diffs
     _temp_region = None  # to control the temporary region
 
     def __init__(self, methodName):

Modified: sandbox/wenzeslaus/gunittest/gmodules.py
===================================================================
--- sandbox/wenzeslaus/gunittest/gmodules.py	2014-07-08 19:16:04 UTC (rev 61199)
+++ sandbox/wenzeslaus/gunittest/gmodules.py	2014-07-08 21:33:46 UTC (rev 61200)
@@ -1,86 +1,62 @@
 # -*- coding: utf-8 -*-
+"""!@package grass.gunittest.case
 
+ at brief GRASS Python testing framework specialized GRASS module interfaces
+
+(C) 2014 by the GRASS Development Team
+This program is free software under the GNU General Public
+License (>=v2). Read the file COPYING that comes with GRASS
+for details.
+
+ at author Vaclav Petras
+ at author Soeren Gebbert
+"""
+
 import subprocess
 from grass.script.core import start_command
+from grass.exceptions import CalledModuleError
+from grass.pygrass.modules import Module
 
 from .utils import do_doctest_gettext_workaround
 
 
-class CalledModuleError(subprocess.CalledProcessError):
-    def __init__(self, returncode, module, kwargs, errors=None):
-        # expecting module name to be args[0]
-        super(CalledModuleError, self).__init__(returncode, module)
-        # TODO: this must be somewhere when doctest is called, not here
-        # TODO: ultimate solution is not to use _ as a buildin in lib/python
-        # for now it is the only place where it works
-        do_doctest_gettext_workaround()
-        # TODO: format parameters
-        # TODO: ignore std* params
-        msg = _("Module run %s %s ended with error") % (module, kwargs)
-        msg += _("\nProcess ended with non-zero return code %s") % returncode
-        if errors:
-            msg += _(". See the following errors:\n%s") % errors
-        else:
-            msg += _(". See errors in the (error) output.")
-        self.msg = msg
-        # TODO: handle other parameters
+class SimpleModule(Module):
+    """Simple wrapper around pygrass.modules.Module to make sure that
+       run_, finish_, stdout and stderr are set correctly.
 
-    def __str__(self):
-        return self.msg
+    >>> mapcalc = SimpleModule('r.mapcalc', expression='test_a = 1',
+    ...                        overwrite=True)
+    >>> mapcalc.run()
+    Module('r.mapcalc')
+    >>> mapcalc.popen.returncode
+    0
 
-
-def run_module(module, **kwargs):
-    """Run module with parameters given in `kwargs`.
-
-    :param str module: module name
-    :param kwargs: module parameters
-
-    :raises CalledModuleError: if module return code is non-zero
+    >>> colors = SimpleModule('r.colors',
+    ...                       map='test_a', rules='-', stdin_='1 red')
+    >>> colors.run()
+    Module('r.colors')
+    >>> colors.popen.returncode
+    0
+    >>> str(colors.inputs.stdin)
+    '1 red'
+    >>> str(colors.outputs.stdout)
+    ''
+    >>> colors.outputs.stderr.strip()
+    "Color table for raster map <test_a> set to 'rules'"
     """
-    process = start_command(module, **kwargs)
-    returncode = process.wait()
-    if returncode:
-        raise CalledModuleError(returncode, module, kwargs)
+    def __init__(self, cmd, *args, **kargs):
+        for banned in ['stdout_', 'stderr_', 'finish_', 'run_']:
+            if banned in kargs:
+                raise ValueError('Do not set %s parameter'
+                                 ', it would be overriden' % banned)
+        kargs['stdout_'] = subprocess.PIPE
+        kargs['stderr_'] = subprocess.PIPE
+        kargs['finish_'] = True
+        kargs['run_'] = False
 
+        Module.__init__(self, cmd, *args, **kargs)
 
-def read_module(module, **kwargs):
-    """Run module with parameters given in `kwargs` and return its output.
 
-    :param str module: module name
-    :param kwargs: module parameters
-
-    :raises CalledModuleError: if module return code is non-zero
-    """
-    if 'stdout' in kwargs:
-        raise TypeError('stdout argument not allowed, it would be overridden.')
-    kwargs['stdout'] = subprocess.PIPE
-    process = start_command(module, **kwargs)
-    output = process.communicate()[0]
-    returncode = process.poll()
-    if returncode:
-        raise CalledModuleError(returncode, module, kwargs)
-    return output
-
-
-def write_module(module, stdin, **kwargs):
-    """Run module with given parameters and feed module standard input.
-
-    :param str module: module name
-    :param stdin: string to be used as module standard input (stdin)
-    :param kwargs: module parameters
-
-    :raises CalledModuleError: if module return code is non-zero
-    """
-    if not stdin:
-        raise ValueError('stdin argument is required.')
-    kwargs['stdin'] = subprocess.PIPE  # to be able to send data to stdin
-    process = start_command(module, **kwargs)
-    process.communicate(stdin)
-    returncode = process.poll()
-    if returncode:
-        raise CalledModuleError(returncode, module, kwargs)
-
-
 def call_module(module, stdin=None,
                 merge_stderr=False, capture_stdout=True, capture_stderr=True,
                 **kwargs):

Modified: sandbox/wenzeslaus/gunittest/testsuite/test_doctests.py
===================================================================
--- sandbox/wenzeslaus/gunittest/testsuite/test_doctests.py	2014-07-08 19:16:04 UTC (rev 61199)
+++ sandbox/wenzeslaus/gunittest/testsuite/test_doctests.py	2014-07-08 21:33:46 UTC (rev 61200)
@@ -6,6 +6,7 @@
 import doctest
 
 import gunittest
+import gunittest.utils
 
 
 # doctest does not allow changing the base classes of test case, skip test case
@@ -22,6 +23,10 @@
 
 
 def load_tests(loader, tests, ignore):
+    # TODO: this must be somewhere when doctest is called, not here
+    # TODO: ultimate solution is not to use _ as a buildin in lib/python
+    # for now it is the only place where it works
+    gunittest.utils.do_doctest_gettext_workaround()
     # this should be called at some top level
     tests.addTests(doctest.DocTestSuite(gunittest.gmodules))
     tests.addTests(doctest.DocTestSuite(gunittest.checkers))

Modified: sandbox/wenzeslaus/gunittest/testsuite/test_gmodules.py
===================================================================
--- sandbox/wenzeslaus/gunittest/testsuite/test_gmodules.py	2014-07-08 19:16:04 UTC (rev 61199)
+++ sandbox/wenzeslaus/gunittest/testsuite/test_gmodules.py	2014-07-08 21:33:46 UTC (rev 61200)
@@ -3,8 +3,7 @@
 import subprocess
 
 import gunittest
-from gunittest.gmodules import (call_module, CalledModuleError,
-                                run_module, read_module, write_module)
+from gunittest.gmodules import (call_module, CalledModuleError)
 
 G_REGION_OUTPUT = """n=...
 s=...
@@ -89,35 +88,5 @@
                           stderr='any_value_or_type_here')
 
 
-class ModuleFunctionsTest(gunittest.TestCase):
-
-    def test_run_module_raise(self):
-        self.assertRaises(CalledModuleError,
-                          run_module,
-                          'r.univar', aaabbbcc='notexist')
-
-    def test_read_module_return(self):
-        self.assertTrue(read_module('r.info', map='elevation'))
-
-    def test_read_module_raise(self):
-        self.assertRaises(CalledModuleError,
-                          read_module,
-                          'r.univar', aaabbbcc='notexist')
-
-    def test_write_module_missing_stdin(self):
-        self.assertRaises(TypeError,
-                          write_module,
-                          'm.proj', aaabbbcc='notexist')
-
-    def test_write_module_return(self):
-        self.assertIsNone(write_module('m.proj', input='-', stdin='50,50',
-                                       flags='o'))
-
-    def test_write_module_raise(self):
-        self.assertRaises(CalledModuleError,
-                          write_module,
-                          'm.proj', stdin='50,50', aaabbbcc='notexist')
-
-
 if __name__ == '__main__':
     gunittest.test()



More information about the grass-commit mailing list