Moving the PHP Unit code to its own class
authorFrederic Massart <fred@moodle.com>
Tue, 4 Nov 2014 08:39:09 +0000 (16:39 +0800)
committerFrederic Massart <fred@moodle.com>
Tue, 4 Nov 2014 08:39:09 +0000 (16:39 +0800)
Hopefully not creating billions of regressions...

mdk/commands/phpunit.py
mdk/phpunit.py [new file with mode: 0644]

index b781ab1..74e0324 100644 (file)
@@ -28,6 +28,7 @@ import gzip
 import urllib
 from ..command import Command
 from ..tools import process, question
+from ..phpunit import PHPUnit
 
 
 class PhpunitCommand(Command):
@@ -98,11 +99,11 @@ class PhpunitCommand(Command):
         if args.testcase and M.branch_compare('26', '<'):
             self.argumentError('The --testcase option only works with Moodle 2.6 or greater.')
 
-        # Composer was introduced with PHP Unit, if the JSON file is there then we will use it
-        hasComposer = os.path.isfile(os.path.join(M.get('path'), 'composer.json'))
+        # Create the Unit test object.
+        PU = PHPUnit(self.Wp, M)
 
         # Install Composer
-        if hasComposer:
+        if PU.usesComposer():
             if not os.path.isfile(os.path.join(M.get('path'), 'composer.phar')):
                 logging.info('Installing Composer')
                 cliFile = 'phpunit_install_composer.php'
@@ -130,26 +131,18 @@ class PhpunitCommand(Command):
             else:
                 prefix = None
 
-            M.initPHPUnit(force=args.force, prefix=prefix)
-            logging.info('PHPUnit ready!')
+            PU.init(force=args.force, prefix=prefix)
 
-            cmd = []
-            if hasComposer:
-                cmd.append('vendor/bin/phpunit')
-            else:
-                cmd.append('phpunit')
-
-            if args.testcase:
-                cmd.append(args.testcase)
-            elif args.unittest:
-                cmd.append(args.unittest)
-            elif args.filter:
-                cmd.append('--filter="%s"' % args.filter)
+            kwargs = {
+                'testcase': args.testcase,
+                'unittest': args.unittest,
+                'filter': args.filter
+            }
 
             if args.run:
-                process(cmd, M.get('path'), None, None)
+                PU.run(**kwargs)
             else:
-                logging.info('Start PHPUnit:\n %s' % (' '.join(cmd)))
+                logging.info('Start PHPUnit:\n %s' % (' '.join(PU.getCommand(**kwargs))))
 
         except Exception as e:
             raise e
diff --git a/mdk/phpunit.py b/mdk/phpunit.py
new file mode 100644 (file)
index 0000000..4ac48b9
--- /dev/null
@@ -0,0 +1,117 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Moodle Development Kit
+
+Copyright (c) 2014 Frédéric Massart - FMCorz.net
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+http://github.com/FMCorz/mdk
+"""
+
+import logging
+import os
+from .config import Conf
+from .tools import mkdir, process
+
+C = Conf()
+
+
+class PHPUnit(object):
+    """Class wrapping PHPUnit functions"""
+
+    _M = None
+    _Wp = None
+
+    def __init__(self, Wp, M):
+        self._Wp = Wp
+        self._M = M
+
+    def getCommand(self, **kwargs):
+        """Get the PHPUnit command"""
+        cmd = []
+        if self.usesComposer():
+            cmd.append('vendor/bin/phpunit')
+        else:
+            cmd.append('phpunit')
+
+        if kwargs.get('testcase'):
+            cmd.append(kwargs.get('testcase'))
+        elif kwargs.get('unittest'):
+            cmd.append(kwargs.get('unittest'))
+        elif kwargs.get('filter'):
+            cmd.append('--filter="%s"' % kwargs.get('filter'))
+
+        return cmd
+
+    def init(self, force=False, prefix=None):
+        """Initialise the PHPUnit environment"""
+
+        if self.M.branch_compare(23, '<'):
+            raise Exception('PHPUnit is only available from Moodle 2.3')
+
+        # Set PHPUnit data root
+        phpunit_dataroot = self.M.get('dataroot') + '_phpu'
+        self.M.updateConfig('phpunit_dataroot', phpunit_dataroot)
+        if not os.path.isdir(phpunit_dataroot):
+            mkdir(phpunit_dataroot, 0777)
+
+        # Set PHPUnit prefix
+        currentPrefix = self.M.get('phpunit_prefix')
+        phpunit_prefix = prefix or 'phpu_'
+
+        if not currentPrefix or force:
+            self.M.updateConfig('phpunit_prefix', phpunit_prefix)
+        elif currentPrefix != phpunit_prefix and self.M.get('dbtype') != 'oci':
+            # Warn that a prefix is already set and we did not change it.
+            # No warning for Oracle as we need to set it to something else.
+            logging.warning('PHPUnit prefix not changed, already set to \'%s\', expected \'%s\'.' % (currentPrefix, phpunit_prefix))
+
+        result = (None, None, None)
+        exception = None
+        try:
+            if force:
+                result = self.M.cli('/admin/tool/phpunit/cli/util.php', args='--drop', stdout=None, stderr=None)
+            result = self.M.cli('/admin/tool/phpunit/cli/init.php', stdout=None, stderr=None)
+        except Exception as exception:
+            pass
+
+        if exception != None or result[0] > 0:
+            if result[0] == 129:
+                raise Exception('PHPUnit is not installed on your system')
+            elif result[0] > 0:
+                raise Exception('Something wrong with PHPUnit configuration')
+            else:
+                raise exception
+
+        logging.info('PHPUnit ready!')
+
+    def run(self, **kwargs):
+        """Execute the command"""
+        cmd = self.getCommand(**kwargs)
+        return process(cmd, self.M.get('path'), None, None)
+
+    def usesComposer(self):
+        """Return whether or not the instance uses composer, the latter is considered installed"""
+        return os.path.isfile(os.path.join(self.M.get('path'), 'composer.json'))
+
+    @property
+    def M(self):
+        return self._M
+
+    @property
+    def Wp(self):
+        return self._Wp