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 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 a hash with pairs of the kind: argument name => actual value
44
- invoke_macro(macro_phrase, table_argument.rows_hash())
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
 
@@ -3,7 +3,7 @@
3
3
 
4
4
  module Macros4Cuke # Module used as a namespace
5
5
  # The version number of the gem.
6
- Version = '0.2.17'
6
+ Version = '0.2.18'
7
7
 
8
8
  # Brief description of the gem.
9
9
  Description = "Macros for Cucumber"
@@ -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 array of couples of the form: [ argument name, a value].
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 array of couples. Each couple is of the form: [macro argument name, a value].
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 array of couples of the form: [argument name, a value].
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
- # [aPhrase] an instance of the macro phrase.
112
- # [rawData] An Array of couples.
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) if aContextObject.respond_to?(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
- return actual_value.is_a?(String) ? actual_value : actual_value.to_s
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 ha&s nested opening chevrons" do
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
- end
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.17
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-05 00:00:00.000000000 Z
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