Merge commit '3b5069d' into develop
authorTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Fri, 30 Sep 2016 13:31:32 +0000 (16:31 +0300)
committerTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Fri, 30 Sep 2016 13:31:32 +0000 (16:31 +0300)
refs #6726

66 files changed:
bundles/org.simantics.tests.modelled.ontology/.classpath [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ontology/.project [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ontology/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ontology/META-INF/MANIFEST.MF [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ontology/build.properties [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ontology/graph.tg [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ontology/graph/Tests.pgraph [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ontology/graph/scl/SCLMain.scl [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ontology/src/org/simantics/tests/modelled/ontology/TestsResource.java [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui.ontology/.classpath [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui.ontology/.project [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui.ontology/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui.ontology/META-INF/MANIFEST.MF [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui.ontology/build.properties [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui.ontology/graph.tg [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui.ontology/graph/TestsUI.pgraph [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui.ontology/graph/images/test.png [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui.ontology/graph/images/tsuite.png [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui.ontology/graph/scl/SCLMain.scl [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui.ontology/src/org/simantics/tests/modelled/ui/ontology/TestsUIResource.java [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui/.classpath [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui/.project [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui/META-INF/MANIFEST.MF [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui/build.properties [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui/icons/greenbar.gif [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui/icons/redbar.gif [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui/icons/test.png [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui/icons/testerr.png [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui/icons/testfail.png [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui/icons/testok.png [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui/icons/testrun.png [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui/icons/tsuite.png [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui/icons/tsuiteerror.png [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui/icons/tsuitefail.png [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui/icons/tsuiteok.png [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui/icons/tsuiterun.png [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui/plugin.xml [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui/scl/Simantics/TestsUI.scl [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/Activator.java [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/CoverageViewSorter.java [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/RedGreenBar.java [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSCounterPanel.java [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSCoverageProvider.java [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSExecutionListener.java [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSProgressBar.java [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSTestEditor.java [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSTestEditorDocumentProvider.java [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSTestRunnerView.java [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSTestSuiteModel.java [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSTestSuiteProvider.java [new file with mode: 0644]
bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/TestsUIUtils.java [new file with mode: 0644]
bundles/org.simantics.tests.modelled/.classpath [new file with mode: 0644]
bundles/org.simantics.tests.modelled/.project [new file with mode: 0644]
bundles/org.simantics.tests.modelled/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
bundles/org.simantics.tests.modelled/META-INF/MANIFEST.MF [new file with mode: 0644]
bundles/org.simantics.tests.modelled/build.properties [new file with mode: 0644]
bundles/org.simantics.tests.modelled/scl/Simantics/Tests.scl [new file with mode: 0644]
bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/Activator.java [new file with mode: 0644]
bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/TestsGraphUtils.java [new file with mode: 0644]
features/org.simantics.tests.modelled.feature/.project [new file with mode: 0644]
features/org.simantics.tests.modelled.feature/build.properties [new file with mode: 0644]
features/org.simantics.tests.modelled.feature/feature.xml [new file with mode: 0644]
features/org.simantics.tests.modelled.ui.feature/.project [new file with mode: 0644]
features/org.simantics.tests.modelled.ui.feature/build.properties [new file with mode: 0644]
features/org.simantics.tests.modelled.ui.feature/feature.xml [new file with mode: 0644]

diff --git a/bundles/org.simantics.tests.modelled.ontology/.classpath b/bundles/org.simantics.tests.modelled.ontology/.classpath
new file mode 100644 (file)
index 0000000..b862a29
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>\r
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>\r
+       <classpathentry kind="src" path="src"/>\r
+       <classpathentry kind="output" path="bin"/>\r
+</classpath>\r
diff --git a/bundles/org.simantics.tests.modelled.ontology/.project b/bundles/org.simantics.tests.modelled.ontology/.project
new file mode 100644 (file)
index 0000000..a3e0b7a
--- /dev/null
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+       <name>org.simantics.tests.modelled.ontology</name>\r
+       <comment></comment>\r
+       <projects>\r
+       </projects>\r
+       <buildSpec>\r
+               <buildCommand>\r
+                       <name>org.simantics.graph.builder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.jdt.core.javabuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.ManifestBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.SchemaBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+       </buildSpec>\r
+       <natures>\r
+               <nature>org.eclipse.pde.PluginNature</nature>\r
+               <nature>org.eclipse.jdt.core.javanature</nature>\r
+               <nature>org.simantics.graph.nature</nature>\r
+       </natures>\r
+</projectDescription>\r
diff --git a/bundles/org.simantics.tests.modelled.ontology/.settings/org.eclipse.jdt.core.prefs b/bundles/org.simantics.tests.modelled.ontology/.settings/org.eclipse.jdt.core.prefs
new file mode 100644 (file)
index 0000000..295926d
--- /dev/null
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1\r
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled\r
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8\r
+org.eclipse.jdt.core.compiler.compliance=1.8\r
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error\r
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error\r
+org.eclipse.jdt.core.compiler.source=1.8\r
diff --git a/bundles/org.simantics.tests.modelled.ontology/META-INF/MANIFEST.MF b/bundles/org.simantics.tests.modelled.ontology/META-INF/MANIFEST.MF
new file mode 100644 (file)
index 0000000..2320422
--- /dev/null
@@ -0,0 +1,8 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: http://www.simantics.org/Tests
+Bundle-SymbolicName: org.simantics.tests.modelled.ontology
+Bundle-Version: 1.0.0.qualifier
+Require-Bundle: org.simantics.layer0
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Export-Package: org.simantics.tests.modelled.ontology
diff --git a/bundles/org.simantics.tests.modelled.ontology/build.properties b/bundles/org.simantics.tests.modelled.ontology/build.properties
new file mode 100644 (file)
index 0000000..022de17
--- /dev/null
@@ -0,0 +1,6 @@
+source.. = src/\r
+output.. = bin/\r
+bin.includes = plugin.xml,\\r
+               META-INF/,\\r
+               .,\\r
+               graph.tg\r
diff --git a/bundles/org.simantics.tests.modelled.ontology/graph.tg b/bundles/org.simantics.tests.modelled.ontology/graph.tg
new file mode 100644 (file)
index 0000000..6ffc03a
Binary files /dev/null and b/bundles/org.simantics.tests.modelled.ontology/graph.tg differ
diff --git a/bundles/org.simantics.tests.modelled.ontology/graph/Tests.pgraph b/bundles/org.simantics.tests.modelled.ontology/graph/Tests.pgraph
new file mode 100644 (file)
index 0000000..11b93d2
--- /dev/null
@@ -0,0 +1,20 @@
+L0 = <http://www.simantics.org/Layer0-1.1>
+
+
+TESTS = <http://www.simantics.org/Tests-1.0> : L0.Ontology
+    @L0.new
+    L0.HasResourceClass "org.simantics.tests.modelled.ontology.TestsResource"
+
+TESTS.SCLMain : L0.SCLModule
+    L0.SCLModule.definition _ : L0.String 
+      @L0.loadString "scl/SCLMain.scl" 
+
+TESTS.STSTest <T L0.Entity
+    >-- TESTS.STSTest.definition --> L0.String <R L0.HasProperty : L0.TotalFunction
+    >-- TESTS.STSTest.executionPriority --> L0.Integer <R L0.HasProperty : L0.TotalFunction
+    @L0.assert TESTS.STSTest.definition ""
+    @L0.assert TESTS.STSTest.executionPriority -1
+
+TESTS.STSSuite <T L0.Entity
+    >-- TESTS.STSSuite.moduleNameFilter --> L0.String <R L0.HasProperty : L0.TotalFunction
+    @L0.assert TESTS.STSSuite.moduleNameFilter ""
\ No newline at end of file
diff --git a/bundles/org.simantics.tests.modelled.ontology/graph/scl/SCLMain.scl b/bundles/org.simantics.tests.modelled.ontology/graph/scl/SCLMain.scl
new file mode 100644 (file)
index 0000000..285a298
--- /dev/null
@@ -0,0 +1 @@
+include "Simantics/Tests"
\ No newline at end of file
diff --git a/bundles/org.simantics.tests.modelled.ontology/src/org/simantics/tests/modelled/ontology/TestsResource.java b/bundles/org.simantics.tests.modelled.ontology/src/org/simantics/tests/modelled/ontology/TestsResource.java
new file mode 100644 (file)
index 0000000..bba4ead
--- /dev/null
@@ -0,0 +1,82 @@
+package org.simantics.tests.modelled.ontology;\r
+\r
+import org.simantics.db.RequestProcessor;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.db.Session;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.service.QueryControl;\r
+\r
+public class TestsResource {\r
+    \r
+    public final Resource SCLMain;\r
+    public final Resource STSSuite;\r
+    public final Resource STSSuite_moduleNameFilter;\r
+    public final Resource STSSuite_moduleNameFilter_Inverse;\r
+    public final Resource STSTest;\r
+    public final Resource STSTest_definition;\r
+    public final Resource STSTest_definition_Inverse;\r
+    public final Resource STSTest_executionPriority;\r
+    public final Resource STSTest_executionPriority_Inverse;\r
+        \r
+    public static class URIs {\r
+        public static final String SCLMain = "http://www.simantics.org/Tests-1.0/SCLMain";\r
+        public static final String STSSuite = "http://www.simantics.org/Tests-1.0/STSSuite";\r
+        public static final String STSSuite_moduleNameFilter = "http://www.simantics.org/Tests-1.0/STSSuite/moduleNameFilter";\r
+        public static final String STSSuite_moduleNameFilter_Inverse = "http://www.simantics.org/Tests-1.0/STSSuite/moduleNameFilter/Inverse";\r
+        public static final String STSTest = "http://www.simantics.org/Tests-1.0/STSTest";\r
+        public static final String STSTest_definition = "http://www.simantics.org/Tests-1.0/STSTest/definition";\r
+        public static final String STSTest_definition_Inverse = "http://www.simantics.org/Tests-1.0/STSTest/definition/Inverse";\r
+        public static final String STSTest_executionPriority = "http://www.simantics.org/Tests-1.0/STSTest/executionPriority";\r
+        public static final String STSTest_executionPriority_Inverse = "http://www.simantics.org/Tests-1.0/STSTest/executionPriority/Inverse";\r
+    }\r
+    \r
+    public static Resource getResourceOrNull(ReadGraph graph, String uri) {\r
+        try {\r
+            return graph.getResource(uri);\r
+        } catch(DatabaseException e) {\r
+            System.err.println(e.getMessage());\r
+            return null;\r
+        }\r
+    }\r
+    \r
+    public TestsResource(ReadGraph graph) {\r
+        SCLMain = getResourceOrNull(graph, URIs.SCLMain);\r
+        STSSuite = getResourceOrNull(graph, URIs.STSSuite);\r
+        STSSuite_moduleNameFilter = getResourceOrNull(graph, URIs.STSSuite_moduleNameFilter);\r
+        STSSuite_moduleNameFilter_Inverse = getResourceOrNull(graph, URIs.STSSuite_moduleNameFilter_Inverse);\r
+        STSTest = getResourceOrNull(graph, URIs.STSTest);\r
+        STSTest_definition = getResourceOrNull(graph, URIs.STSTest_definition);\r
+        STSTest_definition_Inverse = getResourceOrNull(graph, URIs.STSTest_definition_Inverse);\r
+        STSTest_executionPriority = getResourceOrNull(graph, URIs.STSTest_executionPriority);\r
+        STSTest_executionPriority_Inverse = getResourceOrNull(graph, URIs.STSTest_executionPriority_Inverse);\r
+    }\r
+    \r
+    public static TestsResource getInstance(ReadGraph graph) {\r
+        Session session = graph.getSession();\r
+        TestsResource ret = session.peekService(TestsResource.class);\r
+        if(ret == null) {\r
+            QueryControl qc = graph.getService(QueryControl.class);\r
+            ret = new TestsResource(qc.getIndependentGraph(graph));\r
+            session.registerService(TestsResource.class, ret);\r
+        }\r
+        return ret;\r
+    }\r
+    \r
+    public static TestsResource getInstance(RequestProcessor session) throws DatabaseException {\r
+        TestsResource ret = session.peekService(TestsResource.class);\r
+        if(ret == null) {\r
+            ret = session.syncRequest(new Read<TestsResource>() {\r
+                public TestsResource perform(ReadGraph graph) throws DatabaseException {\r
+                    QueryControl qc = graph.getService(QueryControl.class);\r
+                    return new TestsResource(qc.getIndependentGraph(graph));\r
+                }\r
+            });\r
+            session.registerService(TestsResource.class, ret);\r
+        }\r
+        return ret;\r
+    }\r
+    \r
+}\r
+\r
diff --git a/bundles/org.simantics.tests.modelled.ui.ontology/.classpath b/bundles/org.simantics.tests.modelled.ui.ontology/.classpath
new file mode 100644 (file)
index 0000000..b862a29
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>\r
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>\r
+       <classpathentry kind="src" path="src"/>\r
+       <classpathentry kind="output" path="bin"/>\r
+</classpath>\r
diff --git a/bundles/org.simantics.tests.modelled.ui.ontology/.project b/bundles/org.simantics.tests.modelled.ui.ontology/.project
new file mode 100644 (file)
index 0000000..fa169e5
--- /dev/null
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+       <name>org.simantics.tests.modelled.ui.ontology</name>\r
+       <comment></comment>\r
+       <projects>\r
+       </projects>\r
+       <buildSpec>\r
+               <buildCommand>\r
+                       <name>org.simantics.graph.builder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.jdt.core.javabuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.ManifestBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.SchemaBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+       </buildSpec>\r
+       <natures>\r
+               <nature>org.eclipse.pde.PluginNature</nature>\r
+               <nature>org.eclipse.jdt.core.javanature</nature>\r
+               <nature>org.simantics.graph.nature</nature>\r
+       </natures>\r
+</projectDescription>\r
diff --git a/bundles/org.simantics.tests.modelled.ui.ontology/.settings/org.eclipse.jdt.core.prefs b/bundles/org.simantics.tests.modelled.ui.ontology/.settings/org.eclipse.jdt.core.prefs
new file mode 100644 (file)
index 0000000..295926d
--- /dev/null
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1\r
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled\r
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8\r
+org.eclipse.jdt.core.compiler.compliance=1.8\r
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error\r
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error\r
+org.eclipse.jdt.core.compiler.source=1.8\r
diff --git a/bundles/org.simantics.tests.modelled.ui.ontology/META-INF/MANIFEST.MF b/bundles/org.simantics.tests.modelled.ui.ontology/META-INF/MANIFEST.MF
new file mode 100644 (file)
index 0000000..4ad1a0d
--- /dev/null
@@ -0,0 +1,13 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: http://www.simantics.org/TestsUI
+Bundle-SymbolicName: org.simantics.tests.modelled.ui.ontology
+Bundle-Version: 1.0.0.qualifier
+Require-Bundle: org.simantics.layer0,
+ org.simantics.tests.modelled.ontology;bundle-version="1.0.0",
+ org.simantics.viewpoint.ontology;bundle-version="1.2.0",
+ org.simantics.project.ontology;bundle-version="1.2.0",
+ org.simantics.modeling.ontology;bundle-version="1.2.0",
+ org.simantics.silk.ontology;bundle-version="1.1.0",
+ org.simantics.image2.ontology;bundle-version="1.2.0"
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
diff --git a/bundles/org.simantics.tests.modelled.ui.ontology/build.properties b/bundles/org.simantics.tests.modelled.ui.ontology/build.properties
new file mode 100644 (file)
index 0000000..815829b
--- /dev/null
@@ -0,0 +1,8 @@
+source.. = src/\r
+output.. = bin/\r
+bin.includes = plugin.xml,\\r
+               META-INF/,\\r
+               .,\\r
+               graph.tg,\\r
+               graph/scl/\r
+src.includes = graph/scl/\r
diff --git a/bundles/org.simantics.tests.modelled.ui.ontology/graph.tg b/bundles/org.simantics.tests.modelled.ui.ontology/graph.tg
new file mode 100644 (file)
index 0000000..c8b53e5
Binary files /dev/null and b/bundles/org.simantics.tests.modelled.ui.ontology/graph.tg differ
diff --git a/bundles/org.simantics.tests.modelled.ui.ontology/graph/TestsUI.pgraph b/bundles/org.simantics.tests.modelled.ui.ontology/graph/TestsUI.pgraph
new file mode 100644 (file)
index 0000000..6f7d89c
--- /dev/null
@@ -0,0 +1,74 @@
+L0 = <http://www.simantics.org/Layer0-1.1>
+TESTS = <http://www.simantics.org/Tests-1.0>
+VP = <http://www.simantics.org/Viewpoint-1.2>
+PROJECT = <http://www.simantics.org/Project-1.2>
+MOD = <http://www.simantics.org/Modeling-1.2>
+SILK = <http://www.simantics.org/Silk-1.1>
+IMAGE = <http://www.simantics.org/Image2-1.2>
+
+TestsUI = <http://www.simantics.org/TestsUI-1.0> : L0.Ontology
+    @L0.new
+    L0.HasResourceClass "org.simantics.tests.modelled.ui.ontology.TestsUIResource"
+
+TestsUI.SCLMain : L0.SCLModule
+    L0.SCLModule.definition _ : L0.String 
+      @L0.loadString "scl/SCLMain.scl" 
+
+TestsUI.testImage : IMAGE.PngImage
+  @L0.loadBytes "images/test.png"
+
+TestsUI.testSuiteImage : IMAGE.PngImage
+  @L0.loadBytes "images/tsuite.png"
+
+// Library containing all testing viewpoint contributions
+TestsUI.Contributions : L0.Library
+
+
+MBC = TestsUI.BrowseContext : VP.BrowseContext
+    VP.BrowseContext.IsIncludedIn PROJECT.ProjectBrowseContext
+
+MBC
+    @VP.namedRelationChildRule           TestsUI.Contributions.STSSuites L0.Entity   L0.ConsistsOf TESTS.STSSuite
+    @VP.namedConstantImageRule           TestsUI.Contributions.ModuleImage           TESTS.STSSuite                         TestsUI.testSuiteImage
+    @VP.namedRelationChildRule           TestsUI.Contributions.STSTests L0.Entity   L0.ConsistsOf TESTS.STSTest
+    @VP.namedConstantImageRule           TestsUI.Contributions.ModuleImage           TESTS.STSTest                         TestsUI.testImage
+
+MAC = TestsUI.ModelingActionContext : VP.BrowseContext
+    VP.BrowseContext.IsIncludedIn PROJECT.ProjectActionContext
+
+ACTIONS = MAC.Actions : L0.Library
+
+ACTIONS.NewSTSSuite
+  @MOD.sclAction "createSTSSuiteAction"
+ACTIONS.NewSTSTest
+  @MOD.sclAction "createSTSTestAction"
+ACTIONS.RunSTSTest
+  @MOD.sclAction "runSTSTestAction"
+
+MAC
+    VP.BrowseContext.HasActionContribution TestsUI.Contributions.NewSTSSuite : VP.ActionContribution
+        L0.HasLabel "STS Suite"
+        VP.ActionContribution.HasImage TestsUI.testSuiteImage
+        VP.ActionContribution.HasCategory VP.NewActionCategory
+        VP.ActionContribution.HasNodeType
+            L0.Library
+        VP.ActionContribution.HasAction ACTIONS.NewSTSSuite
+    VP.BrowseContext.HasActionContribution TestsUI.Contributions.NewSTSTest : VP.ActionContribution
+        L0.HasLabel "STS Test"
+        VP.ActionContribution.HasImage TestsUI.testImage
+        VP.ActionContribution.HasCategory VP.NewActionCategory
+        VP.ActionContribution.HasNodeType
+            TESTS.STSSuite
+        VP.ActionContribution.HasAction ACTIONS.NewSTSTest
+    VP.BrowseContext.HasActionContribution _ : VP.ActionContribution
+        L0.HasLabel "Run"
+        VP.ActionContribution.HasImage SILK.control_play
+        VP.ActionContribution.HasCategory VP.EditActionCategory
+        VP.ActionContribution.HasNodeType TESTS.STSSuite
+        VP.ActionContribution.HasAction ACTIONS.RunSTSTest
+    VP.BrowseContext.HasActionContribution _ : VP.ActionContribution
+        L0.HasLabel "Run"
+        VP.ActionContribution.HasImage SILK.control_play
+        VP.ActionContribution.HasCategory VP.EditActionCategory
+        VP.ActionContribution.HasNodeType TESTS.STSTest
+        VP.ActionContribution.HasAction ACTIONS.RunSTSTest
\ No newline at end of file
diff --git a/bundles/org.simantics.tests.modelled.ui.ontology/graph/images/test.png b/bundles/org.simantics.tests.modelled.ui.ontology/graph/images/test.png
new file mode 100644 (file)
index 0000000..b74a9fc
Binary files /dev/null and b/bundles/org.simantics.tests.modelled.ui.ontology/graph/images/test.png differ
diff --git a/bundles/org.simantics.tests.modelled.ui.ontology/graph/images/tsuite.png b/bundles/org.simantics.tests.modelled.ui.ontology/graph/images/tsuite.png
new file mode 100644 (file)
index 0000000..b7efb0a
Binary files /dev/null and b/bundles/org.simantics.tests.modelled.ui.ontology/graph/images/tsuite.png differ
diff --git a/bundles/org.simantics.tests.modelled.ui.ontology/graph/scl/SCLMain.scl b/bundles/org.simantics.tests.modelled.ui.ontology/graph/scl/SCLMain.scl
new file mode 100644 (file)
index 0000000..1e41eb2
--- /dev/null
@@ -0,0 +1 @@
+include "Simantics/TestsUI"
\ No newline at end of file
diff --git a/bundles/org.simantics.tests.modelled.ui.ontology/src/org/simantics/tests/modelled/ui/ontology/TestsUIResource.java b/bundles/org.simantics.tests.modelled.ui.ontology/src/org/simantics/tests/modelled/ui/ontology/TestsUIResource.java
new file mode 100644 (file)
index 0000000..4aa14a7
--- /dev/null
@@ -0,0 +1,100 @@
+package org.simantics.tests.modelled.ui.ontology;\r
+\r
+import org.simantics.db.RequestProcessor;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.db.Session;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.service.QueryControl;\r
+\r
+public class TestsUIResource {\r
+    \r
+    public final Resource BrowseContext;\r
+    public final Resource Contributions;\r
+    public final Resource Contributions_ModuleImage;\r
+    public final Resource Contributions_NewSTSSuite;\r
+    public final Resource Contributions_NewSTSTest;\r
+    public final Resource Contributions_STSSuites;\r
+    public final Resource Contributions_STSTests;\r
+    public final Resource ModelingActionContext;\r
+    public final Resource ModelingActionContext_Actions;\r
+    public final Resource ModelingActionContext_Actions_NewSTSSuite;\r
+    public final Resource ModelingActionContext_Actions_NewSTSTest;\r
+    public final Resource ModelingActionContext_Actions_RunSTSTest;\r
+    public final Resource SCLMain;\r
+    public final Resource testImage;\r
+    public final Resource testSuiteImage;\r
+        \r
+    public static class URIs {\r
+        public static final String BrowseContext = "http://www.simantics.org/TestsUI-1.0/BrowseContext";\r
+        public static final String Contributions = "http://www.simantics.org/TestsUI-1.0/Contributions";\r
+        public static final String Contributions_ModuleImage = "http://www.simantics.org/TestsUI-1.0/Contributions/ModuleImage";\r
+        public static final String Contributions_NewSTSSuite = "http://www.simantics.org/TestsUI-1.0/Contributions/NewSTSSuite";\r
+        public static final String Contributions_NewSTSTest = "http://www.simantics.org/TestsUI-1.0/Contributions/NewSTSTest";\r
+        public static final String Contributions_STSSuites = "http://www.simantics.org/TestsUI-1.0/Contributions/STSSuites";\r
+        public static final String Contributions_STSTests = "http://www.simantics.org/TestsUI-1.0/Contributions/STSTests";\r
+        public static final String ModelingActionContext = "http://www.simantics.org/TestsUI-1.0/ModelingActionContext";\r
+        public static final String ModelingActionContext_Actions = "http://www.simantics.org/TestsUI-1.0/ModelingActionContext/Actions";\r
+        public static final String ModelingActionContext_Actions_NewSTSSuite = "http://www.simantics.org/TestsUI-1.0/ModelingActionContext/Actions/NewSTSSuite";\r
+        public static final String ModelingActionContext_Actions_NewSTSTest = "http://www.simantics.org/TestsUI-1.0/ModelingActionContext/Actions/NewSTSTest";\r
+        public static final String ModelingActionContext_Actions_RunSTSTest = "http://www.simantics.org/TestsUI-1.0/ModelingActionContext/Actions/RunSTSTest";\r
+        public static final String SCLMain = "http://www.simantics.org/TestsUI-1.0/SCLMain";\r
+        public static final String testImage = "http://www.simantics.org/TestsUI-1.0/testImage";\r
+        public static final String testSuiteImage = "http://www.simantics.org/TestsUI-1.0/testSuiteImage";\r
+    }\r
+    \r
+    public static Resource getResourceOrNull(ReadGraph graph, String uri) {\r
+        try {\r
+            return graph.getResource(uri);\r
+        } catch(DatabaseException e) {\r
+            System.err.println(e.getMessage());\r
+            return null;\r
+        }\r
+    }\r
+    \r
+    public TestsUIResource(ReadGraph graph) {\r
+        BrowseContext = getResourceOrNull(graph, URIs.BrowseContext);\r
+        Contributions = getResourceOrNull(graph, URIs.Contributions);\r
+        Contributions_ModuleImage = getResourceOrNull(graph, URIs.Contributions_ModuleImage);\r
+        Contributions_NewSTSSuite = getResourceOrNull(graph, URIs.Contributions_NewSTSSuite);\r
+        Contributions_NewSTSTest = getResourceOrNull(graph, URIs.Contributions_NewSTSTest);\r
+        Contributions_STSSuites = getResourceOrNull(graph, URIs.Contributions_STSSuites);\r
+        Contributions_STSTests = getResourceOrNull(graph, URIs.Contributions_STSTests);\r
+        ModelingActionContext = getResourceOrNull(graph, URIs.ModelingActionContext);\r
+        ModelingActionContext_Actions = getResourceOrNull(graph, URIs.ModelingActionContext_Actions);\r
+        ModelingActionContext_Actions_NewSTSSuite = getResourceOrNull(graph, URIs.ModelingActionContext_Actions_NewSTSSuite);\r
+        ModelingActionContext_Actions_NewSTSTest = getResourceOrNull(graph, URIs.ModelingActionContext_Actions_NewSTSTest);\r
+        ModelingActionContext_Actions_RunSTSTest = getResourceOrNull(graph, URIs.ModelingActionContext_Actions_RunSTSTest);\r
+        SCLMain = getResourceOrNull(graph, URIs.SCLMain);\r
+        testImage = getResourceOrNull(graph, URIs.testImage);\r
+        testSuiteImage = getResourceOrNull(graph, URIs.testSuiteImage);\r
+    }\r
+    \r
+    public static TestsUIResource getInstance(ReadGraph graph) {\r
+        Session session = graph.getSession();\r
+        TestsUIResource ret = session.peekService(TestsUIResource.class);\r
+        if(ret == null) {\r
+            QueryControl qc = graph.getService(QueryControl.class);\r
+            ret = new TestsUIResource(qc.getIndependentGraph(graph));\r
+            session.registerService(TestsUIResource.class, ret);\r
+        }\r
+        return ret;\r
+    }\r
+    \r
+    public static TestsUIResource getInstance(RequestProcessor session) throws DatabaseException {\r
+        TestsUIResource ret = session.peekService(TestsUIResource.class);\r
+        if(ret == null) {\r
+            ret = session.syncRequest(new Read<TestsUIResource>() {\r
+                public TestsUIResource perform(ReadGraph graph) throws DatabaseException {\r
+                    QueryControl qc = graph.getService(QueryControl.class);\r
+                    return new TestsUIResource(qc.getIndependentGraph(graph));\r
+                }\r
+            });\r
+            session.registerService(TestsUIResource.class, ret);\r
+        }\r
+        return ret;\r
+    }\r
+    \r
+}\r
+\r
diff --git a/bundles/org.simantics.tests.modelled.ui/.classpath b/bundles/org.simantics.tests.modelled.ui/.classpath
new file mode 100644 (file)
index 0000000..b862a29
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>\r
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>\r
+       <classpathentry kind="src" path="src"/>\r
+       <classpathentry kind="output" path="bin"/>\r
+</classpath>\r
diff --git a/bundles/org.simantics.tests.modelled.ui/.project b/bundles/org.simantics.tests.modelled.ui/.project
new file mode 100644 (file)
index 0000000..d0d29d7
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+       <name>org.simantics.tests.modelled.ui</name>\r
+       <comment></comment>\r
+       <projects>\r
+       </projects>\r
+       <buildSpec>\r
+               <buildCommand>\r
+                       <name>org.eclipse.jdt.core.javabuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.ManifestBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.SchemaBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+       </buildSpec>\r
+       <natures>\r
+               <nature>org.eclipse.pde.PluginNature</nature>\r
+               <nature>org.eclipse.jdt.core.javanature</nature>\r
+       </natures>\r
+</projectDescription>\r
diff --git a/bundles/org.simantics.tests.modelled.ui/.settings/org.eclipse.jdt.core.prefs b/bundles/org.simantics.tests.modelled.ui/.settings/org.eclipse.jdt.core.prefs
new file mode 100644 (file)
index 0000000..295926d
--- /dev/null
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1\r
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled\r
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8\r
+org.eclipse.jdt.core.compiler.compliance=1.8\r
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error\r
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error\r
+org.eclipse.jdt.core.compiler.source=1.8\r
diff --git a/bundles/org.simantics.tests.modelled.ui/META-INF/MANIFEST.MF b/bundles/org.simantics.tests.modelled.ui/META-INF/MANIFEST.MF
new file mode 100644 (file)
index 0000000..e9aba00
--- /dev/null
@@ -0,0 +1,20 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Simantics Modelled Tests UI
+Bundle-SymbolicName: org.simantics.tests.modelled.ui;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.simantics.tests.modelled.ui.Activator
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.ui.editors;bundle-version="3.9.0",
+ org.eclipse.jface.text;bundle-version="3.10.0",
+ org.eclipse.core.runtime,
+ org.simantics.modeling.ui,
+ org.simantics.scl.ui,
+ org.simantics.tests.modelled.ontology,
+ org.eclipse.e4.ui.di,
+ org.simantics.tests.modelled.ui.ontology;bundle-version="1.0.0",
+ org.simantics.tests.modelled;bundle-version="1.0.0",
+ org.eclipse.e4.ui.model.workbench,
+ org.simantics.scl.osgi
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Bundle-ActivationPolicy: lazy
diff --git a/bundles/org.simantics.tests.modelled.ui/build.properties b/bundles/org.simantics.tests.modelled.ui/build.properties
new file mode 100644 (file)
index 0000000..c54907f
--- /dev/null
@@ -0,0 +1,7 @@
+source.. = src/\r
+output.. = bin/\r
+bin.includes = META-INF/,\\r
+               .,\\r
+               plugin.xml,\\r
+               scl/\r
+src.includes = scl/\r
diff --git a/bundles/org.simantics.tests.modelled.ui/icons/greenbar.gif b/bundles/org.simantics.tests.modelled.ui/icons/greenbar.gif
new file mode 100644 (file)
index 0000000..0ba6567
Binary files /dev/null and b/bundles/org.simantics.tests.modelled.ui/icons/greenbar.gif differ
diff --git a/bundles/org.simantics.tests.modelled.ui/icons/redbar.gif b/bundles/org.simantics.tests.modelled.ui/icons/redbar.gif
new file mode 100644 (file)
index 0000000..c2f7146
Binary files /dev/null and b/bundles/org.simantics.tests.modelled.ui/icons/redbar.gif differ
diff --git a/bundles/org.simantics.tests.modelled.ui/icons/test.png b/bundles/org.simantics.tests.modelled.ui/icons/test.png
new file mode 100644 (file)
index 0000000..b74a9fc
Binary files /dev/null and b/bundles/org.simantics.tests.modelled.ui/icons/test.png differ
diff --git a/bundles/org.simantics.tests.modelled.ui/icons/testerr.png b/bundles/org.simantics.tests.modelled.ui/icons/testerr.png
new file mode 100644 (file)
index 0000000..e46c875
Binary files /dev/null and b/bundles/org.simantics.tests.modelled.ui/icons/testerr.png differ
diff --git a/bundles/org.simantics.tests.modelled.ui/icons/testfail.png b/bundles/org.simantics.tests.modelled.ui/icons/testfail.png
new file mode 100644 (file)
index 0000000..057698b
Binary files /dev/null and b/bundles/org.simantics.tests.modelled.ui/icons/testfail.png differ
diff --git a/bundles/org.simantics.tests.modelled.ui/icons/testok.png b/bundles/org.simantics.tests.modelled.ui/icons/testok.png
new file mode 100644 (file)
index 0000000..5977335
Binary files /dev/null and b/bundles/org.simantics.tests.modelled.ui/icons/testok.png differ
diff --git a/bundles/org.simantics.tests.modelled.ui/icons/testrun.png b/bundles/org.simantics.tests.modelled.ui/icons/testrun.png
new file mode 100644 (file)
index 0000000..8d8d6f5
Binary files /dev/null and b/bundles/org.simantics.tests.modelled.ui/icons/testrun.png differ
diff --git a/bundles/org.simantics.tests.modelled.ui/icons/tsuite.png b/bundles/org.simantics.tests.modelled.ui/icons/tsuite.png
new file mode 100644 (file)
index 0000000..b7efb0a
Binary files /dev/null and b/bundles/org.simantics.tests.modelled.ui/icons/tsuite.png differ
diff --git a/bundles/org.simantics.tests.modelled.ui/icons/tsuiteerror.png b/bundles/org.simantics.tests.modelled.ui/icons/tsuiteerror.png
new file mode 100644 (file)
index 0000000..14cb1af
Binary files /dev/null and b/bundles/org.simantics.tests.modelled.ui/icons/tsuiteerror.png differ
diff --git a/bundles/org.simantics.tests.modelled.ui/icons/tsuitefail.png b/bundles/org.simantics.tests.modelled.ui/icons/tsuitefail.png
new file mode 100644 (file)
index 0000000..0dd6ee3
Binary files /dev/null and b/bundles/org.simantics.tests.modelled.ui/icons/tsuitefail.png differ
diff --git a/bundles/org.simantics.tests.modelled.ui/icons/tsuiteok.png b/bundles/org.simantics.tests.modelled.ui/icons/tsuiteok.png
new file mode 100644 (file)
index 0000000..f7a6020
Binary files /dev/null and b/bundles/org.simantics.tests.modelled.ui/icons/tsuiteok.png differ
diff --git a/bundles/org.simantics.tests.modelled.ui/icons/tsuiterun.png b/bundles/org.simantics.tests.modelled.ui/icons/tsuiterun.png
new file mode 100644 (file)
index 0000000..e8ddc30
Binary files /dev/null and b/bundles/org.simantics.tests.modelled.ui/icons/tsuiterun.png differ
diff --git a/bundles/org.simantics.tests.modelled.ui/plugin.xml b/bundles/org.simantics.tests.modelled.ui/plugin.xml
new file mode 100644 (file)
index 0000000..fc04f9e
--- /dev/null
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<?eclipse version="3.4"?>\r
+<plugin>\r
+   <extension\r
+         point="org.eclipse.ui.editors">\r
+      <editor\r
+            default="false"\r
+            name="STS Test Editor"\r
+            class="org.simantics.tests.modelled.ui.STSTestEditor"\r
+            id="org.simantics.tests.ui.stsTestEditor">\r
+      </editor>\r
+   </extension>\r
+   <extension\r
+         point="org.eclipse.core.expressions.definitions">\r
+      <definition\r
+            id="org.simantics.tests.ui.inSTSTestEditor">\r
+         <with\r
+               variable="activePartId">\r
+            <equals\r
+                  value="org.simantics.tests.ui.stsTestEditor">\r
+            </equals>\r
+         </with>\r
+      </definition>\r
+   </extension>\r
+   <extension\r
+         point="org.simantics.ui.resourceEditorAdapter">\r
+       <adapter\r
+            label="STS Test Editor"\r
+            priority="1"\r
+            editorId="org.simantics.tests.ui.stsTestEditor"\r
+            type_uris="http://www.simantics.org/Tests-1.0/STSTest">\r
+      </adapter>\r
+   </extension>\r
+   <extension\r
+         point="org.eclipse.ui.views">\r
+      <e4view\r
+            class="org.simantics.tests.modelled.ui.STSTestRunnerView"\r
+            id="org.simantics.tests.ui.stsTestRunnerView"\r
+            name="STS Test Runner View"\r
+            restorable="true">\r
+      </e4view>\r
+   </extension>\r
+\r
+</plugin>\r
diff --git a/bundles/org.simantics.tests.modelled.ui/scl/Simantics/TestsUI.scl b/bundles/org.simantics.tests.modelled.ui/scl/Simantics/TestsUI.scl
new file mode 100644 (file)
index 0000000..428c18f
--- /dev/null
@@ -0,0 +1,14 @@
+include "Simantics/Tests"\r
+\r
+createSTSTestAction :: Resource -> <Proc> ()\r
+createSTSTestAction res = do\r
+  syncWrite (\() -> createSTSTest res)\r
+  ()\r
+\r
+importJava "org.simantics.tests.ui.TestsUIUtils" where\r
+    runSTSTestAction :: Resource -> <Proc> ()\r
+    \r
+createSTSSuiteAction :: Resource -> <Proc> ()\r
+createSTSSuiteAction res = do\r
+  syncWrite (\() -> createSTSSuite res)\r
+  ()
\ No newline at end of file
diff --git a/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/Activator.java b/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/Activator.java
new file mode 100644 (file)
index 0000000..4349852
--- /dev/null
@@ -0,0 +1,73 @@
+package org.simantics.tests.modelled.ui;\r
+\r
+import java.net.URL;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.eclipse.jface.resource.ImageDescriptor;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.ui.plugin.AbstractUIPlugin;\r
+import org.osgi.framework.BundleContext;\r
+\r
+/**\r
+ * The activator class controls the plug-in life cycle\r
+ */\r
+public class Activator extends AbstractUIPlugin {\r
+\r
+       // The plug-in ID\r
+       public static final String PLUGIN_ID = "org.simantics.tests.modelled.ui"; //$NON-NLS-1$\r
+\r
+       // The shared instance\r
+       private static Activator plugin;\r
+       \r
+       /**\r
+        * The constructor\r
+        */\r
+       public Activator() {\r
+       }\r
+\r
+       /*\r
+        * (non-Javadoc)\r
+        * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)\r
+        */\r
+       public void start(BundleContext context) throws Exception {\r
+               super.start(context);\r
+               plugin = this;\r
+       }\r
+\r
+       /*\r
+        * (non-Javadoc)\r
+        * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)\r
+        */\r
+       public void stop(BundleContext context) throws Exception {\r
+               plugin = null;\r
+               for (Image image : imagesToDispose)\r
+                   image.dispose();\r
+               super.stop(context);\r
+       }\r
+\r
+       /**\r
+        * Returns the shared instance\r
+        *\r
+        * @return the shared instance\r
+        */\r
+       public static Activator getDefault() {\r
+               return plugin;\r
+       }\r
+\r
+    public static ImageDescriptor getImageDescriptor(String relativePath) {\r
+        URL url = getDefault().getBundle().getEntry(relativePath);\r
+        return ImageDescriptor.createFromURL(url);\r
+    }\r
+    \r
+    private static List<Image> imagesToDispose = new ArrayList<>();\r
+\r
+    public static Image createManagedImage(ImageDescriptor descriptor) {\r
+        Image image= descriptor.createImage();\r
+        if (image == null) {\r
+            image= ImageDescriptor.getMissingImageDescriptor().createImage();\r
+        }\r
+        imagesToDispose.add(image);\r
+        return image;\r
+    }\r
+}\r
diff --git a/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/CoverageViewSorter.java b/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/CoverageViewSorter.java
new file mode 100644 (file)
index 0000000..b1a1413
--- /dev/null
@@ -0,0 +1,97 @@
+package org.simantics.tests.modelled.ui;\r
+\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+import org.eclipse.jface.viewers.TreeViewer;\r
+import org.eclipse.jface.viewers.TreeViewerColumn;\r
+import org.eclipse.jface.viewers.Viewer;\r
+import org.eclipse.jface.viewers.ViewerComparator;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.events.SelectionListener;\r
+import org.eclipse.swt.widgets.TreeColumn;\r
+import org.simantics.scl.compiler.module.coverage.Coverage;\r
+\r
+class CoverageViewSorter extends ViewerComparator {\r
+\r
+    private final TreeViewer viewer;\r
+\r
+    public CoverageViewSorter(TreeViewer viewer) {\r
+        this.viewer = viewer;\r
+    }\r
+\r
+    private Map<TreeColumn, Integer> columns = new HashMap<>();\r
+    private int currentDirection;\r
+    \r
+    void addColumn(final TreeViewerColumn viewerColumn, final int columnidx) {\r
+        final TreeColumn column = viewerColumn.getColumn();\r
+        setSortColumnAndDirection(column, SWT.UP);\r
+        column.addSelectionListener(new SelectionListener() {\r
+\r
+            public void widgetSelected(SelectionEvent e) {\r
+                TreeColumn current = column.getParent().getSortColumn();\r
+                if (current.equals(column)) {\r
+                    int sortDirection = column.getParent().getSortDirection();\r
+                    setSortColumnAndDirection(column, sortDirection != SWT.DOWN ? SWT.DOWN : SWT.UP);\r
+                } else {\r
+                    setSortColumnAndDirection(column, SWT.DOWN);\r
+                }\r
+                viewer.refresh();\r
+            }\r
+\r
+            public void widgetDefaultSelected(SelectionEvent e) {\r
+            }\r
+        });\r
+        columns.put(column, columnidx);\r
+    }\r
+\r
+    private void setSortColumnAndDirection(TreeColumn sortColumn, int direction) {\r
+        currentDirection = direction;\r
+        sortColumn.getParent().setSortColumn(sortColumn);\r
+        sortColumn.getParent().setSortDirection(direction);\r
+    }\r
+\r
+    \r
+    @Override\r
+    public int compare(Viewer viewer, Object e1, Object e2) {\r
+\r
+        TreeViewer v = (TreeViewer) viewer;\r
+        TreeColumn currentColumn = v.getTree().getSortColumn();\r
+        \r
+        int res = 0;\r
+        if (e1 instanceof Coverage && e2 instanceof Coverage) {\r
+            Coverage c1 = (Coverage) e1;\r
+            Coverage c2 = (Coverage) e2;\r
+            \r
+            int indx = columns.get(currentColumn);\r
+            switch (indx) {\r
+            case STSTestRunnerView.COLUMN_ELEMENT:\r
+                res = c1.getIdentifier().compareToIgnoreCase(c2.getIdentifier());\r
+                break;\r
+            case STSTestRunnerView.COLUMN_RATIO:\r
+                res = Double.compare(c1.getCoverage(), c2.getCoverage());\r
+                break;\r
+            case STSTestRunnerView.COLUMN_COVERED:\r
+                res = (int) (c1.getCoveredCodeSize() - c2.getCoveredCodeSize());\r
+                break;\r
+            case STSTestRunnerView.COLUMN_MISSED:\r
+                res = (int) (c1.getMissedCodeSize()) - c2.getMissedCodeSize();\r
+                break;\r
+            case STSTestRunnerView.COLUMN_TOTAL:\r
+                res = (int) (c1.getTotalCodeSize() - c2.getTotalCodeSize());\r
+                break;\r
+            }\r
+            if (res == 0) {\r
+                res = c1.getIdentifier().compareTo(c2.getIdentifier());\r
+            } else {\r
+                res = isReverseSort() ? -res : res;\r
+            }\r
+        }\r
+        return res;\r
+    }\r
+\r
+    private boolean isReverseSort() {\r
+        return currentDirection == SWT.DOWN;\r
+    }\r
+}\r
diff --git a/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/RedGreenBar.java b/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/RedGreenBar.java
new file mode 100644 (file)
index 0000000..9812549
--- /dev/null
@@ -0,0 +1,54 @@
+package org.simantics.tests.modelled.ui;\r
+\r
+import java.text.DecimalFormat;\r
+\r
+import org.eclipse.jface.resource.ImageDescriptor;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.simantics.scl.compiler.module.coverage.Coverage;\r
+\r
+public final class RedGreenBar {\r
+\r
+    private static final int BORDER_LEFT = 2;\r
+    private static final int BORDER_RIGHT = 10;\r
+    private static final int BORDER_TOP = 3;\r
+    private static final int BORDER_BOTTOM = 4;\r
+\r
+    private static final String MAX_PERCENTAGE_STRING = new DecimalFormat("0.0 %").format(1.0);\r
+    \r
+    private static final ImageDescriptor redbar = Activator.getImageDescriptor("icons/redbar.gif"); //$NON-NLS-1$\r
+    private static final ImageDescriptor greenbar = Activator.getImageDescriptor("icons/greenbar.gif"); //$NON-NLS-1$\r
+    private static Image redbarIcon = Activator.createManagedImage(redbar);\r
+    private static Image greenbarIcon = Activator.createManagedImage(greenbar);\r
+    \r
+    private RedGreenBar() {\r
+    }\r
+\r
+//    public static void draw(Event event, int columnWith, ICounter counter) {\r
+//        draw(event, columnWith, counter, counter.getTotalCount());\r
+//    }\r
+\r
+    public static void draw(Event event, int columnWith, Coverage coverage) {\r
+        int maxTotal = coverage.getTotalCodeSize();\r
+        if (maxTotal == 0)\r
+            return;\r
+        final int maxWidth = getMaxWidth(event, columnWith);\r
+        final int redLength = maxWidth * coverage.getMissedCodeSize() / maxTotal;\r
+        bar(event, redbarIcon, 0, redLength);\r
+        final int greenLength = maxWidth * coverage.getCoveredCodeSize() / maxTotal;\r
+        bar(event, greenbarIcon, redLength, greenLength);\r
+    }\r
+\r
+    private static void bar(Event event, Image image, int xOffset, int width) {\r
+        final int height = event.getBounds().height - BORDER_TOP - BORDER_BOTTOM;\r
+        event.gc.drawImage(image, 0, 0, 1, 10, event.x + xOffset + BORDER_LEFT,\r
+                event.y + BORDER_TOP, width, height);\r
+    }\r
+\r
+    private static int getMaxWidth(Event event, int columnWith) {\r
+        final int textWidth = event.gc.textExtent(MAX_PERCENTAGE_STRING).x;\r
+        final int max = columnWith - BORDER_LEFT - BORDER_RIGHT - textWidth;\r
+        return Math.max(0, max);\r
+    }\r
+\r
+}
\ No newline at end of file
diff --git a/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSCounterPanel.java b/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSCounterPanel.java
new file mode 100644 (file)
index 0000000..8b04f2f
--- /dev/null
@@ -0,0 +1,156 @@
+/*******************************************************************************\r
+ * Copyright (c) 2000, 2013 IBM Corporation and others.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     IBM Corporation - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.tests.modelled.ui;\r
+\r
+\r
+import java.text.MessageFormat;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.DisposeEvent;\r
+import org.eclipse.swt.events.DisposeListener;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Text;\r
+\r
+/**\r
+ * A panel with counters for the number of Runs, Errors and Failures.\r
+ */\r
+public class STSCounterPanel extends Composite {\r
+    protected Text numberOfErrors;\r
+    protected Text numberOfFailures;\r
+    protected Text numberOfRuns;\r
+    protected int total;\r
+    protected int ignoredCount;\r
+    protected int assumptionFailedCount;\r
+\r
+    private final Image fErrorIcon = null;\r
+    private final Image fFailureIcon = null;\r
+\r
+    public STSCounterPanel(Composite parent) {\r
+        super(parent, SWT.WRAP);\r
+        GridLayout gridLayout= new GridLayout();\r
+        gridLayout.numColumns= 9;\r
+        gridLayout.makeColumnsEqualWidth= false;\r
+        gridLayout.marginWidth= 0;\r
+        setLayout(gridLayout);\r
+\r
+        numberOfRuns= createLabel("Runs:", null, " 0/0  "); //$NON-NLS-1$\r
+        numberOfErrors= createLabel("Errors:", fErrorIcon, " 0 "); //$NON-NLS-1$\r
+        numberOfFailures= createLabel("Failures:", fFailureIcon, " 0 "); //$NON-NLS-1$\r
+\r
+        addDisposeListener(new DisposeListener() {\r
+            public void widgetDisposed(DisposeEvent e) {\r
+                disposeIcons();\r
+            }\r
+        });\r
+    }\r
+\r
+    private void disposeIcons() {\r
+        if (fErrorIcon != null)\r
+            fErrorIcon.dispose();\r
+        if (fFailureIcon != null)\r
+            fFailureIcon.dispose();\r
+    }\r
+\r
+    private Text createLabel(String name, Image image, String init) {\r
+        Label label= new Label(this, SWT.NONE);\r
+        if (image != null) {\r
+            image.setBackground(label.getBackground());\r
+            label.setImage(image);\r
+        }\r
+        label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));\r
+\r
+        label = new Label(this, SWT.NONE);\r
+        label.setText(name);\r
+        label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));\r
+        //label.setFont(JFaceResources.getBannerFont());\r
+\r
+        Text value = new Text(this, SWT.READ_ONLY);\r
+        value.setText(init);\r
+        // bug: 39661 Junit test counters do not repaint correctly [JUnit]\r
+//        SWTUtil.fixReadonlyTextBackground(value);\r
+        value.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.HORIZONTAL_ALIGN_BEGINNING));\r
+        return value;\r
+    }\r
+\r
+    public void reset() {\r
+        setErrorValue(0);\r
+        setFailureValue(0);\r
+        setRunValue(0, 0, 0);\r
+        total= 0;\r
+    }\r
+\r
+    public void setTotal(int value) {\r
+        total= value;\r
+    }\r
+\r
+    public int getTotal(){\r
+        return total;\r
+    }\r
+\r
+    public void setRunValue(int value, int ignoredCount, int assumptionFailureCount) {\r
+        String runString;\r
+        String runStringTooltip;\r
+        if (ignoredCount == 0 && assumptionFailureCount == 0) {\r
+            runString= Messages.format("{0}/{1}", new String[] { Integer.toString(value), Integer.toString(total) });\r
+            runStringTooltip= runString;\r
+        } else if (ignoredCount != 0 && assumptionFailureCount == 0) {\r
+            runString= Messages.format("Skipped", new String[] { Integer.toString(value), Integer.toString(total), Integer.toString(ignoredCount) });\r
+            runStringTooltip= Messages.format("Ignored", new String[] { Integer.toString(value), Integer.toString(total), Integer.toString(ignoredCount) });\r
+        } else if (ignoredCount == 0 && assumptionFailureCount != 0) {\r
+            runString= Messages.format("Skipped", new String[] { Integer.toString(value), Integer.toString(total), Integer.toString(assumptionFailureCount) });\r
+            runStringTooltip= Messages.format("Failed", new String[] { Integer.toString(value), Integer.toString(total), Integer.toString(assumptionFailureCount) });\r
+        } else {\r
+            runString= Messages.format("Skipped", new String[] { Integer.toString(value), Integer.toString(total), Integer.toString(ignoredCount + assumptionFailureCount) });\r
+            runStringTooltip= Messages.format("Failed", new String[] { Integer.toString(value), Integer.toString(total), Integer.toString(ignoredCount), Integer.toString(assumptionFailureCount) });\r
+        }\r
+        numberOfRuns.setText(runString);\r
+        numberOfRuns.setToolTipText(runStringTooltip);\r
+\r
+        if (ignoredCount == 0 && ignoredCount > 0  || ignoredCount != 0 && ignoredCount == 0) {\r
+            layout();\r
+        } else if (assumptionFailedCount == 0 && assumptionFailureCount > 0 || assumptionFailedCount != 0 && assumptionFailureCount == 0) {\r
+            layout();\r
+        } else {\r
+            numberOfRuns.redraw();\r
+            redraw();\r
+        }\r
+        assumptionFailedCount= assumptionFailureCount;\r
+    }\r
+\r
+    public void setErrorValue(int value) {\r
+        numberOfErrors.setText(Integer.toString(value));\r
+        redraw();\r
+    }\r
+\r
+    public void setFailureValue(int value) {\r
+        numberOfFailures.setText(Integer.toString(value));\r
+        redraw();\r
+    }\r
+    \r
+    private static class Messages {\r
+\r
+        public static String format(String message, Object object) {\r
+            return MessageFormat.format(message, new Object[] { object});\r
+        }\r
+\r
+        public static String format(String message, Object[] objects) {\r
+            return MessageFormat.format(message, objects);\r
+        }\r
+\r
+        private Messages() {\r
+            // Not for instantiation\r
+        }\r
+    }\r
+}\r
diff --git a/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSCoverageProvider.java b/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSCoverageProvider.java
new file mode 100644 (file)
index 0000000..0ba65cc
--- /dev/null
@@ -0,0 +1,118 @@
+package org.simantics.tests.modelled.ui;\r
+\r
+import java.text.DecimalFormat;\r
+import java.util.Collection;\r
+\r
+import org.eclipse.jface.viewers.ITreeContentProvider;\r
+import org.eclipse.jface.viewers.LabelProvider;\r
+import org.eclipse.jface.viewers.Viewer;\r
+import org.simantics.scl.compiler.module.coverage.CombinedCoverage;\r
+import org.simantics.scl.compiler.module.coverage.Coverage;\r
+import org.simantics.scl.compiler.module.coverage.FunctionCoverage;\r
+import org.simantics.scl.compiler.module.coverage.ModuleCoverage;\r
+import org.simantics.tests.modelled.ui.STSTestSuiteModel.STSSuite;\r
+import org.simantics.tests.modelled.ui.STSTestSuiteModel.STSTest;\r
+\r
+public class STSCoverageProvider extends LabelProvider implements ITreeContentProvider {\r
+\r
+    private Object input;\r
+    \r
+    @Override\r
+    public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {\r
+        input = newInput;\r
+    }\r
+\r
+    @Override\r
+    public Object[] getElements(Object inputElement) {\r
+        CombinedCoverage coverage;\r
+        if (input instanceof STSTest) {\r
+            STSTest test = (STSTest) input;\r
+            coverage = test.getCoverage();\r
+        } else if (input instanceof STSSuite) {\r
+            STSSuite suite = (STSSuite) input;\r
+            coverage = suite.getCoverage();\r
+        } else {\r
+            return new Object[0];\r
+        }\r
+        if (coverage == null)\r
+            return new Object[0];\r
+        \r
+        return new Object[] { coverage };\r
+        \r
+//        Collection<ModuleCoverage> moduleCoverages = coverage.moduleCoverages.values();\r
+//        return moduleCoverages.toArray(new ModuleCoverage[moduleCoverages.size()]);\r
+    }\r
+\r
+    @Override\r
+    public Object[] getChildren(Object parentElement) {\r
+        if (parentElement instanceof CombinedCoverage) {\r
+            CombinedCoverage coverage = (CombinedCoverage) parentElement;\r
+            Collection<ModuleCoverage> moduleCoverages = coverage.moduleCoverages.values();\r
+            return moduleCoverages.toArray(new ModuleCoverage[moduleCoverages.size()]);\r
+        } else if (parentElement instanceof ModuleCoverage) {\r
+            ModuleCoverage coverage = (ModuleCoverage) parentElement;\r
+            Collection<FunctionCoverage> coverages = coverage.functionCoverages.values();\r
+            return coverages.toArray(new FunctionCoverage[coverages.size()]);\r
+        } else {\r
+            return null;\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public Object getParent(Object element) {\r
+        if (element instanceof FunctionCoverage) {\r
+            FunctionCoverage coverage = (FunctionCoverage) element;\r
+            return new ModuleCoverage[] { null };\r
+        } else {\r
+            return null;\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public boolean hasChildren(Object element) {\r
+        if (element instanceof CombinedCoverage)\r
+            return !((CombinedCoverage) element).moduleCoverages.isEmpty();\r
+        else if (element instanceof ModuleCoverage)\r
+            return !((ModuleCoverage)element).functionCoverages.isEmpty();\r
+        else\r
+            return false;\r
+    }\r
+    \r
+    @Override\r
+    public String getText(Object element) {\r
+        if (element instanceof Coverage)\r
+            return ((Coverage) element).getIdentifier();\r
+        return super.getText(element);\r
+    }\r
+\r
+    public String getRatio(Object element) {\r
+        if (element instanceof Coverage)\r
+            return formatPercentage(((Coverage) element).getCoverage());\r
+        return "unknown " + element;\r
+    }\r
+\r
+    public String getCovered(Object element) {\r
+        if (element instanceof Coverage)\r
+            return ((Coverage) element).getCoveredCodeSize() + "";\r
+        return "unknown " + element;\r
+    }\r
+\r
+    public String getMissed(Object element) {\r
+        if (element instanceof Coverage)\r
+            return ((Coverage) element).getMissedCodeSize() + "";\r
+        return "unknown " + element;\r
+    }\r
+\r
+    public String getTotal(Object element) {\r
+        if (element instanceof Coverage)\r
+            return ((Coverage) element).getTotalCodeSize() + "";\r
+        return "unknown " + element;\r
+    }\r
+    \r
+    private static final DecimalFormat MAX_PERCENTAGE_STRING = new DecimalFormat("0.0 %");\r
+    \r
+    private static String formatPercentage(double perc) {\r
+        return MAX_PERCENTAGE_STRING.format(perc);\r
+    }\r
+\r
+}\r
diff --git a/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSExecutionListener.java b/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSExecutionListener.java
new file mode 100644 (file)
index 0000000..29989a9
--- /dev/null
@@ -0,0 +1,6 @@
+package org.simantics.tests.modelled.ui;\r
+\r
+public interface STSExecutionListener {\r
+\r
+    void testExecuted();\r
+}\r
diff --git a/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSProgressBar.java b/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSProgressBar.java
new file mode 100644 (file)
index 0000000..9a29088
--- /dev/null
@@ -0,0 +1,183 @@
+/*******************************************************************************\r
+ * Copyright (c) 2000, 2010 IBM Corporation and others.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     IBM Corporation - initial API and implementation\r
+ *     Stephan Michels, stephan@apache.org - 104944 [JUnit] Unnecessary code in JUnitProgressBar\r
+ *******************************************************************************/\r
+package org.simantics.tests.modelled.ui;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.ControlAdapter;\r
+import org.eclipse.swt.events.ControlEvent;\r
+import org.eclipse.swt.events.DisposeEvent;\r
+import org.eclipse.swt.events.DisposeListener;\r
+import org.eclipse.swt.events.PaintEvent;\r
+import org.eclipse.swt.events.PaintListener;\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.graphics.GC;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.eclipse.swt.graphics.Rectangle;\r
+import org.eclipse.swt.widgets.Canvas;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Display;\r
+\r
+/**\r
+ * A progress bar with a red/green indication for success or failure.\r
+ */\r
+public class STSProgressBar extends Canvas {\r
+    private static final int DEFAULT_WIDTH = 160;\r
+    private static final int DEFAULT_HEIGHT = 18;\r
+\r
+    private int fCurrentTickCount= 0;\r
+    private int fMaxTickCount= 0;\r
+    private int fColorBarWidth= 0;\r
+    private Color fOKColor;\r
+    private Color fFailureColor;\r
+    private Color fStoppedColor;\r
+    private boolean fError;\r
+    private boolean fStopped= false;\r
+\r
+    public STSProgressBar(Composite parent) {\r
+        super(parent, SWT.NONE);\r
+\r
+        addControlListener(new ControlAdapter() {\r
+            @Override\r
+            public void controlResized(ControlEvent e) {\r
+                fColorBarWidth= scale(fCurrentTickCount);\r
+                redraw();\r
+            }\r
+        });\r
+        addPaintListener(new PaintListener() {\r
+            public void paintControl(PaintEvent e) {\r
+                paint(e);\r
+            }\r
+        });\r
+        addDisposeListener(new DisposeListener() {\r
+            public void widgetDisposed(DisposeEvent e) {\r
+                fFailureColor.dispose();\r
+                fOKColor.dispose();\r
+                fStoppedColor.dispose();\r
+            }\r
+        });\r
+        Display display= parent.getDisplay();\r
+        fFailureColor= new Color(display, 159, 63, 63);\r
+        fOKColor= new Color(display, 95, 191, 95);\r
+        fStoppedColor= new Color(display, 120, 120, 120);\r
+    }\r
+\r
+    public void setMaximum(int max) {\r
+        fMaxTickCount= max;\r
+    }\r
+\r
+    public void reset() {\r
+        fError= false;\r
+        fStopped= false;\r
+        fCurrentTickCount= 0;\r
+        fMaxTickCount= 0;\r
+        fColorBarWidth= 0;\r
+        redraw();\r
+    }\r
+\r
+    public void reset(boolean hasErrors, boolean stopped, int ticksDone, int maximum) {\r
+        boolean noChange= fError == hasErrors && fStopped == stopped && fCurrentTickCount == ticksDone && fMaxTickCount == maximum;\r
+        fError= hasErrors;\r
+        fStopped= stopped;\r
+        fCurrentTickCount= ticksDone;\r
+        fMaxTickCount= maximum;\r
+        fColorBarWidth= scale(ticksDone);\r
+        if (! noChange)\r
+            redraw();\r
+    }\r
+\r
+    private void paintStep(int startX, int endX) {\r
+        GC gc = new GC(this);\r
+        setStatusColor(gc);\r
+        Rectangle rect= getClientArea();\r
+        startX= Math.max(1, startX);\r
+        gc.fillRectangle(startX, 1, endX-startX, rect.height-2);\r
+        gc.dispose();\r
+    }\r
+\r
+    private void setStatusColor(GC gc) {\r
+        if (fStopped)\r
+            gc.setBackground(fStoppedColor);\r
+        else if (fError)\r
+            gc.setBackground(fFailureColor);\r
+        else\r
+            gc.setBackground(fOKColor);\r
+    }\r
+\r
+    public void stopped() {\r
+        fStopped= true;\r
+        redraw();\r
+    }\r
+\r
+    private int scale(int value) {\r
+        if (fMaxTickCount > 0) {\r
+            Rectangle r= getClientArea();\r
+            if (r.width != 0)\r
+                return Math.max(0, value*(r.width-2)/fMaxTickCount);\r
+        }\r
+        return value;\r
+    }\r
+\r
+    private void drawBevelRect(GC gc, int x, int y, int w, int h, Color topleft, Color bottomright) {\r
+        gc.setForeground(topleft);\r
+        gc.drawLine(x, y, x+w-1, y);\r
+        gc.drawLine(x, y, x, y+h-1);\r
+\r
+        gc.setForeground(bottomright);\r
+        gc.drawLine(x+w, y, x+w, y+h);\r
+        gc.drawLine(x, y+h, x+w, y+h);\r
+    }\r
+\r
+    private void paint(PaintEvent event) {\r
+        GC gc = event.gc;\r
+        Display disp= getDisplay();\r
+\r
+        Rectangle rect= getClientArea();\r
+        gc.fillRectangle(rect);\r
+        drawBevelRect(gc, rect.x, rect.y, rect.width-1, rect.height-1,\r
+            disp.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW),\r
+            disp.getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW));\r
+\r
+        setStatusColor(gc);\r
+        fColorBarWidth= Math.min(rect.width-2, fColorBarWidth);\r
+        gc.fillRectangle(1, 1, fColorBarWidth, rect.height-2);\r
+    }\r
+\r
+    @Override\r
+    public Point computeSize(int wHint, int hHint, boolean changed) {\r
+        checkWidget();\r
+        Point size= new Point(DEFAULT_WIDTH, DEFAULT_HEIGHT);\r
+        if (wHint != SWT.DEFAULT) size.x= wHint;\r
+        if (hHint != SWT.DEFAULT) size.y= hHint;\r
+        return size;\r
+    }\r
+\r
+    public void step(int failures) {\r
+        fCurrentTickCount++;\r
+        int x= fColorBarWidth;\r
+\r
+        fColorBarWidth= scale(fCurrentTickCount);\r
+\r
+        if (!fError && failures > 0) {\r
+            fError= true;\r
+            x= 1;\r
+        }\r
+        if (fCurrentTickCount == fMaxTickCount)\r
+            fColorBarWidth= getClientArea().width-1;\r
+        paintStep(x, fColorBarWidth);\r
+    }\r
+\r
+    public void refresh(boolean hasErrors) {\r
+        fError= hasErrors;\r
+        redraw();\r
+    }\r
+\r
+}\r
diff --git a/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSTestEditor.java b/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSTestEditor.java
new file mode 100644 (file)
index 0000000..905a148
--- /dev/null
@@ -0,0 +1,17 @@
+package org.simantics.tests.modelled.ui;\r
+\r
+import org.simantics.modeling.ui.componentTypeEditor.SCLModuleEditor;\r
+import org.simantics.scl.ui.editor.SCLSourceViewerConfigurationNew;\r
+\r
+public class STSTestEditor extends SCLModuleEditor {\r
+    \r
+    \r
+    \r
+    @Override\r
+    protected void preInitialize() {\r
+        SCLSourceViewerConfigurationNew sourceViewerConfiguration = new SCLSourceViewerConfigurationNew(resourceManager);\r
+        setDocumentProvider(new STSTestEditorDocumentProvider(sourceViewerConfiguration));\r
+        setSourceViewerConfiguration(sourceViewerConfiguration);\r
+    }\r
+\r
+}\r
diff --git a/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSTestEditorDocumentProvider.java b/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSTestEditorDocumentProvider.java
new file mode 100644 (file)
index 0000000..ed1633c
--- /dev/null
@@ -0,0 +1,79 @@
+package org.simantics.tests.modelled.ui;\r
+\r
+import java.io.PrintWriter;\r
+import java.io.StringWriter;\r
+\r
+import org.eclipse.core.runtime.CoreException;\r
+import org.eclipse.core.runtime.IProgressMonitor;\r
+import org.eclipse.jface.text.Document;\r
+import org.eclipse.jface.text.IDocument;\r
+import org.eclipse.jface.text.source.IAnnotationModel;\r
+import org.simantics.Simantics;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.UniqueRead;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.Layer0Utils;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.ui.componentTypeEditor.SCLModuleEditorDocumentProvider;\r
+import org.simantics.scl.ui.editor.SCLSourceViewerConfigurationNew;\r
+import org.simantics.tests.modelled.ontology.TestsResource;\r
+import org.simantics.ui.workbench.ResourceEditorInput;\r
+import org.simantics.utils.logging.TimeLogger;\r
+\r
+public class STSTestEditorDocumentProvider extends SCLModuleEditorDocumentProvider {\r
+\r
+    public STSTestEditorDocumentProvider(SCLSourceViewerConfigurationNew sourceViewer) {\r
+        super(sourceViewer);\r
+    }\r
+    \r
+    @Override\r
+    protected IAnnotationModel createAnnotationModel(Object element) throws CoreException {\r
+        return null;\r
+    }\r
+    \r
+    @Override\r
+    protected void updateAnnotations() {\r
+    }\r
+    \r
+    @Override\r
+    protected IDocument createDocument(Object element) throws CoreException {\r
+        ResourceEditorInput input = (ResourceEditorInput)element;\r
+        resource = input.getResource();\r
+        try {\r
+            return Simantics.getSession().syncRequest(new UniqueRead<Document>() {\r
+                @Override\r
+                public Document perform(ReadGraph graph) throws DatabaseException {\r
+                    TestsResource TESTS = TestsResource.getInstance(graph);\r
+                    currentText = graph.getRelatedValue(resource, TESTS.STSTest_definition, Bindings.STRING);\r
+                    errorHappened = false;\r
+                    return new Document(currentText != null ? currentText : "");\r
+                }\r
+            });\r
+        } catch (DatabaseException e) {\r
+            StringWriter sw = new StringWriter();\r
+            PrintWriter pw = new PrintWriter(sw);\r
+            e.printStackTrace(pw);\r
+            errorHappened = true;\r
+            return new Document(sw.toString());\r
+        }\r
+    }\r
+    \r
+    @Override\r
+    protected void doSaveDocument(IProgressMonitor monitor, Object element, IDocument document, boolean overwrite) throws CoreException {\r
+        TimeLogger.resetTimeAndLog("STSTestEditorDocumentProvider.doSaveDocument");\r
+        currentText = document.get();\r
+        Simantics.getSession().asyncRequest(new WriteRequest() {\r
+            @Override\r
+            public void perform(WriteGraph graph) throws DatabaseException {\r
+                graph.markUndoPoint();\r
+                TestsResource TESTS = TestsResource.getInstance(graph);\r
+                graph.claimLiteral(resource, TESTS.STSTest_definition, currentText, Bindings.STRING);\r
+                Layer0Utils.addCommentMetadata(graph, "Saved SCL Module " + graph.getRelatedValue2(resource, Layer0.getInstance(graph).HasName, Bindings.STRING));\r
+            }\r
+        });\r
+    }\r
+\r
+}\r
diff --git a/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSTestRunnerView.java b/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSTestRunnerView.java
new file mode 100644 (file)
index 0000000..09e9599
--- /dev/null
@@ -0,0 +1,419 @@
+package org.simantics.tests.modelled.ui;\r
+\r
+import java.util.List;\r
+import java.util.concurrent.Executors;\r
+\r
+import javax.annotation.PostConstruct;\r
+import javax.annotation.PreDestroy;\r
+\r
+import org.eclipse.e4.ui.di.Focus;\r
+import org.eclipse.jface.layout.TreeColumnLayout;\r
+import org.eclipse.jface.viewers.CellLabelProvider;\r
+import org.eclipse.jface.viewers.ColumnWeightData;\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.jface.viewers.ISelectionChangedListener;\r
+import org.eclipse.jface.viewers.OwnerDrawLabelProvider;\r
+import org.eclipse.jface.viewers.SelectionChangedEvent;\r
+import org.eclipse.jface.viewers.TreeSelection;\r
+import org.eclipse.jface.viewers.TreeViewer;\r
+import org.eclipse.jface.viewers.TreeViewerColumn;\r
+import org.eclipse.jface.viewers.ViewerCell;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.custom.CTabFolder;\r
+import org.eclipse.swt.custom.CTabItem;\r
+import org.eclipse.swt.custom.SashForm;\r
+import org.eclipse.swt.custom.StyledText;\r
+import org.eclipse.swt.custom.ViewForm;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.eclipse.swt.layout.FormAttachment;\r
+import org.eclipse.swt.layout.FormData;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Layout;\r
+import org.eclipse.swt.widgets.Tree;\r
+import org.eclipse.swt.widgets.TreeColumn;\r
+import org.eclipse.ui.part.PageBook;\r
+import org.simantics.db.Resource;\r
+import org.simantics.scl.compiler.module.coverage.Coverage;\r
+\r
+public class STSTestRunnerView {\r
+    \r
+    public static final String ID = "org.simantics.tests.modelled.ui.stsTestRunnerView";\r
+\r
+    private Resource test;\r
+    private SashForm sashForm;\r
+    private PageBook viewerbook;\r
+    private TreeViewer treeViewer;\r
+//    private ITreeContentProvider treeContentProvider;\r
+    private STSTestSuiteProvider provider;\r
+    private StyledText output;\r
+    private STSCounterPanel counterPanel;\r
+    private STSProgressBar progressBar;\r
+    private Composite counterComposite;\r
+\r
+    @PostConstruct\r
+    void createView(Composite parent) {\r
+        \r
+        GridLayout gridLayout= new GridLayout();\r
+        gridLayout.marginWidth= 0;\r
+        gridLayout.marginHeight= 0;\r
+        parent.setLayout(gridLayout);\r
+        \r
+        counterComposite= createProgressCountPanel(parent);\r
+        counterComposite.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL));\r
+        counterComposite.pack();\r
+        \r
+        SashForm sashForm = createSashForm(parent);\r
+        sashForm.setLayoutData(new GridData(GridData.FILL_BOTH));\r
+    }\r
+    \r
+    private SashForm createSashForm(Composite parent) {\r
+        sashForm = new SashForm(parent, SWT.VERTICAL);\r
+\r
+        ViewForm top = new ViewForm(sashForm, SWT.NONE);\r
+\r
+        Composite empty = new Composite(top, SWT.NONE);\r
+        empty.setLayout(new Layout() {\r
+            @Override\r
+            protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) {\r
+                return new Point(1, 1); // (0, 0) does not work with super-intelligent ViewForm\r
+            }\r
+            @Override\r
+            protected void layout(Composite composite, boolean flushCache) {\r
+            }\r
+        });\r
+        top.setTopLeft(empty); // makes ViewForm draw the horizontal separator line ...\r
+//        fTestViewer= new TestViewer(top, fClipboard, this);\r
+        createTestViewers(top);\r
+        top.setContent(viewerbook);\r
+        treeViewer.setInput(test);\r
+\r
+        ViewForm bottom = new ViewForm(sashForm, SWT.NONE);\r
+\r
+        CTabFolder folder = new CTabFolder(bottom, SWT.BORDER);\r
+        folder.setLayoutData(new GridData(GridData.FILL_BOTH));\r
+        \r
+        CTabItem item1 = new CTabItem(folder, SWT.NONE);\r
+        item1.setText("Execution");\r
+//        PageBook fViewerbook2= new PageBook(bottom, SWT.NULL);\r
+        // Upper\r
+        output = new StyledText(folder, SWT.MULTI | SWT.READ_ONLY | SWT.V_SCROLL | SWT.H_SCROLL);\r
+//        output.setFont(textFont);\r
+        {\r
+            FormData formData = new FormData();\r
+            formData.top = new FormAttachment(0);      \r
+//            formData.bottom = new FormAttachment(sash);\r
+            formData.left = new FormAttachment(0);\r
+            formData.right = new FormAttachment(100);\r
+            output.setLayoutData(formData);\r
+        }\r
+        item1.setControl(output);\r
+//        fViewerbook2.showPage(output);\r
+        bottom.setContent(folder);\r
+        folder.setSelection(0);\r
+\r
+        CTabItem item2 = new CTabItem(folder, SWT.NONE);\r
+        item2.setText("Coverage");\r
+        \r
+        Composite treeComposite = new Composite(folder, SWT.NONE);\r
+        \r
+        TreeViewer viewer = createCoverageViewer(treeComposite);\r
+        item2.setControl(treeComposite);\r
+        \r
+        treeViewer.addSelectionChangedListener(new ISelectionChangedListener() {\r
+            \r
+            @Override\r
+            public void selectionChanged(SelectionChangedEvent event) {\r
+                ISelection selection = event.getSelection();\r
+                TreeSelection sel = (TreeSelection) selection;\r
+                List<String> testOutput = provider.getModel().getOutput(sel.getFirstElement());\r
+                \r
+                viewer.setInput(sel.getFirstElement());\r
+                \r
+                StringBuilder sb = new StringBuilder();\r
+                for (String o : testOutput) {\r
+                    sb.append(o);\r
+                }\r
+                output.setText(sb.toString());\r
+            }\r
+        });\r
+        \r
+        sashForm.setWeights(new int[] {50, 50});\r
+        return sashForm;\r
+    }\r
+    \r
+    protected static final int COLUMN_ELEMENT = 0;\r
+    protected static final int COLUMN_RATIO = 1;\r
+    protected static final int COLUMN_COVERED = 2;\r
+    protected static final int COLUMN_MISSED = 3;\r
+    protected static final int COLUMN_TOTAL = 4;\r
+    \r
+    private TreeViewer createCoverageViewer(Composite parent) {\r
+        // Composite treeViewerComposite = new Composite(parent, SWT.NONE);\r
+\r
+        TreeColumnLayout layout = new TreeColumnLayout();\r
+        parent.setLayout(layout);\r
+        \r
+        Tree tree = new Tree(parent, SWT.MULTI | SWT.FULL_SELECTION);\r
+        tree.setHeaderVisible(true);\r
+        tree.setLinesVisible(true);\r
+        \r
+        STSCoverageProvider provider = new STSCoverageProvider();\r
+\r
+        TreeViewer viewer = new TreeViewer(tree);\r
+        \r
+        CoverageViewSorter sorter = new CoverageViewSorter(viewer);\r
+        \r
+        final TreeViewerColumn column0 = new TreeViewerColumn(viewer, SWT.LEFT);\r
+        \r
+        column0.setLabelProvider(new CellLabelProvider() {\r
+\r
+            \r
+            @Override\r
+            public void update(ViewerCell cell) {\r
+                cell.setText(provider.getText(cell.getElement()));\r
+                cell.setImage(provider.getImage(cell.getElement()));\r
+            }\r
+        });\r
+         sorter.addColumn(column0, COLUMN_ELEMENT);\r
+\r
+        final TreeViewerColumn column1 = new TreeViewerColumn(viewer, SWT.RIGHT);\r
+        column1.setLabelProvider(new OwnerDrawLabelProvider() {\r
+\r
+            @Override\r
+            public void update(ViewerCell cell) {\r
+                cell.setText(provider.getRatio(cell.getElement()));\r
+            }\r
+\r
+            @Override\r
+            protected void erase(Event event, Object element) {\r
+            }\r
+\r
+            @Override\r
+            protected void measure(Event event, Object element) {\r
+            }\r
+\r
+            @Override\r
+            protected void paint(Event event, Object element) {\r
+                final Coverage coverage = (Coverage) element;\r
+                if (coverage != null) {\r
+                    RedGreenBar.draw(event, column1.getColumn().getWidth(), coverage);\r
+                }\r
+            }\r
+        });\r
+        sorter.addColumn(column1, COLUMN_RATIO);\r
+\r
+        final TreeViewerColumn column2 = new TreeViewerColumn(viewer, SWT.RIGHT);\r
+        column2.setLabelProvider(new CellLabelProvider() {\r
+\r
+            @Override\r
+            public void update(ViewerCell cell) {\r
+                cell.setText(provider.getCovered(cell.getElement()));\r
+            }\r
+        });\r
+        sorter.addColumn(column2, COLUMN_COVERED);\r
+\r
+        final TreeViewerColumn column3 = new TreeViewerColumn(viewer, SWT.RIGHT);\r
+        column3.setLabelProvider(new CellLabelProvider() {\r
+\r
+            @Override\r
+            public void update(ViewerCell cell) {\r
+                cell.setText(provider.getMissed(cell.getElement()));\r
+            }\r
+        });\r
+        sorter.addColumn(column3, COLUMN_MISSED);\r
+\r
+        final TreeViewerColumn column4 = new TreeViewerColumn(viewer, SWT.RIGHT);\r
+        column4.setLabelProvider(new CellLabelProvider() {\r
+\r
+            @Override\r
+            public void update(ViewerCell cell) {\r
+                cell.setText(provider.getTotal(cell.getElement()));\r
+            }\r
+        });\r
+        sorter.addColumn(column4, COLUMN_TOTAL);\r
+\r
+//        viewer.addFilter(new ViewerFilter() {\r
+//            public boolean select(Viewer viewer, Object parentElement, Object element) {\r
+//                if (element == LOADING_ELEMENT) {\r
+//                    return true;\r
+//                } else {\r
+//                    final ICoverageNode c = CoverageTools.getCoverageInfo(element);\r
+//                    if (c == null) {\r
+//                        return false;\r
+//                    }\r
+//                    final ICounter instructions = c.getInstructionCounter();\r
+//                    if (instructions.getTotalCount() == 0) {\r
+//                        return false;\r
+//                    }\r
+//                    if (settings.getHideUnusedElements() && instructions.getCoveredCount() == 0) {\r
+//                        return false;\r
+//                    }\r
+//                    return true;\r
+//                }\r
+//            }\r
+//        });\r
+        viewer.setComparator(sorter);\r
+        \r
+        layout.setColumnData(column0.getColumn(), new ColumnWeightData(0, 50, false));\r
+        layout.setColumnData(column1.getColumn(), new ColumnWeightData(0, 50, false));\r
+        layout.setColumnData(column2.getColumn(), new ColumnWeightData(0, 50, false));\r
+        layout.setColumnData(column3.getColumn(), new ColumnWeightData(0, 50, false));\r
+        layout.setColumnData(column4.getColumn(), new ColumnWeightData(0, 50, false));\r
+        \r
+        String[] columns = new String[] {"Module", "Coverage", "Covered Instructions", "Missed Instructions", "Total Instructions"};\r
+        TreeColumn[] columns2 = viewer.getTree().getColumns();\r
+        for (int i = 0; i < columns2.length; i++) {\r
+            columns2[i].setText(columns[i]);\r
+        }\r
+        restoreColumnWidth(viewer);\r
+        viewer.setContentProvider(provider);\r
+        return viewer;\r
+\r
+//        viewer.addOpenListener(new IOpenListener() {\r
+//            public void open(OpenEvent event) {\r
+//                openAction.run((IStructuredSelection) event.getSelection());\r
+//            }\r
+//        });\r
+\r
+//        MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$\r
+//        menuMgr.setRemoveAllWhenShown(true);\r
+//        tree.setMenu(menuMgr.createContextMenu(tree));\r
+//        getSite().registerContextMenu(menuMgr, viewer);\r
+//\r
+//        CoverageTools.getSessionManager().addSessionListener(descriptionUpdater);\r
+//        CoverageTools.addJavaCoverageListener(coverageListener);\r
+    }\r
+    \r
+    private static final int[] DEFAULT_COLUMNWIDTH = new int[] { 200, 100, 120,\r
+            120, 120 };\r
+    \r
+    public void restoreColumnWidth(TreeViewer viewer) {\r
+        final TreeColumn[] columns = viewer.getTree().getColumns();\r
+        for (int i = 0; i < DEFAULT_COLUMNWIDTH.length; i++) {\r
+          columns[i].setWidth(DEFAULT_COLUMNWIDTH[i]);\r
+        }\r
+      }\r
+\r
+    protected Composite createProgressCountPanel(Composite parent) {\r
+        Composite composite= new Composite(parent, SWT.NONE);\r
+        GridLayout layout= new GridLayout();\r
+        composite.setLayout(layout);\r
+        layout.numColumns = 1;\r
+\r
+        counterPanel = new STSCounterPanel(composite);\r
+        counterPanel.setLayoutData(\r
+            new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL));\r
+        progressBar = new STSProgressBar(composite);\r
+        progressBar.setLayoutData(\r
+                new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL));\r
+        return composite;\r
+    }\r
+    \r
+    private void createTestViewers(Composite parent) {\r
+        viewerbook = new PageBook(parent, SWT.NULL);\r
+\r
+        treeViewer = new TreeViewer(viewerbook, SWT.V_SCROLL | SWT.SINGLE);\r
+        treeViewer.setUseHashlookup(true);\r
+        \r
+        STSTestSuiteModel model = new STSTestSuiteModel();\r
+        model.addListener(new STSExecutionListener() {\r
+            \r
+            @Override\r
+            public void testExecuted() {\r
+                treeViewer.getControl().getDisplay().syncExec(() -> {\r
+                    refreshCounters();\r
+                    treeViewer.refresh();\r
+                });\r
+            }\r
+        });\r
+        \r
+        provider = new STSTestSuiteProvider(model);\r
+        \r
+        treeViewer.setContentProvider(provider);\r
+        treeViewer.setLabelProvider(provider);\r
+\r
+\r
+        viewerbook.showPage(treeViewer.getTree());\r
+        \r
+    }\r
+    \r
+\r
+    @Focus\r
+    void setFocus() {\r
+        sashForm.setFocus();\r
+    }\r
+\r
+    public void currentTest(Resource test) {\r
+        treeViewer.setInput(test);\r
+        refreshCounters();\r
+    }\r
+    \r
+    private void refreshCounters() {\r
+        // TODO: Inefficient. Either\r
+       // - keep a boolean fHasTestRun and update only on changes, or\r
+       // - improve components to only redraw on changes (once!).\r
+\r
+       int startedCount;\r
+       int ignoredCount;\r
+       int totalCount;\r
+       int errorCount;\r
+       int failureCount;\r
+       int assumptionFailureCount;\r
+       boolean hasErrorsOrFailures;\r
+       boolean stopped;\r
+\r
+       STSTestSuiteModel model = provider.getModel();\r
+       if (model != null) {\r
+           startedCount= model.getStartedCount();\r
+           ignoredCount= model.getIgnoredCount();\r
+           totalCount= model.getTotalCount();\r
+           errorCount= model.getErrorCount();\r
+           failureCount= model.getFailureCount();\r
+           assumptionFailureCount = model.getAssumptionFailureCount();\r
+           hasErrorsOrFailures= errorCount + failureCount > 0;\r
+           stopped= model.isStopped();\r
+       } else {\r
+           startedCount= 0;\r
+           ignoredCount= 0;\r
+           totalCount= 0;\r
+           errorCount= 0;\r
+           failureCount= 0;\r
+           assumptionFailureCount = 0;\r
+           hasErrorsOrFailures= false;\r
+           stopped= false;\r
+       }\r
+\r
+       counterPanel.setTotal(totalCount);\r
+       counterPanel.setRunValue(startedCount, ignoredCount, assumptionFailureCount);\r
+       counterPanel.setErrorValue(errorCount);\r
+       counterPanel.setFailureValue(failureCount);\r
+\r
+       int ticksDone;\r
+       if (startedCount == 0)\r
+           ticksDone= 0;\r
+       else if (startedCount == totalCount &&  model.isStopped())\r
+           ticksDone= totalCount;\r
+       else\r
+           ticksDone= startedCount - 1;\r
+\r
+       progressBar.reset(hasErrorsOrFailures, stopped, ticksDone, totalCount);\r
+   }\r
+\r
+    public void execute() {\r
+        Executors.newSingleThreadExecutor().submit(new Runnable() {\r
+\r
+            @Override\r
+            public void run() {\r
+                provider.getModel().execute();\r
+            }\r
+        });\r
+    }\r
+    \r
+    @PreDestroy\r
+    public void destroy() {\r
+        provider.dispose();\r
+    }\r
+}\r
diff --git a/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSTestSuiteModel.java b/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSTestSuiteModel.java
new file mode 100644 (file)
index 0000000..188574e
--- /dev/null
@@ -0,0 +1,504 @@
+package org.simantics.tests.modelled.ui;\r
+\r
+import java.io.BufferedReader;\r
+import java.io.StringReader;\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.List;\r
+import java.util.regex.Pattern;\r
+import java.util.regex.PatternSyntaxException;\r
+\r
+import org.eclipse.swt.graphics.Image;\r
+import org.simantics.Simantics;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.request.ReadRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.scl.compiler.commands.CommandSession;\r
+import org.simantics.scl.compiler.commands.TestScriptExecutor;\r
+import org.simantics.scl.compiler.module.Module;\r
+import org.simantics.scl.compiler.module.coverage.CombinedCoverage;\r
+import org.simantics.scl.compiler.module.coverage.CoverageBuilder;\r
+import org.simantics.scl.compiler.module.coverage.CoverageUtils;\r
+import org.simantics.scl.compiler.module.options.ModuleCompilationOptions;\r
+import org.simantics.scl.compiler.module.options.ModuleCompilationOptionsAdvisor;\r
+import org.simantics.scl.compiler.module.repository.ModuleRepository;\r
+import org.simantics.scl.compiler.runtime.RuntimeModule;\r
+import org.simantics.scl.osgi.SCLOsgi;\r
+import org.simantics.scl.runtime.reporting.AbstractSCLReportingHandler;\r
+import org.simantics.tests.modelled.ontology.TestsResource;\r
+\r
+public class STSTestSuiteModel {\r
+\r
+    static class STSTest {\r
+        \r
+        private final Resource test;\r
+        private final STSSuite parent;\r
+        private final String definition;\r
+        private final String name;\r
+        private boolean executed = false;\r
+        private long duration;\r
+        private boolean failed = false;\r
+        private boolean isRunning = false;\r
+        private List<String> output = new ArrayList<>();\r
+        private CombinedCoverage coverage;\r
+        private int priority;\r
+        \r
+        public STSTest(Resource test, STSSuite parent, String definition, String name, int executionPrioprity) {\r
+            this.test = test;\r
+            this.parent = parent;\r
+            this.definition = definition;\r
+            this.name = name;\r
+            this.priority = executionPrioprity;\r
+        }\r
+        \r
+        public String getName() {\r
+            return name;\r
+        }\r
+        \r
+        public String getLabel() {\r
+            StringBuilder sb = new StringBuilder();\r
+            sb.append(name);\r
+            if (executed || failed)\r
+                sb.append(" (").append(duration).append(" ms)");\r
+            return sb.toString();\r
+        }\r
+        \r
+        public String getDefinition() {\r
+            return definition;\r
+        }\r
+\r
+        public STSSuite getParent() {\r
+            return parent;\r
+        }\r
+\r
+        public void execute(CommandSession session) {\r
+            isRunning = true;\r
+            \r
+            TestScriptExecutor executor = new TestScriptExecutor(session, new BufferedReader(new StringReader(definition)), new AbstractSCLReportingHandler() {\r
+                \r
+                @Override\r
+                public void print(String text) {\r
+                    appendOutput(text + "\n");\r
+                }\r
+                \r
+                @Override\r
+                public void printCommand(String command) {\r
+                    appendOutput("> " + command + "\n");\r
+                }\r
+                \r
+                @Override\r
+                public void printError(String error) {\r
+                    appendOutput(error + "\n");\r
+                }\r
+            });\r
+            long start = System.currentTimeMillis();\r
+            try {\r
+                if (parent != null)\r
+                    parent.startedCount++;\r
+                executor.execute();\r
+                executed = true;\r
+            } catch (Throwable t) {\r
+                t.printStackTrace();\r
+                if (parent != null)\r
+                    parent.failureCount++;\r
+                failed = true;\r
+            } finally {\r
+                isRunning = false;\r
+                long end = System.currentTimeMillis();\r
+                duration = end - start;\r
+            }\r
+\r
+        }\r
+\r
+        protected void appendOutput(String text) {\r
+            output.add(text);\r
+        }\r
+\r
+        public List<String> getOutput() {\r
+            return output;\r
+        }\r
+\r
+        public void setCoverage(CombinedCoverage coverage) {\r
+            this.coverage = coverage;\r
+        }\r
+        \r
+        public CombinedCoverage getCoverage() {\r
+            return coverage;\r
+        }\r
+        \r
+        @Override\r
+        public String toString() {\r
+            return name + " [priority=" + priority + ", executed=" + executed + ", duration=" + duration + "]";\r
+        }\r
+    }\r
+\r
+    static class STSSuite {\r
+        \r
+        private List<Pattern> moduleNameFilterPatterns = new ArrayList<>();\r
+        private final Resource suite;\r
+        private final String name;\r
+        private STSTest[] children;\r
+        private int startedCount;\r
+        private int errorCount;\r
+        private int failureCount;\r
+        private CoverageBuilder coverageBuilder;\r
+        \r
+        public STSSuite(Resource suite, String name, String moduleNameFilter) {\r
+            this.suite = suite;\r
+            this.name = name;\r
+            for (String s : moduleNameFilter.split(",")) {\r
+                try {\r
+                    s = s.trim().replaceAll("\\*", "\\\\w*").toLowerCase();\r
+                    moduleNameFilterPatterns.add(Pattern.compile(s));\r
+                } catch (PatternSyntaxException e) {\r
+                    e.printStackTrace();\r
+                }\r
+            }\r
+        }\r
+\r
+        public void children(STSTest[] children) {\r
+            this.children = children;\r
+        }\r
+\r
+        public STSTest[] getChildren() {\r
+            return children;\r
+        }\r
+\r
+        public String getName() {\r
+            return name;\r
+        }\r
+\r
+        public String getLabel() {\r
+            StringBuilder sb = new StringBuilder();\r
+            sb.append(name);\r
+            long totalTime = 0; \r
+            if (children != null) {\r
+                for (STSTest test : children) {\r
+                    if (test.executed || test.failed) {\r
+                        totalTime += test.duration;\r
+                    }\r
+                }\r
+            }\r
+            if (totalTime != 0)\r
+                sb.append(" (").append(totalTime).append(" ms)");\r
+            return sb.toString();\r
+        }\r
+\r
+        public boolean isRunning() {\r
+            boolean running = false;\r
+            if (children != null) {\r
+                for (STSTest test: children) {\r
+                    if (test.isRunning) {\r
+                        running = true;\r
+                        break;\r
+                    }\r
+                }\r
+            }\r
+            return running;\r
+        }\r
+\r
+        public boolean executed() {\r
+            boolean executed = true;\r
+            if (children != null) {\r
+                for (STSTest test: children) {\r
+                    if (!test.executed) {\r
+                        executed = false;\r
+                        break;\r
+                    }\r
+                }\r
+            }\r
+            return executed;\r
+        }\r
+\r
+        public boolean failed() {\r
+            boolean failed = false;\r
+            if (children != null) {\r
+                for (STSTest test: children) {\r
+                    if (test.failed) {\r
+                        failed = true;\r
+                        break;\r
+                    }\r
+                }\r
+            }\r
+            return failed;\r
+        }\r
+        \r
+        public void addCoverage(List<Module> modules) {\r
+            if (coverageBuilder == null) {\r
+                coverageBuilder = new CoverageBuilder();\r
+            }\r
+            for (Module module : modules)\r
+                coverageBuilder.addCoverage(module, true);\r
+        }\r
+\r
+        public CombinedCoverage getCoverage() {\r
+            if (coverageBuilder == null)\r
+                return null;\r
+            return coverageBuilder.getCoverage();\r
+        }\r
+    }\r
+\r
+    \r
+    private STSSuite suite;\r
+    private STSTest test;\r
+    private final List<STSExecutionListener> listeners = new ArrayList<>();\r
+    \r
+    public STSTestSuiteModel() {\r
+    }\r
+    \r
+    public void addListener(STSExecutionListener listener) {\r
+        listeners.add(listener);\r
+    }\r
+    \r
+    public void removeListener(STSExecutionListener listener) {\r
+        listeners.remove(listener);\r
+    }\r
+\r
+    public Object[] getElements() {\r
+        if (suite != null)\r
+            return new Object[] {suite};\r
+        else if (test != null)\r
+            return new Object[] {test};\r
+        else return null;\r
+    }\r
+\r
+    public void execute() {\r
+        \r
+        ModuleRepository repo = new ModuleRepository(SCLOsgi.SOURCE_REPOSITORY);\r
+        if (suite != null) {\r
+            repo.setAdvisor(new ModuleCompilationOptionsAdvisor() {\r
+                \r
+                @Override\r
+                public ModuleCompilationOptions getOptions(String moduleName) {\r
+                    boolean coverage = false;\r
+                    for (Pattern p : suite.moduleNameFilterPatterns) {\r
+                        if (p.matcher(moduleName.toLowerCase()).find()) {\r
+                            coverage = true;\r
+                            break;\r
+                        }\r
+                    }\r
+                    return new ModuleCompilationOptions(coverage);\r
+                }\r
+            });\r
+        }\r
+        CommandSession session = new CommandSession(repo, null);\r
+        if (suite != null) {\r
+            executeSuite(session);\r
+        } else if (test != null) {\r
+            executeTest(session);\r
+        }\r
+    }\r
+    \r
+    private void testExecuted() {\r
+        listeners.forEach(listener -> {\r
+            listener.testExecuted();\r
+        });\r
+    }\r
+    \r
+    private void executeSuite(CommandSession session) {\r
+        \r
+        for (STSTest test : suite.getChildren()) {\r
+            test.execute(session);\r
+            \r
+            Collection<RuntimeModule> runtimeModules = session.getRuntimeEnvironment().getRuntimeModules();\r
+            List<Module> modules = new ArrayList<>(runtimeModules.size());\r
+            for (RuntimeModule module : runtimeModules) {\r
+                for (Pattern p : suite.moduleNameFilterPatterns) {\r
+                    if (p.matcher(module.getModule().getName().toLowerCase()).find()) {\r
+                        modules.add(module.getModule());\r
+                    }\r
+                }\r
+            }\r
+            test.setCoverage(CoverageUtils.getCoverage(modules));\r
+            suite.addCoverage(modules);\r
+            \r
+            CoverageUtils.resetCoverage(modules);\r
+            \r
+            testExecuted();\r
+        }\r
+\r
+    }\r
+    \r
+    private void executeTest(CommandSession session) {\r
+        \r
+        test.execute(session);\r
+        testExecuted();\r
+        \r
+        Collection<RuntimeModule> runtimeModules = session.getRuntimeEnvironment().getRuntimeModules();\r
+        List<Module> modules = new ArrayList<>(runtimeModules.size());\r
+        for (RuntimeModule module : runtimeModules) {\r
+            modules.add(module.getModule());\r
+        }\r
+        test.setCoverage(CoverageUtils.getCoverage(modules));\r
+        \r
+        CoverageUtils.resetCoverage(modules);\r
+\r
+    }\r
+    \r
+\r
+    public boolean hasChildren(Object element) {\r
+        if (element instanceof STSTest) {\r
+            return false;\r
+        } else if (element instanceof STSSuite) {\r
+            STSSuite suite = (STSSuite) element;\r
+            return (suite.getChildren() != null ? suite.getChildren().length > 0 : false);\r
+        } else {\r
+            throw new IllegalArgumentException(element.toString());\r
+        }\r
+    }\r
+\r
+    public Object getParent(Object element) {\r
+        if (element instanceof STSTest) {\r
+            return ((STSTest) element).getParent();\r
+        } else if (element instanceof STSSuite) {\r
+            return null;\r
+        } else {\r
+            throw new IllegalArgumentException(element.toString());\r
+        }\r
+    }\r
+\r
+    public Object[] getChildren(Object parentElement) {\r
+        if (parentElement instanceof STSTest) {\r
+            return null;\r
+        } else if (parentElement instanceof STSSuite) {\r
+            STSSuite suite = (STSSuite) parentElement;\r
+            return suite.getChildren();\r
+        } else {\r
+            throw new IllegalArgumentException(parentElement.toString());\r
+        }\r
+    }\r
+\r
+    public String getText(Object element) {\r
+        if (element instanceof STSTest)\r
+            return ((STSTest)element).getLabel();\r
+        else if (element instanceof STSSuite)\r
+            return ((STSSuite)element).getLabel();\r
+        else\r
+            throw new IllegalArgumentException(element.toString());\r
+    }\r
+\r
+    public Image getImage(Object element) {\r
+        if (element instanceof STSSuite) {\r
+            STSSuite suite = (STSSuite) element;\r
+            if (suite.isRunning())\r
+                return STSTestSuiteProvider.suiteRunningIcon;\r
+            else if (suite.executed())\r
+                return STSTestSuiteProvider.suiteOkIcon;\r
+            else if (suite.failed())\r
+                return STSTestSuiteProvider.suiteFailIcon;\r
+            else\r
+                return STSTestSuiteProvider.suiteIcon;\r
+        } else if (element instanceof STSTest) {\r
+            STSTest test = (STSTest) element;\r
+            if (test.isRunning)\r
+                return STSTestSuiteProvider.testRunningIcon;\r
+            else if (test.executed)\r
+                return STSTestSuiteProvider.testOkIcon;\r
+            else if (test.failed)\r
+                return STSTestSuiteProvider.testFailIcon;\r
+            else\r
+                return STSTestSuiteProvider.testIcon;\r
+        }\r
+        return null;\r
+    }\r
+\r
+    public void updateInput(Resource root) {\r
+        suite = null;\r
+        test = null;\r
+        try {\r
+            Simantics.getSession().syncRequest(new ReadRequest() {\r
+                \r
+                @Override\r
+                public void run(ReadGraph graph) throws DatabaseException {\r
+                    Layer0 L0 = Layer0.getInstance(graph);\r
+                    TestsResource TESTS = TestsResource.getInstance(graph);\r
+                    if (graph.isInstanceOf(root, TESTS.STSTest)) {\r
+                        String testName = graph.getRelatedValue2(root, L0.HasName, Bindings.STRING);\r
+                        String definition = graph.getRelatedValue2(root, TESTS.STSTest_definition, Bindings.STRING);\r
+                        Integer executionPrioprity = graph.getRelatedValue2(root, TESTS.STSTest_executionPriority, Bindings.INTEGER);\r
+                        test = new STSTest(root, null, definition, testName, executionPrioprity);\r
+                    } else if (graph.isInstanceOf(root, TESTS.STSSuite)) {\r
+                        String suiteName = graph.getRelatedValue2(root, L0.HasName, Bindings.STRING);\r
+                        String moduleNameFilter = graph.getPossibleRelatedValue2(root, TESTS.STSSuite_moduleNameFilter, Bindings.STRING);\r
+                        suite = new STSSuite(root, suiteName, moduleNameFilter);\r
+                        List<STSTest> tests = new ArrayList<>();\r
+                        for (Resource test : graph.getObjects(root, L0.ConsistsOf)) {\r
+                            String testName = graph.getRelatedValue2(test, L0.HasName, Bindings.STRING);\r
+                            String definition = graph.getRelatedValue2(test, TESTS.STSTest_definition, Bindings.STRING);\r
+                            Integer executionPrioprity = graph.getRelatedValue2(test, TESTS.STSTest_executionPriority, Bindings.INTEGER);\r
+                            tests.add(new STSTest(test, suite, definition, testName, executionPrioprity));\r
+                        }\r
+                        Collections.sort(tests, (o1, o2) -> {\r
+                            if (o1.priority < o2.priority)\r
+                                return -1;\r
+                            if (o1.priority > o2.priority)\r
+                                return 1;\r
+                            return 0;\r
+                        });\r
+                        suite.children(tests.toArray(new STSTest[tests.size()]));\r
+                    } else {\r
+                        throw new IllegalArgumentException(root.toString());\r
+                    }\r
+                }\r
+            });\r
+        } catch (DatabaseException e) {\r
+            e.printStackTrace();\r
+        }\r
+    }\r
+\r
+    public List<String> getOutput(Object element) {\r
+        if (element instanceof STSTest) {\r
+            STSTest test = (STSTest) element;\r
+            return test.getOutput();\r
+        }\r
+        return Collections.emptyList();\r
+    }\r
+\r
+    public int getStartedCount() {\r
+        if (suite != null)\r
+            return suite.startedCount;\r
+        else\r
+            return 0;\r
+    }\r
+\r
+    public int getIgnoredCount() {\r
+        return 0;\r
+    }\r
+\r
+    public int getTotalCount() {\r
+        if (suite != null && suite.getChildren() != null)\r
+            return suite.getChildren().length;\r
+        else if (test != null)\r
+            return 1;\r
+        else\r
+            return 0;\r
+    }\r
+\r
+    public int getErrorCount() {\r
+        if (suite != null)\r
+            return suite.errorCount;\r
+        return 0;\r
+    }\r
+\r
+    public int getFailureCount() {\r
+        if (suite != null)\r
+            return suite.failureCount;\r
+        return 0;\r
+    }\r
+\r
+    public int getAssumptionFailureCount() {\r
+        return 0;\r
+    }\r
+\r
+    public boolean isStopped() {\r
+        if (suite != null)\r
+            return !suite.isRunning();\r
+        else\r
+            return test.isRunning;\r
+    }\r
+}\r
+\r
diff --git a/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSTestSuiteProvider.java b/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSTestSuiteProvider.java
new file mode 100644 (file)
index 0000000..a18b391
--- /dev/null
@@ -0,0 +1,104 @@
+package org.simantics.tests.modelled.ui;\r
+\r
+import org.eclipse.jface.resource.ImageDescriptor;\r
+import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider;\r
+import org.eclipse.jface.viewers.ITreeContentProvider;\r
+import org.eclipse.jface.viewers.LabelProvider;\r
+import org.eclipse.jface.viewers.StyledString;\r
+import org.eclipse.jface.viewers.Viewer;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.simantics.db.Resource;\r
+\r
+public class STSTestSuiteProvider extends LabelProvider implements ITreeContentProvider, IStyledLabelProvider {\r
+\r
+    private static final ImageDescriptor testIconDescriptor = Activator.getImageDescriptor("icons/test.png"); //$NON-NLS-1$\r
+    private static final ImageDescriptor testOkIconDescriptor = Activator.getImageDescriptor("icons/testok.png"); //$NON-NLS-1$\r
+    private static final ImageDescriptor testErrorIconDescriptor = Activator.getImageDescriptor("icons/testerr.png"); //$NON-NLS-1$\r
+    private static final ImageDescriptor testFailIconDescriptor = Activator.getImageDescriptor("icons/testfail.png"); //$NON-NLS-1$\r
+    private static final ImageDescriptor testRunningIconDescriptor = Activator.getImageDescriptor("icons/testrun.png"); //$NON-NLS-1$\r
+\r
+    private static final ImageDescriptor suiteIconDescriptor = Activator.getImageDescriptor("icons/tsuite.png"); //$NON-NLS-1$\r
+    private static final ImageDescriptor suiteOkIconDescriptor = Activator.getImageDescriptor("icons/tsuiteok.png"); //$NON-NLS-1$\r
+    private static final ImageDescriptor suiteErrorIconDescriptor = Activator.getImageDescriptor("icons/tsuiteerror.png"); //$NON-NLS-1$\r
+    private static final ImageDescriptor suiteFailIconDescriptor = Activator.getImageDescriptor("icons/tsuitefail.png"); //$NON-NLS-1$\r
+    private static final ImageDescriptor suiteRunningIconDescriptor = Activator.getImageDescriptor("icons/tsuiterun.png"); //$NON-NLS-1$\r
+\r
+    static Image testIcon;\r
+    static Image testOkIcon;\r
+    static Image testErrorIcon;\r
+    static Image testFailIcon;\r
+    static Image testRunningIcon;\r
+\r
+    static Image suiteIcon;\r
+    static Image suiteOkIcon;\r
+    static Image suiteErrorIcon;\r
+    static Image suiteFailIcon;\r
+    static Image suiteRunningIcon;\r
+    \r
+    private STSTestSuiteModel model;\r
+    \r
+    public STSTestSuiteProvider(STSTestSuiteModel model) {\r
+        this.model = model;\r
+        testIcon = Activator.createManagedImage(testIconDescriptor);\r
+        testOkIcon = Activator.createManagedImage(testOkIconDescriptor);\r
+        testErrorIcon = Activator.createManagedImage(testErrorIconDescriptor);\r
+        testFailIcon = Activator.createManagedImage(testFailIconDescriptor);\r
+        testRunningIcon = Activator.createManagedImage(testRunningIconDescriptor);\r
+        \r
+        suiteIcon = Activator.createManagedImage(suiteIconDescriptor);\r
+        suiteOkIcon = Activator.createManagedImage(suiteOkIconDescriptor);\r
+        suiteErrorIcon = Activator.createManagedImage(suiteErrorIconDescriptor);\r
+        suiteFailIcon = Activator.createManagedImage(suiteFailIconDescriptor);\r
+        suiteRunningIcon = Activator.createManagedImage(suiteRunningIconDescriptor);\r
+    }\r
+\r
+    @Override\r
+    public Object[] getElements(Object inputElement) {\r
+        return model.getElements();\r
+    }\r
+\r
+    @Override\r
+    public Object[] getChildren(Object parentElement) {\r
+        return model.getChildren(parentElement);\r
+    }\r
+\r
+    @Override\r
+    public Object getParent(Object element) {\r
+        return model.getParent(element);\r
+    }\r
+\r
+    @Override\r
+    public boolean hasChildren(Object element) {\r
+        return model.hasChildren(element);\r
+    }\r
+\r
+    @Override\r
+    public StyledString getStyledText(Object element) {\r
+        // TODO Auto-generated method stub\r
+        return null;\r
+    }\r
+    \r
+    @Override\r
+    public String getText(Object element) {\r
+        return model.getText(element);\r
+    }\r
+    \r
+    @Override\r
+    public Image getImage(Object element) {\r
+        return model.getImage(element);\r
+    }\r
+\r
+    @Override\r
+    public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {\r
+        if (newInput != null) {\r
+            if (!(newInput instanceof Resource))\r
+                throw new IllegalArgumentException(newInput.toString());\r
+            model.updateInput((Resource)newInput);\r
+        }\r
+    }\r
+\r
+    public STSTestSuiteModel getModel() {\r
+        return model;\r
+    }\r
+\r
+}\r
diff --git a/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/TestsUIUtils.java b/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/TestsUIUtils.java
new file mode 100644 (file)
index 0000000..c6bd1c2
--- /dev/null
@@ -0,0 +1,23 @@
+package org.simantics.tests.modelled.ui;\r
+\r
+import java.io.IOException;\r
+\r
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.ui.workbench.e4.E4WorkbenchUtils;\r
+\r
+public class TestsUIUtils {\r
+\r
+    private TestsUIUtils() {\r
+    }\r
+\r
+    public static void runSTSTestAction(Resource test) throws DatabaseException, IOException {\r
+        MPart part = E4WorkbenchUtils.getMPartById(STSTestRunnerView.ID);\r
+        E4WorkbenchUtils.openAndShowPart(part);\r
+        Object obj = part.getObject();\r
+        STSTestRunnerView view = (STSTestRunnerView) obj;\r
+        view.currentTest(test);\r
+        view.execute();\r
+    }\r
+}\r
diff --git a/bundles/org.simantics.tests.modelled/.classpath b/bundles/org.simantics.tests.modelled/.classpath
new file mode 100644 (file)
index 0000000..b862a29
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>\r
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>\r
+       <classpathentry kind="src" path="src"/>\r
+       <classpathentry kind="output" path="bin"/>\r
+</classpath>\r
diff --git a/bundles/org.simantics.tests.modelled/.project b/bundles/org.simantics.tests.modelled/.project
new file mode 100644 (file)
index 0000000..ca98d66
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+       <name>org.simantics.tests.modelled</name>\r
+       <comment></comment>\r
+       <projects>\r
+       </projects>\r
+       <buildSpec>\r
+               <buildCommand>\r
+                       <name>org.eclipse.jdt.core.javabuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.ManifestBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.SchemaBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+       </buildSpec>\r
+       <natures>\r
+               <nature>org.eclipse.pde.PluginNature</nature>\r
+               <nature>org.eclipse.jdt.core.javanature</nature>\r
+       </natures>\r
+</projectDescription>\r
diff --git a/bundles/org.simantics.tests.modelled/.settings/org.eclipse.jdt.core.prefs b/bundles/org.simantics.tests.modelled/.settings/org.eclipse.jdt.core.prefs
new file mode 100644 (file)
index 0000000..295926d
--- /dev/null
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1\r
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled\r
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8\r
+org.eclipse.jdt.core.compiler.compliance=1.8\r
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error\r
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error\r
+org.eclipse.jdt.core.compiler.source=1.8\r
diff --git a/bundles/org.simantics.tests.modelled/META-INF/MANIFEST.MF b/bundles/org.simantics.tests.modelled/META-INF/MANIFEST.MF
new file mode 100644 (file)
index 0000000..662bca7
--- /dev/null
@@ -0,0 +1,16 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Simantics Modelled Tests
+Bundle-SymbolicName: org.simantics.tests.modelled
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.simantics.tests.modelled.Activator
+Require-Bundle: org.eclipse.core.runtime,
+ org.simantics.db,
+ org.simantics.db.common,
+ org.simantics.tests.modelled.ontology,
+ org.simantics.scl.osgi,
+ org.simantics,
+ org.simantics.scl.compiler
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Bundle-ActivationPolicy: lazy
+Export-Package: org.simantics.tests.modelled
diff --git a/bundles/org.simantics.tests.modelled/build.properties b/bundles/org.simantics.tests.modelled/build.properties
new file mode 100644 (file)
index 0000000..0a70903
--- /dev/null
@@ -0,0 +1,6 @@
+source.. = src/\r
+output.. = bin/\r
+bin.includes = META-INF/,\\r
+               .,\\r
+               scl/\r
+src.includes = scl/\r
diff --git a/bundles/org.simantics.tests.modelled/scl/Simantics/Tests.scl b/bundles/org.simantics.tests.modelled/scl/Simantics/Tests.scl
new file mode 100644 (file)
index 0000000..fb2d4bf
--- /dev/null
@@ -0,0 +1,5 @@
+include "Simantics/DB"\r
+\r
+importJava "org.simantics.tests.TestsGraphUtils" where\r
+    createSTSTest :: Resource -> <Proc, WriteGraph> Resource\r
+    createSTSSuite :: Resource -> <WriteGraph, Proc> ()\r
diff --git a/bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/Activator.java b/bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/Activator.java
new file mode 100644 (file)
index 0000000..4cc9ece
--- /dev/null
@@ -0,0 +1,30 @@
+package org.simantics.tests.modelled;\r
+\r
+import org.osgi.framework.BundleActivator;\r
+import org.osgi.framework.BundleContext;\r
+\r
+public class Activator implements BundleActivator {\r
+\r
+       private static BundleContext context;\r
+\r
+       static BundleContext getContext() {\r
+               return context;\r
+       }\r
+\r
+       /*\r
+        * (non-Javadoc)\r
+        * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)\r
+        */\r
+       public void start(BundleContext bundleContext) throws Exception {\r
+               Activator.context = bundleContext;\r
+       }\r
+\r
+       /*\r
+        * (non-Javadoc)\r
+        * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)\r
+        */\r
+       public void stop(BundleContext bundleContext) throws Exception {\r
+               Activator.context = null;\r
+       }\r
+\r
+}\r
diff --git a/bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/TestsGraphUtils.java b/bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/TestsGraphUtils.java
new file mode 100644 (file)
index 0000000..cf5c8e3
--- /dev/null
@@ -0,0 +1,98 @@
+package org.simantics.tests.modelled;\r
+\r
+import java.io.BufferedReader;\r
+import java.io.IOException;\r
+import java.io.StringReader;\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.List;\r
+import java.util.regex.Pattern;\r
+\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.scl.compiler.commands.CommandSession;\r
+import org.simantics.scl.compiler.commands.TestScriptExecutor;\r
+import org.simantics.scl.compiler.module.Module;\r
+import org.simantics.scl.compiler.module.coverage.CombinedCoverage;\r
+import org.simantics.scl.compiler.module.coverage.CoverageUtils;\r
+import org.simantics.scl.compiler.module.options.ModuleCompilationOptions;\r
+import org.simantics.scl.compiler.module.options.ModuleCompilationOptionsAdvisor;\r
+import org.simantics.scl.compiler.module.repository.ModuleRepository;\r
+import org.simantics.scl.compiler.runtime.RuntimeModule;\r
+import org.simantics.scl.osgi.SCLOsgi;\r
+import org.simantics.scl.runtime.reporting.SCLReportingHandler;\r
+import org.simantics.tests.modelled.ontology.TestsResource;\r
+\r
+public class TestsGraphUtils {\r
+\r
+    private static final String STS_TEST_PREFIX = "STSTest";\r
+    private static final String STS_SUITE_PREFIX = "STSSuite";\r
+    \r
+    private TestsGraphUtils() {}\r
+    \r
+    public static Resource createSTSTest(WriteGraph graph, Resource parent) throws DatabaseException {\r
+        String name = NameUtils.findFreshEscapedName(graph, STS_TEST_PREFIX, parent);\r
+        Resource stsTest = graph.newResource();\r
+        \r
+        Layer0 L0 = Layer0.getInstance(graph);\r
+        TestsResource TESTS = TestsResource.getInstance(graph);\r
+        \r
+        graph.claim(parent, L0.ConsistsOf, L0.PartOf, stsTest);\r
+        graph.claim(stsTest, L0.InstanceOf, TESTS.STSTest);\r
+        graph.claimLiteral(stsTest, L0.HasName, name, Bindings.STRING);\r
+        graph.claimLiteral(stsTest, TESTS.STSTest_definition, "", Bindings.STRING);\r
+        return stsTest;\r
+    }\r
+    \r
+    public static Resource createSTSSuite(WriteGraph graph, Resource parent) throws DatabaseException {\r
+        String name = NameUtils.findFreshEscapedName(graph, STS_SUITE_PREFIX, parent);\r
+        Resource stsSuite = graph.newResource();\r
+        \r
+        Layer0 L0 = Layer0.getInstance(graph);\r
+        TestsResource TESTS = TestsResource.getInstance(graph);\r
+        \r
+        graph.claim(parent, L0.ConsistsOf, L0.PartOf, stsSuite);\r
+        graph.claim(stsSuite, L0.InstanceOf, TESTS.STSSuite);\r
+        graph.claimLiteral(stsSuite, L0.HasName, name, Bindings.STRING);\r
+        return stsSuite;\r
+    }\r
+\r
+    public static CombinedCoverage runSTSTestDefinition(String definition, List<Pattern> moduleNameFilters, SCLReportingHandler handler) throws IOException {\r
+        \r
+//        ModuleRepository repo = SCLOsgi.MODULE_REPOSITORY;\r
+        ModuleRepository repo = new ModuleRepository(SCLOsgi.SOURCE_REPOSITORY);\r
+        repo.setAdvisor(new ModuleCompilationOptionsAdvisor() {\r
+            \r
+            @Override\r
+            public ModuleCompilationOptions getOptions(String moduleName) {\r
+                boolean coverage = false;\r
+                for (Pattern p : moduleNameFilters) {\r
+                    if (p.matcher(moduleName.toLowerCase()).find()) {\r
+                        coverage = true;\r
+                        break;\r
+                    }\r
+                }\r
+                return new ModuleCompilationOptions(coverage);\r
+            }\r
+        });\r
+        \r
+        CommandSession session = new CommandSession(repo, handler);\r
+        TestScriptExecutor executor = new TestScriptExecutor(session, new BufferedReader(new StringReader(definition)), handler);\r
+        try {\r
+            executor.execute();\r
+        } catch (Throwable t) {\r
+            t.printStackTrace();\r
+        }\r
+        Collection<RuntimeModule> runtimeModules = session.getRuntimeEnvironment().getRuntimeModules();\r
+        List<Module> modules = new ArrayList<>(runtimeModules.size());\r
+        for (RuntimeModule module : runtimeModules) {\r
+            modules.add(module.getModule());\r
+        }\r
+        CombinedCoverage coverage = CoverageUtils.getCoverage(modules);\r
+        return coverage;\r
+    }\r
+}\r
diff --git a/features/org.simantics.tests.modelled.feature/.project b/features/org.simantics.tests.modelled.feature/.project
new file mode 100644 (file)
index 0000000..e3686c8
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+       <name>org.simantics.tests.modelled.feature</name>\r
+       <comment></comment>\r
+       <projects>\r
+       </projects>\r
+       <buildSpec>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.FeatureBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+       </buildSpec>\r
+       <natures>\r
+               <nature>org.eclipse.pde.FeatureNature</nature>\r
+       </natures>\r
+</projectDescription>\r
diff --git a/features/org.simantics.tests.modelled.feature/build.properties b/features/org.simantics.tests.modelled.feature/build.properties
new file mode 100644 (file)
index 0000000..82ab19c
--- /dev/null
@@ -0,0 +1 @@
+bin.includes = feature.xml\r
diff --git a/features/org.simantics.tests.modelled.feature/feature.xml b/features/org.simantics.tests.modelled.feature/feature.xml
new file mode 100644 (file)
index 0000000..780d5dc
--- /dev/null
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<feature\r
+      id="org.simantics.tests.feature"\r
+      label="Simantics Tests Feature"\r
+      version="1.0.0.qualifier"\r
+      provider-name="Semantum Oy">\r
+\r
+   <description url="http://www.example.com/description">\r
+      [Enter Feature Description here.]\r
+   </description>\r
+\r
+   <copyright url="http://www.example.com/copyright">\r
+      [Enter Copyright Description here.]\r
+   </copyright>\r
+\r
+   <license url="http://www.example.com/license">\r
+      [Enter License Description here.]\r
+   </license>\r
+\r
+   <plugin\r
+         id="org.simantics.tests.modelled"\r
+         download-size="0"\r
+         install-size="0"\r
+         version="0.0.0"\r
+         unpack="false"/>\r
+\r
+   <plugin\r
+         id="org.simantics.tests.modelled.ontology"\r
+         download-size="0"\r
+         install-size="0"\r
+         version="0.0.0"\r
+         unpack="false"/>\r
+\r
+</feature>\r
diff --git a/features/org.simantics.tests.modelled.ui.feature/.project b/features/org.simantics.tests.modelled.ui.feature/.project
new file mode 100644 (file)
index 0000000..92afdc9
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+       <name>org.simantics.tests.modelled.ui.feature</name>\r
+       <comment></comment>\r
+       <projects>\r
+       </projects>\r
+       <buildSpec>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.FeatureBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+       </buildSpec>\r
+       <natures>\r
+               <nature>org.eclipse.pde.FeatureNature</nature>\r
+       </natures>\r
+</projectDescription>\r
diff --git a/features/org.simantics.tests.modelled.ui.feature/build.properties b/features/org.simantics.tests.modelled.ui.feature/build.properties
new file mode 100644 (file)
index 0000000..82ab19c
--- /dev/null
@@ -0,0 +1 @@
+bin.includes = feature.xml\r
diff --git a/features/org.simantics.tests.modelled.ui.feature/feature.xml b/features/org.simantics.tests.modelled.ui.feature/feature.xml
new file mode 100644 (file)
index 0000000..ae4c698
--- /dev/null
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<feature\r
+      id="org.simantics.tests.ui.feature"\r
+      label="Simantics Tests UI Feature"\r
+      version="1.0.0.qualifier">\r
+\r
+   <description url="http://www.example.com/description">\r
+      [Enter Feature Description here.]\r
+   </description>\r
+\r
+   <copyright url="http://www.example.com/copyright">\r
+      [Enter Copyright Description here.]\r
+   </copyright>\r
+\r
+   <license url="http://www.example.com/license">\r
+      [Enter License Description here.]\r
+   </license>\r
+\r
+   <plugin\r
+         id="org.simantics.tests.modelled.ui"\r
+         download-size="0"\r
+         install-size="0"\r
+         version="0.0.0"\r
+         unpack="false"/>\r
+\r
+   <plugin\r
+         id="org.simantics.tests.modelled.ui.ontology"\r
+         download-size="0"\r
+         install-size="0"\r
+         version="0.0.0"\r
+         unpack="false"/>\r
+\r
+</feature>\r