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.
Files changed (35) hide show
  1. checksums.yaml +8 -8
  2. data/.rubocop.yml +20 -3
  3. data/CHANGELOG.md +15 -1
  4. data/examples/i18n/fr/features/step_definitions/use_macro_steps.rb +1 -1
  5. data/features/demo06.feature +75 -75
  6. data/features/demo07.feature +15 -0
  7. data/features/support/env.rb +6 -0
  8. data/features/support/macro_support.rb +2 -2
  9. data/lib/macro_steps.rb +19 -2
  10. data/lib/macros4cuke/coll-walker-factory.rb +119 -0
  11. data/lib/macros4cuke/constants.rb +1 -1
  12. data/lib/macros4cuke/exceptions.rb +23 -1
  13. data/lib/macros4cuke/formatter/all-notifications.rb +30 -0
  14. data/lib/macros4cuke/formatter/to-gherkin.rb +80 -0
  15. data/lib/macros4cuke/formatter/to-null.rb +86 -0
  16. data/lib/macros4cuke/formatter/to-trace.rb +100 -0
  17. data/lib/macros4cuke/formatting-service.rb +74 -0
  18. data/lib/macros4cuke/macro-collection.rb +3 -3
  19. data/lib/macros4cuke/macro-step-support.rb +1 -1
  20. data/lib/macros4cuke/macro-step.rb +10 -26
  21. data/lib/macros4cuke/templating/engine.rb +74 -29
  22. data/spec/macros4cuke/coll-walker-factory_spec.rb +269 -0
  23. data/spec/macros4cuke/formatter/to-gherkin_spec.rb +129 -0
  24. data/spec/macros4cuke/formatter/to-null_spec.rb +62 -0
  25. data/spec/macros4cuke/formatter/to-trace_spec.rb +155 -0
  26. data/spec/macros4cuke/formatting-service_spec.rb +138 -0
  27. data/spec/macros4cuke/macro-collection_spec.rb +7 -4
  28. data/spec/macros4cuke/macro-step-support_spec.rb +41 -24
  29. data/spec/macros4cuke/macro-step_spec.rb +13 -6
  30. data/spec/macros4cuke/templating/engine_spec.rb +11 -7
  31. data/spec/macros4cuke/templating/placeholder_spec.rb +1 -1
  32. data/spec/macros4cuke/templating/section_spec.rb +3 -1
  33. data/spec/macros4cuke/use-sample-collection.rb +79 -0
  34. data/spec/spec_helper.rb +3 -0
  35. 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