blob: bb50115f3fee6749d825f5c83e5e4fb4ca8e50e6 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 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 - Bugs 296409, 295166
*******************************************************************************/
package org.eclipse.ocl.tests;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.ocl.OCLInput;
import org.eclipse.ocl.ParserException;
import org.eclipse.ocl.expressions.OCLExpression;
import org.eclipse.ocl.options.ParsingOptions;
/**
* Tests for usages of model features whose names coincide with "keywords"
* defined as reserved words by the OCL specification.
*
* @author Christian W. Damus (cdamus)
*/
@SuppressWarnings("nls")
public abstract class GenericTuplesTest<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 GenericInitializedFruitTestSuite<E, PK, T, C, CLS, DT, PT, ET, O, PM, P, PA, PR, EL, S, COA, SSA, CT> {
/**
* Tests the parsing of tuple literals with part types.
*/
public void test_tupleLiteral_withTypes() {
// one part
parse("package ocltest context Fruit " +
"inv: Tuple{a : Integer = 1} " +
"endpackage");
// multiple parts
parse("package ocltest context Fruit " +
"inv: Tuple{a : Integer = 1, b : String = 'foo', c : Color = Color::red} " +
"endpackage");
}
/**
* Tests the parsing of tuple literals without part types.
*/
public void test_tupleLiteral_noTypes() {
// one part
parse("package ocltest context Fruit " +
"inv: Tuple{a = 1} " +
"endpackage");
// multiple parts
parse("package ocltest context Fruit " +
"inv: Tuple{a = 1, b = 'foo', c = Color::red} " +
"endpackage");
}
/**
* Tests the parsing of tuple literals with a mixture of explicit and
* implicit part types.
*/
public void test_tupleLiteral_mixedTypes() {
parse("package ocltest context Fruit " +
"inv: Tuple{a : Integer = 1, b = 'foo', c : Color = Color::red} " +
"endpackage");
parse("package ocltest context Fruit " +
"inv: Tuple{a = 1, b : String = 'foo', c = Color::red} " +
"endpackage");
}
/**
* Tests that OclVoid and other tuple components with null values work as
* expected
*/
public void test_tupleLiteral_nullValues() {
// one part
assertEquals(null, evaluate(parse(
"package ocltest context Fruit " +
"inv: Tuple{a = null}.a " +
"endpackage")));
assertEquals(null, evaluate(parse(
"package ocltest context Fruit " +
"inv: Tuple{a:OclVoid = null}.a " +
"endpackage")));
assertEquals(null, evaluate(parse(
"package ocltest context Fruit " +
"inv: Tuple{a:String = null}.a " +
"endpackage")));
assertEquals(null, evaluate(parse(
"package ocltest context Fruit " +
"inv: Tuple{a:Fruit = null}.a " +
"endpackage")));
// multiple parts
assertEquals(1, evaluate(parse(
"package ocltest context Fruit " +
"inv: Tuple{a = null, b=1}.b " +
"endpackage")));
assertEquals(null, evaluate(parse(
"package ocltest context Fruit " +
"inv: Tuple{a = null, b=1}.a " +
"endpackage")));
assertEquals(null, evaluate(parse(
"package ocltest context Fruit " +
"inv: Tuple{a:String = null, b='abc'}.a " +
"endpackage")));
assertEquals("abc", evaluate(parse(
"package ocltest context Fruit " +
"inv: Tuple{a:String = null, b='abc'}.b " +
"endpackage")));
assertEquals(null, evaluate(parse(
"package ocltest context Fruit " +
"inv: Tuple{a:Fruit = null, b:String='abc'}.a " +
"endpackage")));
assertEquals(null, evaluate(parse(
"package ocltest context Fruit " +
"inv: Tuple{a:Fruit = null, b:OclVoid=null}.b " +
"endpackage")));
}
/**
* Tests the parsing of initialization of variables of tuple type.
*/
public void test_tupleAssignment() {
parse("package ocltest context Fruit " +
"inv: let t : Tuple(a : Integer, b : String, c : Color) " +
" = Tuple{a = 1, b = 'foo', c = Color::red} " +
" in t " +
"endpackage");
}
/**
* Tests the parsing of collections of tuple types.
*/
public void test_tupleCollections() {
parse("package ocltest context Fruit " +
"inv: let ts : Set(Tuple(a : Integer, b : String, c : Color)) " +
" = Set{}->including(Tuple{a = 1, b = 'foo', c = Color::red}) " +
" in ts " +
"endpackage");
}
/**
* Tests the equivalence of tuples, including irrelevance of ordering of
* the parts
*/
public void test_tupleEquivalence() {
// different value in one part
assertEquals(Boolean.FALSE, evaluate(parse(
"package ocltest context Fruit " +
"inv: Tuple{a = 1, b = 'foo', c = Color::red} " +
" = Tuple{b = 'foo', c = Color::black, a = 1} " +
"endpackage")));
// test the inequality operator
assertEquals(Boolean.TRUE, evaluate(parse(
"package ocltest context Fruit " +
"inv: Tuple{a = 1, b = 'foo', c = Color::red} " +
" <> Tuple{b = 'foo', c = Color::black, a = 1} " +
"endpackage")));
// all parts have same value
assertEquals(Boolean.TRUE, evaluate(parse(
"package ocltest context Fruit " +
"inv: Tuple{a = 1, b = 'foo', c = Color::red} " +
" = Tuple{b = 'foo', c = Color::red, a = 1} " +
"endpackage")));
// equality of collections of tuples
assertEquals(Boolean.TRUE, evaluate(parse(
"package ocltest context Fruit " +
"inv: Set{Tuple{a = 1, b = 'foo'}, Tuple{a = 5, b = 'bar'}} " +
" = Set{Tuple{b = 'bar', a = 5}, Tuple{b = 'foo', a = 1}} " +
"endpackage")));
}
/**
* Tests that the parser distinguishes <code>TupleType</code>s by the names
* and types of their parts, not by the names alone.
*/
public void test_tupleTypeDistinction_192832() {
OCLInput doc = new OCLInput(
"package ocltest context Fruit " +
"def: foo : Tuple(a : String) = Tuple{a = 'foo'} " +
"def: bar : Tuple(a : Integer) = Tuple{a = 100} " +
"endpackage");
try {
ocl.parse(doc);
helper.setContext(fruit);
OCLExpression<C> expr1 = helper.createQuery("self.foo");
OCLExpression<C> expr2 = helper.createQuery("self.bar");
assertNotSame(expr1.getType(), expr2.getType());
C type = expr1.getType();
P a = reflection.getAttribute(type, "a", null);
assertNotNull(a);
assertEquals(getOCLStandardLibrary().getString(), reflection.getOCLType(a));
type = expr2.getType();
a = reflection.getAttribute(type, "a", null);
assertNotNull(a);
assertEquals(getOCLStandardLibrary().getInteger(), reflection.getOCLType(a));
} catch (Exception e) {
fail("Failed to parse: " + e.getLocalizedMessage());
}
}
/**
* Tests access to tuple parts by name when all parts have the same type.
*/
public void test_tuplePartAccess_238049() {
OCLExpression<C> expr = parse(
"package ocltest context Fruit " +
"inv: Tuple{first : String = 'Roger', last : String = 'Bacon'}.first " +
"endpackage");
assertEquals("Roger", evaluate(expr));
}
public void test_tupleWithLongLiteral_349117() {
ParsingOptions.setOption(helper.getOCL().getEnvironment(), ParsingOptions.USE_LONG_INTEGERS, true);
OCLExpression<C> expr = parse("package ocltest context Fruit "
+ "inv: Tuple{first : Integer = 5000000000}.first " + "endpackage");
assertEquals(5000000000l, evaluate(expr));
ParsingOptions.setOption(helper.getOCL().getEnvironment(), ParsingOptions.USE_LONG_INTEGERS, false);
}
public void test_tupleWithLongIntegerProperty_349117() throws ParserException {
ParsingOptions.setOption(helper.getOCL().getEnvironment(), ParsingOptions.USE_LONG_INTEGERS, true);
// tuples work fine with int / java.lang.Integer
helper.setContext(reflection.getUMLInteger());
OCLExpression<C> expr2 = helper.createQuery("Tuple{first : Integer = self}.first");
assertEquals(5000000, evaluate(expr2, Integer.valueOf(5000000)));
// we can compute with Long values
helper.setContext(reflection.getUMLLong());
OCLExpression<C> expr3 = helper.createQuery("2*self");
assertEquals(10000000000l, evaluate(expr3, Long.valueOf(5000000000l)));
// we should be able to create the tuple based on a value exceeding int, represented as long
helper.setContext(reflection.getMetametaclass(denormalize("%Package")));
OCLExpression<C> expr4 = helper.createQuery("Tuple{first : Integer = 1000*5000000}.first");
assertEquals(5000000000l, evaluate(expr4, reflection.getMetametaclass("Package")));
// we should be able to create the tuple based on a java.lang.Long as an OCL Integer
helper.setContext(reflection.getUMLInteger());
OCLExpression<C> expr5 = helper.createQuery("Tuple{first : Integer = self}.first");
assertEquals(5000000000l, evaluate(expr5, Long.valueOf(5000000000l)));
ParsingOptions.setOption(helper.getOCL().getEnvironment(), ParsingOptions.USE_LONG_INTEGERS, false);
}
}