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 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