sbyc 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENCE.textile +12 -0
- data/README.textile +44 -0
- data/lib/sbyc.rb +14 -0
- data/lib/sbyc/codetree.rb +82 -0
- data/lib/sbyc/codetree/ast_node.rb +101 -0
- data/lib/sbyc/codetree/eval.rb +3 -0
- data/lib/sbyc/codetree/eval/ast_node_ext.rb +38 -0
- data/lib/sbyc/codetree/eval/functional_eval.rb +36 -0
- data/lib/sbyc/codetree/eval/object_eval.rb +36 -0
- data/lib/sbyc/codetree/matching.rb +3 -0
- data/lib/sbyc/codetree/matching/ast_node_ext.rb +14 -0
- data/lib/sbyc/codetree/matching/match_data.rb +30 -0
- data/lib/sbyc/codetree/matching/matcher.rb +83 -0
- data/lib/sbyc/codetree/proc_parser.rb +91 -0
- data/lib/sbyc/codetree/producing.rb +1 -0
- data/lib/sbyc/codetree/producing/producer.rb +68 -0
- data/lib/sbyc/codetree/rewriting.rb +4 -0
- data/lib/sbyc/codetree/rewriting/class_methods.rb +15 -0
- data/lib/sbyc/codetree/rewriting/compiler.rb +28 -0
- data/lib/sbyc/codetree/rewriting/instance_methods.rb +92 -0
- data/lib/sbyc/codetree/rewriting/match.rb +59 -0
- data/test/spec/documentation/codetree/production.spec +59 -0
- data/test/spec/documentation/readme/assumptions.spec +33 -0
- data/test/spec/documentation/readme/functional_evaluation.spec +29 -0
- data/test/spec/documentation/readme/object_evaluation.spec +17 -0
- data/test/spec/documentation/readme/rewriting.spec +60 -0
- data/test/spec/documentation/readme/semantics.spec +21 -0
- data/test/spec/documentation/readme/synopsis.spec +27 -0
- data/test/spec/documentation/readme/syntax.spec +26 -0
- data/test/spec/spec_helper.rb +13 -0
- data/test/spec/test_all.rb +6 -0
- data/test/spec/unit/sbyc/codetree/ast_node/coerce.spec +60 -0
- data/test/spec/unit/sbyc/codetree/ast_node/equality.spec +75 -0
- data/test/spec/unit/sbyc/codetree/ast_node/inspect.spec +23 -0
- data/test/spec/unit/sbyc/codetree/ast_node/literal.spec +15 -0
- data/test/spec/unit/sbyc/codetree/ast_node/to_a.spec +27 -0
- data/test/spec/unit/sbyc/codetree/ast_node/to_s.spec +23 -0
- data/test/spec/unit/sbyc/codetree/ast_node/visit.spec +34 -0
- data/test/spec/unit/sbyc/codetree/eval/functional_compile.spec +30 -0
- data/test/spec/unit/sbyc/codetree/eval/functional_eval.spec +34 -0
- data/test/spec/unit/sbyc/codetree/eval/functional_proc.spec +36 -0
- data/test/spec/unit/sbyc/codetree/eval/object_compile.spec +36 -0
- data/test/spec/unit/sbyc/codetree/eval/object_eval.spec +38 -0
- data/test/spec/unit/sbyc/codetree/eval/object_proc.spec +36 -0
- data/test/spec/unit/sbyc/codetree/matching/matcher/args_match.spec +91 -0
- data/test/spec/unit/sbyc/codetree/matching/matcher/do_match.spec +39 -0
- data/test/spec/unit/sbyc/codetree/matching/matcher/function_match.spec +45 -0
- data/test/spec/unit/sbyc/codetree/matching/matcher/match.spec +64 -0
- data/test/spec/unit/sbyc/codetree/proc_parser/expr.spec +20 -0
- data/test/spec/unit/sbyc/codetree/proc_parser/parse.spec +83 -0
- data/test/spec/unit/sbyc/codetree/producing/producer.spec +31 -0
- data/test/spec/unit/sbyc/codetree/producing/producer/apply_args_conventions.spec +60 -0
- data/test/spec/unit/sbyc/codetree/rewriting/instance_methods/apply_args_conventions.spec +60 -0
- data/test/spec/unit/sbyc/codetree/rewriting/instance_methods/node.spec +19 -0
- data/test/spec/unit/sbyc/codetree/rewriting/instance_methods/rewrite.spec +76 -0
- data/test/spec/unit/sbyc/codetree/rewriting/match/apply.spec +23 -0
- data/test/spec/unit/sbyc/codetree/rewriting/match/coerce.spec +48 -0
- data/test/spec/unit/sbyc/codetree/rewriting/match/matches.spec +27 -0
- metadata +129 -0
@@ -0,0 +1,20 @@
|
|
1
|
+
require File.expand_path('../../../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe "CodeTree::ProcParser::Expr" do
|
4
|
+
|
5
|
+
let(:the_expr) { CodeTree::ProcParser::Expr.new }
|
6
|
+
|
7
|
+
describe("should not have access to Kernel methods") do
|
8
|
+
specify{
|
9
|
+
x = the_expr.instance_eval{ puts "hello" }
|
10
|
+
lambda{ x.__to_functional_code }.should_not raise_error
|
11
|
+
x.__to_functional_code.should be_kind_of(CodeTree::AstNode)
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "should not have a to_s method" do
|
16
|
+
subject { the_expr.to_s.__to_functional_code }
|
17
|
+
it { should be_kind_of(CodeTree::AstNode) }
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require File.expand_path('../../../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe "CodeTree::ProcParser#parse" do
|
4
|
+
|
5
|
+
subject { CodeTree::ProcParser::parse(code) }
|
6
|
+
|
7
|
+
context "when called with an argument" do
|
8
|
+
let(:expected) { "(+ (? (_ :a)), (_ 12))" }
|
9
|
+
|
10
|
+
context("with a simple literal") do
|
11
|
+
let(:code) { proc {|t| 12 } }
|
12
|
+
specify { subject.should be_kind_of(CodeTree::AstNode) }
|
13
|
+
specify { subject.inspect.should == CodeTree::parse{ 12 }.inspect }
|
14
|
+
end
|
15
|
+
|
16
|
+
context("with a simple operator call") do
|
17
|
+
let(:code) { proc {|t| t[:a] + 12 } }
|
18
|
+
specify { subject.inspect.should == expected }
|
19
|
+
end
|
20
|
+
|
21
|
+
context("with a simple operator call and dot heuristic") do
|
22
|
+
let(:code) { proc {|t| t.a + 12 } }
|
23
|
+
specify { subject.inspect.should == expected }
|
24
|
+
end
|
25
|
+
|
26
|
+
context("with left literal at left") do
|
27
|
+
let(:code) { proc {|t| 12 + t[:a] } }
|
28
|
+
specify { subject.inspect.should == expected }
|
29
|
+
end
|
30
|
+
|
31
|
+
context("with left literal at left and dot heuristic") do
|
32
|
+
let(:code) { proc {|t| 12 + t.a } }
|
33
|
+
specify { subject.inspect.should == expected }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context "when called without argument" do
|
38
|
+
let(:expected) { "(+ (? (_ :a)), (_ 12))" }
|
39
|
+
|
40
|
+
context("with a simple literal") do
|
41
|
+
let(:code) { proc { 12 } }
|
42
|
+
specify { subject.should be_kind_of(CodeTree::AstNode) }
|
43
|
+
specify { subject.inspect.should == CodeTree::parse{ 12 }.inspect }
|
44
|
+
end
|
45
|
+
|
46
|
+
context("with a simple operator call") do
|
47
|
+
let(:code) { proc { a + 12 } }
|
48
|
+
specify { subject.inspect.should == expected }
|
49
|
+
end
|
50
|
+
|
51
|
+
context("with left literal at left") do
|
52
|
+
let(:code) { proc { 12 + a } }
|
53
|
+
specify { subject.inspect.should == expected }
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context "when called and used with method calls" do
|
58
|
+
let(:expected) { "(plus (? (_ :a)), (_ 12))" }
|
59
|
+
|
60
|
+
context("with a simple method call") do
|
61
|
+
let(:code) { proc {|t| t[:a].plus(12) } }
|
62
|
+
specify { subject.inspect.should == expected }
|
63
|
+
end
|
64
|
+
|
65
|
+
context("with a simple method call and dot heuristic") do
|
66
|
+
let(:code) { proc {|t| t.a.plus(12) } }
|
67
|
+
specify { subject.inspect.should == expected }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context "when call on expressions that refer to ruby Kernel methods" do
|
72
|
+
let(:expected) { "(puts (to_s (? (_ :x))))"}
|
73
|
+
let(:code) { lambda { (puts (to_s x)) } }
|
74
|
+
specify{ subject.inspect.should == expected }
|
75
|
+
end
|
76
|
+
|
77
|
+
context "when call on expressions that refer to typical inherited methods/operators" do
|
78
|
+
let(:expected) { "(== (hash (? (_ :x))), (_ 12))"}
|
79
|
+
let(:code) { lambda { x.hash == 12 } }
|
80
|
+
specify{ subject.inspect.should == expected }
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require File.expand_path('../../../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe "CodeTree::Producing::Producer" do
|
4
|
+
|
5
|
+
let(:expr){ CodeTree::parse{ ~(a & b) } }
|
6
|
+
|
7
|
+
context 'when called with default rules' do
|
8
|
+
let(:producer) {
|
9
|
+
CodeTree::producer{|p|
|
10
|
+
p.rule(:~){|r, n| "not(#{r.apply(n[0])})" }
|
11
|
+
p.rule(:&){|r, n| "(#{r.apply(n.children).join(' and ')})" }
|
12
|
+
p.rule(:|){|r, n| "(#{r.apply(n.children).join(' or ')})" }
|
13
|
+
}
|
14
|
+
}
|
15
|
+
subject{ producer.apply(expr) }
|
16
|
+
it{ should == "not((a and b))" }
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'when called without default rules' do
|
20
|
+
let(:producer) {
|
21
|
+
CodeTree::producer(false){|p|
|
22
|
+
p.rule("*"){|r,n| [n.function] + r.apply(n.children)}
|
23
|
+
}
|
24
|
+
}
|
25
|
+
subject{ producer.apply(expr) }
|
26
|
+
specify{ producer.rules.size.should == 1 }
|
27
|
+
it{ should == [:~, [:&, [:'?', [:_, :a]], [:'?', [:_, :b]]]] }
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require File.expand_path('../../../../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe "CodeTree::Producing::Producer#apply_args_conventions" do
|
4
|
+
|
5
|
+
let(:producer) { ::CodeTree::producer }
|
6
|
+
|
7
|
+
context "when called with a literal" do
|
8
|
+
let(:node) { 12 }
|
9
|
+
subject { producer.send(:apply_args_conventions,node) }
|
10
|
+
it { should == node }
|
11
|
+
end
|
12
|
+
|
13
|
+
context "when called with a single ASTNode instance" do
|
14
|
+
let(:node) { ::CodeTree::parse{ 12 } }
|
15
|
+
subject { producer.send(:apply_args_conventions,node) }
|
16
|
+
it { should == node }
|
17
|
+
end
|
18
|
+
|
19
|
+
context "when called with multiple ASTNode instances" do
|
20
|
+
let(:child1) { ::CodeTree::parse{ "hello" } }
|
21
|
+
let(:child2) { ::CodeTree::parse{ "world" } }
|
22
|
+
subject { producer.send(:apply_args_conventions,child1, child2) }
|
23
|
+
it { should == [child1, child2] }
|
24
|
+
end
|
25
|
+
|
26
|
+
context "when called with an array of ASTNode instances" do
|
27
|
+
let(:child1) { ::CodeTree::parse{ "hello" } }
|
28
|
+
let(:child2) { ::CodeTree::parse{ "world" } }
|
29
|
+
subject { producer.send(:apply_args_conventions,[child1, child2]) }
|
30
|
+
it { should == [child1, child2] }
|
31
|
+
end
|
32
|
+
|
33
|
+
context "when called with a function and a single ASTNode child" do
|
34
|
+
let(:function) { :testfunc }
|
35
|
+
let(:child) { ::CodeTree::parse{ 12 } }
|
36
|
+
let(:expected) { ::CodeTree::parse{ (testfunc 12) } }
|
37
|
+
subject{ producer.send(:apply_args_conventions,function, child) }
|
38
|
+
it { should == expected }
|
39
|
+
end
|
40
|
+
|
41
|
+
context "when called with a function and two ASTNode children" do
|
42
|
+
let(:function) { :say }
|
43
|
+
let(:child1) { ::CodeTree::parse{ "hello" } }
|
44
|
+
let(:child2) { ::CodeTree::parse{ "world" } }
|
45
|
+
let(:expected) { ::CodeTree::parse{ (say "hello", "world") } }
|
46
|
+
subject{ producer.send(:apply_args_conventions,function, child1, child2) }
|
47
|
+
it { should == expected }
|
48
|
+
end
|
49
|
+
|
50
|
+
context "when called with a function and mix of ASTNode children" do
|
51
|
+
let(:function) { :say }
|
52
|
+
let(:child1) { ::CodeTree::parse{ "hello" } }
|
53
|
+
let(:child2) { ::CodeTree::parse{ "you" } }
|
54
|
+
let(:child3) { ::CodeTree::parse{ "world" } }
|
55
|
+
let(:expected) { ::CodeTree::parse{ (say "hello", "you", "world") } }
|
56
|
+
subject{ producer.send(:apply_args_conventions,function, child1, [child2, child3]) }
|
57
|
+
it { should == expected }
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require File.expand_path('../../../../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe "CodeTree::Rewriting::Rewriter#apply_args_conventions" do
|
4
|
+
|
5
|
+
let(:rewriter) { ::CodeTree::rewriter }
|
6
|
+
|
7
|
+
context "when called with a literal" do
|
8
|
+
let(:node) { 12 }
|
9
|
+
subject { rewriter.apply_args_conventions(node) }
|
10
|
+
it { should == node }
|
11
|
+
end
|
12
|
+
|
13
|
+
context "when called with a single ASTNode instance" do
|
14
|
+
let(:node) { ::CodeTree::parse{ 12 } }
|
15
|
+
subject { rewriter.apply_args_conventions(node) }
|
16
|
+
it { should == node }
|
17
|
+
end
|
18
|
+
|
19
|
+
context "when called with multiple ASTNode instances" do
|
20
|
+
let(:child1) { ::CodeTree::parse{ "hello" } }
|
21
|
+
let(:child2) { ::CodeTree::parse{ "world" } }
|
22
|
+
subject { rewriter.apply_args_conventions(child1, child2) }
|
23
|
+
it { should == [child1, child2] }
|
24
|
+
end
|
25
|
+
|
26
|
+
context "when called with an array of ASTNode instances" do
|
27
|
+
let(:child1) { ::CodeTree::parse{ "hello" } }
|
28
|
+
let(:child2) { ::CodeTree::parse{ "world" } }
|
29
|
+
subject { rewriter.apply_args_conventions([child1, child2]) }
|
30
|
+
it { should == [child1, child2] }
|
31
|
+
end
|
32
|
+
|
33
|
+
context "when called with a function and a single ASTNode child" do
|
34
|
+
let(:function) { :testfunc }
|
35
|
+
let(:child) { ::CodeTree::parse{ 12 } }
|
36
|
+
let(:expected) { ::CodeTree::parse{ (testfunc 12) } }
|
37
|
+
subject{ rewriter.apply_args_conventions(function, child) }
|
38
|
+
it { should == expected }
|
39
|
+
end
|
40
|
+
|
41
|
+
context "when called with a function and two ASTNode children" do
|
42
|
+
let(:function) { :say }
|
43
|
+
let(:child1) { ::CodeTree::parse{ "hello" } }
|
44
|
+
let(:child2) { ::CodeTree::parse{ "world" } }
|
45
|
+
let(:expected) { ::CodeTree::parse{ (say "hello", "world") } }
|
46
|
+
subject{ rewriter.apply_args_conventions(function, child1, child2) }
|
47
|
+
it { should == expected }
|
48
|
+
end
|
49
|
+
|
50
|
+
context "when called with a function and mix of ASTNode children" do
|
51
|
+
let(:function) { :say }
|
52
|
+
let(:child1) { ::CodeTree::parse{ "hello" } }
|
53
|
+
let(:child2) { ::CodeTree::parse{ "you" } }
|
54
|
+
let(:child3) { ::CodeTree::parse{ "world" } }
|
55
|
+
let(:expected) { ::CodeTree::parse{ (say "hello", "you", "world") } }
|
56
|
+
subject{ rewriter.apply_args_conventions(function, child1, [child2, child3]) }
|
57
|
+
it { should == expected }
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require File.expand_path('../../../../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe "CodeTree::Rewriting::Rewriter#copy" do
|
4
|
+
|
5
|
+
let(:engine) { CodeTree::rewriter }
|
6
|
+
|
7
|
+
context "when called with a literal" do
|
8
|
+
subject{ engine.node(:test, [ 12 ]) }
|
9
|
+
it { should == CodeTree::parse{ (test 12) } }
|
10
|
+
end
|
11
|
+
|
12
|
+
context "when called with copy in mind" do
|
13
|
+
let(:node) { CodeTree::parse{ 12 } }
|
14
|
+
subject{ engine.node(node.function, node.children) }
|
15
|
+
it { should == CodeTree::parse{ 12 } }
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require File.expand_path('../../../../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe "CodeTree::Rewriting::Rewriter" do
|
4
|
+
|
5
|
+
describe "when called without scope" do
|
6
|
+
subject{
|
7
|
+
CodeTree::rewriter {|r|
|
8
|
+
r.rule(:concat) {|r, node, *args| args.collect{|c| r.apply(c)}.join }
|
9
|
+
r.rule(:_) {|r, node| node.literal }
|
10
|
+
}
|
11
|
+
}
|
12
|
+
|
13
|
+
it { should be_kind_of(CodeTree::Rewriting::Rewriter) }
|
14
|
+
|
15
|
+
context("when applied on an ast string") do
|
16
|
+
specify { subject.rewrite("(concat 1, 2, 3)").should == "123" }
|
17
|
+
end
|
18
|
+
|
19
|
+
context("when applied with a proc argument") do
|
20
|
+
let(:code){ lambda{ (concat 1, 2, 3) } }
|
21
|
+
specify { subject.rewrite(code).should == "123" }
|
22
|
+
end
|
23
|
+
|
24
|
+
context("when applied with a block") do
|
25
|
+
specify { subject.rewrite{ (concat 1, 2, 3) }.should == "123" }
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "when called with a scope object" do
|
31
|
+
subject{
|
32
|
+
CodeTree::rewriter {|r|
|
33
|
+
r.rule(:concat) {|r, node, *args| args.collect{|c| r.apply(c)}.join }
|
34
|
+
r.rule(:get) {|r, node, name| r.scope[r.apply(name)] }
|
35
|
+
r.rule(:_) {|r, node| node.literal }
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
it { should be_kind_of(CodeTree::Rewriting::Rewriter) }
|
40
|
+
|
41
|
+
context("when applied on an ast string") do
|
42
|
+
specify { subject.rewrite("(get :hello)", :hello => "world").should == "world" }
|
43
|
+
end
|
44
|
+
|
45
|
+
context("when applied with a proc argument") do
|
46
|
+
let(:code){ lambda{ (get :hello) } }
|
47
|
+
specify { subject.rewrite(code, :hello => "world").should == "world" }
|
48
|
+
end
|
49
|
+
|
50
|
+
context("when applied with a block") do
|
51
|
+
specify { subject.rewrite(:hello => "world"){ (get :hello) }.should == "world" }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "when only an ANY match is installed" do
|
56
|
+
subject{ CodeTree::rewriter{|r|
|
57
|
+
r.rule(CodeTree::Rewriting::Rewriter::Match::ANY){|r, node, arg| node.leaf? ? arg : r.apply(arg) }
|
58
|
+
}}
|
59
|
+
|
60
|
+
it "should return inner-most argument" do
|
61
|
+
subject.rewrite{ (call (other (one :hello))) }.should == :hello
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "when only an LEAF/BRANCH are used" do
|
66
|
+
subject{ CodeTree::rewriter{|r|
|
67
|
+
r.rule(CodeTree::Rewriting::Rewriter::Match::BRANCH){|r, node, child| r.apply(child)}
|
68
|
+
r.rule(CodeTree::Rewriting::Rewriter::Match::LEAF){|r, node| node.literal}
|
69
|
+
}}
|
70
|
+
|
71
|
+
it "should return inner-most argument" do
|
72
|
+
subject.rewrite{ (call (other (one :hello))) }.should == :hello
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.expand_path('../../../../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe "CodeTree::Rewriting::Rewriter::Match#apply" do
|
4
|
+
|
5
|
+
let(:predicate) { true }
|
6
|
+
let(:block) { lambda{ |r, node, *args| [r, node, args] } }
|
7
|
+
subject { CodeTree::Rewriting::Rewriter::Match.new(predicate, block) }
|
8
|
+
|
9
|
+
context "when called on a leaf node" do
|
10
|
+
let(:node) { CodeTree::AstNode.coerce(:literal) }
|
11
|
+
specify {
|
12
|
+
subject.apply("rewriter", node).should == ["rewriter", node, [ :literal ]]
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
context "when called on a branch node" do
|
17
|
+
let(:node) { CodeTree::AstNode.new(:branch, [1, 2, 3]) }
|
18
|
+
specify {
|
19
|
+
subject.apply("rewriter", node).should == ["rewriter", node, [1, 2, 3]]
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require File.expand_path('../../../../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe "CodeTree::Rewriting::Rewriter::Match.coerce?" do
|
4
|
+
|
5
|
+
let(:branch) { CodeTree::parse{ (branch :hello) } }
|
6
|
+
let(:leaf) { CodeTree::parse{ :hello } }
|
7
|
+
|
8
|
+
context("when called with a symbol") do
|
9
|
+
subject{ CodeTree::Rewriting::Rewriter::Match.coerce(:branch, nil) }
|
10
|
+
|
11
|
+
it { should === branch }
|
12
|
+
it { should_not === leaf }
|
13
|
+
end
|
14
|
+
|
15
|
+
context("when called with a proc") do
|
16
|
+
let(:predicate) { lambda{|node| node.leaf? }}
|
17
|
+
subject{ CodeTree::Rewriting::Rewriter::Match.coerce(predicate, nil) }
|
18
|
+
|
19
|
+
it { should_not === branch }
|
20
|
+
it { should === leaf }
|
21
|
+
end
|
22
|
+
|
23
|
+
context("when called with '.'") do
|
24
|
+
subject{ CodeTree::Rewriting::Rewriter::Match.coerce(".", nil) }
|
25
|
+
|
26
|
+
it { should === 12 }
|
27
|
+
it { should === branch }
|
28
|
+
it { should === leaf }
|
29
|
+
end
|
30
|
+
|
31
|
+
context("when called with '*'") do
|
32
|
+
subject{ CodeTree::Rewriting::Rewriter::Match.coerce("*", nil) }
|
33
|
+
|
34
|
+
it { should_not === 12 }
|
35
|
+
it { should === branch }
|
36
|
+
it { should_not === leaf }
|
37
|
+
end
|
38
|
+
|
39
|
+
context("when called with '@*'") do
|
40
|
+
subject{ CodeTree::Rewriting::Rewriter::Match.coerce("@*", nil) }
|
41
|
+
|
42
|
+
it { should_not === 12 }
|
43
|
+
it { should_not === branch }
|
44
|
+
it { should === leaf }
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require File.expand_path('../../../../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe "CodeTree::Rewriting::Rewriter::Match#matches?" do
|
4
|
+
|
5
|
+
let(:branch) { CodeTree::AstNode.new(:branch, [1, 2, 3]) }
|
6
|
+
let(:literal) { CodeTree::AstNode.coerce(12) }
|
7
|
+
|
8
|
+
context "when built with a symbol" do
|
9
|
+
subject { CodeTree::Rewriting::Rewriter::Match.coerce(:_, nil) }
|
10
|
+
specify {
|
11
|
+
(subject.matches? branch).should be_false
|
12
|
+
(subject.matches? literal).should be_true
|
13
|
+
(subject === branch).should be_false
|
14
|
+
(subject === literal).should be_true
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
context "when built with a proc" do
|
19
|
+
let(:proc) { lambda {|node| node.name == :branch } }
|
20
|
+
subject { CodeTree::Rewriting::Rewriter::Match.coerce(proc, nil) }
|
21
|
+
specify {
|
22
|
+
(subject.matches? branch).should be_true
|
23
|
+
(subject.matches? literal).should be_false
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|