lopata 0.1.24 → 0.1.26
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 +4 -4
- data/lib/lopata/observers/console_output_observer.rb +19 -18
- data/lib/lopata/observers/web_logger.rb +18 -19
- data/lib/lopata/scenario.rb +53 -53
- data/lib/lopata/scenario_builder.rb +7 -3
- data/lib/lopata/step.rb +134 -91
- data/lib/lopata/version.rb +1 -1
- metadata +3 -4
- data/lib/lopata/observers/group_tree.rb +0 -64
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c48d8c35ec3fbda8e6e707ec75a4d48c98a7e0733a4156869e932a00cadb6a10
|
4
|
+
data.tar.gz: 70ef965bafbf052815cd06f9807f1ac209dd06668e7fe17dabee4684e7066885
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9547b0ce6a37588e0fac9a3f0c899502e755e17caf753eac1bdcaba8dbf2119b2d5ddcda3897b8450cecc03b9796a1b2234bd3f09ebe4e442501cc7f79f62410
|
7
|
+
data.tar.gz: f1c6e073a0dce8cfdd22182214fddb5ff88acef2771df288bf8109333533506a941db6e9d3111553e7ea5dea2dba05b21d096924dc424dee6dfea1f5d7cd147d
|
@@ -1,5 +1,4 @@
|
|
1
1
|
require_relative 'backtrace_formatter'
|
2
|
-
require_relative 'group_tree'
|
3
2
|
require 'forwardable'
|
4
3
|
|
5
4
|
module Lopata
|
@@ -34,25 +33,27 @@ module Lopata
|
|
34
33
|
statuses[scenario.status] ||= 0
|
35
34
|
statuses[scenario.status] += 1
|
36
35
|
|
37
|
-
if scenario.failed?
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
36
|
+
log_steps(scenario.steps) if scenario.failed?
|
37
|
+
|
38
|
+
flush
|
39
|
+
end
|
40
|
+
|
41
|
+
# @private
|
42
|
+
def log_steps(steps)
|
43
|
+
steps.each do |step|
|
44
|
+
next unless step.loggable?
|
45
|
+
if step.group?
|
46
|
+
status = step.status
|
47
|
+
if %i{ passed skipped ignored }.include?(status)
|
48
|
+
puts colored(" #{status_marker(step.status)} #{step.title}", status)
|
49
|
+
else
|
50
|
+
log_steps(step.steps)
|
51
51
|
end
|
52
|
+
else
|
53
|
+
puts colored(" #{status_marker(step.status)} #{step.title}", step.status)
|
54
|
+
puts indent(4, backtrace_formatter.error_message(step.exception, include_backtrace: true)) if step.failed?
|
52
55
|
end
|
53
56
|
end
|
54
|
-
|
55
|
-
flush
|
56
57
|
end
|
57
58
|
|
58
59
|
private
|
@@ -61,7 +62,7 @@ module Lopata
|
|
61
62
|
case status
|
62
63
|
when :failed then red(text)
|
63
64
|
when :passed then green(text)
|
64
|
-
when :skipped then cyan(text)
|
65
|
+
when :skipped, :ignored then cyan(text)
|
65
66
|
when :pending then yellow(text)
|
66
67
|
else text
|
67
68
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'httparty'
|
2
2
|
require 'json'
|
3
3
|
require_relative 'backtrace_formatter'
|
4
|
-
require_relative 'group_tree'
|
5
4
|
|
6
5
|
module Lopata
|
7
6
|
module Observers
|
@@ -49,24 +48,7 @@ module Lopata
|
|
49
48
|
|
50
49
|
def add_attempt(scenario, finished)
|
51
50
|
status = scenario.failed? ? Lopata::FAILED : Lopata::PASSED
|
52
|
-
steps =
|
53
|
-
GroupTree.steps_hierarhy(scenario.steps).walk_through do |step|
|
54
|
-
if step.is_a?(Lopata::StepExecution)
|
55
|
-
next unless step.loggable?
|
56
|
-
steps << step_hash(step)
|
57
|
-
else # GroupTree
|
58
|
-
|
59
|
-
group = step
|
60
|
-
if %i{ passed skipped }.include?(group.status)
|
61
|
-
steps << group_hash(group)
|
62
|
-
false
|
63
|
-
else
|
64
|
-
true
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
steps = scenario.steps.select(&:loggable?).map { |s| step_hash(s) }
|
51
|
+
steps = build_hashes(scenario.steps)
|
70
52
|
request = { status: status, steps: steps, launch: { id: @launch_id, finished: finished } }
|
71
53
|
test = test_id(scenario)
|
72
54
|
post("/tests/#{test}/attempts.json", body: request)
|
@@ -76,6 +58,23 @@ module Lopata
|
|
76
58
|
puts e.backtrace
|
77
59
|
end
|
78
60
|
|
61
|
+
def build_hashes(steps)
|
62
|
+
hashes = []
|
63
|
+
steps.each do |step|
|
64
|
+
next unless step.loggable?
|
65
|
+
if step.group?
|
66
|
+
if %i{ passed skipped ignored }.include?(step.status)
|
67
|
+
hashes << group_hash(step)
|
68
|
+
else
|
69
|
+
hashes += build_hashes(step.steps)
|
70
|
+
end
|
71
|
+
else
|
72
|
+
hashes << step_hash(step)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
hashes
|
76
|
+
end
|
77
|
+
|
79
78
|
def step_hash(step)
|
80
79
|
hash = { status: step.status, title: step.title }
|
81
80
|
if step.failed?
|
data/lib/lopata/scenario.rb
CHANGED
@@ -45,8 +45,9 @@ class Lopata::Scenario
|
|
45
45
|
|
46
46
|
# @private
|
47
47
|
def method_missing(method, *args, &block)
|
48
|
-
|
49
|
-
|
48
|
+
|
49
|
+
if (let_method = execution.find_let_method(method))
|
50
|
+
let_method.call_in_scenario(self, *args)
|
50
51
|
elsif metadata.keys.include?(method)
|
51
52
|
metadata[method]
|
52
53
|
else
|
@@ -56,21 +57,18 @@ class Lopata::Scenario
|
|
56
57
|
|
57
58
|
# @private
|
58
59
|
def respond_to_missing?(method, *)
|
59
|
-
execution.
|
60
|
+
execution.find_let_method(method) or metadata.keys.include?(method) or super
|
60
61
|
end
|
61
62
|
|
62
63
|
# @private
|
63
64
|
# Scenario execution and live-cycle information
|
64
65
|
class Execution
|
65
|
-
attr_reader :scenario, :
|
66
|
-
|
67
|
-
def initialize(title,
|
68
|
-
@title = [title, options_title].compact.reject(&:empty?).join(' ')
|
69
|
-
@metadata = metadata
|
70
|
-
@let_methods = {}
|
71
|
-
@status = :not_runned
|
72
|
-
@steps = []
|
66
|
+
attr_reader :scenario, :current_step, :top
|
67
|
+
|
68
|
+
def initialize(title, metadata = {})
|
73
69
|
@scenario = Lopata::Scenario.new(self)
|
70
|
+
@top = Lopata::GroupExecution.new(Lopata::TopStep.new(title, metadata: metadata), nil, steps: [])
|
71
|
+
@current_step = @top
|
74
72
|
end
|
75
73
|
|
76
74
|
# Provide a human-readable representation of this class
|
@@ -79,32 +77,42 @@ class Lopata::Scenario
|
|
79
77
|
end
|
80
78
|
alias to_s inspect
|
81
79
|
|
80
|
+
def steps
|
81
|
+
top.steps
|
82
|
+
end
|
83
|
+
|
82
84
|
def run
|
83
|
-
@status = :running
|
84
|
-
sort_steps
|
85
85
|
world.notify_observers(:scenario_started, self)
|
86
|
-
|
87
|
-
@status = steps.any?(&:failed?) ? :failed : :passed
|
86
|
+
run_step(top)
|
88
87
|
world.notify_observers(:scenario_finished, self)
|
89
88
|
cleanup
|
90
89
|
end
|
91
90
|
|
92
91
|
def run_step(step)
|
93
|
-
|
94
|
-
|
95
|
-
if
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
92
|
+
@current_step = step
|
93
|
+
return :skipped if step.skipped?
|
94
|
+
return :ignored if step.ignored?
|
95
|
+
if step.condition&.dynamic && !step.condition.match_dynamic?(scenario)
|
96
|
+
step.ignored!
|
97
|
+
return :ignored
|
98
|
+
end
|
99
|
+
if step.group?
|
100
|
+
skip_rest = false
|
101
|
+
step.steps.each do
|
102
|
+
if _1.teardown?
|
103
|
+
run_step(_1)
|
104
|
+
elsif skip_rest
|
105
|
+
_1.skip!
|
106
|
+
else
|
107
|
+
run_step(_1)
|
108
|
+
skip_rest = true if _1.failed? && _1.skip_rest_on_failure?
|
109
|
+
end
|
102
110
|
end
|
111
|
+
step.status!
|
112
|
+
else
|
113
|
+
step.run(scenario)
|
114
|
+
step.status
|
103
115
|
end
|
104
|
-
@current_step = step
|
105
|
-
step.run(scenario)
|
106
|
-
skip_rest if step.failed? && step.skip_rest_on_failure?
|
107
|
-
@current_step = nil
|
108
116
|
end
|
109
117
|
|
110
118
|
def world
|
@@ -115,55 +123,47 @@ class Lopata::Scenario
|
|
115
123
|
status == :failed
|
116
124
|
end
|
117
125
|
|
118
|
-
def
|
119
|
-
|
126
|
+
def metadata
|
127
|
+
current_step.metadata
|
120
128
|
end
|
121
129
|
|
122
|
-
def
|
123
|
-
|
130
|
+
def let_methods
|
131
|
+
current_step.let_methods
|
124
132
|
end
|
125
133
|
|
126
|
-
def
|
127
|
-
|
134
|
+
def find_let_method(name)
|
135
|
+
current_step.find_let_method(name)
|
128
136
|
end
|
129
137
|
|
130
|
-
def
|
131
|
-
|
132
|
-
@metadata.merge(current_step.metadata)
|
133
|
-
else
|
134
|
-
@metadata
|
135
|
-
end
|
138
|
+
def title
|
139
|
+
top.title
|
136
140
|
end
|
137
141
|
|
138
|
-
def
|
139
|
-
|
140
|
-
@let_methods.merge(current_step.let_methods)
|
141
|
-
else
|
142
|
-
@let_methods
|
143
|
-
end
|
142
|
+
def status
|
143
|
+
top.status
|
144
144
|
end
|
145
145
|
|
146
146
|
def let_base
|
147
|
-
if current_step
|
148
|
-
current_step
|
147
|
+
if current_step.group?
|
148
|
+
current_step
|
149
149
|
else
|
150
|
-
|
150
|
+
current_step.parent
|
151
151
|
end
|
152
152
|
end
|
153
153
|
|
154
154
|
def let(method_name, &block)
|
155
|
-
let_base
|
155
|
+
let_base.add_let_method(method_name, LetMethod.new(&block))
|
156
156
|
end
|
157
157
|
|
158
158
|
def let!(method_name, &block)
|
159
|
-
let_base
|
159
|
+
let_base.add_let_method(method_name, LetBangMethod.new(&block))
|
160
160
|
end
|
161
161
|
|
162
162
|
def cleanup
|
163
163
|
@title = nil
|
164
|
-
@metadata = nil
|
165
|
-
@steps = nil
|
166
164
|
@scenario = nil
|
165
|
+
@top = nil
|
166
|
+
@current_step = nil
|
167
167
|
end
|
168
168
|
end
|
169
169
|
|
@@ -38,16 +38,20 @@ class Lopata::ScenarioBuilder
|
|
38
38
|
filters = Lopata.configuration.filters
|
39
39
|
option_combinations.each do |option_set|
|
40
40
|
metadata = common_metadata.merge(option_set.metadata)
|
41
|
-
|
42
|
-
|
41
|
+
scenario_title = [title, option_set.title].compact.reject(&:empty?).join(' ')
|
42
|
+
scenario = Lopata::Scenario::Execution.new(scenario_title, metadata)
|
43
|
+
|
43
44
|
unless filters.empty?
|
44
45
|
next unless filters.all? { |f| f[scenario] }
|
45
46
|
end
|
46
47
|
|
48
|
+
exec_steps = []
|
47
49
|
steps_with_hooks.each do |step|
|
48
50
|
next if step.condition && !step.condition.match?(scenario)
|
49
|
-
step.execution_steps(scenario).each { |s|
|
51
|
+
step.execution_steps(scenario, parent: scenario.top).each { |s| exec_steps << s }
|
50
52
|
end
|
53
|
+
scenario.steps.push(*exec_steps.reject(&:teardown?))
|
54
|
+
scenario.steps.push(*exec_steps.select(&:teardown?))
|
51
55
|
|
52
56
|
world.scenarios << scenario
|
53
57
|
end
|
data/lib/lopata/step.rb
CHANGED
@@ -7,12 +7,13 @@ module Lopata
|
|
7
7
|
# metadata overrien by the step.
|
8
8
|
attr_accessor :metadata
|
9
9
|
|
10
|
-
def initialize(method_name, *args, condition: nil, shared_step: nil, &block)
|
10
|
+
def initialize(method_name, *args, condition: nil, shared_step: nil, metadata: {}, &block)
|
11
11
|
@method_name = method_name
|
12
12
|
@args = args
|
13
13
|
@block = block
|
14
14
|
@shared_step = shared_step
|
15
15
|
@condition = condition
|
16
|
+
@metadata = metadata
|
16
17
|
initialized! if defined? initialized!
|
17
18
|
end
|
18
19
|
|
@@ -22,31 +23,31 @@ module Lopata
|
|
22
23
|
base_title
|
23
24
|
end
|
24
25
|
|
25
|
-
def execution_steps(scenario,
|
26
|
+
def execution_steps(scenario, parent:)
|
26
27
|
return [] if condition && !condition.match?(scenario)
|
27
28
|
return [] unless block
|
28
|
-
[StepExecution.new(self,
|
29
|
+
[StepExecution.new(self, parent, condition: condition, &block)]
|
29
30
|
end
|
30
31
|
end
|
31
32
|
|
32
33
|
# @private
|
33
34
|
# Used for action, setup, teardown, verify
|
34
35
|
class ActionStep < Step
|
35
|
-
def execution_steps(scenario,
|
36
|
+
def execution_steps(scenario, parent:)
|
36
37
|
steps = []
|
37
38
|
return steps if condition && !condition.match?(scenario)
|
38
39
|
convert_args(scenario).each do |step|
|
39
40
|
if step.is_a?(String)
|
40
41
|
Lopata::SharedStep.find(step).steps.each do |shared_step|
|
41
42
|
next if shared_step.condition && !shared_step.condition.match?(scenario)
|
42
|
-
steps += shared_step.execution_steps(scenario,
|
43
|
+
steps += shared_step.execution_steps(scenario, parent: parent)
|
43
44
|
end
|
44
45
|
elsif step.is_a?(Proc)
|
45
|
-
steps << StepExecution.new(self,
|
46
|
+
steps << StepExecution.new(self, parent, condition: condition, &step)
|
46
47
|
end
|
47
48
|
end
|
48
|
-
steps << StepExecution.new(self,
|
49
|
-
steps
|
49
|
+
steps << StepExecution.new(self, parent, condition: condition, &block) if block
|
50
|
+
steps
|
50
51
|
end
|
51
52
|
|
52
53
|
def separate_args(args)
|
@@ -74,26 +75,18 @@ module Lopata
|
|
74
75
|
# Used for context
|
75
76
|
class GroupStep < Step
|
76
77
|
|
77
|
-
def execution_steps(scenario,
|
78
|
+
def execution_steps(scenario, parent: nil)
|
78
79
|
steps = []
|
79
80
|
return steps if condition && !condition.match?(scenario)
|
81
|
+
group = GroupExecution.new(self, parent, steps: steps, condition: condition)
|
80
82
|
@steps.each do |step|
|
81
|
-
steps += step.execution_steps(scenario,
|
83
|
+
steps += step.execution_steps(scenario, parent: group)
|
82
84
|
end
|
83
|
-
steps.reject
|
84
|
-
steps.
|
85
|
+
group.steps.push(*steps.reject(&:teardown?))
|
86
|
+
group.steps.push(*steps.select(&:teardown?))
|
87
|
+
[group]
|
85
88
|
end
|
86
89
|
|
87
|
-
def let_methods
|
88
|
-
@let_methods ||= {}
|
89
|
-
end
|
90
|
-
|
91
|
-
def let_bang_methods
|
92
|
-
@let_bang_methods ||= {}
|
93
|
-
end
|
94
|
-
|
95
|
-
private
|
96
|
-
|
97
90
|
# Group step's block is a block in context of builder, not scenario. So hide the @block to not be used in scenario.
|
98
91
|
def initialized!
|
99
92
|
builder = Lopata::ScenarioBuilder.new(title)
|
@@ -103,70 +96,60 @@ module Lopata
|
|
103
96
|
end
|
104
97
|
end
|
105
98
|
|
106
|
-
|
107
|
-
class
|
108
|
-
|
99
|
+
# @private
|
100
|
+
class TopStep < Step
|
101
|
+
def initialize(title, metadata: {})
|
102
|
+
super(:top, title, metadata: metadata)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# @private
|
107
|
+
# Abstract execution step. Composition, may be group or step.
|
108
|
+
class BaseExecution
|
109
|
+
attr_reader :step, :status, :parent, :condition
|
109
110
|
extend Forwardable
|
110
111
|
def_delegators :step, :method_name
|
111
112
|
|
112
|
-
|
113
|
-
|
114
|
-
def initialize(step, groups, condition: nil, &block)
|
113
|
+
def initialize(step, parent, condition: nil)
|
115
114
|
@step = step
|
115
|
+
@parent = parent
|
116
116
|
@status = :not_runned
|
117
|
-
@exception = nil
|
118
|
-
@block = block
|
119
|
-
@groups = groups
|
120
117
|
@condition = condition
|
121
118
|
end
|
122
119
|
|
123
|
-
def
|
124
|
-
|
120
|
+
def group?
|
121
|
+
false
|
125
122
|
end
|
126
123
|
|
127
|
-
def
|
128
|
-
|
124
|
+
def top?
|
125
|
+
!parent
|
129
126
|
end
|
130
127
|
|
131
|
-
def
|
132
|
-
|
133
|
-
begin
|
134
|
-
unless check_dynamic_condition?(scenario)
|
135
|
-
@status = :ignored
|
136
|
-
return
|
137
|
-
end
|
138
|
-
run_step(scenario)
|
139
|
-
if pending?
|
140
|
-
@status = :failed
|
141
|
-
raise PendingStepFixedError, 'Expected step to fail since it is pending, but it passed.'
|
142
|
-
else
|
143
|
-
@status = :passed
|
144
|
-
end
|
145
|
-
rescue Exception => e
|
146
|
-
@status = :failed unless pending?
|
147
|
-
@exception = e
|
148
|
-
end
|
128
|
+
def teardown?
|
129
|
+
%i{ teardown cleanup }.include?(method_name)
|
149
130
|
end
|
150
131
|
|
151
|
-
def
|
152
|
-
|
153
|
-
|
132
|
+
def parents
|
133
|
+
result = []
|
134
|
+
prnt = parent
|
135
|
+
while prnt
|
136
|
+
result << prnt
|
137
|
+
prnt = prnt.parent
|
138
|
+
end
|
139
|
+
result
|
154
140
|
end
|
155
141
|
|
156
|
-
|
157
|
-
|
158
|
-
|
142
|
+
# Step metadata is a combination of metadata given for step and all contexts (groups) the step included
|
143
|
+
def metadata
|
144
|
+
result = step.metadata || {}
|
145
|
+
if parent
|
146
|
+
result = parent.metadata.merge(result)
|
159
147
|
end
|
160
|
-
|
148
|
+
result
|
161
149
|
end
|
162
150
|
|
163
|
-
def
|
164
|
-
|
165
|
-
conds << condition if condition&.dynamic?
|
166
|
-
groups.each do
|
167
|
-
conds << _1.condition if _1.condition&.dynamic?
|
168
|
-
end
|
169
|
-
conds
|
151
|
+
def find_let_method(name)
|
152
|
+
parent&.find_let_method(name)
|
170
153
|
end
|
171
154
|
|
172
155
|
def failed?
|
@@ -193,13 +176,12 @@ module Lopata
|
|
193
176
|
@status = :skipped
|
194
177
|
end
|
195
178
|
|
196
|
-
def
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
@pending_message = message
|
179
|
+
def title
|
180
|
+
if parent && !parent.top?
|
181
|
+
"#{parent.title}: #{step.title}"
|
182
|
+
else
|
183
|
+
step.title
|
184
|
+
end
|
203
185
|
end
|
204
186
|
|
205
187
|
# Need log this step.
|
@@ -208,35 +190,96 @@ module Lopata
|
|
208
190
|
not %i{ let let! }.include?(method_name)
|
209
191
|
end
|
210
192
|
|
211
|
-
def
|
212
|
-
%i{
|
193
|
+
def skip_rest_on_failure?
|
194
|
+
%i{ setup action }.include?(method_name)
|
213
195
|
end
|
196
|
+
end
|
197
|
+
|
198
|
+
# @private
|
199
|
+
class GroupExecution < BaseExecution
|
200
|
+
attr_reader :steps
|
214
201
|
|
215
|
-
def
|
216
|
-
|
202
|
+
def initialize(step, parent, condition: nil, steps:)
|
203
|
+
super(step, parent, condition: condition)
|
204
|
+
@steps = steps
|
205
|
+
@let_methods = {}
|
217
206
|
end
|
218
207
|
|
219
|
-
def
|
220
|
-
|
208
|
+
def group?
|
209
|
+
true
|
221
210
|
end
|
222
211
|
|
223
|
-
def
|
224
|
-
|
212
|
+
def status!
|
213
|
+
# return @status if @status
|
214
|
+
statuses = steps.map(&:status!).uniq
|
215
|
+
@status =
|
216
|
+
if statuses.length == 1
|
217
|
+
statuses.first
|
218
|
+
elsif statuses.include?(:failed)
|
219
|
+
:failed
|
220
|
+
else
|
221
|
+
statuses.first || :skipped
|
222
|
+
end
|
223
|
+
@status = :passed if @status == :pending
|
224
|
+
@status
|
225
225
|
end
|
226
226
|
|
227
|
-
|
228
|
-
|
229
|
-
|
227
|
+
def find_let_method(name)
|
228
|
+
@let_methods[name] || parent&.find_let_method(name)
|
229
|
+
end
|
230
|
+
|
231
|
+
def add_let_method(name, method)
|
232
|
+
@let_methods[name] = method
|
233
|
+
end
|
234
|
+
|
235
|
+
def ignored!
|
236
|
+
@status = :ignored
|
237
|
+
steps.each(&:ignored!)
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
# @private
|
242
|
+
class StepExecution < BaseExecution
|
243
|
+
attr_reader :exception, :block, :pending_message
|
244
|
+
|
245
|
+
class PendingStepFixedError < StandardError; end
|
246
|
+
|
247
|
+
def initialize(step, parent, condition: nil, &block)
|
248
|
+
super(step, parent, condition: condition)
|
249
|
+
@exception = nil
|
250
|
+
@block = block
|
251
|
+
end
|
252
|
+
|
253
|
+
alias status! status
|
254
|
+
|
255
|
+
def run(scenario)
|
256
|
+
@status = :running
|
257
|
+
begin
|
258
|
+
run_step(scenario)
|
259
|
+
if pending?
|
260
|
+
@status = :failed
|
261
|
+
raise PendingStepFixedError, 'Expected step to fail since it is pending, but it passed.'
|
262
|
+
else
|
263
|
+
@status = :passed
|
264
|
+
end
|
265
|
+
rescue Exception => e
|
266
|
+
@status = :failed unless pending?
|
267
|
+
@exception = e
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
def run_step(scenario)
|
272
|
+
return unless block
|
273
|
+
scenario.instance_exec(&block)
|
230
274
|
end
|
231
275
|
|
232
|
-
|
233
|
-
|
234
|
-
(groups).compact.inject({}) { |merged, part| merged.merge(part.let_methods) }
|
276
|
+
def pending?
|
277
|
+
status == :pending
|
235
278
|
end
|
236
279
|
|
237
|
-
|
238
|
-
|
239
|
-
|
280
|
+
def pending!(message = nil)
|
281
|
+
@status = :pending
|
282
|
+
@pending_message = message
|
240
283
|
end
|
241
284
|
end
|
242
285
|
end
|
data/lib/lopata/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lopata
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.26
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexey Volochnev
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-09-
|
11
|
+
date: 2023-09-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: httparty
|
@@ -107,7 +107,6 @@ files:
|
|
107
107
|
- lib/lopata/observers/backtrace_formatter.rb
|
108
108
|
- lib/lopata/observers/base_observer.rb
|
109
109
|
- lib/lopata/observers/console_output_observer.rb
|
110
|
-
- lib/lopata/observers/group_tree.rb
|
111
110
|
- lib/lopata/observers/web_logger.rb
|
112
111
|
- lib/lopata/role.rb
|
113
112
|
- lib/lopata/runner.rb
|
@@ -139,5 +138,5 @@ requirements: []
|
|
139
138
|
rubygems_version: 3.2.15
|
140
139
|
signing_key:
|
141
140
|
specification_version: 4
|
142
|
-
summary: lopata-0.1.
|
141
|
+
summary: lopata-0.1.26
|
143
142
|
test_files: []
|
@@ -1,64 +0,0 @@
|
|
1
|
-
module Lopata
|
2
|
-
GroupTree = Struct.new(:group, :items, :title) do
|
3
|
-
def status
|
4
|
-
# return @status if @status
|
5
|
-
statuses = items.map(&:status).uniq
|
6
|
-
@status =
|
7
|
-
if statuses.length == 1
|
8
|
-
statuses.first
|
9
|
-
elsif statuses.include?(:failed)
|
10
|
-
:failed
|
11
|
-
elsif
|
12
|
-
statuses.first
|
13
|
-
end
|
14
|
-
@status
|
15
|
-
end
|
16
|
-
|
17
|
-
# Returns steps hierarhy: Group with nestet setps or groups
|
18
|
-
def self.steps_hierarhy(steps)
|
19
|
-
top = GroupTree.new(nil, [], '')
|
20
|
-
hierarhy = [top]
|
21
|
-
current_groups = []
|
22
|
-
steps.each do |step|
|
23
|
-
if step.groups == current_groups
|
24
|
-
hierarhy.last.items << step
|
25
|
-
else
|
26
|
-
# ensure hierarhy to is in current step tree - remove from hierary all groups not in new tree.
|
27
|
-
while hierarhy.last.group && !step.groups.include?(hierarhy.last.group)
|
28
|
-
hierarhy.pop
|
29
|
-
end
|
30
|
-
if hierarhy.last.group == step.groups.last
|
31
|
-
hierarhy.last.items << step
|
32
|
-
else
|
33
|
-
group_rest = step.groups.dup
|
34
|
-
while hierarhy.last.group && group_rest.first != hierarhy.last.group
|
35
|
-
group_rest.shift
|
36
|
-
end
|
37
|
-
group_rest.shift if group_rest.first == hierarhy.last.group
|
38
|
-
group_rest.each do
|
39
|
-
title = (hierarhy.map(&:group).compact + [_1]).map(&:title).join(': ')
|
40
|
-
group = GroupTree.new(_1, [], title)
|
41
|
-
hierarhy.last.items << group
|
42
|
-
hierarhy << group
|
43
|
-
end
|
44
|
-
hierarhy.last.items << step
|
45
|
-
end
|
46
|
-
current_groups = step.groups
|
47
|
-
end
|
48
|
-
end
|
49
|
-
return top
|
50
|
-
end
|
51
|
-
|
52
|
-
def walk_through(&block)
|
53
|
-
items.each do |step|
|
54
|
-
if step.is_a?(Lopata::StepExecution)
|
55
|
-
yield step
|
56
|
-
else # GroupTree
|
57
|
-
group = step
|
58
|
-
go_dipper = yield group
|
59
|
-
group.walk_through(&block) if go_dipper
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|