1 /*
2 [The "BSD licence"]
3 Copyright (c) 2005-2007 Kunle Odutola
4 All rights reserved.
5 
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
9 1. Redistributions of source code MUST RETAIN the above copyright
10    notice, this list of conditions and the following disclaimer.
11 2. Redistributions in binary form MUST REPRODUCE the above copyright
12    notice, this list of conditions and the following disclaimer in
13    the documentation and/or other materials provided with the
14    distribution.
15 3. The name of the author may not be used to endorse or promote products
16    derived from this software without specific prior WRITTEN permission.
17 4. Unless explicitly state otherwise, any contribution intentionally
18    submitted for inclusion in this work to the copyright owner or licensor
19    shall be under the terms and conditions of this license, without any
20    additional terms or conditions.
21 
22 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33 
34 
35 namespace Antlr.Runtime.Tests
36 {
37 	using System;
38 	using StringBuilder = System.Text.StringBuilder;
39 
40 	using IToken = Antlr.Runtime.IToken;
41     using Token = Antlr.Runtime.TokenTypes;
42 	using CommonToken = Antlr.Runtime.CommonToken;
43 	using ITree = Antlr.Runtime.Tree.ITree;
44 	using ITreeNodeStream = Antlr.Runtime.Tree.ITreeNodeStream;
45 	using CommonTree = Antlr.Runtime.Tree.CommonTree;
46 	using CommonTreeNodeStream = Antlr.Runtime.Tree.CommonTreeNodeStream;
47 	using BufferedTreeNodeStream = Antlr.Runtime.Tree.BufferedTreeNodeStream;
48 
49 	using MbUnit.Framework;
50 
51 	[TestFixture]
52 	public class ITreeNodeStreamFixture : TestFixtureBase
53     {
54         #region BufferedTreeNodeStream Tests
55 
56         [Test]
testSingleNode()57 		public void testSingleNode()
58 		{
59 			ITree t = new CommonTree(new CommonToken(101));
60 
61 			ITreeNodeStream stream = CreateCommonTreeNodeStream(t);
62 			string expected = " 101";
63 			string actual = GetStringOfEntireStreamContentsWithNodeTypesOnly(stream);
64 			Assert.AreEqual(expected, actual);
65 
66 			expected = " 101";
67 			actual = stream.ToString();
68 			Assert.AreEqual(expected, actual);
69 		}
70 
71 		[Test]
72 		/// <summary>
73 		/// Test a tree with four nodes - ^(101 ^(102 103) 104)
74 		/// </summary>
test4Nodes()75 		public void test4Nodes()
76 		{
77 			ITree t = new CommonTree(new CommonToken(101));
78 			t.AddChild(new CommonTree(new CommonToken(102)));
79 			t.GetChild(0).AddChild(new CommonTree(new CommonToken(103)));
80 			t.AddChild(new CommonTree(new CommonToken(104)));
81 
82             ITreeNodeStream stream = CreateBufferedTreeNodeStream(t);
83 			string expected = " 101 102 103 104";
84 			string actual = GetStringOfEntireStreamContentsWithNodeTypesOnly(stream);
85 			Assert.AreEqual(expected, actual);
86 
87 			expected = " 101 2 102 2 103 3 104 3";
88 			actual = stream.ToString();
89 			Assert.AreEqual(expected, actual);
90 		}
91 
92 		[Test]
testList()93 		public void testList()
94 		{
95 			ITree root = new CommonTree((IToken)null);
96 
97 			ITree t = new CommonTree(new CommonToken(101));
98 			t.AddChild(new CommonTree(new CommonToken(102)));
99 			t.GetChild(0).AddChild(new CommonTree(new CommonToken(103)));
100 			t.AddChild(new CommonTree(new CommonToken(104)));
101 
102 			ITree u = new CommonTree(new CommonToken(105));
103 
104 			root.AddChild(t);
105 			root.AddChild(u);
106 
107             BufferedTreeNodeStream stream = new BufferedTreeNodeStream(root);
108 			string expected = " 101 102 103 104 105";
109 			string actual = GetStringOfEntireStreamContentsWithNodeTypesOnly(stream);
110 			Assert.AreEqual(expected, actual);
111 
112 			expected = " 101 2 102 2 103 3 104 3 105";
113 			actual = stream.ToString();
114 			Assert.AreEqual(expected, actual);
115 		}
116 
117 		[Test]
testFlatList()118 		public void testFlatList()
119 		{
120 			ITree root = new CommonTree((IToken)null);
121 
122 			root.AddChild(new CommonTree(new CommonToken(101)));
123 			root.AddChild(new CommonTree(new CommonToken(102)));
124 			root.AddChild(new CommonTree(new CommonToken(103)));
125 
126             BufferedTreeNodeStream stream = new BufferedTreeNodeStream(root);
127 			string expected = " 101 102 103";
128 			string actual = GetStringOfEntireStreamContentsWithNodeTypesOnly(stream);
129 			Assert.AreEqual(expected, actual);
130 
131 			expected = " 101 102 103";
132 			actual = stream.ToString();
133 			Assert.AreEqual(expected, actual);
134 		}
135 
136 		[Test]
testListWithOneNode()137 		public void testListWithOneNode()
138 		{
139 			ITree root = new CommonTree((IToken)null);
140 
141 			root.AddChild(new CommonTree(new CommonToken(101)));
142 
143             BufferedTreeNodeStream stream = new BufferedTreeNodeStream(root);
144 			string expected = " 101";
145 			string actual = GetStringOfEntireStreamContentsWithNodeTypesOnly(stream);
146 			Assert.AreEqual(expected, actual);
147 
148 			expected = " 101";
149 			actual = stream.ToString();
150 			Assert.AreEqual(expected, actual);
151 		}
152 
153 		[Test]
testAoverB()154 		public void testAoverB()
155 		{
156 			ITree t = new CommonTree(new CommonToken(101));
157 			t.AddChild(new CommonTree(new CommonToken(102)));
158 
159             ITreeNodeStream stream = CreateBufferedTreeNodeStream(t);
160 			string expected = " 101 102";
161 			string actual = GetStringOfEntireStreamContentsWithNodeTypesOnly(stream);
162 			Assert.AreEqual(expected, actual);
163 
164 			expected = " 101 2 102 3";
165 			actual = stream.ToString();
166 			Assert.AreEqual(expected, actual);
167 		}
168 
169 		[Test]
testLT()170 		public void testLT()
171 		{
172 			// ^(101 ^(102 103) 104)
173 			ITree t = new CommonTree(new CommonToken(101));
174 			t.AddChild(new CommonTree(new CommonToken(102)));
175 			t.GetChild(0).AddChild(new CommonTree(new CommonToken(103)));
176 			t.AddChild(new CommonTree(new CommonToken(104)));
177 
178             ITreeNodeStream stream = CreateBufferedTreeNodeStream(t);
179 			Assert.AreEqual(101, ((ITree)stream.LT(1)).Type);
180 			Assert.AreEqual(Token.Down, ((ITree)stream.LT(2)).Type);
181 			Assert.AreEqual(102, ((ITree)stream.LT(3)).Type);
182 			Assert.AreEqual(Token.Down, ((ITree)stream.LT(4)).Type);
183 			Assert.AreEqual(103, ((ITree)stream.LT(5)).Type);
184 			Assert.AreEqual(Token.Up, ((ITree)stream.LT(6)).Type);
185 			Assert.AreEqual(104, ((ITree)stream.LT(7)).Type);
186 			Assert.AreEqual(Token.Up, ((ITree)stream.LT(8)).Type);
187 			Assert.AreEqual(Token.EndOfFile, ((ITree)stream.LT(9)).Type);
188 			// check way ahead
189 			Assert.AreEqual(Token.EndOfFile, ((ITree)stream.LT(100)).Type);
190 		}
191 
192 		[Test]
testMarkRewindEntire()193 		public void testMarkRewindEntire()
194 		{
195 			// ^(101 ^(102 103 ^(106 107) ) 104 105)
196 			// stream has 7 real + 6 nav nodes
197 			// Sequence of types: 101 DN 102 DN 103 106 DN 107 Up Up 104 105 Up EndOfFile
198 			ITree r0 = new CommonTree(new CommonToken(101));
199 			ITree r1 = new CommonTree(new CommonToken(102));
200 			r0.AddChild(r1);
201 			r1.AddChild(new CommonTree(new CommonToken(103)));
202 			ITree r2 = new CommonTree(new CommonToken(106));
203 			r2.AddChild(new CommonTree(new CommonToken(107)));
204 			r1.AddChild(r2);
205 			r0.AddChild(new CommonTree(new CommonToken(104)));
206 			r0.AddChild(new CommonTree(new CommonToken(105)));
207 
208             BufferedTreeNodeStream stream = new BufferedTreeNodeStream(r0);
209 			int m = stream.Mark(); // MARK
210 			for (int k = 1; k <= 13; k++)
211 			{ // consume til end
212 				stream.LT(1);
213 				stream.Consume();
214 			}
215 			Assert.AreEqual(Token.EndOfFile, ((ITree)stream.LT(1)).Type);
216 			Assert.AreEqual(Token.Up, ((ITree)stream.LT(-1)).Type);
217 			stream.Rewind(m);      // REWIND
218 
219 			// consume til end again :)
220 			for (int k = 1; k <= 13; k++)
221 			{ // consume til end
222 				stream.LT(1);
223 				stream.Consume();
224 			}
225 			Assert.AreEqual(Token.EndOfFile, ((ITree)stream.LT(1)).Type);
226 			Assert.AreEqual(Token.Up, ((ITree)stream.LT(-1)).Type);
227 		}
228 
229 		[Test]
testMarkRewindInMiddle()230 		public void testMarkRewindInMiddle()
231 		{
232 			// ^(101 ^(102 103 ^(106 107) ) 104 105)
233 			// stream has 7 real + 6 nav nodes
234 			// Sequence of types: 101 DN 102 DN 103 106 DN 107 Up Up 104 105 Up EndOfFile
235 			ITree r0 = new CommonTree(new CommonToken(101));
236 			ITree r1 = new CommonTree(new CommonToken(102));
237 			r0.AddChild(r1);
238 			r1.AddChild(new CommonTree(new CommonToken(103)));
239 			ITree r2 = new CommonTree(new CommonToken(106));
240 			r2.AddChild(new CommonTree(new CommonToken(107)));
241 			r1.AddChild(r2);
242 			r0.AddChild(new CommonTree(new CommonToken(104)));
243 			r0.AddChild(new CommonTree(new CommonToken(105)));
244 
245             BufferedTreeNodeStream stream = new BufferedTreeNodeStream(r0);
246 			for (int k = 1; k <= 7; k++)
247 			{ // consume til middle
248 				//System.out.println(((ITree)stream.LT(1)).Type);
249 				stream.Consume();
250 			}
251 			Assert.AreEqual(107, ((ITree)stream.LT(1)).Type);
252 			int m = stream.Mark(); // MARK
253 			stream.Consume(); // consume 107
254 			stream.Consume(); // consume Up
255 			stream.Consume(); // consume Up
256 			stream.Consume(); // consume 104
257 			stream.Rewind(m);      // REWIND
258 
259 			Assert.AreEqual(107, ((ITree)stream.LT(1)).Type);
260 			stream.Consume();
261 			Assert.AreEqual(Token.Up, ((ITree)stream.LT(1)).Type);
262 			stream.Consume();
263 			Assert.AreEqual(Token.Up, ((ITree)stream.LT(1)).Type);
264 			stream.Consume();
265 			Assert.AreEqual(104, ((ITree)stream.LT(1)).Type);
266 			stream.Consume();
267 			// now we're past rewind position
268 			Assert.AreEqual(105, ((ITree)stream.LT(1)).Type);
269 			stream.Consume();
270 			Assert.AreEqual(Token.Up, ((ITree)stream.LT(1)).Type);
271 			stream.Consume();
272 			Assert.AreEqual(Token.EndOfFile, ((ITree)stream.LT(1)).Type);
273 			Assert.AreEqual(Token.Up, ((ITree)stream.LT(-1)).Type);
274 		}
275 
276 		[Test]
testMarkRewindNested()277 		public void testMarkRewindNested()
278 		{
279 			// ^(101 ^(102 103 ^(106 107) ) 104 105)
280 			// stream has 7 real + 6 nav nodes
281 			// Sequence of types: 101 DN 102 DN 103 106 DN 107 Up Up 104 105 Up EndOfFile
282 			ITree r0 = new CommonTree(new CommonToken(101));
283 			ITree r1 = new CommonTree(new CommonToken(102));
284 			r0.AddChild(r1);
285 			r1.AddChild(new CommonTree(new CommonToken(103)));
286 			ITree r2 = new CommonTree(new CommonToken(106));
287 			r2.AddChild(new CommonTree(new CommonToken(107)));
288 			r1.AddChild(r2);
289 			r0.AddChild(new CommonTree(new CommonToken(104)));
290 			r0.AddChild(new CommonTree(new CommonToken(105)));
291 
292             BufferedTreeNodeStream stream = new BufferedTreeNodeStream(r0);
293 			int m = stream.Mark(); // MARK at start
294 			stream.Consume(); // consume 101
295 			stream.Consume(); // consume DN
296 			int m2 = stream.Mark(); // MARK on 102
297 			stream.Consume(); // consume 102
298 			stream.Consume(); // consume DN
299 			stream.Consume(); // consume 103
300 			stream.Consume(); // consume 106
301 			stream.Rewind(m2);      // REWIND to 102
302 			Assert.AreEqual(102, ((ITree)stream.LT(1)).Type);
303 			stream.Consume();
304 			Assert.AreEqual(Token.Down, ((ITree)stream.LT(1)).Type);
305 			stream.Consume();
306 			// stop at 103 and rewind to start
307 			stream.Rewind(m); // REWIND to 101
308 			Assert.AreEqual(101, ((ITree)stream.LT(1)).Type);
309 			stream.Consume();
310 			Assert.AreEqual(Token.Down, ((ITree)stream.LT(1)).Type);
311 			stream.Consume();
312 			Assert.AreEqual(102, ((ITree)stream.LT(1)).Type);
313 			stream.Consume();
314 			Assert.AreEqual(Token.Down, ((ITree)stream.LT(1)).Type);
315 		}
316 
317 		[Test]
testSeek()318 		public void testSeek()
319 		{
320 			// ^(101 ^(102 103 ^(106 107) ) 104 105)
321 			// stream has 7 real + 6 nav nodes
322 			// Sequence of types: 101 DN 102 DN 103 106 DN 107 Up Up 104 105 Up EndOfFile
323 			ITree r0 = new CommonTree(new CommonToken(101));
324 			ITree r1 = new CommonTree(new CommonToken(102));
325 			r0.AddChild(r1);
326 			r1.AddChild(new CommonTree(new CommonToken(103)));
327 			ITree r2 = new CommonTree(new CommonToken(106));
328 			r2.AddChild(new CommonTree(new CommonToken(107)));
329 			r1.AddChild(r2);
330 			r0.AddChild(new CommonTree(new CommonToken(104)));
331 			r0.AddChild(new CommonTree(new CommonToken(105)));
332 
333             BufferedTreeNodeStream stream = new BufferedTreeNodeStream(r0);
334 			stream.Consume(); // consume 101
335 			stream.Consume(); // consume DN
336 			stream.Consume(); // consume 102
337 			stream.Seek(7);   // seek to 107
338 			Assert.AreEqual(107, ((ITree)stream.LT(1)).Type);
339 			stream.Consume(); // consume 107
340 			stream.Consume(); // consume Up
341 			stream.Consume(); // consume Up
342 			Assert.AreEqual(104, ((ITree)stream.LT(1)).Type);
343 		}
344 
345 		[Test]
testSeekFromStart()346 		public void testSeekFromStart()
347 		{
348 			// ^(101 ^(102 103 ^(106 107) ) 104 105)
349 			// stream has 7 real + 6 nav nodes
350 			// Sequence of types: 101 DN 102 DN 103 106 DN 107 Up Up 104 105 Up EndOfFile
351 			ITree r0 = new CommonTree(new CommonToken(101));
352 			ITree r1 = new CommonTree(new CommonToken(102));
353 			r0.AddChild(r1);
354 			r1.AddChild(new CommonTree(new CommonToken(103)));
355 			ITree r2 = new CommonTree(new CommonToken(106));
356 			r2.AddChild(new CommonTree(new CommonToken(107)));
357 			r1.AddChild(r2);
358 			r0.AddChild(new CommonTree(new CommonToken(104)));
359 			r0.AddChild(new CommonTree(new CommonToken(105)));
360 
361             BufferedTreeNodeStream stream = new BufferedTreeNodeStream(r0);
362 			stream.Seek(7);   // seek to 107
363 			Assert.AreEqual(107, ((ITree)stream.LT(1)).Type);
364 			stream.Consume(); // consume 107
365 			stream.Consume(); // consume Up
366 			stream.Consume(); // consume Up
367 			Assert.AreEqual(104, ((ITree)stream.LT(1)).Type);
368 		}
369 
370 		[Test]
testPushPop()371 		public void testPushPop()
372 		{
373 			// ^(101 ^(102 103) ^(104 105) ^(106 107) 108 109)
374 			// stream has 9 real + 8 nav nodes
375 			// Sequence of types: 101 DN 102 DN 103 Up 104 DN 105 Up 106 DN 107 Up 108 109 Up
376 			ITree r0 = new CommonTree(new CommonToken(101));
377 			ITree r1 = new CommonTree(new CommonToken(102));
378 			r1.AddChild(new CommonTree(new CommonToken(103)));
379 			r0.AddChild(r1);
380 			ITree r2 = new CommonTree(new CommonToken(104));
381 			r2.AddChild(new CommonTree(new CommonToken(105)));
382 			r0.AddChild(r2);
383 			ITree r3 = new CommonTree(new CommonToken(106));
384 			r3.AddChild(new CommonTree(new CommonToken(107)));
385 			r0.AddChild(r3);
386 			r0.AddChild(new CommonTree(new CommonToken(108)));
387 			r0.AddChild(new CommonTree(new CommonToken(109)));
388 
389             BufferedTreeNodeStream stream = new BufferedTreeNodeStream(r0);
390 			String expecting = " 101 2 102 2 103 3 104 2 105 3 106 2 107 3 108 109 3";
391 			String found = stream.ToString();
392 			Assert.AreEqual(expecting, found);
393 
394 			// Assume we want to hit node 107 and then "call 102" then return
395 
396 			int indexOf102 = 2;
397 			int indexOf107 = 12;
398 			for (int k = 1; k <= indexOf107; k++)
399 			{ // consume til 107 node
400 				stream.Consume();
401 			}
402 			// CALL 102
403 			Assert.AreEqual(107, ((ITree)stream.LT(1)).Type);
404 			stream.Push(indexOf102);
405 			Assert.AreEqual(102, ((ITree)stream.LT(1)).Type);
406 			stream.Consume(); // consume 102
407 			Assert.AreEqual(Token.Down, ((ITree)stream.LT(1)).Type);
408 			stream.Consume(); // consume DN
409 			Assert.AreEqual(103, ((ITree)stream.LT(1)).Type);
410 			stream.Consume(); // consume 103
411 			Assert.AreEqual(Token.Up, ((ITree)stream.LT(1)).Type);
412 			// RETURN
413 			stream.Pop();
414 			Assert.AreEqual(107, ((ITree)stream.LT(1)).Type);
415 		}
416 
417 		[Test]
testNestedPushPop()418 		public void testNestedPushPop()
419 		{
420 			// ^(101 ^(102 103) ^(104 105) ^(106 107) 108 109)
421 			// stream has 9 real + 8 nav nodes
422 			// Sequence of types: 101 DN 102 DN 103 Up 104 DN 105 Up 106 DN 107 Up 108 109 Up
423 			ITree r0 = new CommonTree(new CommonToken(101));
424 			ITree r1 = new CommonTree(new CommonToken(102));
425 			r1.AddChild(new CommonTree(new CommonToken(103)));
426 			r0.AddChild(r1);
427 			ITree r2 = new CommonTree(new CommonToken(104));
428 			r2.AddChild(new CommonTree(new CommonToken(105)));
429 			r0.AddChild(r2);
430 			ITree r3 = new CommonTree(new CommonToken(106));
431 			r3.AddChild(new CommonTree(new CommonToken(107)));
432 			r0.AddChild(r3);
433 			r0.AddChild(new CommonTree(new CommonToken(108)));
434 			r0.AddChild(new CommonTree(new CommonToken(109)));
435 
436             BufferedTreeNodeStream stream = new BufferedTreeNodeStream(r0);
437 
438 			// Assume we want to hit node 107 and then "call 102", which
439 			// calls 104, then return
440 
441 			int indexOf102 = 2;
442 			int indexOf107 = 12;
443 			for (int k = 1; k <= indexOf107; k++)
444 			{ // consume til 107 node
445 				stream.Consume();
446 			}
447 			Assert.AreEqual(107, ((ITree)stream.LT(1)).Type);
448 			// CALL 102
449 			stream.Push(indexOf102);
450 			Assert.AreEqual(102, ((ITree)stream.LT(1)).Type);
451 			stream.Consume(); // consume 102
452 			Assert.AreEqual(Token.Down, ((ITree)stream.LT(1)).Type);
453 			stream.Consume(); // consume DN
454 			Assert.AreEqual(103, ((ITree)stream.LT(1)).Type);
455 			stream.Consume(); // consume 103
456 
457 			// CALL 104
458 			int indexOf104 = 6;
459 			stream.Push(indexOf104);
460 			Assert.AreEqual(104, ((ITree)stream.LT(1)).Type);
461 			stream.Consume(); // consume 102
462 			Assert.AreEqual(Token.Down, ((ITree)stream.LT(1)).Type);
463 			stream.Consume(); // consume DN
464 			Assert.AreEqual(105, ((ITree)stream.LT(1)).Type);
465 			stream.Consume(); // consume 103
466 			Assert.AreEqual(Token.Up, ((ITree)stream.LT(1)).Type);
467 			// RETURN (to Up node in 102 subtree)
468 			stream.Pop();
469 
470 			Assert.AreEqual(Token.Up, ((ITree)stream.LT(1)).Type);
471 			// RETURN (to empty stack)
472 			stream.Pop();
473 			Assert.AreEqual(107, ((ITree)stream.LT(1)).Type);
474 		}
475 
476 		[Test]
testPushPopFromEOF()477 		public void testPushPopFromEOF()
478 		{
479 			// ^(101 ^(102 103) ^(104 105) ^(106 107) 108 109)
480 			// stream has 9 real + 8 nav nodes
481 			// Sequence of types: 101 DN 102 DN 103 Up 104 DN 105 Up 106 DN 107 Up 108 109 Up
482 			ITree r0 = new CommonTree(new CommonToken(101));
483 			ITree r1 = new CommonTree(new CommonToken(102));
484 			r1.AddChild(new CommonTree(new CommonToken(103)));
485 			r0.AddChild(r1);
486 			ITree r2 = new CommonTree(new CommonToken(104));
487 			r2.AddChild(new CommonTree(new CommonToken(105)));
488 			r0.AddChild(r2);
489 			ITree r3 = new CommonTree(new CommonToken(106));
490 			r3.AddChild(new CommonTree(new CommonToken(107)));
491 			r0.AddChild(r3);
492 			r0.AddChild(new CommonTree(new CommonToken(108)));
493 			r0.AddChild(new CommonTree(new CommonToken(109)));
494 
495             BufferedTreeNodeStream stream = new BufferedTreeNodeStream(r0);
496 
497 			while (stream.LA(1) != Token.EndOfFile)
498 			{
499 				stream.Consume();
500 			}
501 			int indexOf102 = 2;
502 			int indexOf104 = 6;
503 			Assert.AreEqual(Token.EndOfFile, ((ITree)stream.LT(1)).Type);
504 
505 			// CALL 102
506 			stream.Push(indexOf102);
507 			Assert.AreEqual(102, ((ITree)stream.LT(1)).Type);
508 			stream.Consume(); // consume 102
509 			Assert.AreEqual(Token.Down, ((ITree)stream.LT(1)).Type);
510 			stream.Consume(); // consume DN
511 			Assert.AreEqual(103, ((ITree)stream.LT(1)).Type);
512 			stream.Consume(); // consume 103
513 			Assert.AreEqual(Token.Up, ((ITree)stream.LT(1)).Type);
514 			// RETURN (to empty stack)
515 			stream.Pop();
516 			Assert.AreEqual(Token.EndOfFile, ((ITree)stream.LT(1)).Type);
517 
518 			// CALL 104
519 			stream.Push(indexOf104);
520 			Assert.AreEqual(104, ((ITree)stream.LT(1)).Type);
521 			stream.Consume(); // consume 102
522 			Assert.AreEqual(Token.Down, ((ITree)stream.LT(1)).Type);
523 			stream.Consume(); // consume DN
524 			Assert.AreEqual(105, ((ITree)stream.LT(1)).Type);
525 			stream.Consume(); // consume 103
526 			Assert.AreEqual(Token.Up, ((ITree)stream.LT(1)).Type);
527 			// RETURN (to empty stack)
528 			stream.Pop();
529 			Assert.AreEqual(Token.EndOfFile, ((ITree)stream.LT(1)).Type);
530 		}
531 
532 		[Test]
testStackStretch()533 		public void testStackStretch()
534 		{
535 			// make more than INITIAL_CALL_STACK_SIZE pushes
536 			ITree r0 = new CommonTree(new CommonToken(101));
537             BufferedTreeNodeStream stream = new BufferedTreeNodeStream(r0);
538 			// go 1 over initial size
539             for (int i = 1; i <= BufferedTreeNodeStream.INITIAL_CALL_STACK_SIZE + 1; i++)
540 			{
541 				stream.Push(i);
542 			}
543 			Assert.AreEqual(10, stream.Pop());
544 			Assert.AreEqual(9, stream.Pop());
545 		}
546 
547 		#endregion
548 
549 
550 		#region CommonTreeNodeStream Tests
551 
552 		[Test]
testBufferOverflow()553 		public void testBufferOverflow()
554 		{
555 			StringBuilder buf = new StringBuilder();
556 			StringBuilder buf2 = new StringBuilder();
557 			// make ^(101 102 ... n)
558 			ITree t = new CommonTree(new CommonToken(101));
559 			buf.Append(" 101");
560 			buf2.Append(" 101");
561 			buf2.Append(" ");
562 			buf2.Append(Token.Down);
563             for (int i = 0; i <= CommonTreeNodeStream.DEFAULT_INITIAL_BUFFER_SIZE + 10; i++)
564 			{
565 				t.AddChild(new CommonTree(new CommonToken(102 + i)));
566 				buf.Append(" ");
567 				buf.Append(102 + i);
568 				buf2.Append(" ");
569 				buf2.Append(102 + i);
570 			}
571 			buf2.Append(" ");
572 			buf2.Append(Token.Up);
573 
574             ITreeNodeStream stream = CreateCommonTreeNodeStream(t);
575 			String expecting = buf.ToString();
576 			String found = GetStringOfEntireStreamContentsWithNodeTypesOnly(stream);
577 			Assert.AreEqual(expecting, found);
578 
579 			expecting = buf2.ToString();
580 			found = stream.ToString();
581 			Assert.AreEqual(expecting, found);
582 		}
583 
584 		/// <summary>
585 		/// Test what happens when tail hits the end of the buffer, but there
586 		/// is more room left.
587 		/// </summary>
588 		/// <remarks>
589 		/// Specifically that would mean that head is not at 0 but has
590 		/// advanced somewhere to the middle of the lookahead buffer.
591 		///
592 		/// Use Consume() to advance N nodes into lookahead.  Then use LT()
593 		/// to load at least INITIAL_LOOKAHEAD_BUFFER_SIZE-N nodes so the
594 		/// buffer has to wrap.
595 		/// </remarks>
596 		[Test]
testBufferWrap()597 		public void testBufferWrap()
598 		{
599 			int N = 10;
600 			// make tree with types: 1 2 ... INITIAL_LOOKAHEAD_BUFFER_SIZE+N
601 			ITree t = new CommonTree((IToken)null);
602             for (int i = 0; i < CommonTreeNodeStream.DEFAULT_INITIAL_BUFFER_SIZE + N; i++)
603 			{
604 				t.AddChild(new CommonTree(new CommonToken(i + 1)));
605 			}
606 
607 			// move head to index N
608             ITreeNodeStream stream = CreateCommonTreeNodeStream(t);
609 			for (int i = 1; i <= N; i++)
610 			{ // consume N
611 				ITree node = (ITree)stream.LT(1);
612 				Assert.AreEqual(i, node.Type);
613 				stream.Consume();
614 			}
615 
616 			// now use LT to lookahead past end of buffer
617             int remaining = CommonTreeNodeStream.DEFAULT_INITIAL_BUFFER_SIZE - N;
618 			int wrapBy = 4; // wrap around by 4 nodes
619 			Assert.IsTrue(wrapBy < N, "bad test code; wrapBy must be less than N");
620 			for (int i = 1; i <= remaining + wrapBy; i++)
621 			{ // wrap past end of buffer
622 				ITree node = (ITree)stream.LT(i); // look ahead to ith token
623 				Assert.AreEqual(N + i, node.Type);
624 			}
625 		}
626 
627 		#endregion
628 
629 
630 		#region Helper Methods
631 
CreateBufferedTreeNodeStream(object t)632         protected ITreeNodeStream CreateBufferedTreeNodeStream(object t)
633 		{
634             return new BufferedTreeNodeStream(t);
635 		}
636 
CreateCommonTreeNodeStream(object t)637 		protected ITreeNodeStream CreateCommonTreeNodeStream(object t)
638 		{
639             return new CommonTreeNodeStream(t);
640 		}
641 
GetStringOfEntireStreamContentsWithNodeTypesOnly(ITreeNodeStream nodes)642 		public string GetStringOfEntireStreamContentsWithNodeTypesOnly(ITreeNodeStream nodes)
643 		{
644 			StringBuilder buf = new StringBuilder();
645 			for (int i = 0; i < nodes.Count; i++)
646 			{
647 				object t = nodes.LT(i + 1);
648 				int type = nodes.TreeAdaptor.GetType(t);
649 				if (!((type == Token.Down) || (type == Token.Up)))
650 				{
651 					buf.Append(" ");
652 					buf.Append(type);
653 				}
654 			}
655 			return buf.ToString();
656 		}
657 
658 		#endregion
659 	}
660 }