lime 0.1.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.
@@ -0,0 +1,7 @@
1
+ .yardoc
2
+ doc
3
+ log
4
+ pkg
5
+ tmp
6
+ site/doc
7
+ QED.rdoc
data/.ruby ADDED
@@ -0,0 +1,51 @@
1
+ ---
2
+ authors:
3
+ - name: Thomas Sawyer
4
+ email: transfire@gmail.com
5
+ copyrights:
6
+ - holder: Thomas Sawyer
7
+ year: "2011"
8
+ license: BSD-2-Clause
9
+ replacements: []
10
+
11
+ conflicts: []
12
+
13
+ requirements:
14
+ - name: test
15
+ - name: ae
16
+ - name: detroit
17
+ groups:
18
+ - build
19
+ development: true
20
+ - name: reap
21
+ groups:
22
+ - build
23
+ development: true
24
+ - name: qed
25
+ groups:
26
+ - test
27
+ development: true
28
+ dependencies: []
29
+
30
+ repositories:
31
+ - uri: git://github.com/proutils/lime.git
32
+ scm: git
33
+ name: upstream
34
+ resources:
35
+ home: http://rubyworks.github.com/lime
36
+ code: http://github.com/rubyworks/lime
37
+ mail: http://groups.google.com/group/rubyworks-mailinglist
38
+ load_path:
39
+ - lib
40
+ extra:
41
+ manifest: MANIFEST
42
+ alternatives: []
43
+
44
+ revision: 0
45
+ title: Lime
46
+ suite: RubyWorks
47
+ summary: Gherkin-style Test Framework
48
+ description: Lime is a "Ruby DSL" knock-off of Cucumber's Gherkin BDD nomenclature that runs on top of ruby-test.
49
+ version: 0.1.0
50
+ name: lime
51
+ date: "2011-07-29"
@@ -0,0 +1,7 @@
1
+ --output-dir site
2
+ --protected
3
+ --readme README.md
4
+ lib
5
+ -
6
+ [A-Z]*.*
7
+
@@ -0,0 +1,46 @@
1
+ ---
2
+ github:
3
+ active: true
4
+
5
+ gem:
6
+ active: true
7
+
8
+ dnote:
9
+ labels: ~
10
+ output: log/NOTES.rdoc
11
+
12
+ yard:
13
+ yardopts: true
14
+
15
+ qed:
16
+ files : ~
17
+ #exclude : ~
18
+ #loadpath: ~
19
+ #requires: ~
20
+ #live : false
21
+ active : false
22
+
23
+ qedoc:
24
+ files : spec/
25
+ output: QED.rdoc
26
+ active: false
27
+
28
+ vclog:
29
+ output: log/ChangeLog.rdoc
30
+ active: false
31
+
32
+ email:
33
+ service: Email
34
+ file : ~
35
+ subject: ~
36
+ mailto :
37
+ - ruby-talk@ruby-lang.org
38
+ - rubyworks-mailinglist@googlegroups.com
39
+ from : <%= ENV['EMAIL_ACCOUNT'] %>
40
+ server : <%= ENV['EMAIL_SERVER'] %>
41
+ port : <%= ENV['EMAIL_PORT'] %>
42
+ account: <%= ENV['EMAIL_ACCOUNT'] %>
43
+ domain : <%= ENV['EMAIL_DOMAIN'] %>
44
+ login : <%= ENV['EMAIL_LOGIN'] %>
45
+ secure : <%= ENV['EMAIL_SECURE'] %>
46
+
@@ -0,0 +1,59 @@
1
+ = COPYRIGHT NOTICES
2
+
3
+ == Lime Test Framework
4
+
5
+ Copyright:: (c) 2011 Thomas Sawyer, RubyWorks
6
+ License:: BSD-2-Clause
7
+ Website:: http://rubyworks.github.com/ruby-test
8
+
9
+ Copyright 2011 Thomas Sawyer. All rights reserved.
10
+
11
+ Redistribution and use in source and binary forms, with or without
12
+ modification, are permitted provided that the following conditions are met:
13
+
14
+ 1. Redistributions of source code must retain the above copyright notice,
15
+ this list of conditions and the following disclaimer.
16
+
17
+ 2. Redistributions in binary form must reproduce the above copyright
18
+ notice, this list of conditions and the following disclaimer in the
19
+ documentation and/or other materials provided with the distribution.
20
+
21
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
22
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
23
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24
+ COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
28
+ OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+
32
+
33
+ == Gherkin
34
+
35
+ Copyright:: (c) 2009-2011 Mike Sassak, Gregory Hnatiuk, Aslak Hellesøy
36
+ License:: MIT
37
+ Website:: https://github.com/cucumber/gherkin
38
+
39
+ Copyright (c) 2009-2011 Mike Sassak, Gregory Hnatiuk, Aslak Hellesøy
40
+
41
+ Permission is hereby granted, free of charge, to any person obtaining
42
+ a copy of this software and associated documentation files (the
43
+ "Software"), to deal in the Software without restriction, including
44
+ without limitation the rights to use, copy, modify, merge, publish,
45
+ distribute, sublicense, and/or sell copies of the Software, and to
46
+ permit persons to whom the Software is furnished to do so, subject to
47
+ the following conditions:
48
+
49
+ The above copyright notice and this permission notice shall be
50
+ included in all copies or substantial portions of the Software.
51
+
52
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
53
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
54
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
55
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
56
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
57
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
58
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
59
+
@@ -0,0 +1,25 @@
1
+ BSD 2 Clause License
2
+
3
+ Copyright 2011 Thomas Sawyer. All rights reserved.
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice,
9
+ this list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright
12
+ notice, this list of conditions and the following disclaimer in the
13
+ documentation and/or other materials provided with the distribution.
14
+
15
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
16
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
17
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
18
+ COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
19
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22
+ OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
+
@@ -0,0 +1,12 @@
1
+ #!mast .ruby .yaropts bin lib spec test [A-Z][A-Z]*
2
+ .ruby
3
+ lib/lime/advice.rb
4
+ lib/lime/feature.rb
5
+ lib/lime/scenario.rb
6
+ lib/lime/step.rb
7
+ lib/lime.rb
8
+ PROFILE
9
+ LICENSE.txt
10
+ README.md
11
+ VERSION
12
+ COPYING.rdoc
data/PROFILE ADDED
@@ -0,0 +1,29 @@
1
+ ---
2
+ title : Lime
3
+ suite : RubyWorks
4
+ summary: Gherkin-style Test Framework
5
+ authors:
6
+ - Thomas Sawyer <transfire@gmail.com>
7
+
8
+ description:
9
+ Lime is a "Ruby DSL" knock-off of Cucumber's Gherkin
10
+ BDD nomenclature that runs on top of ruby-test.
11
+
12
+ resources:
13
+ home: http://rubyworks.github.com/lime
14
+ code: http://github.com/rubyworks/lime
15
+ mail: http://groups.google.com/group/rubyworks-mailinglist
16
+
17
+ repositories:
18
+ upstream: git://github.com/proutils/lime.git
19
+
20
+ copyrights:
21
+ - 2011 Thomas Sawyer (BSD-2-Clause)
22
+
23
+ requirements:
24
+ - test
25
+ - ae
26
+ - detroit (build)
27
+ - reap (build)
28
+ - qed (test)
29
+
@@ -0,0 +1,65 @@
1
+ # Lime
2
+
3
+ Author:: Thomas Sawyer
4
+ License:: FreeBSD
5
+ Copyright:: (c) 2011 Thomas Sawyer, Rubyworks
6
+
7
+
8
+ ## Description
9
+
10
+ Lime is pure Ruby Gherkin-style test framework.
11
+
12
+
13
+ ## Example
14
+
15
+ ``` ruby
16
+ Feature "Addition" do
17
+ To "avoid silly mistakes"
18
+ As "a math idiot"
19
+ We "need to calculate the sum of numbers"
20
+
21
+ Scenario "Add two numbers" do
22
+ Given "I have a calculator"
23
+ Given "I have entered 50 into the calculator"
24
+ Given "I have entered 70 into the calculator"
25
+ When "I press add"
26
+ Then "the result should be 120 on the screen"
27
+ end
28
+
29
+ Scenario "Add three numbers" do
30
+ Given "I have a calculator"
31
+ Given "I have entered 50 into the calculator"
32
+ Given "I have entered 70 into the calculator"
33
+ Given "I have entered 90 into the calculator"
34
+ When "I press add"
35
+ Then "the result should be 2101 on the screen"
36
+ end
37
+
38
+ Given 'I have a calculator' do
39
+ require 'calculator'
40
+ @calculator = Calculator.new
41
+ end
42
+
43
+ Given 'I have entered (((\d+))) into the calculator' do |n|
44
+ @calculator.push n.to_i
45
+ end
46
+
47
+ When 'I press add' do
48
+ @result = @calculator.add
49
+ end
50
+
51
+ Then 'the result should be (((\d+))) on the screen' do |n|
52
+ @result.assert == n.to_i
53
+ end
54
+ end
55
+ ```
56
+
57
+
58
+ ## Copyrights
59
+
60
+ Copyright (c) 2011 Thomas Sawyer, Rubyworks
61
+
62
+ Lime is distributed according to the terms of the *FreeBSD* license.
63
+
64
+ See COPYING.rdoc for details.
65
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,28 @@
1
+ module Lime
2
+ $TEST_SUITE ||= []
3
+
4
+ require 'lime/advice'
5
+ require 'lime/feature'
6
+ require 'lime/scenario'
7
+ require 'lime/step'
8
+ end
9
+
10
+ # Ignore lime paths in backtraces
11
+ ignore_path = File.expand_path(File.dirname(__FILE__) + '/lime')
12
+ ignore_regexp = Regexp.new(Regexp.escape(ignore_path))
13
+ RUBY_IGNORE_CALLERS = [] unless defined? RUBY_IGNORE_CALLERS
14
+ RUBY_IGNORE_CALLERS << ignore_regexp
15
+ RUBY_IGNORE_CALLERS << /bin\/ruby-test/
16
+
17
+ module Test
18
+ extend self
19
+
20
+ # Define a general test case.
21
+ def Feature(label, &block)
22
+ $TEST_SUITE << Lime::Feature.new(:label=>label, &block)
23
+ end
24
+
25
+ alias :feature :Feature
26
+ end
27
+
28
+ extend Test
@@ -0,0 +1,31 @@
1
+ module Lime
2
+
3
+ # Test Advice
4
+ class Advice
5
+
6
+ #
7
+ attr :table
8
+
9
+ # New case instance.
10
+ def initialize
11
+ @table = Hash.new{ |h,k| h[k] = {} }
12
+ end
13
+
14
+ #
15
+ def initialize_copy(original)
16
+ @table = original.table.clone
17
+ end
18
+
19
+ #
20
+ def [](type)
21
+ @table[type.to_sym]
22
+ end
23
+
24
+ ## Returns the description with newlines removed.
25
+ #def to_s
26
+ # description.gsub(/\n/, ' ')
27
+ #end
28
+
29
+ end
30
+
31
+ end
@@ -0,0 +1,251 @@
1
+ #require 'lime/pending'
2
+ require 'lime/advice'
3
+ require 'lime/scenario'
4
+
5
+ module Lime
6
+
7
+ # The TestFeature ...
8
+ #
9
+ # The `advice` are _given_, _when_ and _then_ rules.
10
+ #
11
+ class Feature
12
+
13
+ # Brief description of the feature.
14
+ attr :label
15
+
16
+ #
17
+ attr :story
18
+
19
+ # List of tests and sub-cases.
20
+ attr :scenarios
21
+
22
+ # Advice are labeled procedures, such as before
23
+ # and after advice.
24
+ attr :advice
25
+
26
+ # Module for evaluating tests.
27
+ attr :scope
28
+
29
+ #
30
+ def initialize(settings={}, &block)
31
+ @label = settings[:label]
32
+ @setup = settings[:setup]
33
+
34
+ @advice = Advice.new
35
+ @scope = Module.new
36
+
37
+ @story = []
38
+ @scenarios = []
39
+
40
+ @scope.extend DSL.new(self, &block)
41
+ end
42
+
43
+ # Convenience method for accessing advice, aka step definitions.
44
+ def [](key)
45
+ @advice[key]
46
+ end
47
+
48
+ # Iterate over each scenario.
49
+ def each(&block)
50
+ scenarios.each(&block)
51
+ end
52
+
53
+ # Number of scenarios.
54
+ def size
55
+ scenarios.size
56
+ end
57
+
58
+ # Subclasses of TestCase can override this to describe
59
+ # the type of test case they define.
60
+ def type
61
+ 'Feature'
62
+ end
63
+
64
+ #
65
+ def to_s
66
+ (["#{label}"] + story).join("\n")
67
+ end
68
+
69
+ #
70
+ def omit?
71
+ @omit
72
+ end
73
+
74
+ #
75
+ def omit=(boolean)
76
+ @omit = boolean
77
+ end
78
+
79
+ #
80
+ def update(mixin)
81
+ @advice[:given].concat mixin[:given] || []
82
+ @advice[:when].concat mixin[:when] || []
83
+ @advice[:then].concat mixin[:then] || []
84
+ @scope.extend mixin if Module === mixin
85
+ end
86
+
87
+ #
88
+ class DSL < Module
89
+
90
+ #
91
+ def initialize(feature, &code)
92
+ @_feature = feature
93
+
94
+ module_eval(&code)
95
+ end
96
+
97
+ #
98
+ def To(description)
99
+ @_feature.story << "To " + description
100
+ end
101
+ alias_method :to, :To
102
+
103
+ #
104
+ def As(description)
105
+ @_feature.story << "As " + description
106
+ end
107
+ alias_method :as, :As
108
+
109
+ #
110
+ def We(description)
111
+ @_feature.story << "We " + description
112
+ end
113
+ alias_method :we, :We
114
+
115
+ #
116
+ def Scenario(label, &procedure)
117
+ scenario = Scenario.new(@_feature, :label=>label, &procedure)
118
+ @_feature.scenarios << scenario
119
+ scenario
120
+ end
121
+ alias_method :scenario, :Scenario
122
+
123
+ # Omit a scenario from test runs.
124
+ #
125
+ # omit unit :foo do
126
+ # # ...
127
+ # end
128
+ #
129
+ def Omit(scenario)
130
+ scenario.omit = true
131
+ end
132
+ alias_method :omit, :Omit
133
+
134
+ # Given ...
135
+ #
136
+ # @param [String] description
137
+ # A brief description of the _given_ criteria.
138
+ #
139
+ def Given(description, &procedure)
140
+ @_feature[:given][description] = procedure
141
+ end
142
+ alias_method :given, :Given
143
+
144
+ # When ...
145
+ #
146
+ # @param [String] description
147
+ # A brief description of the _when_ criteria.
148
+ #
149
+ def When(description, &procedure)
150
+ @_feature[:when][description] = procedure
151
+ end
152
+ alias_method :wence, :When
153
+
154
+ # Then ...
155
+ #
156
+ # @param [String] description
157
+ # A brief description of the _then_ criteria.
158
+ #
159
+ def Then(description, &procedure)
160
+ @_feature[:then][description] = procedure
161
+ end
162
+ alias_method :hence, :Then
163
+
164
+ #
165
+ def _feature
166
+ @_feature
167
+ end
168
+
169
+ #
170
+ def include(mixin)
171
+ if Featurable === mixin
172
+ @_feature.update(mixin)
173
+ super(mixin)
174
+ else
175
+ super(mixin)
176
+ end
177
+ end
178
+
179
+ end
180
+
181
+ # Convenience method for creating a feature mixin.
182
+ #
183
+ # @example
184
+ #
185
+ # module MySteps
186
+ # include Lime::Featurable
187
+ # Given "customer's name is '(((\s+)))'" do |name|
188
+ # @name = name
189
+ # end
190
+ # end
191
+ #
192
+ # Feature do
193
+ # include MySteps
194
+ # end
195
+ #
196
+ module Featurable
197
+
198
+ def self.append_features(base)
199
+ base.extend(self)
200
+ base.module_eval %{
201
+ @_advice = Hash.new { |h,k| h[k]={} }
202
+ }
203
+ end
204
+
205
+ #
206
+ #def initialize(&code)
207
+ # @_advice = Hash.new { |h,k| h[k]={} }
208
+ #
209
+ # module_eval(&code)
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
+ alias_method :given, :Given
221
+
222
+ # When ...
223
+ #
224
+ # @param [String] description
225
+ # A brief description of the _when_ criteria.
226
+ #
227
+ def When(description, &procedure)
228
+ @_advice[:when][description] = procedure
229
+ end
230
+ alias_method :wence, :When
231
+
232
+ # Then ...
233
+ #
234
+ # @param [String] description
235
+ # A brief description of the _then_ criteria.
236
+ #
237
+ def Then(description, &procedure)
238
+ @_advice[:then][description] = procedure
239
+ end
240
+ alias_method :hence, :Then
241
+
242
+ # Access to internal feature instance.
243
+ def [](key)
244
+ @_advice[key]
245
+ end
246
+
247
+ end
248
+
249
+ end
250
+
251
+ end
@@ -0,0 +1,160 @@
1
+ require 'lime/step'
2
+
3
+ module Lime
4
+
5
+ #
6
+ class Scenario
7
+
8
+ #
9
+ def initialize(feature, settings={}, &block)
10
+ @feature = feature
11
+
12
+ @label = settings[:label]
13
+
14
+ @scope = Module.new
15
+
16
+ @steps = []
17
+
18
+ @scope.extend DSL.new(self, &block)
19
+ end
20
+
21
+ #
22
+ attr :feature
23
+
24
+ #
25
+ attr :label
26
+
27
+ #
28
+ attr :steps
29
+
30
+ #
31
+ attr :scope
32
+
33
+ #
34
+ def omit?
35
+ @omit
36
+ end
37
+
38
+ #
39
+ def omit=(boolean)
40
+ @omit = boolean
41
+ end
42
+
43
+ #
44
+ def each(&block)
45
+ @steps.each(&block)
46
+ end
47
+
48
+ #
49
+ def size(&block)
50
+ @steps.size
51
+ end
52
+
53
+ #
54
+ def type
55
+ "Scenario"
56
+ end
57
+
58
+ #
59
+ def to_s
60
+ @label.to_s
61
+ end
62
+
63
+ # FIXME
64
+ def subject
65
+ end
66
+
67
+ #
68
+ def run(step)
69
+ type = step.type
70
+ desc = step.label
71
+ feature.advice[type].each do |mask, proc|
72
+ if md = match_regexp(mask).match(desc)
73
+ scope.instance_exec(*md[1..-1], &proc)
74
+ end
75
+ end
76
+ end
77
+
78
+ #
79
+ #--
80
+ # TODO: Change so that the scope is the DSL
81
+ # and includes the DSL of the context?
82
+ #++
83
+ #def scope
84
+ # @scope ||= (
85
+ # #if feature
86
+ # # scope = feature.scope || Object.new
87
+ # # scope.extend(dsl)
88
+ # #else
89
+ # scope = Object.new
90
+ # scope.extend(dsl)
91
+ # #end
92
+ # )
93
+ #end
94
+
95
+ #
96
+ #def find
97
+ # features.clauses[@type].find{ |c| c =~ @description }
98
+ #end
99
+
100
+ # Convert matching string into a regular expression. If the string
101
+ # contains double parenthesis, such as ((.*?)), then the text within
102
+ # them is treated as in regular expression and kept verbatium.
103
+ #
104
+ # TODO: Better way to isolate regexp. Maybe ?:(.*?) or /(.*?)/.
105
+ #
106
+ def match_regexp(str)
107
+ str = str.split(/(\(\(.*?\)\))(?!\))/).map{ |x|
108
+ x =~ /\A\(\((.*)\)\)\Z/ ? $1 : Regexp.escape(x)
109
+ }.join
110
+ str = str.gsub(/\\\s+/, '\s+')
111
+ Regexp.new(str, Regexp::IGNORECASE)
112
+ end
113
+
114
+ # TODO: Need to ensure the correct order of Given, When, Then.
115
+ class DSL < Module
116
+
117
+ #
118
+ def initialize(scenario, &code)
119
+ @scenario = scenario
120
+
121
+ extend(scenario.feature.scope)
122
+
123
+ module_eval(&code)
124
+ end
125
+
126
+ # Given ...
127
+ #
128
+ # @param [String] description
129
+ # A matching description of the _given_ procedure.
130
+ #
131
+ def Given(label)
132
+ @scenario.steps << Step.new(@scenario, label, :type=>:given)
133
+ end
134
+ alias_method :given, :Given
135
+
136
+ # When ...
137
+ #
138
+ # @param [String] label
139
+ # A matching description of the _when_ procedure.
140
+ #
141
+ def When(label)
142
+ @scenario.steps << Step.new(@scenario, label, :type=>:when)
143
+ end
144
+ alias_method :wence, :When
145
+
146
+ # Then ...
147
+ #
148
+ # @param [String] label
149
+ # A matching description of the _then_ procedure.
150
+ #
151
+ def Then(label)
152
+ @scenario.steps << Step.new(@scenario, label, :type=>:then)
153
+ end
154
+ alias_method :hence, :Then
155
+
156
+ end
157
+
158
+ end
159
+
160
+ end
@@ -0,0 +1,64 @@
1
+ module Lime
2
+
3
+ # Test step.
4
+ #
5
+ class Step
6
+
7
+ # New unit test procedure.
8
+ #
9
+ def initialize(scenario, label, settings={})
10
+ @scenario = scenario
11
+ @label = label
12
+
13
+ @type = settings[:type]
14
+
15
+ @omit = false
16
+ #@tested = false
17
+ end
18
+
19
+ # The type of step (:given, :when or :then).
20
+ attr :type
21
+
22
+ # The scenario to which this step belongs.
23
+ attr :scenario
24
+
25
+ # Label of test.
26
+ attr :label
27
+
28
+ #
29
+ def omit?
30
+ @omit
31
+ end
32
+
33
+ #
34
+ def omit=(boolean)
35
+ @omit = boolean
36
+ end
37
+
38
+ #
39
+ def to_s
40
+ "#{type.to_s.capitalize} #{label}"
41
+ end
42
+
43
+ # FIXME
44
+ def subject
45
+ end
46
+
47
+ #
48
+ def to_proc
49
+ lambda{ call }
50
+ end
51
+
52
+ #
53
+ #def match?(match)
54
+ # match == target || match === label
55
+ #end
56
+
57
+ #
58
+ def call
59
+ scenario.run(self)
60
+ end
61
+
62
+ end
63
+
64
+ end
@@ -0,0 +1,152 @@
1
+ # encoding: utf-8
2
+
3
+ require 'yaml'
4
+
5
+ Gem::Specification.new do |gemspec|
6
+
7
+ manifest = Dir.glob('manifest{,.txt)', File::FNM_CASEFOLD).first
8
+
9
+ scm = case
10
+ when File.directory?('.git')
11
+ :git
12
+ end
13
+
14
+ files = case
15
+ when manifest
16
+ File.readlines(manifest).
17
+ map{ |line| line.srtip }.
18
+ reject{ |line| line.empty? || line[0,1] == '#' }
19
+ when scm == :git
20
+ `git ls-files -z`.split("\0")
21
+ else
22
+ Dir.glob('{**/}{.*,*}') # TODO: be more specific using standard locations ?
23
+ end.select{ |path| File.file?(path) }
24
+
25
+ patterns = {
26
+ :bin_files => 'bin/*',
27
+ :lib_files => 'lib/{**/}*.rb',
28
+ :ext_files => 'ext/{**/}extconf.rb',
29
+ :doc_files => '*.{txt,rdoc,md,markdown,tt,textile}',
30
+ :test_files => '{test/{**/}*_test.rb,spec/{**/}*_spec.rb}'
31
+ }
32
+
33
+ glob_files = lambda { |pattern|
34
+ Dir.glob(pattern).select { |path|
35
+ File.file?(path) && files.include?(path)
36
+ }
37
+ }
38
+
39
+ #files = glob_files[patterns[:files]]
40
+
41
+ executables = glob_files[patterns[:bin_files]].map do |path|
42
+ File.basename(path)
43
+ end
44
+
45
+ extensions = glob_files[patterns[:ext_files]].map do |path|
46
+ File.basename(path)
47
+ end
48
+
49
+ metadata = YAML.load_file('.ruby')
50
+
51
+ # build-out the gemspec
52
+
53
+ case metadata['revision']
54
+ when 0
55
+ gemspec.name = metadata['name']
56
+ gemspec.version = metadata['version']
57
+ gemspec.summary = metadata['summary']
58
+ gemspec.description = metadata['description']
59
+
60
+ metadata['authors'].each do |author|
61
+ gemspec.authors << author['name']
62
+
63
+ if author.has_key?('email')
64
+ if gemspec.email
65
+ gemspec.email << author['email']
66
+ else
67
+ gemspec.email = [author['email']]
68
+ end
69
+ end
70
+ end
71
+
72
+ gemspec.licenses = metadata['licenses']
73
+
74
+ metadata['requirements'].each do |req|
75
+ name = req['name']
76
+ version = req['version']
77
+ groups = req['groups'] || []
78
+
79
+ if md = /^(.*?)([+-~])$/.match(version)
80
+ version = case md[2]
81
+ when '+' then ">= #{$1}"
82
+ when '-' then "< #{$1}"
83
+ when '~' then "~> #{$1}"
84
+ else version
85
+ end
86
+ end
87
+
88
+ #development = req['development']
89
+ #if development
90
+ # # populate development dependencies
91
+ # if gemspec.respond_to?(:add_development_dependency)
92
+ # gemspec.add_development_dependency(name,*version)
93
+ # else
94
+ # gemspec.add_dependency(name,*version)
95
+ # end
96
+ #else
97
+ # # populate runtime dependencies
98
+ # if gemspec.respond_to?(:add_runtime_dependency)
99
+ # gemspec.add_runtime_dependency(name,*version)
100
+ # else
101
+ # gemspec.add_dependency(name,*version)
102
+ # end
103
+ #end
104
+
105
+ if groups.empty? or groups.include?('runtime')
106
+ # populate runtime dependencies
107
+ if gemspec.respond_to?(:add_runtime_dependency)
108
+ gemspec.add_runtime_dependency(name,*version)
109
+ else
110
+ gemspec.add_dependency(name,*version)
111
+ end
112
+ else
113
+ # populate development dependencies
114
+ if gemspec.respond_to?(:add_development_dependency)
115
+ gemspec.add_development_dependency(name,*version)
116
+ else
117
+ gemspec.add_dependency(name,*version)
118
+ end
119
+ end
120
+ end
121
+
122
+ # convert external dependencies into a requirements
123
+ if metadata['external_dependencies']
124
+ ##gemspec.requirements = [] unless metadata['external_dependencies'].empty?
125
+ metadata['external_dependencies'].each do |req|
126
+ gemspec.requirements << req.to_s
127
+ end
128
+ end
129
+
130
+ # determine homepage from resources
131
+ homepage = metadata['resources'].find{ |key, url| key =~ /^home/ }
132
+ gemspec.homepage = homepage.last if homepage
133
+
134
+ gemspec.require_paths = metadata['load_path'] || ['lib']
135
+ gemspec.post_install_message = metadata['install_message']
136
+
137
+ # RubyGems specific metadata
138
+ gemspec.files = files
139
+ gemspec.extensions = extensions
140
+ gemspec.executables = executables
141
+
142
+ if Gem::VERSION < '1.7.'
143
+ gemspec.default_executable = gemspec.executables.first
144
+ end
145
+
146
+ gemspec.test_files = glob_files[patterns[:test_files]]
147
+
148
+ unless gemspec.files.include?('.document')
149
+ gemspec.extra_rdoc_files = glob_files[patterns[:doc_files]]
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,3 @@
1
+ $:.unshift '.'
2
+ require 'ae'
3
+ require 'lime'
@@ -0,0 +1,15 @@
1
+ class Calculator
2
+
3
+ def initialize
4
+ @stack = []
5
+ end
6
+
7
+ def push(int)
8
+ @stack << int
9
+ end
10
+
11
+ def add
12
+ @stack.inject(0){ |sum, val| sum += val; sum }
13
+ end
14
+
15
+ end
@@ -0,0 +1,40 @@
1
+ Test::Feature "Addition" do
2
+ To "avoid silly mistakes"
3
+ As "a math idiot"
4
+ We "need to calculate the sum of numbers"
5
+
6
+ Scenario "Add two numbers" do
7
+ Given "I have a calculator"
8
+ Given "I have entered 50 into the calculator"
9
+ Given "I have entered 70 into the calculator"
10
+ When "I press add"
11
+ Then "the result should be 120 on the screen"
12
+ end
13
+
14
+ Scenario "Add three numbers" do
15
+ Given "I have a calculator"
16
+ Given "I have entered 50 into the calculator"
17
+ Given "I have entered 70 into the calculator"
18
+ Given "I have entered 90 into the calculator"
19
+ When "I press add"
20
+ Then "the result should be 210 on the screen"
21
+ end
22
+
23
+ Given 'I have a calculator' do
24
+ require 'calculator'
25
+ @calculator = Calculator.new
26
+ end
27
+
28
+ Given 'I have entered (((\d+))) into the calculator' do |n|
29
+ @calculator.push n.to_i
30
+ end
31
+
32
+ When 'I press add' do
33
+ @result = @calculator.add
34
+ end
35
+
36
+ Then 'the result should be (((\d+))) on the screen' do |n|
37
+ @result.assert == n.to_i
38
+ end
39
+ end
40
+
metadata ADDED
@@ -0,0 +1,129 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lime
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.0
6
+ platform: ruby
7
+ authors:
8
+ - Thomas Sawyer
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-07-29 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: test
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ type: :runtime
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: ae
28
+ prerelease: false
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "0"
35
+ type: :runtime
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: detroit
39
+ prerelease: false
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ type: :development
47
+ version_requirements: *id003
48
+ - !ruby/object:Gem::Dependency
49
+ name: reap
50
+ prerelease: false
51
+ requirement: &id004 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ type: :development
58
+ version_requirements: *id004
59
+ - !ruby/object:Gem::Dependency
60
+ name: qed
61
+ prerelease: false
62
+ requirement: &id005 !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "0"
68
+ type: :development
69
+ version_requirements: *id005
70
+ description: Lime is a "Ruby DSL" knock-off of Cucumber's Gherkin BDD nomenclature that runs on top of ruby-test.
71
+ email:
72
+ - transfire@gmail.com
73
+ executables: []
74
+
75
+ extensions: []
76
+
77
+ extra_rdoc_files:
78
+ - LICENSE.txt
79
+ - COPYING.rdoc
80
+ - README.md
81
+ files:
82
+ - .gitignore
83
+ - .ruby
84
+ - .yardopts
85
+ - Assembly
86
+ - COPYING.rdoc
87
+ - LICENSE.txt
88
+ - MANIFEST
89
+ - PROFILE
90
+ - README.md
91
+ - VERSION
92
+ - lib/lime.rb
93
+ - lib/lime/advice.rb
94
+ - lib/lime/feature.rb
95
+ - lib/lime/scenario.rb
96
+ - lib/lime/step.rb
97
+ - lime.gemspec
98
+ - try/.testrb
99
+ - try/calculator.rb
100
+ - try/feature_example.rb
101
+ homepage: http://rubyworks.github.com/lime
102
+ licenses: []
103
+
104
+ post_install_message:
105
+ rdoc_options: []
106
+
107
+ require_paths:
108
+ - lib
109
+ required_ruby_version: !ruby/object:Gem::Requirement
110
+ none: false
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: "0"
115
+ required_rubygems_version: !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: "0"
121
+ requirements: []
122
+
123
+ rubyforge_project:
124
+ rubygems_version: 1.8.2
125
+ signing_key:
126
+ specification_version: 3
127
+ summary: Gherkin-style Test Framework
128
+ test_files: []
129
+