cuke-patterns 0.1.3 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/cuke-patterns.gemspec +8 -5
- data/features/apply_pattern.feature +8 -0
- data/features/apply_pattern_steps.rb +9 -0
- data/features/pattern_generator.feature +13 -0
- data/features/simple_patterns.feature +40 -0
- data/features/step_definitions/pattern_generator_steps.rb +18 -0
- data/features/step_definitions/simple_pattern_steps.rb +17 -26
- data/lib/cuke-patterns.rb +1 -0
- data/lib/cuke-patterns/rb_dsl_ext.rb +8 -4
- data/lib/cuke-patterns/rb_language_ext.rb +42 -5
- data/lib/cuke-patterns/rb_world_ext.rb +15 -0
- metadata +9 -6
- data/features/no_regressions_in_normal_cukes.feature +0 -9
- data/features/simple_cuke_patterns.feature +0 -16
- data/features/step_definitions/no_regression_steps.rb +0 -6
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.4
|
data/cuke-patterns.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{cuke-patterns}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.4"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Brendan Baldwin"]
|
12
|
-
s.date = %q{2010-08-
|
12
|
+
s.date = %q{2010-08-18}
|
13
13
|
s.description = %q{Makes cucumber step definitions more focused, understandable, searchable and awesomeable.}
|
14
14
|
s.email = %q{brendan@usergenic.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -23,14 +23,17 @@ Gem::Specification.new do |s|
|
|
23
23
|
"Rakefile",
|
24
24
|
"VERSION",
|
25
25
|
"cuke-patterns.gemspec",
|
26
|
-
"features/
|
27
|
-
"features/
|
28
|
-
"features/
|
26
|
+
"features/apply_pattern.feature",
|
27
|
+
"features/apply_pattern_steps.rb",
|
28
|
+
"features/pattern_generator.feature",
|
29
|
+
"features/simple_patterns.feature",
|
30
|
+
"features/step_definitions/pattern_generator_steps.rb",
|
29
31
|
"features/step_definitions/simple_pattern_steps.rb",
|
30
32
|
"features/support/env.rb",
|
31
33
|
"lib/cuke-patterns.rb",
|
32
34
|
"lib/cuke-patterns/rb_dsl_ext.rb",
|
33
35
|
"lib/cuke-patterns/rb_language_ext.rb",
|
36
|
+
"lib/cuke-patterns/rb_world_ext.rb",
|
34
37
|
"lib/cuke-patterns/step_mother_ext.rb"
|
35
38
|
]
|
36
39
|
s.homepage = %q{http://github.com/brendan/cuke-patterns}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Feature: Pattern Generator
|
2
|
+
|
3
|
+
Sometimes its nice to be able to have a catch-all like Ruby's method_missing
|
4
|
+
so we can do more dynamic things. A PatternGenerator works like this, taking
|
5
|
+
a string of word characters representing a "word" or ":symbol" and then
|
6
|
+
returns a regexp and optional conversion proc. If it returns neither, we
|
7
|
+
move on to the next defined Pattern Generator.
|
8
|
+
|
9
|
+
Scenario: singular/plural form agnosticizer
|
10
|
+
When I eat 1 apple
|
11
|
+
And I eat 2 apples
|
12
|
+
Then I should have eaten 3 apples
|
13
|
+
|
@@ -0,0 +1,40 @@
|
|
1
|
+
Feature: Simple Patterns
|
2
|
+
These are some examples of very simple but useful patterns.
|
3
|
+
|
4
|
+
Scenario: :fixnum
|
5
|
+
When I assign @x to 1
|
6
|
+
Then @x should be equal to 1
|
7
|
+
And @x should be a Fixnum
|
8
|
+
|
9
|
+
Scenario: :fixnum (negative)
|
10
|
+
When I assign @x to -1
|
11
|
+
Then @x should be equal to -1
|
12
|
+
And @x should be a Fixnum
|
13
|
+
|
14
|
+
Scenario: :float
|
15
|
+
When I assign @x to 2.0
|
16
|
+
Then @x should be equal to 2.0
|
17
|
+
And @x should be a Float
|
18
|
+
|
19
|
+
Scenario: :float (negative)
|
20
|
+
When I assign @x to -2.0
|
21
|
+
Then @x should be equal to -2.0
|
22
|
+
And @x should be a Float
|
23
|
+
|
24
|
+
Scenario: :hash
|
25
|
+
When I assign @x to {'a'=>'b','c'=>'d'}
|
26
|
+
Then @x should be equal to {'a'=>'b','c'=>'d'}
|
27
|
+
And @x should be a Hash
|
28
|
+
|
29
|
+
Scenario: :array
|
30
|
+
When I assign @x to [1,2,3]
|
31
|
+
Then @x should be equal to [1,2,3]
|
32
|
+
And @x should be an Array
|
33
|
+
|
34
|
+
Scenario: :string
|
35
|
+
When I assign @x to "aww yeah"
|
36
|
+
Then @x should be equal to "aww yeah"
|
37
|
+
And @x should be a String
|
38
|
+
|
39
|
+
|
40
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
When "I eat :value apples" do |count|
|
2
|
+
@apples_consumed ||= 0
|
3
|
+
@apples_consumed += count
|
4
|
+
end
|
5
|
+
|
6
|
+
Then "I should have eaten :value apples" do |count|
|
7
|
+
@apples_consumed.should == count
|
8
|
+
end
|
9
|
+
|
10
|
+
# This pattern generator doesn't do *real* pluralize/singularize;
|
11
|
+
# it's just a demonstration of the concept. Here I strip and append
|
12
|
+
# an 's' onto the word passed in and construct a regexp that looks
|
13
|
+
# for all forms rather naively.
|
14
|
+
PatternGenerator do |word|
|
15
|
+
base_plural_singular = [word, word+'s', word.sub(/s$/,'')].uniq
|
16
|
+
base_plural_singular.map! {|w| Regexp.escape(w)}
|
17
|
+
Regexp.new(base_plural_singular.join('|'))
|
18
|
+
end
|
@@ -1,39 +1,30 @@
|
|
1
|
-
When "
|
2
|
-
|
1
|
+
When "I assign :ivar_name to :value" do |ivar, value|
|
2
|
+
instance_variable_set(ivar, value)
|
3
3
|
end
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
Then ":ivar should be equal to :value" do |ivar, value|
|
6
|
+
ivar.should == value
|
7
7
|
end
|
8
8
|
|
9
|
-
Then "
|
10
|
-
|
9
|
+
Then ":ivar should be a :class" do |ivar, klass|
|
10
|
+
ivar.should be_kind_of(klass)
|
11
11
|
end
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
end
|
13
|
+
Pattern /a|an/
|
14
|
+
Pattern /is|are/
|
16
15
|
|
17
|
-
Pattern :class, /([A-Z][
|
18
|
-
|
16
|
+
Pattern :class, /([A-Z]\w*(?:::[A-Z]\w*)*)/ do |class_name|
|
17
|
+
class_name.split(/::/).inject(Object) do |klass, subname|
|
18
|
+
klass.const_get(subname)
|
19
|
+
end
|
19
20
|
end
|
20
21
|
|
21
|
-
Pattern :
|
22
|
-
|
22
|
+
Pattern :ivar, /(@\w+)/ do |ivar_name|
|
23
|
+
instance_variable_get(ivar_name)
|
23
24
|
end
|
24
25
|
|
25
|
-
Pattern :
|
26
|
-
list.split(/ *(?:,|and) */).map{|number| number.to_i}
|
27
|
-
end
|
26
|
+
Pattern :ivar_name, /(@\w+)/
|
28
27
|
|
29
|
-
|
30
|
-
|
28
|
+
Pattern :value, /(.*)/ do |expression|
|
29
|
+
eval(expression)
|
31
30
|
end
|
32
|
-
|
33
|
-
## This PatternGenerator would enable automatic singularize/pluralize of ALL words
|
34
|
-
## so you don't have to resort to regexp construction for steps just do deal with
|
35
|
-
## pluralization related nonsense.
|
36
|
-
#
|
37
|
-
# PatternGenerator do |key|
|
38
|
-
# Regexp.new([Regexp.escape(key.singularize), Regexp.escape(key.pluralize)].join('|'))
|
39
|
-
# end
|
data/lib/cuke-patterns.rb
CHANGED
@@ -1,8 +1,12 @@
|
|
1
1
|
module CukePatterns
|
2
2
|
module RbDslExt
|
3
3
|
|
4
|
-
def
|
5
|
-
@rb_language.
|
4
|
+
def apply_rb_cuke_pattern(name, string)
|
5
|
+
@rb_language.apply_rb_cuke_pattern(name, string)
|
6
|
+
end
|
7
|
+
|
8
|
+
def register_rb_cuke_pattern(*args, &proc)
|
9
|
+
@rb_language.register_rb_cuke_pattern(*args, &proc)
|
6
10
|
end
|
7
11
|
|
8
12
|
def register_rb_cuke_pattern_generator(&proc)
|
@@ -15,8 +19,8 @@ end
|
|
15
19
|
Cucumber::RbSupport::RbDsl.module_eval do
|
16
20
|
extend CukePatterns::RbDslExt
|
17
21
|
|
18
|
-
def Pattern(
|
19
|
-
Cucumber::RbSupport::RbDsl.register_rb_cuke_pattern(
|
22
|
+
def Pattern(*args, &proc)
|
23
|
+
Cucumber::RbSupport::RbDsl.register_rb_cuke_pattern(*args, &proc)
|
20
24
|
end
|
21
25
|
|
22
26
|
def PatternGenerator(&proc)
|
@@ -25,7 +25,7 @@ module CukePatterns
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def cuke_patterns
|
28
|
-
@cuke_patterns ||=
|
28
|
+
@cuke_patterns ||= {}
|
29
29
|
end
|
30
30
|
|
31
31
|
# Hook this method to automatically generate regexp matches for words in step
|
@@ -33,7 +33,7 @@ module CukePatterns
|
|
33
33
|
def default_cuke_pattern(key)
|
34
34
|
default_cuke_pattern_generators.each do |generator|
|
35
35
|
regexp, proc = generator[key]
|
36
|
-
return
|
36
|
+
return regexp, proc if regexp
|
37
37
|
end
|
38
38
|
return nil
|
39
39
|
end
|
@@ -42,8 +42,45 @@ module CukePatterns
|
|
42
42
|
@default_cuke_pattern_generators ||= []
|
43
43
|
end
|
44
44
|
|
45
|
-
def
|
46
|
-
name = ":#{name}" if name.is_a?(Symbol)
|
45
|
+
def apply_rb_cuke_pattern(name, string)
|
46
|
+
name = ":#{name}" if name.is_a?(Symbol)
|
47
|
+
regexp, proc = lookup_cuke_pattern(name)
|
48
|
+
match = regexp.match(string)
|
49
|
+
raise "Pattern #{regexp.to_s} does not match #{string.inspect}" unless match
|
50
|
+
return instance_exec(*match.captures, &proc) if proc
|
51
|
+
return match.to_s
|
52
|
+
end
|
53
|
+
|
54
|
+
def lookup_cuke_pattern(name)
|
55
|
+
keys, regexp, proc = [], nil, nil
|
56
|
+
cuke_patterns.each do |key, value|
|
57
|
+
if key === name
|
58
|
+
keys << key
|
59
|
+
regexp, proc = value
|
60
|
+
end
|
61
|
+
end
|
62
|
+
return default_cuke_pattern(name) if keys.empty?
|
63
|
+
return regexp, proc if keys.length == 1
|
64
|
+
raise "Ambiguous Pattern for #{name.inspect}: #{keys.inspect}"
|
65
|
+
end
|
66
|
+
|
67
|
+
def register_rb_cuke_pattern(*args, &conversion_proc)
|
68
|
+
if args.length == 1
|
69
|
+
if args.first.is_a?(Hash)
|
70
|
+
args.first.each do |key, value|
|
71
|
+
register_rb_cuke_pattern(key, value, &conversion_proc)
|
72
|
+
end
|
73
|
+
return
|
74
|
+
else
|
75
|
+
# We wrap the key form of the regexp in begin/end
|
76
|
+
# so that we match only whole tokens when doing lookup
|
77
|
+
name = Regexp.new("^(?:#{args.first})$")
|
78
|
+
regexp = args.first
|
79
|
+
end
|
80
|
+
elsif args.length == 2
|
81
|
+
name, regexp = args
|
82
|
+
name = ":#{name}" if name.is_a?(Symbol) # so :user becomes ':user'
|
83
|
+
end
|
47
84
|
|
48
85
|
if conversion_proc
|
49
86
|
# Count the capturing '(' characters to get the pattern arity
|
@@ -83,7 +120,7 @@ module CukePatterns
|
|
83
120
|
# Split the string by non-alphanumeric, underscore or leading-colon characters
|
84
121
|
matcher.scan(/(:?\w+)|([^:\w]+|:)/) do |candidate, non_candidate|
|
85
122
|
|
86
|
-
regexp, conversion_proc =
|
123
|
+
regexp, conversion_proc = lookup_cuke_pattern(candidate) if candidate
|
87
124
|
|
88
125
|
if non_candidate or not regexp
|
89
126
|
matcher_regexp << Regexp.escape(candidate || non_candidate)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module CukePatterns
|
2
|
+
|
3
|
+
module RbWorldExt
|
4
|
+
|
5
|
+
def Pattern(name, string)
|
6
|
+
Cucumber::RbSupport::RbDsl.apply_rb_cuke_pattern(name, string)
|
7
|
+
end
|
8
|
+
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
Cucumber::RbSupport::RbWorld.module_eval do
|
14
|
+
include CukePatterns::RbWorldExt
|
15
|
+
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 1
|
8
|
-
-
|
9
|
-
version: 0.1.
|
8
|
+
- 4
|
9
|
+
version: 0.1.4
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Brendan Baldwin
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-08-
|
17
|
+
date: 2010-08-18 00:00:00 -07:00
|
18
18
|
default_executable:
|
19
19
|
dependencies: []
|
20
20
|
|
@@ -34,14 +34,17 @@ files:
|
|
34
34
|
- Rakefile
|
35
35
|
- VERSION
|
36
36
|
- cuke-patterns.gemspec
|
37
|
-
- features/
|
38
|
-
- features/
|
39
|
-
- features/
|
37
|
+
- features/apply_pattern.feature
|
38
|
+
- features/apply_pattern_steps.rb
|
39
|
+
- features/pattern_generator.feature
|
40
|
+
- features/simple_patterns.feature
|
41
|
+
- features/step_definitions/pattern_generator_steps.rb
|
40
42
|
- features/step_definitions/simple_pattern_steps.rb
|
41
43
|
- features/support/env.rb
|
42
44
|
- lib/cuke-patterns.rb
|
43
45
|
- lib/cuke-patterns/rb_dsl_ext.rb
|
44
46
|
- lib/cuke-patterns/rb_language_ext.rb
|
47
|
+
- lib/cuke-patterns/rb_world_ext.rb
|
45
48
|
- lib/cuke-patterns/step_mother_ext.rb
|
46
49
|
has_rdoc: true
|
47
50
|
homepage: http://github.com/brendan/cuke-patterns
|
@@ -1,9 +0,0 @@
|
|
1
|
-
Feature: No regressions in normal cukes
|
2
|
-
In order for anyone to want to use this cuke-patterns gem
|
3
|
-
As a developer of cuke-patterns
|
4
|
-
I want to ensure this doesn't screw anything up
|
5
|
-
|
6
|
-
Scenario: Simple regexp matched scenario
|
7
|
-
Given a typical given step
|
8
|
-
When a typical when step
|
9
|
-
Then a typical then step
|
@@ -1,16 +0,0 @@
|
|
1
|
-
Feature: Simple Cuke Patterns
|
2
|
-
|
3
|
-
Scenario: Transform string of digits into Fixnum
|
4
|
-
When @x is 1234
|
5
|
-
Then @x should be a Fixnum
|
6
|
-
And @x should evaluate to 1234
|
7
|
-
|
8
|
-
Scenario: Transform digits with negative sign into Fixnum
|
9
|
-
When @x is -1234
|
10
|
-
Then @x should be a Fixnum
|
11
|
-
And @x should evaluate to -1234
|
12
|
-
|
13
|
-
Scenario: Transform a list to an array of Fixnums
|
14
|
-
When @x contains 1, 2, 3 and 4
|
15
|
-
Then @x should be an Array
|
16
|
-
And @x should evaluate to [1, 2, 3, 4]
|