lime 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+