Package: AcceleoNonStandardLibraryTest

AcceleoNonStandardLibraryTest

nameinstructionbranchcomplexitylinemethod
AcceleoNonStandardLibraryTest()
M: 135 C: 0
0%
M: 6 C: 0
0%
M: 4 C: 0
0%
M: 23 C: 0
0%
M: 1 C: 0
0%
getModuleLocation()
M: 2 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
getOperation(String, String)
M: 26 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 5 C: 0
0%
M: 1 C: 0
0%
getReferencePath()
M: 2 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
setUp()
M: 35 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 8 C: 0
0%
M: 1 C: 0
0%
tearDown()
M: 4 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
testOclAnyAncestorsParameterizable()
M: 81 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 22 C: 0
0%
M: 1 C: 0
0%
testOclAnyAncestorsUnParameterizable()
M: 81 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 23 C: 0
0%
M: 1 C: 0
0%
testOclAnyEAllContentsParameterizable()
M: 105 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 28 C: 0
0%
M: 1 C: 0
0%
testOclAnyEAllContentsUnparameterizable()
M: 94 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 27 C: 0
0%
M: 1 C: 0
0%
testOclAnyEInverseParameterizable()
M: 92 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 23 C: 0
0%
M: 1 C: 0
0%
testOclAnyEInverseUnparameterizable()
M: 92 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 25 C: 0
0%
M: 1 C: 0
0%
testOclAnyInvoke()
M: 213 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 47 C: 0
0%
M: 1 C: 0
0%
testOclAnySiblingsParameterizable()
M: 105 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 25 C: 0
0%
M: 1 C: 0
0%
testOclAnySiblingsUnparameterizable()
M: 109 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 26 C: 0
0%
M: 1 C: 0
0%
testOclAnySiblingsUnparameterizableResourceRoot()
M: 100 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 20 C: 0
0%
M: 1 C: 0
0%
testOclAnySiblingsUnparameterizableResourceRootWithCrossContainment()
M: 129 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 23 C: 0
0%
M: 1 C: 0
0%
testOclAnyToString()
M: 128 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 30 C: 0
0%
M: 1 C: 0
0%
testStringContains()
M: 188 C: 0
0%
M: 8 C: 0
0%
M: 5 C: 0
0%
M: 34 C: 0
0%
M: 1 C: 0
0%
testStringEndsWith()
M: 172 C: 0
0%
M: 8 C: 0
0%
M: 5 C: 0
0%
M: 32 C: 0
0%
M: 1 C: 0
0%
testStringReplace()
M: 108 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 27 C: 0
0%
M: 1 C: 0
0%
testStringReplaceAll()
M: 108 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 27 C: 0
0%
M: 1 C: 0
0%
testStringStartsWith()
M: 173 C: 0
0%
M: 8 C: 0
0%
M: 5 C: 0
0%
M: 32 C: 0
0%
M: 1 C: 0
0%
testStringSubstituteAll()
M: 101 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 25 C: 0
0%
M: 1 C: 0
0%
testStringTokenize()
M: 91 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 15 C: 0
0%
M: 1 C: 0
0%
testStringTrim()
M: 24 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 8 C: 0
0%
M: 1 C: 0
0%
testUndefinedOperation()
M: 66 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 19 C: 0
0%
M: 1 C: 0
0%

Coverage

1: /*******************************************************************************
2: * Copyright (c) 2009, 2013 Obeo and others.
3: * All rights reserved. This program and the accompanying materials
4: * are made available under the terms of the Eclipse Public License v1.0
5: * which accompanies this distribution, and is available at
6: * http://www.eclipse.org/legal/epl-v10.html
7: *
8: * Contributors:
9: * Obeo - initial API and implementation
10: * Christian W. Damus - Bug 424214 siblings() of resource roots
11: *******************************************************************************/
12: package org.eclipse.acceleo.engine.tests.unit.environment;
13:
14: import static org.junit.Assert.assertEquals;
15: import static org.junit.Assert.assertNotNull;
16: import static org.junit.Assert.assertSame;
17: import static org.junit.Assert.assertTrue;
18: import static org.junit.Assert.fail;
19:
20: import java.util.ArrayList;
21: import java.util.Arrays;
22: import java.util.Collection;
23: import java.util.HashMap;
24: import java.util.Iterator;
25: import java.util.List;
26: import java.util.Map;
27: import java.util.StringTokenizer;
28:
29: import org.eclipse.acceleo.common.utils.AcceleoNonStandardLibrary;
30: import org.eclipse.acceleo.engine.AcceleoEvaluationException;
31: import org.eclipse.acceleo.engine.event.IAcceleoTextGenerationListener;
32: import org.eclipse.acceleo.engine.internal.environment.AcceleoEnvironmentFactory;
33: import org.eclipse.acceleo.engine.internal.environment.AcceleoEvaluationEnvironment;
34: import org.eclipse.acceleo.engine.internal.environment.AcceleoLibraryOperationVisitor;
35: import org.eclipse.acceleo.engine.internal.environment.AcceleoPropertiesLookup;
36: import org.eclipse.acceleo.engine.tests.AcceleoEngineTestPlugin;
37: import org.eclipse.acceleo.engine.tests.unit.AbstractAcceleoTest;
38: import org.eclipse.emf.common.util.BasicMonitor;
39: import org.eclipse.emf.common.util.TreeIterator;
40: import org.eclipse.emf.common.util.URI;
41: import org.eclipse.emf.ecore.EAnnotation;
42: import org.eclipse.emf.ecore.EAttribute;
43: import org.eclipse.emf.ecore.EClass;
44: import org.eclipse.emf.ecore.EEnum;
45: import org.eclipse.emf.ecore.EGenericType;
46: import org.eclipse.emf.ecore.EObject;
47: import org.eclipse.emf.ecore.EOperation;
48: import org.eclipse.emf.ecore.EPackage;
49: import org.eclipse.emf.ecore.EcoreFactory;
50: import org.eclipse.emf.ecore.EcorePackage;
51: import org.eclipse.emf.ecore.resource.Resource;
52: import org.eclipse.emf.ecore.resource.impl.ResourceImpl;
53: import org.eclipse.emf.ecore.util.EcoreUtil;
54: import org.eclipse.ocl.ecore.OCL;
55: import org.junit.After;
56: import org.junit.Before;
57: import org.junit.Test;
58:
59: /**
60: * This will test the behavior of the Acceleo non standard library's operations.
61: *
62: * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
63: */
64: @SuppressWarnings("nls")
65: public class AcceleoNonStandardLibraryTest extends AbstractAcceleoTest {
66:         /** The evaluation environment to call for non standard operations on. */
67:         private AcceleoEvaluationEnvironment evaluationEnvironment;
68:
69:         /** This will be created at setUp and disposed of at tearDown time. */
70:         private AcceleoEnvironmentFactory factory;
71:
72:         /** EOperations defined in the non standard lib. */
73:         private final Map<String, List<EOperation>> nonStdLib = new HashMap<String, List<EOperation>>();
74:
75:         /** Values that will be used to test non standard string operations. */
76:         private final String[] stringValues = new String[] {"a", "\u00e9\u00e8\u0020\u00f1", "", "Foehn12",
77:                         "Standard sentence.", };
78:
79:         {
80:                 AcceleoNonStandardLibrary lib = new AcceleoNonStandardLibrary();
81:
82:                 List<EOperation> stringOperations = lib
83:                                 .getExistingOperations(AcceleoNonStandardLibrary.PRIMITIVE_STRING_NAME);
84:                 List<EOperation> copyOperations = new ArrayList<EOperation>(stringOperations.size());
85:•                for (EOperation operation : stringOperations) {
86:                         copyOperations.add((EOperation)EcoreUtil.copy(operation));
87:                 }
88:                 nonStdLib.put(AcceleoNonStandardLibrary.PRIMITIVE_STRING_NAME, copyOperations);
89:
90:                 List<EOperation> oclAnyOperations = lib
91:                                 .getExistingOperations(AcceleoNonStandardLibrary.TYPE_OCLANY_NAME);
92:                 copyOperations = new ArrayList<EOperation>(oclAnyOperations.size());
93:•                for (EOperation operation : oclAnyOperations) {
94:                         copyOperations.add((EOperation)EcoreUtil.copy(operation));
95:                 }
96:                 nonStdLib.put(AcceleoNonStandardLibrary.TYPE_OCLANY_NAME, copyOperations);
97:
98:                 List<EOperation> eObjectOperations = lib
99:                                 .getExistingOperations(AcceleoNonStandardLibrary.TYPE_EOBJECT_NAME);
100:                 copyOperations = new ArrayList<EOperation>(eObjectOperations.size());
101:•                for (EOperation operation : eObjectOperations) {
102:                         copyOperations.add((EOperation)EcoreUtil.copy(operation));
103:                 }
104:                 nonStdLib.put(AcceleoNonStandardLibrary.TYPE_EOBJECT_NAME, copyOperations);
105:         }
106:
107:         /**
108:          * {@inheritDoc}
109:          *
110:          * @see org.eclipse.acceleo.engine.tests.unit.AbstractAcceleoTest#setUp()
111:          */
112:         @Before
113:         @Override
114:         public void setUp() {
115:                 super.setUp();
116:                 // only used for initialization
117:                 this.init("NonStdLib");
118:                 factory = new AcceleoEnvironmentFactory(generationRoot, module,
119:                                 new ArrayList<IAcceleoTextGenerationListener>(), new AcceleoPropertiesLookup(),
120:                                 previewStrategy, new BasicMonitor());
121:                 final OCL ocl = OCL.newInstance(factory);
122:                 evaluationEnvironment = (AcceleoEvaluationEnvironment)ocl.getEvaluationEnvironment();
123:         }
124:
125:         /**
126:          * {@inheritDoc}
127:          *
128:          * @see org.eclipse.acceleo.engine.tests.unit.AbstractAcceleoTest#getModuleLocation()
129:          */
130:         @Override
131:         public String getModuleLocation() {
132:                 // Reusing the generic engine test template. This is only used for setup.
133:                 return "data/GenericEngine/generic_engine.mtl";
134:         }
135:
136:         /**
137:          * {@inheritDoc}
138:          *
139:          * @see org.eclipse.acceleo.engine.tests.unit.AbstractAcceleoTest#getReferencePath()
140:          */
141:         @Override
142:         public String getReferencePath() {
143:                 return "NonStandardLibrary";
144:         }
145:
146:         /**
147:          * {@inheritDoc}
148:          *
149:          * @see org.eclipse.acceleo.engine.tests.unit.AbstractAcceleoTest#tearDown()
150:          */
151:         @After
152:         @Override
153:         public void tearDown() {
154:                 factory.dispose();
155:         }
156:
157:         /**
158:          * Tests the behavior of the non standard "ancestors()" operation on OclAny.
159:          * <p>
160:          * Expects the result to contain all of the containers of the given object.
161:          * </p>
162:          */
163:         @Test
164:         public void testOclAnyAncestorsUnParameterizable() {
165:                 EOperation operation = getOperation(AcceleoNonStandardLibrary.TYPE_EOBJECT_NAME,
166:                                 AcceleoNonStandardLibrary.OPERATION_EOBJECT_ANCESTORS);
167:
168:                 final EPackage root = EcoreFactory.eINSTANCE.createEPackage();
169:                 final EPackage sub = EcoreFactory.eINSTANCE.createEPackage();
170:                 final EPackage subSub = EcoreFactory.eINSTANCE.createEPackage();
171:                 final EClass clazz = EcoreFactory.eINSTANCE.createEClass();
172:                 final EAttribute attribute = EcoreFactory.eINSTANCE.createEAttribute();
173:                 clazz.getEStructuralFeatures().add(attribute);
174:                 subSub.getEClassifiers().add(clazz);
175:                 sub.getESubpackages().add(subSub);
176:                 root.getESubpackages().add(sub);
177:
178:                 Object result = AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment,
179:                                 operation, attribute);
180:                 assertSame("Unexpected count of ancestors returned", 4, ((Collection<?>)result).size());
181:                 final Iterator<?> children = ((Collection<?>)result).iterator();
182:                 assertSame("The first container of the attribute should have been the class", clazz, children.next());
183:                 assertSame("The second container of the attribute should have been the second sub-package", subSub,
184:                                 children.next());
185:                 assertSame("The third container of the attribute should have been the first sub-package", sub,
186:                                 children.next());
187:                 assertSame("The fourth container of the attribute should have been the root package", root, children
188:                                 .next());
189:         }
190:
191:         /**
192:          * Tests the behavior of the non standard "ancestors(OclAny)" operation on OclAny.
193:          * <p>
194:          * Expects the result to contain all of the containers of the given type for the given object.
195:          * </p>
196:          */
197:         @Test
198:         public void testOclAnyAncestorsParameterizable() {
199:                 EOperation operation = getOperation(AcceleoNonStandardLibrary.TYPE_EOBJECT_NAME,
200:                                 AcceleoNonStandardLibrary.OPERATION_EOBJECT_ANCESTORS);
201:
202:                 final EPackage root = EcoreFactory.eINSTANCE.createEPackage();
203:                 final EPackage sub = EcoreFactory.eINSTANCE.createEPackage();
204:                 final EPackage subSub = EcoreFactory.eINSTANCE.createEPackage();
205:                 final EClass clazz = EcoreFactory.eINSTANCE.createEClass();
206:                 final EAttribute attribute = EcoreFactory.eINSTANCE.createEAttribute();
207:                 clazz.getEStructuralFeatures().add(attribute);
208:                 subSub.getEClassifiers().add(clazz);
209:                 sub.getESubpackages().add(subSub);
210:                 root.getESubpackages().add(sub);
211:
212:                 Object result = AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment,
213:                                 operation, attribute, EcorePackage.eINSTANCE.getEPackage());
214:                 assertSame("Unexpected count of ancestors returned", 3, ((Collection<?>)result).size());
215:                 final Iterator<?> children = ((Collection<?>)result).iterator();
216:                 assertSame("The first container of the attribute should have been the second sub-package", subSub,
217:                                 children.next());
218:                 assertSame("The second container of the attribute should have been the first sub-package", sub,
219:                                 children.next());
220:                 assertSame("The third container of the attribute should have been the root package", root, children
221:                                 .next());
222:         }
223:
224:         /**
225:          * Tests the behavior of the non standard "eAllContents()" operation on OclAny.
226:          * <p>
227:          * Expects the result to contain all of the Objects that can be iterated over through
228:          * {@link EObject#eAllContents()}.
229:          * </p>
230:          */
231:         @Test
232:         public void testOclAnyEAllContentsUnparameterizable() {
233:                 EOperation operation = getOperation(AcceleoNonStandardLibrary.TYPE_EOBJECT_NAME,
234:                                 AcceleoNonStandardLibrary.OPERATION_EOBJECT_EALLCONTENTS);
235:
236:                 final EPackage root = EcoreFactory.eINSTANCE.createEPackage();
237:                 final EPackage sub = EcoreFactory.eINSTANCE.createEPackage();
238:                 final EPackage subSub = EcoreFactory.eINSTANCE.createEPackage();
239:                 final EPackage subSub2 = EcoreFactory.eINSTANCE.createEPackage();
240:                 final EClass clazz = EcoreFactory.eINSTANCE.createEClass();
241:                 final EAttribute attribute = EcoreFactory.eINSTANCE.createEAttribute();
242:                 clazz.getEStructuralFeatures().add(attribute);
243:                 subSub.getEClassifiers().add(clazz);
244:                 sub.getESubpackages().add(subSub);
245:                 sub.getESubpackages().add(subSub2);
246:                 root.getESubpackages().add(sub);
247:
248:                 Object result = AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment,
249:                                 operation, root);
250:                 assertSame("Unexpected count of descendants returned", 5, ((Collection<?>)result).size());
251:                 final Iterator<?> children = ((Collection<?>)result).iterator();
252:                 assertSame("The first descendant of the root should have been the first sub-package", sub, children
253:                                 .next());
254:                 assertSame("The second descendant of the root should have been the second sub-package", subSub,
255:                                 children.next());
256:                 assertSame("The third descendant of the root should have been the EClass", clazz, children.next());
257:                 assertSame("The fourth descendant of the root should have been the attribute", attribute, children
258:                                 .next());
259:                 assertSame("The fifth descendant of the root should have been the third sub-package", subSub2,
260:                                 children.next());
261:         }
262:
263:         /**
264:          * Tests the behavior of the non standard "eAllContents(OclAny)" operation on OclAny.
265:          * <p>
266:          * Expects the result to contain all of the Objects that can be iterated over through
267:          * {@link EObject#eAllContents()} of ther given type.
268:          * </p>
269:          */
270:         @Test
271:         public void testOclAnyEAllContentsParameterizable() {
272:                 EOperation operation = getOperation(AcceleoNonStandardLibrary.TYPE_EOBJECT_NAME,
273:                                 AcceleoNonStandardLibrary.OPERATION_EOBJECT_EALLCONTENTS);
274:
275:                 final EPackage root = EcoreFactory.eINSTANCE.createEPackage();
276:                 final EPackage sub = EcoreFactory.eINSTANCE.createEPackage();
277:                 final EPackage subSub = EcoreFactory.eINSTANCE.createEPackage();
278:                 final EPackage subSub2 = EcoreFactory.eINSTANCE.createEPackage();
279:                 final EClass clazz = EcoreFactory.eINSTANCE.createEClass();
280:                 final EAttribute attribute = EcoreFactory.eINSTANCE.createEAttribute();
281:                 clazz.getEStructuralFeatures().add(attribute);
282:                 subSub.getEClassifiers().add(clazz);
283:                 sub.getESubpackages().add(subSub);
284:                 sub.getESubpackages().add(subSub2);
285:                 root.getESubpackages().add(sub);
286:
287:                 Object result = AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment,
288:                                 operation, root, EcorePackage.eINSTANCE.getEPackage());
289:                 assertSame("Unexpected count of descendants returned", 3, ((Collection<?>)result).size());
290:                 final Iterator<?> children = ((Collection<?>)result).iterator();
291:                 assertSame("The first descendant of the root should have been the first sub-package", sub, children
292:                                 .next());
293:                 assertSame("The second descendant of the root should have been the second sub-package", subSub,
294:                                 children.next());
295:                 assertSame("The third descendant of the root should have been the third sub-package", subSub2,
296:                                 children.next());
297:
298:                 // Ensure the behavior when passing null as argument doesn't evolve
299:                 try {
300:                         AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment, operation, root,
301:                                         (EObject)null);
302:                         fail("The non standard eAllContents(OclAny) operation previously threw NPEs when called with null argument");
303:                 } catch (NullPointerException e) {
304:                         // Expected behavior
305:                 }
306:         }
307:
308:         /**
309:          * Tests the behavior of the non standard "eInverse()" operation on OclAny.
310:          * <p>
311:          * Expects the result to contain all of the Objects that have a reference towards self.
312:          * </p>
313:          */
314:         @Test
315:         public void testOclAnyEInverseUnparameterizable() {
316:                 EOperation operation = getOperation(AcceleoNonStandardLibrary.TYPE_EOBJECT_NAME,
317:                                 AcceleoNonStandardLibrary.OPERATION_EOBJECT_EINVERSE);
318:
319:                 final EPackage root = EcoreFactory.eINSTANCE.createEPackage();
320:                 final EPackage sub = EcoreFactory.eINSTANCE.createEPackage();
321:                 final EPackage subSub = EcoreFactory.eINSTANCE.createEPackage();
322:                 final EPackage subSub2 = EcoreFactory.eINSTANCE.createEPackage();
323:                 final EClass clazz = EcoreFactory.eINSTANCE.createEClass();
324:                 final EClass clazz2 = EcoreFactory.eINSTANCE.createEClass();
325:                 final EAttribute attribute = EcoreFactory.eINSTANCE.createEAttribute();
326:                 clazz.getEStructuralFeatures().add(attribute);
327:                 subSub.getEClassifiers().add(clazz);
328:                 sub.getESubpackages().add(subSub);
329:                 subSub2.getEClassifiers().add(clazz2);
330:                 sub.getESubpackages().add(subSub2);
331:                 root.getESubpackages().add(sub);
332:                 clazz.getESuperTypes().add(clazz2);
333:
334:                 Object result = AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment,
335:                                 operation, clazz2);
336:                 assertSame("Unexpected count of inverse references returned", 2, ((Collection<?>)result).size());
337:                 final Iterator<?> children = ((Collection<?>)result).iterator();
338:                 assertSame("The first inverse reference on the second EClass should have been the first EClass",
339:                                 clazz, children.next());
340:                 assertTrue("The second inverse reference on the second EClass should have been a GenericType",
341:                                 children.next() instanceof EGenericType);
342:         }
343:
344:         /**
345:          * Tests the behavior of the non standard "eInverse(OclAny)" operation on OclAny.
346:          * <p>
347:          * Expects the result to contain all of the Objects that have a reference towards self and are instances
348:          * of the given type.
349:          * </p>
350:          */
351:         @Test
352:         public void testOclAnyEInverseParameterizable() {
353:                 EOperation operation = getOperation(AcceleoNonStandardLibrary.TYPE_EOBJECT_NAME,
354:                                 AcceleoNonStandardLibrary.OPERATION_EOBJECT_EINVERSE);
355:
356:                 final EPackage root = EcoreFactory.eINSTANCE.createEPackage();
357:                 final EPackage sub = EcoreFactory.eINSTANCE.createEPackage();
358:                 final EPackage subSub = EcoreFactory.eINSTANCE.createEPackage();
359:                 final EPackage subSub2 = EcoreFactory.eINSTANCE.createEPackage();
360:                 final EClass clazz = EcoreFactory.eINSTANCE.createEClass();
361:                 final EClass clazz2 = EcoreFactory.eINSTANCE.createEClass();
362:                 final EAttribute attribute = EcoreFactory.eINSTANCE.createEAttribute();
363:                 clazz.getEStructuralFeatures().add(attribute);
364:                 subSub.getEClassifiers().add(clazz);
365:                 sub.getESubpackages().add(subSub);
366:                 subSub2.getEClassifiers().add(clazz2);
367:                 sub.getESubpackages().add(subSub2);
368:                 root.getESubpackages().add(sub);
369:                 clazz.getESuperTypes().add(clazz2);
370:
371:                 Object result = AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment,
372:                                 operation, clazz2, EcorePackage.eINSTANCE.getEGenericType());
373:                 assertSame("Unexpected count of inverse references returned", 1, ((Collection<?>)result).size());
374:                 final Iterator<?> children = ((Collection<?>)result).iterator();
375:                 assertTrue("The inverse reference on the second EClass should have been a GenericType", children
376:                                 .next() instanceof EGenericType);
377:         }
378:
379:         /**
380:          * Tests the behavior of the non standard "siblings()" operation on OclAny.
381:          * <p>
382:          * Expects the result to contain all of the siblings of the given object, excluding self.
383:          * </p>
384:          */
385:         @Test
386:         public void testOclAnySiblingsUnparameterizable() {
387:                 EOperation operation = getOperation(AcceleoNonStandardLibrary.TYPE_EOBJECT_NAME,
388:                                 AcceleoNonStandardLibrary.OPERATION_EOBJECT_SIBLINGS);
389:
390:                 final EPackage root = EcoreFactory.eINSTANCE.createEPackage();
391:                 final EPackage sub = EcoreFactory.eINSTANCE.createEPackage();
392:                 final EPackage subSub = EcoreFactory.eINSTANCE.createEPackage();
393:                 final EClass clazz1 = EcoreFactory.eINSTANCE.createEClass();
394:                 final EClass clazz2 = EcoreFactory.eINSTANCE.createEClass();
395:                 final EClass clazz3 = EcoreFactory.eINSTANCE.createEClass();
396:                 subSub.getEClassifiers().add(clazz1);
397:                 subSub.getEClassifiers().add(clazz2);
398:                 subSub.getEClassifiers().add(clazz3);
399:                 sub.getESubpackages().add(subSub);
400:                 root.getESubpackages().add(sub);
401:
402:                 Object result = AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment,
403:                                 operation, clazz2);
404:                 assertSame("Unexpected count of siblings returned", 2, ((Collection<?>)result).size());
405:                 Iterator<?> children = ((Collection<?>)result).iterator();
406:                 assertSame("The sibling should have been the first added EClass.", clazz1, children.next());
407:                 assertSame("The sibling should have been the third added EClass.", clazz3, children.next());
408:
409:                 result = AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment, operation,
410:                                 clazz1);
411:                 assertSame("Unexpected count of siblings returned", 2, ((Collection<?>)result).size());
412:                 children = ((Collection<?>)result).iterator();
413:                 assertSame("The sibling should have been the second added EClass.", clazz2, children.next());
414:                 assertSame("The sibling should have been the third added EClass.", clazz3, children.next());
415:         }
416:
417:         /**
418:          * Tests the behavior of the non standard "siblings()" operation on OclAny with an object that is a root
419:          * (in the resource contents, no container).
420:          * <p>
421:          * Expects the result to contain all of the other roots of the given object's resource, excluding self.
422:          * </p>
423:          */
424:         @Test
425:         public void testOclAnySiblingsUnparameterizableResourceRoot() {
426:                 EOperation operation = getOperation(AcceleoNonStandardLibrary.TYPE_EOBJECT_NAME,
427:                                 AcceleoNonStandardLibrary.OPERATION_EOBJECT_SIBLINGS);
428:
429:                 final Resource resource = new ResourceImpl(URI.createURI("junk://test"));
430:                 final EPackage p1 = EcoreFactory.eINSTANCE.createEPackage();
431:                 final EPackage p2 = EcoreFactory.eINSTANCE.createEPackage();
432:                 final EPackage p3 = EcoreFactory.eINSTANCE.createEPackage();
433:                 resource.getContents().addAll(Arrays.asList(p1, p2, p3));
434:
435:                 Object result = AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment,
436:                                 operation, p2);
437:                 assertSame("Unexpected count of siblings returned", 2, ((Collection<?>)result).size());
438:                 Iterator<?> children = ((Collection<?>)result).iterator();
439:                 assertSame("The sibling should have been the first added EPackage.", p1, children.next());
440:                 assertSame("The sibling should have been the third added EPackage.", p3, children.next());
441:
442:                 result = AcceleoLibraryOperationVisitor
443:                                 .callNonStandardOperation(evaluationEnvironment, operation, p1);
444:                 assertSame("Unexpected count of siblings returned", 2, ((Collection<?>)result).size());
445:                 children = ((Collection<?>)result).iterator();
446:                 assertSame("The sibling should have been the second added EPackage.", p2, children.next());
447:                 assertSame("The sibling should have been the third added EPackage.", p3, children.next());
448:         }
449:
450:         /**
451:          * Tests the behavior of the non standard "siblings()" operation on OclAny with an object that is a root
452:          * (in the resource contents, no container) but whose containing resource has cross-resource-contained
453:          * objects.
454:          * <p>
455:          * Expects the result to contain all of the other roots of the given object's resource, excluding self.
456:          * </p>
457:          */
458:         @Test
459:         public void testOclAnySiblingsUnparameterizableResourceRootWithCrossContainment() {
460:                 EOperation operation = getOperation(AcceleoNonStandardLibrary.TYPE_EOBJECT_NAME,
461:                                 AcceleoNonStandardLibrary.OPERATION_EOBJECT_SIBLINGS);
462:
463:                 final Resource resource = new ResourceImpl(URI.createURI("junk://test"));
464:                 final EPackage p1 = EcoreFactory.eINSTANCE.createEPackage();
465:                 final EPackage p2 = EcoreFactory.eINSTANCE.createEPackage();
466:                 final EPackage p3 = EcoreFactory.eINSTANCE.createEPackage();
467:                 final EPackage sub1 = EcoreFactory.eINSTANCE.createEPackage();
468:                 final EPackage sub2 = EcoreFactory.eINSTANCE.createEPackage();
469:                 p1.getESubpackages().addAll(Arrays.asList(sub1, sub2));
470:                 resource.getContents().addAll(Arrays.asList(p1, sub1, p2, sub2, p3));
471:
472:                 Object result = AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment,
473:                                 operation, p2);
474:                 assertSame("Unexpected count of siblings returned", 2, ((Collection<?>)result).size());
475:                 Iterator<?> children = ((Collection<?>)result).iterator();
476:                 assertSame("The sibling should have been the first added EPackage.", p1, children.next());
477:                 assertSame("The sibling should have been the third added EPackage.", p3, children.next());
478:
479:                 result = AcceleoLibraryOperationVisitor
480:                                 .callNonStandardOperation(evaluationEnvironment, operation, p1);
481:                 assertSame("Unexpected count of siblings returned", 2, ((Collection<?>)result).size());
482:                 children = ((Collection<?>)result).iterator();
483:                 assertSame("The sibling should have been the second added EPackage.", p2, children.next());
484:                 assertSame("The sibling should have been the third added EPackage.", p3, children.next());
485:         }
486:
487:         /**
488:          * Tests the behavior of the non standard "invoke()" operation on OclAny.
489:          * <p>
490:          * As this can be used more or less for anything, we will use it to invoke generic methods with easily
491:          * inferred results.
492:          * </p>
493:          */
494:         @Test
495:         public void testOclAnyInvoke() {
496:                 final Resource resource = new ResourceImpl();
497:                 resource.setURI(URI.createPlatformPluginURI('/' + AcceleoEngineTestPlugin.PLUGIN_ID + '/'
498:                                 + "data/Library/nonstdlib" + EMTL_EXTENSION, true));
499:                 EOperation operation = getOperation(AcceleoNonStandardLibrary.TYPE_OCLANY_NAME,
500:                                 AcceleoNonStandardLibrary.OPERATION_OCLANY_INVOKE);
501:                 resource.getContents().add(operation);
502:
503:                 final EPackage root = EcoreFactory.eINSTANCE.createEPackage();
504:                 final EPackage sub = EcoreFactory.eINSTANCE.createEPackage();
505:                 final EPackage subSub = EcoreFactory.eINSTANCE.createEPackage();
506:                 final EClass clazz1 = EcoreFactory.eINSTANCE.createEClass();
507:                 final EClass clazz2 = EcoreFactory.eINSTANCE.createEClass();
508:                 final EClass clazz3 = EcoreFactory.eINSTANCE.createEClass();
509:                 final EEnum enumeration = EcoreFactory.eINSTANCE.createEEnum();
510:                 subSub.getEClassifiers().add(clazz1);
511:                 subSub.getEClassifiers().add(clazz2);
512:                 subSub.getEClassifiers().add(clazz3);
513:                 subSub.getEClassifiers().add(enumeration);
514:                 sub.getESubpackages().add(subSub);
515:                 root.getESubpackages().add(sub);
516:
517:                 final List<Object> args = new ArrayList<Object>();
518:
519:                 Object result = AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment,
520:                                 operation, root, "java.lang.Object", "toString()", args);
521:                 assertNotNull("A result should have been returned", result);
522:                 assertEquals("Unexpected result of invocation with Object.toString as target", root.toString(),
523:                                 result);
524:
525:                 args.add(root);
526:                 result = AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment, operation,
527:                                 root, "org.eclipse.emf.ecore.util.EcoreUtil", "getURI(org.eclipse.emf.ecore.EObject)", args);
528:                 assertNotNull("A result should have been returned", result);
529:                 assertEquals("Unexpected result of invocation with Object.toString as target",
530:                                 EcoreUtil.getURI(root), result);
531:
532:                 // ClassNotFound
533:                 try {
534:                         result = AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment,
535:                                         operation, root, "inexisting.Object", "method()", args);
536:                         fail("The non-standard 'invoke' operation is expected to fail in AcceleoEvaluationException "
537:                                         + "when trying to invoke a method of an inexisting class.");
538:                 } catch (AcceleoEvaluationException e) {
539:                         // expected behavior
540:                 }
541:
542:                 // NoSuchMethod
543:                 try {
544:                         result = AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment,
545:                                         operation, root, "java.lang.Object", "unknownMethod()", args);
546:                         fail("The non-standard 'invoke' operation is expected to fail in AcceleoEvaluationException "
547:                                         + "when trying to invoke an inexisting method.");
548:                 } catch (AcceleoEvaluationException e) {
549:                         // expected behavior
550:                 }
551:
552:                 // IllegalArgument
553:                 try {
554:                         args.clear();
555:                         args.add("test");
556:                         result = AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment,
557:                                         operation, root, "org.eclipse.emf.ecore.util.EcoreUtil",
558:                                         "getURI(org.eclipse.emf.ecore.EObject)", args);
559:                         fail("The non-standard 'invoke' operation is expected to fail in AcceleoEvaluationException "
560:                                         + "when trying to invoke a method with illegal arguments.");
561:                 } catch (AcceleoEvaluationException e) {
562:                         // expected behavior
563:                 }
564:         }
565:
566:         /**
567:          * Tests the behavior of the non standard "siblings(OclAny)" operation on OclAny.
568:          * <p>
569:          * Expects the result to contain all of the siblings of the given type for the given object, excluding
570:          * self.
571:          * </p>
572:          */
573:         @Test
574:         public void testOclAnySiblingsParameterizable() {
575:                 EOperation operation = getOperation(AcceleoNonStandardLibrary.TYPE_EOBJECT_NAME,
576:                                 AcceleoNonStandardLibrary.OPERATION_EOBJECT_SIBLINGS);
577:
578:                 final EPackage root = EcoreFactory.eINSTANCE.createEPackage();
579:                 final EPackage sub = EcoreFactory.eINSTANCE.createEPackage();
580:                 final EPackage subSub = EcoreFactory.eINSTANCE.createEPackage();
581:                 final EClass clazz1 = EcoreFactory.eINSTANCE.createEClass();
582:                 final EClass clazz2 = EcoreFactory.eINSTANCE.createEClass();
583:                 final EClass clazz3 = EcoreFactory.eINSTANCE.createEClass();
584:                 final EEnum enumeration = EcoreFactory.eINSTANCE.createEEnum();
585:                 subSub.getEClassifiers().add(clazz1);
586:                 subSub.getEClassifiers().add(clazz2);
587:                 subSub.getEClassifiers().add(clazz3);
588:                 subSub.getEClassifiers().add(enumeration);
589:                 sub.getESubpackages().add(subSub);
590:                 root.getESubpackages().add(sub);
591:
592:                 Object result = AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment,
593:                                 operation, clazz2, EcorePackage.eINSTANCE.getEEnum());
594:                 assertSame("Unexpected count of siblings returned", 1, ((Collection<?>)result).size());
595:                 Iterator<?> children = ((Collection<?>)result).iterator();
596:                 assertSame("The sibling should have been the only eenum.", enumeration, children.next());
597:
598:                 result = AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment, operation,
599:                                 enumeration, EcorePackage.eINSTANCE.getEEnum());
600:                 assertTrue("There shouldn't have been any sibling of type EEnum for the only EEnum of a package",
601:                                 ((Collection<?>)result).isEmpty());
602:         }
603:
604:         /**
605:          * Tests the behavior of the non standard "toString()" operation on OclAny.
606:          * <p>
607:          * Expects the result to be the same as a call to Object#toString() on the receiver.
608:          * </p>
609:          */
610:         @Test
611:         public void testOclAnyToString() {
612:                 EOperation operation = getOperation(AcceleoNonStandardLibrary.TYPE_OCLANY_NAME,
613:                                 AcceleoNonStandardLibrary.OPERATION_OCLANY_TOSTRING);
614:
615:                 final EPackage root = EcoreFactory.eINSTANCE.createEPackage();
616:                 final EPackage sub = EcoreFactory.eINSTANCE.createEPackage();
617:                 final EPackage subSub = EcoreFactory.eINSTANCE.createEPackage();
618:                 final EPackage subSub2 = EcoreFactory.eINSTANCE.createEPackage();
619:                 final EClass clazz = EcoreFactory.eINSTANCE.createEClass();
620:                 final EClass clazz2 = EcoreFactory.eINSTANCE.createEClass();
621:                 final EAttribute attribute = EcoreFactory.eINSTANCE.createEAttribute();
622:                 clazz.getEStructuralFeatures().add(attribute);
623:                 subSub.getEClassifiers().add(clazz);
624:                 sub.getESubpackages().add(subSub);
625:                 subSub2.getEClassifiers().add(clazz2);
626:                 sub.getESubpackages().add(subSub2);
627:                 root.getESubpackages().add(sub);
628:                 clazz.getESuperTypes().add(clazz2);
629:
630:                 final TreeIterator<EObject> childrenIterator = root.eAllContents();
631:•                while (childrenIterator.hasNext()) {
632:                         final EObject child = childrenIterator.next();
633:                         assertEquals("Unexpected result of the non-standard toString operation on " + child, child
634:                                         .toString(), AcceleoLibraryOperationVisitor.callNonStandardOperation(
635:                                         evaluationEnvironment, operation, child));
636:                 }
637:
638:•                for (String value : stringValues) {
639:                         assertEquals("Unexpected result of the non-standard toString operation on a String", value,
640:                                         AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment, operation,
641:                                                         value));
642:                 }
643:
644:                 assertEquals("Unexpected result of the non-standard toString operation on an Integer", "0",
645:                                 AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment, operation,
646:                                                 Integer.valueOf(0)));
647:         }
648:
649:         /**
650:          * Tests the behavior of the non standard "contains(String)" operation on String.
651:          * <p>
652:          * Expects the result to be the same as {@link String#contains(CharSequence)}.
653:          * </p>
654:          */
655:         @Test
656:         public void testStringContains() {
657:                 EOperation operation = getOperation(AcceleoNonStandardLibrary.PRIMITIVE_STRING_NAME,
658:                                 AcceleoNonStandardLibrary.OPERATION_STRING_CONTAINS);
659:
660:                 final String uncontainedString = "tgdjfsleo";
661:
662:                 // Taking random characters as the value : expecting contains to return false
663:•                for (String value : stringValues) {
664:                         final Object result = AcceleoLibraryOperationVisitor.callNonStandardOperation(
665:                                         evaluationEnvironment, operation, value, uncontainedString);
666:                         assertTrue("Result of contains should have been a boolean", result instanceof Boolean);
667:                         assertEquals("Result should have been false.", Boolean.FALSE, result);
668:                         assertEquals("The non standard operation should have returned the same result as "
669:                                         + "String#contains(CharSequence)", value.contains(uncontainedString), result);
670:                 }
671:
672:                 // Taking random substring of the value : expecting contains to return true
673:•                for (String value : stringValues) {
674:                         final String subString;
675:•                        if (value.length() == 0) {
676:                                 subString = value;
677:                         } else {
678:                                 final int offset1 = Double.valueOf(Math.random() * value.length()).intValue();
679:                                 final int offset2 = Double.valueOf(Math.random() * value.length()).intValue();
680:                                 subString = value.substring(Math.min(offset1, offset2), Math.max(offset1, offset2));
681:                         }
682:                         final Object result = AcceleoLibraryOperationVisitor.callNonStandardOperation(
683:                                         evaluationEnvironment, operation, value, subString);
684:                         assertTrue("Result of contains should have been a boolean", result instanceof Boolean);
685:                         assertEquals("Result should have been true.", Boolean.TRUE, result);
686:                         assertEquals("The non standard operation should have returned the same result as "
687:                                         + "String#contains(CharSequence)", value.contains(subString), result);
688:                 }
689:
690:                 // Checking if value "contains" itself : expecting contains to return true
691:•                for (String value : stringValues) {
692:                         final Object result = AcceleoLibraryOperationVisitor.callNonStandardOperation(
693:                                         evaluationEnvironment, operation, value, value);
694:                         assertTrue("Result of contains should have been a boolean", result instanceof Boolean);
695:                         assertEquals("Result should have been true.", Boolean.TRUE, result);
696:                         assertEquals("The non standard operation should have returned the same result as "
697:                                         + "String#contains(CharSequence)", value.contains(value), result);
698:                 }
699:
700:                 // Ensure the behavior when passing null as argument doesn't evolve
701:                 try {
702:                         AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment, operation,
703:                                         stringValues[0], (Object)null);
704:                         fail("The non standard String.contains operation previously threw NPEs when called with null argument");
705:                 } catch (NullPointerException e) {
706:                         // Expected behavior
707:                 }
708:         }
709:
710:         /**
711:          * Tests the behavior of the non standard "endsWith(String)" operation on String.
712:          * <p>
713:          * Expects the result to be the same as {@link String#endsWith(String)}.
714:          * </p>
715:          */
716:         @Test
717:         public void testStringEndsWith() {
718:                 EOperation operation = getOperation(AcceleoNonStandardLibrary.PRIMITIVE_STRING_NAME,
719:                                 AcceleoNonStandardLibrary.OPERATION_STRING_ENDSWITH);
720:
721:                 final String uncontainedString = "tgdjfsleo";
722:
723:                 // Taking random characters as the end value : expecting endsWith to return false
724:•                for (String value : stringValues) {
725:                         final Object result = AcceleoLibraryOperationVisitor.callNonStandardOperation(
726:                                         evaluationEnvironment, operation, value, uncontainedString);
727:                         assertTrue("Result of endsWith should have been a boolean", result instanceof Boolean);
728:                         assertEquals("Result should have been false.", Boolean.FALSE, result);
729:                         assertEquals("The non standard operation should have returned the same result as "
730:                                         + "String#endsWith(String)", value.endsWith(uncontainedString), result);
731:                 }
732:
733:                 // Taking last part of the value : expecting endsWith to return true
734:•                for (String value : stringValues) {
735:                         final String lastPart;
736:•                        if (value.length() == 0) {
737:                                 lastPart = value;
738:                         } else {
739:                                 lastPart = value.substring(Math.max(value.length() / 2, 1));
740:                         }
741:                         final Object result = AcceleoLibraryOperationVisitor.callNonStandardOperation(
742:                                         evaluationEnvironment, operation, value, lastPart);
743:                         assertTrue("Result of endsWith should have been a boolean", result instanceof Boolean);
744:                         assertEquals("Result should have been true.", Boolean.TRUE, result);
745:                         assertEquals("The non standard operation should have returned the same result as "
746:                                         + "String#endsWith(String)", value.endsWith(lastPart), result);
747:                 }
748:
749:                 // Checking if value "endsWith" itself : expecting endsWith to return true
750:•                for (String value : stringValues) {
751:                         final Object result = AcceleoLibraryOperationVisitor.callNonStandardOperation(
752:                                         evaluationEnvironment, operation, value, value);
753:                         assertTrue("Result of endsWith should have been a boolean", result instanceof Boolean);
754:                         assertEquals("Result should have been true.", Boolean.TRUE, result);
755:                         assertEquals("The non standard operation should have returned the same result as "
756:                                         + "String#endsWith(String)", value.endsWith(value), result);
757:                 }
758:
759:                 // Ensure the behavior when passing null as argument doesn't evolve
760:                 try {
761:                         AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment, operation,
762:                                         stringValues[0], (Object)null);
763:                         fail("The non standard String.endsWith operation previously threw NPEs when called with null argument");
764:                 } catch (NullPointerException e) {
765:                         // Expected behavior
766:                 }
767:         }
768:
769:         /**
770:          * Tests the behavior of the non standard "replace(String, String)" operation on String.
771:          * <p>
772:          * Expects the result to be the same as {@link String#replaceFirst(String, String)}.
773:          * </p>
774:          */
775:         @Test
776:         public void testStringReplace() {
777:                 EOperation operation = getOperation(AcceleoNonStandardLibrary.PRIMITIVE_STRING_NAME,
778:                                 AcceleoNonStandardLibrary.OPERATION_STRING_REPLACE);
779:
780:                 final String value = "start .*abc.* - .*abc.* end";
781:                 String search = "(.*?)abc.*( end)";
782:                 String replace = "$1 -$2";
783:                 Object result = AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment,
784:                                 operation, value, search, replace);
785:                 assertEquals("Non standard operation String.replace(String, String) didn't return the "
786:                                 + "expected result.", "start .* - end", result);
787:                 assertEquals("Non standard replace didn't yield the same result as String.replace().", value
788:                                 .replaceFirst(search, replace), result);
789:
790:                 search = "not contained substring";
791:                 replace = "random replacement";
792:                 result = AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment, operation,
793:                                 value, search, replace);
794:                 assertEquals("standard operation String.replace(String, String) didn't return the "
795:                                 + "expected result.", "start .*abc.* - .*abc.* end", result);
796:                 assertEquals("Non standard replace didn't yield the same result as String.replace().", value
797:                                 .replaceFirst(search, replace), result);
798:
799:                 // Ensure the behavior when passing null as argument doesn't evolve
800:                 try {
801:                         AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment, operation, value,
802:                                         (Object)null, "abc");
803:                         fail("The non standard String.replace operation previously threw NPEs when called with null argument");
804:                 } catch (NullPointerException e) {
805:                         // Expected behavior
806:                 }
807:                 try {
808:                         AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment, operation, value,
809:                                         "abc", (Object)null);
810:                         fail("The non standard String.replace operation previously threw NPEs when called with null argument");
811:                 } catch (NullPointerException e) {
812:                         // Expected behavior
813:                 }
814:         }
815:
816:         /**
817:          * Tests the behavior of the non standard "replaceAll(String, String)" operation on String.
818:          * <p>
819:          * Expects the result to be the same as {@link String#replaceAll(String, String)}.
820:          * </p>
821:          */
822:         @Test
823:         public void testStringReplaceAll() {
824:                 EOperation operation = getOperation(AcceleoNonStandardLibrary.PRIMITIVE_STRING_NAME,
825:                                 AcceleoNonStandardLibrary.OPERATION_STRING_REPLACEALL);
826:
827:                 final String value = "start .*abc.* - .*abc.* end";
828:                 String search = "(.*?)abc";
829:                 String replace = "$1def";
830:                 Object result = AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment,
831:                                 operation, value, search, replace);
832:                 assertEquals("Non standard operation String.replaceAll(String, String) didn't return the "
833:                                 + "expected result.", "start .*def.* - .*def.* end", result);
834:                 assertEquals("Non standard replace didn't yield the same result as String.replaceAll().", value
835:                                 .replaceAll(search, replace), result);
836:
837:                 search = "not contained substring";
838:                 replace = "random replacement";
839:                 result = AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment, operation,
840:                                 value, search, replace);
841:                 assertEquals("standard operation String.replaceAll(String, String) didn't return the "
842:                                 + "expected result.", "start .*abc.* - .*abc.* end", result);
843:                 assertEquals("Non standard replaceAll didn't yield the same result as String.replaceAll().", value
844:                                 .replaceAll(search, replace), result);
845:
846:                 // Ensure the behavior when passing null as argument doesn't evolve
847:                 try {
848:                         AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment, operation, value,
849:                                         (Object)null, "abc");
850:                         fail("The non standard String.replaceAll operation previously threw NPEs when called with null argument");
851:                 } catch (NullPointerException e) {
852:                         // Expected behavior
853:                 }
854:                 try {
855:                         AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment, operation, value,
856:                                         "abc", (Object)null);
857:                         fail("The non standard String.replaceAll operation previously threw NPEs when called with null argument");
858:                 } catch (NullPointerException e) {
859:                         // Expected behavior
860:                 }
861:         }
862:
863:         /**
864:          * Tests the behavior of the non standard "startsWith(String)" operation on String.
865:          * <p>
866:          * Expects the result to be the same as {@link String#startsWith(String)}.
867:          * </p>
868:          */
869:         @Test
870:         public void testStringStartsWith() {
871:                 EOperation operation = getOperation(AcceleoNonStandardLibrary.PRIMITIVE_STRING_NAME,
872:                                 AcceleoNonStandardLibrary.OPERATION_STRING_STARTSWITH);
873:
874:                 final String uncontainedString = "tgdjfsleo";
875:
876:                 // Taking random characters as the end value : expecting startsWith to return false
877:•                for (String value : stringValues) {
878:                         final Object result = AcceleoLibraryOperationVisitor.callNonStandardOperation(
879:                                         evaluationEnvironment, operation, value, uncontainedString);
880:                         assertTrue("Result of startsWith should have been a boolean", result instanceof Boolean);
881:                         assertEquals("Result should have been false.", Boolean.FALSE, result);
882:                         assertEquals("The non standard operation should have returned the same result as "
883:                                         + "String#startsWith(String)", value.startsWith(uncontainedString), result);
884:                 }
885:
886:                 // Taking first part of the value : expecting startsWith to return true
887:•                for (String value : stringValues) {
888:                         final String firstPart;
889:•                        if (value.length() == 0) {
890:                                 firstPart = value;
891:                         } else {
892:                                 firstPart = value.substring(0, Math.max(value.length() / 2, 1));
893:                         }
894:                         final Object result = AcceleoLibraryOperationVisitor.callNonStandardOperation(
895:                                         evaluationEnvironment, operation, value, firstPart);
896:                         assertTrue("Result of startsWith should have been a boolean", result instanceof Boolean);
897:                         assertEquals("Result should have been true.", Boolean.TRUE, result);
898:                         assertEquals("The non standard operation should have returned the same result as "
899:                                         + "String#startsWith(String)", value.startsWith(firstPart), result);
900:                 }
901:
902:                 // Checking if value "startsWith" itself : expecting startsWith to return true
903:•                for (String value : stringValues) {
904:                         final Object result = AcceleoLibraryOperationVisitor.callNonStandardOperation(
905:                                         evaluationEnvironment, operation, value, value);
906:                         assertTrue("Result of startsWith should have been a boolean", result instanceof Boolean);
907:                         assertEquals("Result should have been true.", Boolean.TRUE, result);
908:                         assertEquals("The non standard operation should have returned the same result as "
909:                                         + "String#startsWith(String)", value.startsWith(value), result);
910:                 }
911:
912:                 // Ensure the behavior when passing null as argument doesn't evolve
913:                 try {
914:                         AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment, operation,
915:                                         stringValues[0], (Object)null);
916:                         fail("The non standard String.startsWith operation previously threw NPEs when called with null argument");
917:                 } catch (NullPointerException e) {
918:                         // Expected behavior
919:                 }
920:         }
921:
922:         /**
923:          * Tests the behavior of the non standard String.substituteAll(String, String) operation.
924:          * <p>
925:          * We expect the call to replace all occurences of the substring by the replacement, not considering both
926:          * parameters as regular expressions. Result should be the same as
927:          * {@link String#replace(CharSequence, CharSequence)}.
928:          * </p>
929:          */
930:         @Test
931:         public void testStringSubstituteAll() {
932:                 EOperation operation = getOperation(AcceleoNonStandardLibrary.PRIMITIVE_STRING_NAME,
933:                                 AcceleoNonStandardLibrary.OPERATION_STRING_SUBSTITUTEALL);
934:
935:                 final String value = "start .*abc.* - .*abc.* end";
936:                 String search = ".*abc.*";
937:                 String replace = "\\$1\\1def\\2$2\\";
938:                 Object result = AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment,
939:                                 operation, value, search, replace);
940:                 assertEquals("Non standard operation String.substituteAll(String, String) didn't return the "
941:                                 + "expected result.", "start \\$1\\1def\\2$2\\ - \\$1\\1def\\2$2\\ end", result);
942:                 assertEquals("Result of the non standard substituteAll should have been the same as calling"
943:                                 + "String#replace(CharSequence, CharSequence).", value.replace(search, replace), result);
944:
945:                 search = "not contained substring";
946:                 replace = "random replacement";
947:                 result = AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment, operation,
948:                                 value, search, replace);
949:                 assertEquals("Non standard operation String.substituteAll(String, String) didn't return the "
950:                                 + "expected result.", "start .*abc.* - .*abc.* end", result);
951:
952:                 // Ensure the behavior when passing null as argument doesn't evolve
953:                 try {
954:                         AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment, operation, value,
955:                                         (EObject)null, "abc");
956:                         fail("The non standard String.substituteAll operation previously threw NPEs when called with null argument");
957:                 } catch (NullPointerException e) {
958:                         // Expected behavior
959:                 }
960:                 try {
961:                         AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment, operation, value,
962:                                         "abc", (EObject)null);
963:                         fail("The non standard String.substitute operation previously threw NPEs when called with null argument");
964:                 } catch (NullPointerException e) {
965:                         // Expected behavior
966:                 }
967:         }
968:
969:         /**
970:          * Tests the behavior of the non standard "tokenize(String)" operation on String.
971:          * <p>
972:          * Expects the behavior to mimic that of the {@link StringTokenizer}.
973:          * </p>
974:          */
975:         @Test
976:         @SuppressWarnings("unchecked")
977:         public void testStringTokenize() {
978:                 EOperation operation = getOperation(AcceleoNonStandardLibrary.PRIMITIVE_STRING_NAME,
979:                                 AcceleoNonStandardLibrary.OPERATION_STRING_TOKENIZE);
980:
981:                 final String[] expected = {"this", "is", "a", "randomly", "delimited", "sentence", };
982:                 final String value = "this/is.a\\randomly_delimited^sentence";
983:                 final Object result = AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment,
984:                                 operation, value, "^/_.\\");
985:                 assertTrue("Result should have been a list.", result instanceof List<?>);
986:                 assertSame("Result should have contained 6 words.", expected.length, ((List<String>)result).size());
987:•                for (int i = 0; i < expected.length; i++) {
988:                         assertEquals("unexpected String in the tokenized list.", expected[i], ((List<String>)result)
989:                                         .get(i));
990:                 }
991:
992:                 // Ensure the behavior when passing null as argument doesn't evolve
993:                 try {
994:                         AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment, operation, value,
995:                                         (EObject)null);
996:                         fail("The non standard String.tokenize operation previously threw NPEs when called with null argument");
997:                 } catch (NullPointerException e) {
998:                         // Expected behavior
999:                 }
1000:         }
1001:
1002:         /**
1003:          * Tests the behavior of the non standard "trim()" operation on String.
1004:          */
1005:         @Test
1006:         public void testStringTrim() {
1007:                 EOperation operation = getOperation(AcceleoNonStandardLibrary.PRIMITIVE_STRING_NAME,
1008:                                 AcceleoNonStandardLibrary.OPERATION_STRING_TRIM);
1009:
1010:                 final String value = " abc abc\nabc\n ";
1011:                 final Object result = AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment,
1012:                                 operation, value.trim());
1013:                 assertEquals("Unexpected result of the non standard String.trim operation.", "abc abc\nabc", result);
1014:                 assertEquals("Non standard String.trim did not yield the same result as java's String#trim().", value
1015:                                 .trim(), result);
1016:         }
1017:
1018:         /**
1019:          * Tests the behavior of the environment when calling for an undefined operation.
1020:          * <p>
1021:          * Expects an {@link UnsupportedOperationException} to be thrown with an accurate error message.
1022:          * </p>
1023:          */
1024:         @Test
1025:         public void testUndefinedOperation() {
1026:                 final EOperation operation = EcoreFactory.eINSTANCE.createEOperation();
1027:                 operation.setName("undefinedOperation");
1028:                 operation.setEType(EcorePackage.eINSTANCE.getEString());
1029:                 final EAnnotation acceleoAnnotation = EcoreFactory.eINSTANCE.createEAnnotation();
1030:                 acceleoAnnotation.setSource("Acceleo non-standard");
1031:                 operation.getEAnnotations().add(acceleoAnnotation);
1032:
1033:                 try {
1034:                         AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment, operation,
1035:                                         "source");
1036:                         fail("Expected Unsupported Operation hasn't been thrown by the evaluation environment.");
1037:                 } catch (UnsupportedOperationException e) {
1038:                         // Expected behavior
1039:                         final String expectedErrMsg = "undefinedOperation()";
1040:                         assertTrue("Exception hasn't been affected an accurate error message", e.getMessage().contains(
1041:                                         expectedErrMsg));
1042:                 }
1043:
1044:                 try {
1045:                         AcceleoLibraryOperationVisitor.callNonStandardOperation(evaluationEnvironment, operation,
1046:                                         "source", "arg1", "arg2");
1047:                         fail("Expected Unsupported Operation hasn't been thrown by the evaluation environment.");
1048:                 } catch (UnsupportedOperationException e) {
1049:                         // Expected behavior
1050:                         final String expectedErrMsg = "undefinedOperation(String, String)";
1051:                         assertTrue("Exception hasn't been affected an accurate error message", e.getMessage().contains(
1052:                                         expectedErrMsg));
1053:                 }
1054:         }
1055:
1056:         /**
1057:          * Returns the operation named <code>operationName</code> registered against the type
1058:          * <code>typeName</code> in the standard library.
1059:          *
1060:          * @param typeName
1061:          * Name of the classifier we seek an operation of.
1062:          * @return The sought operation.
1063:          */
1064:         private EOperation getOperation(String typeName, String operationName) {
1065:                 final List<EOperation> candidates = nonStdLib.get(typeName);
1066:•                for (EOperation candidate : candidates) {
1067:•                        if (candidate.getName().equals(operationName)) {
1068:                                 return candidate;
1069:                         }
1070:                 }
1071:                 // not guarded
1072:                 return null;
1073:         }
1074: }