macros4cuke 0.3.17 → 0.3.18
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +8 -0
- data/README.md +45 -4
- data/examples/demo/features/multiline.feature +30 -0
- data/examples/demo/features/step_definitions/step_defs.rb +9 -1
- data/lib/macros4cuke/constants.rb +1 -1
- data/lib/macros4cuke/macro-step.rb +15 -7
- data/lib/macros4cuke/templating/engine.rb +2 -3
- data/spec/macros4cuke/macro-step_spec.rb +21 -2
- metadata +3 -2
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
## 0.3.18 / 2013-05-21
|
2
|
+
* [FEATURE] Support for sub-steps having multiline text arguments (docstring).
|
3
|
+
* [CHANGE] Method MacroStep#expand passes also built-in arguments to template engine.
|
4
|
+
* [CHANGE] Method MacroStep#validate_phrase_args does not apply validations on built-in arguments.
|
5
|
+
* [CHANGE] File `macro-step_spec.rb`: Added one example to test the insertion of triple quotes.
|
6
|
+
* [NEW] File `multiline.feature` added in examples/features/ folder.
|
7
|
+
* [CHANGE] File `README.md`: Added section 'Sub-steps with multiline text argument'
|
8
|
+
|
1
9
|
## 0.3.17 / 2013-05-20
|
2
10
|
* [CHANGE] File `README.md`: Added dynamic dependencies badge (Gemnasium).
|
3
11
|
|
data/README.md
CHANGED
@@ -236,7 +236,7 @@ The next example is based on one of the demo feature files:
|
|
236
236
|
"""
|
237
237
|
```
|
238
238
|
|
239
|
-
This step can be used like this:
|
239
|
+
This step can be used like this:
|
240
240
|
```cucumber
|
241
241
|
When I [enter my address as follows]:"
|
242
242
|
|lastname|Doe|
|
@@ -272,13 +272,13 @@ Taking again a previous example of a -partial- macro-step definition:
|
|
272
272
|
"""
|
273
273
|
```
|
274
274
|
|
275
|
-
The following step invokation is invalid:
|
275
|
+
The following step invokation is invalid:
|
276
276
|
```cucumber
|
277
277
|
When I [travel from "San Francisco" to via "Las Vegas"]
|
278
278
|
```
|
279
279
|
|
280
280
|
The issue is: the destination value is missing, Macros4Cuke won't be able to find a step with that syntax.
|
281
|
-
The next invokation is syntactically correct for Macros4Cuke:
|
281
|
+
The next invokation is syntactically correct for Macros4Cuke:
|
282
282
|
```cucumber
|
283
283
|
When I [travel from "San Francisco" to "" via "Las Vegas"]
|
284
284
|
```
|
@@ -290,6 +290,47 @@ For any argument that can receive a value through a data table, three situations
|
|
290
290
|
2. A row for that argument and an empty text value are specified at invokation. The argument is bound to an empty text.
|
291
291
|
3. There is no row for that argument. The argument is unbound (nil) but is rendered as an empty text.
|
292
292
|
|
293
|
+
## Sub-steps with multiline text argument ##
|
294
|
+
- __Question__: is it possible to define a macro-step with a sub-step that itself
|
295
|
+
uses a multiline text argument (also called a docstring)?
|
296
|
+
- __Answer__: Yes but there is a catch.
|
297
|
+
|
298
|
+
Consider the following attempt of a macro-step definition:
|
299
|
+
```cucumber
|
300
|
+
Given I define the step "* I [make a long journey]" to mean:
|
301
|
+
"""
|
302
|
+
When I visit the cities:
|
303
|
+
"""
|
304
|
+
Amsterdam
|
305
|
+
Brussels
|
306
|
+
Copenhagen
|
307
|
+
"""
|
308
|
+
"""
|
309
|
+
```
|
310
|
+
|
311
|
+
This will result in an error. The issue is caused by the nesting of triple quotes:
|
312
|
+
Cucumber simply doesn't allow this. In fact, the error is reported by [Gherkin](https://github.com/cucumber/gherkin),
|
313
|
+
a component used by Cucumber.
|
314
|
+
As Gherkin has other [issues](https://github.com/cucumber/gherkin/issues/124) with docstrings, we
|
315
|
+
need a workaround today until the fixes are applied.
|
316
|
+
The workaround is the following:
|
317
|
+
- There exists in Macros4Cuke a predefined sub-step argument called __\<quotes\>__ and its value
|
318
|
+
is set to a triple quote sequence """.
|
319
|
+
- Use it everywhere you want to place nested triple quotes.
|
320
|
+
|
321
|
+
Thus to make the previous example work, one must change it like follows:
|
322
|
+
```cucumber
|
323
|
+
Given I define the step "* I [make a long journey]" to mean:
|
324
|
+
"""
|
325
|
+
When I visit the cities:
|
326
|
+
<quotes>
|
327
|
+
Amsterdam
|
328
|
+
Brussels
|
329
|
+
Copenhagen
|
330
|
+
<quotes>
|
331
|
+
"""
|
332
|
+
```
|
333
|
+
|
293
334
|
|
294
335
|
## Conditional sections in substeps. ##
|
295
336
|
To make the macros more flexible, it is possible to define conditional sections in the substep sequence.
|
@@ -377,7 +418,7 @@ This last argument becomes important in the context of user acceptance testing,
|
|
377
418
|
every tester is also Rubyist is -alas!- far from the truth.
|
378
419
|
|
379
420
|
|
380
|
-
Macros with Cucumber is highly debated topic, so it is
|
421
|
+
Macros with Cucumber is highly debated topic, so it is good to know what other people say about it:
|
381
422
|
[Support for Macros] (https://github.com/cucumber/gherkin/issues/178)
|
382
423
|
[Substeps - macro request for the nth time] (http://grokbase.com/t/gg/cukes/133ey063b8/cucumber-substeps-macro-request-for-the-nth-time)
|
383
424
|
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# File: multiline.feature
|
2
|
+
|
3
|
+
Feature: Show how multiline text inside macros
|
4
|
+
As a Cuke user
|
5
|
+
So that I enjoy writing scenario.
|
6
|
+
|
7
|
+
|
8
|
+
Scenario: Using a step with multiline text argument
|
9
|
+
When I visit the cities:
|
10
|
+
"""
|
11
|
+
Amsterdam
|
12
|
+
Brussels
|
13
|
+
Copenhagen
|
14
|
+
"""
|
15
|
+
|
16
|
+
Scenario: Definition of macro-step having a substep with multiline text
|
17
|
+
Given I define the step "* I [make a long journey from <origin> to <destination>]" to mean:
|
18
|
+
"""
|
19
|
+
When I visit the cities:
|
20
|
+
<quotes>
|
21
|
+
<origin>
|
22
|
+
Amsterdam
|
23
|
+
Brussels
|
24
|
+
Copenhagen
|
25
|
+
<destination>
|
26
|
+
<quotes>
|
27
|
+
"""
|
28
|
+
|
29
|
+
# Now use it...
|
30
|
+
When I [make a long journey from "London" to "Oslo"]
|
@@ -7,15 +7,23 @@ When(/^I leave '(.*)'$/) do |city|
|
|
7
7
|
end
|
8
8
|
|
9
9
|
|
10
|
-
When(/^I visit (
|
10
|
+
When(/^I visit (\S+)$/) do |city|
|
11
11
|
show "I visit #{city}"
|
12
12
|
end
|
13
13
|
|
14
14
|
|
15
|
+
# This step uses a multiline text argument
|
16
|
+
When(/^I visit the cities:$/) do |cities_raw|
|
17
|
+
cities = cities_raw.split(/\r\n?|\n/)
|
18
|
+
cities.each { |city| show "I visit #{city}" }
|
19
|
+
end
|
20
|
+
|
21
|
+
|
15
22
|
When(/^I arrive in (.+)$/) do |city|
|
16
23
|
show "I arrive in #{city}"
|
17
24
|
end
|
18
25
|
|
26
|
+
|
19
27
|
When(/^I type \"([^"]*)\"$/) do |text|
|
20
28
|
show text
|
21
29
|
end
|
@@ -16,6 +16,11 @@ module Macros4Cuke # Module used as a namespace
|
|
16
16
|
# The actual values bound to these arguments
|
17
17
|
# are passed to the sub-steps at execution time.
|
18
18
|
class MacroStep
|
19
|
+
# The set of predefined macro argument constant values.
|
20
|
+
BuiltinParameters = {
|
21
|
+
'quotes' => '"""'
|
22
|
+
}
|
23
|
+
|
19
24
|
# A template engine that expands the sub-steps upon request.
|
20
25
|
attr_reader(:renderer)
|
21
26
|
|
@@ -28,7 +33,6 @@ class MacroStep
|
|
28
33
|
# The list of macro argument names (as appearing in the substeps
|
29
34
|
# and in the macro phrase).
|
30
35
|
attr_reader(:args)
|
31
|
-
|
32
36
|
|
33
37
|
# Constructor.
|
34
38
|
# @param aMacroPhrase[String] The text from the macro step definition
|
@@ -110,11 +114,15 @@ class MacroStep
|
|
110
114
|
# Render the steps from the template, given the values
|
111
115
|
# taken by the parameters
|
112
116
|
# @param aPhrase [String] an instance of the macro phrase.
|
113
|
-
# @param rawData [Array or nil] An Array with
|
117
|
+
# @param rawData [Array or nil] An Array with couples of the form:
|
114
118
|
# [macro argument name, a value].
|
115
119
|
# Multiple rows with same argument name are acceptable.
|
116
120
|
def expand(aPhrase, rawData)
|
117
121
|
params = validate_params(aPhrase, rawData)
|
122
|
+
|
123
|
+
# Add built-in constants if necessary.
|
124
|
+
params = BuiltinParameters.merge(params)
|
125
|
+
|
118
126
|
return renderer.render(nil, params)
|
119
127
|
end
|
120
128
|
|
@@ -132,7 +140,6 @@ private
|
|
132
140
|
quoted_values.each_with_index do |val, index|
|
133
141
|
macro_parameters[phrase_args[index]] = val
|
134
142
|
end
|
135
|
-
|
136
143
|
|
137
144
|
unless rawData.nil?
|
138
145
|
rawData.each do |(a_key, value)|
|
@@ -153,7 +160,7 @@ private
|
|
153
160
|
end
|
154
161
|
|
155
162
|
|
156
|
-
|
163
|
+
|
157
164
|
|
158
165
|
# Retrieve from the macro phrase, all the text between <..> or double quotes.
|
159
166
|
# Returns an array. Each of its elements corresponds to quoted text.
|
@@ -180,7 +187,7 @@ private
|
|
180
187
|
|
181
188
|
return args
|
182
189
|
end
|
183
|
-
|
190
|
+
|
184
191
|
# Return the substeps text after some transformation
|
185
192
|
# [theSubstepsSource] The source text of the steps
|
186
193
|
# to be expanded upon macro invokation.
|
@@ -208,8 +215,9 @@ private
|
|
208
215
|
# and the macro-step does not use data table.
|
209
216
|
unless use_table?
|
210
217
|
substepsVars.each do |substep_arg|
|
211
|
-
unless thePhraseArgs.include?
|
212
|
-
|
218
|
+
unless (thePhraseArgs.include?(substep_arg) ||
|
219
|
+
BuiltinParameters.include?(substep_arg))
|
220
|
+
raise UnreachableSubstepArgument.new(substep_arg)
|
213
221
|
end
|
214
222
|
end
|
215
223
|
end
|
@@ -166,9 +166,8 @@ public
|
|
166
166
|
end # class
|
167
167
|
|
168
168
|
|
169
|
-
#
|
170
|
-
#
|
171
|
-
# on the (in)existence of an actual value bound to the variable name.
|
169
|
+
# A specialized section in a template for which its rendition
|
170
|
+
# depends on the (in)existence of an actual value bound to the variable name.
|
172
171
|
class ConditionalSection < Section
|
173
172
|
# A boolean that indicates whether the rendition condition is
|
174
173
|
# the existence of a value for the variable (true)
|
@@ -94,7 +94,7 @@ SNIPPET
|
|
94
94
|
|
95
95
|
text.should == expectation
|
96
96
|
end
|
97
|
-
|
97
|
+
|
98
98
|
it "should un-escape the double-quotes for phrase arguments" do
|
99
99
|
specific_phrase = %q|enter my credentials as "quotable\""|
|
100
100
|
text = subject.expand(specific_phrase, [ %w(password no-secret) ])
|
@@ -109,7 +109,7 @@ SNIPPET
|
|
109
109
|
text.should == expectation
|
110
110
|
end
|
111
111
|
|
112
|
-
|
112
|
+
|
113
113
|
it "should complain when an unknown variable is used" do
|
114
114
|
# Error case: there is no macro argument called <unknown>
|
115
115
|
error_message = "Unknown macro-step argument 'unknown'."
|
@@ -118,6 +118,25 @@ SNIPPET
|
|
118
118
|
UnknownArgumentError, error_message)
|
119
119
|
end
|
120
120
|
|
121
|
+
|
122
|
+
it "should expand built-in variables" do
|
123
|
+
phrase = "do nothing useful"
|
124
|
+
substeps = <<-SNIPPET
|
125
|
+
Given I travel through:
|
126
|
+
<quotes>
|
127
|
+
London
|
128
|
+
Paris
|
129
|
+
San Francisco
|
130
|
+
<quotes>
|
131
|
+
SNIPPET
|
132
|
+
|
133
|
+
instance = MacroStep.new(phrase, substeps, true)
|
134
|
+
actual = instance.expand(phrase, [])
|
135
|
+
expected = substeps.gsub(/<quotes>/, '"""')
|
136
|
+
actual.should == expected
|
137
|
+
end
|
138
|
+
|
139
|
+
|
121
140
|
end # context
|
122
141
|
|
123
142
|
end # describe
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: macros4cuke
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.18
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-05-
|
12
|
+
date: 2013-05-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: cucumber
|
@@ -104,6 +104,7 @@ files:
|
|
104
104
|
- lib/macros4cuke/templating/engine.rb
|
105
105
|
- examples/demo/cucumber.yml
|
106
106
|
- examples/demo/features/basic.feature
|
107
|
+
- examples/demo/features/multiline.feature
|
107
108
|
- examples/demo/features/step_definitions/step_defs.rb
|
108
109
|
- examples/demo/features/step_definitions/use_macro_steps.rb
|
109
110
|
- examples/demo/features/support/env.rb
|