macros4cuke 0.2.17 → 0.2.18
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/CHANGELOG.md +4 -0
- data/features/demo05.feature +37 -0
- data/lib/macro_steps.rb +3 -3
- data/lib/macros4cuke/constants.rb +1 -1
- data/lib/macros4cuke/macro-collection.rb +1 -1
- data/lib/macros4cuke/macro-step-support.rb +1 -1
- data/lib/macros4cuke/macro-step.rb +3 -4
- data/lib/macros4cuke/templating/engine.rb +17 -4
- data/spec/macros4cuke/macro-step-support_spec.rb +2 -2
- data/spec/macros4cuke/templating/engine_spec.rb +40 -7
- metadata +3 -2
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
## 0.2.18 / 2013-05-06
|
2
|
+
* [CHANGE] Amended spec files and added a new demo feature. SimpleCov code coverage raised to more than 97%.
|
3
|
+
* [CHANGE] Macro-step arguments can be multivalued (experimental)
|
4
|
+
|
1
5
|
## 0.2.17 / 2013-05-05
|
2
6
|
* [CHANGE] File `engine_spec.rb`: Added more RSpec examples. SimpleCov code coverage raised to more than 96%.
|
3
7
|
* [CHANGE] Added section in README.md
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# File: demo05.feature
|
2
|
+
|
3
|
+
Feature: Show the use of a macro with multiple arguments in a table
|
4
|
+
As a Cuke user
|
5
|
+
So that I enjoy writing scenario.
|
6
|
+
|
7
|
+
|
8
|
+
Scenario: Defining a macro to be used with multiple arguments in a table
|
9
|
+
# The next step creates a macro(-step)
|
10
|
+
# The syntax of the new macro-step is specified between double quotes.
|
11
|
+
# The steps to execute when the macro is used/invoked are listed in the multiline triple quotes arguments.
|
12
|
+
# The macro arguments are put between chevrons <...>.
|
13
|
+
Given I define the step "When I [enter my profile as]:" to mean:
|
14
|
+
"""
|
15
|
+
And I fill in "location" with "<location>"
|
16
|
+
And I fill in "email" with "<email>"
|
17
|
+
And I fill in "comment" with "<comment>"
|
18
|
+
And I click "Save"
|
19
|
+
"""
|
20
|
+
|
21
|
+
Scenario: # Let's use the macro we created above
|
22
|
+
# Here the macro is invoked. Actual value for the argument are passed in a table argument.
|
23
|
+
When I [enter my profile as]:
|
24
|
+
|location|Nowhere-City|
|
25
|
+
|email|nobody@example.com|
|
26
|
+
|comment|First comment line|
|
27
|
+
|comment|Second comment line|
|
28
|
+
|comment|Third comment line|
|
29
|
+
|
30
|
+
# The next step verifies that the steps from the macro were effectively executed.
|
31
|
+
Then I expect the following step trace:
|
32
|
+
"""
|
33
|
+
Invoked step: ... I fill in "location" with "Nowhere-City"
|
34
|
+
Invoked step: ... I fill in "email" with "nobody@example.com"
|
35
|
+
Invoked step: ... I fill in "comment" with "First comment line<br/>Second comment line<br/>Third comment line"
|
36
|
+
Invoked step: ... I click "Save"
|
37
|
+
"""
|
data/lib/macro_steps.rb
CHANGED
@@ -38,10 +38,10 @@ When(/^I \[([^\]]+)\]:$/) do |macro_phrase, table_argument|
|
|
38
38
|
unless table_argument.kind_of?(Cucumber::Ast::Table)
|
39
39
|
raise Macros4Cuke::DataTableNotFound, "This step must have a data table as an argument."
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
# This will call the macro with the given phrase.
|
43
|
-
# The second argument consists of
|
44
|
-
invoke_macro(macro_phrase, table_argument.
|
43
|
+
# The second argument consists of an array with couples of the kind: [argument name, actual value]
|
44
|
+
invoke_macro(macro_phrase, table_argument.raw)
|
45
45
|
end
|
46
46
|
|
47
47
|
|
@@ -38,7 +38,7 @@ public
|
|
38
38
|
# and (optionally) given a table of values.
|
39
39
|
# Return the rendered steps as a text.
|
40
40
|
# @param aPhrase [String] an instance of the macro phrase.
|
41
|
-
# @param rawData [Array] An
|
41
|
+
# @param rawData [Array or nil] An Array with coupples of the form: [macro argument name, a value].
|
42
42
|
# Multiple rows with same argument name are acceptable.
|
43
43
|
# @return [String]
|
44
44
|
def render_steps(aPhrase, rawData = nil)
|
@@ -27,7 +27,7 @@ public
|
|
27
27
|
|
28
28
|
# Invoke a macro with given phrase and (optionally) a table of values
|
29
29
|
# @param aPhraseInstance [String] an instance of the macro phrase. That is, the text between [...] and with zero or more actual values.
|
30
|
-
# @param rawData [Array or nil] An
|
30
|
+
# @param rawData [Array or nil] An Array with coupples of the form: [macro argument name, a value].
|
31
31
|
# Multiple rows with same argument name are acceptable.
|
32
32
|
def invoke_macro(aPhraseInstance, rawData = nil)
|
33
33
|
# Generate a text rendition of the step to be executed.
|
@@ -99,7 +99,7 @@ class MacroStep
|
|
99
99
|
# Render the steps from the template, given the values
|
100
100
|
# taken by the parameters
|
101
101
|
# @param aPhrase [String] an instance of the macro phrase.
|
102
|
-
# @param rawData [Array] An
|
102
|
+
# @param rawData [Array or nil] An Array with coupples of the form: [macro argument name, a value].
|
103
103
|
# Multiple rows with same argument name are acceptable.
|
104
104
|
def expand(aPhrase, rawData)
|
105
105
|
params = validate_params(aPhrase, rawData)
|
@@ -108,9 +108,8 @@ class MacroStep
|
|
108
108
|
|
109
109
|
private
|
110
110
|
# Build a Hash from the given raw data.
|
111
|
-
# [
|
112
|
-
# [
|
113
|
-
# Each couple is of the form: argument name, a value.
|
111
|
+
# @param aPhrase [String] an instance of the macro phrase.
|
112
|
+
# @param rawData [Array or nil] An Array with coupples of the form: [macro argument name, a value].
|
114
113
|
# Multiple rows with same argument name are acceptable.
|
115
114
|
def validate_params(aPhrase, rawData)
|
116
115
|
macro_parameters = {}
|
@@ -56,12 +56,25 @@ public
|
|
56
56
|
# Returns an empty string when no value is assigned to the placeholder.
|
57
57
|
def render(aContextObject, theLocals)
|
58
58
|
actual_value = theLocals[name]
|
59
|
-
if actual_value.nil?
|
60
|
-
actual_value = aContextObject.send(name.to_sym)
|
61
|
-
actual_value = '' if actual_value.nil?
|
59
|
+
if actual_value.nil? && aContextObject.respond_to?(name.to_sym)
|
60
|
+
actual_value = aContextObject.send(name.to_sym)
|
62
61
|
end
|
63
62
|
|
64
|
-
|
63
|
+
result = case actual_value
|
64
|
+
when NilClass
|
65
|
+
''
|
66
|
+
|
67
|
+
when Array
|
68
|
+
# TODO: Move away from hard-coded separator.
|
69
|
+
actual_value.join("<br/>")
|
70
|
+
|
71
|
+
when String
|
72
|
+
actual_value
|
73
|
+
else
|
74
|
+
actual_value.to_s()
|
75
|
+
end
|
76
|
+
|
77
|
+
return result
|
65
78
|
end
|
66
79
|
|
67
80
|
end # class
|
@@ -57,7 +57,7 @@ SNIPPET
|
|
57
57
|
end
|
58
58
|
end # context
|
59
59
|
|
60
|
-
context "Invoking macro(s)" do
|
60
|
+
context "Invoking macro(s):" do
|
61
61
|
|
62
62
|
it "should complain when invoking an unknown macro-step" do
|
63
63
|
phrase_unknown = "dream of a perfect world"
|
@@ -68,7 +68,7 @@ SNIPPET
|
|
68
68
|
|
69
69
|
end # context
|
70
70
|
|
71
|
-
context "Clearing macro(s)" do
|
71
|
+
context "Clearing macro(s):" do
|
72
72
|
|
73
73
|
it "should clear all macros" do
|
74
74
|
lambda { world.clear_macros() }.should_not raise_error
|
@@ -134,18 +134,18 @@ SNIPPET
|
|
134
134
|
error_message = "Missing closing chevron '>'."
|
135
135
|
lambda { Engine::parse(sample_text) }.should raise_error(StandardError, error_message)
|
136
136
|
end
|
137
|
-
|
137
|
+
|
138
138
|
it "should complain if a text misses an opening chevron" do
|
139
139
|
sample_text = 'begin <some_tag> > end'
|
140
140
|
error_message = "Missing opening chevron '<'."
|
141
141
|
lambda { Engine::parse(sample_text) }.should raise_error(StandardError, error_message)
|
142
142
|
end
|
143
|
-
|
144
|
-
it "should complain if a text
|
143
|
+
|
144
|
+
it "should complain if a text has nested opening chevrons" do
|
145
145
|
sample_text = 'begin <<some_tag> > end'
|
146
146
|
error_message = "Nested opening chevron '<'."
|
147
147
|
lambda { Engine::parse(sample_text) }.should raise_error(StandardError, error_message)
|
148
|
-
end
|
148
|
+
end
|
149
149
|
|
150
150
|
end # context
|
151
151
|
|
@@ -185,8 +185,8 @@ SNIPPET
|
|
185
185
|
instance = Engine.new ''
|
186
186
|
instance.variables.should be_empty
|
187
187
|
end
|
188
|
-
|
189
|
-
|
188
|
+
|
189
|
+
|
190
190
|
it "should ignore variables/placeholders in comments" do
|
191
191
|
substeps = " # Comment 1 <miscellaneous>\n" + sample_template
|
192
192
|
substeps += " #\n Comment 2 <haphazard>"
|
@@ -207,6 +207,22 @@ SNIPPET
|
|
207
207
|
And I click "Sign in"
|
208
208
|
SNIPPET
|
209
209
|
|
210
|
+
rendered_text.should == expected
|
211
|
+
|
212
|
+
# Case of an actual that's not a String
|
213
|
+
locals = {'userid' => "johndoe", "password" => 12345678 }
|
214
|
+
rendered_text = subject.render(Object.new, locals)
|
215
|
+
expected = <<-SNIPPET
|
216
|
+
Given I landed in the homepage
|
217
|
+
# The credentials are entered here
|
218
|
+
And I fill in "Username" with "johndoe"
|
219
|
+
And I fill in "Password" with "12345678"
|
220
|
+
And I click "Sign in"
|
221
|
+
SNIPPET
|
222
|
+
|
223
|
+
rendered_text.should == expected
|
224
|
+
|
225
|
+
|
210
226
|
# Place actual value in context object
|
211
227
|
Context = Struct.new(:userid, :password)
|
212
228
|
context = Context.new("sherlock", "holmes")
|
@@ -219,12 +235,29 @@ SNIPPET
|
|
219
235
|
And I click "Sign in"
|
220
236
|
SNIPPET
|
221
237
|
|
238
|
+
rendered_text.should == expected
|
239
|
+
|
222
240
|
|
223
241
|
# Case of an empty source template text
|
224
242
|
instance = Engine.new ''
|
225
243
|
instance.render(nil, {}).should be_empty
|
226
244
|
end
|
227
|
-
|
245
|
+
|
246
|
+
it "should render multivalued actuals" do
|
247
|
+
locals = {'userid' => ["johndoe", "yeti"] } # Silly case
|
248
|
+
|
249
|
+
rendered_text = subject.render(Object.new, locals)
|
250
|
+
expected = <<-SNIPPET
|
251
|
+
Given I landed in the homepage
|
252
|
+
# The credentials are entered here
|
253
|
+
And I fill in "Username" with "johndoe<br/>yeti"
|
254
|
+
And I fill in "Password" with ""
|
255
|
+
And I click "Sign in"
|
256
|
+
SNIPPET
|
257
|
+
|
258
|
+
rendered_text.should == expected
|
259
|
+
end
|
260
|
+
end # context
|
228
261
|
|
229
262
|
end # describe
|
230
263
|
|
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.2.
|
4
|
+
version: 0.2.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-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: cucumber
|
@@ -83,6 +83,7 @@ files:
|
|
83
83
|
- features/demo02.feature
|
84
84
|
- features/demo03.feature
|
85
85
|
- features/demo04.feature
|
86
|
+
- features/demo05.feature
|
86
87
|
- features/travelling-demo.feature
|
87
88
|
- features/step_definitions/demo_steps.rb
|
88
89
|
- features/step_definitions/use_macro_steps.rb
|