lopata 0.1.21 → 0.1.23

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 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: []