lopata 0.1.21 → 0.1.23

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c89f9dfc95a2a0586323e2fd682d971f619f8f47cba620c2846035af7a8d3736
4
- data.tar.gz: ba2c2067b9cbce8691899cc5ba0a76c34295f54d1bb5bacea6234ac7b4756a46
3
+ metadata.gz: 9404c01f3020e012451ba5cd5c6d91fbec443df94fe961ad9159e296f5783775
4
+ data.tar.gz: 16523f8e209f6864370912267f5e26955e1cc07708cfc7f31b2d4f324c0a2aec
5
5
  SHA512:
6
- metadata.gz: 0eada79585b1ca222a2ba29dacdecfb094cc32e50b21406e2e59e9326a8ad6f0463eff8f9772074d3f27bd2442a67efe233c3c08661ab3284b7b4cd71b069864
7
- data.tar.gz: 1003113a61e1ec7093c7f6eab47e49ee87ab0ec7b267a593afe9c3b0625f095ce7ee024188837d7ec21e987e4437e7b26f42b8cdfc2370b6b813aacb9b2651b1
6
+ metadata.gz: 2c81b2e83e0df4838d7743dccdc6c79ef689ccb0d8a1caed6bf3ba3ecfd228041841b531881390a5efe369cc05d681feab919b0d0acebea8d48a065c36e0c6be
7
+ data.tar.gz: 363b3ea67a91e50ead1d51eb23c50856e9a5a8f2a0f524f56fbabd9f72d3c1b5cb4b7254b9bcf6bcc4fbaef57024ffe6a207bb52d277f8eb96e1a3723d1346fc
@@ -1,14 +1,19 @@
1
1
  module Lopata
2
2
  # @private
3
3
  class Condition
4
- attr_reader :condition, :positive
4
+ attr_reader :condition, :positive, :dynamic
5
5
  def initialize(condition, positive: true)
6
6
  @condition, @positive = condition, positive
7
+ @dynamic = @condition.is_a?(Proc)
7
8
  end
8
9
 
9
10
  alias positive? positive
11
+ alias dynamic? dynamic
10
12
 
13
+ # Match scenario on build-time.
11
14
  def match?(scenario)
15
+ # dynamic steps match scenario in build-time: will be verified later
16
+ return true if dynamic?
12
17
  matched = match_metadata?(scenario)
13
18
  positive? ? matched : !matched
14
19
  end
@@ -33,5 +38,10 @@ module Lopata
33
38
  end
34
39
  end
35
40
 
41
+ def match_dynamic?(scenario_runtime)
42
+ return false unless dynamic?
43
+ matched = scenario_runtime.instance_exec(&condition)
44
+ positive? ? matched : !matched
45
+ end
36
46
  end
37
47
  end
@@ -1,4 +1,5 @@
1
1
  require_relative 'backtrace_formatter'
2
+ require_relative 'group_tree'
2
3
  require 'forwardable'
3
4
 
4
5
  module Lopata
@@ -34,9 +35,20 @@ module Lopata
34
35
  statuses[scenario.status] += 1
35
36
 
36
37
  if scenario.failed?
37
- scenario.steps.each do |step|
38
- puts colored(" #{status_marker(step.status)} #{step.title}", step.status)
39
- puts indent(4, backtrace_formatter.error_message(step.exception, include_backtrace: true)) if step.failed?
38
+ GroupTree.steps_hierarhy(scenario.steps).walk_through do |step|
39
+ if step.is_a?(Lopata::StepExecution)
40
+ next unless step.loggable?
41
+ puts colored(" #{status_marker(step.status)} #{step.title}", step.status)
42
+ puts indent(4, backtrace_formatter.error_message(step.exception, include_backtrace: true)) if step.failed?
43
+ else # GroupTree
44
+ group = step
45
+ if %i{ passed skipped }.include?(group.status)
46
+ puts colored(" #{status_marker(group.status)} #{group.title}", group.status)
47
+ false
48
+ else
49
+ true
50
+ end
51
+ end
40
52
  end
41
53
  end
42
54
 
@@ -0,0 +1,64 @@
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
@@ -1,6 +1,7 @@
1
1
  require 'httparty'
2
2
  require 'json'
3
3
  require_relative 'backtrace_formatter'
4
+ require_relative 'group_tree'
4
5
 
5
6
  module Lopata
6
7
  module Observers
@@ -48,7 +49,24 @@ module Lopata
48
49
 
49
50
  def add_attempt(scenario, finished)
50
51
  status = scenario.failed? ? Lopata::FAILED : Lopata::PASSED
51
- steps = scenario.steps.map { |s| step_hash(s) }
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) }
52
70
  request = { status: status, steps: steps, launch: { id: @launch_id, finished: finished } }
53
71
  test = test_id(scenario)
54
72
  post("/tests/#{test}/attempts.json", body: request)
@@ -67,6 +85,10 @@ module Lopata
67
85
  hash
68
86
  end
69
87
 
88
+ def group_hash(group)
89
+ { status: group.status, title: group.title }
90
+ end
91
+
70
92
  def test_id(scenario)
71
93
  request = {
72
94
  test: {
@@ -90,7 +90,17 @@ class Lopata::Scenario
90
90
  end
91
91
 
92
92
  def run_step(step)
93
- return if step.skipped?
93
+ return if step.skipped? || step.ignored?
94
+ groups = step.groups
95
+ if groups.length > 0 && groups != @current_groups
96
+ @current_groups = groups
97
+ condition = groups.last.condition
98
+ if condition&.dynamic? && !condition.match_dynamic?(scenario)
99
+ step.ignored!
100
+ ignore_groups(groups)
101
+ return
102
+ end
103
+ end
94
104
  @current_step = step
95
105
  step.run(scenario)
96
106
  skip_rest if step.failed? && step.skip_rest_on_failure?
@@ -113,6 +123,10 @@ class Lopata::Scenario
113
123
  steps.select { |s| s.status == :not_runned && !s.teardown? }.each(&:skip!)
114
124
  end
115
125
 
126
+ def ignore_groups(groups)
127
+ steps.select { _1.status == :not_runned && _1.groups.take(groups.length) == groups }.each(&:ignored!)
128
+ end
129
+
116
130
  def metadata
117
131
  if current_step
118
132
  @metadata.merge(current_step.metadata)
@@ -145,7 +159,6 @@ class Lopata::Scenario
145
159
  let_base[method_name] = LetBangMethod.new(&block)
146
160
  end
147
161
 
148
-
149
162
  def cleanup
150
163
  @title = nil
151
164
  @metadata = nil
data/lib/lopata/step.rb CHANGED
@@ -25,7 +25,7 @@ module Lopata
25
25
  def execution_steps(scenario, groups: [])
26
26
  return [] if condition && !condition.match?(scenario)
27
27
  return [] unless block
28
- [StepExecution.new(self, groups, &block)]
28
+ [StepExecution.new(self, groups, condition: condition, &block)]
29
29
  end
30
30
  end
31
31
 
@@ -39,13 +39,14 @@ module Lopata
39
39
  if step.is_a?(String)
40
40
  Lopata::SharedStep.find(step).steps.each do |shared_step|
41
41
  next if shared_step.condition && !shared_step.condition.match?(scenario)
42
- steps += shared_step.execution_steps(scenario, groups: groups)
42
+ shared_group = SharedGroupStep.new(:shared_step)
43
+ steps += shared_step.execution_steps(scenario, groups: groups + [shared_group])
43
44
  end
44
45
  elsif step.is_a?(Proc)
45
- steps << StepExecution.new(self, groups, &step)
46
+ steps << StepExecution.new(self, groups, condition: condition, &step)
46
47
  end
47
48
  end
48
- steps << StepExecution.new(self, groups, &block) if block
49
+ steps << StepExecution.new(self, groups, condition: condition, &block) if block
49
50
  steps.reject { |s| !s.block }
50
51
  end
51
52
 
@@ -103,30 +104,48 @@ module Lopata
103
104
  end
104
105
  end
105
106
 
107
+ # @private
108
+ # Fake group for shared step instance
109
+ # Used to build group hierarhy including chared steps
110
+ class SharedGroupStep < Step
111
+ # stub title - should not be used in scenario/step name generation.
112
+ def title
113
+ ''
114
+ end
115
+ end
116
+
106
117
  #@private
107
118
  class StepExecution
108
- attr_reader :step, :status, :exception, :block, :pending_message, :groups
119
+ attr_reader :step, :status, :exception, :block, :pending_message, :groups, :condition
109
120
  extend Forwardable
110
121
  def_delegators :step, :method_name
111
122
 
112
123
  class PendingStepFixedError < StandardError; end
113
124
 
114
- def initialize(step, groups, &block)
125
+ def initialize(step, groups, condition: nil, &block)
115
126
  @step = step
116
127
  @status = :not_runned
117
128
  @exception = nil
118
129
  @block = block
119
130
  @groups = groups
131
+ @condition = condition
120
132
  end
121
133
 
122
134
  def title
123
- group_title = groups.map { |g| "#{g.title}: " }.join
124
135
  "#{group_title}#{step.title}"
125
136
  end
126
137
 
138
+ def group_title
139
+ groups.map { |g| "#{g.title}: " }.join
140
+ end
141
+
127
142
  def run(scenario)
128
143
  @status = :running
129
144
  begin
145
+ unless check_dynamic_condition?(scenario)
146
+ @status = :ignored
147
+ return
148
+ end
130
149
  run_step(scenario)
131
150
  if pending?
132
151
  @status = :failed
@@ -145,6 +164,22 @@ module Lopata
145
164
  scenario.instance_exec(&block)
146
165
  end
147
166
 
167
+ def check_dynamic_condition?(scenario)
168
+ dynamic_conditions.each do
169
+ return false unless _1.match_dynamic?(scenario)
170
+ end
171
+ true
172
+ end
173
+
174
+ def dynamic_conditions
175
+ conds = []
176
+ conds << condition if condition&.dynamic?
177
+ groups.each do
178
+ conds << _1.condition if _1.condition&.dynamic?
179
+ end
180
+ conds
181
+ end
182
+
148
183
  def failed?
149
184
  status == :failed
150
185
  end
@@ -157,6 +192,14 @@ module Lopata
157
192
  status == :skipped
158
193
  end
159
194
 
195
+ def ignored?
196
+ status == :ignored
197
+ end
198
+
199
+ def ignored!
200
+ status == :ignored
201
+ end
202
+
160
203
  def skip!
161
204
  @status = :skipped
162
205
  end
@@ -170,6 +213,12 @@ module Lopata
170
213
  @pending_message = message
171
214
  end
172
215
 
216
+ # Need log this step.
217
+ def loggable?
218
+ return false if ignored?
219
+ not %i{ let let! }.include?(method_name)
220
+ end
221
+
173
222
  def teardown?
174
223
  %i{ teardown cleanup }.include?(method_name)
175
224
  end
@@ -178,6 +227,10 @@ module Lopata
178
227
  teardown? && self.groups.last == group
179
228
  end
180
229
 
230
+ def in_group?(group)
231
+ groups.include?(group)
232
+ end
233
+
181
234
  def skip_rest_on_failure?
182
235
  %i{ setup action }.include?(method_name)
183
236
  end
@@ -1,6 +1,6 @@
1
1
  module Lopata
2
2
  # @private
3
3
  module Version
4
- STRING = '0.1.21'
4
+ STRING = '0.1.23'
5
5
  end
6
6
  end
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.21
4
+ version: 0.1.23
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-08-09 00:00:00.000000000 Z
11
+ date: 2023-09-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -107,6 +107,7 @@ 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
110
111
  - lib/lopata/observers/web_logger.rb
111
112
  - lib/lopata/role.rb
112
113
  - lib/lopata/runner.rb
@@ -138,5 +139,5 @@ requirements: []
138
139
  rubygems_version: 3.2.15
139
140
  signing_key:
140
141
  specification_version: 4
141
- summary: lopata-0.1.21
142
+ summary: lopata-0.1.23
142
143
  test_files: []