macros4cuke 0.3.42 → 0.4.00
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/.rubocop.yml +20 -3
- data/CHANGELOG.md +15 -1
- data/examples/i18n/fr/features/step_definitions/use_macro_steps.rb +1 -1
- data/features/demo06.feature +75 -75
- data/features/demo07.feature +15 -0
- data/features/support/env.rb +6 -0
- data/features/support/macro_support.rb +2 -2
- data/lib/macro_steps.rb +19 -2
- data/lib/macros4cuke/coll-walker-factory.rb +119 -0
- data/lib/macros4cuke/constants.rb +1 -1
- data/lib/macros4cuke/exceptions.rb +23 -1
- data/lib/macros4cuke/formatter/all-notifications.rb +30 -0
- data/lib/macros4cuke/formatter/to-gherkin.rb +80 -0
- data/lib/macros4cuke/formatter/to-null.rb +86 -0
- data/lib/macros4cuke/formatter/to-trace.rb +100 -0
- data/lib/macros4cuke/formatting-service.rb +74 -0
- data/lib/macros4cuke/macro-collection.rb +3 -3
- data/lib/macros4cuke/macro-step-support.rb +1 -1
- data/lib/macros4cuke/macro-step.rb +10 -26
- data/lib/macros4cuke/templating/engine.rb +74 -29
- data/spec/macros4cuke/coll-walker-factory_spec.rb +269 -0
- data/spec/macros4cuke/formatter/to-gherkin_spec.rb +129 -0
- data/spec/macros4cuke/formatter/to-null_spec.rb +62 -0
- data/spec/macros4cuke/formatter/to-trace_spec.rb +155 -0
- data/spec/macros4cuke/formatting-service_spec.rb +138 -0
- data/spec/macros4cuke/macro-collection_spec.rb +7 -4
- data/spec/macros4cuke/macro-step-support_spec.rb +41 -24
- data/spec/macros4cuke/macro-step_spec.rb +13 -6
- data/spec/macros4cuke/templating/engine_spec.rb +11 -7
- data/spec/macros4cuke/templating/placeholder_spec.rb +1 -1
- data/spec/macros4cuke/templating/section_spec.rb +3 -1
- data/spec/macros4cuke/use-sample-collection.rb +79 -0
- data/spec/spec_helper.rb +3 -0
- metadata +15 -2
@@ -23,6 +23,9 @@ class MacroStep
|
|
23
23
|
# A template engine that expands the sub-steps upon request.
|
24
24
|
attr_reader(:renderer)
|
25
25
|
|
26
|
+
# The sentence fragment that defines the syntax of the macro-step
|
27
|
+
attr_reader(:phrase)
|
28
|
+
|
26
29
|
# Unique key of the macro as derived from the macro phrase.
|
27
30
|
attr_reader(:key)
|
28
31
|
|
@@ -30,7 +33,7 @@ class MacroStep
|
|
30
33
|
attr_reader(:phrase_args)
|
31
34
|
|
32
35
|
# The list of macro argument names (as appearing in the substeps
|
33
|
-
#
|
36
|
+
# AND in the macro phrase).
|
34
37
|
attr_reader(:args)
|
35
38
|
|
36
39
|
# Constructor.
|
@@ -41,15 +44,12 @@ class MacroStep
|
|
41
44
|
# @param useTable [boolean] A flag indicating whether a data table
|
42
45
|
# must be used to pass actual values.
|
43
46
|
def initialize(aMacroPhrase, theSubsteps, useTable)
|
47
|
+
@phrase = aMacroPhrase
|
44
48
|
@key = self.class.macro_key(aMacroPhrase, useTable, :definition)
|
45
49
|
|
46
50
|
# Retrieve the macro arguments embedded in the phrase.
|
47
51
|
@phrase_args = scan_arguments(aMacroPhrase, :definition)
|
48
|
-
|
49
|
-
# Manipulate the substeps source text
|
50
|
-
substeps_processed = preprocess(theSubsteps)
|
51
|
-
|
52
|
-
@renderer = Templating::Engine.new(substeps_processed)
|
52
|
+
@renderer = Templating::Engine.new(theSubsteps)
|
53
53
|
substeps_vars = renderer.variables
|
54
54
|
|
55
55
|
|
@@ -165,17 +165,15 @@ private
|
|
165
165
|
# @param params [Hash] The pairs phrase argument name => value
|
166
166
|
def validate_row(a_row, params)
|
167
167
|
(a_key, value) = a_row
|
168
|
-
|
168
|
+
fail(UnknownArgumentError.new(a_key)) unless args.include? a_key
|
169
169
|
if (phrase_args.include? a_key) && (params[a_key] != value)
|
170
|
-
|
170
|
+
fail(AmbiguousArgumentValue.new(a_key, params[a_key], value))
|
171
171
|
end
|
172
172
|
|
173
173
|
return a_row
|
174
174
|
end
|
175
175
|
|
176
176
|
|
177
|
-
|
178
|
-
|
179
177
|
# Retrieve from the macro phrase, all the text between <..> or double quotes.
|
180
178
|
# Returns an array. Each of its elements corresponds to quoted text.
|
181
179
|
# Example:
|
@@ -201,20 +199,6 @@ private
|
|
201
199
|
|
202
200
|
return args
|
203
201
|
end
|
204
|
-
|
205
|
-
# Return the substeps text after some transformation
|
206
|
-
# [theSubstepsSource] The source text of the steps
|
207
|
-
# to be expanded upon macro invokation.
|
208
|
-
def preprocess(theSubstepsSource)
|
209
|
-
# Split text into lines
|
210
|
-
lines = theSubstepsSource.split(/\r\n?|\n/)
|
211
|
-
|
212
|
-
# Reject comment lines. This is necessary because
|
213
|
-
# Cucumber::RbSupport::RbWorld#steps complains when it sees a comment.
|
214
|
-
processed = lines.reject { |a_line| a_line =~ /\s*#/ }
|
215
|
-
|
216
|
-
return processed.join("\n")
|
217
|
-
end
|
218
202
|
|
219
203
|
# Check for inconsistencies between the argument names
|
220
204
|
# in the phrase and the substeps part.
|
@@ -222,7 +206,7 @@ private
|
|
222
206
|
# Error when the phrase names an argument that never occurs in the substeps
|
223
207
|
thePhraseArgs.each do |phrase_arg|
|
224
208
|
unless substepsVars.include? phrase_arg
|
225
|
-
|
209
|
+
fail(UselessPhraseArgument.new(phrase_arg))
|
226
210
|
end
|
227
211
|
end
|
228
212
|
# Error when a substep has an argument that never appears in the phrase
|
@@ -231,7 +215,7 @@ private
|
|
231
215
|
substepsVars.each do |substep_arg|
|
232
216
|
unless thePhraseArgs.include?(substep_arg) ||
|
233
217
|
BuiltinParameters.include?(substep_arg)
|
234
|
-
|
218
|
+
fail(UnreachableSubstepArgument.new(substep_arg))
|
235
219
|
end
|
236
220
|
end
|
237
221
|
end
|
@@ -38,6 +38,34 @@ class StaticText
|
|
38
38
|
end # class
|
39
39
|
|
40
40
|
|
41
|
+
# Class used internally by the template engine.
|
42
|
+
# Represents a comment from a template.
|
43
|
+
# A static text is a text that is reproduced verbatim
|
44
|
+
# when rendering a template.
|
45
|
+
class Comment
|
46
|
+
# The comment as extracted from the original template.
|
47
|
+
attr_reader(:source)
|
48
|
+
|
49
|
+
|
50
|
+
# @param aSourceText [String] A piece of text extracted
|
51
|
+
# from the template that must be rendered verbatim.
|
52
|
+
def initialize(aSourceText)
|
53
|
+
@source = aSourceText
|
54
|
+
end
|
55
|
+
|
56
|
+
public
|
57
|
+
|
58
|
+
# Render the comment.
|
59
|
+
# Comments are rendered as empty text. This is necessary because
|
60
|
+
# Cucumber::RbSupport::RbWorld#steps complains when it sees a comment.
|
61
|
+
# This method has the same signature as the {Engine#render} method.
|
62
|
+
# @return [String] Empty string ("as is")
|
63
|
+
def render(aContextObject, theLocals)
|
64
|
+
return ''
|
65
|
+
end
|
66
|
+
end # class
|
67
|
+
|
68
|
+
|
41
69
|
# Class used internally by the template engine.
|
42
70
|
# Represents an end of line that must be rendered as such.
|
43
71
|
class EOLine
|
@@ -160,7 +188,7 @@ class Section < UnaryElement
|
|
160
188
|
# Returns an empty string when no value is assigned to the placeholder.
|
161
189
|
def render(aContextObject, theLocals)
|
162
190
|
msg = "Method Section.#{__method__} must be implemented in subclass."
|
163
|
-
|
191
|
+
fail(NotImplementedError, msg)
|
164
192
|
end
|
165
193
|
|
166
194
|
end # class
|
@@ -239,6 +267,9 @@ class Engine
|
|
239
267
|
# The original text of the template is kept here.
|
240
268
|
attr_reader(:source)
|
241
269
|
|
270
|
+
# The internal representation of the template text
|
271
|
+
attr_reader(:representation)
|
272
|
+
|
242
273
|
# Builds an Engine and compiles the given template text into
|
243
274
|
# an internal representation.
|
244
275
|
# @param aSourceTemplate [String] The template source text.
|
@@ -260,11 +291,19 @@ public
|
|
260
291
|
# the passed argument values.
|
261
292
|
def render(aContextObject = Object.new, theLocals)
|
262
293
|
return '' if @representation.empty?
|
263
|
-
|
294
|
+
|
295
|
+
prev = nil
|
264
296
|
result = @representation.each_with_object('') do |element, subResult|
|
265
|
-
|
297
|
+
# Output compaction rules:
|
298
|
+
# -In case of consecutive eol's only one is rendered.
|
299
|
+
# -In case of comment followed by one eol, both aren't rendered
|
300
|
+
unless element.is_a?(EOLine) &&
|
301
|
+
(prev.is_a?(EOLine) || prev.is_a?(Comment))
|
302
|
+
subResult << element.render(aContextObject, theLocals)
|
303
|
+
end
|
304
|
+
prev = element
|
266
305
|
end
|
267
|
-
|
306
|
+
|
268
307
|
return result
|
269
308
|
end
|
270
309
|
|
@@ -295,24 +334,28 @@ public
|
|
295
334
|
|
296
335
|
# Class method. Parse the given line text into a raw representation.
|
297
336
|
# @return [Array] Couples of the form:
|
298
|
-
# [:static, text] or [:dynamic, tag text]
|
337
|
+
# [:static, text], [:comment, text] or [:dynamic, tag text]
|
299
338
|
def self.parse(aTextLine)
|
300
339
|
scanner = StringScanner.new(aTextLine)
|
301
340
|
result = []
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
341
|
+
|
342
|
+
if scanner.check(/\s*#/) # Detect comment line
|
343
|
+
result << [:comment, aTextLine]
|
344
|
+
else
|
345
|
+
until scanner.eos?
|
346
|
+
# Scan tag at current position...
|
347
|
+
tag_literal = scanner.scan(/<(?:[^\\<>]|\\.)*>/)
|
348
|
+
unless tag_literal.nil?
|
349
|
+
result << [:dynamic, tag_literal.gsub(/^<|>$/, '')]
|
350
|
+
end
|
351
|
+
|
352
|
+
# ... or scan plain text at current position
|
353
|
+
literal = scanner.scan(/(?:[^\\<>]|\\.)+/)
|
354
|
+
result << [:static, literal] unless literal.nil?
|
355
|
+
identify_parse_error(aTextLine) if tag_literal.nil? && literal.nil?
|
308
356
|
end
|
309
|
-
|
310
|
-
# ... or scan plain text at current position
|
311
|
-
text_literal = scanner.scan(/(?:[^\\<>]|\\.)+/)
|
312
|
-
result << [:static, text_literal] unless text_literal.nil?
|
313
|
-
identify_parse_error(aTextLine) if tag_literal.nil? && text_literal.nil?
|
314
357
|
end
|
315
|
-
|
358
|
+
|
316
359
|
return result
|
317
360
|
end
|
318
361
|
|
@@ -336,11 +379,11 @@ private
|
|
336
379
|
when '>' then unbalance -= 1
|
337
380
|
end
|
338
381
|
|
339
|
-
|
340
|
-
|
382
|
+
fail(StandardError, "Nested opening chevron '<'.") if unbalance > 1
|
383
|
+
fail(StandardError, "Missing opening chevron '<'.") if unbalance < 0
|
341
384
|
end
|
342
385
|
|
343
|
-
|
386
|
+
fail(StandardError, "Missing closing chevron '>'.") if unbalance == 1
|
344
387
|
end
|
345
388
|
|
346
389
|
|
@@ -355,7 +398,7 @@ private
|
|
355
398
|
line_items.each do |(kind, text)|
|
356
399
|
# A tag text cannot be empty nor blank
|
357
400
|
if (kind == :dynamic) && text.strip.empty?
|
358
|
-
|
401
|
+
fail(EmptyArgumentError.new(line.strip))
|
359
402
|
end
|
360
403
|
end
|
361
404
|
|
@@ -390,7 +433,7 @@ private
|
|
390
433
|
false
|
391
434
|
end
|
392
435
|
end
|
393
|
-
if line_to_squeeze && !
|
436
|
+
if line_to_squeeze && !section_item.nil?
|
394
437
|
line_rep = [section_item]
|
395
438
|
else
|
396
439
|
line_rep_ending(line_rep)
|
@@ -398,7 +441,7 @@ private
|
|
398
441
|
|
399
442
|
return line_rep
|
400
443
|
end
|
401
|
-
|
444
|
+
|
402
445
|
|
403
446
|
# Apply rule: if last item in line is an end of section marker,
|
404
447
|
# then place eoline before that item.
|
@@ -418,15 +461,17 @@ private
|
|
418
461
|
# Where kind must be one of :static, :dynamic
|
419
462
|
def compile_couple(aCouple)
|
420
463
|
(kind, text) = aCouple
|
421
|
-
|
464
|
+
|
422
465
|
result = case kind
|
423
466
|
when :static then StaticText.new(text)
|
467
|
+
when :comment then Comment.new(text)
|
424
468
|
when :dynamic then parse_tag(text)
|
425
469
|
end
|
426
470
|
|
427
471
|
return result
|
428
472
|
end
|
429
|
-
|
473
|
+
|
474
|
+
|
430
475
|
# Parse the contents of a tag entry.
|
431
476
|
# @param aText [String] The text that is enclosed between chevrons.
|
432
477
|
def parse_tag(aText)
|
@@ -437,7 +482,7 @@ private
|
|
437
482
|
# Disallow punctuation and delimiter signs in tags.
|
438
483
|
matching = DisallowedSigns.match(aText)
|
439
484
|
end
|
440
|
-
|
485
|
+
fail(InvalidCharError.new(aText, matching[0])) if matching
|
441
486
|
|
442
487
|
result = case aText[0, 1]
|
443
488
|
when '?'
|
@@ -477,7 +522,7 @@ private
|
|
477
522
|
|
478
523
|
unless open_sections.empty?
|
479
524
|
error_message = "Unterminated section #{open_sections.last}."
|
480
|
-
|
525
|
+
fail(StandardError, error_message)
|
481
526
|
end
|
482
527
|
|
483
528
|
return compiled
|
@@ -490,11 +535,11 @@ private
|
|
490
535
|
|
491
536
|
if sections.empty?
|
492
537
|
msg = 'found while no corresponding section is open.'
|
493
|
-
|
538
|
+
fail(StandardError, msg_prefix + msg)
|
494
539
|
end
|
495
540
|
if marker.name != sections.last.name
|
496
541
|
msg = "doesn't match current section '#{sections.last.name}'."
|
497
|
-
|
542
|
+
fail(StandardError, msg_prefix + msg)
|
498
543
|
end
|
499
544
|
end
|
500
545
|
|
@@ -0,0 +1,269 @@
|
|
1
|
+
# File: collection-walker_spec.rb
|
2
|
+
|
3
|
+
require_relative '../spec_helper'
|
4
|
+
|
5
|
+
# Load mix-in module for creating a sample collection of macro-steps
|
6
|
+
require_relative 'use-sample-collection'
|
7
|
+
|
8
|
+
# Load the class under test
|
9
|
+
require_relative '../../lib/macros4cuke/coll-walker-factory'
|
10
|
+
|
11
|
+
module Macros4Cuke # Open this namespace to avoid module qualifier prefixes
|
12
|
+
|
13
|
+
describe CollWalkerFactory do
|
14
|
+
include UseSampleCollection # Add convenience methods for sample collection
|
15
|
+
|
16
|
+
|
17
|
+
before(:all) do
|
18
|
+
# Fill the collection of macro-steps with sample steps
|
19
|
+
fill_collection
|
20
|
+
end
|
21
|
+
|
22
|
+
after(:all) do
|
23
|
+
# Clear the collection to prevent interference between spec files
|
24
|
+
macro_coll.clear
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'Initialization:' do
|
28
|
+
it 'should be created without parameter' do
|
29
|
+
expect { CollWalkerFactory.new }.not_to raise_error
|
30
|
+
end
|
31
|
+
|
32
|
+
end # context
|
33
|
+
|
34
|
+
context 'Provided factory services:' do
|
35
|
+
# Default factory instantiation
|
36
|
+
subject { CollWalkerFactory.new }
|
37
|
+
|
38
|
+
it 'should build a walker for the given macro collection' do
|
39
|
+
walker = subject.build_walker(macro_coll)
|
40
|
+
expect(walker).to be_kind_of(Enumerator)
|
41
|
+
end
|
42
|
+
end # context
|
43
|
+
|
44
|
+
context 'Provided walker services:' do
|
45
|
+
# Default walker instantiation
|
46
|
+
subject do
|
47
|
+
factory = CollWalkerFactory.new
|
48
|
+
factory.build_walker(macro_coll)
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
it 'should notify the start of the visit of the collection' do
|
53
|
+
initial_event = subject.next
|
54
|
+
expect(initial_event).to eq([:on_collection, 0, macro_coll])
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'should notify the visit of a first macro step' do
|
58
|
+
1.times { subject.next }
|
59
|
+
first_step = subject.next
|
60
|
+
step1 = macro_coll.macro_steps.values[0]
|
61
|
+
expect(first_step).to eq([:on_step, 1, step1])
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'should notify the visit of the phrase of the first macro step' do
|
65
|
+
2.times { subject.next }
|
66
|
+
first_phrase = subject.next
|
67
|
+
sample_phrase1 = UseSampleCollection::SamplePhrase1
|
68
|
+
expect(first_phrase).to eq([:on_phrase, 2, sample_phrase1, true])
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'should notify the visit of the substeps renderer of the first step' do
|
72
|
+
3.times { subject.next }
|
73
|
+
first_step = macro_coll.macro_steps.values[0]
|
74
|
+
first_renderer = subject.next
|
75
|
+
expectation = [:on_renderer, 2, first_step.renderer]
|
76
|
+
expect(first_renderer).to eq(expectation)
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'should notify the visit of the internal representation of substeps' do
|
80
|
+
first_step = macro_coll.macro_steps.values[0]
|
81
|
+
substep_chunks = first_step.renderer.representation
|
82
|
+
4.times { subject.next }
|
83
|
+
text_representation = subject.next
|
84
|
+
expectation = [:on_source, 3, first_step.renderer.source]
|
85
|
+
expect(text_representation).to eq(expectation)
|
86
|
+
|
87
|
+
first_substep_piece = subject.next
|
88
|
+
expectation = [:on_static_text, 3, substep_chunks[0].source]
|
89
|
+
expect(first_substep_piece).to eq(expectation)
|
90
|
+
|
91
|
+
second_substep_piece = subject.next
|
92
|
+
expect(second_substep_piece).to eq([:on_eol, 3, nil])
|
93
|
+
|
94
|
+
third_substep_piece = subject.next
|
95
|
+
expectation = [:on_static_text, 3, substep_chunks[2].source]
|
96
|
+
expect(third_substep_piece).to eq(expectation)
|
97
|
+
|
98
|
+
fourth_substep_piece = subject.next
|
99
|
+
expect(fourth_substep_piece).to eq([:on_eol, 3, nil])
|
100
|
+
|
101
|
+
fifth_substep_piece = subject.next
|
102
|
+
expectation = [:on_static_text, 3, substep_chunks[4].source]
|
103
|
+
expect(fifth_substep_piece).to eq(expectation)
|
104
|
+
|
105
|
+
sixth_substep_piece = subject.next
|
106
|
+
expectation = [:on_placeholder, 3, substep_chunks[5].name]
|
107
|
+
expect(sixth_substep_piece).to eq(expectation)
|
108
|
+
|
109
|
+
seventh_substep_piece = subject.next
|
110
|
+
expectation = [:on_static_text, 3, substep_chunks[6].source]
|
111
|
+
expect(seventh_substep_piece).to eq(expectation)
|
112
|
+
|
113
|
+
eighth_substep_piece = subject.next
|
114
|
+
expect(eighth_substep_piece).to eq([:on_eol, 3, nil])
|
115
|
+
|
116
|
+
ninth_substep_piece = subject.next
|
117
|
+
expectation = [:on_static_text, 3, substep_chunks[8].source]
|
118
|
+
expect(ninth_substep_piece).to eq(expectation)
|
119
|
+
|
120
|
+
tenth_substep_piece = subject.next
|
121
|
+
expectation = [:on_placeholder, 3, substep_chunks[9].name]
|
122
|
+
expect(tenth_substep_piece).to eq(expectation)
|
123
|
+
|
124
|
+
eleventh_substep_piece = subject.next
|
125
|
+
expectation = [:on_static_text, 3, substep_chunks[10].source]
|
126
|
+
expect(eleventh_substep_piece).to eq(expectation)
|
127
|
+
|
128
|
+
twelfth_substep_piece = subject.next
|
129
|
+
expect(twelfth_substep_piece).to eq([:on_eol, 3, nil])
|
130
|
+
|
131
|
+
thirtieth_substep_piece = subject.next
|
132
|
+
expectation = [:on_static_text, 3, substep_chunks[12].source]
|
133
|
+
expect(thirtieth_substep_piece).to eq(expectation)
|
134
|
+
|
135
|
+
fourteenth_substep_piece = subject.next
|
136
|
+
expect(fourteenth_substep_piece).to eq([:on_eol, 3, nil])
|
137
|
+
|
138
|
+
fifteenth_substep_piece = subject.next
|
139
|
+
expect(fifteenth_substep_piece).to eq([:on_renderer_end, 2, nil])
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'should notify the visit of a following macro step' do
|
143
|
+
(4 + 15 + 1).times { subject.next }
|
144
|
+
end_step = subject.next
|
145
|
+
expect(end_step).to eq([:on_step_end, 1, nil])
|
146
|
+
a_step = subject.next
|
147
|
+
expect(a_step).to eq([:on_step, 1, macro_coll.macro_steps.values[1]])
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'should notify the visit of the phrase of a following macro step' do
|
151
|
+
(4 + 16 + 2).times { subject.next }
|
152
|
+
phrase = subject.next
|
153
|
+
sample_phrase = UseSampleCollection::SamplePhrase2
|
154
|
+
expect(phrase).to eq([:on_phrase, 2, sample_phrase, true])
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'should notify the visit of the substeps of a following step' do
|
158
|
+
(4 + 16 + 3).times { subject.next }
|
159
|
+
a_renderer = subject.next
|
160
|
+
second_step = macro_coll.macro_steps.values[1]
|
161
|
+
expect(a_renderer).to eq([:on_renderer, 2, second_step.renderer])
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'should notify the visit in substeps of following step' do
|
165
|
+
second_step = macro_coll.macro_steps.values[1]
|
166
|
+
substep_chunks = second_step.renderer.representation.dup
|
167
|
+
substep_chunks.map! do |ck|
|
168
|
+
if ck.kind_of?(Templating::Section)
|
169
|
+
[ck, ck.children, ck].flatten
|
170
|
+
else
|
171
|
+
ck
|
172
|
+
end
|
173
|
+
end
|
174
|
+
substep_chunks.flatten!
|
175
|
+
|
176
|
+
(4 + 16 + 4).times { subject.next }
|
177
|
+
substeps_text = subject.next
|
178
|
+
expectation = [:on_source, 3, second_step.renderer.source]
|
179
|
+
expect(substeps_text).to eq(expectation)
|
180
|
+
|
181
|
+
first_substep_piece = subject.next
|
182
|
+
expectation = [:on_static_text, 3, substep_chunks[0].source]
|
183
|
+
expect(first_substep_piece).to eq(expectation)
|
184
|
+
|
185
|
+
[
|
186
|
+
[:on_placeholder, 3, :name], # 0
|
187
|
+
[:on_static_text, 3, :source], # 1
|
188
|
+
[:on_eol, 3, nil], # 2
|
189
|
+
[:on_static_text, 3, :source], # 3
|
190
|
+
[:on_placeholder, 3, :name], # 4
|
191
|
+
[:on_static_text, 3, :source], # 5
|
192
|
+
[:on_eol, 3, nil], # 6
|
193
|
+
[:on_static_text, 3, :source], # 7
|
194
|
+
[:on_placeholder, 3, :name], # 8
|
195
|
+
[:on_static_text, 3, :source], # 9
|
196
|
+
[:on_eol, 3, nil], # 10
|
197
|
+
[:on_static_text, 3, :source], # 11
|
198
|
+
[:on_placeholder, 3, :name], # 12
|
199
|
+
[:on_static_text, 3, :source], # 13
|
200
|
+
[:on_eol, 3, nil], # 14
|
201
|
+
[:on_static_text, 3, :source], # 15
|
202
|
+
[:on_placeholder, 3, :name], # 16
|
203
|
+
[:on_static_text, 3, :source], # 17
|
204
|
+
[:on_eol, 3, nil], # 18
|
205
|
+
[:on_static_text, 3, :source], # 19
|
206
|
+
[:on_placeholder, 3, :name], # 20
|
207
|
+
[:on_static_text, 3, :source], # 21
|
208
|
+
[:on_eol, 3, nil], # 22
|
209
|
+
[:on_eol, 3, nil], # 23
|
210
|
+
[:on_comment, 3, :source], # 24
|
211
|
+
[:on_eol, 3, nil], # 25
|
212
|
+
[:on_comment, 3, :source], # 26
|
213
|
+
[:on_eol, 3, nil], # 27
|
214
|
+
[:on_comment, 3, :source], # 28
|
215
|
+
[:on_eol, 3, nil], # 29
|
216
|
+
[:on_section, 3, :name], # 30
|
217
|
+
[:on_static_text, 4, :source], # 31
|
218
|
+
[:on_placeholder, 4, :name], # 32
|
219
|
+
[:on_static_text, 4, :source], # 33
|
220
|
+
[:on_eol, 4, nil], # 34
|
221
|
+
[:on_section_end, 3, nil], # 35
|
222
|
+
[:on_eol, 3, nil], # 36
|
223
|
+
[:on_comment, 3, :source], # 37
|
224
|
+
[:on_eol, 3, nil], # 38
|
225
|
+
[:on_comment, 3, :source], # 39
|
226
|
+
[:on_eol, 3, nil], # 40
|
227
|
+
[:on_comment, 3, :source], # 41
|
228
|
+
[:on_eol, 3, nil], # 42
|
229
|
+
[:on_section, 3, :name], # 43
|
230
|
+
[:on_static_text, 4, :source], # 44
|
231
|
+
[:on_placeholder, 4, :name], # 45
|
232
|
+
[:on_static_text, 4, :source], # 46
|
233
|
+
[:on_eol, 4, nil], # 47
|
234
|
+
[:on_section_end, 3, nil], # 48
|
235
|
+
[:on_static_text, 3, :source], # 49
|
236
|
+
[:on_eol, 3, nil], # 50
|
237
|
+
[:on_renderer_end, 2, nil], # 51
|
238
|
+
[:on_step_end, 1, nil], # 52
|
239
|
+
[:on_collection_end, 0, nil] # 53
|
240
|
+
].each_with_index do |event, i|
|
241
|
+
actual = subject.next
|
242
|
+
expect(actual[0]).to eq(event[0])
|
243
|
+
expect(actual[1]).to eq(event[1])
|
244
|
+
unless event[2].nil?
|
245
|
+
expected_obj = substep_chunks[i + 1]
|
246
|
+
expect(actual[2]).to eq(expected_obj.send(event[2]))
|
247
|
+
end
|
248
|
+
end
|
249
|
+
expect { subject.next }.to raise_error(StopIteration)
|
250
|
+
|
251
|
+
end
|
252
|
+
|
253
|
+
# Must be last test script since it pollutes the macro-collection
|
254
|
+
it 'should complain when visiting an unsupported node' do
|
255
|
+
first_step = macro_coll.macro_steps.values[0]
|
256
|
+
first_step.renderer.representation.insert(2, :not_a_valid_element)
|
257
|
+
err_type = Macros4Cuke::InternalError
|
258
|
+
err_msg = "Don't know how to format a Symbol."
|
259
|
+
expect { subject.each { |x| } }.to raise_error(err_type, err_msg)
|
260
|
+
end
|
261
|
+
|
262
|
+
end # context
|
263
|
+
|
264
|
+
end # describe
|
265
|
+
|
266
|
+
end # module
|
267
|
+
|
268
|
+
|
269
|
+
# End of file
|