Home | History | Annotate | Download | only in unit
      1 #!/usr/bin/ruby
      2 # encoding: utf-8
      3 
      4 require 'antlr3'
      5 require 'antlr3/tree/wizard'
      6 require 'test/unit'
      7 require 'spec'
      8 
      9 include ANTLR3
     10 include ANTLR3::AST
     11 
     12 class TestPatternLexer < Test::Unit::TestCase
     13   
     14   # vvvvvvvv tests vvvvvvvvv
     15   
     16   def test_open
     17     lexer = Wizard::PatternLexer.new( '(' )
     18     type = lexer.next_token
     19     assert_equal( type, :open )
     20     assert_equal( lexer.text, '' )
     21     assert_equal( lexer.error, false )
     22   end
     23   
     24   def test_close
     25     lexer = Wizard::PatternLexer.new(')')
     26     type = lexer.next_token
     27     assert_equal(type, :close)
     28     assert_equal(lexer.text, '')
     29     assert_equal(lexer.error, false)
     30   end
     31   
     32   def test_percent
     33     lexer = Wizard::PatternLexer.new('%')
     34     type = lexer.next_token
     35     assert_equal(type, :percent)
     36     assert_equal(lexer.text, '')
     37     assert_equal(lexer.error, false)
     38   end
     39   
     40   def test_dot
     41     lexer = Wizard::PatternLexer.new('.')
     42     type = lexer.next_token
     43     assert_equal(type, :dot)
     44     assert_equal(lexer.text, '')
     45     assert_equal(lexer.error, false)
     46   end
     47   
     48   def test_eof
     49     lexer = Wizard::PatternLexer.new(" \n \r \t ")
     50     type = lexer.next_token
     51     assert_equal(type, EOF)
     52     assert_equal(lexer.text, '')
     53     assert_equal(lexer.error, false)
     54   end
     55   
     56   def test_id
     57     lexer = Wizard::PatternLexer.new('__whatever_1__')
     58     type = lexer.next_token
     59     assert_equal(:identifier, type)
     60     assert_equal('__whatever_1__', lexer.text)
     61     assert( !(lexer.error) )
     62   end
     63   
     64   def test_arg
     65     lexer = Wizard::PatternLexer.new('[ \]bla\n]')
     66     type = lexer.next_token
     67     assert_equal(type, :argument)
     68     assert_equal(' ]bla\n', lexer.text)
     69     assert( !(lexer.error) )
     70   end
     71   
     72   def test_error
     73     lexer = Wizard::PatternLexer.new("1")
     74     type = lexer.next_token
     75     assert_equal(type, EOF)
     76     assert_equal(lexer.text, '')
     77     assert_equal(lexer.error, true)
     78   end
     79   
     80 end
     81 
     82 
     83 class TestPatternParser < Test::Unit::TestCase
     84   Tokens = TokenScheme.build %w(A B C D E ID VAR)
     85   include Tokens
     86   
     87   def setup
     88     @adaptor = CommonTreeAdaptor.new( Tokens.token_class )
     89     @pattern_adaptor = Wizard::PatternAdaptor.new( Tokens.token_class )
     90     @wizard = Wizard.new( :adaptor => @adaptor, :token_scheme => Tokens )
     91   end
     92   
     93   # vvvvvvvv tests vvvvvvvvv
     94   def test_single_node
     95     tree = Wizard::PatternParser.parse( 'ID', Tokens, @adaptor )
     96     
     97     assert_instance_of(CommonTree, tree)
     98     assert_equal( ID, tree.type )
     99     assert_equal( 'ID', tree.text )
    100   end
    101   
    102   def test_single_node_with_arg
    103     tree = Wizard::PatternParser.parse( 'ID[foo]', Tokens, @adaptor )
    104     
    105     assert_instance_of( CommonTree, tree )
    106     assert_equal( ID, tree.type )
    107     assert_equal( 'foo', tree.text )
    108   end
    109   
    110   def test_single_level_tree
    111     tree = Wizard::PatternParser.parse( '(A B)', Tokens, @adaptor )
    112     
    113     assert_instance_of( CommonTree, tree )
    114     assert_equal(A, tree.type)
    115     assert_equal('A', tree.text)
    116     assert_equal(tree.child_count, 1)
    117     assert_equal(tree.child(0).type, B)
    118     assert_equal(tree.child(0).text, 'B')
    119   end
    120   
    121   def test_nil
    122     tree = Wizard::PatternParser.parse( 'nil', Tokens, @adaptor )
    123     
    124     assert_instance_of(CommonTree, tree)
    125     assert_equal(0, tree.type)
    126     assert_nil tree.text
    127   end
    128   
    129   def test_wildcard
    130     tree = Wizard::PatternParser.parse( '(.)', Tokens, @adaptor )
    131     assert_instance_of( Wizard::WildcardPattern, tree )
    132   end
    133   
    134   def test_label
    135     tree = Wizard::PatternParser.parse( '(%a:A)', Tokens, @pattern_adaptor )
    136     assert_instance_of(Wizard::Pattern, tree)
    137     assert_equal('a', tree.label)
    138   end
    139   
    140   def test_error_1
    141     tree = Wizard::PatternParser.parse( ')', Tokens, @adaptor )
    142     assert_nil tree
    143   end
    144   
    145   def test_error_2
    146     tree = Wizard::PatternParser.parse( '()', Tokens, @adaptor )
    147     assert_nil tree
    148   end
    149   
    150   def test_error_3
    151     tree = Wizard::PatternParser.parse( '(A ])', Tokens, @adaptor )
    152     assert_nil tree
    153   end
    154   
    155 end
    156 
    157 
    158 class TestTreeWizard < Test::Unit::TestCase
    159   Tokens = TokenScheme.build %w(A B C D E ID VAR)
    160   include Tokens
    161 
    162   def setup
    163     @adaptor = CommonTreeAdaptor.new( Tokens.token_class )
    164     @wizard = Wizard.new( :adaptor => @adaptor, :token_scheme => Tokens )
    165   end
    166   
    167   def create_wizard( tokens )
    168     Wizard.new( :tokens => tokens )
    169   end
    170   
    171   # vvvvvvvv tests vvvvvvvvv
    172   def test_init
    173     @wizard = Wizard.new( :tokens => %w(A B), :adaptor => @adaptor )
    174     
    175     assert_equal( @wizard.adaptor, @adaptor )
    176     assert_kind_of( ANTLR3::TokenScheme, @wizard.token_scheme )
    177   end
    178   
    179   def test_single_node
    180     t = @wizard.create("ID")
    181     assert_equal(t.inspect, 'ID')
    182   end
    183   
    184   def test_single_node_with_arg
    185     t = @wizard.create("ID[foo]")
    186     
    187     assert_equal(t.inspect, 'foo')
    188   end
    189   
    190   def test_single_node_tree
    191     t = @wizard.create("(A)")
    192     assert_equal(t.inspect, 'A')
    193   end
    194   
    195   def test_single_level_tree
    196     t = @wizard.create("(A B C D)")
    197     assert_equal(t.inspect, '(A B C D)')
    198   end
    199   
    200   def test_list_tree
    201     t = @wizard.create("(nil A B C)")
    202     assert_equal(t.inspect, 'A B C')
    203   end
    204   
    205   def test_invalid_list_tree
    206     t = @wizard.create("A B C")
    207     assert_nil t
    208   end
    209   
    210   def test_double_level_tree
    211     t = @wizard.create("(A (B C) (B D) E)")
    212     assert_equal(t.inspect, "(A (B C) (B D) E)")
    213   end
    214   
    215   SIMPLIFY_MAP = lambda do |imap|
    216     Hash[
    217       imap.map { |type, nodes| [type, nodes.map { |n| n.to_s }] }
    218     ]
    219   end
    220   
    221   def test_single_node_index
    222     tree = @wizard.create("ID")
    223     index_map = SIMPLIFY_MAP[@wizard.index(tree)]
    224     
    225     assert_equal(index_map, ID => %w(ID))
    226   end
    227   
    228   
    229   def test_no_repeats_index
    230     tree = @wizard.create("(A B C D)")
    231     index_map = SIMPLIFY_MAP[@wizard.index(tree)]
    232     
    233     assert_equal(index_map,
    234         D => %w(D), B => %w(B),
    235         C => %w(C), A => %w(A)
    236     )
    237   end
    238   
    239   def test_repeats_index
    240     tree = @wizard.create("(A B (A C B) B D D)")
    241     index_map = SIMPLIFY_MAP[@wizard.index(tree)]
    242     
    243     assert_equal(index_map,
    244         D => %w(D D), B => %w(B B B),
    245         C => %w(C), A => %w(A A)
    246     )
    247   end
    248   
    249   
    250   def test_no_repeats_visit
    251     tree = @wizard.create("(A B C D)")
    252     
    253     elements = []
    254     @wizard.visit( tree, B ) do |node, parent, child_index, labels|
    255       elements << node.to_s
    256     end
    257     
    258     assert_equal( %w(B), elements )
    259   end
    260   
    261   
    262   def test_no_repeats_visit2
    263     tree = @wizard.create("(A B (A C B) B D D)")
    264     
    265     elements = []
    266     @wizard.visit( tree, C ) do |node, parent, child_index, labels|
    267       elements << node.to_s
    268     end
    269     
    270     assert_equal(%w(C), elements)
    271   end
    272   
    273   
    274   def test_repeats_visit
    275     tree = @wizard.create("(A B (A C B) B D D)")
    276     
    277     elements = []
    278     @wizard.visit( tree, B ) do |node, parent, child_index, labels|
    279       elements << node.to_s
    280     end
    281     
    282     assert_equal(%w(B B B), elements)
    283   end
    284   
    285   
    286   def test_repeats_visit2
    287     tree = @wizard.create("(A B (A C B) B D D)")
    288     
    289     elements = []
    290     @wizard.visit( tree, A ) do |node, parent, child_index, labels|
    291       elements << node.to_s
    292     end
    293     
    294     assert_equal(%w(A A), elements)
    295   end
    296   
    297   def context(node, parent, index)
    298     '%s@%s[%d]' % [node.to_s, (parent || 'nil').to_s, index]
    299   end
    300   
    301   def test_repeats_visit_with_context
    302     tree = @wizard.create("(A B (A C B) B D D)")
    303     
    304     elements = []
    305     @wizard.visit( tree, B ) do |node, parent, child_index, labels|
    306       elements << context(node, parent, child_index)
    307     end
    308     
    309     assert_equal(['B@A[0]', 'B@A[1]', 'B@A[2]'], elements)
    310   end
    311   
    312   
    313   def test_repeats_visit_with_null_parent_and_context
    314     tree = @wizard.create("(A B (A C B) B D D)")
    315     
    316     elements = []
    317     @wizard.visit( tree, A ) do |node, parent, child_index, labels|
    318       elements << context(node, parent, child_index)
    319     end
    320     
    321     assert_equal(['A@nil[-1]', 'A@A[1]'], elements)
    322   end
    323   
    324   def test_visit_pattern
    325     tree = @wizard.create("(A B C (A B) D)")
    326     
    327     elements = []
    328     @wizard.visit(tree, '(A B)') do |node, parent, child_index, labels|
    329       elements << node.to_s
    330     end
    331     
    332     assert_equal(%w(A), elements)
    333   end
    334   
    335   
    336   def test_visit_pattern_multiple
    337     tree = @wizard.create("(A B C (A B) (D (A B)))")
    338     
    339     elements = []
    340     @wizard.visit(tree, '(A B)') do |node, parent, child_index, labels|
    341       elements << context(node, parent, child_index)
    342     end
    343     
    344     assert_equal( %w(A@A[2] A@D[0]) , elements )
    345   end
    346   
    347   def labeled_context(node, parent, index, labels, *names)
    348     suffix = names.map { |n| labels[n].to_s }.join('&')
    349     '%s@%s[%d]%s' % [node.to_s, (parent || 'nil').to_s, index, suffix]
    350   end
    351     
    352   def test_visit_pattern_multiple_with_labels
    353     tree = @wizard.create("(A B C (A[foo] B[bar]) (D (A[big] B[dog])))")
    354     
    355     elements = []
    356     @wizard.visit(tree, '(%a:A %b:B)') do |node, parent, child_index, labels|
    357       elements << labeled_context(node, parent, child_index, labels, 'a', 'b')
    358     end
    359     
    360     assert_equal( ['foo@A[2]foo&bar', 'big@D[0]big&dog'] , elements )
    361   end
    362   
    363   
    364   def test_match
    365     tree = @wizard.create("(A B C)")
    366     assert @wizard.match(tree, "(A B C)")
    367   end
    368   
    369   def test_match_single_node
    370     tree = @wizard.create('A')
    371     assert @wizard.match(tree, 'A')
    372   end
    373   
    374   def test_match_single_node_fails
    375     tree = @wizard.create('A')
    376     assert( !(@wizard.match(tree, 'B')) )
    377   end
    378   
    379   
    380   def test_match_flat_tree
    381     tree = @wizard.create('(nil A B C)')
    382     assert @wizard.match(tree, '(nil A B C)')
    383   end
    384   
    385   def test_match_flat_tree_fails
    386     tree = @wizard.create('(nil A B C)')
    387     assert( !(@wizard.match(tree, '(nil A B)')) )
    388   end
    389 
    390   def test_match_flat_tree_fails2
    391     tree = @wizard.create('(nil A B C)')
    392     assert( !(@wizard.match(tree, '(nil A B A)')) )
    393   end
    394   
    395   def test_wildcard
    396     tree = @wizard.create('(A B C)')
    397     assert @wizard.match(tree, '(A . .)')
    398   end
    399   
    400   def test_match_with_text
    401     tree = @wizard.create('(A B[foo] C[bar])')
    402     assert @wizard.match(tree, '(A B[foo] C)')
    403   end
    404   
    405   def test_match_with_text_fails
    406     tree = @wizard.create('(A B C)')
    407     assert( !(@wizard.match(tree, '(A[foo] B C)')) )
    408   end
    409   
    410   def test_match_labels
    411     tree = @wizard.create('(A B C)')
    412     labels = @wizard.match( tree, '(%a:A %b:B %c:C)' )
    413     
    414     assert_equal('A', labels['a'].to_s)
    415     assert_equal('B', labels['b'].to_s)
    416     assert_equal('C', labels['c'].to_s)
    417   end
    418   
    419   def test_match_with_wildcard_labels
    420     tree = @wizard.create('(A B C)')
    421     labels = @wizard.match(tree, '(A %b:. %c:.)')
    422     assert_kind_of( Hash, labels )
    423     assert_equal('B', labels['b'].to_s)
    424     assert_equal('C', labels['c'].to_s)
    425   end
    426   
    427   
    428   def test_match_labels_and_test_text
    429     tree = @wizard.create('(A B[foo] C)')
    430     labels = @wizard.match( tree, '(%a:A %b:B[foo] %c:C)' )
    431     assert_kind_of( Hash, labels )
    432     assert_equal('A', labels['a'].to_s)
    433     assert_equal('foo', labels['b'].to_s)
    434     assert_equal('C', labels['c'].to_s)
    435   end
    436   
    437   def test_match_labels_in_nested_tree
    438     tree = @wizard.create('(A (B C) (D E))')
    439     labels = @wizard.match( tree, '(%a:A (%b:B %c:C) (%d:D %e:E))' )
    440     assert_kind_of( Hash, labels )
    441     assert_equal('A', labels['a'].to_s)
    442     assert_equal('B', labels['b'].to_s)
    443     assert_equal('C', labels['c'].to_s)
    444     assert_equal('D', labels['d'].to_s)
    445     assert_equal('E', labels['e'].to_s)
    446   end
    447   
    448   
    449   def test_equals
    450     tree1 = @wizard.create("(A B C)")
    451     tree2 = @wizard.create("(A B C)")
    452     assert @wizard.equals(tree1, tree2)
    453   end
    454   
    455   
    456   def test_equals_with_text
    457     tree1 = @wizard.create("(A B[foo] C)")
    458     tree2 = @wizard.create("(A B[foo] C)")
    459     assert @wizard.equals(tree1, tree2)
    460   end
    461   
    462   
    463   def test_equals_with_mismatched_text
    464     tree1 = @wizard.create("(A B[foo] C)")
    465     tree2 = @wizard.create("(A B C)")
    466     assert( !(@wizard.equals(tree1, tree2)) )
    467   end
    468   
    469   
    470   def test_equals_with_mismatched_list
    471     tree1 = @wizard.create("(A B C)")
    472     tree2 = @wizard.create("(A B A)")
    473     assert( !(@wizard.equals(tree1, tree2)) )
    474   end
    475   
    476   def test_equals_with_mismatched_list_length
    477     tree1 = @wizard.create("(A B C)")
    478     tree2 = @wizard.create("(A B)")
    479     assert( !(@wizard.equals(tree1, tree2)) )
    480   end
    481   
    482   def test_find_pattern
    483     tree = @wizard.create("(A B C (A[foo] B[bar]) (D (A[big] B[dog])))")
    484     subtrees = @wizard.find(tree, "(A B)").map { |t| t.to_s }
    485     assert_equal(%w(foo big), subtrees)
    486   end
    487   
    488   def test_find_token_type
    489     tree = @wizard.create("(A B C (A[foo] B[bar]) (D (A[big] B[dog])))")
    490     subtrees = @wizard.find( tree, A ).map { |t| t.to_s }
    491     assert_equal(%w(A foo big), subtrees)
    492   end
    493 end
    494 
    495