lopata 0.1.13 → 0.1.14

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.
@@ -1,39 +1,39 @@
1
- module Lopata
2
- # @private
3
- class SharedStep
4
- attr_reader :name, :block
5
-
6
- class NotFound < StandardError; end
7
-
8
-
9
- def self.register(name, &block)
10
- raise ArgumentError, "Comma is not allowed in shared step name: '%s'" % name if name =~ /,/
11
- registry[name] = new(name, &block)
12
- end
13
-
14
- def self.find(name)
15
- registry[name] or raise NotFound, "Shared step '%s' not found" % name
16
- end
17
-
18
- def initialize(name, &block)
19
- @name, @block = name, block
20
- end
21
-
22
- def steps
23
- @steps ||= build_steps
24
- end
25
-
26
- def build_steps
27
- builder = Lopata::ScenarioBuilder.new(name)
28
- builder.shared_step = self
29
- builder.instance_exec(&block)
30
- builder.steps
31
- end
32
-
33
- private
34
-
35
- def self.registry
36
- @shared_steps ||= {}
37
- end
38
- end
1
+ module Lopata
2
+ # @private
3
+ class SharedStep
4
+ attr_reader :name, :block
5
+
6
+ class NotFound < StandardError; end
7
+
8
+
9
+ def self.register(name, &block)
10
+ raise ArgumentError, "Comma is not allowed in shared step name: '%s'" % name if name =~ /,/
11
+ registry[name] = new(name, &block)
12
+ end
13
+
14
+ def self.find(name)
15
+ registry[name] or raise NotFound, "Shared step '%s' not found" % name
16
+ end
17
+
18
+ def initialize(name, &block)
19
+ @name, @block = name, block
20
+ end
21
+
22
+ def steps
23
+ @steps ||= build_steps
24
+ end
25
+
26
+ def build_steps
27
+ builder = Lopata::ScenarioBuilder.new(name)
28
+ builder.shared_step = self
29
+ builder.instance_exec(&block)
30
+ builder.steps
31
+ end
32
+
33
+ private
34
+
35
+ def self.registry
36
+ @shared_steps ||= {}
37
+ end
38
+ end
39
39
  end
data/lib/lopata/step.rb CHANGED
@@ -1,191 +1,191 @@
1
- require 'forwardable'
2
-
3
- module Lopata
4
- # @private
5
- class Step
6
- attr_reader :block, :args, :condition, :method_name, :shared_step
7
- # metadata overrien by the step.
8
- attr_accessor :metadata
9
-
10
- def initialize(method_name, *args, condition: nil, shared_step: nil, &block)
11
- @method_name = method_name
12
- @args = args
13
- @block = block
14
- @shared_step = shared_step
15
- @condition = condition
16
- initialized! if defined? initialized!
17
- end
18
-
19
- def title
20
- base_title = args.first
21
- base_title ||= shared_step && "#{method_name.capitalize} #{shared_step.name}" || "Untitled #{method_name}"
22
- base_title
23
- end
24
-
25
- def execution_steps(scenario, groups: [])
26
- return [] if condition && !condition.match?(scenario)
27
- return [] unless block
28
- [StepExecution.new(self, groups, &block)]
29
- end
30
- end
31
-
32
- # @private
33
- # Used for action, setup, teardown, verify
34
- class ActionStep < Step
35
- def execution_steps(scenario, groups: [])
36
- steps = []
37
- return steps if condition && !condition.match?(scenario)
38
- convert_args(scenario).each do |step|
39
- if step.is_a?(String)
40
- Lopata::SharedStep.find(step).steps.each do |shared_step|
41
- next if shared_step.condition && !shared_step.condition.match?(scenario)
42
- steps += shared_step.execution_steps(scenario, groups: groups)
43
- end
44
- elsif step.is_a?(Proc)
45
- steps << StepExecution.new(self, groups, &step)
46
- end
47
- end
48
- steps << StepExecution.new(self, groups, &block) if block
49
- steps.reject { |s| !s.block }
50
- end
51
-
52
- def separate_args(args)
53
- args.map { |a| a.is_a?(String) && a =~ /,/ ? a.split(',').map(&:strip) : a }.flatten
54
- end
55
-
56
- def convert_args(scenario)
57
- flat_args = separate_args(args.flatten)
58
- flat_args.map do |arg|
59
- case arg
60
- # trait symbols as link to metadata.
61
- when Symbol then scenario.metadata[arg]
62
- else
63
- arg
64
- end
65
- end.flatten
66
- end
67
-
68
- def title
69
- shared_step && "#{method_name.capitalize} #{shared_step.name}" || "Untitled #{method_name}"
70
- end
71
- end
72
-
73
- # @private
74
- # Used for context
75
- class GroupStep < Step
76
-
77
- def execution_steps(scenario, groups: [])
78
- steps = []
79
- return steps if condition && !condition.match?(scenario)
80
- @steps.each do |step|
81
- steps += step.execution_steps(scenario, groups: groups + [self])
82
- end
83
- steps.reject! { |s| !s.block }
84
- steps.reject { |s| s.teardown_group?(self) } + steps.select { |s| s.teardown_group?(self) }
85
- end
86
-
87
- def let_methods
88
- @let_methods ||= {}
89
- end
90
-
91
- private
92
-
93
- # Group step's block is a block in context of builder, not scenario. So hide the @block to not be used in scenario.
94
- def initialized!
95
- builder = Lopata::ScenarioBuilder.new(title)
96
- builder.instance_exec(&@block)
97
- @steps = builder.steps
98
- @block = nil
99
- end
100
- end
101
-
102
- #@private
103
- class StepExecution
104
- attr_reader :step, :status, :exception, :block, :pending_message, :groups
105
- extend Forwardable
106
- def_delegators :step, :method_name
107
-
108
- class PendingStepFixedError < StandardError; end
109
-
110
- def initialize(step, groups, &block)
111
- @step = step
112
- @status = :not_runned
113
- @exception = nil
114
- @block = block
115
- @groups = groups
116
- end
117
-
118
- def title
119
- group_title = groups.map { |g| "#{g.title}: " }.join
120
- "#{group_title}#{step.title}"
121
- end
122
-
123
- def run(scenario)
124
- @status = :running
125
- begin
126
- run_step(scenario)
127
- if pending?
128
- @status = :failed
129
- raise PendingStepFixedError, 'Expected step to fail since it is pending, but it passed.'
130
- else
131
- @status = :passed
132
- end
133
- rescue Exception => e
134
- @status = :failed unless pending?
135
- @exception = e
136
- end
137
- end
138
-
139
- def run_step(scenario)
140
- return unless block
141
- scenario.instance_exec(&block)
142
- end
143
-
144
- def failed?
145
- status == :failed
146
- end
147
-
148
- def passed?
149
- status == :passed
150
- end
151
-
152
- def skipped?
153
- status == :skipped
154
- end
155
-
156
- def skip!
157
- @status = :skipped
158
- end
159
-
160
- def pending?
161
- status == :pending
162
- end
163
-
164
- def pending!(message = nil)
165
- @status = :pending
166
- @pending_message = message
167
- end
168
-
169
- def teardown?
170
- %i{ teardown cleanup }.include?(method_name)
171
- end
172
-
173
- def teardown_group?(group = nil)
174
- teardown? && self.groups.last == group
175
- end
176
-
177
- def skip_rest_on_failure?
178
- %i{ setup action }.include?(method_name)
179
- end
180
-
181
- # Step metadata is a combination of metadata given for step and all contexts (groups) the step included
182
- def metadata
183
- (groups + [step]).compact.inject({}) { |merged, part| merged.merge(part.metadata) }
184
- end
185
-
186
- # Step methods is a combination of let_methods for all contexts (group) the step included
187
- def let_methods
188
- (groups).compact.inject({}) { |merged, part| merged.merge(part.let_methods) }
189
- end
190
- end
191
- end
1
+ require 'forwardable'
2
+
3
+ module Lopata
4
+ # @private
5
+ class Step
6
+ attr_reader :block, :args, :condition, :method_name, :shared_step
7
+ # metadata overrien by the step.
8
+ attr_accessor :metadata
9
+
10
+ def initialize(method_name, *args, condition: nil, shared_step: nil, &block)
11
+ @method_name = method_name
12
+ @args = args
13
+ @block = block
14
+ @shared_step = shared_step
15
+ @condition = condition
16
+ initialized! if defined? initialized!
17
+ end
18
+
19
+ def title
20
+ base_title = args.first
21
+ base_title ||= shared_step && "#{method_name.capitalize} #{shared_step.name}" || "Untitled #{method_name}"
22
+ base_title
23
+ end
24
+
25
+ def execution_steps(scenario, groups: [])
26
+ return [] if condition && !condition.match?(scenario)
27
+ return [] unless block
28
+ [StepExecution.new(self, groups, &block)]
29
+ end
30
+ end
31
+
32
+ # @private
33
+ # Used for action, setup, teardown, verify
34
+ class ActionStep < Step
35
+ def execution_steps(scenario, groups: [])
36
+ steps = []
37
+ return steps if condition && !condition.match?(scenario)
38
+ convert_args(scenario).each do |step|
39
+ if step.is_a?(String)
40
+ Lopata::SharedStep.find(step).steps.each do |shared_step|
41
+ next if shared_step.condition && !shared_step.condition.match?(scenario)
42
+ steps += shared_step.execution_steps(scenario, groups: groups)
43
+ end
44
+ elsif step.is_a?(Proc)
45
+ steps << StepExecution.new(self, groups, &step)
46
+ end
47
+ end
48
+ steps << StepExecution.new(self, groups, &block) if block
49
+ steps.reject { |s| !s.block }
50
+ end
51
+
52
+ def separate_args(args)
53
+ args.map { |a| a.is_a?(String) && a =~ /,/ ? a.split(',').map(&:strip) : a }.flatten
54
+ end
55
+
56
+ def convert_args(scenario)
57
+ flat_args = separate_args(args.flatten)
58
+ flat_args.map do |arg|
59
+ case arg
60
+ # trait symbols as link to metadata.
61
+ when Symbol then scenario.metadata[arg]
62
+ else
63
+ arg
64
+ end
65
+ end.flatten
66
+ end
67
+
68
+ def title
69
+ shared_step && "#{method_name.capitalize} #{shared_step.name}" || "Untitled #{method_name}"
70
+ end
71
+ end
72
+
73
+ # @private
74
+ # Used for context
75
+ class GroupStep < Step
76
+
77
+ def execution_steps(scenario, groups: [])
78
+ steps = []
79
+ return steps if condition && !condition.match?(scenario)
80
+ @steps.each do |step|
81
+ steps += step.execution_steps(scenario, groups: groups + [self])
82
+ end
83
+ steps.reject! { |s| !s.block }
84
+ steps.reject { |s| s.teardown_group?(self) } + steps.select { |s| s.teardown_group?(self) }
85
+ end
86
+
87
+ def let_methods
88
+ @let_methods ||= {}
89
+ end
90
+
91
+ private
92
+
93
+ # Group step's block is a block in context of builder, not scenario. So hide the @block to not be used in scenario.
94
+ def initialized!
95
+ builder = Lopata::ScenarioBuilder.new(title)
96
+ builder.instance_exec(&@block)
97
+ @steps = builder.steps
98
+ @block = nil
99
+ end
100
+ end
101
+
102
+ #@private
103
+ class StepExecution
104
+ attr_reader :step, :status, :exception, :block, :pending_message, :groups
105
+ extend Forwardable
106
+ def_delegators :step, :method_name
107
+
108
+ class PendingStepFixedError < StandardError; end
109
+
110
+ def initialize(step, groups, &block)
111
+ @step = step
112
+ @status = :not_runned
113
+ @exception = nil
114
+ @block = block
115
+ @groups = groups
116
+ end
117
+
118
+ def title
119
+ group_title = groups.map { |g| "#{g.title}: " }.join
120
+ "#{group_title}#{step.title}"
121
+ end
122
+
123
+ def run(scenario)
124
+ @status = :running
125
+ begin
126
+ run_step(scenario)
127
+ if pending?
128
+ @status = :failed
129
+ raise PendingStepFixedError, 'Expected step to fail since it is pending, but it passed.'
130
+ else
131
+ @status = :passed
132
+ end
133
+ rescue Exception => e
134
+ @status = :failed unless pending?
135
+ @exception = e
136
+ end
137
+ end
138
+
139
+ def run_step(scenario)
140
+ return unless block
141
+ scenario.instance_exec(&block)
142
+ end
143
+
144
+ def failed?
145
+ status == :failed
146
+ end
147
+
148
+ def passed?
149
+ status == :passed
150
+ end
151
+
152
+ def skipped?
153
+ status == :skipped
154
+ end
155
+
156
+ def skip!
157
+ @status = :skipped
158
+ end
159
+
160
+ def pending?
161
+ status == :pending
162
+ end
163
+
164
+ def pending!(message = nil)
165
+ @status = :pending
166
+ @pending_message = message
167
+ end
168
+
169
+ def teardown?
170
+ %i{ teardown cleanup }.include?(method_name)
171
+ end
172
+
173
+ def teardown_group?(group = nil)
174
+ teardown? && self.groups.last == group
175
+ end
176
+
177
+ def skip_rest_on_failure?
178
+ %i{ setup action }.include?(method_name)
179
+ end
180
+
181
+ # Step metadata is a combination of metadata given for step and all contexts (groups) the step included
182
+ def metadata
183
+ (groups + [step]).compact.inject({}) { |merged, part| merged.merge(part.metadata) }
184
+ end
185
+
186
+ # Step methods is a combination of let_methods for all contexts (group) the step included
187
+ def let_methods
188
+ (groups).compact.inject({}) { |merged, part| merged.merge(part.let_methods) }
189
+ end
190
+ end
191
+ end