View Javadoc
1   package de.fhdw.wtf.parser.test;
2   
3   import static org.junit.Assert.assertEquals;
4   import static org.junit.Assert.assertTrue;
5   import static org.junit.Assert.fail;
6   
7   import java.util.Iterator;
8   import java.util.Vector;
9   
10  import org.junit.Before;
11  import org.junit.Test;
12  
13  import de.fhdw.wtf.common.ast.Attribute;
14  import de.fhdw.wtf.common.ast.Constructor;
15  import de.fhdw.wtf.common.ast.Group;
16  import de.fhdw.wtf.common.ast.GroupElement;
17  import de.fhdw.wtf.common.ast.Model;
18  import de.fhdw.wtf.common.ast.Name;
19  import de.fhdw.wtf.common.ast.Operation;
20  import de.fhdw.wtf.common.ast.UnqualifiedName;
21  import de.fhdw.wtf.common.ast.type.ByNameState;
22  import de.fhdw.wtf.common.ast.type.ClassModifier;
23  import de.fhdw.wtf.common.ast.type.ClassModifierAbstract;
24  import de.fhdw.wtf.common.ast.type.ClassModifierService;
25  import de.fhdw.wtf.common.ast.type.ClassModifierTransient;
26  import de.fhdw.wtf.common.ast.type.ClassModifierVisitable;
27  import de.fhdw.wtf.common.ast.type.ClassType;
28  import de.fhdw.wtf.common.ast.type.RegularClassType;
29  import de.fhdw.wtf.common.ast.type.Type;
30  import de.fhdw.wtf.common.ast.type.TypeProxy;
31  import de.fhdw.wtf.common.exception.parser.AbstractParserException;
32  import de.fhdw.wtf.common.exception.parser.ClassModifierAlreadyAddedException;
33  import de.fhdw.wtf.common.exception.parser.NoValidTokenStreamException;
34  import de.fhdw.wtf.common.stream.SimpleTokenStream;
35  import de.fhdw.wtf.common.stream.TokenStream;
36  import de.fhdw.wtf.common.token.EndToken;
37  import de.fhdw.wtf.common.token.IdentifierToken;
38  import de.fhdw.wtf.common.token.Position;
39  import de.fhdw.wtf.common.token.keywords.AbstractToken;
40  import de.fhdw.wtf.common.token.keywords.ClassToken;
41  import de.fhdw.wtf.common.token.keywords.GroupToken;
42  import de.fhdw.wtf.common.token.keywords.ServiceToken;
43  import de.fhdw.wtf.common.token.keywords.TransientToken;
44  import de.fhdw.wtf.common.token.keywords.VisitableToken;
45  import de.fhdw.wtf.common.token.symbols.ColonToken;
46  import de.fhdw.wtf.common.token.symbols.CurlyBracketCloseToken;
47  import de.fhdw.wtf.common.token.symbols.CurlyBracketOpenToken;
48  import de.fhdw.wtf.common.token.symbols.EqualToken;
49  import de.fhdw.wtf.common.token.symbols.PlusSymbolToken;
50  import de.fhdw.wtf.common.token.symbols.SemicolonToken;
51  import de.fhdw.wtf.common.token.symbols.SquareBracketCloseToken;
52  import de.fhdw.wtf.common.token.symbols.SquareBracketOpenToken;
53  import de.fhdw.wtf.parser.Parser;
54  
55  /**
56   * Tests the parsing of classes.
57   */
58  public class TestClasses {
59  	
60  	private Parser parser;
61  	private TokenStream stream;
62  	
63  	private IdentifierToken group1IdentifierToken;
64  	private IdentifierToken group2IdentifierToken;
65  	
66  	private IdentifierToken classIdentifierToken;
67  	private IdentifierToken superClass1IdentifierToken;
68  	private IdentifierToken superClass2IdentifierToken;
69  	
70  	private ColonToken colonToken;
71  	private GroupToken groupToken;
72  	private EqualToken equalToken;
73  	private SquareBracketOpenToken squareBracketOpenToken;
74  	private SquareBracketCloseToken squareBracketCloseToken;
75  	private SemicolonToken semicolonToken;
76  	private ClassToken classToken;
77  	private CurlyBracketOpenToken curlyBracketOpenToken;
78  	private CurlyBracketCloseToken curlyBracketCloseToken;
79  	private EndToken endToken;
80  	private AbstractToken abstractToken;
81  	private TransientToken transientToken;
82  	private ServiceToken serviceToken;
83  	private VisitableToken visitableToken;
84  	private PlusSymbolToken plusSymbolToken;
85  	
86  	/**
87  	 * Creates the most important Tokens.
88  	 * 
89  	 * @throws Exception
90  	 */
91  	@Before
92  	public void setUp() throws Exception {
93  		this.stream = SimpleTokenStream.create();
94  		this.parser = Parser.create(this.stream);
95  		
96  		this.group1IdentifierToken = IdentifierToken.create("Group", Position.create("", 0 + 1, 0 + 1, 0));
97  		this.group2IdentifierToken = IdentifierToken.create("Group", Position.create("", 0 + 1, 0 + 1, 0));
98  		this.classIdentifierToken = IdentifierToken.create("Class", Position.create("", 0 + 1, 0 + 1, 0));
99  		this.superClass1IdentifierToken = IdentifierToken.create("Superclass", Position.create("", 0 + 1, 0 + 1, 0));
100 		this.superClass2IdentifierToken = IdentifierToken.create("Superclass", Position.create("", 0 + 1, 0 + 1, 0));
101 		this.colonToken = ColonToken.create(Position.create("", 0 + 1, 0 + 1, 0));
102 		this.groupToken = GroupToken.create(Position.create("", 0 + 1, 0 + 1, 0));
103 		this.equalToken = EqualToken.create(Position.create("", 0 + 1, 0 + 1, 0));
104 		this.squareBracketOpenToken = SquareBracketOpenToken.create(Position.create("", 0 + 1, 0 + 1, 0));
105 		this.squareBracketCloseToken = SquareBracketCloseToken.create(Position.create("", 0 + 1, 0 + 1, 0));
106 		this.semicolonToken = SemicolonToken.create(Position.create("", 0 + 1, 0 + 1, 0));
107 		this.classToken = ClassToken.create(Position.create("", 0 + 1, 0 + 1, 0));
108 		this.curlyBracketOpenToken = CurlyBracketOpenToken.create(Position.create("", 0 + 1, 0 + 1, 0));
109 		this.curlyBracketCloseToken = CurlyBracketCloseToken.create(Position.create("", 0 + 1, 0 + 1, 0));
110 		this.endToken = EndToken.create(Position.create("", 0 + 1, 0 + 1, 0));
111 		this.abstractToken = AbstractToken.create(Position.create("", 0 + 1, 0 + 1, 0));
112 		this.transientToken = TransientToken.create(Position.create("", 0 + 1, 0 + 1, 0));
113 		this.serviceToken = ServiceToken.create(Position.create("", 0 + 1, 0 + 1, 0));
114 		this.visitableToken = VisitableToken.create(Position.create("", 0 + 1, 0 + 1, 0));
115 		this.plusSymbolToken = PlusSymbolToken.create(Position.create("", 0 + 1, 0 + 1, 0));
116 	}
117 	
118 	/**
119 	 * Group:group=[Class:class={};]; .
120 	 * 
121 	 * @throws Exception
122 	 */
123 	@Test
124 	public void testSimpleClass() throws Exception {
125 		this.stream.add(this.group1IdentifierToken);
126 		this.stream.add(this.colonToken);
127 		this.stream.add(this.groupToken);
128 		this.stream.add(this.equalToken);
129 		this.stream.add(this.squareBracketOpenToken);
130 		this.stream.add(this.classIdentifierToken);
131 		this.stream.add(this.colonToken);
132 		this.stream.add(this.classToken);
133 		this.stream.add(this.equalToken);
134 		this.stream.add(this.curlyBracketOpenToken);
135 		this.stream.add(this.curlyBracketCloseToken);
136 		this.stream.add(this.semicolonToken);
137 		this.stream.add(this.squareBracketCloseToken);
138 		this.stream.add(this.semicolonToken);
139 		this.stream.add(this.endToken);
140 		
141 		final Vector<GroupElement> groupVector = new Vector<>();
142 		
143 		final Name groupName = UnqualifiedName.create(this.group1IdentifierToken);
144 		final Group group = Group.create(groupName, groupVector, this.group1IdentifierToken);
145 		final Name className = groupName.addName(this.classIdentifierToken);
146 		final ClassType class1 =
147 				RegularClassType.create(
148 						className,
149 						new Vector<ClassModifier>(),
150 						new Vector<Attribute>(),
151 						new Vector<Type>(),
152 						new Vector<Operation>(),
153 						new Vector<Constructor>(),
154 						this.classIdentifierToken,
155 						
156 						new Vector<ClassType>());
157 		groupVector.add(class1);
158 		final Model expected = Model.create(this.group1IdentifierToken);
159 		expected.addGroup(group);
160 		
161 		final Model actual = this.parser.parse();
162 		assertEquals(expected, actual);
163 		assertEquals(0, this.parser.getExceptions().size());
164 		
165 	}
166 	
167 	/**
168 	 * Group:group=[Class:class={}]; .
169 	 */
170 	@Test
171 	public void testSimpleClassWithoutSemicolon() {
172 		this.stream.add(this.group1IdentifierToken);
173 		this.stream.add(this.colonToken);
174 		this.stream.add(this.groupToken);
175 		this.stream.add(this.equalToken);
176 		this.stream.add(this.squareBracketOpenToken);
177 		this.stream.add(this.classIdentifierToken);
178 		this.stream.add(this.colonToken);
179 		this.stream.add(this.classToken);
180 		this.stream.add(this.equalToken);
181 		this.stream.add(this.curlyBracketOpenToken);
182 		this.stream.add(this.curlyBracketCloseToken);
183 		this.stream.add(this.squareBracketCloseToken);
184 		this.stream.add(this.semicolonToken);
185 		this.stream.add(this.endToken);
186 		
187 		try {
188 			this.parser.parse();
189 			fail();
190 		} catch (final NoValidTokenStreamException e) {
191 			assertEquals(1, this.parser.getExceptions().size());
192 		}
193 	}
194 	
195 	/**
196 	 * Group:group=[Class:class={;]; .
197 	 */
198 	@Test
199 	public void testSimpleClassWithoutClassEnd() {
200 		this.stream.add(this.group1IdentifierToken);
201 		this.stream.add(this.colonToken);
202 		this.stream.add(this.groupToken);
203 		this.stream.add(this.equalToken);
204 		this.stream.add(this.squareBracketOpenToken);
205 		this.stream.add(this.classIdentifierToken);
206 		this.stream.add(this.colonToken);
207 		this.stream.add(this.classToken);
208 		this.stream.add(this.equalToken);
209 		this.stream.add(this.curlyBracketOpenToken);
210 		this.stream.add(this.semicolonToken);
211 		this.stream.add(this.squareBracketCloseToken);
212 		this.stream.add(this.semicolonToken);
213 		this.stream.add(this.endToken);
214 		
215 		try {
216 			this.parser.parse();
217 			fail();
218 		} catch (final NoValidTokenStreamException e) {
219 			assertEquals(1, this.parser.getExceptions().size());
220 		}
221 	}
222 	
223 	/**
224 	 * Class:class={}; .
225 	 */
226 	@Test
227 	public void testClassWithoutAGroup() {
228 		this.stream.add(this.classIdentifierToken);
229 		this.stream.add(this.colonToken);
230 		this.stream.add(this.classToken);
231 		this.stream.add(this.equalToken);
232 		this.stream.add(this.curlyBracketOpenToken);
233 		this.stream.add(this.curlyBracketCloseToken);
234 		this.stream.add(EndToken.create(Position.create("", 0 + 1, 0 + 1, 0)));
235 		
236 		try {
237 			this.parser.parse();
238 			fail();
239 		} catch (final NoValidTokenStreamException e) {
240 			assertEquals(1, this.parser.getExceptions().size());
241 		}
242 	}
243 	
244 	/**
245 	 * Group:group=[Class:class={} abstract;]; .
246 	 * 
247 	 * @throws Exception
248 	 */
249 	@Test
250 	public void testClassAbstractModifier() throws Exception {
251 		this.stream.add(this.group1IdentifierToken);
252 		this.stream.add(this.colonToken);
253 		this.stream.add(this.groupToken);
254 		this.stream.add(this.equalToken);
255 		this.stream.add(this.squareBracketOpenToken);
256 		this.stream.add(this.classIdentifierToken);
257 		this.stream.add(this.colonToken);
258 		this.stream.add(this.classToken);
259 		this.stream.add(this.equalToken);
260 		this.stream.add(this.curlyBracketOpenToken);
261 		this.stream.add(this.curlyBracketCloseToken);
262 		this.stream.add(this.abstractToken);
263 		this.stream.add(this.semicolonToken);
264 		this.stream.add(this.squareBracketCloseToken);
265 		this.stream.add(this.semicolonToken);
266 		this.stream.add(this.endToken);
267 		
268 		final Vector<GroupElement> groupVector = new Vector<>();
269 		final Vector<ClassModifier> modifiers = new Vector<>();
270 		
271 		final Name groupName = UnqualifiedName.create(this.group1IdentifierToken);
272 		final Group group = Group.create(groupName, groupVector, this.group1IdentifierToken);
273 		final Name className = groupName.addName(this.classIdentifierToken);
274 		modifiers.add(ClassModifierAbstract.create(this.abstractToken));
275 		final ClassType class1 =
276 				RegularClassType.create(
277 						className,
278 						modifiers,
279 						new Vector<Attribute>(),
280 						new Vector<Type>(),
281 						new Vector<Operation>(),
282 						new Vector<Constructor>(),
283 						this.classIdentifierToken,
284 						
285 						new Vector<ClassType>());
286 		groupVector.add(class1);
287 		final Model expected = Model.create(this.group1IdentifierToken);
288 		expected.addGroup(group);
289 		
290 		final Model actual = this.parser.parse();
291 		assertEquals(expected, actual);
292 		assertEquals(0, this.parser.getExceptions().size());
293 	}
294 	
295 	/**
296 	 * Group:group=[Class:class={} transient;]; .
297 	 * 
298 	 * @throws Exception
299 	 */
300 	@Test
301 	public void testClassTransientModifier() throws Exception {
302 		this.stream.add(this.group1IdentifierToken);
303 		this.stream.add(this.colonToken);
304 		this.stream.add(this.groupToken);
305 		this.stream.add(this.equalToken);
306 		this.stream.add(this.squareBracketOpenToken);
307 		this.stream.add(this.classIdentifierToken);
308 		this.stream.add(this.colonToken);
309 		this.stream.add(this.classToken);
310 		this.stream.add(this.equalToken);
311 		this.stream.add(this.curlyBracketOpenToken);
312 		this.stream.add(this.curlyBracketCloseToken);
313 		this.stream.add(this.transientToken);
314 		this.stream.add(this.semicolonToken);
315 		this.stream.add(this.squareBracketCloseToken);
316 		this.stream.add(this.semicolonToken);
317 		this.stream.add(this.endToken);
318 		
319 		final Vector<GroupElement> groupVector = new Vector<>();
320 		final Vector<ClassModifier> modifiers = new Vector<>();
321 		
322 		final Name groupName = UnqualifiedName.create(this.group1IdentifierToken);
323 		final Group group = Group.create(groupName, groupVector, this.group1IdentifierToken);
324 		final Name className = groupName.addName(this.classIdentifierToken);
325 		modifiers.add(ClassModifierTransient.create(this.transientToken));
326 		final ClassType class1 =
327 				RegularClassType.create(
328 						className,
329 						modifiers,
330 						new Vector<Attribute>(),
331 						new Vector<Type>(),
332 						new Vector<Operation>(),
333 						new Vector<Constructor>(),
334 						this.classIdentifierToken,
335 						
336 						new Vector<ClassType>());
337 		groupVector.add(class1);
338 		final Model expected = Model.create(this.group1IdentifierToken);
339 		expected.addGroup(group);
340 		
341 		final Model actual = this.parser.parse();
342 		assertEquals(expected, actual);
343 		assertEquals(0, this.parser.getExceptions().size());
344 	}
345 	
346 	/**
347 	 * Group:group=[Class:class={} service;]; .
348 	 * 
349 	 * @throws Exception
350 	 */
351 	@Test
352 	public void testClassServiceModifier() throws Exception {
353 		this.stream.add(this.group1IdentifierToken);
354 		this.stream.add(this.colonToken);
355 		this.stream.add(this.groupToken);
356 		this.stream.add(this.equalToken);
357 		this.stream.add(this.squareBracketOpenToken);
358 		this.stream.add(this.classIdentifierToken);
359 		this.stream.add(this.colonToken);
360 		this.stream.add(this.classToken);
361 		this.stream.add(this.equalToken);
362 		this.stream.add(this.curlyBracketOpenToken);
363 		this.stream.add(this.curlyBracketCloseToken);
364 		this.stream.add(this.serviceToken);
365 		this.stream.add(this.semicolonToken);
366 		this.stream.add(this.squareBracketCloseToken);
367 		this.stream.add(this.semicolonToken);
368 		this.stream.add(this.endToken);
369 		
370 		final Vector<GroupElement> groupVector = new Vector<>();
371 		final Vector<ClassModifier> modifiers = new Vector<>();
372 		
373 		final Name groupName = UnqualifiedName.create(this.group1IdentifierToken);
374 		final Group group = Group.create(groupName, groupVector, this.group1IdentifierToken);
375 		final Name className = groupName.addName(this.classIdentifierToken);
376 		modifiers.add(ClassModifierService.create(this.serviceToken));
377 		final ClassType class1 =
378 				RegularClassType.create(
379 						className,
380 						modifiers,
381 						new Vector<Attribute>(),
382 						new Vector<Type>(),
383 						new Vector<Operation>(),
384 						new Vector<Constructor>(),
385 						this.classIdentifierToken,
386 						
387 						new Vector<ClassType>());
388 		groupVector.add(class1);
389 		final Model expected = Model.create(this.group1IdentifierToken);
390 		expected.addGroup(group);
391 		
392 		final Model actual = this.parser.parse();
393 		assertEquals(expected, actual);
394 		assertEquals(0, this.parser.getExceptions().size());
395 	}
396 	
397 	/**
398 	 * Group:group=[Class:class={} visitable;]; .
399 	 * 
400 	 * @throws Exception
401 	 */
402 	@Test
403 	public void testClassVisitableModifier() throws Exception {
404 		this.stream.add(this.group1IdentifierToken);
405 		this.stream.add(this.colonToken);
406 		this.stream.add(this.groupToken);
407 		this.stream.add(this.equalToken);
408 		this.stream.add(this.squareBracketOpenToken);
409 		this.stream.add(this.classIdentifierToken);
410 		this.stream.add(this.colonToken);
411 		this.stream.add(this.classToken);
412 		this.stream.add(this.equalToken);
413 		this.stream.add(this.curlyBracketOpenToken);
414 		this.stream.add(this.curlyBracketCloseToken);
415 		this.stream.add(this.visitableToken);
416 		this.stream.add(this.semicolonToken);
417 		this.stream.add(this.squareBracketCloseToken);
418 		this.stream.add(this.semicolonToken);
419 		this.stream.add(this.endToken);
420 		
421 		final Vector<GroupElement> groupVector = new Vector<>();
422 		final Vector<ClassModifier> modifiers = new Vector<>();
423 		
424 		final Name groupName = UnqualifiedName.create(this.group1IdentifierToken);
425 		final Group group = Group.create(groupName, groupVector, this.group1IdentifierToken);
426 		final Name className = groupName.addName(this.classIdentifierToken);
427 		modifiers.add(ClassModifierVisitable.create(this.visitableToken));
428 		final ClassType class1 =
429 				RegularClassType.create(
430 						className,
431 						modifiers,
432 						new Vector<Attribute>(),
433 						new Vector<Type>(),
434 						new Vector<Operation>(),
435 						new Vector<Constructor>(),
436 						this.classIdentifierToken,
437 						
438 						new Vector<ClassType>());
439 		groupVector.add(class1);
440 		final Model expected = Model.create(this.group1IdentifierToken);
441 		expected.addGroup(group);
442 		
443 		final Model actual = this.parser.parse();
444 		assertEquals(expected, actual);
445 		assertEquals(0, this.parser.getExceptions().size());
446 	}
447 	
448 	/**
449 	 * Group:group=[Class:class={} [;]; .
450 	 */
451 	@Test
452 	public void testClassWithExceptionInParseModifier() {
453 		this.stream.add(this.group1IdentifierToken);
454 		this.stream.add(this.colonToken);
455 		this.stream.add(this.groupToken);
456 		this.stream.add(this.equalToken);
457 		this.stream.add(this.squareBracketOpenToken);
458 		this.stream.add(this.classIdentifierToken);
459 		this.stream.add(this.colonToken);
460 		this.stream.add(this.classToken);
461 		this.stream.add(this.equalToken);
462 		this.stream.add(this.curlyBracketOpenToken);
463 		this.stream.add(this.curlyBracketCloseToken);
464 		this.stream.add(this.squareBracketOpenToken);
465 		this.stream.add(this.semicolonToken);
466 		this.stream.add(this.squareBracketCloseToken);
467 		this.stream.add(this.semicolonToken);
468 		this.stream.add(this.endToken);
469 		
470 		try {
471 			this.parser.parse();
472 			fail();
473 		} catch (final NoValidTokenStreamException e) {
474 			assertEquals(1, this.parser.getExceptions().size());
475 		}
476 	}
477 	
478 	/**
479 	 * Group:group=[Class:class={} visitable visitable;]; .
480 	 */
481 	@Test
482 	public void testClassWithMultipleSameModifiers() {
483 		this.stream.add(this.group1IdentifierToken);
484 		this.stream.add(this.colonToken);
485 		this.stream.add(this.groupToken);
486 		this.stream.add(this.equalToken);
487 		this.stream.add(this.squareBracketOpenToken);
488 		this.stream.add(this.classIdentifierToken);
489 		this.stream.add(this.colonToken);
490 		this.stream.add(this.classToken);
491 		this.stream.add(this.equalToken);
492 		this.stream.add(this.curlyBracketOpenToken);
493 		this.stream.add(this.curlyBracketCloseToken);
494 		this.stream.add(this.visitableToken);
495 		this.stream.add(this.visitableToken);
496 		this.stream.add(this.semicolonToken);
497 		this.stream.add(this.squareBracketCloseToken);
498 		this.stream.add(this.semicolonToken);
499 		this.stream.add(this.endToken);
500 		
501 		try {
502 			this.parser.parse();
503 			fail();
504 		} catch (final NoValidTokenStreamException e) {
505 			assertEquals(1, this.parser.getExceptions().size());
506 		}
507 	}
508 	
509 	/**
510 	 * Group:group=[Class:class={} abstract transient service visitable;]; .
511 	 * 
512 	 * @throws Exception
513 	 */
514 	@Test
515 	public void testClassWithAllModifier() throws Exception {
516 		this.stream.add(this.group1IdentifierToken);
517 		this.stream.add(this.colonToken);
518 		this.stream.add(this.groupToken);
519 		this.stream.add(this.equalToken);
520 		this.stream.add(this.squareBracketOpenToken);
521 		this.stream.add(this.classIdentifierToken);
522 		this.stream.add(this.colonToken);
523 		this.stream.add(this.classToken);
524 		this.stream.add(this.equalToken);
525 		this.stream.add(this.curlyBracketOpenToken);
526 		this.stream.add(this.curlyBracketCloseToken);
527 		this.stream.add(this.abstractToken);
528 		this.stream.add(this.transientToken);
529 		this.stream.add(this.serviceToken);
530 		this.stream.add(this.visitableToken);
531 		this.stream.add(this.semicolonToken);
532 		this.stream.add(this.squareBracketCloseToken);
533 		this.stream.add(this.semicolonToken);
534 		this.stream.add(this.endToken);
535 		
536 		final Vector<GroupElement> groupVector = new Vector<>();
537 		final Vector<ClassModifier> modifiers = new Vector<>();
538 		
539 		final Name groupName = UnqualifiedName.create(this.group1IdentifierToken);
540 		final Group group = Group.create(groupName, groupVector, this.group1IdentifierToken);
541 		final Name className = groupName.addName(this.classIdentifierToken);
542 		modifiers.add(ClassModifierAbstract.create(this.abstractToken));
543 		modifiers.add(ClassModifierTransient.create(this.transientToken));
544 		modifiers.add(ClassModifierService.create(this.serviceToken));
545 		modifiers.add(ClassModifierVisitable.create(this.visitableToken));
546 		final ClassType class1 =
547 				RegularClassType.create(
548 						className,
549 						modifiers,
550 						new Vector<Attribute>(),
551 						new Vector<Type>(),
552 						new Vector<Operation>(),
553 						new Vector<Constructor>(),
554 						this.classIdentifierToken,
555 						
556 						new Vector<ClassType>());
557 		groupVector.add(class1);
558 		final Model expected = Model.create(this.group1IdentifierToken);
559 		expected.addGroup(group);
560 		
561 		final Model actual = this.parser.parse();
562 		assertEquals(expected, actual);
563 		assertEquals(0, this.parser.getExceptions().size());
564 	}
565 	
566 	/**
567 	 * Group:group=[Class:class={} service abstract visitable transient;]; .
568 	 * 
569 	 * @throws Exception
570 	 */
571 	@Test
572 	public void testClassWithAllModifierInDifferentOrder() throws Exception {
573 		this.stream.add(this.group1IdentifierToken);
574 		this.stream.add(this.colonToken);
575 		this.stream.add(this.groupToken);
576 		this.stream.add(this.equalToken);
577 		this.stream.add(this.squareBracketOpenToken);
578 		this.stream.add(this.classIdentifierToken);
579 		this.stream.add(this.colonToken);
580 		this.stream.add(this.classToken);
581 		this.stream.add(this.equalToken);
582 		this.stream.add(this.curlyBracketOpenToken);
583 		this.stream.add(this.curlyBracketCloseToken);
584 		this.stream.add(this.serviceToken);
585 		this.stream.add(this.abstractToken);
586 		this.stream.add(this.visitableToken);
587 		this.stream.add(this.transientToken);
588 		this.stream.add(this.semicolonToken);
589 		this.stream.add(this.squareBracketCloseToken);
590 		this.stream.add(this.semicolonToken);
591 		this.stream.add(this.endToken);
592 		
593 		final Vector<GroupElement> groupVector = new Vector<>();
594 		final Vector<ClassModifier> modifiers = new Vector<>();
595 		
596 		final Name groupName = UnqualifiedName.create(this.group1IdentifierToken);
597 		final Group group = Group.create(groupName, groupVector, this.group1IdentifierToken);
598 		final Name className = groupName.addName(this.classIdentifierToken);
599 		modifiers.add(ClassModifierService.create(this.serviceToken));
600 		modifiers.add(ClassModifierAbstract.create(this.abstractToken));
601 		modifiers.add(ClassModifierVisitable.create(this.visitableToken));
602 		modifiers.add(ClassModifierTransient.create(this.transientToken));
603 		final ClassType class1 =
604 				RegularClassType.create(
605 						className,
606 						modifiers,
607 						new Vector<Attribute>(),
608 						new Vector<Type>(),
609 						new Vector<Operation>(),
610 						new Vector<Constructor>(),
611 						this.classIdentifierToken,
612 						
613 						new Vector<ClassType>());
614 		groupVector.add(class1);
615 		final Model expected = Model.create(this.group1IdentifierToken);
616 		expected.addGroup(group);
617 		
618 		final Model actual = this.parser.parse();
619 		assertEquals(expected, actual);
620 		assertEquals(0, this.parser.getExceptions().size());
621 	}
622 	
623 	/**
624 	 * Group:group=[Class:class={} abstract abstract abstract abstract abstract;]; .
625 	 */
626 	@Test
627 	public void testClassMultipleAbstractModifier() {
628 		this.stream.add(this.group1IdentifierToken);
629 		this.stream.add(this.colonToken);
630 		this.stream.add(this.groupToken);
631 		this.stream.add(this.equalToken);
632 		this.stream.add(this.squareBracketOpenToken);
633 		this.stream.add(this.classIdentifierToken);
634 		this.stream.add(this.colonToken);
635 		this.stream.add(this.classToken);
636 		this.stream.add(this.equalToken);
637 		this.stream.add(this.curlyBracketOpenToken);
638 		this.stream.add(this.curlyBracketCloseToken);
639 		this.stream.add(this.abstractToken);
640 		this.stream.add(this.abstractToken);
641 		this.stream.add(this.abstractToken);
642 		this.stream.add(this.abstractToken);
643 		this.stream.add(this.abstractToken);
644 		this.stream.add(this.semicolonToken);
645 		this.stream.add(this.squareBracketCloseToken);
646 		this.stream.add(this.semicolonToken);
647 		this.stream.add(this.endToken);
648 		
649 		try {
650 			this.parser.parse();
651 			fail();
652 		} catch (final NoValidTokenStreamException e) {
653 			assertEquals(4, this.parser.getExceptions().size());
654 			final Iterator<AbstractParserException> i = this.parser.getExceptions().iterator();
655 			while (i.hasNext()) {
656 				final AbstractParserException current = i.next();
657 				assertTrue(current instanceof ClassModifierAlreadyAddedException);
658 			}
659 		}
660 	}
661 	
662 	/**
663 	 * Group:group=[Superclass:class={};Class:class=Superclass+{};]; .
664 	 * 
665 	 * @throws Exception
666 	 */
667 	@Test
668 	public void testSimpleInheritance() throws Exception {
669 		this.stream.add(this.group1IdentifierToken);
670 		this.stream.add(this.colonToken);
671 		this.stream.add(this.groupToken);
672 		this.stream.add(this.equalToken);
673 		this.stream.add(this.squareBracketOpenToken);
674 		this.stream.add(this.superClass1IdentifierToken);
675 		this.stream.add(this.colonToken);
676 		this.stream.add(this.classToken);
677 		this.stream.add(this.equalToken);
678 		this.stream.add(this.curlyBracketOpenToken);
679 		this.stream.add(this.curlyBracketCloseToken);
680 		this.stream.add(this.semicolonToken);
681 		this.stream.add(this.classIdentifierToken);
682 		this.stream.add(this.colonToken);
683 		this.stream.add(this.classToken);
684 		this.stream.add(this.equalToken);
685 		this.stream.add(this.superClass1IdentifierToken);
686 		this.stream.add(this.plusSymbolToken);
687 		this.stream.add(this.curlyBracketOpenToken);
688 		this.stream.add(this.curlyBracketCloseToken);
689 		this.stream.add(this.semicolonToken);
690 		this.stream.add(this.squareBracketCloseToken);
691 		this.stream.add(this.semicolonToken);
692 		this.stream.add(this.endToken);
693 		
694 		final Vector<GroupElement> groupVector = new Vector<>();
695 		
696 		final Name groupName = UnqualifiedName.create(this.group1IdentifierToken);
697 		final Group group = Group.create(groupName, groupVector, this.group1IdentifierToken);
698 		final Name className = groupName.addName(this.classIdentifierToken);
699 		final Name superclassName = groupName.addName(this.superClass1IdentifierToken);
700 		final TypeProxy supertype =
701 				TypeProxy.create(null, ByNameState.create(UnqualifiedName.create(this.superClass1IdentifierToken)));
702 		final Vector<Type> supertypes = new Vector<>();
703 		supertypes.add(supertype);
704 		final ClassType class1 =
705 				RegularClassType.create(
706 						className,
707 						new Vector<ClassModifier>(),
708 						new Vector<Attribute>(),
709 						supertypes,
710 						new Vector<Operation>(),
711 						new Vector<Constructor>(),
712 						this.classIdentifierToken,
713 						
714 						new Vector<ClassType>());
715 		
716 		final ClassType superclass =
717 				RegularClassType.create(
718 						superclassName,
719 						new Vector<ClassModifier>(),
720 						new Vector<Attribute>(),
721 						new Vector<Type>(),
722 						new Vector<Operation>(),
723 						new Vector<Constructor>(),
724 						this.superClass1IdentifierToken,
725 						
726 						new Vector<ClassType>());
727 		groupVector.add(superclass);
728 		groupVector.add(class1);
729 		final Model expected = Model.create(this.group1IdentifierToken);
730 		expected.addGroup(group);
731 		
732 		final Model actual = this.parser.parse();
733 		assertEquals(expected, actual);
734 		assertEquals(0, this.parser.getExceptions().size());
735 	}
736 	
737 	/**
738 	 * Group:group=[Superclass1:class={};Superclass2:class{};Subclass:class= Superclass1+Superclass2+{};]; .
739 	 * 
740 	 * @throws Exception
741 	 */
742 	@Test
743 	public void testMultipleInheritance() throws Exception {
744 		this.stream.add(this.group1IdentifierToken);
745 		this.stream.add(this.colonToken);
746 		this.stream.add(this.groupToken);
747 		this.stream.add(this.equalToken);
748 		this.stream.add(this.squareBracketOpenToken);
749 		this.stream.add(this.superClass1IdentifierToken);
750 		this.stream.add(this.colonToken);
751 		this.stream.add(this.classToken);
752 		this.stream.add(this.equalToken);
753 		this.stream.add(this.curlyBracketOpenToken);
754 		this.stream.add(this.curlyBracketCloseToken);
755 		this.stream.add(this.semicolonToken);
756 		this.stream.add(this.superClass2IdentifierToken);
757 		this.stream.add(this.colonToken);
758 		this.stream.add(this.classToken);
759 		this.stream.add(this.equalToken);
760 		this.stream.add(this.curlyBracketOpenToken);
761 		this.stream.add(this.curlyBracketCloseToken);
762 		this.stream.add(this.semicolonToken);
763 		this.stream.add(this.classIdentifierToken);
764 		this.stream.add(this.colonToken);
765 		this.stream.add(this.classToken);
766 		this.stream.add(this.equalToken);
767 		this.stream.add(this.superClass1IdentifierToken);
768 		this.stream.add(this.plusSymbolToken);
769 		this.stream.add(this.superClass2IdentifierToken);
770 		this.stream.add(this.plusSymbolToken);
771 		this.stream.add(this.curlyBracketOpenToken);
772 		this.stream.add(this.curlyBracketCloseToken);
773 		this.stream.add(this.semicolonToken);
774 		this.stream.add(this.squareBracketCloseToken);
775 		this.stream.add(this.semicolonToken);
776 		this.stream.add(this.endToken);
777 		
778 		final Vector<GroupElement> groupVector = new Vector<>();
779 		
780 		final Name groupName = UnqualifiedName.create(this.group1IdentifierToken);
781 		final Group group = Group.create(groupName, groupVector, this.group1IdentifierToken);
782 		final Name className = groupName.addName(this.classIdentifierToken);
783 		
784 		final TypeProxy supertype =
785 				TypeProxy.create(null, ByNameState.create(UnqualifiedName.create(this.superClass1IdentifierToken)));
786 		final Vector<Type> supertypes = new Vector<>();
787 		supertypes.add(supertype);
788 		supertypes.add(supertype);
789 		
790 		final ClassType class1 =
791 				RegularClassType.create(
792 						className,
793 						new Vector<ClassModifier>(),
794 						new Vector<Attribute>(),
795 						supertypes,
796 						new Vector<Operation>(),
797 						new Vector<Constructor>(),
798 						this.classIdentifierToken,
799 						
800 						new Vector<ClassType>());
801 		final Name superclass1Name = groupName.addName(this.superClass1IdentifierToken);
802 		final ClassType superclass1 =
803 				RegularClassType.create(
804 						superclass1Name,
805 						new Vector<ClassModifier>(),
806 						new Vector<Attribute>(),
807 						new Vector<Type>(),
808 						new Vector<Operation>(),
809 						new Vector<Constructor>(),
810 						this.superClass1IdentifierToken,
811 						
812 						new Vector<ClassType>());
813 		final Name superclass2Name = groupName.addName(this.superClass2IdentifierToken);
814 		final ClassType superclass2 =
815 				RegularClassType.create(
816 						superclass2Name,
817 						new Vector<ClassModifier>(),
818 						new Vector<Attribute>(),
819 						new Vector<Type>(),
820 						new Vector<Operation>(),
821 						new Vector<Constructor>(),
822 						this.superClass1IdentifierToken,
823 						
824 						new Vector<ClassType>());
825 		groupVector.add(superclass1);
826 		groupVector.add(superclass2);
827 		groupVector.add(class1);
828 		final Model expected = Model.create(this.group1IdentifierToken);
829 		expected.addGroup(group);
830 		
831 		final Model actual = this.parser.parse();
832 		assertEquals(expected, actual);
833 		assertEquals(0, this.parser.getExceptions().size());
834 	}
835 	
836 	/**
837 	 * Group1:group=[Superclass:class={};]; Group2:group=[Class:class=Superclass+{};]; .
838 	 * 
839 	 * @throws Exception
840 	 */
841 	@Test
842 	public void testSimpleInheritanceWithTwoGroups() throws Exception {
843 		this.stream.add(this.group1IdentifierToken);
844 		this.stream.add(this.colonToken);
845 		this.stream.add(this.groupToken);
846 		this.stream.add(this.equalToken);
847 		this.stream.add(this.squareBracketOpenToken);
848 		this.stream.add(this.superClass1IdentifierToken);
849 		this.stream.add(this.colonToken);
850 		this.stream.add(this.classToken);
851 		this.stream.add(this.equalToken);
852 		this.stream.add(this.curlyBracketOpenToken);
853 		this.stream.add(this.curlyBracketCloseToken);
854 		this.stream.add(this.semicolonToken);
855 		this.stream.add(this.squareBracketCloseToken);
856 		this.stream.add(this.semicolonToken);
857 		this.stream.add(this.group2IdentifierToken);
858 		this.stream.add(this.colonToken);
859 		this.stream.add(this.groupToken);
860 		this.stream.add(this.equalToken);
861 		this.stream.add(this.squareBracketOpenToken);
862 		this.stream.add(this.classIdentifierToken);
863 		this.stream.add(this.colonToken);
864 		this.stream.add(this.classToken);
865 		this.stream.add(this.equalToken);
866 		this.stream.add(this.superClass1IdentifierToken);
867 		this.stream.add(this.plusSymbolToken);
868 		this.stream.add(this.curlyBracketOpenToken);
869 		this.stream.add(this.curlyBracketCloseToken);
870 		this.stream.add(this.semicolonToken);
871 		this.stream.add(this.squareBracketCloseToken);
872 		this.stream.add(this.semicolonToken);
873 		this.stream.add(this.endToken);
874 		
875 		final Vector<GroupElement> groupVector1 = new Vector<>();
876 		final Vector<GroupElement> groupVector2 = new Vector<>();
877 		
878 		final Name group1Name = UnqualifiedName.create(this.group1IdentifierToken);
879 		final Group group1 = Group.create(group1Name, groupVector1, this.group1IdentifierToken);
880 		
881 		final Name group2Name = UnqualifiedName.create(this.group2IdentifierToken);
882 		final Group group2 = Group.create(group2Name, groupVector2, this.group2IdentifierToken);
883 		
884 		final TypeProxy supertype =
885 				TypeProxy.create(null, ByNameState.create(UnqualifiedName.create(this.superClass1IdentifierToken)));
886 		final Vector<Type> supertypes = new Vector<>();
887 		supertypes.add(supertype);
888 		
889 		final Name className = group2Name.addName(this.classIdentifierToken);
890 		final ClassType class1 =
891 				RegularClassType.create(
892 						className,
893 						new Vector<ClassModifier>(),
894 						new Vector<Attribute>(),
895 						supertypes,
896 						new Vector<Operation>(),
897 						new Vector<Constructor>(),
898 						this.classIdentifierToken,
899 						
900 						new Vector<ClassType>());
901 		final Name superclassName = group1Name.addName(this.superClass1IdentifierToken);
902 		final ClassType superclass =
903 				RegularClassType.create(
904 						superclassName,
905 						new Vector<ClassModifier>(),
906 						new Vector<Attribute>(),
907 						new Vector<Type>(),
908 						new Vector<Operation>(),
909 						new Vector<Constructor>(),
910 						this.superClass1IdentifierToken,
911 						
912 						new Vector<ClassType>());
913 		
914 		groupVector1.add(superclass);
915 		groupVector2.add(class1);
916 		final Model expected = Model.create(this.group1IdentifierToken);
917 		expected.addGroup(group1);
918 		expected.addGroup(group2);
919 		
920 		final Model actual = this.parser.parse();
921 		assertEquals(expected, actual);
922 		assertEquals(0, this.parser.getExceptions().size());
923 	}
924 }