lopata 0.1.2 → 0.1.7
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/.yardopts +1 -0
- data/README.md +6 -2
- data/exe/lopata +1 -1
- data/lib/lopata.rb +52 -2
- data/lib/lopata/active_record.rb +105 -5
- data/lib/lopata/condition.rb +2 -1
- data/lib/lopata/configuration.rb +126 -0
- data/lib/lopata/environment.rb +36 -0
- data/lib/lopata/factory_bot.rb +52 -16
- data/lib/lopata/generators/app.rb +2 -2
- data/lib/lopata/generators/templates/Gemfile +0 -2
- data/lib/lopata/generators/templates/config/environments/qa.yml +0 -1
- data/lib/lopata/id.rb +1 -0
- data/lib/lopata/loader.rb +2 -0
- data/lib/lopata/observers.rb +1 -0
- data/lib/lopata/observers/backtrace_formatter.rb +16 -2
- data/lib/lopata/observers/base_observer.rb +17 -6
- data/lib/lopata/observers/console_output_observer.rb +30 -8
- data/lib/lopata/observers/web_logger.rb +30 -33
- data/lib/lopata/role.rb +91 -0
- data/lib/lopata/runner.rb +18 -21
- data/lib/lopata/scenario.rb +57 -6
- data/lib/lopata/scenario_builder.rb +250 -68
- data/lib/lopata/shared_step.rb +2 -0
- data/lib/lopata/step.rb +25 -23
- data/lib/lopata/version.rb +2 -1
- data/lib/lopata/world.rb +8 -12
- metadata +7 -8
- data/lib/lopata/config.rb +0 -97
- data/lib/lopata/generators/templates/.rspec +0 -3
- data/lib/lopata/generators/templates/spec/spec_helper.rb +0 -2
- data/lib/lopata/rspec/dsl.rb +0 -39
- data/lib/lopata/rspec/role.rb +0 -74
data/lib/lopata/shared_step.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
module Lopata
|
2
|
+
# @private
|
2
3
|
class SharedStep
|
3
4
|
attr_reader :name, :block
|
4
5
|
|
5
6
|
class NotFound < StandardError; end
|
6
7
|
|
8
|
+
|
7
9
|
def self.register(name, &block)
|
8
10
|
raise ArgumentError, "Comma is not allowed in shared step name: '%s'" % name if name =~ /,/
|
9
11
|
registry[name] = new(name, &block)
|
data/lib/lopata/step.rb
CHANGED
@@ -1,27 +1,23 @@
|
|
1
1
|
module Lopata
|
2
|
+
# @private
|
2
3
|
class Step
|
3
|
-
attr_reader :block, :args, :condition, :method_name, :shared_step
|
4
|
+
attr_reader :block, :args, :condition, :method_name, :shared_step
|
4
5
|
# metadata overrien by the step.
|
5
6
|
attr_accessor :metadata
|
6
7
|
|
7
|
-
def initialize(method_name, *args, condition: nil, shared_step: nil,
|
8
|
+
def initialize(method_name, *args, condition: nil, shared_step: nil, &block)
|
8
9
|
@method_name = method_name
|
9
10
|
@args = args
|
10
11
|
@block = block
|
11
12
|
@shared_step = shared_step
|
12
13
|
@condition = condition
|
13
|
-
@group = group
|
14
14
|
initialized! if defined? initialized!
|
15
15
|
end
|
16
16
|
|
17
17
|
def title
|
18
18
|
base_title = args.first
|
19
19
|
base_title ||= shared_step && "#{method_name.capitalize} #{shared_step.name}" || "Untitled #{method_name}"
|
20
|
-
|
21
|
-
"#{group.title}: #{base_title}"
|
22
|
-
else
|
23
|
-
base_title
|
24
|
-
end
|
20
|
+
base_title
|
25
21
|
end
|
26
22
|
|
27
23
|
def execution_steps(scenario, groups: [])
|
@@ -31,7 +27,8 @@ module Lopata
|
|
31
27
|
end
|
32
28
|
end
|
33
29
|
|
34
|
-
#
|
30
|
+
# @private
|
31
|
+
# Used for action, setup, teardown, verify
|
35
32
|
class ActionStep < Step
|
36
33
|
def execution_steps(scenario, groups: [])
|
37
34
|
steps = []
|
@@ -67,14 +64,11 @@ module Lopata
|
|
67
64
|
end
|
68
65
|
|
69
66
|
def title
|
70
|
-
|
71
|
-
"%s: %s" % [group.title, method_name]
|
72
|
-
else
|
73
|
-
shared_step && "#{method_name.capitalize} #{shared_step.name}" || "Untitled #{method_name}"
|
74
|
-
end
|
67
|
+
shared_step && "#{method_name.capitalize} #{shared_step.name}" || "Untitled #{method_name}"
|
75
68
|
end
|
76
69
|
end
|
77
70
|
|
71
|
+
# @private
|
78
72
|
# Used for context
|
79
73
|
class GroupStep < Step
|
80
74
|
|
@@ -88,22 +82,26 @@ module Lopata
|
|
88
82
|
steps.reject { |s| s.teardown_group?(self) } + steps.select { |s| s.teardown_group?(self) }
|
89
83
|
end
|
90
84
|
|
85
|
+
def let_methods
|
86
|
+
@let_methods ||= {}
|
87
|
+
end
|
88
|
+
|
91
89
|
private
|
92
90
|
|
93
91
|
# Group step's block is a block in context of builder, not scenario. So hide the @block to not be used in scenario.
|
94
92
|
def initialized!
|
95
93
|
builder = Lopata::ScenarioBuilder.new(title)
|
96
|
-
builder.group = self
|
97
94
|
builder.instance_exec(&@block)
|
98
95
|
@steps = builder.steps
|
99
96
|
@block = nil
|
100
97
|
end
|
101
98
|
end
|
102
99
|
|
100
|
+
#@private
|
103
101
|
class StepExecution
|
104
102
|
attr_reader :step, :status, :exception, :block, :pending_message, :groups
|
105
103
|
extend Forwardable
|
106
|
-
def_delegators :step, :
|
104
|
+
def_delegators :step, :method_name
|
107
105
|
|
108
106
|
class PendingStepFixedError < StandardError; end
|
109
107
|
|
@@ -115,9 +113,13 @@ module Lopata
|
|
115
113
|
@groups = groups
|
116
114
|
end
|
117
115
|
|
116
|
+
def title
|
117
|
+
group_title = groups.map { |g| "#{g.title}: " }.join
|
118
|
+
"#{group_title}#{step.title}"
|
119
|
+
end
|
120
|
+
|
118
121
|
def run(scenario)
|
119
122
|
@status = :running
|
120
|
-
world.notify_observers(:step_started, self)
|
121
123
|
begin
|
122
124
|
run_step(scenario)
|
123
125
|
if pending?
|
@@ -130,7 +132,6 @@ module Lopata
|
|
130
132
|
@status = :failed unless pending?
|
131
133
|
@exception = e
|
132
134
|
end
|
133
|
-
world.notify_observers(:step_finished, self)
|
134
135
|
end
|
135
136
|
|
136
137
|
def run_step(scenario)
|
@@ -138,10 +139,6 @@ module Lopata
|
|
138
139
|
scenario.instance_exec(&block)
|
139
140
|
end
|
140
141
|
|
141
|
-
def world
|
142
|
-
@world ||= Lopata::Config.world
|
143
|
-
end
|
144
|
-
|
145
142
|
def failed?
|
146
143
|
status == :failed
|
147
144
|
end
|
@@ -181,7 +178,12 @@ module Lopata
|
|
181
178
|
|
182
179
|
# Step metadata is a combination of metadata given for step and all contexts (groups) the step included
|
183
180
|
def metadata
|
184
|
-
([step]
|
181
|
+
(groups + [step]).compact.inject({}) { |merged, part| merged.merge(part.metadata) }
|
182
|
+
end
|
183
|
+
|
184
|
+
# Step methods is a combination of let_methods for all contexts (group) the step included
|
185
|
+
def let_methods
|
186
|
+
(groups).compact.inject({}) { |merged, part| merged.merge(part.let_methods) }
|
185
187
|
end
|
186
188
|
end
|
187
189
|
end
|
data/lib/lopata/version.rb
CHANGED
data/lib/lopata/world.rb
CHANGED
@@ -1,29 +1,25 @@
|
|
1
|
+
# Container for gobal non-configuration data
|
1
2
|
class Lopata::World
|
3
|
+
# Scenarios are selected for current run
|
4
|
+
# @return [Array<Lopata::Scenario::Execution>]
|
2
5
|
attr_reader :scenarios
|
3
6
|
|
7
|
+
# @private
|
4
8
|
def initialize
|
5
9
|
@scenarios = []
|
6
10
|
end
|
7
11
|
|
8
|
-
|
9
|
-
notify_observers(:started, self)
|
10
|
-
end
|
11
|
-
|
12
|
-
# Called at the end of test running.
|
13
|
-
#
|
14
|
-
# Notifies observers about testing finish
|
15
|
-
def finish
|
16
|
-
notify_observers(:finished, self)
|
17
|
-
end
|
18
|
-
|
12
|
+
# @private
|
19
13
|
def notify_observers(event, context)
|
20
14
|
observers.each do |observer|
|
21
15
|
observer.send event, context
|
22
16
|
end
|
23
17
|
end
|
24
18
|
|
19
|
+
private
|
20
|
+
|
25
21
|
# Define observers based on configuration
|
26
22
|
def observers
|
27
|
-
|
23
|
+
Lopata.configuration.observers
|
28
24
|
end
|
29
25
|
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.
|
4
|
+
version: 0.1.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexey Volochnev
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-06-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: httparty
|
@@ -87,20 +87,20 @@ executables:
|
|
87
87
|
extensions: []
|
88
88
|
extra_rdoc_files: []
|
89
89
|
files:
|
90
|
+
- ".yardopts"
|
90
91
|
- README.md
|
91
92
|
- exe/lopata
|
92
93
|
- lib/lopata.rb
|
93
94
|
- lib/lopata/active_record.rb
|
94
95
|
- lib/lopata/condition.rb
|
95
|
-
- lib/lopata/
|
96
|
+
- lib/lopata/configuration.rb
|
97
|
+
- lib/lopata/environment.rb
|
96
98
|
- lib/lopata/factory_bot.rb
|
97
99
|
- lib/lopata/generators/app.rb
|
98
|
-
- lib/lopata/generators/templates/.rspec
|
99
100
|
- lib/lopata/generators/templates/Gemfile
|
100
101
|
- lib/lopata/generators/templates/Lopatafile
|
101
102
|
- lib/lopata/generators/templates/config/environments/qa.yml
|
102
103
|
- lib/lopata/generators/templates/config/initializers/capybara.rb
|
103
|
-
- lib/lopata/generators/templates/spec/spec_helper.rb
|
104
104
|
- lib/lopata/id.rb
|
105
105
|
- lib/lopata/loader.rb
|
106
106
|
- lib/lopata/observers.rb
|
@@ -108,8 +108,7 @@ files:
|
|
108
108
|
- lib/lopata/observers/base_observer.rb
|
109
109
|
- lib/lopata/observers/console_output_observer.rb
|
110
110
|
- lib/lopata/observers/web_logger.rb
|
111
|
-
- lib/lopata/
|
112
|
-
- lib/lopata/rspec/role.rb
|
111
|
+
- lib/lopata/role.rb
|
113
112
|
- lib/lopata/runner.rb
|
114
113
|
- lib/lopata/scenario.rb
|
115
114
|
- lib/lopata/scenario_builder.rb
|
@@ -139,5 +138,5 @@ requirements: []
|
|
139
138
|
rubygems_version: 3.0.3
|
140
139
|
signing_key:
|
141
140
|
specification_version: 4
|
142
|
-
summary: lopata-0.1.
|
141
|
+
summary: lopata-0.1.7
|
143
142
|
test_files: []
|
data/lib/lopata/config.rb
DELETED
@@ -1,97 +0,0 @@
|
|
1
|
-
module Lopata
|
2
|
-
module Config
|
3
|
-
extend self
|
4
|
-
|
5
|
-
attr_accessor :build_number, :lopata_host, :lopata_code, :only_roles, :role_descriptions,
|
6
|
-
:default_role, :ops
|
7
|
-
|
8
|
-
def init(env)
|
9
|
-
require 'yaml'
|
10
|
-
@config = {}
|
11
|
-
config_filename = "./config/environments/#{env}.yml"
|
12
|
-
@config = YAML::load(File.open(config_filename)) if File.exists?(config_filename)
|
13
|
-
init_db
|
14
|
-
@role_descriptions ||= {}
|
15
|
-
# init_includes
|
16
|
-
end
|
17
|
-
|
18
|
-
def [](key)
|
19
|
-
@config[key]
|
20
|
-
end
|
21
|
-
|
22
|
-
%w{url name readonly}.each do |opt|
|
23
|
-
define_method opt do
|
24
|
-
raise "Lopata::Config unititlalized, use Lopata::Config#init(env) to set environment" unless @config
|
25
|
-
@config[opt]
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def init_db
|
30
|
-
ActiveRecord::Base.establish_connection(@config['db']) if @config['db']
|
31
|
-
end
|
32
|
-
|
33
|
-
def init_rspec
|
34
|
-
require 'lopata/rspec/dsl'
|
35
|
-
require 'lopata/rspec/role'
|
36
|
-
::RSpec.configure do |c|
|
37
|
-
c.include Lopata::RSpec::DSL
|
38
|
-
c.include Lopata::RSpec::Role
|
39
|
-
end
|
40
|
-
init_rspec_filters
|
41
|
-
end
|
42
|
-
|
43
|
-
def init_lopata_logging(build)
|
44
|
-
self.build_number = build
|
45
|
-
require 'lopata/observers/web_logger'
|
46
|
-
add_observer Lopata::Observers::WebLogger.new
|
47
|
-
end
|
48
|
-
|
49
|
-
def init_rspec_filters
|
50
|
-
filters = {}
|
51
|
-
filters[:focus] = true if ops[:focus]
|
52
|
-
unless filters.blank?
|
53
|
-
::RSpec.configure do |c|
|
54
|
-
c.inclusion_filter = filters
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
def before_start(&block)
|
60
|
-
@before_start = block
|
61
|
-
end
|
62
|
-
|
63
|
-
def before_scenario(*steps, &block)
|
64
|
-
before_scenario_steps.append(*steps) unless steps.empty?
|
65
|
-
before_scenario_steps.append(block) if block_given?
|
66
|
-
end
|
67
|
-
|
68
|
-
def before_scenario_steps
|
69
|
-
@before_scenario_steps ||= []
|
70
|
-
end
|
71
|
-
|
72
|
-
def after_scenario(*steps, &block)
|
73
|
-
after_scenario_steps.append(*steps) unless steps.empty?
|
74
|
-
after_scenario_steps.append(block) if block_given?
|
75
|
-
end
|
76
|
-
|
77
|
-
def after_scenario_steps
|
78
|
-
@after_scenario_steps ||= []
|
79
|
-
end
|
80
|
-
|
81
|
-
def initialize_test
|
82
|
-
@before_start.call if @before_start
|
83
|
-
end
|
84
|
-
|
85
|
-
def world
|
86
|
-
@world ||= Lopata::World.new
|
87
|
-
end
|
88
|
-
|
89
|
-
def filters
|
90
|
-
@filters ||= []
|
91
|
-
end
|
92
|
-
|
93
|
-
def add_observer(observer)
|
94
|
-
world.observers << observer
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
data/lib/lopata/rspec/dsl.rb
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
module Lopata
|
2
|
-
module RSpec
|
3
|
-
module DSL
|
4
|
-
def self.included(base)
|
5
|
-
base.extend(ClassMethods)
|
6
|
-
end
|
7
|
-
|
8
|
-
module ClassMethods
|
9
|
-
def action *contexts, &block
|
10
|
-
contexts.each do |context|
|
11
|
-
if context.is_a?(Proc)
|
12
|
-
action(&context)
|
13
|
-
else
|
14
|
-
verify context
|
15
|
-
end
|
16
|
-
end
|
17
|
-
before(:all, &block) if block_given?
|
18
|
-
end
|
19
|
-
|
20
|
-
def setup *contexts, &block
|
21
|
-
root_setup = false
|
22
|
-
unless @doing_setup
|
23
|
-
root_setup = true
|
24
|
-
@doing_setup = true
|
25
|
-
end
|
26
|
-
action *contexts, &block
|
27
|
-
if root_setup
|
28
|
-
# action Config.after_setup if Config.after_setup
|
29
|
-
@doing_setup = false
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def teardown &block
|
34
|
-
after(:all, &block) if block_given?
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
data/lib/lopata/rspec/role.rb
DELETED
@@ -1,74 +0,0 @@
|
|
1
|
-
module Lopata::RSpec::Role
|
2
|
-
def self.included(base)
|
3
|
-
base.extend(ClassMethods)
|
4
|
-
end
|
5
|
-
|
6
|
-
# Filter names
|
7
|
-
def self.filter_roles *names
|
8
|
-
allowed = Lopata::Config.only_roles
|
9
|
-
selected = names.flatten.select { |n| allowed.blank? || allowed.member?(n) }
|
10
|
-
# ENV['quick'] ? [selected.first] : selected
|
11
|
-
selected
|
12
|
-
end
|
13
|
-
|
14
|
-
# http://jorgemanrubia.net/2010/01/16/using-macros-to-create-custom-example-groups-in-rspec/
|
15
|
-
module ClassMethods
|
16
|
-
def as *names, &block
|
17
|
-
return if current_role && !Lopata::RSpec::Role.filter_roles(*names).include?(current_role)
|
18
|
-
if current_role
|
19
|
-
self.class_eval(&block)
|
20
|
-
else
|
21
|
-
Lopata::RSpec::Role.filter_roles(*names).each do |name|
|
22
|
-
example_group_class = describe role_description(name), :current_role => name do
|
23
|
-
define_method :current_role do
|
24
|
-
name
|
25
|
-
end
|
26
|
-
end
|
27
|
-
example_group_class.class_eval(&block)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def except(*names, &block)
|
33
|
-
raise "'expecpt' block must be neseted for 'as' block" unless current_role
|
34
|
-
return if names.include? current_role
|
35
|
-
self.class_eval(&block)
|
36
|
-
end
|
37
|
-
|
38
|
-
def current_role
|
39
|
-
metadata[:current_role]
|
40
|
-
end
|
41
|
-
|
42
|
-
# To be redefined in impelemntations so RSpec descriptions to be more verbal
|
43
|
-
def role_description(name)
|
44
|
-
Lopata::Config.role_descriptions[name] || name
|
45
|
-
end
|
46
|
-
|
47
|
-
def scenario(*args, &block)
|
48
|
-
raise "scenario required a name in first argument" unless args.first.is_a? String
|
49
|
-
example_group_class = describe(*args)
|
50
|
-
example_group_class.nested_with_as(*args, &block)
|
51
|
-
end
|
52
|
-
|
53
|
-
def nested_with_as(*args, &block)
|
54
|
-
if (args.last.is_a?(Hash) && args.last[:as])
|
55
|
-
roles = args.last[:as]
|
56
|
-
roles = [roles] unless roles.is_a?(Array)
|
57
|
-
class_eval { as(*roles, &block) }
|
58
|
-
else
|
59
|
-
class_eval(&block)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
module Lopata
|
66
|
-
# Adds the #scenario method to the top-level namespace.
|
67
|
-
def self.scenario(*args, &block)
|
68
|
-
raise "scenario required a name in first argument" unless args.first.is_a? String
|
69
|
-
example_group_class = RSpec.describe(*args)
|
70
|
-
example_group_class.nested_with_as(*args, &block)
|
71
|
-
# example_group_class.register
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|