| /******************************************************************************* |
| * Copyright (c) 2005, 2011, 2018 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v2.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v20.html |
| * |
| * Contributors: |
| * IBM - Initial API and implementation |
| * Zeligsoft - Bug 253252 |
| * Borland - Bug 242880 |
| * E.D.Willink - Bug 295166 |
| * Axel Uhl (SAP AG) - Bug 342644 |
| *******************************************************************************/ |
| |
| package org.eclipse.ocl.ecore.tests; |
| |
| import java.io.IOException; |
| import java.util.Collections; |
| import java.util.Set; |
| |
| import org.eclipse.emf.common.util.URI; |
| import org.eclipse.emf.ecore.EAnnotation; |
| import org.eclipse.emf.ecore.EAttribute; |
| import org.eclipse.emf.ecore.EClass; |
| import org.eclipse.emf.ecore.EClassifier; |
| import org.eclipse.emf.ecore.EOperation; |
| import org.eclipse.emf.ecore.EPackage.Registry; |
| import org.eclipse.emf.ecore.EcoreFactory; |
| import org.eclipse.emf.ecore.EcorePackage; |
| import org.eclipse.emf.ecore.impl.EPackageRegistryImpl; |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.ocl.ParserException; |
| import org.eclipse.ocl.ecore.EcoreEnvironment; |
| import org.eclipse.ocl.ecore.EcoreEnvironmentFactory; |
| import org.eclipse.ocl.ecore.OCL; |
| import org.eclipse.ocl.ecore.OCL.Helper; |
| import org.eclipse.ocl.ecore.OperationCallExp; |
| import org.eclipse.ocl.ecore.TypeExp; |
| import org.eclipse.ocl.expressions.CollectionKind; |
| import org.eclipse.ocl.expressions.ExpressionsPackage; |
| import org.eclipse.ocl.expressions.OCLExpression; |
| import org.eclipse.ocl.options.EvaluationOptions; |
| import org.eclipse.ocl.options.ParsingOptions; |
| import org.eclipse.ocl.types.CollectionType; |
| |
| /** |
| * Basic tests for OCL engine. |
| * |
| */ |
| @SuppressWarnings("nls") |
| public class BasicOCLTest |
| extends AbstractTestSuite { |
| |
| public void testAliasPackageName() throws ParserException { |
| EClass eCls = EcoreFactory.eINSTANCE.createEClass(); |
| eCls.setName("bar"); |
| Registry r = new EPackageRegistryImpl(); |
| r.put("EMFEcore", EcorePackage.eINSTANCE); |
| r.put("OCLEcore", org.eclipse.ocl.ecore.EcorePackage.eINSTANCE); |
| OCL ocl = OCL.newInstance(new EcoreEnvironmentFactory(r)); |
| ((EcoreEnvironment) ocl.getEnvironment()).setOption( |
| ParsingOptions.PACKAGE_LOOKUP_STRATEGY, |
| ParsingOptions.PACKAGE_LOOKUP_STRATEGIES.LOOKUP_PACKAGE_BY_ALIAS); |
| Helper helper = ocl.createOCLHelper(); |
| helper.setContext(org.eclipse.ocl.ecore.EcorePackage.eINSTANCE.getOCLExpression()); |
| org.eclipse.ocl.ecore.OCLExpression expr = helper.createQuery( |
| "self.oclIsKindOf(EMFEcore::EClassifier) and not self.oclIsKindOf(OCLEcore::OCLExpression)"); |
| assertTrue(check(expr, eCls)); |
| OperationCallExp and = (OperationCallExp) expr; |
| OperationCallExp selfOclIsKindOfEMFEcoreEClassifier = (OperationCallExp) and |
| .getSource(); |
| TypeExp emfEcoreEClassifier = (TypeExp) selfOclIsKindOfEMFEcoreEClassifier |
| .getArgument().get(0); |
| assertSame(EcorePackage.eINSTANCE.getEClassifier(), |
| emfEcoreEClassifier.getReferredType()); |
| OperationCallExp not = (OperationCallExp) and.getArgument().get(0); |
| OperationCallExp selfOclIsKindOfOCLEcoreOCLExpression = (OperationCallExp) not |
| .getSource(); |
| TypeExp oclEcoreOCLExpression = (TypeExp) selfOclIsKindOfOCLEcoreOCLExpression |
| .getArgument().get(0); |
| assertSame( |
| org.eclipse.ocl.ecore.EcorePackage.eINSTANCE.getOCLExpression(), |
| oclEcoreOCLExpression.getReferredType()); |
| } |
| |
| /** |
| * Ensure that regular package names are still found even if alias lookup strategy is selected |
| */ |
| public void testRegularPackageNameInContextWithAliasLookupEnabled() |
| throws ParserException { |
| EClass eCls = EcoreFactory.eINSTANCE.createEClass(); |
| eCls.setName("bar"); |
| Registry r = new EPackageRegistryImpl(); |
| r.put("EMFEcore", EcorePackage.eINSTANCE); |
| r.put("OCLEcore", org.eclipse.ocl.ecore.EcorePackage.eINSTANCE); |
| OCL ocl = OCL.newInstance(new EcoreEnvironmentFactory(r)); |
| ((EcoreEnvironment) ocl.getEnvironment()).setOption( |
| ParsingOptions.PACKAGE_LOOKUP_STRATEGY, |
| ParsingOptions.PACKAGE_LOOKUP_STRATEGIES.LOOKUP_PACKAGE_BY_ALIAS); |
| Helper helper = ocl.createOCLHelper(); |
| helper.setContext(org.eclipse.ocl.ecore.EcorePackage.eINSTANCE |
| .getOCLExpression()); |
| org.eclipse.ocl.ecore.OCLExpression expr = helper |
| .createQuery("self.oclIsKindOf(ecore::OCLExpression)"); |
| OperationCallExp oclIsKindOf = (OperationCallExp) expr; |
| TypeExp emfEcoreEClassifier = (TypeExp) oclIsKindOf.getArgument().get(0); |
| assertSame( |
| org.eclipse.ocl.ecore.EcorePackage.eINSTANCE.getOCLExpression(), |
| emfEcoreEClassifier.getReferredType()); |
| } |
| |
| /** |
| * Ensure that regular package names are still found even if alias lookup strategy is selected |
| */ |
| public void testRegularPackageNameOutOfContextWithAliasLookupEnabled() |
| throws ParserException { |
| initFruitPackage(); |
| EClass eCls = EcoreFactory.eINSTANCE.createEClass(); |
| eCls.setName("bar"); |
| Registry r = new EPackageRegistryImpl(); // delegating registry |
| r.putAll(resourceSet.getPackageRegistry()); |
| r.put("EMFEcore", EcorePackage.eINSTANCE); |
| r.put("OCLEcore", org.eclipse.ocl.ecore.EcorePackage.eINSTANCE); |
| OCL ocl = OCL.newInstance(new EcoreEnvironmentFactory(r)); |
| ((EcoreEnvironment) ocl.getEnvironment()).setOption( |
| ParsingOptions.PACKAGE_LOOKUP_STRATEGY, |
| ParsingOptions.PACKAGE_LOOKUP_STRATEGIES.LOOKUP_PACKAGE_BY_ALIAS_THEN_NAME); |
| Helper helper = ocl.createOCLHelper(); |
| helper.setContext(org.eclipse.ocl.ecore.EcorePackage.eINSTANCE |
| .getOCLExpression()); |
| org.eclipse.ocl.ecore.OCLExpression expr = helper |
| .createQuery("self.oclIsKindOf(OclTest::Fruit)"); |
| OperationCallExp oclIsKindOf = (OperationCallExp) expr; |
| TypeExp emfEcoreEClassifier = (TypeExp) oclIsKindOf.getArgument().get(0); |
| assertSame( |
| fruitPackage.getEClassifier("Fruit"), |
| emfEcoreEClassifier.getReferredType()); |
| } |
| |
| public void hide_test_createStandardLibrary() { |
| Resource res = ocl.getEnvironment().getOCLStandardLibrary().getOclAny().eResource(); |
| URI oldURI = res.getURI(); |
| |
| res.setURI(URI.createFileURI("c:/temp/oclstdlib.ecore")); |
| try { |
| res.save(Collections.EMPTY_MAP); |
| } catch (IOException e) { |
| fail(e.getLocalizedMessage()); |
| } finally { |
| // restore the correct URI |
| res.setURI(oldURI); |
| } |
| } |
| |
| /** |
| * Tests that the results of the <tt>oclOperations()</tt> and <tt>oclIterators()</tt> |
| * methods are the same regardless of which is invoked first. |
| */ |
| public void test_collectionsAndIteratorsAccess_222747() { |
| CollectionType<EClassifier, EOperation> type = ocl.getEnvironment().getOCLFactory().createSetType( |
| (EClassifier) EcorePackage.Literals.ERESOURCE); |
| |
| Set<EOperation> iterators = new java.util.HashSet<EOperation>(type.oclIterators()); |
| Set<EOperation> operations = new java.util.HashSet<EOperation>(type.oclOperations()); |
| |
| // compute the set difference |
| Set<EOperation> difference = new java.util.HashSet<EOperation>(operations); |
| difference.removeAll(iterators); |
| |
| assertEquals(difference.size(), operations.size()); |
| assertTrue(operations.size() > 0); |
| assertTrue(iterators.size() > 0); |
| } |
| |
| public void testTrivialExpressions() { |
| OCLExpression<EClassifier> constraint = parseConstraint( |
| "package ecore context EClass " + |
| "inv: true " + |
| "endpackage"); |
| |
| Object result = evaluate(constraint); |
| assertEquals(Boolean.TRUE, result); |
| |
| constraint = parseConstraint( |
| "package ecore context EClass " + |
| "inv: false " + |
| "endpackage"); |
| |
| result = evaluate(constraint); |
| assertEquals(Boolean.FALSE, result); |
| } |
| |
| public void testLogicalConnectives() { |
| OCLExpression<EClassifier> constraint = parseConstraint( |
| "package ecore context EClass " + |
| "inv: true and true " + |
| "endpackage"); |
| |
| Object result = evaluate(constraint); |
| assertEquals(Boolean.TRUE, result); |
| |
| constraint = parseConstraint( |
| "package ecore context EClass " + |
| "inv: false or false " + |
| "endpackage"); |
| |
| result = evaluate(constraint); |
| assertEquals(Boolean.FALSE, result); |
| |
| constraint = parseConstraint( |
| "package ecore context EClass " + |
| "inv: true and false " + |
| "endpackage"); |
| |
| result = evaluate(constraint); |
| assertEquals(Boolean.FALSE, result); |
| |
| constraint = parseConstraint( |
| "package ecore context EClass " + |
| "inv: true or false " + |
| "endpackage"); |
| |
| result = evaluate(constraint); |
| assertEquals(Boolean.TRUE, result); |
| |
| constraint = parseConstraint( |
| "package ecore context EClass " + |
| "inv: not true " + |
| "endpackage"); |
| |
| result = evaluate(constraint); |
| assertEquals(Boolean.FALSE, result); |
| |
| constraint = parseConstraint( |
| "package ecore context EClass " + |
| "inv: true implies true " + |
| "endpackage"); |
| |
| result = evaluate(constraint); |
| assertEquals(Boolean.TRUE, result); |
| |
| constraint = parseConstraint( |
| "package ecore context EClass " + |
| "inv: true implies false " + |
| "endpackage"); |
| |
| result = evaluate(constraint); |
| assertEquals(Boolean.FALSE, result); |
| |
| constraint = parseConstraint( |
| "package ecore context EClass " + |
| "inv: false implies true " + |
| "endpackage"); |
| |
| result = evaluate(constraint); |
| assertEquals(Boolean.TRUE, result); |
| |
| constraint = parseConstraint( |
| "package ecore context EClass " + |
| "inv: false implies false " + |
| "endpackage"); |
| |
| result = evaluate(constraint); |
| assertEquals(Boolean.TRUE, result); |
| } |
| |
| public void testSimpleAttributeExpressions() { |
| EClass eCls = EcoreFactory.eINSTANCE.createEClass(); |
| eCls.setName("bar"); |
| |
| OCLExpression<EClassifier> constraint = parseConstraint( |
| "package ecore context EClass " + |
| "inv: self.name <> 'foo' " + |
| "endpackage"); |
| |
| assertTrue(check(constraint, eCls)); |
| |
| eCls.setName("foo"); |
| assertFalse(check(constraint, eCls)); |
| } |
| |
| public void testCollectionExpressions() { |
| EClass eCls = EcoreFactory.eINSTANCE.createEClass(); |
| eCls.setName("bar"); |
| |
| EAttribute eAttr = EcoreFactory.eINSTANCE.createEAttribute(); |
| eAttr.setName("att1"); |
| eCls.getEStructuralFeatures().add(eAttr); |
| eAttr = EcoreFactory.eINSTANCE.createEAttribute(); |
| eAttr.setName("att2"); |
| eCls.getEStructuralFeatures().add(eAttr); |
| |
| assertEquals(eCls.getEAttributes().size(),2); |
| |
| OCLExpression<EClassifier> constraint = parseConstraint( |
| "package ecore context EClass " + |
| "inv: self.eAttributes->size() = 2 " + |
| "endpackage"); |
| |
| assertTrue(check(constraint, eCls)); |
| |
| OCLExpression<EClassifier> constraint2 = parseConstraint( |
| "package ecore context EClass " + |
| "inv: Tuple{status:Boolean=self.eAttributes->size() = 2}.status " + |
| "endpackage"); |
| |
| assertTrue(check(constraint2, eCls)); |
| |
| constraint = parseConstraint( |
| "package ecore context EClass " + |
| "inv: self.eAttributes->forAll(a: EAttribute | not a.derived) " + |
| "endpackage"); |
| |
| assertTrue(check(constraint, eCls)); |
| } |
| |
| public void testNonBooleansExpressions() { |
| EClass eCls = EcoreFactory.eINSTANCE.createEClass(); |
| eCls.setName("bar"); |
| |
| OCLExpression<EClassifier> expr = parse( |
| "package ecore context EClass " + |
| "inv: self.name " + |
| "endpackage "); |
| |
| Object result = evaluate(expr, eCls); |
| assertEquals("bar", result); |
| |
| expr = parse( |
| "package ecore context EClass " + |
| "inv: self " + |
| "endpackage"); |
| |
| result = evaluate(expr, eCls); |
| assertSame(eCls, result); |
| } |
| |
| public void testIfExpressions() { |
| EClass eCls = EcoreFactory.eINSTANCE.createEClass(); |
| eCls.setName("bar"); |
| |
| OCLExpression<EClassifier> expr = parse( |
| "package ecore context EClass " + |
| "inv: if self.abstract then name = 'bar' else name <> 'bar' endif " + |
| "endpackage "); |
| |
| assertFalse(check(expr, eCls)); |
| |
| eCls.setAbstract(true); |
| |
| assertTrue(check(expr, eCls)); |
| |
| eCls.setName("foo"); |
| |
| assertFalse(check(expr, eCls)); |
| } |
| |
| public void testIfExpressions_184048() { |
| EClass eCls = EcoreFactory.eINSTANCE.createEClass(); |
| eCls.setName("bar"); |
| |
| OCLExpression<EClassifier> expr = parse( |
| "package ecore context EClass " + |
| "inv: if self.abstract then name = 'bar' else name <> 'bar' endif ->asSequence()->at(1)" + |
| "endpackage "); |
| |
| assertFalse(check(expr, eCls)); |
| |
| eCls.setAbstract(true); |
| |
| assertTrue(check(expr, eCls)); |
| |
| eCls.setName("foo"); |
| |
| assertFalse(check(expr, eCls)); |
| |
| OCLExpression<EClassifier> expr2 = parse( |
| "package ecore context EClass " + |
| "inv: 7 = 1 + let a : String = invalid in 1 + if self.oclIsUndefined() then 1 else 5 endif " + |
| "endpackage "); |
| assertTrue(check(expr2, eCls)); |
| } |
| |
| public void testLetExpressions() { |
| EClass eCls = EcoreFactory.eINSTANCE.createEClass(); |
| eCls.setName("foo"); |
| |
| OCLExpression<EClassifier> expr = parse( |
| "package ecore context EClass " + |
| "inv: let feats : OrderedSet(EStructuralFeature) = self.eAllStructuralFeatures in " + |
| " feats->isEmpty() implies name <> 'bar' " + |
| "endpackage "); |
| |
| assertTrue(check(expr, eCls)); |
| |
| eCls.setName("bar"); |
| |
| assertFalse(check(expr, eCls)); |
| |
| eCls.getEStructuralFeatures().add(EcoreFactory.eINSTANCE.createEAttribute()); |
| |
| assertTrue(check(expr, eCls)); |
| |
| eCls.setName("foo"); |
| |
| assertTrue(check(expr, eCls)); |
| } |
| |
| /** |
| * Tests the support for data types as context classifiers, rather than |
| * EClasses. The parser now supports arbitrary EClassifiers. |
| */ |
| public void test_dataTypeAsContext() { |
| OCLExpression<EClassifier> expr = parse( |
| "package ecore context EString " + |
| "inv: self.toUpper() <> self.toLower() " + |
| "endpackage "); |
| |
| assertTrue(check(expr, "anything")); |
| assertTrue(check(expr, "ANYTHING")); |
| |
| expr = parse( |
| "package ecore context EString " + |
| "inv: self.toUpper() " + |
| "endpackage "); |
| |
| assertEquals("ANYTHING", evaluate(expr, "anything")); |
| } |
| |
| /** |
| * Tests the overrides for equality of primitive values. In OCL, reals |
| * can equal integers, but not in Java. |
| */ |
| public void test_equals_primitives() { |
| assertTrue(check("1 = 1")); |
| assertTrue(check("1 = 1.0")); |
| assertTrue(check("1.0 = 1")); |
| assertTrue(check("1.0 = 1.0")); |
| |
| assertTrue(check("'foo' = 'foo'")); |
| |
| assertTrue(check("ocltest::Color::red = ocltest::Color::red")); |
| assertFalse(check("ocltest::Color::red = ocltest::Color::black")); |
| } |
| |
| /** |
| * Tests backslashes in strings and the non-standard escape for |
| * double-quotes in the double-quote syntax that is non-standard, anyway. |
| */ |
| public void test_backslashes_184948() { |
| helper.setContext(EcorePackage.Literals.ESTRING); |
| |
| Boolean oldBackslashProcessingEnabled = ParsingOptions.getValue(ocl |
| .getEnvironment(), ParsingOptions.USE_BACKSLASH_ESCAPE_PROCESSING); |
| ParsingOptions.setOption(ocl.getEnvironment(), |
| ParsingOptions.USE_BACKSLASH_ESCAPE_PROCESSING, false); |
| |
| String self = ""; |
| |
| try { |
| assertEquals("str\\ning", |
| evaluate(helper, self, "'str\\ning'")); |
| |
| assertEquals("str\\(ing", |
| evaluate(helper, self, "'str\\(ing'")); |
| |
| assertEquals("string", |
| evaluate(helper, self, "let \"s\\\"g\" : String = 'string' in " + |
| "\"s\\\"g\"")); |
| } catch (ParserException e) { |
| fail("Failed to parse or evaluate: " + e.getLocalizedMessage()); |
| } finally { |
| ParsingOptions.setOption(ocl.getEnvironment(), |
| ParsingOptions.USE_BACKSLASH_ESCAPE_PROCESSING, |
| oldBackslashProcessingEnabled); |
| } |
| } |
| |
| /** |
| * Tests backslash escaping in string literals. |
| */ |
| public void test_escapeSequences_242880() { |
| helper.setContext(EcorePackage.Literals.ESTRING); |
| String self = ""; |
| |
| try { |
| assertInvalidString("'\\\\\\ '"); |
| assertInvalidString("'str\\(ing'"); |
| // a comment |
| assertInvalidString("'string\\'"); |
| assertInvalidString("'string\\9'"); |
| |
| assertEquals("\\", |
| evaluate(helper, self, "'\\\\'")); |
| |
| assertEquals("str\ning", |
| evaluate(helper, self, "'str\\ning'")); |
| |
| assertEquals("str\\(ing", |
| evaluate(helper, self, "'str\\\\(ing'")); |
| |
| assertEquals("string", |
| evaluate(helper, self, |
| "let \"s\\\"g\" : String = 'string' in " + |
| "\"s\\\"g\"")); |
| |
| assertEquals("str\b \t \n \f \r \" \' \\ing", |
| evaluate(helper, self, |
| "'str\\b \\t \\n \\f \\r \\\" \\\' \\\\ing'")); |
| |
| assertEquals("\123tring", |
| evaluate(helper, self, "'\\123tring'")); |
| |
| assertEquals("\0123tring", |
| evaluate(helper, self, "'\\0123tring'")); |
| |
| assertEquals("\70123tring", |
| evaluate(helper, self, "'\\70123tring'")); |
| |
| assertEquals("\70\123tring", |
| evaluate(helper, self, "'\\70\\123tring'")); |
| |
| assertEquals("\70\123tring", |
| evaluate(helper, self, "'\\70\\123tring'")); |
| |
| assertEquals("\345string", |
| evaluate(helper, self, "'\\345string'")); |
| |
| assertEquals("\456string", |
| evaluate(helper, self, "'\\456string'")); |
| |
| assertEquals("\12", |
| evaluate(helper, self, "'\\12'")); |
| |
| assertEquals("string\12", |
| evaluate(helper, self, "'string\\12'")); |
| |
| assertEquals("string\377", |
| evaluate(helper, self, "'string\\377'")); |
| |
| assertEquals("string\t\378", |
| evaluate(helper, self, "'string\\t\\378'")); |
| } catch (ParserException e) { |
| fail("Failed to parse or evaluate: " + e.getLocalizedMessage()); |
| } |
| } |
| |
| public void test_stringEscapes_184948() { |
| helper.setContext(EcorePackage.Literals.ESTRING); |
| String self = ""; |
| |
| try { |
| // assertEquals("str'ing", |
| // evaluate(helper, self, "'str''ing'")); |
| |
| assertEquals("", |
| evaluate(helper, self, "''")); |
| |
| assertEquals("", |
| evaluate(helper, self, "''''")); |
| assertEquals("", |
| evaluate(helper, self, "'' ''")); |
| assertEquals("string", |
| evaluate(helper, self, "'str' 'ing'")); |
| } catch (ParserException e) { |
| fail("Failed to parse or evaluate: " + e.getLocalizedMessage()); |
| } |
| } |
| |
| /** |
| * Tests that the value of an enumeration literal expression is the Java |
| * enumerated type instance, not the <tt>EEnumLiteral</tt> model element. |
| */ |
| public void test_enumerationLiteralValue_198945() { |
| helper.setContext(ExpressionsPackage.Literals.COLLECTION_KIND); |
| |
| try { |
| assertSame(CollectionKind.SEQUENCE_LITERAL, |
| evaluate(helper, CollectionKind.BAG_LITERAL, "CollectionKind::Sequence")); |
| } catch (ParserException e) { |
| fail("Failed to parse or evaluate: " + e.getLocalizedMessage()); |
| } |
| } |
| |
| /** |
| * Tests the lax null-handling option for <tt>null</tt> values. |
| */ |
| public void test_laxNullHandling_null() { |
| helper.setContext(EcorePackage.Literals.EANNOTATION); |
| EAnnotation annotation = EcoreFactory.eINSTANCE.createEAnnotation(); |
| |
| try { |
| // lax null handling on for literal nulls (which are handled |
| // separately from null values in non-OclVoid expressions) |
| assertEquals(Boolean.TRUE, |
| evaluate(helper, annotation, "null.oclIsTypeOf(OclVoid)")); |
| assertEquals(Boolean.TRUE, |
| evaluate(helper, annotation, "null.oclIsKindOf(OclVoid)")); |
| assertEquals(Boolean.FALSE, |
| evaluate(helper, annotation, "null.oclIsTypeOf(OclInvalid)")); |
| assertEquals(Boolean.FALSE, |
| evaluate(helper, annotation, "null.oclIsKindOf(OclInvalid)")); |
| assertNull( |
| evaluate(helper, annotation, "null.oclAsType(OclVoid)")); |
| assertNull( |
| evaluate(helper, annotation, "null.oclAsType(EAnnotation)")); |
| assertNull( |
| evaluate(helper, annotation, "null.oclAsType(String)")); |
| |
| // lax null handling on for null values in non-OclVoid expressions) |
| assertEquals(Boolean.TRUE, |
| evaluate(helper, annotation, "source.oclIsTypeOf(OclVoid)")); |
| assertEquals(Boolean.TRUE, |
| evaluate(helper, annotation, "source.oclIsKindOf(OclVoid)")); |
| assertNull( |
| evaluate(helper, annotation, "source.oclAsType(OclVoid)")); |
| assertNull( |
| evaluate(helper, annotation, "source.oclAsType(EAnnotation)")); |
| assertNull( |
| evaluate(helper, annotation, "source.oclAsType(String)")); |
| |
| |
| EvaluationOptions.setOption(ocl.getEvaluationEnvironment(), |
| EvaluationOptions.LAX_NULL_HANDLING, false); |
| |
| // strict null handling on for literal nulls (which are handled |
| // separately from null values in non-OclVoid expressions) |
| assertEquals(getInvalid(), |
| evaluate(helper, annotation, "null.oclIsTypeOf(OclVoid)")); |
| assertEquals(getInvalid(), |
| evaluate(helper, annotation, "null.oclIsKindOf(OclVoid)")); |
| assertEquals(getInvalid(), |
| evaluate(helper, annotation, "null.oclIsTypeOf(OclInvalid)")); |
| assertEquals(getInvalid(), |
| evaluate(helper, annotation, "null.oclIsKindOf(OclInvalid)")); |
| assertEquals(getInvalid(), |
| evaluate(helper, annotation, "null.oclAsType(OclVoid)")); |
| assertEquals(getInvalid(), |
| evaluate(helper, annotation, "null.oclAsType(EAnnotation)")); |
| assertEquals(getInvalid(), |
| evaluate(helper, annotation, "null.oclAsType(String)")); |
| |
| // strict null handling on for null values in non-OclVoid expressions) |
| assertEquals(getInvalid(), |
| evaluate(helper, annotation, "source.oclIsTypeOf(OclVoid)")); |
| assertEquals(getInvalid(), |
| evaluate(helper, annotation, "source.oclIsKindOf(OclVoid)")); |
| assertEquals(getInvalid(), |
| evaluate(helper, annotation, "source.oclAsType(OclVoid)")); |
| assertEquals(getInvalid(), |
| evaluate(helper, annotation, "source.oclAsType(EAnnotation)")); |
| assertEquals(getInvalid(), |
| evaluate(helper, annotation, "source.oclAsType(String)")); |
| } catch (ParserException e) { |
| fail("Failed to parse or evaluate: " + e.getLocalizedMessage()); |
| } |
| } |
| |
| /** |
| * Tests the lax null-handling option for <tt>OclInvalid</tt> values. |
| */ |
| public void test_laxNullHandling_OclInvalid() { |
| helper.setContext(EcorePackage.Literals.EANNOTATION); |
| EAnnotation annotation = EcoreFactory.eINSTANCE.createEAnnotation(); |
| |
| try { |
| // lax null handling on for literal invalids (which are handled |
| // separately from invalid values in non-OclInvalid expressions) |
| assertEquals(Boolean.TRUE, |
| evaluate(helper, annotation, "invalid.oclIsTypeOf(OclInvalid)")); |
| assertEquals(Boolean.TRUE, |
| evaluate(helper, annotation, "invalid.oclIsKindOf(OclInvalid)")); |
| assertEquals(getInvalid(), |
| evaluate(helper, annotation, "invalid.oclAsType(OclInvalid)")); |
| assertEquals(getInvalid(), |
| evaluate(helper, annotation, "invalid.oclAsType(EAnnotation)")); |
| assertEquals(getInvalid(), |
| evaluate(helper, annotation, "invalid.oclAsType(String)")); |
| |
| // lax null handling on for invalid values in non-OclInvalid expressions) |
| assertEquals(Boolean.TRUE, |
| evaluate(helper, annotation, "source.substring(1, 1).oclIsTypeOf(OclInvalid)")); |
| assertEquals(Boolean.TRUE, |
| evaluate(helper, annotation, "source.substring(1, 1).oclIsKindOf(OclInvalid)")); |
| assertEquals(getInvalid(), |
| evaluate(helper, annotation, "source.substring(1, 1).oclAsType(OclInvalid)")); |
| assertEquals(getInvalid(), |
| evaluate(helper, annotation, "source.substring(1, 1).oclAsType(EAnnotation)")); |
| assertEquals(getInvalid(), |
| evaluate(helper, annotation, "source.substring(1, 1).oclAsType(String)")); |
| |
| |
| EvaluationOptions.setOption(ocl.getEvaluationEnvironment(), |
| EvaluationOptions.LAX_NULL_HANDLING, false); |
| |
| // strict null handling on for literal invalids (which are handled |
| // separately from invalid values in non-OclInvalid expressions) |
| assertEquals(getInvalid(), |
| evaluate(helper, annotation, "invalid.oclIsTypeOf(OclInvalid)")); |
| assertEquals(getInvalid(), |
| evaluate(helper, annotation, "invalid.oclIsKindOf(OclInvalid)")); |
| assertEquals(getInvalid(), |
| evaluate(helper, annotation, "invalid.oclAsType(OclInvalid)")); |
| assertEquals(getInvalid(), |
| evaluate(helper, annotation, "invalid.oclAsType(EAnnotation)")); |
| assertEquals(getInvalid(), |
| evaluate(helper, annotation, "invalid.oclAsType(String)")); |
| |
| // strict null handling on for invalid values in non-OclInvalid expressions) |
| assertEquals(getInvalid(), |
| evaluate(helper, annotation, "source.substring(1, 1).oclIsTypeOf(OclInvalid)")); |
| assertEquals(getInvalid(), |
| evaluate(helper, annotation, "source.substring(1, 1).oclIsKindOf(OclInvalid)")); |
| assertEquals(getInvalid(), |
| evaluate(helper, annotation, "source.substring(1, 1).oclAsType(OclInvalid)")); |
| assertEquals(getInvalid(), |
| evaluate(helper, annotation, "source.substring(1, 1).oclAsType(EAnnotation)")); |
| assertEquals(getInvalid(), |
| evaluate(helper, annotation, "source.substring(1, 1).oclAsType(String)")); |
| } catch (ParserException e) { |
| fail("Failed to parse or evaluate: " + e.getLocalizedMessage()); |
| } |
| } |
| |
| /** |
| * Tests that lax null handling works with oclAsType in the EClass context, |
| * as well (in the Ecore metamodel). |
| */ |
| public void test_lax_null_handling_on_EcoreModel_253252() { |
| helper.setContext(EcorePackage.Literals.ECLASSIFIER); |
| EClassifier eclassifier = null; |
| |
| try { |
| // lax null handling on for invalid values in non-OclInvalid expressions) |
| assertEquals(null, |
| evaluate(helper, eclassifier, "self.oclAsType(EClass)")); |
| |
| EvaluationOptions.setOption(ocl.getEvaluationEnvironment(), |
| EvaluationOptions.LAX_NULL_HANDLING, false); |
| |
| // strict null handling on for invalid values in non-OclInvalid expressions) |
| assertEquals(getInvalid(), |
| evaluate(helper, eclassifier, "self.oclAsType(EClass)")); |
| } catch (ParserException e) { |
| fail("Failed to parse or evaluate: " + e.getLocalizedMessage()); |
| } |
| } |
| |
| /** |
| * Tests that the null type conforms to all others, and supports |
| * equality comparison with all other types. |
| */ |
| public void test_null_typeConformance_191041() { |
| helper.setContext(EcorePackage.Literals.ESTRING); |
| |
| try { |
| assertTrue( |
| check(helper, EcorePackage.eNS_URI, "null <> Set{'foo'}")); |
| assertFalse( |
| check(helper, EcorePackage.eNS_URI, "null = Set{'foo'}")); |
| assertTrue( |
| check(helper, EcorePackage.eNS_URI, "null <> Sequence{'foo'}")); |
| assertFalse( |
| check(helper, EcorePackage.eNS_URI, "null = Sequence{'foo'}")); |
| assertTrue( |
| check(helper, EcorePackage.eNS_URI, "null <> OrderedSet{'foo'}")); |
| assertFalse( |
| check(helper, EcorePackage.eNS_URI, "null = OrderedSet{'foo'}")); |
| assertTrue( |
| check(helper, EcorePackage.eNS_URI, "null <> Bag{'foo'}")); |
| assertFalse( |
| check(helper, EcorePackage.eNS_URI, "null = Bag{'foo'}")); |
| } catch (ParserException e) { |
| fail("Failed to parse or evaluate: " + e.getLocalizedMessage()); |
| } |
| } |
| |
| /** |
| * oclAsType must result in invalid for source not conforming to target type and |
| * in the source object in case it conforms to the target type |
| */ |
| public void test_oclAsTypeConformingAndNonConforming() { |
| helper.setContext(EcorePackage.eINSTANCE.getEClassifier()); |
| try { |
| assertTrue( |
| check(helper, EcorePackage.eINSTANCE.getEOperation(), "self.oclAsType(EAnnotation).oclIsInvalid()")); |
| assertTrue( |
| check(helper, EcorePackage.eINSTANCE.getEOperation(), "self.oclAsType(EClassifier) = self")); |
| assertTrue( |
| check(helper, EcorePackage.eINSTANCE.getEOperation(), "self.oclAsType(EClass) = self")); |
| assertTrue( |
| check(helper, EcorePackage.eINSTANCE.getEOperation(), "self.oclAsType(EDataType).oclIsInvalid()")); |
| assertTrue( |
| check(helper, EcorePackage.eINSTANCE.getEOperation(), "self.oclAsType(ocl::ecore::TupleType).oclIsInvalid()")); |
| } catch (ParserException e) { |
| fail("Failed to parse or evaluate: " + e.getLocalizedMessage()); |
| } |
| } |
| |
| /** |
| * Tests that the OclInvalid type conforms to all others, and supports |
| * equality comparison with all other types. |
| */ |
| public void test_OclInvalid_typeConformance_191041() { |
| helper.setContext(EcorePackage.Literals.ESTRING); |
| |
| try { |
| assertTrue( |
| check(helper, EcorePackage.eNS_URI, "(invalid <> Set{'foo'}).oclIsInvalid()")); |
| assertTrue( |
| check(helper, EcorePackage.eNS_URI, "(invalid = Set{'foo'}).oclIsInvalid()")); |
| assertTrue( |
| check(helper, EcorePackage.eNS_URI, "(invalid <> Sequence{'foo'}).oclIsInvalid()")); |
| assertTrue( |
| check(helper, EcorePackage.eNS_URI, "(invalid = Sequence{'foo'}).oclIsInvalid()")); |
| assertTrue( |
| check(helper, EcorePackage.eNS_URI, "(invalid <> OrderedSet{'foo'}).oclIsInvalid()")); |
| assertTrue( |
| check(helper, EcorePackage.eNS_URI, "(invalid = OrderedSet{'foo'}).oclIsInvalid()")); |
| assertTrue( |
| check(helper, EcorePackage.eNS_URI, "(invalid <> Bag{'foo'}).oclIsInvalid()")); |
| assertTrue( |
| check(helper, EcorePackage.eNS_URI, "(invalid = Bag{'foo'}).oclIsInvalid()")); |
| } catch (ParserException e) { |
| fail("Failed to parse or evaluate: " + e.getLocalizedMessage()); |
| } |
| } |
| |
| private void assertInvalidString(String input) { |
| boolean isParserError = false; |
| try { |
| evaluate(helper, "", input); |
| } catch (ParserException e) { |
| isParserError = true; |
| } |
| assertTrue(isParserError); |
| } |
| } |