macros4cuke 0.2.17 → 0.2.18
Sign up to get free protection for your applications and to get access to all the features.
- 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
|