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