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 CHANGED
@@ -1 +1 @@
1
- 0.1.3
1
+ 0.1.4
@@ -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.3"
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-16}
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/no_regressions_in_normal_cukes.feature",
27
- "features/simple_cuke_patterns.feature",
28
- "features/step_definitions/no_regression_steps.rb",
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,8 @@
1
+ Feature: Apply Pattern
2
+
3
+ Patterns can be called from within other Patterns.
4
+
5
+ Scenario: A list pattern
6
+ When @x contains 1, "potato", 2.0 and "potato"
7
+ Then @x should be equal to [1, "potato", 2.0, "potato"]
8
+ And @x should be an Array
@@ -0,0 +1,9 @@
1
+ When ":ivar_name contains :list" do |ivar, array|
2
+ instance_variable_set(ivar, array)
3
+ end
4
+
5
+ Pattern :list, /(.+(?:,| and ).+)/ do |list|
6
+ list.split(/ *(?:,|and) */).map do |item|
7
+ Pattern :value, item
8
+ end
9
+ end
@@ -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 "@x is :integer" do |integer|
2
- @x = integer
1
+ When "I assign :ivar_name to :value" do |ivar, value|
2
+ instance_variable_set(ivar, value)
3
3
  end
4
4
 
5
- When "@x contains :list_of_integers" do |list|
6
- @x = list
5
+ Then ":ivar should be equal to :value" do |ivar, value|
6
+ ivar.should == value
7
7
  end
8
8
 
9
- Then "@x should be a :class" do |klass|
10
- @x.class.should == klass
9
+ Then ":ivar should be a :class" do |ivar, klass|
10
+ ivar.should be_kind_of(klass)
11
11
  end
12
12
 
13
- Then /^@x should evaluate to (.*)$/ do |expression|
14
- @x.should == eval(expression)
15
- end
13
+ Pattern /a|an/
14
+ Pattern /is|are/
16
15
 
17
- Pattern :class, /([A-Z][a-z]+)/ do |class_name|
18
- Object.const_get(class_name)
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 :integer, /(-?\d+)/ do |number|
22
- number.to_i
22
+ Pattern :ivar, /(@\w+)/ do |ivar_name|
23
+ instance_variable_get(ivar_name)
23
24
  end
24
25
 
25
- Pattern :list_of_integers, /(-?\d+(?: *(?:,|and) *-?\d+)*)/ do |list|
26
- list.split(/ *(?:,|and) */).map{|number| number.to_i}
27
- end
26
+ Pattern :ivar_name, /(@\w+)/
28
27
 
29
- PatternGenerator do |key|
30
- %w[a an].include?(key) and /a|an/
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
@@ -3,5 +3,6 @@ end
3
3
 
4
4
  require 'cuke-patterns/rb_dsl_ext'
5
5
  require 'cuke-patterns/rb_language_ext'
6
+ require 'cuke-patterns/rb_world_ext'
6
7
  require 'cuke-patterns/step_mother_ext'
7
8
 
@@ -1,8 +1,12 @@
1
1
  module CukePatterns
2
2
  module RbDslExt
3
3
 
4
- def register_rb_cuke_pattern(name, regexp, &proc)
5
- @rb_language.register_rb_cuke_pattern(name, regexp, &proc)
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(name, regexp, &proc)
19
- Cucumber::RbSupport::RbDsl.register_rb_cuke_pattern(name, regexp, &proc)
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 ||= Hash.new {|hash, key| default_cuke_pattern(key)}
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 [regexp, proc] if regexp
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 register_rb_cuke_pattern(name, regexp, &conversion_proc)
46
- name = ":#{name}" if name.is_a?(Symbol) # so :user becomes ':user'
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 = cuke_patterns[candidate] if candidate
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
- - 3
9
- version: 0.1.3
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-16 00:00:00 -07:00
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/no_regressions_in_normal_cukes.feature
38
- - features/simple_cuke_patterns.feature
39
- - features/step_definitions/no_regression_steps.rb
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]
@@ -1,6 +0,0 @@
1
- Given /^a typical given step$/ do
2
- end
3
- When /^a typical when step$/ do
4
- end
5
- Then /^a typical then step$/ do
6
- end