macros4cuke 0.3.42 → 0.4.00
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.
- 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
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# File: to-gherkin_spec.rb
|
|
2
|
+
|
|
3
|
+
require 'stringio'
|
|
4
|
+
require_relative '../../spec_helper'
|
|
5
|
+
|
|
6
|
+
require_relative '../../../lib/macros4cuke/macro-step'
|
|
7
|
+
|
|
8
|
+
# Load mix-in module for creating a sample collection of macro-steps
|
|
9
|
+
require_relative '../use-sample-collection'
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
require_relative '../../../lib/macros4cuke/formatting-service'
|
|
13
|
+
# Load the class under test
|
|
14
|
+
require_relative '../../../lib/macros4cuke/formatter/to-gherkin'
|
|
15
|
+
|
|
16
|
+
module Macros4Cuke
|
|
17
|
+
|
|
18
|
+
module Formatter # Open this namespace to get rid of module qualifier prefixes
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
describe ToGherkin do
|
|
22
|
+
include UseSampleCollection # Add convenience methods for sample collection
|
|
23
|
+
|
|
24
|
+
let(:destination) { StringIO.new }
|
|
25
|
+
|
|
26
|
+
before(:all) do
|
|
27
|
+
# Fill the collection of macro-steps with sample steps
|
|
28
|
+
fill_collection
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
after(:all) do
|
|
32
|
+
# Clear the collection to prevent interference between spec files
|
|
33
|
+
macro_coll.clear
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
context 'Creation and initialization:' do
|
|
38
|
+
|
|
39
|
+
it 'should be created with an IO object' do
|
|
40
|
+
an_io = StringIO.new
|
|
41
|
+
expect { ToGherkin.new(an_io) }.not_to raise_error
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
end # context
|
|
45
|
+
|
|
46
|
+
context 'Provided services:' do
|
|
47
|
+
# Default instantiation rule
|
|
48
|
+
subject { ToGherkin.new(destination) }
|
|
49
|
+
|
|
50
|
+
# The expected feature file created from the sample collection
|
|
51
|
+
let(:expected_output) do
|
|
52
|
+
version = Macros4Cuke::Version
|
|
53
|
+
now = Time.now.asctime
|
|
54
|
+
trace_details = <<-SNIPPET
|
|
55
|
+
# Feature file generated by Macro4Cuke #{version} on #{now}
|
|
56
|
+
|
|
57
|
+
Feature: the set of macro-step definitions
|
|
58
|
+
As a feature file writer
|
|
59
|
+
So that I write higher-level steps
|
|
60
|
+
|
|
61
|
+
Scenario: Macro 1
|
|
62
|
+
Given I define the step "* I [enter my credentials as <userid>]:" to mean:
|
|
63
|
+
"""
|
|
64
|
+
Given I landed in the homepage
|
|
65
|
+
When I click "Sign in"
|
|
66
|
+
And I fill in "Username" with "<userid>"
|
|
67
|
+
And I fill in "Password" with "<password>"
|
|
68
|
+
And I click "Submit"
|
|
69
|
+
"""
|
|
70
|
+
|
|
71
|
+
Scenario: Macro 2
|
|
72
|
+
Given I define the step "* I [fill in the form with]:" to mean:
|
|
73
|
+
"""
|
|
74
|
+
When I fill in "first_name" with "<firstname>"
|
|
75
|
+
And I fill in "last_name" with "<lastname>"
|
|
76
|
+
And I fill in "street_address" with "<street_address>"
|
|
77
|
+
And I fill in "zip" with "<postcode>"
|
|
78
|
+
And I fill in "city" with "<city>"
|
|
79
|
+
And I fill in "country" with "<country>"
|
|
80
|
+
|
|
81
|
+
# Let's assume that the e-mail field is optional.
|
|
82
|
+
# The step between the <?email>...<email> will be executed
|
|
83
|
+
# when the argument <email> has a value assigned to it.
|
|
84
|
+
<?email>
|
|
85
|
+
And I fill in "email" with "<email>"
|
|
86
|
+
</email>
|
|
87
|
+
|
|
88
|
+
# Let's also assume that comment is also optional
|
|
89
|
+
# See the slightly different syntax: the conditional section
|
|
90
|
+
# <?comment>...<comment> may fit in a single line
|
|
91
|
+
<?comment> And I fill in "comment" with "<comment>"</comment>
|
|
92
|
+
And I click "Save"
|
|
93
|
+
"""
|
|
94
|
+
|
|
95
|
+
SNIPPET
|
|
96
|
+
|
|
97
|
+
trace_details
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
it 'should render the trace event for a given macro-step collection' do
|
|
102
|
+
service = FormattingService.new
|
|
103
|
+
service.register(subject)
|
|
104
|
+
expect { service.start!(macro_coll) }.not_to raise_error
|
|
105
|
+
|
|
106
|
+
# Line-by-line comparison
|
|
107
|
+
actual_lines = subject.io.string.split(/\r\n?|\n/)
|
|
108
|
+
expected_lines = expected_output.split(/\r\n?|\n/)
|
|
109
|
+
|
|
110
|
+
# Exclude line 1 (because it is time-dependent) from the comparison
|
|
111
|
+
actual_lines.shift
|
|
112
|
+
expected_lines.shift
|
|
113
|
+
|
|
114
|
+
# Remove starting/ending spaces
|
|
115
|
+
actual_lines.map!(&:strip)
|
|
116
|
+
expected_lines.map!(&:strip)
|
|
117
|
+
|
|
118
|
+
expect(actual_lines).to eq(expected_lines)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
end # context
|
|
122
|
+
|
|
123
|
+
end # describe
|
|
124
|
+
|
|
125
|
+
end # module
|
|
126
|
+
|
|
127
|
+
end # module
|
|
128
|
+
|
|
129
|
+
# End of file
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# File: to-null_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
|
+
|
|
9
|
+
require_relative '../../../lib/macros4cuke/formatting-service'
|
|
10
|
+
# Load the class under test
|
|
11
|
+
require_relative '../../../lib/macros4cuke/formatter/to-null'
|
|
12
|
+
|
|
13
|
+
module Macros4Cuke
|
|
14
|
+
|
|
15
|
+
module Formatter # Open this namespace to get rid of module qualifier prefixes
|
|
16
|
+
|
|
17
|
+
describe ToNull do
|
|
18
|
+
include UseSampleCollection # Add convenience methods for sample collection
|
|
19
|
+
|
|
20
|
+
before(:all) do
|
|
21
|
+
# Fill the collection of macro-steps with sample steps
|
|
22
|
+
fill_collection
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
after(:all) do
|
|
26
|
+
# Clear the collection to prevent interference between spec files
|
|
27
|
+
macro_coll.clear
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
context 'Initialization:' do
|
|
32
|
+
it 'should be created without parameter' do
|
|
33
|
+
expect { ToNull.new }.not_to raise_error
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it 'should react to all the notifications' do
|
|
37
|
+
instance = ToNull.new
|
|
38
|
+
expect(instance.implements).to eq(Formatter::AllNotifications)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
end # context
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
context 'Provided services:' do
|
|
45
|
+
# Default instantiation rule
|
|
46
|
+
subject { ToNull.new }
|
|
47
|
+
|
|
48
|
+
it 'should render a given macro-step collection' do
|
|
49
|
+
service = FormattingService.new
|
|
50
|
+
service.register(subject)
|
|
51
|
+
expect { service.start!(macro_coll) }.not_to raise_error
|
|
52
|
+
end
|
|
53
|
+
end # context
|
|
54
|
+
|
|
55
|
+
end # describe
|
|
56
|
+
|
|
57
|
+
end # module
|
|
58
|
+
|
|
59
|
+
end # module
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
# End of file
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# File: to-trace_spec.rb
|
|
2
|
+
|
|
3
|
+
require 'stringio'
|
|
4
|
+
require_relative '../../spec_helper'
|
|
5
|
+
|
|
6
|
+
# Load mix-in module for creating a sample collection of macro-steps
|
|
7
|
+
require_relative '../use-sample-collection'
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
require_relative '../../../lib/macros4cuke/formatting-service'
|
|
11
|
+
# Load the class under test
|
|
12
|
+
require_relative '../../../lib/macros4cuke/formatter/to-trace'
|
|
13
|
+
|
|
14
|
+
module Macros4Cuke
|
|
15
|
+
|
|
16
|
+
module Formatter # Open this namespace to get rid of module qualifier prefixes
|
|
17
|
+
|
|
18
|
+
describe ToTrace do
|
|
19
|
+
include UseSampleCollection # Add convenience methods for sample collection
|
|
20
|
+
|
|
21
|
+
let(:destination) { StringIO.new }
|
|
22
|
+
|
|
23
|
+
before(:all) do
|
|
24
|
+
# Fill the collection of macro-steps with sample steps
|
|
25
|
+
fill_collection
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
after(:all) do
|
|
29
|
+
# Clear the collection to prevent interference between spec files
|
|
30
|
+
macro_coll.clear
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
context 'Initialization:' do
|
|
35
|
+
it 'should be created with an IO parameter' do
|
|
36
|
+
expect { ToTrace.new(destination) }.not_to raise_error
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it 'should react to all the notifications' do
|
|
40
|
+
instance = ToTrace.new(destination)
|
|
41
|
+
expect(instance.implements).to eq(Formatter::AllNotifications)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
end # context
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
context 'Provided services:' do
|
|
48
|
+
# Default instantiation rule
|
|
49
|
+
subject { ToTrace.new(destination) }
|
|
50
|
+
|
|
51
|
+
# The expected event trace for the sample collection
|
|
52
|
+
let(:expected_trace) do
|
|
53
|
+
trace_details = <<-SNIPPET
|
|
54
|
+
on_collection
|
|
55
|
+
on_step
|
|
56
|
+
on_phrase
|
|
57
|
+
on_renderer
|
|
58
|
+
on_source
|
|
59
|
+
on_static_text
|
|
60
|
+
on_eol
|
|
61
|
+
on_static_text
|
|
62
|
+
on_eol
|
|
63
|
+
on_static_text
|
|
64
|
+
on_placeholder
|
|
65
|
+
on_static_text
|
|
66
|
+
on_eol
|
|
67
|
+
on_static_text
|
|
68
|
+
on_placeholder
|
|
69
|
+
on_static_text
|
|
70
|
+
on_eol
|
|
71
|
+
on_static_text
|
|
72
|
+
on_eol
|
|
73
|
+
on_renderer_end
|
|
74
|
+
on_step_end
|
|
75
|
+
on_step
|
|
76
|
+
on_phrase
|
|
77
|
+
on_renderer
|
|
78
|
+
on_source
|
|
79
|
+
on_static_text
|
|
80
|
+
on_placeholder
|
|
81
|
+
on_static_text
|
|
82
|
+
on_eol
|
|
83
|
+
on_static_text
|
|
84
|
+
on_placeholder
|
|
85
|
+
on_static_text
|
|
86
|
+
on_eol
|
|
87
|
+
on_static_text
|
|
88
|
+
on_placeholder
|
|
89
|
+
on_static_text
|
|
90
|
+
on_eol
|
|
91
|
+
on_static_text
|
|
92
|
+
on_placeholder
|
|
93
|
+
on_static_text
|
|
94
|
+
on_eol
|
|
95
|
+
on_static_text
|
|
96
|
+
on_placeholder
|
|
97
|
+
on_static_text
|
|
98
|
+
on_eol
|
|
99
|
+
on_static_text
|
|
100
|
+
on_placeholder
|
|
101
|
+
on_static_text
|
|
102
|
+
on_eol
|
|
103
|
+
on_eol
|
|
104
|
+
on_comment
|
|
105
|
+
on_eol
|
|
106
|
+
on_comment
|
|
107
|
+
on_eol
|
|
108
|
+
on_comment
|
|
109
|
+
on_eol
|
|
110
|
+
on_section
|
|
111
|
+
on_static_text
|
|
112
|
+
on_placeholder
|
|
113
|
+
on_static_text
|
|
114
|
+
on_eol
|
|
115
|
+
on_section_end
|
|
116
|
+
on_eol
|
|
117
|
+
on_comment
|
|
118
|
+
on_eol
|
|
119
|
+
on_comment
|
|
120
|
+
on_eol
|
|
121
|
+
on_comment
|
|
122
|
+
on_eol
|
|
123
|
+
on_section
|
|
124
|
+
on_static_text
|
|
125
|
+
on_placeholder
|
|
126
|
+
on_static_text
|
|
127
|
+
on_eol
|
|
128
|
+
on_section_end
|
|
129
|
+
on_static_text
|
|
130
|
+
on_eol
|
|
131
|
+
on_renderer_end
|
|
132
|
+
on_step_end
|
|
133
|
+
on_collection_end
|
|
134
|
+
SNIPPET
|
|
135
|
+
|
|
136
|
+
trace_details
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
it 'should render the trace event for a given macro-step collection' do
|
|
141
|
+
service = FormattingService.new
|
|
142
|
+
service.register(subject)
|
|
143
|
+
expect { service.start!(macro_coll) }.not_to raise_error
|
|
144
|
+
expect(subject.io.string).to eq(expected_trace)
|
|
145
|
+
end
|
|
146
|
+
end # context
|
|
147
|
+
|
|
148
|
+
end # describe
|
|
149
|
+
|
|
150
|
+
end # module
|
|
151
|
+
|
|
152
|
+
end # module
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
# End of file
|
|
@@ -0,0 +1,138 @@
|
|
|
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
|
+
|
|
9
|
+
# Load the class under test
|
|
10
|
+
require_relative '../../lib/macros4cuke/formatting-service'
|
|
11
|
+
|
|
12
|
+
module Macros4Cuke # Open this namespace to avoid module qualifier prefixes
|
|
13
|
+
|
|
14
|
+
describe FormattingService do
|
|
15
|
+
include UseSampleCollection # Add convenience methods for sample collection
|
|
16
|
+
|
|
17
|
+
# Default instantiation rule
|
|
18
|
+
subject { FormattingService.new }
|
|
19
|
+
|
|
20
|
+
before(:all) do
|
|
21
|
+
# Fill the collection of macro-steps with sample steps
|
|
22
|
+
fill_collection
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
after(:all) do
|
|
26
|
+
# Clear the collection to prevent interference between spec files
|
|
27
|
+
macro_coll.clear
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
context 'Initialization:' do
|
|
32
|
+
it 'should be created without parameter' do
|
|
33
|
+
expect { FormattingService.new }.not_to raise_error
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it 'has no formatter at start' do
|
|
37
|
+
expect(subject).to have(0).formatters
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end # context
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
context 'Provided services:' do
|
|
44
|
+
it 'should know its registered formatter(s)' do
|
|
45
|
+
formatter1 = double('fake_one')
|
|
46
|
+
formatter1.should_receive(:implements).once.and_return([:on_collection])
|
|
47
|
+
subject.register(formatter1)
|
|
48
|
+
expect(subject).to have(1).formatters
|
|
49
|
+
|
|
50
|
+
formatter2 = double('fake_two')
|
|
51
|
+
formatter2.should_receive(:implements).once.and_return([:on_step])
|
|
52
|
+
subject.register(formatter2)
|
|
53
|
+
expect(subject).to have(2).formatters
|
|
54
|
+
|
|
55
|
+
expect(subject.formatters).to eq([formatter1, formatter2])
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "should complain when a formatter doesn't implement notifications" do
|
|
59
|
+
formatter1 = double('formatter')
|
|
60
|
+
formatter1.should_receive(:implements).once.and_return([])
|
|
61
|
+
err_type = Macros4Cuke::NoFormattingEventForFormatter
|
|
62
|
+
err_msg = 'Formatter RSpec::Mocks::Mock does not ' +
|
|
63
|
+
'support any formatting event.'
|
|
64
|
+
expect { subject.register(formatter1) }.to raise_error(err_type, err_msg)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it 'should complain when a formatter uses an unknown formatting event' do
|
|
68
|
+
notifications = [
|
|
69
|
+
:on_collection,
|
|
70
|
+
:on_collection_end,
|
|
71
|
+
:non_standard,
|
|
72
|
+
:on_step,
|
|
73
|
+
:on_step_end
|
|
74
|
+
]
|
|
75
|
+
formatter = double('formatter')
|
|
76
|
+
formatter.should_receive(:implements).once.and_return(notifications)
|
|
77
|
+
err_type = Macros4Cuke::UnknownFormattingEvent
|
|
78
|
+
err_msg = 'Formatter RSpec::Mocks::Mock uses ' +
|
|
79
|
+
"the unknown formatting event 'non_standard'."
|
|
80
|
+
expect { subject.register(formatter) }.to raise_error(err_type, err_msg)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
it 'should support formatters using a subset of possible notifications' do
|
|
84
|
+
# Case: formatter that supports a few notifications only
|
|
85
|
+
formatter1 = double('formatter')
|
|
86
|
+
supported_notifications = [
|
|
87
|
+
:on_collection,
|
|
88
|
+
:on_collection_end,
|
|
89
|
+
:on_step,
|
|
90
|
+
:on_step_end
|
|
91
|
+
]
|
|
92
|
+
formatter1.should_receive(:implements).at_least(69).times.and_return(supported_notifications)
|
|
93
|
+
subject.register(formatter1)
|
|
94
|
+
|
|
95
|
+
# Test the notifications send to the formatter
|
|
96
|
+
formatter1.should_receive(:on_collection).once do |level, coll|
|
|
97
|
+
expect(level).to eq(0)
|
|
98
|
+
expect(coll).to eq(macro_coll)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
formatter1.should_receive(:on_step).twice do |level, a_step|
|
|
102
|
+
expect(level).to eq(1)
|
|
103
|
+
expect(macro_coll.macro_steps.values).to include(a_step)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
formatter1.should_receive(:on_step_end).twice do |level, arg|
|
|
107
|
+
expect(level).to eq(1)
|
|
108
|
+
expect(arg).to be_nil
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
formatter1.should_receive(:on_collection_end).once do |level, arg|
|
|
112
|
+
expect(level).to eq(0)
|
|
113
|
+
expect(arg).to be_nil
|
|
114
|
+
end
|
|
115
|
+
subject.start!(macro_coll)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
it 'should support multiple formatters' do
|
|
119
|
+
formatter1 = double('formatter')
|
|
120
|
+
supported_notifications = [:on_collection]
|
|
121
|
+
formatter1.should_receive(:implements).at_least(69 * 3).times.and_return(supported_notifications)
|
|
122
|
+
|
|
123
|
+
# Cheating: registering three times the same formatter...
|
|
124
|
+
3.times { subject.register(formatter1) }
|
|
125
|
+
|
|
126
|
+
# ... then the collection is formatted three times
|
|
127
|
+
formatter1.should_receive(:on_collection).at_least(3).times
|
|
128
|
+
subject.start!(macro_coll)
|
|
129
|
+
end
|
|
130
|
+
end # context
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
end # describe
|
|
134
|
+
|
|
135
|
+
end # module
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
# End of file
|