Browse files

Merge branch 'new_method_name_regexp'

  • Loading branch information...
2 parents c1cc416 + f6de9e6 commit 1f471f7161ec0d76221743bce553d530fa262e37 @LTe committed Jun 13, 2012
Showing with 98 additions and 9 deletions.
  1. +15 −1 lib/machete/matchers.rb
  2. +26 −1 lib/machete/parser.y
  3. +49 −7 spec/machete/matchers_spec.rb
  4. +8 −0 spec/machete/parser_spec.rb
View
16 lib/machete/matchers.rb
@@ -137,7 +137,7 @@ def matches?(node)
end
# @private
- class StringRegexpMatcher
+ class RegexpMatcher
attr_reader :regexp
def initialize(regexp)
@@ -149,6 +149,20 @@ def ==(other)
end
def matches?(node)
+ node =~ @regexp
+ end
+ end
+
+ # @private
+ class SymbolRegexpMatcher < RegexpMatcher
+ def matches?(node)
+ node.is_a?(Symbol) && node.to_s =~ @regexp
+ end
+ end
+
+ # @private
+ class StringRegexpMatcher < RegexpMatcher
+ def matches?(node)
node.is_a?(String) && node =~ @regexp
end
end
View
27 lib/machete/parser.y
@@ -41,6 +41,27 @@ attrs : attr
| attrs "," attr { result = val[0].merge(val[2]) }
attr : method_name "=" expression { result = { val[0].to_sym => val[2] } }
+ | method_name "^=" SYMBOL {
+ result = {
+ val[0].to_sym => SymbolRegexpMatcher.new(
+ Regexp.new("^" + Regexp.escape(symbol_value(val[2])))
+ )
+ }
+ }
+ | method_name "$=" SYMBOL {
+ result = {
+ val[0].to_sym => SymbolRegexpMatcher.new(
+ Regexp.new(Regexp.escape(symbol_value(val[2])) + "$")
+ )
+ }
+ }
+ | method_name "*=" SYMBOL {
+ result = {
+ val[0].to_sym => SymbolRegexpMatcher.new(
+ Regexp.new(Regexp.escape(symbol_value(val[2])))
+ )
+ }
+ }
| method_name "^=" STRING {
result = {
val[0].to_sym => StringRegexpMatcher.new(
@@ -109,7 +130,7 @@ quantifier : "*" { result = [0, nil, 1] }
| "{" EVEN "}" { result = [0, nil, 2] }
| "{" ODD "}" { result = [1, nil, 2] }
-literal : SYMBOL { result = LiteralMatcher.new(val[0][1..-1].to_sym) }
+literal : SYMBOL { result = LiteralMatcher.new(symbol_value(val[0]).to_sym) }
| INTEGER { result = LiteralMatcher.new(integer_value(val[0])) }
| STRING { result = LiteralMatcher.new(string_value(val[0])) }
| TRUE { result = LiteralMatcher.new(true) }
@@ -173,6 +194,10 @@ def string_value(value)
end
end
+def symbol_value(value)
+ value.to_s[1..-1]
+end
+
# "^" needs to be here because if it were among operators recognized by
# METHOD_NAME, "^=" would be recognized as two tokens.
SIMPLE_TOKENS = [
View
56 spec/machete/matchers_spec.rb
@@ -409,9 +409,11 @@ class SubclassedLiteralMatcher < LiteralMatcher
end
end
- describe StringRegexpMatcher do
- before :each do
- @matcher = StringRegexpMatcher.new(/abcd/)
+ describe RegexpMatcher do
+ before do
+ @matcher = RegexpMatcher.new(/abcd/)
+ @object_true = stub(:=~ => true)
+ @object_false = stub(:=~ => false)
end
describe "initialize" do
@@ -426,23 +428,63 @@ class SubclassedLiteralMatcher < LiteralMatcher
end
it "returns true when passed a StartsWithMatcher initialized with the same parameters" do
- @matcher.should == StringRegexpMatcher.new(/abcd/)
+ @matcher.should == RegexpMatcher.new(/abcd/)
end
it "returns false when passed some random object" do
@matcher.should_not == Object.new
end
it "returns false when passed a subclass of StartsWithMatcher initialized with the same parameters" do
- class SubclassedStringRegexpMatcher < StringRegexpMatcher
+ class SubclassedRegexpMatcher < RegexpMatcher
end
- @matcher.should_not == SubclassedStringRegexpMatcher.new(/abcd/)
+ @matcher.should_not == SubclassedRegexpMatcher.new(/abcd/)
end
it "returns false when passed a StartsWithMatcher initialized with different parameters" do
- @matcher.should_not == StringRegexpMatcher.new(/efgh/)
+ @matcher.should_not == RegexpMatcher.new(/efgh/)
+ end
+ end
+
+ describe "matches?" do
+ it "matches a object matching the regexp" do
+ @matcher.matches?(@object_true).should be_true
+ end
+
+ it "does not match a object not matching the regexp" do
+ @matcher.matches?(@object_false).should be_false
+ end
+
+ it "does not match some random object" do
+ @matcher.matches?(Object.new).should be_false
+ end
+ end
+ end
+
+ describe SymbolRegexpMatcher do
+ before do
+ @matcher = SymbolRegexpMatcher.new(/abcd/)
+ end
+
+ describe "matches?" do
+ it "matches a string matching the regexp" do
+ @matcher.matches?(:efghabcdijkl).should be_true
end
+
+ it "does not match a string not matching the regexp" do
+ @matcher.matches?(:efghijkl).should be_false
+ end
+
+ it "does not match some random object" do
+ @matcher.matches?(Object.new).should be_false
+ end
+ end
+ end
+
+ describe StringRegexpMatcher do
+ before :each do
+ @matcher = StringRegexpMatcher.new(/abcd/)
end
describe "matches?" do
View
8 spec/machete/parser_spec.rb
@@ -73,6 +73,14 @@ def array_matcher_with_quantifier(min, max, step)
# Canonical attr is "a = 42".
it "parses attr" do
'Foo<a = 42 | 43>'.should be_parsed_as(NodeMatcher.new(:Foo, :a => @ch4243))
+
+ 'Foo<a ^= :symbol>'.should be_parsed_as(
+ NodeMatcher.new(:Foo, :a => SymbolRegexpMatcher.new(/^symbol/) ))
+ 'Foo<a $= :symbol>'.should be_parsed_as(
+ NodeMatcher.new(:Foo, :a => SymbolRegexpMatcher.new(/symbol$/) ))
+ 'Foo<a *= :symbol>'.should be_parsed_as(
+ NodeMatcher.new(:Foo, :a => SymbolRegexpMatcher.new(/symbol/) ))
+
'Foo<a ^= "abcd">'.should be_parsed_as(
NodeMatcher.new(:Foo, :a => StringRegexpMatcher.new(/^abcd/))
)

0 comments on commit 1f471f7

Please sign in to comment.