1#!/usr/bin/ruby
2# encoding: utf-8
3
4require 'antlr3'
5require 'test/unit'
6require 'spec'
7
8include ANTLR3
9include ANTLR3::AST
10
11class TestTreeNodeStream < Test::Unit::TestCase
12  def setup
13    @adaptor = CommonTreeAdaptor.new
14  end
15  
16  def new_stream(t)
17    CommonTreeNodeStream.new(t)
18  end
19  
20  def test_single_node
21    t = CommonTree.new(CommonToken.new { |t| t.type = 101 })
22    stream = new_stream(t)
23    expecting = '101'
24    
25    found = nodes_only_string(stream)
26    
27    found.should == expecting
28    
29    expecting = '<UNKNOWN: 101>'
30    found = stream.inspect
31    
32    found.should == expecting
33  end
34  
35  def test_two_children_of_nil_root
36    v = Class.new(CommonTree) do
37      def initialize(token = nil, type = nil, x = nil)
38        @x = x
39        super(token || (CommonToken.new { |t| t.type = type } if type))
40      end
41      def to_s
42        (@token.text rescue '') + '<V>'
43      end
44    end
45    
46    root_0 = @adaptor.create_flat_list
47    t = v.new(nil, 101, 2)
48    u = v.new CommonToken.create(:type => 102, :text => '102')
49    @adaptor.add_child(root_0, t)
50    @adaptor.add_child(root_0, u)
51    
52    assert(root_0.parent.nil?)
53    root_0.child_index.should == -1
54    t.child_index.should == 0
55    u.child_index.should == 1
56    
57  end
58  
59  def test_4_nodes
60    t = CommonTree.new CommonToken[101]
61    t.add_child( CommonTree.new CommonToken[102] )
62    t.child(0).add_child(CommonTree.new CommonToken[103])
63    t.add_child(CommonTree.new CommonToken[104])
64    
65    stream = new_stream(t)
66
67    expecting = "101 102 103 104"
68    found = nodes_only_string(stream)
69    found.should == expecting
70    
71    expecting = "<UNKNOWN: 101> <DOWN> <UNKNOWN: 102> <DOWN> <UNKNOWN: 103> <UP> <UNKNOWN: 104> <UP>"
72    found = stream.inspect
73    found.should == expecting
74  end
75  
76  def test_list
77    root = CommonTree.new(nil)
78    t = CommonTree.new CommonToken[101]
79    t.add_child CommonTree.new(CommonToken[102])
80    t.child(0).add_child(CommonTree.new(CommonToken[103]))
81    t.add_child(CommonTree.new(CommonToken[104]))
82    
83    u = CommonTree.new CommonToken[105]
84    
85    root.add_child(t)
86    root.add_child(u)
87    
88    stream = CommonTreeNodeStream.new(root)
89    
90    expecting = '101 102 103 104 105'
91    found = nodes_only_string(stream)
92    found.should == expecting
93    
94    expecting = "<UNKNOWN: 101> <DOWN> <UNKNOWN: 102> <DOWN> <UNKNOWN: 103> <UP> <UNKNOWN: 104> <UP> <UNKNOWN: 105>"
95    found = stream.inspect
96    found.should == expecting
97  end
98  
99  def test_flat_list
100    root = CommonTree.new(nil)
101    
102    root.add_child CommonTree.new(CommonToken[101])
103    root.add_child(CommonTree.new(CommonToken[102]))
104    root.add_child(CommonTree.new(CommonToken[103]))
105    
106    stream = CommonTreeNodeStream.new( root )
107    
108    expecting = '101 102 103'
109    found = nodes_only_string(stream)
110    found.should == expecting
111    
112    expecting = '<UNKNOWN: 101> <UNKNOWN: 102> <UNKNOWN: 103>'
113    found = stream.inspect
114    found.should == expecting
115  end
116  
117  def test_list_with_one_node
118    root = CommonTree.new(nil)
119    
120    root.add_child(CommonTree.new(CommonToken[101]))
121    
122    stream = CommonTreeNodeStream.new(root)
123    
124    expecting = '101'
125    found = nodes_only_string(stream)
126    found.should == expecting
127    
128    expecting = "<UNKNOWN: 101>"
129    found = stream.inspect
130    found.should == expecting
131  end
132  
133  def test_a_over_b
134    t = CommonTree.new(CommonToken[101])
135    t.add_child(CommonTree.new(CommonToken[102]))
136    
137    stream = new_stream(t)
138    expecting = '101 102'
139    found = nodes_only_string(stream)
140    found.should == expecting
141    
142    expecting = '<UNKNOWN: 101> <DOWN> <UNKNOWN: 102> <UP>'
143    found = stream.inspect
144    found.should == expecting
145  end
146  
147  def test_LT
148    # ^(101 ^(102 103) 104)
149    t = CommonTree.new CommonToken[101]
150    t.add_child CommonTree.new(CommonToken[102])
151    t.child(0).add_child(CommonTree.new(CommonToken[103]))
152    t.add_child(CommonTree.new(CommonToken[104]))
153    
154    stream = new_stream(t)
155    [101, DOWN, 102, DOWN, 103, UP, 104, UP, EOF].each_with_index do |type, index|
156      stream.look(index + 1).type.should == type
157    end
158    stream.look(100).type.should == EOF
159  end
160  
161  def test_mark_rewind_entire
162    # ^(101 ^(102 103 ^(106 107)) 104 105)
163    r0 = new_node new_token(101)
164    r1 = new_node new_token(102)
165    r0.add_child(r1)
166    r1.add_child(new_node new_token(103))
167    r2 = new_node new_token(106)
168    r2.add_child new_node( new_token 107 )
169    r1.add_child r2
170    r0.add_child new_node( new_token 104 )
171    r0.add_child new_node( new_token 105 )
172    
173    stream = CommonTreeNodeStream.new(r0)
174    m = stream.mark
175    13.times { stream.look(1); stream.consume } # consume until end
176    
177    stream.look(1).type.should == EOF
178    stream.look(-1).type.should == UP
179    stream.rewind(m)
180    
181    13.times { stream.look(1); stream.consume } # consume until end
182    
183    stream.look(1).type.should == EOF
184    stream.look(-1).type.should == UP
185  end
186  
187  def test_mark_rewind_in_middle
188    # ^(101 ^(102 103 ^(106 107)) 104 105)
189    r0 = new_node new_token(101)
190    r1 = new_node new_token(102)
191    r0.add_child r1
192    r1.add_child new_node( new_token 103 )
193    r2 = new_node new_token(106)
194    r2.add_child new_node( new_token 107 )
195    r1.add_child r2
196    r0.add_child new_node( new_token 104 )
197    r0.add_child new_node( new_token 105 )
198    
199    stream = CommonTreeNodeStream.new(r0)
200    7.times { stream.consume }
201    
202    stream.look(1).type.should == 107
203    m = stream.mark
204    4.times { stream.consume }
205    stream.rewind(m)
206    
207    [107, UP, UP, 104].each do |val|
208      stream.look(1).type.should == val
209      stream.consume
210    end
211    # past rewind position now
212    [105, UP].each do |val|
213      stream.look(1).type.should == val
214      stream.consume
215    end
216    stream.look(1).type.should == EOF
217    stream.look(-1).type.should == UP
218  end
219  
220  def test_mark_rewind_nested
221    # ^(101 ^(102 103 ^(106 107)) 104 105)
222    r0 = new_node new_token(101)
223    r1 = new_node new_token(102)
224    r0.add_child r1
225    r1.add_child new_node( new_token 103 )
226    r2 = new_node new_token(106)
227    r2.add_child new_node( new_token 107 )
228    r1.add_child r2
229    r0.add_child new_node( new_token 104 )
230    r0.add_child new_node( new_token 105 )
231    
232    stream = CommonTreeNodeStream.new(r0)
233    m = stream.mark
234    2.times { stream.consume }
235    m2 = stream.mark
236    4.times { stream.consume }
237    stream.rewind(m2)
238    stream.look(1).type.should == 102
239    stream.consume
240    stream.look(1).type.should == DOWN
241    stream.consume
242    
243    stream.rewind(m)
244    [101, DOWN, 102].each do |val|
245      stream.look(1).type.should == val
246      stream.consume
247    end
248    stream.look(1).type.should == DOWN
249  end
250  
251  def test_seek
252    # ^(101 ^(102 103 ^(106 107) ) 104 105)
253    # stream has 7 real + 6 nav nodes
254    # Sequence of types: 101 DN 102 DN 103 106 DN 107 UP UP 104 105 UP EOF
255
256    r0 = new_node new_token(101)
257    r1 = new_node new_token(102)
258    r0.add_child r1
259    r1.add_child new_node( new_token 103 )
260    r2 = new_node new_token(106)
261    r2.add_child new_node( new_token 107 )
262    r1.add_child r2
263    r0.add_child new_node( new_token 104 )
264    r0.add_child new_node( new_token 105 )
265    
266    stream = CommonTreeNodeStream.new(r0)
267    3.times { stream.consume }
268    stream.seek(7)
269    stream.look(1).type.should == 107
270    3.times { stream.consume }
271    stream.look(1).type.should == 104
272  end
273  
274  def test_seek_from_start
275    r0 = new_node new_token(101)
276    r1 = new_node new_token(102)
277    r0.add_child r1
278    r1.add_child new_node( new_token 103 )
279    r2 = new_node new_token(106)
280    r2.add_child new_node( new_token 107 )
281    r1.add_child r2
282    r0.add_child new_node( new_token 104 )
283    r0.add_child new_node( new_token 105 )
284    
285    stream = CommonTreeNodeStream.new(r0)
286    stream.seek(7)
287    stream.look(1).type.should == 107
288    3.times { stream.consume }
289    stream.look(1).type.should == 104
290  end
291  
292  def nodes_only_string(nodes)
293    buffer = []
294    nodes.size.times do |index|
295      t = nodes.look(index + 1)
296      type = nodes.tree_adaptor.type_of(t)
297      buffer << type.to_s unless type == DOWN or type == UP
298    end
299    return buffer.join(' ')
300  end
301  
302  def new_token(type, opts = {})
303    opts[:type] = type
304    CommonToken.create(opts)
305  end
306  def new_node(token)
307    CommonTree.new(token)
308  end
309
310
311end
312
313class TestCommonTreeNodeStream < Test::Unit::TestCase
314  def setup
315    # before-each-test code
316  end
317  def teardown
318    # after-each-test code
319  end
320  
321  # vvvvvvvv tests vvvvvvvvv
322  
323  def test_push_pop
324    r0 = new_node new_token(101)
325    r1 = new_node new_token(102)
326    r1.add_child new_node( new_token 103 )
327    r0.add_child r1
328    r2 = new_node new_token(104)
329    r2.add_child new_node( new_token 105 )
330    r0.add_child r2
331    r3 = new_node new_token(106)
332    r3.add_child new_node( new_token 107 )
333    r0.add_child r3
334    r0.add_child new_node( new_token 108 )
335    r0.add_child new_node( new_token 109 )
336    
337    stream = CommonTreeNodeStream.new(r0)
338    expecting = '<UNKNOWN: 101> <DOWN> <UNKNOWN: 102> <DOWN> <UNKNOWN: 103> <UP> <UNKNOWN: 104> ' +
339                '<DOWN> <UNKNOWN: 105> <UP> <UNKNOWN: 106> <DOWN> <UNKNOWN: 107> <UP> ' +
340                '<UNKNOWN: 108> <UNKNOWN: 109> <UP>'
341    found = stream.inspect
342    found.should == expecting
343    
344    index_of_102 = 2
345    index_of_107 = 12
346    index_of_107.times { stream.consume }
347    
348    stream.look(1).type.should == 107
349    stream.push(index_of_102)
350    stream.look(1).type.should == 102
351    stream.consume
352    stream.look(1).type.should == DOWN
353    stream.consume
354    stream.look(1).type.should == 103
355    stream.consume
356    stream.look(1).type.should == UP
357    stream.pop
358    stream.look(1).type.should == 107
359  end
360  
361  def test_nested_push_pop
362    r0 = new_node new_token(101)
363    r1 = new_node new_token(102)
364    r1.add_child new_node( new_token 103 )
365    r0.add_child r1
366    r2 = new_node new_token(104)
367    r2.add_child new_node( new_token 105 )
368    r0.add_child r2
369    r3 = new_node new_token(106)
370    r3.add_child new_node( new_token 107 )
371    r0.add_child r3
372    r0.add_child new_node( new_token 108 )
373    r0.add_child new_node( new_token 109 )
374    
375    stream = CommonTreeNodeStream.new(r0)
376    
377    index_of_102 = 2
378    index_of_107 = 12
379    
380    index_of_107.times { stream.consume }
381    
382    stream.look(1).type.should == 107
383    stream.push(index_of_102)
384    [102, DOWN, 103].each do |val|
385      stream.look(1).type.should == val
386      stream.consume
387    end
388    
389    index_of_104 = 6
390    stream.push(index_of_104)
391    [104,DOWN,105].each do |val|
392      stream.look(1).type.should == val
393      stream.consume
394    end
395    stream.look(1).type.should == UP
396    stream.pop
397    
398    stream.look(1).type.should == UP
399    stream.pop
400    stream.look(1).type.should == 107
401  end
402  
403  def test_push_pop_from_eof
404    r0 = new_node new_token(101)
405    r1 = new_node new_token(102)
406    r1.add_child new_node( new_token 103 )
407    r0.add_child r1
408    r2 = new_node new_token(104)
409    r2.add_child new_node( new_token 105 )
410    r0.add_child r2
411    r3 = new_node new_token(106)
412    r3.add_child new_node( new_token 107 )
413    r0.add_child r3
414    r0.add_child new_node( new_token 108 )
415    r0.add_child new_node( new_token 109 )
416    
417    stream = CommonTreeNodeStream.new(r0)
418    stream.consume until stream.peek(1) == EOF
419    
420    index_of_102 = 2
421    index_of_104 = 6
422    stream.look(1).type.should == EOF
423    
424    stream.push(index_of_102)
425    [102, DOWN, 103].each do |val|
426      stream.look(1).type.should == val
427      stream.consume
428    end
429    stream.look(1).type.should == UP
430    
431    stream.pop
432    stream.look(1).type.should == EOF
433    
434    stream.push(index_of_104)
435    [104, DOWN, 105].each do |val|
436      stream.look(1).type.should == val
437      stream.consume
438    end
439    stream.look(1).type.should == UP
440    
441    stream.pop
442    stream.look(1).type.should == EOF
443  end
444  
445  
446  def new_token(type, opts = {})
447    opts[:type] = type
448    CommonToken.create(opts)
449  end
450  def new_node(token)
451    CommonTree.new(token)
452  end
453end
454
455
456class TestCommonTree < Test::Unit::TestCase
457  def setup
458    @adaptor = CommonTreeAdaptor.new
459  end
460  def teardown
461    # after-each-test code
462  end
463  
464  # vvvvvvvv tests vvvvvvvvv
465  
466  def test_single_node
467    t = new_node( new_token 101 )
468    assert_nil t.parent
469    t.child_index.should == -1
470  end
471  
472  def test_4_nodes
473    # ^(101 ^(102 103) 104)
474    r0 = new_node( new_token 101 )
475    r0.add_child new_node( new_token 102 )
476    r0.child(0).add_child new_node( new_token 103 )
477    r0.add_child new_node( new_token 104 )
478    
479    assert_nil r0.parent
480    r0.child_index.should == -1
481  end
482  
483  def test_list
484    # ^(nil 101 102 103)
485    r0 = CommonTree.new(nil)
486    c0 = new_node( new_token 101 )
487    r0.add_child c0
488    c1 = new_node( new_token 102 )
489    r0.add_child c1
490    c2 = new_node( new_token 103 )
491    r0.add_child c2
492    
493    assert_nil r0.parent
494    r0.child_index.should == -1
495    c0.parent.should == r0
496    c0.child_index.should == 0
497    c1.parent.should == r0
498    c1.child_index.should == 1
499    c2.parent.should == r0
500    c2.child_index.should == 2
501  end
502  
503  def test_list2
504    # ^(nil 101 102 103)
505    root = new_node( new_token 5 )
506    r0 = CommonTree.new(nil)
507    c0 = new_node( new_token 101 )
508    r0.add_child c0
509    c1 = new_node( new_token 102 )
510    r0.add_child c1
511    c2 = new_node( new_token 103 )
512    r0.add_child c2
513    
514    root.add_child r0
515    
516    assert_nil root.parent
517    root.child_index.should == -1
518    c0.parent.should == root
519    c0.child_index.should == 0
520    c1.parent.should == root            # note -- actual python tests all use c0 here, which i think might be wrong
521    c1.child_index.should == 1
522    c2.parent.should == root            # note -- actual python tests all use c0 here, which i think might be wrong
523    c2.child_index.should == 2
524  end
525  
526  def test_add_list_to_exist_children
527    root = new_node( new_token 5 )
528    root.add_child new_node( new_token 6 )
529    
530    r0 = CommonTree.new(nil)
531    c0 = new_node( new_token 101 )
532    r0.add_child c0
533    c1 = new_node( new_token 102 )
534    r0.add_child c1
535    c2 = new_node( new_token 103 )
536    r0.add_child c2
537    # ^(nil c0=101 c1=102 c2=103)
538    
539    root.add_child(r0)
540    
541    assert_nil root.parent
542    root.child_index.should == -1
543    c0.parent.should == root
544    c0.child_index.should == 1
545    c1.parent.should == root
546    c1.child_index.should == 2
547    c2.parent.should == root
548    c2.child_index.should == 3
549  end
550  
551  def test_copy_tree
552    r0 = new_node( new_token 101 )
553    r1 = new_node( new_token 102 )
554    r2 = new_node( new_token 106 )
555    r0.add_child( r1 )
556    r1.add_child( new_node( new_token 103 ) )
557    r2.add_child( new_node( new_token 107 ) )
558    r1.add_child( r2 )
559    r0.add_child( new_node( new_token 104 ) )
560    r0.add_child( new_node( new_token 105 ) )
561    
562    dup = @adaptor.copy_tree( r0 )
563    assert_nil dup.parent
564    dup.child_index.should == -1
565    dup.sanity_check
566  end
567  
568  def test_become_root
569    new_root = new_node( new_token 5 )
570    
571    old_root = new_node nil
572    old_root.add_child( new_node( new_token 101 ) )
573    old_root.add_child( new_node( new_token 102 ) )
574    old_root.add_child( new_node( new_token 103 ) )
575    
576    @adaptor.become_root(new_root, old_root)
577    new_root.sanity_check
578  end
579  
580  def test_become_root2
581    new_root = new_node( new_token 5 )
582    
583    old_root = new_node( new_token 101 )
584    old_root.add_child( new_node( new_token 102 ) )
585    old_root.add_child( new_node( new_token 103 ) )
586    
587    @adaptor.become_root(new_root, old_root)
588    new_root.sanity_check
589  end
590  
591  def test_become_root3
592    new_root = new_node nil
593    new_root.add_child( new_node( new_token 5 ) )
594    
595    old_root = new_node nil
596    old_root.add_child( new_node( new_token 101 ) )
597    old_root.add_child( new_node( new_token 102 ) )
598    old_root.add_child( new_node( new_token 103 ) )
599    
600    @adaptor.become_root(new_root, old_root)
601    new_root.sanity_check
602  end
603  
604  def test_become_root5
605    new_root = new_node nil
606    new_root.add_child( new_node( new_token 5 ) )
607    
608    old_root = new_node( new_token 101 )
609    old_root.add_child( new_node( new_token 102 ) )
610    old_root.add_child( new_node( new_token 103 ) )
611    
612    @adaptor.become_root(new_root, old_root)
613    new_root.sanity_check
614  end
615  
616  def test_become_root6
617    root_0 = @adaptor.create_flat_list
618    root_1 = @adaptor.create_flat_list
619    root_1 = @adaptor.become_root( new_node( new_token 5 ), root_1 )
620    
621    @adaptor.add_child( root_1, new_node( new_token 6 ) )
622    @adaptor.add_child( root_0, root_1 )
623    root_0.sanity_check
624  end
625  
626  def test_replace_with_no_children
627    t = new_node( new_token 101 )
628    new_child = new_node( new_token 5 )
629    error = false
630    assert_raise(IndexError) do
631      t.replace_children(0, 0, new_child)
632    end
633  end
634  
635  def test_replace_with_one_children
636    t = new_node( new_token 99, :text => 'a' )
637    c0 = new_node( new_token 99, :text => 'b' )
638    t.add_child(c0)
639    
640    new_child = new_node( new_token 99, :text => 'c' )
641    t.replace_children(0,0,new_child)
642    
643    t.inspect.should == '(a c)'
644    t.sanity_check
645
646  end
647  def test_replace_in_middle
648    t = new_node( new_token 99, :text => 'a' )
649    t.add_child new_node( new_token 99, :text => 'b' )
650    t.add_child new_node( new_token 99, :text => 'c' )
651    t.add_child new_node( new_token 99, :text => 'd' )
652    
653    new_child = new_node( new_token 99, :text => 'x' )
654    t.replace_children(1, 1, new_child)
655    t.inspect.should == '(a b x d)'
656    t.sanity_check
657  end
658  
659  def test_replace_at_left
660    t = new_node( new_token 99, :text => 'a' )
661    t.add_child new_node( new_token 99, :text => 'b' )
662    t.add_child new_node( new_token 99, :text => 'c' )
663    t.add_child new_node( new_token 99, :text => 'd' )
664    
665    new_child = new_node( new_token 99, :text => 'x' )
666    t.replace_children(0, 0, new_child)
667    t.inspect.should == '(a x c d)'
668    t.sanity_check
669  end
670  
671  def test_replace_at_left
672    t = new_node( new_token 99, :text => 'a' )
673    t.add_child new_node( new_token 99, :text => 'b' )
674    t.add_child new_node( new_token 99, :text => 'c' )
675    t.add_child new_node( new_token 99, :text => 'd' )
676    
677    new_child = new_node( new_token 99, :text => 'x' )
678    t.replace_children(2, 2, new_child)
679    t.inspect.should == '(a b c x)'
680    t.sanity_check
681  end
682  
683  def test_replace_one_with_two_at_left
684    t = new_node( new_token 99, :text => 'a' )
685    t.add_child new_node( new_token 99, :text => 'b' )
686    t.add_child new_node( new_token 99, :text => 'c' )
687    t.add_child new_node( new_token 99, :text => 'd' )
688    
689    new_children = @adaptor.create_flat_list
690    new_children.add_child new_node( new_token 99, :text => 'x' )
691    new_children.add_child new_node( new_token 99, :text => 'y' )
692    
693    t.replace_children(0, 0, new_children)
694    t.inspect.should == '(a x y c d)'
695    t.sanity_check
696  end
697  
698  def test_replace_one_with_two_at_right
699    t = new_node( new_token 99, :text => 'a' )
700    t.add_child new_node( new_token 99, :text => 'b' )
701    t.add_child new_node( new_token 99, :text => 'c' )
702    t.add_child new_node( new_token 99, :text => 'd' )
703    
704    new_children = @adaptor.create_flat_list
705    new_children.add_child new_node( new_token 99, :text => 'x' )
706    new_children.add_child new_node( new_token 99, :text => 'y' )
707    
708    t.replace_children(2, 2, new_children)
709    t.inspect.should == '(a b c x y)'
710    t.sanity_check
711  end
712  
713  def test_replace_one_with_two_in_middle
714    t = new_node( new_token 99, :text => 'a' )
715    t.add_child new_node( new_token 99, :text => 'b' )
716    t.add_child new_node( new_token 99, :text => 'c' )
717    t.add_child new_node( new_token 99, :text => 'd' )
718    
719    new_children = @adaptor.create_flat_list
720    new_children.add_child new_node( new_token 99, :text => 'x' )
721    new_children.add_child new_node( new_token 99, :text => 'y' )
722    
723    t.replace_children(1, 1, new_children)
724    t.inspect.should == '(a b x y d)'
725    t.sanity_check
726  end
727  
728  def test_replace_two_with_one_at_left
729    t = new_node( new_token 99, :text => 'a' )
730    t.add_child new_node( new_token 99, :text => 'b' )
731    t.add_child new_node( new_token 99, :text => 'c' )
732    t.add_child new_node( new_token 99, :text => 'd' )
733    
734    new_child = new_node( new_token 99, :text => 'x' )
735    
736    t.replace_children(0, 1, new_child)
737    t.inspect.should == '(a x d)'
738    t.sanity_check
739  end
740  
741  def test_replace_two_with_one_at_right
742    t = new_node( new_token 99, :text => 'a' )
743    t.add_child new_node( new_token 99, :text => 'b' )
744    t.add_child new_node( new_token 99, :text => 'c' )
745    t.add_child new_node( new_token 99, :text => 'd' )
746    
747    new_child = new_node( new_token 99, :text => 'x' )
748    
749    t.replace_children(1, 2, new_child)
750    t.inspect.should == '(a b x)'
751    t.sanity_check
752  end
753  
754  def test_replace_all_with_one
755    t = new_node( new_token 99, :text => 'a' )
756    t.add_child new_node( new_token 99, :text => 'b' )
757    t.add_child new_node( new_token 99, :text => 'c' )
758    t.add_child new_node( new_token 99, :text => 'd' )
759    
760    new_child = new_node( new_token 99, :text => 'x' )
761    
762    t.replace_children(0, 2, new_child)
763    t.inspect.should == '(a x)'
764    t.sanity_check
765  end
766  
767  def test_replace_all_with_two
768    t = new_node( new_token 99, :text => 'a' )
769    t.add_child new_node( new_token 99, :text => 'b' )
770    t.add_child new_node( new_token 99, :text => 'c' )
771    t.add_child new_node( new_token 99, :text => 'd' )
772    
773    new_children = @adaptor.create_flat_list
774    new_children.add_child new_node( new_token 99, :text => 'x' )
775    new_children.add_child new_node( new_token 99, :text => 'y' )
776    
777    t.replace_children(0, 1, new_children)
778    t.inspect.should == '(a x y d)'
779    t.sanity_check
780  end
781  
782  def new_token(type, opts = {})
783    opts[:type] = type
784    CommonToken.create(opts)
785  end
786  def new_node(token)
787    CommonTree.new(token)
788  end
789end
790
791
792class TestTreeContext < Test::Unit::TestCase
793  TOKEN_NAMES = %w(
794    <invalid> <EOR> <DOWN> <UP> VEC ASSIGN PRINT
795    PLUS MULT DOT ID INT WS '[' ',' ']'
796  )
797  Tokens = TokenScheme.build( TOKEN_NAMES )
798  
799  def setup
800    @wizard = Wizard.new( :token_scheme => Tokens )
801  end
802  
803  def teardown
804    # after-each-test code
805  end
806  
807  # vvvvvvvv tests vvvvvvvvv
808  
809  def test_simple_parent
810    tree = @wizard.create(
811      "(nil (ASSIGN ID[x] INT[3]) (PRINT (MULT ID[x] (VEC INT[1] INT[2] INT[3]))))"
812    )
813    labels = @wizard.match( tree,
814      "(nil (ASSIGN ID[x] INT[3]) (PRINT (MULT ID (VEC INT %x:INT INT))))"
815    )
816    
817    assert_kind_of( Hash, labels )
818    @wizard.in_context?( labels.fetch( 'x' ), 'VEC' ).should be_true
819  end
820  
821  def test_no_parent
822    tree = @wizard.create(
823      '(PRINT (MULT ID[x] (VEC INT[1] INT[2] INT[3])))'
824    )
825    
826    labels = @wizard.match( tree, "(%x:PRINT (MULT ID (VEC INT INT INT)))" )
827    assert_kind_of( Hash, labels )
828    @wizard.in_context?( labels.fetch( 'x' ), 'VEC' ).should be_false
829  end
830  
831  def test_parent_with_wildcard
832    tree = @wizard.create(
833      "(nil (ASSIGN ID[x] INT[3]) (PRINT (MULT ID[x] (VEC INT[1] INT[2] INT[3]))))"
834    )
835    
836    labels = @wizard.match( tree,
837      "(nil (ASSIGN ID[x] INT[3]) (PRINT (MULT ID (VEC INT %x:INT INT))))"
838    )
839    assert_kind_of( Hash, labels )
840    node = labels.fetch( 'x' )
841    @wizard.in_context?( node, 'VEC ...' ).should be_true
842  end
843end
844