lime 0.2.0 → 0.3.0

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/.ruby CHANGED
@@ -1,16 +1,15 @@
1
1
  ---
2
+ source:
3
+ - meta
2
4
  authors:
3
- - name: Thomas Sawyer
5
+ - name: Trans
4
6
  email: transfire@gmail.com
5
7
  copyrights:
6
- - holder: Thomas Sawyer
8
+ - holder: Rubyworks
7
9
  year: '2011'
8
10
  license: BSD-2-Clause
9
- replacements: []
10
- conflicts: []
11
11
  requirements:
12
- - name: test
13
- - name: ae
12
+ - name: rubytest
14
13
  - name: detroit
15
14
  groups:
16
15
  - build
@@ -23,7 +22,13 @@ requirements:
23
22
  groups:
24
23
  - test
25
24
  development: true
25
+ - name: ae
26
+ groups:
27
+ - test
28
+ development: true
26
29
  dependencies: []
30
+ alternatives: []
31
+ conflicts: []
27
32
  repositories:
28
33
  - uri: git://github.com/proutils/lime.git
29
34
  scm: git
@@ -31,18 +36,19 @@ repositories:
31
36
  resources:
32
37
  home: http://rubyworks.github.com/lime
33
38
  code: http://github.com/rubyworks/lime
34
- mail: http://groups.google.com/group/rubyworks-mailinglist
39
+ bugs: http://github.com/rubyworks/lime/issues
40
+ mail: http://groups.google.com/groups/rubyworks-mailinglist
41
+ extra: {}
35
42
  load_path:
36
43
  - lib
37
- extra:
38
- manifest: MANIFEST
39
- alternatives: []
40
44
  revision: 0
45
+ created: '2011-08-11'
46
+ summary: Pure Ruby Gherkin-style Test Framework
41
47
  title: Lime
42
- suite: RubyWorks
43
- summary: Gherkin-style Test Framework
44
- description: Lime is a pure Ruby variation of Cucumber's Gherkin BDD test system that
45
- runs on top of the Ruby Universal Test Harness.
46
- version: 0.2.0
48
+ version: 0.3.0
47
49
  name: lime
48
- date: '2011-08-11'
50
+ description: ! 'Lime is a pure Ruby variation of Cucumber''s Gherkin BDD test system
51
+
52
+ that runs on top of RubyTest, a Universal Test Harness for Ruby.'
53
+ organization: Rubyworks
54
+ date: '2012-03-03'
data/HISTORY.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Release History
2
2
 
3
+ ## 0.3.0 / 2012-03-03
4
+
5
+ Fix execution scope so that method definitions in Featurettes
6
+ are visible to advice procedures. Also will automatically require
7
+ any `*.rb` files in `featurettes` directory relative to feature
8
+ file.
9
+
10
+ Changes:
11
+
12
+ * Fix execution scope so that featurettes are included.
13
+ * Automatically require featurette files.
14
+ * Alias #I to #We.
15
+
3
16
 
4
17
  ## 0.2.0 / 2011-08-11
5
18
 
@@ -1,6 +1,8 @@
1
- BSD 2 Clause License
1
+ Lime, Pure-Ruby Gherkin-style BDD Test Framework
2
2
 
3
- Copyright 2011 Thomas Sawyer. All rights reserved.
3
+ Copyright 2011 Rubyworks. All rights reserved.
4
+
5
+ (BSD-2-Clause License)
4
6
 
5
7
  Redistribution and use in source and binary forms, with or without
6
8
  modification, are permitted provided that the following conditions are met:
data/README.md CHANGED
@@ -1,16 +1,20 @@
1
1
  # Lime
2
2
 
3
- Author:: Thomas Sawyer
4
- License:: FreeBSD
5
- Copyright:: (c) 2011 Thomas Sawyer, Rubyworks
3
+ [Website](http://rubyworks.github.com/lime) /
4
+ [Source Code](http://github.com/rubyworks/lime) /
5
+ [Report Issue](http://github.com/rubyworks/lime/issues) /
6
+ [Mailing List](http://groups.google.com/groups/rubyworks-mailinglist)
6
7
 
7
8
 
8
9
  ## Description
9
10
 
10
- Lime is pure Ruby Gherkin-style test framework.
11
+ Lime is pure-Ruby Gherkin-style test framework.
11
12
 
12
13
 
13
- ## Example
14
+ ## Instruction
15
+
16
+ Lime lets you write features scripts using Ruby, yet still do
17
+ so with a close approximation to Gherkin domain language.
14
18
 
15
19
  ``` ruby
16
20
  Feature "Addition" do
@@ -54,12 +58,50 @@ Feature "Addition" do
54
58
  end
55
59
  ```
56
60
 
61
+ The last set of `Given` and `When` procedures are called the *advice definitions*. These
62
+ can be placed in their own modules and included into the Feature scope like any other module.
63
+ They simply need to include the `Lime::Featurette` module to do so. For instance:
64
+
65
+ ```ruby
66
+ module CalculatorAdvice
67
+ include Lime::Featurette
68
+
69
+ Given 'I have a calculator' do
70
+ require 'calculator'
71
+ @calculator = Calculator.new
72
+ end
73
+
74
+ Given 'I have entered (((\d+))) into the calculator' do |n|
75
+ @calculator.push n.to_i
76
+ end
77
+
78
+ When 'I press add' do
79
+ @result = @calculator.add
80
+ end
81
+
82
+ Then 'the result should be (((\d+))) on the screen' do |n|
83
+ @result.assert == n.to_i
84
+ end
85
+ end
86
+ ```
87
+
88
+ If you add such scripts to a subdirectory called `featurettes` relative to the
89
+ feature that uses them, then they will be loaded automatically when features
90
+ are run.
91
+
92
+ Speaking of which, to run features use the `rubytest` command line tool.
93
+
94
+ ```
95
+ $ rubytest -Ilib spec/feature_addition.rb
96
+ ```
97
+
98
+ See [RubyTest](http://rubyworks.github.com/rubytest) to learn more.
99
+
57
100
 
58
101
  ## Copyrights
59
102
 
60
- Copyright (c) 2011 Thomas Sawyer, Rubyworks
103
+ Copyright (c) 2011 Rubyworks
61
104
 
62
105
  Lime is distributed according to the terms of the *FreeBSD* license.
63
106
 
64
- See COPYING.rdoc for details.
65
-
107
+ See LICENSE.txt for details.
@@ -1,8 +1,8 @@
1
1
  # Ignore lime paths in backtraces
2
2
  ignore_path = File.expand_path(File.dirname(__FILE__) + '/lime')
3
3
  ignore_regexp = Regexp.new(Regexp.escape(ignore_path))
4
- RUBY_IGNORE_CALLERS = [] unless defined? RUBY_IGNORE_CALLERS
5
- RUBY_IGNORE_CALLERS << ignore_regexp
4
+ $RUBY_IGNORE_CALLERS ||= []
5
+ $RUBY_IGNORE_CALLERS << ignore_regexp
6
6
 
7
7
  # Make sure the global test array is defined.
8
8
  $TEST_SUITE ||= []
@@ -15,15 +15,33 @@ module Lime
15
15
  require 'lime/step'
16
16
 
17
17
  # Toplevel DSL.
18
+ #
18
19
  module DSL
19
20
 
21
+ #
20
22
  # Define a feature.
23
+ #
21
24
  def Feature(label, &block)
25
+ require_featurettes(File.dirname(caller[0]))
26
+
22
27
  $TEST_SUITE << Lime::Feature.new(:label=>label, &block)
23
28
  end
24
29
 
25
30
  alias :feature :Feature
26
31
 
32
+ #
33
+ # Require any featurettes located in `{feature_dir}/featurettes` directory.
34
+ #
35
+ def require_featurettes(feature_dir)
36
+ featurettes_dir = File.join(feature_dir, 'featurettes')
37
+ if File.directory?(featurettes_dir)
38
+ featurette_files = Dir[File.join(featurettes_dir, '*.rb')]
39
+ featurette_files.each do |file|
40
+ require file
41
+ end
42
+ end
43
+ end
44
+
27
45
  end
28
46
 
29
47
  end
@@ -4,6 +4,7 @@ module Lime
4
4
  require 'lime/world'
5
5
  require 'lime/advice'
6
6
  require 'lime/scenario'
7
+ require 'lime/featurette'
7
8
 
8
9
  # Features contain scenarios.
9
10
  #
@@ -38,8 +39,11 @@ module Lime
38
39
  @story = []
39
40
  @scenarios = []
40
41
 
41
- @scope = Scope.new(self)
42
- @scope.module_eval(&block)
42
+ @scope = Scope.new(self, &block)
43
+
44
+ @scenarios.each do |scenario|
45
+ scenario.scope.__send__(:extend, @scope)
46
+ end
43
47
  end
44
48
 
45
49
  # Convenience method for accessing advice, aka step definitions.
@@ -70,20 +74,22 @@ module Lime
70
74
 
71
75
  #
72
76
  def update(mixin)
73
- @advice[:given].concat mixin[:given] || []
74
- @advice[:when].concat mixin[:when] || []
75
- @advice[:then].concat mixin[:then] || []
76
- @scope.extend mixin if Module === mixin
77
+ @advice[:given].update( mixin[:given] || {} )
78
+ @advice[:when].update( mixin[:when] || {} )
79
+ @advice[:then].update( mixin[:then] || {} )
80
+
81
+ #@scope.__send__(:include, mixin) if Module === mixin
77
82
  end
78
83
 
79
84
  #
80
85
  class Scope < World
81
86
 
82
87
  #
83
- def initialize(feature) #, &code)
88
+ def initialize(feature, &block)
84
89
  @_feature = feature
85
90
  @_skip = false
86
- #module_eval(&code)
91
+
92
+ module_eval(&block) if block
87
93
  end
88
94
 
89
95
  #
@@ -107,6 +113,11 @@ module Lime
107
113
 
108
114
  alias :we :We
109
115
 
116
+ alias :I :We
117
+ alias :i :I
118
+
119
+ #
120
+ # Define a Scenario.
110
121
  #
111
122
  def Scenario(label, &procedure)
112
123
  scenario = Scenario.new(
@@ -167,86 +178,22 @@ module Lime
167
178
  @_skip = reason
168
179
  end
169
180
 
170
- # Is this necessary?
181
+ #
182
+ # Access to underlying feature instance.
183
+ #
171
184
  def _feature
172
185
  @_feature
173
186
  end
174
187
 
188
+ #
189
+ # Include module and if a Featurette, also update Feature instance.
175
190
  #
176
191
  def include(mixin)
177
- if Featurable === mixin
192
+ if Featurette === mixin
178
193
  @_feature.update(mixin)
179
- super(mixin)
180
- else
181
- super(mixin)
182
194
  end
195
+ super(mixin)
183
196
  end
184
-
185
- end
186
-
187
- # Convenience method for creating a feature mixin.
188
- #
189
- # @example
190
- #
191
- # module MyStepDefinitions
192
- # include Lime::Featurette
193
- #
194
- # Given "customer's name is '(((\s+)))'" do |name|
195
- # @name = name
196
- # end
197
- # end
198
- #
199
- # Feature do
200
- # include MyStepDefinitions
201
- # end
202
- #
203
- module Featurette
204
-
205
- def self.append_features(base)
206
- base.extend(self)
207
- base.module_eval %{
208
- @_advice = Hash.new{ |h,k| h[k]={} }
209
- }
210
- end
211
-
212
- # Given ...
213
- #
214
- # @param [String] description
215
- # A brief description of the _given_ criteria.
216
- #
217
- def Given(description, &procedure)
218
- @_advice[:given][description] = procedure
219
- end
220
-
221
- alias :given :Given
222
-
223
- # When ...
224
- #
225
- # @param [String] description
226
- # A brief description of the _when_ criteria.
227
- #
228
- def When(description, &procedure)
229
- @_advice[:when][description] = procedure
230
- end
231
-
232
- alias :wence :When
233
-
234
- # Then ...
235
- #
236
- # @param [String] description
237
- # A brief description of the _then_ criteria.
238
- #
239
- def Then(description, &procedure)
240
- @_advice[:then][description] = procedure
241
- end
242
-
243
- alias :hence :Then
244
-
245
- # Access to advice.
246
- def [](key)
247
- @_advice[key]
248
- end
249
-
250
197
  end
251
198
 
252
199
  end
@@ -0,0 +1,68 @@
1
+ module Lime
2
+
3
+ # Convenience method for creating a feature mixin.
4
+ #
5
+ # @example
6
+ #
7
+ # module MyStepDefinitions
8
+ # include Lime::Featurette
9
+ #
10
+ # Given "customer's name is '(((\s+)))'" do |name|
11
+ # @name = name
12
+ # end
13
+ # end
14
+ #
15
+ # Feature do
16
+ # include MyStepDefinitions
17
+ # end
18
+ #
19
+ module Featurette
20
+
21
+ def self.append_features(base)
22
+ base.extend(self)
23
+ base.module_eval %{
24
+ @_advice = Hash.new{ |h,k| h[k] = {} }
25
+ }
26
+ end
27
+
28
+ # Given ...
29
+ #
30
+ # @param [String] description
31
+ # A brief description of the _given_ criteria.
32
+ #
33
+ def Given(description, &procedure)
34
+ @_advice[:given][description] = procedure
35
+ end
36
+
37
+ alias :given :Given
38
+
39
+ # When ...
40
+ #
41
+ # @param [String] description
42
+ # A brief description of the _when_ criteria.
43
+ #
44
+ def When(description, &procedure)
45
+ @_advice[:when][description] = procedure
46
+ end
47
+
48
+ alias :wence :When
49
+
50
+ # Then ...
51
+ #
52
+ # @param [String] description
53
+ # A brief description of the _then_ criteria.
54
+ #
55
+ def Then(description, &procedure)
56
+ @_advice[:then][description] = procedure
57
+ end
58
+
59
+ alias :hence :Then
60
+
61
+ # Access to advice.
62
+ def [](key)
63
+ @_advice[key]
64
+ end
65
+
66
+ end
67
+
68
+ end
@@ -14,8 +14,7 @@ module Lime
14
14
 
15
15
  @steps = []
16
16
 
17
- @scope = Scope.new(self)
18
- @scope.module_eval(&block)
17
+ @scope = Scope.new(self, &block)
19
18
  end
20
19
 
21
20
  # Parent feature.
@@ -66,7 +65,9 @@ module Lime
66
65
  def topic
67
66
  end
68
67
 
68
+ #
69
69
  # Run a step in the context of this scenario.
70
+ #
70
71
  def run(step)
71
72
  type = step.type
72
73
  desc = step.label
@@ -82,6 +83,7 @@ module Lime
82
83
  # features.clauses[@type].find{ |c| c =~ @description }
83
84
  #end
84
85
 
86
+ #
85
87
  # Convert matching string into a regular expression. If the string
86
88
  # contains parentheticals, e.g. `(.*?)`, the text within them is
87
89
  # treated as a case-insensitve back-referenceing regular expression
@@ -89,6 +91,7 @@ module Lime
89
91
  #
90
92
  # To use a regular expression, but leave the resulting match out of
91
93
  # the backreferences use `?:`, e.g. `(?:\d+)`.
94
+ #
92
95
  def match_regexp(str)
93
96
  ## the old way required double and triple parens
94
97
  #str = str.split(/(\(\(.*?\)\))(?!\))/).map{ |x|
@@ -102,15 +105,17 @@ module Lime
102
105
  end
103
106
 
104
107
  # TODO: Need to ensure the correct order of Given, When, Then.
108
+
109
+ #
105
110
  class Scope < Module
106
111
 
107
112
  #
108
- def initialize(scenario) #, &code)
113
+ def initialize(scenario, &block)
109
114
  @scenario = scenario
110
115
 
111
- extend(scenario.feature.scope)
116
+ #include(scenario.feature.scope)
112
117
 
113
- #module_eval(&code)
118
+ module_eval(&block)
114
119
  end
115
120
 
116
121
  # Given ...