matches 1.0.3 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/TODO.md +10 -0
- data/VERSION +1 -1
- data/features/define_matches.feature +29 -5
- data/features/step_definitions/method_steps.rb +4 -4
- data/features/support/env.rb +14 -1
- data/lib/matches.rb +9 -6
- data/matches.gemspec +2 -1
- data/spec/matches_spec.rb +104 -42
- metadata +2 -1
data/TODO.md
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
To do
|
2
|
+
=====
|
3
|
+
|
4
|
+
Implement regular-expression priorities like Cucumber:
|
5
|
+
------------------------------------------------------
|
6
|
+
|
7
|
+
1. The longest Regexp with 0 capture groups always wins.
|
8
|
+
2. The Regexp with the most capture groups wins (when there are none with 0 groups)
|
9
|
+
3. If there are 2+ Regexen with the same number of capture groups, the one with the shortest overall captured string length wins
|
10
|
+
4. If there are still 2+ options then an Ambiguous error is raised
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.
|
1
|
+
1.0.4
|
@@ -6,7 +6,7 @@ Scenario: Define a matcher method
|
|
6
6
|
Given I have the following Ruby code:
|
7
7
|
"""
|
8
8
|
class Hippo
|
9
|
-
matches
|
9
|
+
matches /^(\w+)\!$/ do |verb|
|
10
10
|
puts "I've been #{verb}ed!"
|
11
11
|
end
|
12
12
|
end
|
@@ -17,7 +17,6 @@ Scenario: Define a matcher method
|
|
17
17
|
Then I should see "I've been touched!" in the output
|
18
18
|
|
19
19
|
Scenario: Another meta-method
|
20
|
-
Given I reset the class Hippo
|
21
20
|
Given I have the following Ruby code:
|
22
21
|
"""
|
23
22
|
class Hippo
|
@@ -25,11 +24,11 @@ Scenario: Another meta-method
|
|
25
24
|
@verbs = []
|
26
25
|
end
|
27
26
|
|
28
|
-
matches
|
27
|
+
matches /^(\w+)\!$/ do |verb|
|
29
28
|
@verbs << verb
|
30
29
|
end
|
31
30
|
|
32
|
-
matches
|
31
|
+
matches /^(\w+)ed\?$/ do |verb|
|
33
32
|
@verbs.include?(verb)
|
34
33
|
end
|
35
34
|
end
|
@@ -41,4 +40,29 @@ Scenario: Another meta-method
|
|
41
40
|
puts herman.touched?
|
42
41
|
"""
|
43
42
|
When I execute the code
|
44
|
-
Then I should see "true" in the output
|
43
|
+
Then I should see "true" in the output
|
44
|
+
|
45
|
+
Scenario: Defining class methods
|
46
|
+
Given I have the following Ruby code:
|
47
|
+
"""
|
48
|
+
class Hippo
|
49
|
+
attr_accessor :disposition
|
50
|
+
|
51
|
+
def initialize(dis)
|
52
|
+
self.disposition = dis
|
53
|
+
end
|
54
|
+
|
55
|
+
class << self
|
56
|
+
matches /^new_(\w+)$/ do |dis|
|
57
|
+
new(dis)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
herman = Hippo.new_angry
|
63
|
+
|
64
|
+
puts herman.disposition
|
65
|
+
"""
|
66
|
+
When I execute the code
|
67
|
+
Then I should see "angry" in the output
|
68
|
+
|
@@ -1,7 +1,3 @@
|
|
1
|
-
Given /^I reset the class (.+)$/ do |klass|
|
2
|
-
eval("#{klass}.reset_meta_methods")
|
3
|
-
end
|
4
|
-
|
5
1
|
Given /^I have the following Ruby code:$/ do |code|
|
6
2
|
@code = code
|
7
3
|
end
|
@@ -30,4 +26,8 @@ class OutputStorage
|
|
30
26
|
def self.output
|
31
27
|
@@output
|
32
28
|
end
|
29
|
+
|
30
|
+
def self.clear
|
31
|
+
@@output = ""
|
32
|
+
end
|
33
33
|
end
|
data/features/support/env.rb
CHANGED
@@ -1,3 +1,16 @@
|
|
1
1
|
require File.dirname(__FILE__) + "/../../lib/matches"
|
2
2
|
|
3
|
-
require 'spec/stubs/cucumber'
|
3
|
+
require 'spec/stubs/cucumber'
|
4
|
+
|
5
|
+
Before do
|
6
|
+
# Look through all the classes, some of which will have been defined
|
7
|
+
# in the scenarios. Reset their match methods if necessary.
|
8
|
+
Module.constants.each do |constant|
|
9
|
+
klass = Kernel.const_get(constant)
|
10
|
+
if klass.kind_of?(Class)
|
11
|
+
klass.reset_match_methods if klass.respond_to?(:reset_match_methods)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
OutputStorage.clear()
|
16
|
+
end
|
data/lib/matches.rb
CHANGED
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + "/match_method"
|
|
2
2
|
|
3
3
|
# Defines all the necessary components to allow defining dynamic methods.
|
4
4
|
module MatchDef
|
5
|
-
# Defines a new class method that allows you to define
|
5
|
+
# Defines a new class method that allows you to define dynamicinstance methods.
|
6
6
|
# Takes a regular expression and a block, which are stored and called later.
|
7
7
|
def matches(regexp, &block)
|
8
8
|
@@match_methods ||= []
|
@@ -10,18 +10,21 @@ module MatchDef
|
|
10
10
|
@@match_methods << MatchMethod.new( :matcher => regexp,
|
11
11
|
:proc => block )
|
12
12
|
self.class_eval {
|
13
|
-
unless
|
13
|
+
unless method_defined? :method_missing
|
14
|
+
def method_missing(meth, *args, &block); super; end
|
15
|
+
end
|
16
|
+
|
17
|
+
unless method_defined?(:match_method_missing)
|
14
18
|
# Defines a +method_missing+ that is aware of the
|
15
19
|
# dynamically-defined methods and will call them if appropriate.
|
16
|
-
def match_method_missing(message, *args)
|
20
|
+
def match_method_missing(message, *args, &block)
|
17
21
|
# Attempt to evaluate this using a MetaMethod
|
18
22
|
result = @@match_methods.find do |mm|
|
19
23
|
if mm.matches?(message)
|
20
24
|
return mm.match(self, message, args)
|
21
25
|
end
|
22
26
|
end
|
23
|
-
return result
|
24
|
-
return old_method_missing(message, args)
|
27
|
+
return result || old_method_missing(message, args, &block)
|
25
28
|
end
|
26
29
|
|
27
30
|
alias_method :old_method_missing, :method_missing
|
@@ -32,7 +35,7 @@ module MatchDef
|
|
32
35
|
|
33
36
|
# Allows you to delete all defined dynamic methods on a class.
|
34
37
|
# This permits testing.
|
35
|
-
def
|
38
|
+
def reset_match_methods
|
36
39
|
@@match_methods = []
|
37
40
|
end
|
38
41
|
end
|
data/matches.gemspec
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{matches}
|
8
|
-
s.version = "1.0.
|
8
|
+
s.version = "1.0.4"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Phil Calvin"]
|
@@ -26,6 +26,7 @@ Gem::Specification.new do |s|
|
|
26
26
|
"README.md",
|
27
27
|
"README.rdoc",
|
28
28
|
"Rakefile",
|
29
|
+
"TODO.md",
|
29
30
|
"VERSION",
|
30
31
|
"features/define_matches.feature",
|
31
32
|
"features/step_definitions/method_steps.rb",
|
data/spec/matches_spec.rb
CHANGED
@@ -2,68 +2,130 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
2
2
|
|
3
3
|
describe MatchDef do
|
4
4
|
before(:each) do
|
5
|
-
Hippo.
|
5
|
+
Hippo.reset_match_methods
|
6
|
+
|
7
|
+
class Hippo
|
8
|
+
def method_missing(message, *args)
|
9
|
+
super
|
10
|
+
end
|
11
|
+
|
12
|
+
if method_defined?(:match_method_missing)
|
13
|
+
undef match_method_missing
|
14
|
+
end
|
15
|
+
end
|
6
16
|
end
|
7
17
|
|
8
|
-
|
9
|
-
|
18
|
+
describe "when defining instance methods" do
|
19
|
+
|
20
|
+
it "should provide a matches method on classes" do
|
21
|
+
lambda {
|
22
|
+
Hippo.class_eval do
|
23
|
+
matches /foo/
|
24
|
+
end
|
25
|
+
}.should_not raise_error
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should call the method if it matches" do
|
10
29
|
Hippo.class_eval do
|
11
|
-
matches /
|
30
|
+
matches /bar/ do
|
31
|
+
worked
|
32
|
+
end
|
12
33
|
end
|
13
|
-
|
14
|
-
|
34
|
+
|
35
|
+
test = Hippo.new
|
36
|
+
test.should_receive(:worked).once
|
37
|
+
test.bar
|
38
|
+
end
|
15
39
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
40
|
+
it "should pass in the match groups" do
|
41
|
+
Hippo.class_eval do
|
42
|
+
matches /bar_(\w+)/ do |activity|
|
43
|
+
worked(activity)
|
44
|
+
end
|
20
45
|
end
|
46
|
+
|
47
|
+
test = Hippo.new
|
48
|
+
test.should_receive(:worked).once.with('fight')
|
49
|
+
test.bar_fight()
|
21
50
|
end
|
22
51
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
it "should pass in the match groups" do
|
29
|
-
Hippo.class_eval do
|
30
|
-
matches /bar_(\w+)/ do |activity|
|
31
|
-
worked(activity)
|
52
|
+
it "should fall through normally if no match" do
|
53
|
+
Hippo.class_eval do
|
54
|
+
matches /bar_(\w+)/ do |activity|
|
55
|
+
worked(activity)
|
56
|
+
end
|
32
57
|
end
|
33
|
-
end
|
34
58
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
59
|
+
test = Hippo.new
|
60
|
+
test.should_receive(:worked).never
|
61
|
+
lambda { test.totally_unmatched }.should raise_error(NoMethodError)
|
62
|
+
end
|
39
63
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
64
|
+
it "should respect an existing method_missing" do
|
65
|
+
Hippo.class_eval do
|
66
|
+
def method_missing(message, *args)
|
67
|
+
affirm(message)
|
68
|
+
end
|
45
69
|
|
46
|
-
|
47
|
-
|
70
|
+
matches /second/ do
|
71
|
+
affirm(:second)
|
72
|
+
end
|
48
73
|
end
|
74
|
+
|
75
|
+
test = Hippo.new
|
76
|
+
test.should_receive(:affirm).once.with(:first)
|
77
|
+
test.should_receive(:affirm).once.with(:second)
|
78
|
+
test.first()
|
79
|
+
test.second()
|
49
80
|
end
|
81
|
+
|
82
|
+
it "should not pollute other classes" do
|
83
|
+
Hippo.class_eval do
|
84
|
+
matches /second/ do
|
85
|
+
throw "Should never be reached"
|
86
|
+
end
|
87
|
+
end
|
50
88
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
test.second()
|
89
|
+
test = Rhino.new
|
90
|
+
lambda { test.second() }.should raise_error
|
91
|
+
end
|
92
|
+
|
56
93
|
end
|
57
94
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
95
|
+
describe "when defining class methods" do
|
96
|
+
|
97
|
+
it "should call the method if it matches" do
|
98
|
+
Hippo.should_receive(:worked).once
|
99
|
+
class Hippo
|
100
|
+
class << self
|
101
|
+
matches /foo/ do
|
102
|
+
worked
|
103
|
+
end
|
104
|
+
end
|
62
105
|
end
|
106
|
+
|
107
|
+
Hippo.foo
|
63
108
|
end
|
64
109
|
|
65
|
-
|
66
|
-
|
110
|
+
it "should differentiate between class and instance methods" do
|
111
|
+
class Hippo
|
112
|
+
matches /foo/ do
|
113
|
+
worked
|
114
|
+
end
|
115
|
+
|
116
|
+
class << self
|
117
|
+
matches /foo/ do
|
118
|
+
failed
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
herman = Hippo.new
|
124
|
+
Hippo.should_receive(:failed).never
|
125
|
+
herman.should_receive(:worked).once
|
126
|
+
|
127
|
+
herman.foo
|
128
|
+
end
|
67
129
|
end
|
68
130
|
end
|
69
131
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: matches
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Phil Calvin
|
@@ -52,6 +52,7 @@ files:
|
|
52
52
|
- README.md
|
53
53
|
- README.rdoc
|
54
54
|
- Rakefile
|
55
|
+
- TODO.md
|
55
56
|
- VERSION
|
56
57
|
- features/define_matches.feature
|
57
58
|
- features/step_definitions/method_steps.rb
|