aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/language
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2022-07-29 21:58:47 +0200
committerLibravatar Kristóf Marussy <kristof@marussy.com>2022-07-29 21:58:47 +0200
commit1d43c802f853b08f03c4b3954af242ad005c8afd (patch)
tree9a98da19c07fc587b6a3e2283aca707ad345e252 /subprojects/language
parentbuild: clean up buildSrc scripts (diff)
downloadrefinery-1d43c802f853b08f03c4b3954af242ad005c8afd.tar.gz
refinery-1d43c802f853b08f03c4b3954af242ad005c8afd.tar.zst
refinery-1d43c802f853b08f03c4b3954af242ad005c8afd.zip
refactor: simplify language project
* Move all utilities for language-model to language, since they do not make sense on their own * Convert xtend code into java
Diffstat (limited to 'subprojects/language')
-rw-r--r--subprojects/language/build.gradle7
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/ProblemStandaloneSetup.java30
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/ProblemUtil.java11
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/ProblemXmiRuntimeModule.java35
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/resource/ProblemLocationInFileProvider.java2
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java2
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemGlobalScopeProvider.java2
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemLocalScopeProvider.java2
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemScopeProvider.java4
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java2
-rw-r--r--subprojects/language/src/main/resources/tools/refinery/language/builtin.problem21
-rw-r--r--subprojects/language/src/test/java/tools/refinery/language/tests/ProblemParsingTest.java58
-rw-r--r--subprojects/language/src/test/java/tools/refinery/language/tests/ProblemParsingTest_.xtend64
-rw-r--r--subprojects/language/src/test/java/tools/refinery/language/tests/formatting2/ProblemFormatterTest.java2
-rw-r--r--subprojects/language/src/test/java/tools/refinery/language/tests/rules/DirectRuleParsingTest.java84
-rw-r--r--subprojects/language/src/test/java/tools/refinery/language/tests/rules/DirectRuleParsingTest_.xtend96
-rw-r--r--subprojects/language/src/test/java/tools/refinery/language/tests/scoping/NodeScopingTest.java321
-rw-r--r--subprojects/language/src/test/java/tools/refinery/language/tests/scoping/NodeScopingTest_.xtend322
-rw-r--r--subprojects/language/src/test/java/tools/refinery/language/tests/serializer/ProblemSerializerTest.java31
-rw-r--r--subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/ProblemNavigationUtil.java20
-rw-r--r--subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/ProblemParseHelper.java22
-rw-r--r--subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedActionLiteral.java25
-rw-r--r--subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedArgument.java25
-rw-r--r--subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedAssertion.java13
-rw-r--r--subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedAssertionArgument.java15
-rw-r--r--subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedAtom.java13
-rw-r--r--subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedClassDeclaration.java14
-rw-r--r--subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedConjunction.java13
-rw-r--r--subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedEnumDeclaration.java14
-rw-r--r--subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedLiteral.java24
-rw-r--r--subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedParametricDefinition.java16
-rw-r--r--subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedPredicateDefinition.java11
-rw-r--r--subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedProblem.java85
-rw-r--r--subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedRuleDefinition.java14
34 files changed, 849 insertions, 571 deletions
diff --git a/subprojects/language/build.gradle b/subprojects/language/build.gradle
index 91b65c82..654558e3 100644
--- a/subprojects/language/build.gradle
+++ b/subprojects/language/build.gradle
@@ -3,7 +3,6 @@ plugins {
3 id 'refinery-java-test-fixtures' 3 id 'refinery-java-test-fixtures'
4 id 'refinery-mwe2' 4 id 'refinery-mwe2'
5 id 'refinery-sonarqube' 5 id 'refinery-sonarqube'
6 id 'refinery-xtend'
7 id 'refinery-xtext-conventions' 6 id 'refinery-xtext-conventions'
8} 7}
9 8
@@ -14,7 +13,6 @@ dependencies {
14 api libs.xtext.xbase 13 api libs.xtext.xbase
15 api project(':refinery-language-model') 14 api project(':refinery-language-model')
16 testFixturesApi libs.xtext.testing 15 testFixturesApi libs.xtext.testing
17 testFixturesApi testFixtures(project(':refinery-language-model'))
18 mwe2 libs.xtext.generator 16 mwe2 libs.xtext.generator
19 mwe2 libs.xtext.generator.antlr 17 mwe2 libs.xtext.generator.antlr
20} 18}
@@ -50,7 +48,6 @@ for (taskName in [
50 'compileJava', 48 'compileJava',
51 'processResources', 49 'processResources',
52 'processTestFixturesResources', 50 'processTestFixturesResources',
53 'generateXtext',
54 'generateEclipseSourceFolders' 51 'generateEclipseSourceFolders'
55 ]) { 52 ]) {
56 tasks.named(taskName) { 53 tasks.named(taskName) {
@@ -70,3 +67,7 @@ sonarqube.properties {
70 'src/testFixtures/xtext-gen/**', 67 'src/testFixtures/xtext-gen/**',
71 ] 68 ]
72} 69}
70
71eclipse.project.natures += [
72 'org.eclipse.xtext.ui.shared.xtextNature'
73]
diff --git a/subprojects/language/src/main/java/tools/refinery/language/ProblemStandaloneSetup.java b/subprojects/language/src/main/java/tools/refinery/language/ProblemStandaloneSetup.java
index d753a119..41c96114 100644
--- a/subprojects/language/src/main/java/tools/refinery/language/ProblemStandaloneSetup.java
+++ b/subprojects/language/src/main/java/tools/refinery/language/ProblemStandaloneSetup.java
@@ -3,14 +3,11 @@
3 */ 3 */
4package tools.refinery.language; 4package tools.refinery.language;
5 5
6import org.eclipse.emf.ecore.resource.Resource; 6import org.eclipse.emf.ecore.EPackage;
7import org.eclipse.xtext.resource.IResourceFactory;
8import org.eclipse.xtext.resource.IResourceServiceProvider;
9 7
10import com.google.inject.Guice;
11import com.google.inject.Injector; 8import com.google.inject.Injector;
12 9
13import tools.refinery.language.model.ProblemEMFSetup; 10import tools.refinery.language.model.problem.ProblemPackage;
14 11
15/** 12/**
16 * Initialization support for running Xtext languages without Equinox extension 13 * Initialization support for running Xtext languages without Equinox extension
@@ -22,23 +19,16 @@ public class ProblemStandaloneSetup extends ProblemStandaloneSetupGenerated {
22 new ProblemStandaloneSetup().createInjectorAndDoEMFRegistration(); 19 new ProblemStandaloneSetup().createInjectorAndDoEMFRegistration();
23 } 20 }
24 21
22 // Here we can't rely on java.util.HashMap#putIfAbsent, because
23 // org.eclipse.emf.ecore.impl.EPackageRegistryImpl#containsKey is overridden
24 // without also overriding putIfAbsent. We must make sure to call the
25 // overridden containsKey implementation.
26 @SuppressWarnings("squid:S3824")
25 @Override 27 @Override
26 public Injector createInjectorAndDoEMFRegistration() { 28 public Injector createInjectorAndDoEMFRegistration() {
27 ProblemEMFSetup.doEMFRegistration(); 29 if (!EPackage.Registry.INSTANCE.containsKey(ProblemPackage.eNS_URI)) {
28 var xmiInjector = createXmiInjector(); 30 EPackage.Registry.INSTANCE.put(ProblemPackage.eNS_URI, ProblemPackage.eINSTANCE);
29 registerXmiInjector(xmiInjector); 31 }
30 return super.createInjectorAndDoEMFRegistration(); 32 return super.createInjectorAndDoEMFRegistration();
31 } 33 }
32
33 protected Injector createXmiInjector() {
34 return Guice.createInjector(new ProblemXmiRuntimeModule());
35 }
36
37 protected void registerXmiInjector(Injector injector) {
38 IResourceFactory resourceFactory = injector.getInstance(IResourceFactory.class);
39 IResourceServiceProvider serviceProvider = injector.getInstance(IResourceServiceProvider.class);
40
41 Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put(ProblemEMFSetup.XMI_RESOURCE_EXTENSION, resourceFactory);
42 IResourceServiceProvider.Registry.INSTANCE.getExtensionToFactoryMap().put(ProblemEMFSetup.XMI_RESOURCE_EXTENSION, serviceProvider);
43 }
44} 34}
diff --git a/subprojects/language/src/main/java/tools/refinery/language/ProblemUtil.java b/subprojects/language/src/main/java/tools/refinery/language/ProblemUtil.java
index d8958381..b1e39176 100644
--- a/subprojects/language/src/main/java/tools/refinery/language/ProblemUtil.java
+++ b/subprojects/language/src/main/java/tools/refinery/language/ProblemUtil.java
@@ -1,4 +1,4 @@
1package tools.refinery.language.model; 1package tools.refinery.language;
2 2
3import java.util.ArrayDeque; 3import java.util.ArrayDeque;
4import java.util.Collection; 4import java.util.Collection;
@@ -34,15 +34,15 @@ public final class ProblemUtil {
34 public static boolean isSingletonVariable(Variable variable) { 34 public static boolean isSingletonVariable(Variable variable) {
35 return variable.eContainingFeature() == ProblemPackage.Literals.VARIABLE_OR_NODE_ARGUMENT__SINGLETON_VARIABLE; 35 return variable.eContainingFeature() == ProblemPackage.Literals.VARIABLE_OR_NODE_ARGUMENT__SINGLETON_VARIABLE;
36 } 36 }
37 37
38 public static boolean isImplicitVariable(Variable variable) { 38 public static boolean isImplicitVariable(Variable variable) {
39 return variable instanceof ImplicitVariable; 39 return variable instanceof ImplicitVariable;
40 } 40 }
41 41
42 public static boolean isImplicitNode(Node node) { 42 public static boolean isImplicitNode(Node node) {
43 return node.eContainingFeature() == ProblemPackage.Literals.PROBLEM__NODES; 43 return node.eContainingFeature() == ProblemPackage.Literals.PROBLEM__NODES;
44 } 44 }
45 45
46 public static boolean isImplicit(EObject eObject) { 46 public static boolean isImplicit(EObject eObject) {
47 if (eObject instanceof Node node) { 47 if (eObject instanceof Node node) {
48 return isImplicitNode(node); 48 return isImplicitNode(node);
@@ -115,7 +115,6 @@ public final class ProblemUtil {
115 115
116 private static URI getLibraryUri(String libraryName) { 116 private static URI getLibraryUri(String libraryName) {
117 return URI.createURI(ProblemUtil.class.getClassLoader() 117 return URI.createURI(ProblemUtil.class.getClassLoader()
118 .getResource("model/" + libraryName + "." + ProblemEMFSetup.XMI_RESOURCE_EXTENSION) 118 .getResource("tools/refinery/language/%s.problem".formatted(libraryName)).toString());
119 .toString());
120 } 119 }
121} 120}
diff --git a/subprojects/language/src/main/java/tools/refinery/language/ProblemXmiRuntimeModule.java b/subprojects/language/src/main/java/tools/refinery/language/ProblemXmiRuntimeModule.java
deleted file mode 100644
index 03a33bee..00000000
--- a/subprojects/language/src/main/java/tools/refinery/language/ProblemXmiRuntimeModule.java
+++ /dev/null
@@ -1,35 +0,0 @@
1package tools.refinery.language;
2
3import org.eclipse.xtext.naming.IQualifiedNameConverter;
4import org.eclipse.xtext.resource.IDefaultResourceDescriptionStrategy;
5import org.eclipse.xtext.resource.IResourceFactory;
6import org.eclipse.xtext.resource.generic.AbstractGenericResourceRuntimeModule;
7
8import tools.refinery.language.model.ProblemEMFSetup;
9import tools.refinery.language.naming.ProblemQualifiedNameConverter;
10import tools.refinery.language.resource.ProblemResourceDescriptionStrategy;
11import tools.refinery.language.resource.ProblemXmiResourceFactory;
12
13public class ProblemXmiRuntimeModule extends AbstractGenericResourceRuntimeModule {
14 @Override
15 protected String getLanguageName() {
16 return "tools.refinery.language.ProblemXmi";
17 }
18
19 @Override
20 protected String getFileExtensions() {
21 return ProblemEMFSetup.XMI_RESOURCE_EXTENSION;
22 }
23
24 public Class<? extends IResourceFactory> bindIResourceFactory() {
25 return ProblemXmiResourceFactory.class;
26 }
27
28 public Class<? extends IQualifiedNameConverter> bindIQualifiedNameConverter() {
29 return ProblemQualifiedNameConverter.class;
30 }
31
32 public Class<? extends IDefaultResourceDescriptionStrategy> bindIDefaultResourceDescriptionStrategy() {
33 return ProblemResourceDescriptionStrategy.class;
34 }
35}
diff --git a/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemLocationInFileProvider.java b/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemLocationInFileProvider.java
index 7aa75833..f6ae4f1e 100644
--- a/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemLocationInFileProvider.java
+++ b/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemLocationInFileProvider.java
@@ -4,7 +4,7 @@ import org.eclipse.emf.ecore.EObject;
4import org.eclipse.xtext.resource.DefaultLocationInFileProvider; 4import org.eclipse.xtext.resource.DefaultLocationInFileProvider;
5import org.eclipse.xtext.util.ITextRegion; 5import org.eclipse.xtext.util.ITextRegion;
6 6
7import tools.refinery.language.model.ProblemUtil; 7import tools.refinery.language.ProblemUtil;
8import tools.refinery.language.model.problem.ImplicitVariable; 8import tools.refinery.language.model.problem.ImplicitVariable;
9import tools.refinery.language.model.problem.Node; 9import tools.refinery.language.model.problem.Node;
10 10
diff --git a/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java b/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java
index f86ebd38..24d00f07 100644
--- a/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java
+++ b/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java
@@ -12,7 +12,7 @@ import org.eclipse.xtext.util.IAcceptor;
12import com.google.inject.Inject; 12import com.google.inject.Inject;
13import com.google.inject.Singleton; 13import com.google.inject.Singleton;
14 14
15import tools.refinery.language.model.ProblemUtil; 15import tools.refinery.language.ProblemUtil;
16import tools.refinery.language.model.problem.NamedElement; 16import tools.refinery.language.model.problem.NamedElement;
17import tools.refinery.language.model.problem.Node; 17import tools.refinery.language.model.problem.Node;
18import tools.refinery.language.model.problem.Problem; 18import tools.refinery.language.model.problem.Problem;
diff --git a/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemGlobalScopeProvider.java b/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemGlobalScopeProvider.java
index b582d16b..ea4682f9 100644
--- a/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemGlobalScopeProvider.java
+++ b/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemGlobalScopeProvider.java
@@ -6,7 +6,7 @@ import org.eclipse.emf.common.util.URI;
6import org.eclipse.emf.ecore.resource.Resource; 6import org.eclipse.emf.ecore.resource.Resource;
7import org.eclipse.xtext.scoping.impl.ImportUriGlobalScopeProvider; 7import org.eclipse.xtext.scoping.impl.ImportUriGlobalScopeProvider;
8 8
9import tools.refinery.language.model.ProblemUtil; 9import tools.refinery.language.ProblemUtil;
10 10
11public class ProblemGlobalScopeProvider extends ImportUriGlobalScopeProvider { 11public class ProblemGlobalScopeProvider extends ImportUriGlobalScopeProvider {
12 @Override 12 @Override
diff --git a/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemLocalScopeProvider.java b/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemLocalScopeProvider.java
index 85797025..53815e37 100644
--- a/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemLocalScopeProvider.java
+++ b/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemLocalScopeProvider.java
@@ -13,7 +13,7 @@ import org.eclipse.xtext.scoping.impl.ImportedNamespaceAwareLocalScopeProvider;
13 13
14import com.google.inject.Inject; 14import com.google.inject.Inject;
15 15
16import tools.refinery.language.model.ProblemUtil; 16import tools.refinery.language.ProblemUtil;
17 17
18public class ProblemLocalScopeProvider extends ImportedNamespaceAwareLocalScopeProvider { 18public class ProblemLocalScopeProvider extends ImportedNamespaceAwareLocalScopeProvider {
19 private static final QualifiedName BUILTIN_LIBRARY_QUALIFIED_NAME = QualifiedName 19 private static final QualifiedName BUILTIN_LIBRARY_QUALIFIED_NAME = QualifiedName
diff --git a/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemScopeProvider.java b/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemScopeProvider.java
index d31a5308..7a3e77a4 100644
--- a/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemScopeProvider.java
+++ b/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemScopeProvider.java
@@ -12,12 +12,12 @@ import org.eclipse.xtext.EcoreUtil2;
12import org.eclipse.xtext.scoping.IScope; 12import org.eclipse.xtext.scoping.IScope;
13import org.eclipse.xtext.scoping.Scopes; 13import org.eclipse.xtext.scoping.Scopes;
14 14
15import tools.refinery.language.model.ProblemUtil; 15import tools.refinery.language.ProblemUtil;
16import tools.refinery.language.model.problem.Action;
16import tools.refinery.language.model.problem.ClassDeclaration; 17import tools.refinery.language.model.problem.ClassDeclaration;
17import tools.refinery.language.model.problem.ExistentialQuantifier; 18import tools.refinery.language.model.problem.ExistentialQuantifier;
18import tools.refinery.language.model.problem.NewActionLiteral; 19import tools.refinery.language.model.problem.NewActionLiteral;
19import tools.refinery.language.model.problem.ParametricDefinition; 20import tools.refinery.language.model.problem.ParametricDefinition;
20import tools.refinery.language.model.problem.Action;
21import tools.refinery.language.model.problem.Problem; 21import tools.refinery.language.model.problem.Problem;
22import tools.refinery.language.model.problem.ProblemPackage; 22import tools.refinery.language.model.problem.ProblemPackage;
23import tools.refinery.language.model.problem.ReferenceDeclaration; 23import tools.refinery.language.model.problem.ReferenceDeclaration;
diff --git a/subprojects/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java b/subprojects/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java
index 975fdca2..6b0982eb 100644
--- a/subprojects/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java
+++ b/subprojects/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java
@@ -8,7 +8,7 @@ import org.eclipse.xtext.validation.Check;
8 8
9import com.google.inject.Inject; 9import com.google.inject.Inject;
10 10
11import tools.refinery.language.model.ProblemUtil; 11import tools.refinery.language.ProblemUtil;
12import tools.refinery.language.model.problem.Node; 12import tools.refinery.language.model.problem.Node;
13import tools.refinery.language.model.problem.Problem; 13import tools.refinery.language.model.problem.Problem;
14import tools.refinery.language.model.problem.ProblemPackage; 14import tools.refinery.language.model.problem.ProblemPackage;
diff --git a/subprojects/language/src/main/resources/tools/refinery/language/builtin.problem b/subprojects/language/src/main/resources/tools/refinery/language/builtin.problem
new file mode 100644
index 00000000..5e913b51
--- /dev/null
+++ b/subprojects/language/src/main/resources/tools/refinery/language/builtin.problem
@@ -0,0 +1,21 @@
1problem builtin.
2
3abstract class node {
4 refers node[] equals opposite equals.
5}
6
7pred exists(node node).
8
9abstract class domain extends node.
10
11abstract class data extends node.
12
13enum bool {
14 true, false
15}
16
17class real extends data.
18
19class int extends data.
20
21class string extends data.
diff --git a/subprojects/language/src/test/java/tools/refinery/language/tests/ProblemParsingTest.java b/subprojects/language/src/test/java/tools/refinery/language/tests/ProblemParsingTest.java
new file mode 100644
index 00000000..1e8682a3
--- /dev/null
+++ b/subprojects/language/src/test/java/tools/refinery/language/tests/ProblemParsingTest.java
@@ -0,0 +1,58 @@
1package tools.refinery.language.tests;
2
3import static org.hamcrest.MatcherAssert.assertThat;
4import static org.hamcrest.Matchers.empty;
5
6import org.eclipse.xtext.testing.InjectWith;
7import org.eclipse.xtext.testing.extensions.InjectionExtension;
8import org.junit.jupiter.api.Test;
9import org.junit.jupiter.api.extension.ExtendWith;
10
11import com.google.inject.Inject;
12
13import tools.refinery.language.model.tests.utils.ProblemParseHelper;
14
15@ExtendWith(InjectionExtension.class)
16@InjectWith(ProblemInjectorProvider.class)
17class ProblemParsingTest {
18 @Inject
19 private ProblemParseHelper parseHelper;
20
21 @Test
22 void exampleTest() {
23 var problem = parseHelper.parse("""
24 class Family {
25 contains Person[] members
26 }
27
28 class Person {
29 Person[0..*] children opposite parent
30 Person[0..1] parent opposite children
31 int age
32 TaxStatus taxStatus
33 }
34
35 enum TaxStatus {
36 child, student, adult, retired
37 }
38
39 % A child cannot have any dependents.
40 error invalidTaxStatus(Person p) <->
41 taxStatus(p, child), children(p, _q).
42
43 indiv family.
44 Family(family).
45 members(family, anne): true.
46 members(family, bob).
47 members(family, ciri).
48 children(anne, ciri).
49 ?children(bob, ciri).
50 taxStatus(anne, adult).
51 age(anne, 35).
52 bobAge: 27.
53 age(bob, bobAge).
54 !age(ciri, bobAge).
55 """);
56 assertThat(problem.errors(), empty());
57 }
58}
diff --git a/subprojects/language/src/test/java/tools/refinery/language/tests/ProblemParsingTest_.xtend b/subprojects/language/src/test/java/tools/refinery/language/tests/ProblemParsingTest_.xtend
deleted file mode 100644
index 53d31a6c..00000000
--- a/subprojects/language/src/test/java/tools/refinery/language/tests/ProblemParsingTest_.xtend
+++ /dev/null
@@ -1,64 +0,0 @@
1/*
2 * generated by Xtext 2.26.0.M1
3 */
4package tools.refinery.language.tests
5
6import com.google.inject.Inject
7import org.eclipse.xtext.testing.InjectWith
8import org.eclipse.xtext.testing.extensions.InjectionExtension
9import org.eclipse.xtext.testing.util.ParseHelper
10import org.junit.jupiter.api.Test
11import org.junit.jupiter.api.^extension.ExtendWith
12import tools.refinery.language.model.problem.Problem
13import tools.refinery.language.model.tests.ProblemTestUtil
14
15import static org.hamcrest.MatcherAssert.assertThat
16import static org.hamcrest.Matchers.*
17
18@ExtendWith(InjectionExtension)
19@InjectWith(ProblemInjectorProvider)
20class ProblemParsingTest {
21 @Inject
22 ParseHelper<Problem> parseHelper
23
24 @Inject
25 extension ProblemTestUtil
26
27 @Test
28 def void exampleTest() {
29 val it = parseHelper.parse('''
30 class Family {
31 contains Person[] members
32 }
33
34 class Person {
35 Person[0..*] children opposite parent
36 Person[0..1] parent opposite children
37 int age
38 TaxStatus taxStatus
39 }
40
41 enum TaxStatus {
42 child, student, adult, retired
43 }
44
45 % A child cannot have any dependents.
46 error invalidTaxStatus(Person p) <->
47 taxStatus(p, child), children(p, _q).
48
49 indiv family.
50 Family(family).
51 members(family, anne): true.
52 members(family, bob).
53 members(family, ciri).
54 children(anne, ciri).
55 ?children(bob, ciri).
56 taxStatus(anne, adult).
57 age(anne, 35).
58 bobAge: 27.
59 age(bob, bobAge).
60 !age(ciri, bobAge).
61 ''')
62 assertThat(errors, empty)
63 }
64}
diff --git a/subprojects/language/src/test/java/tools/refinery/language/tests/formatting2/ProblemFormatterTest.java b/subprojects/language/src/test/java/tools/refinery/language/tests/formatting2/ProblemFormatterTest.java
index 41ad2d31..083c5184 100644
--- a/subprojects/language/src/test/java/tools/refinery/language/tests/formatting2/ProblemFormatterTest.java
+++ b/subprojects/language/src/test/java/tools/refinery/language/tests/formatting2/ProblemFormatterTest.java
@@ -230,6 +230,6 @@ class ProblemFormatterTest {
230 request.setTextRegionAccess(regionAccess); 230 request.setTextRegionAccess(regionAccess);
231 List<ITextReplacement> replacements = formatter2.format(request); 231 List<ITextReplacement> replacements = formatter2.format(request);
232 var formattedString = regionAccess.getRewriter().renderToString(replacements); 232 var formattedString = regionAccess.getRewriter().renderToString(replacements);
233 assertThat(formattedString, equalTo(expected)); 233 assertThat(formattedString.replace("\r\n", "\n"), equalTo(expected.replace("\r\n", "\n")));
234 } 234 }
235} 235}
diff --git a/subprojects/language/src/test/java/tools/refinery/language/tests/rules/DirectRuleParsingTest.java b/subprojects/language/src/test/java/tools/refinery/language/tests/rules/DirectRuleParsingTest.java
new file mode 100644
index 00000000..d5ee722b
--- /dev/null
+++ b/subprojects/language/src/test/java/tools/refinery/language/tests/rules/DirectRuleParsingTest.java
@@ -0,0 +1,84 @@
1package tools.refinery.language.tests.rules;
2
3import static org.hamcrest.MatcherAssert.assertThat;
4import static org.hamcrest.Matchers.empty;
5import static org.hamcrest.Matchers.equalTo;
6import static org.hamcrest.Matchers.not;
7
8import org.eclipse.xtext.testing.InjectWith;
9import org.eclipse.xtext.testing.extensions.InjectionExtension;
10import org.junit.jupiter.api.Test;
11import org.junit.jupiter.api.extension.ExtendWith;
12import org.junit.jupiter.params.ParameterizedTest;
13import org.junit.jupiter.params.provider.ValueSource;
14
15import com.google.inject.Inject;
16
17import tools.refinery.language.model.tests.utils.ProblemParseHelper;
18import tools.refinery.language.tests.ProblemInjectorProvider;
19
20@ExtendWith(InjectionExtension.class)
21@InjectWith(ProblemInjectorProvider.class)
22class DirectRuleParsingTest {
23 @Inject
24 private ProblemParseHelper parseHelper;
25
26 @ParameterizedTest
27 @ValueSource(strings = { """
28 pred Person(p).
29 direct rule r(p1): Person(p1) = true ~> Person(p1) = false.
30 """, """
31 pred Person(p).
32 direct rule r(p1): Person(p1) = true ~> Person(p1): false.
33 """, """
34 pred Person(p).
35 direct rule r(p1): Person(p1): false ~> delete p1.
36 """ })
37 void simpleTest(String text) {
38 var problem = parseHelper.parse(text);
39 assertThat(problem.errors(), empty());
40 }
41
42 @Test
43 void newNodeTest() {
44 var problem = parseHelper.parse("""
45 pred Person(p).
46 direct rule r(p1): Person(p1) = true ~> new p2, Person(p2) = unknown.
47 """);
48 assertThat(problem.errors(), empty());
49 assertThat(problem.rule("r").param(0), equalTo(problem.rule("r").conj(0).lit(0).valueAtom().arg(0).variable()));
50 assertThat(problem.rule("r").actionLit(0).newVar(),
51 equalTo(problem.rule("r").actionLit(1).valueAtom().arg(0).variable()));
52 }
53
54 @Test
55 void differentScopeTest() {
56 var problem = parseHelper.parse("""
57 pred Friend(a, b).
58 direct rule r(p1): Friend(p1, p2) = false ~> new p2, Friend(p1, p2) = true.
59 """);
60 assertThat(problem.errors(), empty());
61 assertThat(problem.rule("r").conj(0).lit(0).valueAtom().arg(1).variable(),
62 not(equalTo(problem.rule("r").actionLit(1).valueAtom().arg(1).variable())));
63 }
64
65 @Test
66 void parameterShadowingTest() {
67 var problem = parseHelper.parse("""
68 pred Friend(a, b).
69 direct rule r(p1, p2): Friend(p1, p2) = false ~> new p2, Friend(p1, p2) = true.
70 """);
71 assertThat(problem.errors(), empty());
72 assertThat(problem.rule("r").param(1),
73 not(equalTo(problem.rule("r").actionLit(1).valueAtom().arg(1).variable())));
74 }
75
76 @Test
77 void deleteDifferentScopeNodeTest() {
78 var problem = parseHelper.parse("""
79 pred Person(p).
80 direct rule r(p1): Friend(p1, p2) = true ~> delete p2.
81 """);
82 assertThat(problem.errors(), not(empty()));
83 }
84}
diff --git a/subprojects/language/src/test/java/tools/refinery/language/tests/rules/DirectRuleParsingTest_.xtend b/subprojects/language/src/test/java/tools/refinery/language/tests/rules/DirectRuleParsingTest_.xtend
deleted file mode 100644
index d60651a0..00000000
--- a/subprojects/language/src/test/java/tools/refinery/language/tests/rules/DirectRuleParsingTest_.xtend
+++ /dev/null
@@ -1,96 +0,0 @@
1package tools.refinery.language.tests.rules
2
3import com.google.inject.Inject
4import org.eclipse.xtext.testing.InjectWith
5import org.eclipse.xtext.testing.extensions.InjectionExtension
6import org.eclipse.xtext.testing.util.ParseHelper
7import org.junit.jupiter.api.Test
8import org.junit.jupiter.api.^extension.ExtendWith
9import tools.refinery.language.model.problem.Problem
10import tools.refinery.language.tests.ProblemInjectorProvider
11import tools.refinery.language.model.tests.ProblemTestUtil
12
13import static org.hamcrest.MatcherAssert.assertThat
14import static org.hamcrest.Matchers.*
15
16@ExtendWith(InjectionExtension)
17@InjectWith(ProblemInjectorProvider)
18class DirectRuleParsingTest {
19 @Inject
20 ParseHelper<Problem> parseHelper
21
22 @Inject
23 extension ProblemTestUtil
24
25 @Test
26 def void relationValueRewriteTest() {
27 val it = parseHelper.parse('''
28 pred Person(p).
29 direct rule r(p1): Person(p1) = true ~> Person(p1) = false.
30 ''')
31 assertThat(errors, empty)
32 }
33
34 @Test
35 def void relationValueMergeTest() {
36 val it = parseHelper.parse('''
37 pred Person(p).
38 direct rule r(p1): Person(p1): true ~> Person(p1): false.
39 ''')
40 assertThat(errors, empty)
41 }
42
43 @Test
44 def void newNodeTest() {
45 val it = parseHelper.parse('''
46 pred Person(p).
47 direct rule r(p1): Person(p1) = true ~> new p2, Person(p2) = unknown.
48 ''')
49 assertThat(errors, empty)
50 assertThat(rule("r").param(0), equalTo(rule("r").conj(0).lit(0).valueAtom.arg(0).variable))
51 assertThat(rule("r").actionLit(0).newVar,
52 equalTo(rule("r").actionLit(1).valueAtom.arg(0).variable)
53 )
54 }
55
56 @Test
57 def void differentScopeTest() {
58 val it = parseHelper.parse('''
59 pred Friend(a, b).
60 direct rule r(p1): Friend(p1, p2) = false ~> new p2, Friend(p1, p2) = true.
61 ''')
62 assertThat(errors, empty)
63 assertThat(rule("r").conj(0).lit(0).valueAtom.arg(1).variable,
64 not(equalTo(rule("r").actionLit(1).valueAtom.arg(1).variable)))
65 }
66
67 @Test
68 def void parameterShadowingTest() {
69 val it = parseHelper.parse('''
70 pred Friend(a, b).
71 direct rule r(p1, p2): Friend(p1, p2) = false ~> new p2, Friend(p1, p2) = true.
72 ''')
73 assertThat(errors, empty)
74 assertThat(rule("r").param(1),
75 not(equalTo(rule("r").actionLit(1).valueAtom.arg(1).variable)))
76 }
77
78 @Test
79 def void deleteParameterNodeTest() {
80 val it = parseHelper.parse('''
81 pred Person(p).
82 direct rule r(p1): Person(p1): false ~> delete p1.
83 ''')
84 assertThat(errors, empty)
85 }
86
87 @Test
88 def void deleteDifferentScopeNodeTest() {
89 val it = parseHelper.parse('''
90 pred Friend(p).
91 direct rule r(p1): Friend(p1, p2) = true ~> delete p2.
92 ''')
93 assertThat(errors, not(empty))
94 }
95
96}
diff --git a/subprojects/language/src/test/java/tools/refinery/language/tests/scoping/NodeScopingTest.java b/subprojects/language/src/test/java/tools/refinery/language/tests/scoping/NodeScopingTest.java
new file mode 100644
index 00000000..5c905ede
--- /dev/null
+++ b/subprojects/language/src/test/java/tools/refinery/language/tests/scoping/NodeScopingTest.java
@@ -0,0 +1,321 @@
1package tools.refinery.language.tests.scoping;
2
3import static org.hamcrest.MatcherAssert.assertThat;
4import static org.hamcrest.Matchers.empty;
5import static org.hamcrest.Matchers.equalTo;
6import static org.hamcrest.Matchers.hasItems;
7import static org.hamcrest.Matchers.not;
8
9import java.util.stream.Stream;
10
11import org.eclipse.xtext.testing.InjectWith;
12import org.eclipse.xtext.testing.extensions.InjectionExtension;
13import org.junit.jupiter.api.Test;
14import org.junit.jupiter.api.extension.ExtendWith;
15import org.junit.jupiter.params.ParameterizedTest;
16import org.junit.jupiter.params.provider.Arguments;
17import org.junit.jupiter.params.provider.MethodSource;
18import org.junit.jupiter.params.provider.ValueSource;
19
20import com.google.inject.Inject;
21
22import tools.refinery.language.model.tests.utils.ProblemParseHelper;
23import tools.refinery.language.model.tests.utils.WrappedProblem;
24import tools.refinery.language.tests.ProblemInjectorProvider;
25
26@ExtendWith(InjectionExtension.class)
27@InjectWith(ProblemInjectorProvider.class)
28class NodeScopingTest {
29 @Inject
30 private ProblemParseHelper parseHelper;
31
32 @ParameterizedTest
33 @ValueSource(strings = { "", "builtin::" })
34 void builtInArgumentTypeTest(String qualifiedNamePrefix) {
35 var problem = parse("""
36 pred predicate({PARAM}node a, {PARAM}data b, {PARAM}int c).
37 """, qualifiedNamePrefix);
38 assertThat(problem.errors(), empty());
39 assertThat(problem.pred("predicate").param(0).getParameterType(),
40 equalTo(problem.builtin().findClass("node").get()));
41 assertThat(problem.pred("predicate").param(1).getParameterType(),
42 equalTo(problem.builtin().findClass("data").get()));
43 assertThat(problem.pred("predicate").param(2).getParameterType(),
44 equalTo(problem.builtin().findClass("int").get()));
45 }
46
47 @Test
48 void implicitNodeInAssertionTest() {
49 var problem = parse("""
50 pred predicate(node x, node y) <-> node(x).
51 predicate(a, a).
52 ?predicate(a, b).
53 """);
54 assertThat(problem.errors(), empty());
55 assertThat(problem.nodeNames(), hasItems("a", "b"));
56 assertThat(problem.assertion(0).arg(0).node(), equalTo(problem.node("a")));
57 assertThat(problem.assertion(0).arg(1).node(), equalTo(problem.node("a")));
58 assertThat(problem.assertion(1).arg(0).node(), equalTo(problem.node("a")));
59 assertThat(problem.assertion(1).arg(1).node(), equalTo(problem.node("b")));
60 }
61
62 @Test
63 void implicitNodeInNodeValueAssertionTest() {
64 var problem = parseHelper.parse("""
65 a: 16.
66 """);
67 assertThat(problem.errors(), empty());
68 assertThat(problem.nodeNames(), hasItems("a"));
69 assertThat(problem.nodeValueAssertion(0).getNode(), equalTo(problem.node("a")));
70 }
71
72 @Test
73 void implicitNodeInPredicateTest() {
74 var problem = parse("""
75 pred predicate(node a) <-> node(b).
76 predicate(b).
77 """);
78 assertThat(problem.errors(), empty());
79 assertThat(problem.nodeNames(), hasItems("b"));
80 assertThat(problem.pred("predicate").conj(0).lit(0).arg(0).node(), equalTo(problem.node("b")));
81 assertThat(problem.assertion(0).arg(0).node(), equalTo(problem.node("b")));
82 }
83
84 @ParameterizedTest
85 @MethodSource("individualNodeReferenceSource")
86 void individualNodeInAssertionTest(String qualifiedNamePrefix, boolean namedProblem) {
87 var problem = parse("""
88 indiv a, b.
89 pred predicate(node x, node y) <-> node(x).
90 predicate({PARAM}a, {PARAM}a).
91 ?predicate({PARAM}a, {PARAM}b).
92 """, qualifiedNamePrefix, namedProblem);
93 assertThat(problem.errors(), empty());
94 assertThat(problem.nodeNames(), empty());
95 assertThat(problem.assertion(0).arg(0).node(), equalTo(problem.individualNode("a")));
96 assertThat(problem.assertion(0).arg(1).node(), equalTo(problem.individualNode("a")));
97 assertThat(problem.assertion(1).arg(0).node(), equalTo(problem.individualNode("a")));
98 assertThat(problem.assertion(1).arg(1).node(), equalTo(problem.individualNode("b")));
99 }
100
101 @ParameterizedTest
102 @MethodSource("individualNodeReferenceSource")
103 void individualNodeInNodeValueAssertionTest(String qualifiedNamePrefix, boolean namedProblem) {
104 var problem = parse("""
105 indiv a.
106 {PARAM}a: 16.
107 """, qualifiedNamePrefix, namedProblem);
108 assertThat(problem.errors(), empty());
109 assertThat(problem.nodeNames(), empty());
110 assertThat(problem.nodeValueAssertion(0).getNode(), equalTo(problem.individualNode("a")));
111 }
112
113 @ParameterizedTest
114 @MethodSource("individualNodeReferenceSource")
115 void individualNodeInPredicateTest(String qualifiedNamePrefix, boolean namedProblem) {
116 var problem = parse("""
117 indiv b.
118 pred predicate(node a) <-> node({PARAM}b).
119 """);
120 assertThat(problem.errors(), empty());
121 assertThat(problem.nodeNames(), empty());
122 assertThat(problem.pred("predicate").conj(0).lit(0).arg(0).node(), equalTo(problem.individualNode("b")));
123 }
124
125 static Stream<Arguments> individualNodeReferenceSource() {
126 return Stream.of(Arguments.of("", false), Arguments.of("", true), Arguments.of("test::", true));
127 }
128
129 @ParameterizedTest
130 @MethodSource("builtInNodeReferencesSource")
131 void builtInNodeTest(String qualifiedName) {
132 var problem = parse("""
133 pred predicate(node x) <-> node(x).
134 predicate({PARAM}).
135 """, qualifiedName);
136 assertThat(problem.errors(), empty());
137 assertThat(problem.nodeNames(), empty());
138 assertThat(problem.assertion(0).arg(0).node(), equalTo(problem.builtin().findClass("int").get().getNewNode()));
139 }
140
141 @ParameterizedTest
142 @MethodSource("builtInNodeReferencesSource")
143 void builtInNodeInNodeValueAssertionTest(String qualifiedName) {
144 var problem = parse("""
145 {PARAM}: 16.
146 """, qualifiedName);
147 assertThat(problem.errors(), empty());
148 assertThat(problem.nodeNames(), empty());
149 assertThat(problem.nodeValueAssertion(0).getNode(),
150 equalTo(problem.builtin().findClass("int").get().getNewNode()));
151 }
152
153 @ParameterizedTest
154 @MethodSource("builtInNodeReferencesSource")
155 void builtInNodeInPredicateTest(String qualifiedName) {
156 var problem = parse("""
157 pred predicate(node x) <-> node({PARAM}).
158 """, qualifiedName);
159 assertThat(problem.errors(), empty());
160 assertThat(problem.nodeNames(), empty());
161 assertThat(problem.pred("predicate").conj(0).lit(0).arg(0).node(),
162 equalTo(problem.builtin().findClass("int").get().getNewNode()));
163 }
164
165 static Stream<Arguments> builtInNodeReferencesSource() {
166 return Stream.of(Arguments.of("int::new"), Arguments.of("builtin::int::new"));
167 }
168
169 @ParameterizedTest
170 @MethodSource("classNewNodeReferencesSource")
171 void classNewNodeTest(String qualifiedName, boolean namedProblem) {
172 var problem = parse("""
173 class Foo.
174 pred predicate(node x) <-> node(x).
175 predicate({PARAM}).
176 """, qualifiedName, namedProblem);
177 assertThat(problem.errors(), empty());
178 assertThat(problem.nodeNames(), empty());
179 assertThat(problem.assertion(0).arg(0).node(), equalTo(problem.findClass("Foo").get().getNewNode()));
180 }
181
182 @ParameterizedTest
183 @MethodSource("classNewNodeReferencesSource")
184 void classNewNodeInNodeValueAssertionTest(String qualifiedName, boolean namedProblem) {
185 var problem = parse("""
186 class Foo.
187 {PARAM}: 16.
188 """, qualifiedName, namedProblem);
189 assertThat(problem.errors(), empty());
190 assertThat(problem.nodeNames(), empty());
191 assertThat(problem.nodeValueAssertion(0).getNode(), equalTo(problem.findClass("Foo").get().getNewNode()));
192 }
193
194 @ParameterizedTest
195 @MethodSource("classNewNodeReferencesSource")
196 void classNewNodeInPredicateTest(String qualifiedName, boolean namedProblem) {
197 var problem = parse("""
198 class Foo.
199 pred predicate(node x) <-> node({PARAM}).
200 """, qualifiedName, namedProblem);
201 assertThat(problem.errors(), empty());
202 assertThat(problem.nodeNames(), empty());
203 assertThat(problem.pred("predicate").conj(0).lit(0).arg(0).node(),
204 equalTo(problem.findClass("Foo").get().getNewNode()));
205 }
206
207 static Stream<Arguments> classNewNodeReferencesSource() {
208 return Stream.of(Arguments.of("Foo::new", false), Arguments.of("Foo::new", true),
209 Arguments.of("test::Foo::new", true));
210 }
211
212 @Test
213 void newNodeIsNotSpecial() {
214 var problem = parse("""
215 class Foo.
216 pred predicate(node x) <-> node(x).
217 predicate(new).
218 """);
219 assertThat(problem.errors(), empty());
220 assertThat(problem.nodeNames(), hasItems("new"));
221 assertThat(problem.assertion(0).arg(0).node(), not(equalTo(problem.findClass("Foo").get().getNewNode())));
222 }
223
224 @ParameterizedTest
225 @MethodSource("enumLiteralReferencesSource")
226 void enumLiteralTest(String qualifiedName, boolean namedProblem) {
227 var problem = parse("""
228 enum Foo { alpha, beta }
229 pred predicate(Foo a) <-> node(a).
230 predicate({PARAM}).
231 """, qualifiedName, namedProblem);
232 assertThat(problem.errors(), empty());
233 assertThat(problem.nodeNames(), empty());
234 assertThat(problem.assertion(0).arg(0).node(), equalTo(problem.findEnum("Foo").literal("alpha")));
235 }
236
237 @ParameterizedTest
238 @MethodSource("enumLiteralReferencesSource")
239 void enumLiteralInNodeValueAssertionTest(String qualifiedName, boolean namedProblem) {
240 var problem = parse("""
241 enum Foo { alpha, beta }
242 {PARAM}: 16.
243 """, qualifiedName, namedProblem);
244 assertThat(problem.errors(), empty());
245 assertThat(problem.nodeNames(), empty());
246 assertThat(problem.nodeValueAssertion(0).getNode(), equalTo(problem.findEnum("Foo").literal("alpha")));
247 }
248
249 @ParameterizedTest
250 @MethodSource("enumLiteralReferencesSource")
251 void enumLiteralInPredicateTest(String qualifiedName, boolean namedProblem) {
252 var problem = parse("""
253 enum Foo { alpha, beta }
254 pred predicate(Foo a) <-> node({PARAM}).
255 """, qualifiedName, namedProblem);
256 assertThat(problem.errors(), empty());
257 assertThat(problem.nodeNames(), empty());
258 assertThat(problem.pred("predicate").conj(0).lit(0).arg(0).node(),
259 equalTo(problem.findEnum("Foo").literal("alpha")));
260 }
261
262 static Stream<Arguments> enumLiteralReferencesSource() {
263 return Stream.of(Arguments.of("alpha", false), Arguments.of("alpha", true), Arguments.of("Foo::alpha", false),
264 Arguments.of("Foo::alpha", true), Arguments.of("test::alpha", true),
265 Arguments.of("test::Foo::alpha", true));
266 }
267
268 @ParameterizedTest
269 @MethodSource("builtInEnumLiteralReferencesSource")
270 void builtInEnumLiteralTest(String qualifiedName) {
271 var problem = parse("""
272 pred predicate(node a) <-> node(a).
273 predicate({PARAM}).
274 """, qualifiedName);
275 assertThat(problem.errors(), empty());
276 assertThat(problem.nodeNames(), empty());
277 assertThat(problem.assertion(0).arg(0).node(), equalTo(problem.builtin().findEnum("bool").literal("true")));
278 }
279
280 @ParameterizedTest
281 @MethodSource("builtInEnumLiteralReferencesSource")
282 void builtInEnumLiteralInNodeValueAssertionTest(String qualifiedName) {
283 var problem = parse("""
284 {PARAM}: 16.
285 """, qualifiedName);
286 assertThat(problem.errors(), empty());
287 assertThat(problem.nodeNames(), empty());
288 assertThat(problem.nodeValueAssertion(0).getNode(),
289 equalTo(problem.builtin().findEnum("bool").literal("true")));
290 }
291
292 @ParameterizedTest
293 @MethodSource("builtInEnumLiteralReferencesSource")
294 void bultInEnumLiteralInPredicateTest(String qualifiedName) {
295 var problem = parse("""
296 pred predicate() <-> node({PARAM}).
297 """, qualifiedName);
298 assertThat(problem.errors(), empty());
299 assertThat(problem.nodeNames(), empty());
300 assertThat(problem.pred("predicate").conj(0).lit(0).arg(0).node(),
301 equalTo(problem.builtin().findEnum("bool").literal("true")));
302 }
303
304 static Stream<Arguments> builtInEnumLiteralReferencesSource() {
305 return Stream.of(Arguments.of("true"), Arguments.of("bool::true"), Arguments.of("builtin::true"),
306 Arguments.of("builtin::bool::true"));
307 }
308
309 private WrappedProblem parse(String text, String parameter, boolean namedProblem) {
310 var problemName = namedProblem ? "problem test.\n" : "";
311 return parseHelper.parse(problemName + text.replace("{PARAM}", parameter));
312 }
313
314 private WrappedProblem parse(String text, String parameter) {
315 return parse(text, parameter, false);
316 }
317
318 private WrappedProblem parse(String text) {
319 return parse(text, "");
320 }
321}
diff --git a/subprojects/language/src/test/java/tools/refinery/language/tests/scoping/NodeScopingTest_.xtend b/subprojects/language/src/test/java/tools/refinery/language/tests/scoping/NodeScopingTest_.xtend
deleted file mode 100644
index 3a046341..00000000
--- a/subprojects/language/src/test/java/tools/refinery/language/tests/scoping/NodeScopingTest_.xtend
+++ /dev/null
@@ -1,322 +0,0 @@
1package tools.refinery.language.tests.scoping
2
3import com.google.inject.Inject
4import java.util.stream.Stream
5import org.eclipse.xtext.testing.InjectWith
6import org.eclipse.xtext.testing.extensions.InjectionExtension
7import org.eclipse.xtext.testing.util.ParseHelper
8import org.junit.jupiter.api.Test
9import org.junit.jupiter.api.^extension.ExtendWith
10import org.junit.jupiter.params.ParameterizedTest
11import org.junit.jupiter.params.provider.Arguments
12import org.junit.jupiter.params.provider.MethodSource
13import org.junit.jupiter.params.provider.ValueSource
14import tools.refinery.language.model.problem.Problem
15import tools.refinery.language.model.tests.ProblemTestUtil
16import tools.refinery.language.tests.ProblemInjectorProvider
17
18import static org.hamcrest.MatcherAssert.assertThat
19import static org.hamcrest.Matchers.*
20
21@ExtendWith(InjectionExtension)
22@InjectWith(ProblemInjectorProvider)
23class NodeScopingTest {
24 @Inject
25 ParseHelper<Problem> parseHelper
26
27 @Inject
28 extension ProblemTestUtil
29
30 @ParameterizedTest
31 @ValueSource(strings=#["", "builtin::"])
32 def void builtInArgumentTypeTest(String prefix) {
33 val it = parseHelper.parse('''
34 pred predicate(«prefix»node a, «prefix»data b, «prefix»int c).
35 ''')
36 assertThat(errors, empty)
37 assertThat(pred('predicate').param(0).parameterType, equalTo(builtin.findClass('node')))
38 assertThat(pred('predicate').param(1).parameterType, equalTo(builtin.findClass('data')))
39 assertThat(pred('predicate').param(2).parameterType, equalTo(builtin.findClass('int')))
40 }
41
42 @Test
43 def void implicitNodeInAssertionTest() {
44 val it = parseHelper.parse('''
45 pred predicate(node x, node y) <-> node(x).
46 predicate(a, a).
47 ?predicate(a, b).
48 ''')
49 assertThat(errors, empty)
50 assertThat(nodeNames, hasItems('a', 'b'))
51 assertThat(assertion(0).arg(0).node, equalTo(node('a')))
52 assertThat(assertion(0).arg(1).node, equalTo(node('a')))
53 assertThat(assertion(1).arg(0).node, equalTo(node('a')))
54 assertThat(assertion(1).arg(1).node, equalTo(node('b')))
55 }
56
57 @Test
58 def void implicitNodeInNodeValueAssertionTest() {
59 val it = parseHelper.parse('''
60 a: 16.
61 ''')
62 assertThat(errors, empty)
63 assertThat(nodeNames, hasItems('a'))
64 assertThat(nodeValueAssertion(0).node, equalTo(node('a')))
65 }
66
67 @Test
68 def void implicitNodeInPredicateTest() {
69 val it = parseHelper.parse('''
70 pred predicate(node a) <-> node(b).
71 predicate(b).
72 ''')
73 assertThat(errors, empty)
74 assertThat(nodeNames, hasItem("b"))
75 assertThat(pred("predicate").conj(0).lit(0).arg(0).node, equalTo(node("b")))
76 assertThat(assertion(0).arg(0).node, equalTo(node("b")))
77 }
78
79 @ParameterizedTest
80 @MethodSource("individualNodeReferenceSource")
81 def void individualNodeInAssertionTest(String qualifiedNamePrefix, boolean namedProblem) {
82 val it = parseHelper.parse('''
83 «IF namedProblem»problem test.«ENDIF»
84 indiv a, b.
85 pred predicate(node x, node y) <-> node(x).
86 predicate(«qualifiedNamePrefix»a, «qualifiedNamePrefix»a).
87 ?predicate(«qualifiedNamePrefix»a, «qualifiedNamePrefix»b).
88 ''')
89 assertThat(errors, empty)
90 assertThat(nodeNames, empty)
91 assertThat(assertion(0).arg(0).node, equalTo(individualNode('a')))
92 assertThat(assertion(0).arg(1).node, equalTo(individualNode('a')))
93 assertThat(assertion(1).arg(0).node, equalTo(individualNode('a')))
94 assertThat(assertion(1).arg(1).node, equalTo(individualNode('b')))
95 }
96
97 @ParameterizedTest
98 @MethodSource("individualNodeReferenceSource")
99 def void individualNodeInNodeValueAssertionTest(String qualifiedNamePrefix, boolean namedProblem) {
100 val it = parseHelper.parse('''
101 «IF namedProblem»problem test.«ENDIF»
102 indiv a.
103 «qualifiedNamePrefix»a: 16.
104 ''')
105 assertThat(errors, empty)
106 assertThat(nodeNames, empty)
107 assertThat(nodeValueAssertion(0).node, equalTo(individualNode('a')))
108 }
109
110 @ParameterizedTest
111 @MethodSource("individualNodeReferenceSource")
112 def void individualNodeInPredicateTest(String qualifiedNamePrefix, boolean namedProblem) {
113 val it = parseHelper.parse('''
114 «IF namedProblem»problem test.«ENDIF»
115 indiv b.
116 pred predicate(node a) <-> node(«qualifiedNamePrefix»b).
117 ''')
118 assertThat(errors, empty)
119 assertThat(nodeNames, empty)
120 assertThat(pred("predicate").conj(0).lit(0).arg(0).node, equalTo(individualNode("b")))
121 }
122
123 static def individualNodeReferenceSource() {
124 Stream.of(
125 Arguments.of("", false),
126 Arguments.of("", true),
127 Arguments.of("test::", true)
128 )
129 }
130
131 @ParameterizedTest
132 @MethodSource("builtInNodeReferencesSource")
133 def void builtInNodeTest(String qualifiedName) {
134 val it = parseHelper.parse('''
135 pred predicate(node x) <-> node(x).
136 predicate(«qualifiedName»).
137 ''')
138 assertThat(errors, empty)
139 assertThat(nodes, empty)
140 assertThat(assertion(0).arg(0).node, equalTo(builtin.findClass('int').newNode))
141 }
142
143 @ParameterizedTest
144 @MethodSource("builtInNodeReferencesSource")
145 def void builtInNodeInNodeValueAssertionTest(String qualifiedName) {
146 val it = parseHelper.parse('''
147 «qualifiedName»: 16.
148 ''')
149 assertThat(errors, empty)
150 assertThat(nodes, empty)
151 assertThat(nodeValueAssertion(0).node, equalTo(builtin.findClass('int').newNode))
152 }
153
154 @ParameterizedTest
155 @MethodSource("builtInNodeReferencesSource")
156 def void builtInNodeInPredicateTest(String qualifiedName) {
157 val it = parseHelper.parse('''
158 pred predicate(node x) <-> node(«qualifiedName»).
159 ''')
160 assertThat(errors, empty)
161 assertThat(pred("predicate").conj(0).lit(0).arg(0).node, equalTo(builtin.findClass('int').newNode))
162 }
163
164 static def builtInNodeReferencesSource() {
165 Stream.of(
166 Arguments.of("int::new"),
167 Arguments.of("builtin::int::new")
168 )
169 }
170
171 @ParameterizedTest(name="{0}, namedProblem={1}")
172 @MethodSource("classNewNodeReferencesSource")
173 def void classNewNodeTest(String qualifiedName, boolean namedProblem) {
174 val it = parseHelper.parse('''
175 «IF namedProblem»problem test.«ENDIF»
176 class Foo.
177 pred predicate(node x) <-> node(x).
178 predicate(«qualifiedName»).
179 ''')
180 assertThat(errors, empty)
181 assertThat(nodes, empty)
182 assertThat(assertion(0).arg(0).node, equalTo(findClass('Foo').newNode))
183 }
184
185 @ParameterizedTest(name="{0}, namedProblem={1}")
186 @MethodSource("classNewNodeReferencesSource")
187 def void classNewNodeInNodeValueAssertionTest(String qualifiedName, boolean namedProblem) {
188 val it = parseHelper.parse('''
189 «IF namedProblem»problem test.«ENDIF»
190 class Foo.
191 «qualifiedName»: 16.
192 ''')
193 assertThat(errors, empty)
194 assertThat(nodes, empty)
195 assertThat(nodeValueAssertion(0).node, equalTo(findClass('Foo').newNode))
196 }
197
198 @ParameterizedTest(name="{0}, namedProblem={1}")
199 @MethodSource("classNewNodeReferencesSource")
200 def void classNewNodeInPredicateTest(String qualifiedName, boolean namedProblem) {
201 val it = parseHelper.parse('''
202 «IF namedProblem»problem test.«ENDIF»
203 class Foo.
204 pred predicate(node x) <-> node(«qualifiedName»).
205 ''')
206 assertThat(errors, empty)
207 assertThat(pred("predicate").conj(0).lit(0).arg(0).node, equalTo(findClass('Foo').newNode))
208 }
209
210 static def classNewNodeReferencesSource() {
211 Stream.of(
212 Arguments.of("Foo::new", false),
213 Arguments.of("Foo::new", true),
214 Arguments.of("test::Foo::new", true)
215 )
216 }
217
218 @Test
219 def void newNodeIsNotSpecial() {
220 val it = parseHelper.parse('''
221 class Foo.
222 pred predicate(node x) <-> node(x).
223 predicate(new).
224 ''')
225 assertThat(errors, empty)
226 assertThat(nodeNames, hasItem('new'))
227 assertThat(assertion(0).arg(0).node, not(equalTo(findClass('Foo').newNode)))
228 }
229
230 @ParameterizedTest(name="{0}, namedProblem={1}")
231 @MethodSource("enumLiteralReferencesSource")
232 def void enumLiteralTest(String qualifiedName, boolean namedProblem) {
233 val it = parseHelper.parse('''
234 «IF namedProblem»problem test.«ENDIF»
235 enum Foo { alpha, beta }
236 pred predicate(Foo a) <-> node(a).
237 predicate(«qualifiedName»).
238 ''')
239 assertThat(errors, empty)
240 assertThat(nodes, empty)
241 assertThat(assertion(0).arg(0).node, equalTo(findEnum("Foo").literal("alpha")))
242 }
243
244 @ParameterizedTest(name="{0}, namedProblem={1}")
245 @MethodSource("enumLiteralReferencesSource")
246 def void enumLiteralInNodeValueAssertionTest(String qualifiedName, boolean namedProblem) {
247 val it = parseHelper.parse('''
248 «IF namedProblem»problem test.«ENDIF»
249 enum Foo { alpha, beta }
250 «qualifiedName»: 16.
251 ''')
252 assertThat(errors, empty)
253 assertThat(nodes, empty)
254 assertThat(nodeValueAssertion(0).node, equalTo(findEnum("Foo").literal("alpha")))
255 }
256
257 @ParameterizedTest(name="{0}, namedProblem={1}")
258 @MethodSource("enumLiteralReferencesSource")
259 def void enumLiteralInPredicateTest(String qualifiedName, boolean namedProblem) {
260 val it = parseHelper.parse('''
261 «IF namedProblem»problem test.«ENDIF»
262 enum Foo { alpha, beta }
263 pred predicate(Foo a) <-> node(«qualifiedName»).
264 ''')
265 assertThat(errors, empty)
266 assertThat(nodes, empty)
267 assertThat(pred("predicate").conj(0).lit(0).arg(0).node, equalTo(findEnum("Foo").literal("alpha")))
268 }
269
270 static def enumLiteralReferencesSource() {
271 Stream.of(
272 Arguments.of("alpha", false),
273 Arguments.of("alpha", true),
274 Arguments.of("Foo::alpha", false),
275 Arguments.of("Foo::alpha", true),
276 Arguments.of("test::alpha", true),
277 Arguments.of("test::Foo::alpha", true)
278 )
279 }
280
281 @ParameterizedTest
282 @MethodSource("builtInEnumLiteralReferencesSource")
283 def void builtInEnumLiteralTest(String qualifiedName) {
284 val it = parseHelper.parse('''
285 pred predicate(node a) <-> node(a).
286 predicate(«qualifiedName»).
287 ''')
288 assertThat(errors, empty)
289 assertThat(nodes, empty)
290 assertThat(assertion(0).arg(0).node, equalTo(builtin.findEnum("bool").literal("true")))
291 }
292
293 @ParameterizedTest
294 @MethodSource("builtInEnumLiteralReferencesSource")
295 def void builtInEnumLiteralInNodeValueAssertionTest(String qualifiedName) {
296 val it = parseHelper.parse('''
297 «qualifiedName»: 16.
298 ''')
299 assertThat(errors, empty)
300 assertThat(nodes, empty)
301 assertThat(nodeValueAssertion(0).node, equalTo(builtin.findEnum("bool").literal("true")))
302 }
303
304 @ParameterizedTest
305 @MethodSource("builtInEnumLiteralReferencesSource")
306 def void bultInEnumLiteralInPredicateTest(String qualifiedName) {
307 val it = parseHelper.parse('''
308 pred predicate() <-> node(«qualifiedName»).
309 ''')
310 assertThat(errors, empty)
311 assertThat(pred("predicate").conj(0).lit(0).arg(0).node, equalTo(builtin.findEnum("bool").literal("true")))
312 }
313
314 static def builtInEnumLiteralReferencesSource() {
315 Stream.of(
316 Arguments.of("true"),
317 Arguments.of("bool::true"),
318 Arguments.of("builtin::true"),
319 Arguments.of("builtin::bool::true")
320 )
321 }
322}
diff --git a/subprojects/language/src/test/java/tools/refinery/language/tests/serializer/ProblemSerializerTest.java b/subprojects/language/src/test/java/tools/refinery/language/tests/serializer/ProblemSerializerTest.java
index ba3aaeb7..ea858e92 100644
--- a/subprojects/language/src/test/java/tools/refinery/language/tests/serializer/ProblemSerializerTest.java
+++ b/subprojects/language/src/test/java/tools/refinery/language/tests/serializer/ProblemSerializerTest.java
@@ -22,7 +22,6 @@ import org.junit.jupiter.params.provider.MethodSource;
22 22
23import com.google.inject.Inject; 23import com.google.inject.Inject;
24 24
25import tools.refinery.language.model.ProblemUtil;
26import tools.refinery.language.model.problem.Atom; 25import tools.refinery.language.model.problem.Atom;
27import tools.refinery.language.model.problem.LogicValue; 26import tools.refinery.language.model.problem.LogicValue;
28import tools.refinery.language.model.problem.Node; 27import tools.refinery.language.model.problem.Node;
@@ -31,7 +30,7 @@ import tools.refinery.language.model.problem.Problem;
31import tools.refinery.language.model.problem.ProblemFactory; 30import tools.refinery.language.model.problem.ProblemFactory;
32import tools.refinery.language.model.problem.Relation; 31import tools.refinery.language.model.problem.Relation;
33import tools.refinery.language.model.problem.VariableOrNode; 32import tools.refinery.language.model.problem.VariableOrNode;
34import tools.refinery.language.model.tests.ProblemTestUtil; 33import tools.refinery.language.model.tests.utils.WrappedProblem;
35import tools.refinery.language.tests.ProblemInjectorProvider; 34import tools.refinery.language.tests.ProblemInjectorProvider;
36 35
37@ExtendWith(InjectionExtension.class) 36@ExtendWith(InjectionExtension.class)
@@ -40,21 +39,19 @@ class ProblemSerializerTest {
40 @Inject 39 @Inject
41 private ResourceSet resourceSet; 40 private ResourceSet resourceSet;
42 41
43 @Inject
44 private ProblemTestUtil testUtil;
45
46 private Resource resource; 42 private Resource resource;
47 43
48 private Problem problem; 44 private Problem problem;
49 45
50 private Problem builtin; 46 private WrappedProblem builtin;
51 47
52 @BeforeEach 48 @BeforeEach
53 void beforeEach() { 49 void beforeEach() {
54 problem = ProblemFactory.eINSTANCE.createProblem(); 50 problem = ProblemFactory.eINSTANCE.createProblem();
55 resource = resourceSet.createResource(URI.createFileURI("test.problem")); 51 resource = resourceSet.createResource(URI.createFileURI("test.problem"));
56 resource.getContents().add(problem); 52 resource.getContents().add(problem);
57 builtin = ProblemUtil.getBuiltInLibrary(problem).get(); 53 var wrappedProblem = new WrappedProblem(problem);
54 builtin = wrappedProblem.builtin();
58 } 55 }
59 56
60 @ParameterizedTest 57 @ParameterizedTest
@@ -99,8 +96,8 @@ class ProblemSerializerTest {
99 var pred = ProblemFactory.eINSTANCE.createPredicateDefinition(); 96 var pred = ProblemFactory.eINSTANCE.createPredicateDefinition();
100 pred.setName("foo"); 97 pred.setName("foo");
101 var parameter = ProblemFactory.eINSTANCE.createParameter(); 98 var parameter = ProblemFactory.eINSTANCE.createParameter();
102 var nodeType = testUtil.findClass(builtin, "node"); 99 var nodeType = builtin.findClass("node");
103 parameter.setParameterType(nodeType); 100 parameter.setParameterType(nodeType.get());
104 parameter.setName("p"); 101 parameter.setName("p");
105 pred.getParameters().add(parameter); 102 pred.getParameters().add(parameter);
106 problem.getStatements().add(pred); 103 problem.getStatements().add(pred);
@@ -142,20 +139,20 @@ class ProblemSerializerTest {
142 void implicitVariableTest() { 139 void implicitVariableTest() {
143 var pred = ProblemFactory.eINSTANCE.createPredicateDefinition(); 140 var pred = ProblemFactory.eINSTANCE.createPredicateDefinition();
144 pred.setName("foo"); 141 pred.setName("foo");
145 var nodeType = testUtil.findClass(builtin, "node"); 142 var nodeType = builtin.findClass("node");
146 var parameter1 = ProblemFactory.eINSTANCE.createParameter(); 143 var parameter1 = ProblemFactory.eINSTANCE.createParameter();
147 parameter1.setParameterType(nodeType); 144 parameter1.setParameterType(nodeType.get());
148 parameter1.setName("p1"); 145 parameter1.setName("p1");
149 pred.getParameters().add(parameter1); 146 pred.getParameters().add(parameter1);
150 var parameter2 = ProblemFactory.eINSTANCE.createParameter(); 147 var parameter2 = ProblemFactory.eINSTANCE.createParameter();
151 parameter2.setParameterType(nodeType); 148 parameter2.setParameterType(nodeType.get());
152 parameter2.setName("p2"); 149 parameter2.setName("p2");
153 pred.getParameters().add(parameter2); 150 pred.getParameters().add(parameter2);
154 var conjunction = ProblemFactory.eINSTANCE.createConjunction(); 151 var conjunction = ProblemFactory.eINSTANCE.createConjunction();
155 var variable = ProblemFactory.eINSTANCE.createImplicitVariable(); 152 var variable = ProblemFactory.eINSTANCE.createImplicitVariable();
156 variable.setName("q"); 153 variable.setName("q");
157 conjunction.getImplicitVariables().add(variable); 154 conjunction.getImplicitVariables().add(variable);
158 var equals = testUtil.reference(nodeType, "equals"); 155 var equals = nodeType.reference("equals");
159 conjunction.getLiterals().add(createAtom(equals, parameter1, variable)); 156 conjunction.getLiterals().add(createAtom(equals, parameter1, variable));
160 conjunction.getLiterals().add(createAtom(equals, variable, parameter2)); 157 conjunction.getLiterals().add(createAtom(equals, variable, parameter2));
161 pred.getBodies().add(conjunction); 158 pred.getBodies().add(conjunction);
@@ -182,14 +179,14 @@ class ProblemSerializerTest {
182 void singletonVariableTest() { 179 void singletonVariableTest() {
183 var pred = ProblemFactory.eINSTANCE.createPredicateDefinition(); 180 var pred = ProblemFactory.eINSTANCE.createPredicateDefinition();
184 pred.setName("foo"); 181 pred.setName("foo");
185 var nodeType = testUtil.findClass(builtin, "node"); 182 var nodeType = builtin.findClass("node");
186 var parameter = ProblemFactory.eINSTANCE.createParameter(); 183 var parameter = ProblemFactory.eINSTANCE.createParameter();
187 parameter.setParameterType(nodeType); 184 parameter.setParameterType(nodeType.get());
188 parameter.setName("p"); 185 parameter.setName("p");
189 pred.getParameters().add(parameter); 186 pred.getParameters().add(parameter);
190 var conjunction = ProblemFactory.eINSTANCE.createConjunction(); 187 var conjunction = ProblemFactory.eINSTANCE.createConjunction();
191 var atom = ProblemFactory.eINSTANCE.createAtom(); 188 var atom = ProblemFactory.eINSTANCE.createAtom();
192 var equals = testUtil.reference(nodeType, "equals"); 189 var equals = nodeType.reference("equals");
193 atom.setRelation(equals); 190 atom.setRelation(equals);
194 var arg1 = ProblemFactory.eINSTANCE.createVariableOrNodeArgument(); 191 var arg1 = ProblemFactory.eINSTANCE.createVariableOrNodeArgument();
195 arg1.setVariableOrNode(parameter); 192 arg1.setVariableOrNode(parameter);
@@ -224,6 +221,6 @@ class ProblemSerializerTest {
224 } 221 }
225 var problemString = outputStream.toString(); 222 var problemString = outputStream.toString();
226 223
227 assertThat(problemString, equalTo(expected)); 224 assertThat(problemString.replace("\r\n", "\n"), equalTo(expected.replace("\r\n", "\n")));
228 } 225 }
229} 226}
diff --git a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/ProblemNavigationUtil.java b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/ProblemNavigationUtil.java
new file mode 100644
index 00000000..5761935b
--- /dev/null
+++ b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/ProblemNavigationUtil.java
@@ -0,0 +1,20 @@
1package tools.refinery.language.model.tests.utils;
2
3import java.util.List;
4import java.util.stream.Stream;
5
6import tools.refinery.language.model.problem.NamedElement;
7
8class ProblemNavigationUtil {
9 private ProblemNavigationUtil() {
10 throw new IllegalStateException("This is a static utility class and should not be instantiated directly");
11 }
12
13 public static <T extends NamedElement> T named(Stream<? extends T> stream, String name) {
14 return stream.filter(statement -> name.equals(statement.getName())).findAny().get();
15 }
16
17 public static <T extends NamedElement> T named(List<? extends T> list, String name) {
18 return named(list.stream(), name);
19 }
20}
diff --git a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/ProblemParseHelper.java b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/ProblemParseHelper.java
new file mode 100644
index 00000000..5e044a94
--- /dev/null
+++ b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/ProblemParseHelper.java
@@ -0,0 +1,22 @@
1package tools.refinery.language.model.tests.utils;
2
3import org.eclipse.xtext.testing.util.ParseHelper;
4
5import com.google.inject.Inject;
6
7import tools.refinery.language.model.problem.Problem;
8
9public class ProblemParseHelper {
10 @Inject
11 private ParseHelper<Problem> parseHelper;
12
13 public WrappedProblem parse(String text) {
14 Problem problem;
15 try {
16 problem = parseHelper.parse(text);
17 } catch (Exception e) {
18 throw new RuntimeException("Unexpected exception while parsing Problem", e);
19 }
20 return new WrappedProblem(problem);
21 }
22}
diff --git a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedActionLiteral.java b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedActionLiteral.java
new file mode 100644
index 00000000..1411a7ba
--- /dev/null
+++ b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedActionLiteral.java
@@ -0,0 +1,25 @@
1package tools.refinery.language.model.tests.utils;
2
3import tools.refinery.language.model.problem.ActionLiteral;
4import tools.refinery.language.model.problem.DeleteActionLiteral;
5import tools.refinery.language.model.problem.NewActionLiteral;
6import tools.refinery.language.model.problem.ValueActionLiteral;
7import tools.refinery.language.model.problem.VariableOrNode;
8
9public record WrappedActionLiteral(ActionLiteral actionLiteral) {
10 public ActionLiteral get() {
11 return actionLiteral;
12 }
13
14 public VariableOrNode newVar() {
15 return ((NewActionLiteral) actionLiteral).getVariable();
16 }
17
18 public VariableOrNode deleteVar() {
19 return ((DeleteActionLiteral) actionLiteral).getVariableOrNode();
20 }
21
22 public WrappedAtom valueAtom() {
23 return new WrappedAtom(((ValueActionLiteral) actionLiteral).getAtom());
24 }
25}
diff --git a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedArgument.java b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedArgument.java
new file mode 100644
index 00000000..61492184
--- /dev/null
+++ b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedArgument.java
@@ -0,0 +1,25 @@
1package tools.refinery.language.model.tests.utils;
2
3import tools.refinery.language.model.problem.Argument;
4import tools.refinery.language.model.problem.Node;
5import tools.refinery.language.model.problem.Variable;
6import tools.refinery.language.model.problem.VariableOrNode;
7import tools.refinery.language.model.problem.VariableOrNodeArgument;
8
9public record WrappedArgument(Argument argument) {
10 public Argument get() {
11 return argument;
12 }
13
14 public VariableOrNode variableOrNode() {
15 return ((VariableOrNodeArgument) argument).getVariableOrNode();
16 }
17
18 public Variable variable() {
19 return (Variable) variableOrNode();
20 }
21
22 public Node node() {
23 return (Node) variableOrNode();
24 }
25}
diff --git a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedAssertion.java b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedAssertion.java
new file mode 100644
index 00000000..2c38639d
--- /dev/null
+++ b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedAssertion.java
@@ -0,0 +1,13 @@
1package tools.refinery.language.model.tests.utils;
2
3import tools.refinery.language.model.problem.Assertion;
4
5public record WrappedAssertion(Assertion assertion) {
6 public Assertion get() {
7 return assertion;
8 }
9
10 public WrappedAssertionArgument arg(int i) {
11 return new WrappedAssertionArgument(assertion.getArguments().get(i));
12 }
13}
diff --git a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedAssertionArgument.java b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedAssertionArgument.java
new file mode 100644
index 00000000..77ad3746
--- /dev/null
+++ b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedAssertionArgument.java
@@ -0,0 +1,15 @@
1package tools.refinery.language.model.tests.utils;
2
3import tools.refinery.language.model.problem.AssertionArgument;
4import tools.refinery.language.model.problem.Node;
5import tools.refinery.language.model.problem.NodeAssertionArgument;
6
7public record WrappedAssertionArgument(AssertionArgument assertionArgument) {
8 public AssertionArgument get() {
9 return assertionArgument;
10 }
11
12 public Node node() {
13 return ((NodeAssertionArgument) assertionArgument).getNode();
14 }
15}
diff --git a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedAtom.java b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedAtom.java
new file mode 100644
index 00000000..498991f8
--- /dev/null
+++ b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedAtom.java
@@ -0,0 +1,13 @@
1package tools.refinery.language.model.tests.utils;
2
3import tools.refinery.language.model.problem.Atom;
4
5public record WrappedAtom(Atom atom) {
6 public Atom get() {
7 return atom;
8 }
9
10 public WrappedArgument arg(int i) {
11 return new WrappedArgument(atom.getArguments().get(i));
12 }
13}
diff --git a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedClassDeclaration.java b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedClassDeclaration.java
new file mode 100644
index 00000000..d8926c29
--- /dev/null
+++ b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedClassDeclaration.java
@@ -0,0 +1,14 @@
1package tools.refinery.language.model.tests.utils;
2
3import tools.refinery.language.model.problem.ClassDeclaration;
4import tools.refinery.language.model.problem.ReferenceDeclaration;
5
6public record WrappedClassDeclaration(ClassDeclaration classDeclaration) {
7 public ClassDeclaration get() {
8 return classDeclaration;
9 }
10
11 public ReferenceDeclaration reference(String name) {
12 return ProblemNavigationUtil.named(classDeclaration.getReferenceDeclarations(), name);
13 }
14}
diff --git a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedConjunction.java b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedConjunction.java
new file mode 100644
index 00000000..88ff71ab
--- /dev/null
+++ b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedConjunction.java
@@ -0,0 +1,13 @@
1package tools.refinery.language.model.tests.utils;
2
3import tools.refinery.language.model.problem.Conjunction;
4
5public record WrappedConjunction(Conjunction conjunction) {
6 public Conjunction get() {
7 return conjunction;
8 }
9
10 public WrappedLiteral lit(int i) {
11 return new WrappedLiteral(conjunction.getLiterals().get(i));
12 }
13}
diff --git a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedEnumDeclaration.java b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedEnumDeclaration.java
new file mode 100644
index 00000000..74dcf01b
--- /dev/null
+++ b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedEnumDeclaration.java
@@ -0,0 +1,14 @@
1package tools.refinery.language.model.tests.utils;
2
3import tools.refinery.language.model.problem.EnumDeclaration;
4import tools.refinery.language.model.problem.Node;
5
6public record WrappedEnumDeclaration(EnumDeclaration enumDeclaration) {
7 public EnumDeclaration get() {
8 return enumDeclaration;
9 }
10
11 public Node literal(String name) {
12 return ProblemNavigationUtil.named(enumDeclaration.getLiterals(), name);
13 }
14}
diff --git a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedLiteral.java b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedLiteral.java
new file mode 100644
index 00000000..95d651e6
--- /dev/null
+++ b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedLiteral.java
@@ -0,0 +1,24 @@
1package tools.refinery.language.model.tests.utils;
2
3import tools.refinery.language.model.problem.Atom;
4import tools.refinery.language.model.problem.Literal;
5import tools.refinery.language.model.problem.NegativeLiteral;
6import tools.refinery.language.model.problem.ValueLiteral;
7
8public record WrappedLiteral(Literal literal) {
9 public Literal get() {
10 return literal;
11 }
12
13 public WrappedAtom valueAtom() {
14 return new WrappedAtom(((ValueLiteral) literal).getAtom());
15 }
16
17 public WrappedAtom negated() {
18 return new WrappedAtom(((NegativeLiteral) literal).getAtom());
19 }
20
21 public WrappedArgument arg(int i) {
22 return new WrappedAtom((Atom) literal).arg(i);
23 }
24}
diff --git a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedParametricDefinition.java b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedParametricDefinition.java
new file mode 100644
index 00000000..b390051a
--- /dev/null
+++ b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedParametricDefinition.java
@@ -0,0 +1,16 @@
1package tools.refinery.language.model.tests.utils;
2
3import tools.refinery.language.model.problem.Parameter;
4import tools.refinery.language.model.problem.ParametricDefinition;
5
6public interface WrappedParametricDefinition {
7 public ParametricDefinition get();
8
9 public default Parameter param(int i) {
10 return get().getParameters().get(i);
11 }
12
13 public default WrappedConjunction conj(int i) {
14 return new WrappedConjunction(get().getBodies().get(i));
15 }
16}
diff --git a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedPredicateDefinition.java b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedPredicateDefinition.java
new file mode 100644
index 00000000..6b07366d
--- /dev/null
+++ b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedPredicateDefinition.java
@@ -0,0 +1,11 @@
1package tools.refinery.language.model.tests.utils;
2
3import tools.refinery.language.model.problem.PredicateDefinition;
4
5public record WrappedPredicateDefinition(PredicateDefinition predicateDefinition)
6 implements WrappedParametricDefinition {
7 @Override
8 public PredicateDefinition get() {
9 return predicateDefinition;
10 }
11}
diff --git a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedProblem.java b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedProblem.java
new file mode 100644
index 00000000..2bedb4a6
--- /dev/null
+++ b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedProblem.java
@@ -0,0 +1,85 @@
1package tools.refinery.language.model.tests.utils;
2
3import java.util.List;
4import java.util.stream.Stream;
5
6import org.eclipse.emf.ecore.resource.Resource.Diagnostic;
7import org.eclipse.emf.ecore.util.EcoreUtil;
8
9import tools.refinery.language.ProblemUtil;
10import tools.refinery.language.model.problem.Assertion;
11import tools.refinery.language.model.problem.ClassDeclaration;
12import tools.refinery.language.model.problem.EnumDeclaration;
13import tools.refinery.language.model.problem.IndividualDeclaration;
14import tools.refinery.language.model.problem.NamedElement;
15import tools.refinery.language.model.problem.Node;
16import tools.refinery.language.model.problem.NodeValueAssertion;
17import tools.refinery.language.model.problem.PredicateDefinition;
18import tools.refinery.language.model.problem.Problem;
19import tools.refinery.language.model.problem.RuleDefinition;
20import tools.refinery.language.model.problem.Statement;
21
22public record WrappedProblem(Problem problem) {
23 public Problem get() {
24 return problem;
25 }
26
27 public List<Diagnostic> errors() {
28 EcoreUtil.resolveAll(problem);
29 return problem.eResource().getErrors();
30 }
31
32 public WrappedProblem builtin() {
33 return new WrappedProblem(ProblemUtil.getBuiltInLibrary(problem).get());
34 }
35
36 public List<String> nodeNames() {
37 return problem.getNodes().stream().map(node -> node.getName()).toList();
38 }
39
40 public WrappedPredicateDefinition pred(String name) {
41 return new WrappedPredicateDefinition(namedStatementOfType(PredicateDefinition.class, name));
42 }
43
44 public WrappedRuleDefinition rule(String name) {
45 return new WrappedRuleDefinition(namedStatementOfType(RuleDefinition.class, name));
46 }
47
48 public WrappedClassDeclaration findClass(String name) {
49 return new WrappedClassDeclaration(namedStatementOfType(ClassDeclaration.class, name));
50 }
51
52 public WrappedEnumDeclaration findEnum(String name) {
53 return new WrappedEnumDeclaration(namedStatementOfType(EnumDeclaration.class, name));
54 }
55
56 public WrappedAssertion assertion(int i) {
57 return new WrappedAssertion(nthStatementOfType(Assertion.class, i));
58 }
59
60 public Node node(String name) {
61 return ProblemNavigationUtil.named(problem.getNodes(), name);
62 }
63
64 public Node individualNode(String name) {
65 var uniqueNodes = statementsOfType(IndividualDeclaration.class)
66 .flatMap(declaration -> declaration.getNodes().stream());
67 return ProblemNavigationUtil.named(uniqueNodes, name);
68 }
69
70 public NodeValueAssertion nodeValueAssertion(int i) {
71 return nthStatementOfType(NodeValueAssertion.class, i);
72 }
73
74 private <T extends Statement> Stream<T> statementsOfType(Class<? extends T> type) {
75 return problem.getStatements().stream().filter(type::isInstance).map(type::cast);
76 }
77
78 private <T extends Statement & NamedElement> T namedStatementOfType(Class<? extends T> type, String name) {
79 return ProblemNavigationUtil.named(statementsOfType(type), name);
80 }
81
82 private <T extends Statement> T nthStatementOfType(Class<? extends T> type, int n) {
83 return statementsOfType(type).skip(n).findFirst().get();
84 }
85}
diff --git a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedRuleDefinition.java b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedRuleDefinition.java
new file mode 100644
index 00000000..53a90dde
--- /dev/null
+++ b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedRuleDefinition.java
@@ -0,0 +1,14 @@
1package tools.refinery.language.model.tests.utils;
2
3import tools.refinery.language.model.problem.RuleDefinition;
4
5public record WrappedRuleDefinition(RuleDefinition ruleDefinition) implements WrappedParametricDefinition {
6 @Override
7 public RuleDefinition get() {
8 return ruleDefinition;
9 }
10
11 public WrappedActionLiteral actionLit(int i) {
12 return new WrappedActionLiteral(ruleDefinition.getAction().getActionLiterals().get(i));
13 }
14}