You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

495 lines
12 KiB

#!/usr/bin/ruby
# encoding: utf-8
require 'antlr3'
require 'antlr3/tree/wizard'
require 'test/unit'
require 'spec'
include ANTLR3
include ANTLR3::AST
class TestPatternLexer < Test::Unit::TestCase
# vvvvvvvv tests vvvvvvvvv
def test_open
lexer = Wizard::PatternLexer.new( '(' )
type = lexer.next_token
assert_equal( type, :open )
assert_equal( lexer.text, '' )
assert_equal( lexer.error, false )
end
def test_close
lexer = Wizard::PatternLexer.new(')')
type = lexer.next_token
assert_equal(type, :close)
assert_equal(lexer.text, '')
assert_equal(lexer.error, false)
end
def test_percent
lexer = Wizard::PatternLexer.new('%')
type = lexer.next_token
assert_equal(type, :percent)
assert_equal(lexer.text, '')
assert_equal(lexer.error, false)
end
def test_dot
lexer = Wizard::PatternLexer.new('.')
type = lexer.next_token
assert_equal(type, :dot)
assert_equal(lexer.text, '')
assert_equal(lexer.error, false)
end
def test_eof
lexer = Wizard::PatternLexer.new(" \n \r \t ")
type = lexer.next_token
assert_equal(type, EOF)
assert_equal(lexer.text, '')
assert_equal(lexer.error, false)
end
def test_id
lexer = Wizard::PatternLexer.new('__whatever_1__')
type = lexer.next_token
assert_equal(:identifier, type)
assert_equal('__whatever_1__', lexer.text)
assert( !(lexer.error) )
end
def test_arg
lexer = Wizard::PatternLexer.new('[ \]bla\n]')
type = lexer.next_token
assert_equal(type, :argument)
assert_equal(' ]bla\n', lexer.text)
assert( !(lexer.error) )
end
def test_error
lexer = Wizard::PatternLexer.new("1")
type = lexer.next_token
assert_equal(type, EOF)
assert_equal(lexer.text, '')
assert_equal(lexer.error, true)
end
end
class TestPatternParser < Test::Unit::TestCase
Tokens = TokenScheme.build %w(A B C D E ID VAR)
include Tokens
def setup
@adaptor = CommonTreeAdaptor.new( Tokens.token_class )
@pattern_adaptor = Wizard::PatternAdaptor.new( Tokens.token_class )
@wizard = Wizard.new( :adaptor => @adaptor, :token_scheme => Tokens )
end
# vvvvvvvv tests vvvvvvvvv
def test_single_node
tree = Wizard::PatternParser.parse( 'ID', Tokens, @adaptor )
assert_instance_of(CommonTree, tree)
assert_equal( ID, tree.type )
assert_equal( 'ID', tree.text )
end
def test_single_node_with_arg
tree = Wizard::PatternParser.parse( 'ID[foo]', Tokens, @adaptor )
assert_instance_of( CommonTree, tree )
assert_equal( ID, tree.type )
assert_equal( 'foo', tree.text )
end
def test_single_level_tree
tree = Wizard::PatternParser.parse( '(A B)', Tokens, @adaptor )
assert_instance_of( CommonTree, tree )
assert_equal(A, tree.type)
assert_equal('A', tree.text)
assert_equal(tree.child_count, 1)
assert_equal(tree.child(0).type, B)
assert_equal(tree.child(0).text, 'B')
end
def test_nil
tree = Wizard::PatternParser.parse( 'nil', Tokens, @adaptor )
assert_instance_of(CommonTree, tree)
assert_equal(0, tree.type)
assert_nil tree.text
end
def test_wildcard
tree = Wizard::PatternParser.parse( '(.)', Tokens, @adaptor )
assert_instance_of( Wizard::WildcardPattern, tree )
end
def test_label
tree = Wizard::PatternParser.parse( '(%a:A)', Tokens, @pattern_adaptor )
assert_instance_of(Wizard::Pattern, tree)
assert_equal('a', tree.label)
end
def test_error_1
tree = Wizard::PatternParser.parse( ')', Tokens, @adaptor )
assert_nil tree
end
def test_error_2
tree = Wizard::PatternParser.parse( '()', Tokens, @adaptor )
assert_nil tree
end
def test_error_3
tree = Wizard::PatternParser.parse( '(A ])', Tokens, @adaptor )
assert_nil tree
end
end
class TestTreeWizard < Test::Unit::TestCase
Tokens = TokenScheme.build %w(A B C D E ID VAR)
include Tokens
def setup
@adaptor = CommonTreeAdaptor.new( Tokens.token_class )
@wizard = Wizard.new( :adaptor => @adaptor, :token_scheme => Tokens )
end
def create_wizard( tokens )
Wizard.new( :tokens => tokens )
end
# vvvvvvvv tests vvvvvvvvv
def test_init
@wizard = Wizard.new( :tokens => %w(A B), :adaptor => @adaptor )
assert_equal( @wizard.adaptor, @adaptor )
assert_kind_of( ANTLR3::TokenScheme, @wizard.token_scheme )
end
def test_single_node
t = @wizard.create("ID")
assert_equal(t.inspect, 'ID')
end
def test_single_node_with_arg
t = @wizard.create("ID[foo]")
assert_equal(t.inspect, 'foo')
end
def test_single_node_tree
t = @wizard.create("(A)")
assert_equal(t.inspect, 'A')
end
def test_single_level_tree
t = @wizard.create("(A B C D)")
assert_equal(t.inspect, '(A B C D)')
end
def test_list_tree
t = @wizard.create("(nil A B C)")
assert_equal(t.inspect, 'A B C')
end
def test_invalid_list_tree
t = @wizard.create("A B C")
assert_nil t
end
def test_double_level_tree
t = @wizard.create("(A (B C) (B D) E)")
assert_equal(t.inspect, "(A (B C) (B D) E)")
end
SIMPLIFY_MAP = lambda do |imap|
Hash[
imap.map { |type, nodes| [type, nodes.map { |n| n.to_s }] }
]
end
def test_single_node_index
tree = @wizard.create("ID")
index_map = SIMPLIFY_MAP[@wizard.index(tree)]
assert_equal(index_map, ID => %w(ID))
end
def test_no_repeats_index
tree = @wizard.create("(A B C D)")
index_map = SIMPLIFY_MAP[@wizard.index(tree)]
assert_equal(index_map,
D => %w(D), B => %w(B),
C => %w(C), A => %w(A)
)
end
def test_repeats_index
tree = @wizard.create("(A B (A C B) B D D)")
index_map = SIMPLIFY_MAP[@wizard.index(tree)]
assert_equal(index_map,
D => %w(D D), B => %w(B B B),
C => %w(C), A => %w(A A)
)
end
def test_no_repeats_visit
tree = @wizard.create("(A B C D)")
elements = []
@wizard.visit( tree, B ) do |node, parent, child_index, labels|
elements << node.to_s
end
assert_equal( %w(B), elements )
end
def test_no_repeats_visit2
tree = @wizard.create("(A B (A C B) B D D)")
elements = []
@wizard.visit( tree, C ) do |node, parent, child_index, labels|
elements << node.to_s
end
assert_equal(%w(C), elements)
end
def test_repeats_visit
tree = @wizard.create("(A B (A C B) B D D)")
elements = []
@wizard.visit( tree, B ) do |node, parent, child_index, labels|
elements << node.to_s
end
assert_equal(%w(B B B), elements)
end
def test_repeats_visit2
tree = @wizard.create("(A B (A C B) B D D)")
elements = []
@wizard.visit( tree, A ) do |node, parent, child_index, labels|
elements << node.to_s
end
assert_equal(%w(A A), elements)
end
def context(node, parent, index)
'%s@%s[%d]' % [node.to_s, (parent || 'nil').to_s, index]
end
def test_repeats_visit_with_context
tree = @wizard.create("(A B (A C B) B D D)")
elements = []
@wizard.visit( tree, B ) do |node, parent, child_index, labels|
elements << context(node, parent, child_index)
end
assert_equal(['B@A[0]', 'B@A[1]', 'B@A[2]'], elements)
end
def test_repeats_visit_with_null_parent_and_context
tree = @wizard.create("(A B (A C B) B D D)")
elements = []
@wizard.visit( tree, A ) do |node, parent, child_index, labels|
elements << context(node, parent, child_index)
end
assert_equal(['A@nil[-1]', 'A@A[1]'], elements)
end
def test_visit_pattern
tree = @wizard.create("(A B C (A B) D)")
elements = []
@wizard.visit(tree, '(A B)') do |node, parent, child_index, labels|
elements << node.to_s
end
assert_equal(%w(A), elements)
end
def test_visit_pattern_multiple
tree = @wizard.create("(A B C (A B) (D (A B)))")
elements = []
@wizard.visit(tree, '(A B)') do |node, parent, child_index, labels|
elements << context(node, parent, child_index)
end
assert_equal( %w(A@A[2] A@D[0]) , elements )
end
def labeled_context(node, parent, index, labels, *names)
suffix = names.map { |n| labels[n].to_s }.join('&')
'%s@%s[%d]%s' % [node.to_s, (parent || 'nil').to_s, index, suffix]
end
def test_visit_pattern_multiple_with_labels
tree = @wizard.create("(A B C (A[foo] B[bar]) (D (A[big] B[dog])))")
elements = []
@wizard.visit(tree, '(%a:A %b:B)') do |node, parent, child_index, labels|
elements << labeled_context(node, parent, child_index, labels, 'a', 'b')
end
assert_equal( ['foo@A[2]foo&bar', 'big@D[0]big&dog'] , elements )
end
def test_match
tree = @wizard.create("(A B C)")
assert @wizard.match(tree, "(A B C)")
end
def test_match_single_node
tree = @wizard.create('A')
assert @wizard.match(tree, 'A')
end
def test_match_single_node_fails
tree = @wizard.create('A')
assert( !(@wizard.match(tree, 'B')) )
end
def test_match_flat_tree
tree = @wizard.create('(nil A B C)')
assert @wizard.match(tree, '(nil A B C)')
end
def test_match_flat_tree_fails
tree = @wizard.create('(nil A B C)')
assert( !(@wizard.match(tree, '(nil A B)')) )
end
def test_match_flat_tree_fails2
tree = @wizard.create('(nil A B C)')
assert( !(@wizard.match(tree, '(nil A B A)')) )
end
def test_wildcard
tree = @wizard.create('(A B C)')
assert @wizard.match(tree, '(A . .)')
end
def test_match_with_text
tree = @wizard.create('(A B[foo] C[bar])')
assert @wizard.match(tree, '(A B[foo] C)')
end
def test_match_with_text_fails
tree = @wizard.create('(A B C)')
assert( !(@wizard.match(tree, '(A[foo] B C)')) )
end
def test_match_labels
tree = @wizard.create('(A B C)')
labels = @wizard.match( tree, '(%a:A %b:B %c:C)' )
assert_equal('A', labels['a'].to_s)
assert_equal('B', labels['b'].to_s)
assert_equal('C', labels['c'].to_s)
end
def test_match_with_wildcard_labels
tree = @wizard.create('(A B C)')
labels = @wizard.match(tree, '(A %b:. %c:.)')
assert_kind_of( Hash, labels )
assert_equal('B', labels['b'].to_s)
assert_equal('C', labels['c'].to_s)
end
def test_match_labels_and_test_text
tree = @wizard.create('(A B[foo] C)')
labels = @wizard.match( tree, '(%a:A %b:B[foo] %c:C)' )
assert_kind_of( Hash, labels )
assert_equal('A', labels['a'].to_s)
assert_equal('foo', labels['b'].to_s)
assert_equal('C', labels['c'].to_s)
end
def test_match_labels_in_nested_tree
tree = @wizard.create('(A (B C) (D E))')
labels = @wizard.match( tree, '(%a:A (%b:B %c:C) (%d:D %e:E))' )
assert_kind_of( Hash, labels )
assert_equal('A', labels['a'].to_s)
assert_equal('B', labels['b'].to_s)
assert_equal('C', labels['c'].to_s)
assert_equal('D', labels['d'].to_s)
assert_equal('E', labels['e'].to_s)
end
def test_equals
tree1 = @wizard.create("(A B C)")
tree2 = @wizard.create("(A B C)")
assert @wizard.equals(tree1, tree2)
end
def test_equals_with_text
tree1 = @wizard.create("(A B[foo] C)")
tree2 = @wizard.create("(A B[foo] C)")
assert @wizard.equals(tree1, tree2)
end
def test_equals_with_mismatched_text
tree1 = @wizard.create("(A B[foo] C)")
tree2 = @wizard.create("(A B C)")
assert( !(@wizard.equals(tree1, tree2)) )
end
def test_equals_with_mismatched_list
tree1 = @wizard.create("(A B C)")
tree2 = @wizard.create("(A B A)")
assert( !(@wizard.equals(tree1, tree2)) )
end
def test_equals_with_mismatched_list_length
tree1 = @wizard.create("(A B C)")
tree2 = @wizard.create("(A B)")
assert( !(@wizard.equals(tree1, tree2)) )
end
def test_find_pattern
tree = @wizard.create("(A B C (A[foo] B[bar]) (D (A[big] B[dog])))")
subtrees = @wizard.find(tree, "(A B)").map { |t| t.to_s }
assert_equal(%w(foo big), subtrees)
end
def test_find_token_type
tree = @wizard.create("(A B C (A[foo] B[bar]) (D (A[big] B[dog])))")
subtrees = @wizard.find( tree, A ).map { |t| t.to_s }
assert_equal(%w(A foo big), subtrees)
end
end