blob: 5b1ceeca7aa87051649277e9515a946b90fc0675 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006, 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
* E.D.Willink - Bug 296409, 297541
*******************************************************************************/
package org.eclipse.ocl.tests;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.ocl.SemanticException;
import org.eclipse.ocl.SyntaxException;
import org.eclipse.ocl.internal.l10n.OCLMessages;
import org.eclipse.ocl.options.EvaluationOptions;
/**
* Tests for iterator expressions.
*
* @author Christian W. Damus (cdamus)
*/
@SuppressWarnings("nls")
public abstract class GenericIteratorsTest<E extends EObject, PK extends E, T extends E, C extends T, CLS extends C, DT extends C, PT extends C, ET extends DT, O extends E, PM extends E, P extends E, PA extends P, PR extends P, EL, S, COA, SSA, CT>
extends GenericTestSuite<E, PK, T, C, CLS, DT, PT, ET, O, PM, P, PA, PR, EL, S, COA, SSA, CT> {
PK pkg1;
PK pkg2;
PK pkg3;
PK pkg4;
PK pkg5;
PK jim;
PK bob;
PK george;
@Override
protected void setUp() {
super.setUp();
// need a metamodel that has a reflexive EReference.
// Ecore will do nicely. Create the following structure:
// pkg1
// pkg1::pkg2
// pkg1::pkg2::jim
// pkg1::bob
// pkg1::pkg3
// pkg1::pkg3::pkg4
// pkg1::pkg3::pkg5
// pkg1::pkg3::pkg5::george
pkg1 = reflection.createPackage("pkg1");
pkg2 = reflection.createNestedPackage(pkg1, "pkg2");
jim = reflection.createNestedPackage(pkg2, "jim");
bob = reflection.createNestedPackage(pkg1, "bob");
pkg3 = reflection.createNestedPackage(pkg1, "pkg3");
pkg4 = reflection.createNestedPackage(pkg3, "pkg4");
pkg5 = reflection.createNestedPackage(pkg3, "pkg5");
george = reflection.createNestedPackage(pkg5, "george");
helper.setContext(getMetaclass(denormalize("%Package")));
}
/**
* Tests the generic iterate() iterator.
*/
public void test_iterate_143996() {
Set<String> expected = createSet("pkg2", "bob", "pkg3");
// complete form
assertQueryEquals(pkg1, expected, "%nestedPackage->iterate(p; s : Set(String) = Set{} | s->including(p.name))");
// shorter form
assertQueryEquals(pkg1, expected, "%nestedPackage->iterate(p; s : Set(String) = Set{} | s->including(p.name))");
// shortest form
assertQueryEquals(pkg1, expected, "%nestedPackage->iterate(s : Set(String) = Set{} | s->including(name))");
}
/**
* Tests the select() iterator.
*/
public void test_select() {
boolean isOrdered = reflection.isOrdered("nestedPackage");
@SuppressWarnings("unchecked")
Collection<PK> expected = createCollection(isOrdered, true, pkg2, pkg3);
// complete form
assertQueryEquals(pkg1, expected, "%nestedPackage->select(p : %Package | p.name <> 'bob')");
// shorter form
assertQueryEquals(pkg1, expected, "%nestedPackage->select(p | p.name <> 'bob')");
// shortest form
assertQueryEquals(pkg1, expected, "%nestedPackage->select(name <> 'bob')");
expected.clear();
expected.addAll(reflection.getNestedPackages(pkg1));
assertQueryEquals(pkg1, expected, "%nestedPackage->select(true)");
}
/**
* Tests the reject() iterator.
*/
public void test_reject() {
boolean isOrdered = reflection.isOrdered("nestedPackage");
@SuppressWarnings("unchecked")
Collection<PK> expected = createCollection(isOrdered, true, pkg2, pkg3);
// complete form
assertQueryEquals(pkg1, expected, "%nestedPackage->reject(p : %Package | p.name = 'bob')");
// shorter form
assertQueryEquals(pkg1, expected, "%nestedPackage->reject(p | p.name = 'bob')");
// shortest form
assertQueryEquals(pkg1, expected, "%nestedPackage->reject(name = 'bob')");
expected.clear();
assertQueryEquals(pkg1, expected, "%nestedPackage->reject(true)");
}
/**
* Tests the any() iterator.
*/
public void test_any() {
// complete form
assertQuerySame(pkg1, bob, "%nestedPackage->any(p : %Package | p.name = 'bob')");
// shorter form
assertQuerySame(pkg1, bob, "%nestedPackage->any(p | p.name = 'bob')");
// shortest form
assertQuerySame(pkg1, bob, "%nestedPackage->any(name = 'bob')");
// negative
assertQueryNotSame(pkg1, bob, "%nestedPackage->any(name = 'pkg2')");
assertQueryNotNull(pkg1, "%nestedPackage->any(true)");
assertQueryNull(pkg1, "%nestedPackage->any(false)");
assertQueryNull(null, "Sequence{}->any(s | s = false)");
assertQueryFalse(null, "Sequence{false}->any(s | s = false)");
assertQueryFalse(null, "Sequence{false, false}->any(s | s = false)");
assertQueryNull(null, "Sequence{}->any(s | s = null)");
assertQueryNull(null, "Sequence{null}->any(s | s = null)");
assertQueryNull(null, "Sequence{null, null}->any(s | s = null)");
EvaluationOptions.setOption(ocl.getEvaluationEnvironment(), EvaluationOptions.ANY_LESS_IS_INVALID, true);
assertQueryInvalid(null, "Sequence{}->any(s | s = false)"); // OMG Issue 18504
assertQueryInvalid(null, "Sequence{}->any(s | s = null)"); // OMG Issue 18504
assertQueryInvalid(pkg1, "%nestedPackage->any(false)"); // OMG Issue 18504
EvaluationOptions.setOption(ocl.getEvaluationEnvironment(), EvaluationOptions.ANY_LESS_IS_INVALID, false);
assertQueryNull(pkg1, "%nestedPackage->any(false)");
}
/**
* Tests the isUnique() iterator.
*/
public void test_isUnique_126861() {
assertQueryTrue(pkg1, "Sequence{'a', 'b', 'c', 'd', 'e'}->isUnique(e | e)");
assertQueryFalse(pkg1, "Sequence{'a', 'b', 'c', 'c', 'e'}->isUnique(e | e)");
// when there are no values, they implicitly all evaluate to a
// different result
assertQueryTrue(pkg1, "Sequence{}->isUnique(e | e)");
assertQueryNotNull(pkg1, "%nestedPackage->isUnique(name)");
}
/**
* Tests the exists() iterator.
*/
public void test_exists() {
assertQueryTrue(pkg1, "Sequence{'a', 'b', 'c', 'd', 'e'}->exists(e | e = 'c')");
assertQueryTrue(pkg1, "Sequence{'a', 'b', 'c', 'c', 'e'}->exists(e | e = 'c')");
assertQueryFalse(pkg1, "Sequence{'a', 'b', 'd', 'e'}->exists(e | e = 'c')");
// when there are no values, they the desired result implictly
// does not occur
assertQueryFalse(pkg1, "Sequence{}->exists(e | e = 'c')");
assertQueryTrue(pkg1, "%nestedPackage->exists(true)");
}
/**
* Tests the forAll() iterator.
*/
public void test_forAll() {
assertQueryFalse(pkg1, "Sequence{'a', 'b', 'c', 'd', 'e'}->forAll(e | e = 'c')");
assertQueryFalse(pkg1, "Sequence{'a', 'b', 'd', 'e'}->forAll(e | e = 'c')");
assertQueryTrue(pkg1, "Sequence{'c', 'c', 'c', 'c'}->forAll(e | e = 'c')");
assertQueryTrue(pkg1, "Sequence{'c'}->forAll(e | e = 'c')");
// when there are no values, they implicitly all evaluate to the
// desired result
assertQueryTrue(pkg1, "Sequence{}->forAll(e | e = 'c')");
assertQueryTrue(pkg1, "%nestedPackage->forAll(true)");
}
/**
* Tests the one() iterator.
*/
public void test_one() {
assertQueryTrue(pkg1, "Sequence{'a', 'b', 'c', 'd', 'e'}->one(e | e = 'c')");
assertQueryFalse(pkg1, "Sequence{'a', 'b', 'c', 'c', 'e'}->one(e | e = 'c')");
assertQueryFalse(pkg1, "Sequence{'a', 'b', 'd', 'e'}->one(e | e = 'c')");
assertQueryTrue(pkg1, "Sequence{'a'}->one(true)");
}
/**
* Tests the collect() iterator.
*/
public void test_collect() {
boolean isOrdered = reflection.isOrdered("nestedPackage");
Collection<String> expected1 = createCollection(isOrdered, false, "pkg2", "bob", "pkg3");
// complete form
assertQueryEquals(pkg1, expected1, "%nestedPackage->collect(p : %Package | p.name)");
// shorter form
assertQueryEquals(pkg1, expected1, "%nestedPackage->collect(p | p.name)");
// yet shorter form
assertQueryEquals(pkg1, expected1, "%nestedPackage->collect(name)");
// shortest form
assertQueryEquals(pkg1, expected1, "%nestedPackage.name");
// flattening of nested collections
@SuppressWarnings("unchecked")
Collection<PK> expected2 = createCollection(isOrdered, false, jim, pkg4, pkg5);
assertQueryEquals(pkg1, expected2, "%nestedPackage.%nestedPackage");
}
/**
* Tests that parsing fails, in the case of an unknown property in a
* collection navigation, with an appropriate parse failure, not a
* <code>ClassCastException</code>.
*/
public void test_implicitCollect_unknownAttribute_232669() {
assertBadInvariant(SemanticException.class, Diagnostic.ERROR,
"%nestedPackage.unknownAttribute",
OCLMessages.UnrecognizedVar_ERROR_, "unknownAttribute");
}
/**
* Tests that parsing fails, in the case of an unknown operation in a
* collection navigation, with an appropriate parse failure, not a
* <code>ClassCastException</code>.
*/
public void test_implicitCollect_unknownOperation_232669() {
assertBadInvariant(SemanticException.class, Diagnostic.ERROR,
"%nestedPackage.unknownOperation(self)",
OCLMessages.OperationNotFound_ERROR_, denormalize("unknownOperation(%Package)"), denormalize("%Package"));
}
/**
* Tests that the collect() iterator correctly flattens its result.
*/
public void test_collect_flattens_217461() {
String self = "foo";
List<String> expected = createSequence("THIS AND", "THAT", "THE OTHER");
assertQueryEquals(self, expected, "Sequence{Sequence{'this and', 'that'}, Sequence{'the other'}}->collect(s : Sequence(String) | s.toUpper())");
}
/**
* Tests that the collect() iterator correctly deals with empty collections.
*/
public void test_collect_empty_217461() {
String self = "foo";
List<String> expected = Collections.emptyList();
assertQueryEquals(self, expected, "let c : Sequence(OrderedSet(String)) = Sequence{} in c->collect(s : OrderedSet(String) | s.toUpper())");
}
/**
* Tests the collectNested() iterator.
*/
public void test_collectNested() {
boolean isOrdered = reflection.isOrdered("nestedPackage");
Collection<String> expected1 = createCollection(isOrdered, false, "pkg2", "bob", "pkg3");
// complete form
assertQueryEquals(pkg1, expected1, "%nestedPackage->collectNested(p : %Package | p.name)");
// shorter form
assertQueryEquals(pkg1, expected1, "%nestedPackage->collectNested(p | p.name)");
// shortest form
assertQueryEquals(pkg1, expected1, "%nestedPackage->collectNested(name)");
// nested collections not flattened
Set<PK> e1 = Collections.singleton(jim);
Set e2 = Collections.EMPTY_SET;
HashSet<Object> e3 = new HashSet<Object>(Arrays.asList(new Object[] {pkg4, pkg5}));
Collection<? extends Object> expected2 = createCollection(isOrdered, false, e1, e2, e3);
assertQueryEquals(pkg1, expected2, "%nestedPackage->collectNested(%nestedPackage)");
}
/**
* Tests the collect() iterator return type.
*/
public void test_collect_returns_490982() {
Collection<Boolean> expected1 = createBag(false, true, true);
Collection<Boolean> expected2 = createSequence(true, false, true);
assertQueryEquals(null, expected1, "Bag{1,2,3}->collect(p | (p.mod(2)) <> 0)");
assertQueryEquals(null, expected2, "OrderedSet{1,2,3}->collect(p | (p.mod(2)) <> 0)");
assertQueryEquals(null, expected2, "Sequence{1,2,3}->collect(p | (p.mod(2)) <> 0)");
assertQueryEquals(null, expected1, "Set{1,2,3}->collect(p | (p.mod(2)) <> 0)");
}
/**
* Tests the collectNested() iterator return type.
*/
public void test_collectNested_returns_490982() {
Collection<Boolean> expected1 = createBag(false, true, true);
Collection<Boolean> expected2 = createSequence(true, false, true);
assertQueryEquals(null, false, "OrderedSet{1,2,3}->collectNested(p | (p.mod(2)) <> 0)->at(2)");
assertQueryEquals(null, expected1, "Bag{1,2,3}->collectNested(p | (p.mod(2)) <> 0)");
assertQueryEquals(null, expected2, "OrderedSet{1,2,3}->collectNested(p | (p.mod(2)) <> 0)");
assertQueryEquals(null, expected2, "Sequence{1,2,3}->collectNested(p | (p.mod(2)) <> 0)");
assertQueryEquals(null, expected1, "Set{1,2,3}->collectNested(p | (p.mod(2)) <> 0)");
// assertQueryEquals(null, expected1, "Bag{1,2,3}->collectNested(p | (p.mod(2)) <> 0)->at(2)");
assertQueryEquals(null, false, "OrderedSet{1,2,3}->collectNested(p | (p.mod(2)) <> 0)->at(2)");
assertQueryEquals(null, false, "Sequence{1,2,3}->collectNested(p | (p.mod(2)) <> 0)->at(2)");
// assertQueryEquals(null, expected1, "Set{1,2,3}->collectNested(p | (p.mod(2)) <> 0)");
}
/**
* Tests the sortedBy() iterator.
*/
public void test_sortedBy() {
@SuppressWarnings("unchecked")
Set<PK> expectedSet = createSet(bob, pkg2, pkg3);
// complete form
assertQueryEquals(pkg1, expectedSet, "%nestedPackage->sortedBy(p : %Package | p.name)");
// shorter form
assertQueryEquals(pkg1, expectedSet, "%nestedPackage->sortedBy(p | p.name)");
// shortest form
assertQueryEquals(pkg1, expectedSet, "%nestedPackage->sortedBy(name)");
List<String> expected = createSequence("a", "b", "c", "d", "e");
assertQueryEquals(pkg1, expected, "Bag{'d', 'b', 'e', 'a', 'c'}->sortedBy(e | e)");
}
/**
* Tests the closure() iterator.
*/
public void test_closure() {
boolean nestedIsOrdered = reflection.isOrdered("nestedPackage"); // Ecore and UML differ here
boolean nestingIsOrdered = reflection.isOrdered("nestingPackage");
//
// Implicitly exclude sources
//
@SuppressWarnings("unchecked")
Collection<PK> expected11 = createCollection(nestingIsOrdered, true, pkg1, pkg3, pkg5); // closure does not include self (george)
assertQueryEquals(george, expected11, "self->closure(%nestingPackage)");
@SuppressWarnings("unchecked")
Collection<PK> expected12 = createCollection(nestedIsOrdered, true, pkg2, jim, bob, pkg3, pkg4, pkg5, george);
assertQueryEquals(pkg1, expected12, "self->closure(%nestedPackage)");
assertQueryEquals(pkg1, expected12, "self->asSequence()->closure(%nestedPackage)");
assertQueryEquals(pkg1, expected12, "self->closure(%nestedPackage->asSequence())");
@SuppressWarnings("unchecked")
Collection<PK> expected13 = createSet(pkg2, jim, bob, pkg3, pkg4, pkg5, george);
assertQueryEquals(pkg1, expected13, "self->asBag()->closure(%nestedPackage)");
assertQueryEquals(pkg1, expected13, "self->closure(%nestedPackage->asBag())");
// empty closure
@SuppressWarnings("unchecked")
Collection<PK> expected14 = createCollection(nestingIsOrdered, true);
assertQueryEquals(pkg1, expected14, "self->closure(%nestingPackage)");
// empty closure
assertQueryEquals(pkg1, expected14, "self->asSequence()->closure(%nestingPackage)");
//
// Explicitly include sources
//
EvaluationOptions.setOption(ocl.getEvaluationEnvironment(), EvaluationOptions.CLOSURE_INCLUDES_SOURCES, true);
@SuppressWarnings("unchecked")
Collection<PK> expected21 = createCollection(nestingIsOrdered, true, pkg1, pkg3, pkg5, george); // closure does not include self (george)
assertQueryEquals(george, expected21, "self->closure(%nestingPackage)");
@SuppressWarnings("unchecked")
Collection<PK> expected22 = createCollection(nestedIsOrdered, true, pkg1, pkg2, jim, bob, pkg3, pkg4, pkg5, george);
assertQueryEquals(pkg1, expected22, "self->closure(%nestedPackage)");
assertQueryEquals(pkg1, expected22, "self->asSequence()->closure(%nestedPackage)");
assertQueryEquals(pkg1, expected22, "self->closure(%nestedPackage->asSequence())");
@SuppressWarnings("unchecked")
Collection<PK> expected23 = createSet(pkg1, pkg2, jim, bob, pkg3, pkg4, pkg5, george);
assertQueryEquals(pkg1, expected23, "self->asBag()->closure(%nestedPackage)");
assertQueryEquals(pkg1, expected23, "self->closure(%nestedPackage->asBag())");
// empty closure
@SuppressWarnings("unchecked")
Collection<PK> expected24 = createCollection(nestingIsOrdered, true, pkg1);
assertQueryEquals(pkg1, expected24, "self->closure(%nestingPackage)");
// empty closure
assertQueryEquals(pkg1, expected24, "self->asSequence()->closure(%nestingPackage)");
//
// Explicitly exclude sources
//
EvaluationOptions.setOption(ocl.getEvaluationEnvironment(), EvaluationOptions.CLOSURE_INCLUDES_SOURCES, false);
assertQueryEquals(george, expected11, "self->closure(%nestingPackage)");
assertQueryEquals(pkg1, expected12, "self->closure(%nestedPackage)");
assertQueryEquals(pkg1, expected12, "self->asSequence()->closure(%nestedPackage)");
assertQueryEquals(pkg1, expected12, "self->closure(%nestedPackage->asSequence())");
assertQueryEquals(pkg1, expected13, "self->asBag()->closure(%nestedPackage)");
assertQueryEquals(pkg1, expected13, "self->closure(%nestedPackage->asBag())");
// empty closure
assertQueryEquals(pkg1, expected14, "self->closure(%nestingPackage)");
// empty closure
assertQueryEquals(pkg1, expected14, "self->asSequence()->closure(%nestingPackage)");
}
/**
* Tests that the closure() iterator handles cycles.
*/
public void test_closure_cycles() {
C packageMetaclass = getMetaclass(denormalize("%Package"));
P nestedPackage = reflection.getAttribute(packageMetaclass, denormalize("%nestedPackage"), packageMetaclass);
P nestingPackage = reflection.getAttribute(packageMetaclass, denormalize("%nestingPackage"), packageMetaclass);
helper.setContext(getMetaclass(denormalize("%Reference")));
@SuppressWarnings("unchecked")
Set<P> expected = createSet(nestedPackage, nestingPackage); // cyclic closure *does* include self
assertQueryEquals(nestingPackage, expected, "self->closure(%opposite)");
assertQueryEquals(nestedPackage, expected, "self->closure(%opposite)");
}
/**
* Tests parsing the closure of operation calls.
*/
public void test_closure_operations() {
PK fakePkg = reflection.createPackage("fake");
CLS fake = reflection.createOwnedClass(fakePkg, "Fake", false);
O getFakes = reflection.createOwnedOperation(fake, "getFakes", null, null, fake, true);
reflection.setOperationUpper(getFakes, reflection.getUnlimitedValue());
assertQuery(fake, "self->closure(getFakes())");
}
/**
* Tests the validation of the closure() iterator.
*/
public void test_closureValidation() {
// non-recursive reference
assertBadQuery(SemanticException.class, Diagnostic.ERROR,
"self->closure(%ownedType)",
OCLMessages.ElementTypeConformanceClosure_ERROR_, denormalize("%Type"), denormalize("%Package"));
}
/**
* Tests the validation of the closure() iterator for conformance of the
* body type with the iterator variable (source element) type.
*/
public void test_closureValidation_typeConformance_154695() {
PK fakePkg = reflection.createPackage("fake");
CLS fake = reflection.createOwnedClass(fakePkg, "Fake", false);
O getFakes = reflection.createOwnedOperation(fake, "getFakes", null, null, fake, true);
reflection.setOperationUpper(getFakes, reflection.getUnlimitedValue());
// subclass the Fake class
CLS subFake = reflection.createOwnedClass(fakePkg, "Subfake", false);
reflection.createGeneralization(subFake, fake);
// get sub-fakes from a fake
O getSubFakes = reflection.createOwnedOperation(fake, "getSubFakes", null, null, subFake, true);
reflection.setOperationUpper(getSubFakes, reflection.getUnlimitedValue());
helper.setContext(subFake);
// this should not parse because the result of the closure
// expression
// is more general than the iterator variable, so cannot be
// assigned recursively
assertBadQuery(SemanticException.class, Diagnostic.ERROR,
"self->closure(getFakes())",
OCLMessages.ElementTypeConformanceClosure_ERROR_, "Fake", "Subfake");
// this should parse OK because the result of the closure expression
// is more specific than the iterator variable, so it can be
// assigned recursively
assertQuery(fake, "self->closure(getSubFakes())");
}
/**
* Tests that when the body of an iterator results in invalid, the entire
* iterator expression's value is invalid.
*/
public void test_forAll_invalidBody_142518() {
assertQueryInvalid(EcorePackage.eINSTANCE,
"let b:Boolean = null in Bag{1, 2, 3}->forAll(b and b)");
// check that the "check" API interprets invalid as a constraint
// violation
assertInvariantFalse(EcorePackage.eINSTANCE,
"let b:Boolean = null in Bag{1}->forAll(b and b)");
// same deal for a null value (in the forAll case)
assertQueryInvalid(EcorePackage.eINSTANCE,
"Bag{1, 2, 3}->forAll(null.oclAsType(Boolean))");
}
/**
* Tests that when the body of an iterator results in invalid, the entire
* iterator expression's value is invalid.
*/
public void test_exists_invalidBody_142518() {
assertQueryInvalid(EcorePackage.eINSTANCE,
"let b:Boolean = null in Bag{1, 2, 3}->exists(b and b)");
// same deal for a null value (in the exists case)
assertQueryInvalid(EcorePackage.eINSTANCE,
"Bag{1, 2, 3}->exists(null.oclAsType(Boolean))");
}
/**
* Tests that when the body of an iterator results in invalid, the entire
* iterator expression's value is invalid.
*/
public void test_one_invalidBody_142518() {
assertQueryInvalid(EcorePackage.eINSTANCE,
"let b:Boolean = null in Bag{1, 2, 3}->one(b and b)");
// same deal for a null value (in the one case)
assertQueryInvalid(EcorePackage.eINSTANCE,
"Bag{1, 2, 3}->one(null.oclAsType(Boolean))");
}
/**
* Tests that when the body of an iterator results in invalid, the entire
* iterator expression's value is invalid.
*/
public void test_any_invalidBody_142518() {
assertQueryInvalid(EcorePackage.eINSTANCE,
"let b:Boolean = null in Bag{1, 2, 3}->any(b and b)");
// same deal for a null value (in the any case)
assertQueryInvalid(EcorePackage.eINSTANCE,
"Bag{1, 2, 3}->any(null.oclAsType(Boolean))");
}
/**
* Tests that when the body of an iterator results in invalid, the entire
* iterator expression's value is invalid.
*/
public void test_select_invalidBody_142518() {
assertQueryInvalid(EcorePackage.eINSTANCE,
"let b:Boolean = null in Bag{1, 2, 3}->select(b and b)");
// same deal for a null value (in the exists case)
assertQueryInvalid(EcorePackage.eINSTANCE,
"Bag{1, 2, 3}->select(null.oclAsType(Boolean))");
}
/**
* Tests that when the body of an iterator results in invalid, the entire
* iterator expression's value is invalid.
*/
public void test_reject_invalidBody_142518() {
assertQueryInvalid(EcorePackage.eINSTANCE,
"let b:Boolean = null in Bag{1, 2, 3}->reject(b and b)");
// same deal for a null value (in the exists case)
assertQueryInvalid(EcorePackage.eINSTANCE,
"Bag{1, 2, 3}->reject(null.oclAsType(Boolean))");
}
/**
* Tests that when the body of an iterator results in invalid, the
* isUnique iterator expression treats it like any other value.
*/
public void test_isUnique_invalidBody_142518() {
assertQueryFalse(EcorePackage.eINSTANCE,
"let b:Boolean = null in Bag{1, 2, 3}->isUnique(b and b)");
assertQueryFalse(EcorePackage.eINSTANCE,
"let b:Boolean = null in Bag{1, 2, 3}->isUnique(null)");
}
/**
* Tests that when the body of an iterator results in invalid, the entire
* iterator expression's value is invalid.
*/
public void test_collect_invalidBody_142518() {
assertQueryInvalid(EcorePackage.eINSTANCE,
"let b:Boolean = null in Bag{1, 2, 3}->collect(b and b)");
// in the case of a null value, null is allowed in a collection, so
// it does not result in invalid
Collection<Object> expected = createBag(null, null, null);
assertQueryEquals(EcorePackage.eINSTANCE, expected,
"let b:Boolean = null in Bag{1, 2, 3}->collect(null)");
}
/**
* Tests that when the body of an iterator results in invalid, the entire
* iterator expression's value is invalid.
*/
public void test_collectNested_invalidBody_142518() {
assertQueryInvalid(EcorePackage.eINSTANCE,
"let b:Boolean = null in Bag{1, 2, 3}->collectNested(b and b)");
// in the case of a null value, null is allowed in a collection, so
// it does not result in invalid
Set<Integer> e1 = Collections.singleton(Integer.valueOf(1));
Set<Integer> e2 = null;
Set<Integer> e3 = Collections.singleton(Integer.valueOf(3));
@SuppressWarnings("unchecked")
Collection<? extends Object> expected = createBag(e1, e2, e3);
assertQueryEquals(EcorePackage.eINSTANCE, expected,
"let b:Boolean = null in Bag{1, 2, 3}->collectNested(e | if e = 2 then null else Set{e} endif)");
}
/**
* Tests that when the body of an iterator results in invalid, the entire
* iterator expression's value is invalid.
*/
public void test_closure_invalidBody_142518() {
assertQueryInvalid(getUMLMetamodel(),
"let c : %Type = invalid in %ownedType->closure(c)");
// in the case of a null value, null is allowed in a collection, so
// it does not result in invalid
Object result = assertQueryEvaluate(getUMLMetamodel(),
"let c : Set(%Type) = Set{null} in %ownedType->closure(c)");
assertTrue(result instanceof Collection<?>);
Collection<?> collResult = (Collection<?>) result;
assertEquals(1, collResult.size());
assertNull(collResult.iterator().next());
EvaluationOptions.setOption(ocl.getEvaluationEnvironment(), EvaluationOptions.CLOSURE_INCLUDES_SOURCES, true);
Collection<Integer> expected3 = createSet(null, 5);
assertQueryEquals(pkg1, expected3, "let c : Set(UnlimitedNatural) = Set{null} in 5->closure(c)");
}
/**
* Tests that when the body of an iterator results in invalid, the entire
* iterator expression's value is invalid.
*/
public void test_sortedBy_invalidBody_142518() {
assertQueryInvalid(EcorePackage.eINSTANCE,
"let s : String = null in Bag{1, 2, 3}->sortedBy(s.size())");
// same deal for null values
assertQueryInvalid(EcorePackage.eINSTANCE,
"Bag{1, 2, 3}->sortedBy(null.oclAsType(Integer))");
}
/**
* Tests that the generic iterate() iterator returns invalid when the
* source collection is null or invalid.
*/
public void test_iterateWithNullSource_143996() {
assertQueryInvalid(pkg1,
"let e : Collection(%Package) = null in e->iterate(" +
"p : %Package; s : String = '' | s.concat(p.name))");
assertQueryInvalid(pkg1,
"let e : Collection(%Package) = invalid in e->iterate(" +
"p : %Package; s : String = '' | s.concat(p.name))");
}
/**
* Tests that the exists() iterator return invalid when the source
* collection is null or invalid.
*/
public void test_existsWithNullSource_143996() {
assertQueryInvalid(pkg1,
"let e : Collection(%Package) = null in e->exists(" +
"p : %Package | p.name = 'bob')");
assertQueryInvalid(pkg1,
"let e : Collection(%Package) = invalid in e->exists(" +
"p : %Package | p.name = 'bob')");
}
/**
* Tests the exists iterator with multiple iterator variables.
*/
public void test_exists_multipleIteratorVariables() {
assertInvariantTrue(pkg1, "Sequence{1, 2, 3, 4}->exists(e1, e2 | e1 = e2)");
assertInvariantFalse(pkg1, "Sequence{1, 2, 3, 4}->exists(e1, e2 | (e1 + e2) = 0)");
// when there are no values, the the desired result implictly
// does not occur
assertInvariantFalse(pkg1, "Sequence{}->exists(e1, e2 | e1 = e2)");
}
/**
* Tests the forAll iterator with multiple iterator variables.
*/
public void test_forAll_multipleIteratorVariables() {
assertInvariantFalse(pkg1, "Sequence{1, 2, 3, 4}->forAll(e1, e2 | e1 = e2)");
assertInvariantTrue(pkg1, "Sequence{1, 2, 3, 4}->forAll(e1, e2 | (e1 + e2) > e1)");
// when there are no values, the the desired result implictly occurs
assertInvariantTrue(pkg1, "Sequence{}->forAll(e1, e2 | e1 = e2)");
}
/**
* Tests the validation the number of iterator variables for iterators that
* do not support multiple variables.
*/
public void test_invalidMultipleIteratorVariables() {
assertBadQuery(SyntaxException.class, Diagnostic.ERROR, // FIXME Bug 296990
"Sequence{'a', 'b', 'c'}->exists(e1, e2, e3 | e1 = e2)",
OCLMessages.OCLParseErrorCodes_SUBSTITUTION_SECONDARY, "2:44:2:44", "\",\"", "\"|\"");
assertBadQuery(SyntaxException.class, Diagnostic.ERROR, // FIXME Bug 296990
"Sequence{'a', 'b', 'c'}->forAll(e1, e2, e3 | e1 = e2)",
OCLMessages.OCLParseErrorCodes_SUBSTITUTION_SECONDARY, "1:44:1:44", "\",\"", "\"|\"");
assertBadQuery(SemanticException.class, Diagnostic.ERROR,
"Sequence{'a', 'b', 'c'}->collect(e1, e2 | Tuple{a : String = e1, b : String = e2})",
OCLMessages.TooManyIteratorVariables_ERROR_, "collect");
assertBadQuery(SemanticException.class, Diagnostic.ERROR,
"Sequence{'a', 'b', 'c'}->any(e1, e2 | e1 = e2)",
OCLMessages.TooManyIteratorVariables_ERROR_, "any");
assertBadQuery(SemanticException.class, Diagnostic.ERROR,
"Sequence{'a', 'b', 'c'}->one(e1, e2 | e1 = e2)",
OCLMessages.TooManyIteratorVariables_ERROR_, "one");
assertBadQuery(SemanticException.class, Diagnostic.ERROR,
"Sequence{'a', 'b', 'c'}->select(e1, e2 | e1 = e2)",
OCLMessages.TooManyIteratorVariables_ERROR_, "select");
assertBadQuery(SemanticException.class, Diagnostic.ERROR,
"Sequence{'a', 'b', 'c'}->reject(e1, e2 | e1 = e2)",
OCLMessages.TooManyIteratorVariables_ERROR_, "reject");
assertBadQuery(SemanticException.class, Diagnostic.ERROR,
"Sequence{'a', 'b', 'c'}->isUnique(e1, e2 | e1 = e2)",
OCLMessages.TooManyIteratorVariables_ERROR_, "isUnique");
}
/**
* Test to check the validation of the <tt>sortedBy</tt> iterator, that
* the body expression type has a <tt>&lt;</tt> operation.
*/
public void test_sortedByRequiresComparability_192729() {
C context = getMetaclass(denormalize("%Package"));
assertBadQuery(SemanticException.class, Diagnostic.ERROR,
"%ownedType->sortedBy(e | e)",
OCLMessages.OperationNotFound_ERROR_, "<", denormalize("%Type"));
assertQuery(context, "%ownedType->sortedBy(e | e.name)");
}
}