View Javadoc
1   package de.fhdw.wtf.walker.tasks.test;
2   
3   import static org.junit.Assert.assertEquals;
4   import static org.junit.Assert.assertNotNull;
5   import static org.junit.Assert.assertTrue;
6   
7   import java.util.ArrayList;
8   import java.util.Collection;
9   import java.util.Iterator;
10  import java.util.List;
11  import java.util.concurrent.ExecutionException;
12  
13  import org.junit.Test;
14  
15  import de.fhdw.wtf.common.ast.Attribute;
16  import de.fhdw.wtf.common.ast.GroupElement;
17  import de.fhdw.wtf.common.ast.Model;
18  import de.fhdw.wtf.common.ast.Operation;
19  import de.fhdw.wtf.common.ast.type.BaseType;
20  import de.fhdw.wtf.common.ast.type.ClassType;
21  import de.fhdw.wtf.common.ast.type.ListType;
22  import de.fhdw.wtf.common.ast.type.MapType;
23  import de.fhdw.wtf.common.ast.type.ProductElementType;
24  import de.fhdw.wtf.common.ast.type.ProductType;
25  import de.fhdw.wtf.common.ast.type.SumType;
26  import de.fhdw.wtf.common.ast.type.Type;
27  import de.fhdw.wtf.common.ast.type.TypeProxy;
28  import de.fhdw.wtf.common.exception.parser.NoValidTokenStreamException;
29  import de.fhdw.wtf.common.exception.walker.CyclicDependencyException;
30  import de.fhdw.wtf.common.stream.FilteredTokenStream;
31  import de.fhdw.wtf.common.stream.SimpleScannerInput;
32  import de.fhdw.wtf.common.stream.TokenStream;
33  import de.fhdw.wtf.common.task.TaskExecutorFixed;
34  import de.fhdw.wtf.common.task.result.ExceptionalTaskResult;
35  import de.fhdw.wtf.common.task.result.OKTaskResult;
36  import de.fhdw.wtf.common.task.result.TaskResult;
37  import de.fhdw.wtf.common.task.result.visitor.TaskResultVisitor;
38  import de.fhdw.wtf.dsl.scanner.common.Scanner;
39  import de.fhdw.wtf.dsl.scanner.modelScanner.ModelDslScanner;
40  import de.fhdw.wtf.parser.Parser;
41  import de.fhdw.wtf.walker.tasks.CyclicInheritanceCheck;
42  import de.fhdw.wtf.walker.tasks.PrototypesTask;
43  import de.fhdw.wtf.walker.tasks.SubtypesFillTask;
44  import de.fhdw.wtf.walker.tasks.TypeReferencer;
45  import de.fhdw.wtf.walker.walker.HelperUtils;
46  import de.fhdw.wtf.walker.walker.SimpleWalkerTask;
47  
48  /**
49   * Tests that every {@link Type} has a prototype so that no duplicates are used.
50   */
51  public class TestPrototypesTask {
52  	
53  	/**
54  	 * Scanner, Parser, TypeReferencer und PrototypesTask laufen durch und liefern das Model.
55  	 * 
56  	 * @param input
57  	 * @return
58  	 * @throws CyclicDependencyException
59  	 * @throws InterruptedException
60  	 * @throws ExecutionException
61  	 * @throws NoValidTokenStreamException
62  	 */
63  	private Model getModel(final SimpleScannerInput input) throws CyclicDependencyException, InterruptedException,
64  			ExecutionException, NoValidTokenStreamException {
65  		final TokenStream output = FilteredTokenStream.create();
66  		final Scanner scanner = ModelDslScanner.create();
67  		scanner.scan(input, output);
68  		final Parser parser = Parser.create(output);
69  		Model model = null;
70  		model = parser.parse();
71  		assertEquals(0, parser.getExceptions().size());
72  		
73  		final TaskExecutorFixed taskmanager = TaskExecutorFixed.create();
74  		final SimpleWalkerTask referencer = TypeReferencer.create(model, taskmanager);
75  		final SimpleWalkerTask prototypesTask = PrototypesTask.create(model, taskmanager);
76  		final SimpleWalkerTask subtypesFillTask = SubtypesFillTask.create(model, taskmanager);
77  		final SimpleWalkerTask cyclicInheritance = CyclicInheritanceCheck.create(model, taskmanager);
78  		cyclicInheritance.addDependency(referencer);
79  		subtypesFillTask.addDependency(cyclicInheritance);
80  		prototypesTask.addDependency(subtypesFillTask);
81  		taskmanager.startAllKnownTasks();
82  		
83  		final Collection<OKTaskResult> okResult = new ArrayList<>();
84  		final Collection<ExceptionalTaskResult> failResult = new ArrayList<>();
85  		final Collection<TaskResult> results = taskmanager.getResultsAndShutdown();
86  		for (final TaskResult current : results) {
87  			current.accept(new TaskResultVisitor() {
88  				
89  				@Override
90  				public void handleOkTaskResult(final OKTaskResult result) {
91  					okResult.add(result);
92  				}
93  				
94  				@Override
95  				public void handleExceptionalTaskResult(final ExceptionalTaskResult result) {
96  					failResult.add(result);
97  				}
98  			});
99  		}
100 		
101 		assertEquals(4, okResult.size());
102 		assertEquals(0, failResult.size());
103 		
104 		return model;
105 	}
106 	
107 	/**
108 	 * Group:group=[Class:class={Attribute:(name:String,count:Integer)*; Attribute2:(name:String,count:Integer)*;};]; .
109 	 * 
110 	 * @throws Exception
111 	 */
112 	@Test
113 	public void testTwoListsOfTheSameProduct() throws Exception {
114 		final SimpleScannerInput input =
115 				new SimpleScannerInput("Group:group=[Class:class={Attribute:(name:String,count:Integer)*; "
116 						+ "Attribute2:(name:String,count:Integer)*;};];");
117 		final Model model = this.getModel(input);
118 		
119 		assertTrue(model.getString().getPrototype() == model.getString());
120 		assertTrue(model.getInteger().getPrototype() == model.getInteger());
121 		
122 		final ClassType cls = (ClassType) model.getGroups().iterator().next().getGroupElements().iterator().next();
123 		
124 		assertTrue(cls.getPrototype() == cls);
125 		
126 		final Iterator<Attribute> iterator = cls.getAttributes().iterator();
127 		final Attribute attribute_1 = iterator.next();
128 		final Attribute attribute_2 = iterator.next();
129 		
130 		assertTrue(((ListType) attribute_1.getAttrType()).getPrototype() != null
131 				&& ((ListType) attribute_1.getAttrType()).getPrototype() == ((ListType) attribute_2.getAttrType())
132 						.getPrototype());
133 		assertTrue(((ProductType) ((ListType) attribute_1.getAttrType()).getOf()).getPrototype() != null
134 				&& ((ProductType) ((ListType) attribute_1.getAttrType()).getOf()).getPrototype() == ((ProductType) ((ListType) attribute_2
135 						.getAttrType()).getOf()).getPrototype());
136 		
137 		final ProductType productPrototype =
138 				((ProductType) ((ListType) attribute_1.getAttrType()).getOf()).getPrototype();
139 		final ProductType productOrig = (ProductType) ((ListType) attribute_1.getAttrType()).getOf();
140 		final Iterator<ProductElementType> iteratorPrototyp = productPrototype.getElements().iterator();
141 		for (final ProductElementType current : productOrig.sortElements()) {
142 			assertTrue(current.equals(iteratorPrototyp.next()));
143 		}
144 		
145 		final ProductType productOrig2 = (ProductType) ((ListType) attribute_2.getAttrType()).getOf();
146 		final Iterator<ProductElementType> iteratorPrototyp2 = productPrototype.getElements().iterator();
147 		for (final ProductElementType current : productOrig2.sortElements()) {
148 			assertTrue(current.equals(iteratorPrototyp2.next()));
149 		}
150 		
151 		assertTrue(productOrig.getAbstractPrototype() != null);
152 		assertTrue(productOrig2.getAbstractPrototype() != null);
153 		assertTrue(productPrototype.getAbstractPrototype() != null);
154 		assertTrue(productOrig.getAbstractPrototype() == productOrig2.getAbstractPrototype());
155 		assertTrue(productPrototype.getAbstractPrototype() == productOrig.getAbstractPrototype());
156 		assertTrue(productPrototype.getAbstractPrototype() == productPrototype.getAbstractPrototype()
157 				.getAbstractPrototype());
158 		assertTrue(productPrototype.getAbstractPrototype() == productPrototype.getAbstractPrototype().getPrototype());
159 	}
160 	
161 	/**
162 	 * Group:group=[Class:class={Attribute:String;};]; .
163 	 * 
164 	 * @throws Exception
165 	 */
166 	@Test
167 	public void testAnything() throws Exception {
168 		final SimpleScannerInput input = new SimpleScannerInput("Group:group=[Class:class={Attribute:String;};];");
169 		final Model model = this.getModel(input);
170 		
171 		assertTrue(model.getString().getPrototype() == model.getString());
172 		assertTrue(model.getInteger().getPrototype() == model.getInteger());
173 		
174 		assertTrue(model.getAnything().getPrototype() != null);
175 	}
176 	
177 	/**
178 	 * Group:group=[Class:class={Attribute:{Anything,String};};]; .
179 	 * 
180 	 * @throws Exception
181 	 */
182 	@Test
183 	public void testAnything2() throws Exception {
184 		final SimpleScannerInput input =
185 				new SimpleScannerInput("Group:group=[Class:class={Attribute:{Anything,String};};];");
186 		final Model model = this.getModel(input);
187 		
188 		assertTrue(model.getString().getPrototype() == model.getString());
189 		assertTrue(model.getInteger().getPrototype() == model.getInteger());
190 		
191 		assertTrue(model.getAnything().getPrototype() != null);
192 		
193 		final ClassType cls = (ClassType) model.getGroups().iterator().next().getGroupElements().iterator().next();
194 		
195 		assertTrue(cls.getPrototype() == cls);
196 		
197 		final Iterator<Attribute> attributes = cls.getAttributes().iterator();
198 		final Attribute attribute_1 = attributes.next();
199 		
200 		assertTrue(attribute_1.getAttrType() instanceof SumType);
201 		final SumType sum = (SumType) attribute_1.getAttrType();
202 		assertTrue(sum.getPrototype() != null);
203 		assertTrue(model.getAnything().getPrototype() == sum.getPrototype());
204 	}
205 	
206 	/**
207 	 * Group:group=[Class:class={Attribute:Anything;};]; .
208 	 * 
209 	 * @throws Exception
210 	 *             Exception
211 	 */
212 	@Test
213 	public void testAnything3() throws Exception {
214 		final SimpleScannerInput input = new SimpleScannerInput("Group:group=[Class:class={Attribute:Anything;};];");
215 		final Model model = this.getModel(input);
216 		
217 		assertTrue(model.getString().getPrototype() == model.getString());
218 		assertTrue(model.getInteger().getPrototype() == model.getInteger());
219 		
220 		assertTrue(model.getAnything().getPrototype() != null);
221 	}
222 	
223 	/**
224 	 * Group:group=[Class:class={Attribute1:[Integer->String]; Attribute2:(name:String, count:Integer);
225 	 * Attribute3:[Integer->String];};]; .
226 	 * 
227 	 * @throws Exception
228 	 */
229 	@Test
230 	public void testTwoEqualMapsAndOneOtherType() throws Exception {
231 		final SimpleScannerInput input =
232 				new SimpleScannerInput("Group:group=[Class:class={Attribute1:[Integer->String]; "
233 						+ "Attribute2:(name:String, count:Integer); Attribute3:[Integer->String];};];");
234 		final Model model = this.getModel(input);
235 		
236 		assertTrue(model.getString().getPrototype() == model.getString());
237 		assertTrue(model.getInteger().getPrototype() == model.getInteger());
238 		
239 		final ClassType cls = (ClassType) model.getGroups().iterator().next().getGroupElements().iterator().next();
240 		
241 		assertTrue(cls.getPrototype() == cls);
242 		
243 		final Iterator<Attribute> attributes = cls.getAttributes().iterator();
244 		final Attribute attribute_1 = attributes.next();
245 		final Attribute attribute_2 = attributes.next();
246 		final Attribute attribute_3 = attributes.next();
247 		
248 		assertTrue(attribute_1.getAttrType() instanceof MapType);
249 		final MapType map1 = (MapType) attribute_1.getAttrType();
250 		assertTrue(attribute_2.getAttrType() instanceof ProductType);
251 		final ProductType product = (ProductType) attribute_2.getAttrType();
252 		assertTrue(attribute_3.getAttrType() instanceof MapType);
253 		final MapType map3 = (MapType) attribute_3.getAttrType();
254 		
255 		assertTrue(map1.getPrototype() == map3.getPrototype());
256 		assertNotNull(product.getPrototype());
257 	}
258 	
259 	/**
260 	 * Group:group=[Class:class={Attribute1:{String, Integer}; Attribute2:{Integer, String};};]; .
261 	 * 
262 	 * @throws Exception
263 	 */
264 	@Test
265 	public void testTwoEqualSums() throws Exception {
266 		final SimpleScannerInput input =
267 				new SimpleScannerInput(
268 						"Group:group=[Class:class={Attribute1:{String, Integer}; Attribute2:{Integer, String};};];");
269 		final Model model = this.getModel(input);
270 		
271 		assertTrue(model.getString().getPrototype() == model.getString());
272 		assertTrue(model.getInteger().getPrototype() == model.getInteger());
273 		
274 		final ClassType cls = (ClassType) model.getGroups().iterator().next().getGroupElements().iterator().next();
275 		
276 		assertTrue(cls.getPrototype() == cls);
277 		
278 		final Iterator<Attribute> attributes = cls.getAttributes().iterator();
279 		final Attribute attribute_1 = attributes.next();
280 		final Attribute attribute_2 = attributes.next();
281 		
282 		assertTrue(attribute_1.getAttrType() instanceof SumType);
283 		final SumType sum1 = (SumType) attribute_1.getAttrType();
284 		assertTrue(attribute_2.getAttrType() instanceof SumType);
285 		final SumType sum2 = (SumType) attribute_2.getAttrType();
286 		
287 		assertTrue(sum1.getPrototype() == sum2.getPrototype());
288 		
289 		final List<Type> sorted = sum1.sortElements();
290 		assertEquals(sorted, ((SumType) sum2.getPrototype()).getElements());
291 	}
292 	
293 	/**
294 	 * Group:group=[Class:class={Attribute1:{Integer};};]; .
295 	 * 
296 	 * @throws Exception
297 	 *             possible Exception
298 	 */
299 	@Test
300 	public void testSumWithOneElementAtBeginningInteger() throws Exception {
301 		final SimpleScannerInput input = new SimpleScannerInput("Group:group=[Class:class={Attribute1:{Integer};};];");
302 		final Model model = this.getModel(input);
303 		
304 		assertTrue(model.getString().getPrototype() == model.getString());
305 		assertTrue(model.getInteger().getPrototype() == model.getInteger());
306 		
307 		final ClassType cls = (ClassType) model.getGroups().iterator().next().getGroupElements().iterator().next();
308 		
309 		assertTrue(cls.getPrototype() == cls);
310 		
311 		final Iterator<Attribute> attributes = cls.getAttributes().iterator();
312 		final Attribute attribute1 = attributes.next();
313 		
314 		assertTrue(attribute1.getAttrType() instanceof SumType);
315 		final SumType sum = (SumType) attribute1.getAttrType();
316 		
317 		assertTrue(sum.getPrototype() instanceof BaseType);
318 		final BaseType integer = (BaseType) sum.getPrototype();
319 		
320 		assertTrue(integer == model.getInteger());
321 		// String,Integer,Class
322 		assertEquals(3, ((SumType) model.getAnything().getPrototype()).getElements().size());
323 	}
324 	
325 	/**
326 	 * Group:group=[Class:class={Attribute1:{String};};]; .
327 	 * 
328 	 * @throws Exception
329 	 *             possible Exception
330 	 */
331 	@Test
332 	public void testSumWithOneElementAtBeginningString() throws Exception {
333 		final SimpleScannerInput input = new SimpleScannerInput("Group:group=[Class:class={Attribute1:{String};};];");
334 		final Model model = this.getModel(input);
335 		
336 		assertTrue(model.getString().getPrototype() == model.getString());
337 		assertTrue(model.getInteger().getPrototype() == model.getInteger());
338 		
339 		final ClassType cls = (ClassType) model.getGroups().iterator().next().getGroupElements().iterator().next();
340 		
341 		assertTrue(cls.getPrototype() == cls);
342 		
343 		final Iterator<Attribute> attributes = cls.getAttributes().iterator();
344 		final Attribute attribute1 = attributes.next();
345 		
346 		assertTrue(attribute1.getAttrType() instanceof SumType);
347 		final SumType sum = (SumType) attribute1.getAttrType();
348 		
349 		assertTrue(sum.getPrototype() instanceof BaseType);
350 		final BaseType string = (BaseType) sum.getPrototype();
351 		
352 		assertTrue(string == model.getString());
353 		// String,Integer,Class
354 		assertEquals(3, ((SumType) model.getAnything().getPrototype()).getElements().size());
355 	}
356 	
357 	/**
358 	 * Group:group=[Class:class={Attribute1:{Class};};]; .
359 	 * 
360 	 * @throws Exception
361 	 *             possible Exception
362 	 */
363 	@Test
364 	public void testSumWithOneElementAtBeginningOneClass() throws Exception {
365 		final SimpleScannerInput input = new SimpleScannerInput("Group:group=[Class:class={Attribute1:{Class};};];");
366 		final Model model = this.getModel(input);
367 		
368 		assertTrue(model.getString().getPrototype() == model.getString());
369 		assertTrue(model.getInteger().getPrototype() == model.getInteger());
370 		
371 		final ClassType cls = (ClassType) model.getGroups().iterator().next().getGroupElements().iterator().next();
372 		
373 		assertTrue(cls.getPrototype() == cls);
374 		
375 		final Iterator<Attribute> attributes = cls.getAttributes().iterator();
376 		final Attribute attribute1 = attributes.next();
377 		
378 		assertTrue(attribute1.getAttrType() instanceof SumType);
379 		final SumType sum = (SumType) attribute1.getAttrType();
380 		
381 		assertTrue(sum.getPrototype() == cls);
382 		// String,Integer,Class
383 		assertEquals(3, ((SumType) model.getAnything().getPrototype()).getElements().size());
384 	}
385 	
386 	/**
387 	 * Group:group=[Class:class={Attribute1:{{Class}};};]; .
388 	 * 
389 	 * @throws Exception
390 	 *             possible Exception
391 	 */
392 	@Test
393 	public void testSumWithOneElementAtBeginningOneSumWithOneClass() throws Exception {
394 		final SimpleScannerInput input = new SimpleScannerInput("Group:group=[Class:class={Attribute1:{{Class}};};];");
395 		final Model model = this.getModel(input);
396 		
397 		assertTrue(model.getString().getPrototype() == model.getString());
398 		assertTrue(model.getInteger().getPrototype() == model.getInteger());
399 		
400 		final ClassType cls = (ClassType) model.getGroups().iterator().next().getGroupElements().iterator().next();
401 		
402 		assertTrue(cls.getPrototype() == cls);
403 		
404 		final Iterator<Attribute> attributes = cls.getAttributes().iterator();
405 		final Attribute attribute1 = attributes.next();
406 		
407 		assertTrue(attribute1.getAttrType() instanceof SumType);
408 		final SumType sum = (SumType) attribute1.getAttrType();
409 		
410 		assertTrue(sum.getPrototype() == cls);
411 		// String,Integer,Class
412 		assertEquals(3, ((SumType) model.getAnything().getPrototype()).getElements().size());
413 	}
414 	
415 	/**
416 	 * Group:group=[Class:class={Attribute1:{String*}; Attribute2:String*;};]; .
417 	 * 
418 	 * @throws Exception
419 	 *             possible Exception
420 	 */
421 	@Test
422 	public void testSumWithOneElementAtBeginningOneList() throws Exception {
423 		final SimpleScannerInput input =
424 				new SimpleScannerInput("Group:group=[Class:class={Attribute1:{String*}; Attribute2:String*;};];");
425 		final Model model = this.getModel(input);
426 		
427 		assertTrue(model.getString().getPrototype() == model.getString());
428 		assertTrue(model.getInteger().getPrototype() == model.getInteger());
429 		
430 		final ClassType cls = (ClassType) model.getGroups().iterator().next().getGroupElements().iterator().next();
431 		
432 		assertTrue(cls.getPrototype() == cls);
433 		
434 		final Iterator<Attribute> attributes = cls.getAttributes().iterator();
435 		final Attribute attribute1 = attributes.next();
436 		final Attribute attribute2 = attributes.next();
437 		
438 		assertTrue(attribute1.getAttrType() instanceof SumType);
439 		final SumType sum = (SumType) attribute1.getAttrType();
440 		
441 		assertTrue(sum.getPrototype() instanceof ListType);
442 		final ListType list = (ListType) sum.getPrototype();
443 		
444 		assertTrue(list.getPrototype() == list);
445 		assertTrue(list == ((ListType) attribute2.getAttrType()).getPrototype());
446 		// String,Integer,Class and the List
447 		assertEquals(4, ((SumType) model.getAnything().getPrototype()).getElements().size());
448 	}
449 	
450 	/**
451 	 * Group:group=[Class:class={Attribute1:{(name:String,alter:Integer)}; Attribute2:(name:String,alter:Integer);};]; .
452 	 * 
453 	 * @throws Exception
454 	 *             possible Exception
455 	 */
456 	@Test
457 	public void testSumWithOneElementAtBeginningOneProduct() throws Exception {
458 		final SimpleScannerInput input =
459 				new SimpleScannerInput("Group:group=[Class:class={Attribute1:{(name:String,alter:Integer)}; "
460 						+ "Attribute2:(name:String,alter:Integer);};];");
461 		final Model model = this.getModel(input);
462 		
463 		assertTrue(model.getString().getPrototype() == model.getString());
464 		assertTrue(model.getInteger().getPrototype() == model.getInteger());
465 		
466 		final ClassType cls = (ClassType) model.getGroups().iterator().next().getGroupElements().iterator().next();
467 		
468 		assertTrue(cls.getPrototype() == cls);
469 		
470 		final Iterator<Attribute> attributes = cls.getAttributes().iterator();
471 		final Attribute attribute1 = attributes.next();
472 		final Attribute attribute2 = attributes.next();
473 		
474 		assertTrue(attribute1.getAttrType() instanceof SumType);
475 		final SumType sum = (SumType) attribute1.getAttrType();
476 		
477 		assertTrue(sum.getPrototype() instanceof ProductType);
478 		final ProductType product = (ProductType) sum.getPrototype();
479 		
480 		assertTrue(product.getPrototype() == product);
481 		assertTrue(product == ((ProductType) attribute2.getAttrType()).getPrototype());
482 		
483 		// String,Integer,Class and the Product + abstr. Product
484 		assertEquals(5, ((SumType) model.getAnything().getPrototype()).getElements().size());
485 	}
486 	
487 	/**
488 	 * Group:group=[Class:class={Attribute1:{[String->Integer]}; Attribute2:[String->Integer];};]; .
489 	 * 
490 	 * @throws Exception
491 	 *             possible Exception
492 	 */
493 	@Test
494 	public void testSumWithOneElementAtBeginningOneMap() throws Exception {
495 		final SimpleScannerInput input =
496 				new SimpleScannerInput("Group:group=[Class:class={Attribute1:{[String->Integer]};"
497 						+ " Attribute2:[String->Integer];};];");
498 		final Model model = this.getModel(input);
499 		
500 		assertTrue(model.getString().getPrototype() == model.getString());
501 		assertTrue(model.getInteger().getPrototype() == model.getInteger());
502 		
503 		final ClassType cls = (ClassType) model.getGroups().iterator().next().getGroupElements().iterator().next();
504 		
505 		assertTrue(cls.getPrototype() == cls);
506 		
507 		final Iterator<Attribute> attributes = cls.getAttributes().iterator();
508 		final Attribute attribute1 = attributes.next();
509 		final Attribute attribute2 = attributes.next();
510 		
511 		assertTrue(attribute1.getAttrType() instanceof SumType);
512 		final SumType sum = (SumType) attribute1.getAttrType();
513 		
514 		assertTrue(sum.getPrototype() instanceof MapType);
515 		final MapType product = (MapType) sum.getPrototype();
516 		
517 		assertTrue(product.getPrototype() == product);
518 		assertTrue(product == ((MapType) attribute2.getAttrType()).getPrototype());
519 		// String,Integer,Class and the Map
520 		assertEquals(4, ((SumType) model.getAnything().getPrototype()).getElements().size());
521 	}
522 	
523 	/**
524 	 * Group:group=[Class:class={Attribute1:{Class};};]; .
525 	 * 
526 	 * @throws Exception
527 	 *             possible Exception
528 	 */
529 	@Test
530 	public void testSumWithOneElementAtBeginningOneClassAfterStandardize() throws Exception {
531 		final SimpleScannerInput input =
532 				new SimpleScannerInput("Group:group=[Class:class={Attribute1:{Class,Class2};};"
533 						+ " Class2:class=Class+{};];");
534 		final Model model = this.getModel(input);
535 		
536 		assertTrue(model.getString().getPrototype() == model.getString());
537 		assertTrue(model.getInteger().getPrototype() == model.getInteger());
538 		
539 		final ClassType cls = (ClassType) model.getGroups().iterator().next().getGroupElements().iterator().next();
540 		
541 		assertTrue(cls.getPrototype() == cls);
542 		
543 		final Iterator<Attribute> attributes = cls.getAttributes().iterator();
544 		final Attribute attribute1 = attributes.next();
545 		
546 		assertTrue(attribute1.getAttrType() instanceof SumType);
547 		final SumType sum = (SumType) attribute1.getAttrType();
548 		
549 		assertTrue(sum.getPrototype() == cls);
550 		// String,Integer,Class
551 		assertEquals(3, ((SumType) model.getAnything().getPrototype()).getElements().size());
552 	}
553 	
554 	/**
555 	 * Group:group=[Class1:class={Attribute7:String*;}; Class2:class={Attribute1:{Class1, Integer}; Attribute2:{Class1,
556 	 * String}; Attribute3:String* Attribute4:String* Attribute5:{Integer, Class1} Attribute6:{String, Class1}}; };]; .
557 	 * 
558 	 * @throws Exception
559 	 */
560 	@Test
561 	public void testMoreEqualTypes() throws Exception {
562 		final SimpleScannerInput input =
563 				new SimpleScannerInput(
564 						"Group:group=[Class1:class={Attribute7:String*;}; Class2:class={Attribute1:{Class1, Integer}; "
565 								+ "Attribute2:{Class1, String}; Attribute3:String*; Attribute4:String*; "
566 								+ "Attribute5:{Integer, Class1}; Attribute6:{String, Class1}; };];");
567 		final Model model = this.getModel(input);
568 		
569 		assertTrue(model.getString().getPrototype() == model.getString());
570 		assertTrue(model.getInteger().getPrototype() == model.getInteger());
571 		
572 		final Iterator<GroupElement> groupElementIterator =
573 				model.getGroups().iterator().next().getGroupElements().iterator();
574 		final ClassType class1 = (ClassType) groupElementIterator.next();
575 		
576 		assertTrue(class1.getPrototype() == class1);
577 		
578 		final ClassType class2 = (ClassType) groupElementIterator.next();
579 		
580 		assertTrue(class2.getPrototype() == class2);
581 		
582 		final Iterator<Attribute> attributesClass1 = class1.getAttributes().iterator();
583 		final ListType attribute7 = (ListType) attributesClass1.next().getAttrType();
584 		
585 		final Iterator<Attribute> attributesClass2 = class2.getAttributes().iterator();
586 		final SumType attribute1 = (SumType) attributesClass2.next().getAttrType();
587 		final SumType attribute2 = (SumType) attributesClass2.next().getAttrType();
588 		final ListType attribute3 = (ListType) attributesClass2.next().getAttrType();
589 		final ListType attribute4 = (ListType) attributesClass2.next().getAttrType();
590 		final SumType attribute5 = (SumType) attributesClass2.next().getAttrType();
591 		final SumType attribute6 = (SumType) attributesClass2.next().getAttrType();
592 		
593 		assertTrue(attribute1.getPrototype() == attribute5.getPrototype());
594 		assertTrue(attribute2.getPrototype() == attribute6.getPrototype());
595 		assertTrue(attribute3.getPrototype() == attribute4.getPrototype());
596 		assertTrue(attribute3.getPrototype() == attribute7.getPrototype());
597 		
598 		final List<Type> sorted1 = attribute1.sortElements();
599 		assertEquals(sorted1, ((SumType) attribute1.getPrototype()).getElements());
600 		final List<Type> sorted2 = attribute2.sortElements();
601 		assertEquals(sorted2, ((SumType) attribute2.getPrototype()).getElements());
602 	}
603 	
604 	/**
605 	 * Group:group=[Class:class={operation1:[[(test1:String, test2:String)->Integer*]]; operation2:[[(test1:String,
606 	 * test2:String)->Integer*]];};]; .
607 	 * 
608 	 * @throws Exception
609 	 */
610 	@Test
611 	public void testTwoOperationsWithSameParamsAndReturnValue() throws Exception {
612 		final SimpleScannerInput input =
613 				new SimpleScannerInput(
614 						" Group:group=[Class:class={operation1:[[(test1:String, test2:String)->Integer*]]; operation2:[[(test1:String, test2:String)->Integer*]];};];");
615 		final Model model = this.getModel(input);
616 		
617 		assertTrue(model.getString().getPrototype() == model.getString());
618 		assertTrue(model.getInteger().getPrototype() == model.getInteger());
619 		
620 		final Iterator<GroupElement> groupElementIterator =
621 				model.getGroups().iterator().next().getGroupElements().iterator();
622 		final ClassType cls = (ClassType) groupElementIterator.next();
623 		
624 		assertTrue(cls.getPrototype() == cls);
625 		
626 		final Iterator<Operation> operations = cls.getOperations().iterator();
627 		final Operation operation1 = operations.next();
628 		final Operation operation2 = operations.next();
629 		
630 		assertTrue(operation1.getParameters().getPrototype() == operation2.getParameters().getPrototype());
631 		assertTrue(operation1.getParameters().getPrototype() == operation2.getParameters().getPrototype());
632 	}
633 	
634 	/**
635 	 * Group:group=[Class:class={Attribute1:(sum1:{String, Integer}, sum2:{Integer, String}, map1:[String*->String*],
636 	 * map2:[String*->String*]); Attribute2:(sum1:{String, Integer}, sum2:{Integer, String}, map1:[String*->String*],
637 	 * map2:[String*->String*]);};]; .
638 	 * 
639 	 * @throws Exception
640 	 */
641 	@Test
642 	public void testTwoComplexAttributesWithSameType() throws Exception {
643 		final SimpleScannerInput input =
644 				new SimpleScannerInput("Group:group=[Class:class={Attribute1:(sum1:{String, Integer}, "
645 						+ "sum2:{Integer, String}, map1:[String*->String*], map2:[String*->String*]); "
646 						+ "Attribute2:(sum1:{String, Integer}, sum2:{Integer, String}, map1:[String*->String*], "
647 						+ "map2:[String*->String*]);};];");
648 		final Model model = this.getModel(input);
649 		
650 		assertTrue(model.getString().getPrototype() == model.getString());
651 		assertTrue(model.getInteger().getPrototype() == model.getInteger());
652 		
653 		final Iterator<GroupElement> groupElementIterator =
654 				model.getGroups().iterator().next().getGroupElements().iterator();
655 		final ClassType cls = (ClassType) groupElementIterator.next();
656 		
657 		assertTrue(cls.getPrototype() == cls);
658 		
659 		final Iterator<Attribute> attributes = cls.getAttributes().iterator();
660 		final ProductType product1 = (ProductType) attributes.next().getAttrType();
661 		final ProductType product2 = (ProductType) attributes.next().getAttrType();
662 		
663 		assertTrue(product1.getPrototype() == product2.getPrototype());
664 		
665 		final Iterator<ProductElementType> productElements1 = product1.getElements().iterator();
666 		final SumType sum11 = (SumType) productElements1.next().getType();
667 		final SumType sum12 = (SumType) productElements1.next().getType();
668 		final MapType map11 = (MapType) productElements1.next().getType();
669 		final MapType map12 = (MapType) productElements1.next().getType();
670 		
671 		assertTrue(sum11.getPrototype() == sum12.getPrototype());
672 		assertTrue(map11.getPrototype() == map12.getPrototype());
673 		
674 		final Iterator<ProductElementType> productElements2 = product2.getElements().iterator();
675 		final SumType sum21 = (SumType) productElements2.next().getType();
676 		final SumType sum22 = (SumType) productElements2.next().getType();
677 		final MapType map21 = (MapType) productElements2.next().getType();
678 		final MapType map22 = (MapType) productElements2.next().getType();
679 		
680 		assertTrue(sum21.getPrototype() == sum22.getPrototype());
681 		assertTrue(map12.getPrototype() == map22.getPrototype());
682 		assertTrue(sum11.getPrototype() == sum21.getPrototype());
683 		assertTrue(sum12.getPrototype() == sum22.getPrototype());
684 		assertTrue(map11.getPrototype() == map21.getPrototype());
685 		assertTrue(map12.getPrototype() == map22.getPrototype());
686 	}
687 	
688 	/**
689 	 * Group:group=[Class:class={Attribute1:Class;};]; .
690 	 * 
691 	 * @throws Exception
692 	 *             possible Exception
693 	 */
694 	@Test
695 	public void testTypeProxy() throws Exception {
696 		final SimpleScannerInput input = new SimpleScannerInput("Group:group=[Class:class={Attribute1:Class;};];");
697 		final Model model = this.getModel(input);
698 		
699 		assertTrue(model.getString().getPrototype() == model.getString());
700 		assertTrue(model.getInteger().getPrototype() == model.getInteger());
701 		
702 		final ClassType cls = (ClassType) model.getGroups().iterator().next().getGroupElements().iterator().next();
703 		
704 		assertTrue(cls.getPrototype() == cls);
705 		
706 		final Iterator<Attribute> attributes = cls.getAttributes().iterator();
707 		final Attribute attribute1 = attributes.next();
708 		
709 		assertTrue(attribute1.getAttrType() instanceof TypeProxy);
710 		final TypeProxy typeProxy = (TypeProxy) attribute1.getAttrType();
711 		
712 		assertTrue(typeProxy.getPrototype() == typeProxy);
713 		
714 		assertTrue(HelperUtils.getTargetType(typeProxy) == cls);
715 	}
716 	
717 	/**
718 	 * Group:group=[Class:class={Attribute:(name:String,count:Integer); Attribute2:(p1:String,p2:Integer);};]; .
719 	 * 
720 	 * @throws Exception
721 	 *             Exception
722 	 */
723 	@Test
724 	public void testProduct() throws Exception {
725 		final SimpleScannerInput input =
726 				new SimpleScannerInput("Group:group=[Class:class={Attribute:(name:String,count:Integer); "
727 						+ "Attribute2:(p1:String,p2:Integer);};];");
728 		final Model model = this.getModel(input);
729 		
730 		assertTrue(model.getString().getPrototype() == model.getString());
731 		assertTrue(model.getInteger().getPrototype() == model.getInteger());
732 		
733 		final ClassType cls = (ClassType) model.getGroups().iterator().next().getGroupElements().iterator().next();
734 		
735 		assertTrue(cls.getPrototype() == cls);
736 		
737 		final Iterator<Attribute> iterator = cls.getAttributes().iterator();
738 		final Attribute attribute1 = iterator.next();
739 		final Attribute attribute2 = iterator.next();
740 		
741 		assertTrue(attribute1.getAttrType().getPrototype() != null);
742 		assertTrue(attribute2.getAttrType().getPrototype() != null);
743 		
744 		final ProductType product1 = (ProductType) attribute1.getAttrType();
745 		final ProductType product2 = (ProductType) attribute2.getAttrType();
746 		
747 		assertTrue(product1.getAbstractPrototype() != null);
748 		assertTrue(product2.getAbstractPrototype() != null);
749 		
750 		assertTrue(product1.getPrototype() != null);
751 		assertTrue(product2.getPrototype() != null);
752 		
753 		assertTrue(product1.getAbstractPrototype() == product1.getPrototype().getAbstractPrototype());
754 		assertTrue(product2.getAbstractPrototype() == product2.getPrototype().getAbstractPrototype());
755 		
756 		assertTrue(product1.getAbstractPrototype() == product2.getAbstractPrototype());
757 	}
758 	
759 	/**
760 	 * Group:group=[Class:class={Attribute:(p1:String,p2:Integer);};]; .
761 	 * 
762 	 * @throws Exception
763 	 *             Exception
764 	 */
765 	@Test
766 	public void testProduct2() throws Exception {
767 		final SimpleScannerInput input =
768 				new SimpleScannerInput("Group:group=[Class:class={Attribute:(p1:String,p2:Integer); };];");
769 		final Model model = this.getModel(input);
770 		
771 		assertTrue(model.getString().getPrototype() == model.getString());
772 		assertTrue(model.getInteger().getPrototype() == model.getInteger());
773 		
774 		final ClassType cls = (ClassType) model.getGroups().iterator().next().getGroupElements().iterator().next();
775 		
776 		assertTrue(cls.getPrototype() == cls);
777 		
778 		final Iterator<Attribute> iterator = cls.getAttributes().iterator();
779 		final Attribute attribute1 = iterator.next();
780 		
781 		assertTrue(attribute1.getAttrType().getPrototype() != null);
782 		
783 		final ProductType product1 = (ProductType) attribute1.getAttrType();
784 		
785 		assertTrue(product1.getAbstractPrototype() != null);
786 		assertTrue(product1.getPrototype() != null);
787 		
788 		assertTrue(product1.getAbstractPrototype() == product1.getPrototype().getAbstractPrototype());
789 	}
790 }