1/*
2[The "BSD licence"]
3Copyright (c) 2005-2007 Kunle Odutola
4All rights reserved.
5
6Redistribution and use in source and binary forms, with or without
7modification, are permitted provided that the following conditions
8are met:
91. Redistributions of source code MUST RETAIN the above copyright
10   notice, this list of conditions and the following disclaimer.
112. 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.
153. The name of the author may not be used to endorse or promote products
16   derived from this software without specific prior WRITTEN permission.
174. 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
22THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32*/
33
34
35namespace 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]
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>
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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
632        protected ITreeNodeStream CreateBufferedTreeNodeStream(object t)
633		{
634            return new BufferedTreeNodeStream(t);
635		}
636
637		protected ITreeNodeStream CreateCommonTreeNodeStream(object t)
638		{
639            return new CommonTreeNodeStream(t);
640		}
641
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}