Bug 520148: [UnitTest] Unittest framework v2.0

  add support for python unittest style tests

Change-Id: Iae5082864cee63b3ab7988f4eef200d7bff2018d
diff --git a/plugins/org.eclipse.ease.lang.unittest/resources/testrunner/testrunner.JavaScript b/plugins/org.eclipse.ease.lang.unittest/resources/testrunner/testrunner.js
similarity index 100%
rename from plugins/org.eclipse.ease.lang.unittest/resources/testrunner/testrunner.JavaScript
rename to plugins/org.eclipse.ease.lang.unittest/resources/testrunner/testrunner.js
diff --git a/plugins/org.eclipse.ease.lang.unittest/resources/testrunner/testrunner.py b/plugins/org.eclipse.ease.lang.unittest/resources/testrunner/testrunner.py
new file mode 100644
index 0000000..737a5c1
--- /dev/null
+++ b/plugins/org.eclipse.ease.lang.unittest/resources/testrunner/testrunner.py
@@ -0,0 +1,135 @@
+import unittest
+import warnings
+import sys
+from unittest.signals import registerResult
+
+MOD_org_eclipse_ease_lang_unittest_UnitTestModule = loadModule("/Unittest")
+
+class EASETestResult(unittest.result.TestResult):
+    def __init__(self, stream, descriptions, verbosity):
+        super(EASETestResult, self).__init__(stream, descriptions, verbosity)
+        self.stream = stream
+        self.showAll = verbosity > 1
+        self.dots = verbosity == 1
+        self.descriptions = descriptions
+       
+    def getUnitTestModule(self):
+        return MOD_org_eclipse_ease_lang_unittest_UnitTestModule
+       
+    def startTest(self, test):
+        super(EASETestResult, self).startTest(test)
+        self.getUnitTestModule().startTest(test._testMethodName, test.shortDescription())
+       
+    def stopTest(self, test):
+        self.getUnitTestModule().endTest()
+ 
+    def addError(self, test, err):
+        try:
+            if (hasattr(err[1], 'java_exception')):
+                if ("org.eclipse.ease.lang.unittest.AssertionException" == err[1].java_exception.getClass().getName()):
+                    self.addFailure(test, (AssertionError, AssertionError(err[1].java_exception.getMessage()), err[2]))
+                    return
+        except:
+            pass
+
+        super(EASETestResult, self).addError(test, err)
+        self.addTestResult(org.eclipse.ease.lang.unittest.runtime.TestStatus.ERROR, str(err[0].__name__) + ": " + str(err[1]))
+ 
+    def addFailure(self, test, err):
+        super(EASETestResult, self).addFailure(test, err)
+        self.addTestResult(org.eclipse.ease.lang.unittest.runtime.TestStatus.FAILURE, str(err[1]))
+   
+    def addTestResult(self, type, message):
+        result = org.eclipse.ease.lang.unittest.runtime.IRuntimeFactory.eINSTANCE.createTestResult()
+        result.setStatus(type);
+        result.setMessage(message);
+       
+        try:
+            result.setStackTrace(getScriptEngine().getStackTrace())
+        except Exception:
+            print("could not set stacktrace")
+            pass
+       
+        self.getUnitTestModule().getCurrentTest().getResults().add(result);       
+    
+    def addSkip(self, test, reason):
+        super(EASETestResult, self).addSkip(test, reason)
+        self.addTestResult(org.eclipse.ease.lang.unittest.runtime.TestStatus.DISABLED, reason)
+ 
+    def addUnexpectedSuccess(self, test):
+        super(EASETestResult, self).addUnexpectedSuccess(test)
+        self.addTestResult(org.eclipse.ease.lang.unittest.runtime.TestStatus.FAILURE, "We expected an error")
+  
+class EASETestRunner(object):
+    """A test runner class that cooperates with the Eclipse EASE framework.
+    """
+    resultclass = EASETestResult
+
+    def __init__(self, stream=None, descriptions=True, verbosity=1,
+                 failfast=False, buffer=False, resultclass=None, warnings=None):
+        if stream is None:
+            stream = sys.stderr
+        
+        self.stream = stream
+        self.descriptions = descriptions
+        self.verbosity = verbosity
+        self.failfast = failfast
+        self.buffer = buffer
+        self.warnings = warnings
+        if resultclass is not None:
+            self.resultclass = resultclass
+
+    def _makeResult(self):
+        return self.resultclass(self.stream, self.descriptions, self.verbosity)
+
+    def run(self, test):
+        "Run the given test case or test suite."
+        result = self._makeResult()
+        registerResult(result)
+        result.failfast = self.failfast
+        result.buffer = self.buffer
+        with warnings.catch_warnings():
+            if self.warnings:
+                # if self.warnings is set, use it to filter all the warnings
+                warnings.simplefilter(self.warnings)
+                # if the filter is 'default' or 'always', special-case the
+                # warnings from the deprecated unittest methods to show them
+                # no more than once per module, because they can be fairly
+                # noisy.  The -Wd and -Wa flags can be used to bypass this
+                # only when self.warnings is None.
+                if self.warnings in ['default', 'always']:
+                    warnings.filterwarnings('module',
+                            category=DeprecationWarning,
+                            message='Please use assert\w+ instead.')
+            startTestRun = getattr(result, 'startTestRun', None)
+            if startTestRun is not None:
+                startTestRun()
+            try:
+                test(result)
+            finally:
+                stopTestRun = getattr(result, 'stopTestRun', None)
+                if stopTestRun is not None:
+                    stopTestRun()
+        result.printErrors()
+        run = result.testsRun
+
+        expectedFails = unexpectedSuccesses = skipped = 0
+        try:
+            results = map(len, (result.expectedFailures,
+                                result.unexpectedSuccesses,
+                                result.skipped))
+        except AttributeError:
+            pass
+        else:
+            expectedFails, unexpectedSuccesses, skipped = results
+
+        infos = []
+        return result
+   
+if __name__ == "__main__":
+    # Dynamically create test suite to combine test cases
+    tests = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+    testSuite = unittest.TestSuite(tests)
+    
+    runner = EASETestRunner()
+    runner.run(testSuite)
diff --git a/plugins/org.eclipse.ease.lang.unittest/resources/testrunner/testrunner_definitions.py b/plugins/org.eclipse.ease.lang.unittest/resources/testrunner/testrunner_definitions.py
new file mode 100644
index 0000000..2bfe9a9
--- /dev/null
+++ b/plugins/org.eclipse.ease.lang.unittest/resources/testrunner/testrunner_definitions.py
@@ -0,0 +1,14 @@
+import functools
+
+class timeout(object):
+
+    def __init__(self, timeout):
+        self.timeout = timeout        
+
+    def __call__(self, fn):
+        @functools.wraps(fn)
+        def decorated(*args, **kwargs):
+            MOD_org_eclipse_ease_lang_unittest_UnitTestModule.setTestTimeout(self.timeout)
+            fn(*args, **kwargs)
+            
+        return decorated
diff --git a/plugins/org.eclipse.ease.lang.unittest/src-gen/org/eclipse/ease/lang/unittest/runtime/impl/TestFile.java b/plugins/org.eclipse.ease.lang.unittest/src-gen/org/eclipse/ease/lang/unittest/runtime/impl/TestFile.java
index 0b7e98d..5762687 100644
--- a/plugins/org.eclipse.ease.lang.unittest/src-gen/org/eclipse/ease/lang/unittest/runtime/impl/TestFile.java
+++ b/plugins/org.eclipse.ease.lang.unittest/src-gen/org/eclipse/ease/lang/unittest/runtime/impl/TestFile.java
@@ -247,7 +247,7 @@
 							if (!fScriptEngine.hasVariable("__EASE_UnitTest_TestRunner")) {
 								// load the unittest runner
 								try {
-									final URL url = new URL("platform:/plugin/org.eclipse.ease.lang.unittest/resources/testrunner/testrunner.JavaScript");
+									final URL url = new URL("platform:/plugin/org.eclipse.ease.lang.unittest/resources/testrunner/testrunner.js");
 									executionResult = fScriptEngine.executeSync(url);
 									if (executionResult.hasException())
 										getTest("[EASE Testrunner]").addError(executionResult.getException().getMessage(), fScriptEngine);
@@ -256,6 +256,18 @@
 									getTest("[EASE Testrunner]").addError(e.getMessage(), fScriptEngine);
 								}
 							}
+
+						} else if (scriptType.getName().equals("Python")) {
+							// load the unittest runner
+							try {
+								final URL url = new URL("platform:/plugin/org.eclipse.ease.lang.unittest/resources/testrunner/testrunner.py");
+								executionResult = fScriptEngine.executeSync(url);
+								if (executionResult.hasException())
+									getTest("[EASE Testrunner]").addError(executionResult.getException().getMessage(), fScriptEngine);
+
+							} catch (final MalformedURLException e) {
+								getTest("[EASE Testrunner]").addError(e.getMessage(), fScriptEngine);
+							}
 						}
 					}
 				}