macros4cuke 0.2.18 → 0.2.19
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 +6 -0
- data/README.md +8 -0
- data/lib/macros4cuke/constants.rb +1 -1
- data/lib/macros4cuke/exceptions.rb +12 -4
- data/lib/macros4cuke/templating/engine.rb +22 -4
- data/spec/macros4cuke/templating/engine_spec.rb +11 -5
- metadata +2 -2
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
## 0.2.19 / 2013-05-06
|
2
|
+
* [CHANGE] Added validation of macro argument names in new `Engine::parse_tag` method.
|
3
|
+
* [CHANGE] InvalidCharError exception added.
|
4
|
+
* [CHANGE] File `engine_spec.rb`: Added one RSpec example for an invalid argument name.
|
5
|
+
* [CHANGE] File `README.md`: added a new section on naming macro arguments.
|
6
|
+
|
1
7
|
## 0.2.18 / 2013-05-06
|
2
8
|
* [CHANGE] Amended spec files and added a new demo feature. SimpleCov code coverage raised to more than 97%.
|
3
9
|
* [CHANGE] Macro-step arguments can be multivalued (experimental)
|
data/README.md
CHANGED
@@ -245,6 +245,14 @@ Here are few observations worth noticing:
|
|
245
245
|
the value "Main Street, 22".
|
246
246
|
- Data rows don't have to follow strictly the order of the arguments in the sub-step sequence.
|
247
247
|
|
248
|
+
## Naming macro-step arguments ##
|
249
|
+
In line with most computer languages, Macros4Cuke accepts argument names containing alphanumeric characters and
|
250
|
+
underscores.
|
251
|
+
In fact, the only characters that are not allowed in argument names are the following punctuation or delimiting
|
252
|
+
signs:
|
253
|
+
__\!"'\#$%\&\*\+\-/,\.\:\;\=\?\(\)\<\>\[\]\{\}\\\^\`\|\~__
|
254
|
+
|
255
|
+
|
248
256
|
## With great power comes great responsibility. ##
|
249
257
|
_Stan Lee_
|
250
258
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# encoding: utf-8 -- You should see a paragraph character: §
|
1
|
+
# encoding: utf-8 -- You should see a paragraph character: §
|
2
2
|
# File: exceptions.rb
|
3
3
|
|
4
4
|
module Macros4Cuke # Module used as a namespace
|
@@ -8,7 +8,7 @@ module Macros4Cuke # Module used as a namespace
|
|
8
8
|
class Macros4CukeError < StandardError
|
9
9
|
end # class
|
10
10
|
|
11
|
-
# Raised when one attempts to define a new macro
|
11
|
+
# Raised when one attempts to define a new macro
|
12
12
|
# that has the same phrase as an existing macro.
|
13
13
|
class DuplicateMacroError < Macros4CukeError
|
14
14
|
def initialize(aPhrase)
|
@@ -44,7 +44,15 @@ class EmptyArgumentError < Macros4CukeError
|
|
44
44
|
end # class
|
45
45
|
|
46
46
|
|
47
|
-
# Raised when
|
47
|
+
# Raised when an argument name contains invalid characters.
|
48
|
+
class InvalidCharError < Macros4CukeError
|
49
|
+
def initialize(aText, aWrongChar)
|
50
|
+
super("The invalid sign '#{aWrongChar}' occurs in the argument/tag '#{aText}'.")
|
51
|
+
end
|
52
|
+
end # class
|
53
|
+
|
54
|
+
|
55
|
+
# Raised when one invokes a macro-step with an unknown phrase.
|
48
56
|
class UnknownMacroError < Macros4CukeError
|
49
57
|
def initialize(aPhrase)
|
50
58
|
super("Unknown macro-step with phrase: '#{aPhrase}'.")
|
@@ -54,7 +62,7 @@ end # class
|
|
54
62
|
|
55
63
|
|
56
64
|
# Raised when one invokes a macro-step with an argument
|
57
|
-
# that has an unknown name.
|
65
|
+
# that has an unknown name.
|
58
66
|
class UnknownArgumentError < Macros4CukeError
|
59
67
|
def initialize(argName)
|
60
68
|
super("Unknown macro-step argument '#{argName}'.")
|
@@ -101,6 +101,15 @@ end # class
|
|
101
101
|
# while Mustache use !{{...}} delimiters),
|
102
102
|
# - Feature files are meant to be simple, so should the template engine be.
|
103
103
|
class Engine
|
104
|
+
# The regular expression that matches any punctuation sign or delimiter that is forbidden between chevrons <...> template tags.
|
105
|
+
DisallowedSigns = begin
|
106
|
+
forbidden = '!"#' + "$%&'()*+,-./:;<=>?[\\]^`{|}~" # Used concatenation (+) to work around Ruby bug!
|
107
|
+
all_escaped = []
|
108
|
+
forbidden.each_char() { |ch| all_escaped << Regexp.escape(ch) }
|
109
|
+
pattern = all_escaped.join("|")
|
110
|
+
Regexp.new(pattern)
|
111
|
+
end
|
112
|
+
|
104
113
|
# The original text of the template is kept here.
|
105
114
|
attr_reader(:source)
|
106
115
|
|
@@ -140,7 +149,6 @@ public
|
|
140
149
|
return @variables
|
141
150
|
end
|
142
151
|
|
143
|
-
|
144
152
|
# Class method. Parse the given line text into a raw representation.
|
145
153
|
# @return [Array] Couples of the form:
|
146
154
|
# [:static, text] or [:dynamic, tag text]
|
@@ -211,7 +219,7 @@ private
|
|
211
219
|
end
|
212
220
|
|
213
221
|
|
214
|
-
# [
|
222
|
+
# @param aCouple [Array] a two-element array of the form: [kind, text]
|
215
223
|
# Where kind must be one of :static, :dynamic
|
216
224
|
def compile_couple(aCouple)
|
217
225
|
(kind, text) = aCouple
|
@@ -221,14 +229,24 @@ private
|
|
221
229
|
StaticText.new(text)
|
222
230
|
|
223
231
|
when :dynamic
|
224
|
-
|
232
|
+
parse_tag(text)
|
225
233
|
else
|
226
234
|
raise StandardError, "Internal error: Don't know template element of kind #{kind}"
|
227
235
|
end
|
228
|
-
|
236
|
+
|
229
237
|
return result
|
230
238
|
end
|
231
239
|
|
240
|
+
# Parse the contents of a tag entry.
|
241
|
+
# @param aText [String] The text that is enclosed between chevrons.
|
242
|
+
def parse_tag(aText)
|
243
|
+
# Disallow punctuation and delimiter signs in tags.
|
244
|
+
matching = DisallowedSigns.match(aText)
|
245
|
+
raise InvalidCharError.new(aText, matching[0]) if matching
|
246
|
+
|
247
|
+
return Placeholder.new(aText)
|
248
|
+
end
|
249
|
+
|
232
250
|
end # class
|
233
251
|
|
234
252
|
end # module
|
@@ -4,6 +4,7 @@
|
|
4
4
|
require_relative '../../spec_helper'
|
5
5
|
require_relative '../../../lib/macros4cuke/templating/engine' # Load the class under test
|
6
6
|
|
7
|
+
|
7
8
|
module Macros4Cuke
|
8
9
|
|
9
10
|
module Templating # Open this namespace to get rid of module qualifier prefixes
|
@@ -171,9 +172,14 @@ SNIPPET
|
|
171
172
|
text_w_empty_arg = sample_template.sub(/userid/, '')
|
172
173
|
error_message = %Q|An empty or blank argument occurred in 'And I fill in "Username" with "<>"'.|
|
173
174
|
lambda { Engine.new text_w_empty_arg }.should raise_error(Macros4Cuke::EmptyArgumentError, error_message)
|
175
|
+
end
|
174
176
|
|
177
|
+
it "should complain when a placeholder contains an invalid character" do
|
178
|
+
text_w_empty_arg = sample_template.sub(/userid/, 'user%id')
|
179
|
+
error_message = "The invalid sign '%' occurs in the argument/tag 'user%id'."
|
180
|
+
lambda { Engine.new text_w_empty_arg }.should raise_error(Macros4Cuke::InvalidCharError, error_message)
|
175
181
|
end
|
176
|
-
end
|
182
|
+
end # context
|
177
183
|
|
178
184
|
context "Provided services" do
|
179
185
|
|
@@ -208,7 +214,7 @@ SNIPPET
|
|
208
214
|
SNIPPET
|
209
215
|
|
210
216
|
rendered_text.should == expected
|
211
|
-
|
217
|
+
|
212
218
|
# Case of an actual that's not a String
|
213
219
|
locals = {'userid' => "johndoe", "password" => 12345678 }
|
214
220
|
rendered_text = subject.render(Object.new, locals)
|
@@ -220,8 +226,8 @@ SNIPPET
|
|
220
226
|
And I click "Sign in"
|
221
227
|
SNIPPET
|
222
228
|
|
223
|
-
rendered_text.should == expected
|
224
|
-
|
229
|
+
rendered_text.should == expected
|
230
|
+
|
225
231
|
|
226
232
|
# Place actual value in context object
|
227
233
|
Context = Struct.new(:userid, :password)
|
@@ -236,7 +242,7 @@ SNIPPET
|
|
236
242
|
SNIPPET
|
237
243
|
|
238
244
|
rendered_text.should == expected
|
239
|
-
|
245
|
+
|
240
246
|
|
241
247
|
# Case of an empty source template text
|
242
248
|
instance = Engine.new ''
|
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.19
|
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-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: cucumber
|