lopata 0.1.3 → 0.1.8
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 +31 -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 -7
- data/lib/lopata/scenario_builder.rb +250 -68
- data/lib/lopata/shared_step.rb +2 -0
- data/lib/lopata/step.rb +27 -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,25 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
1
3
|
module Lopata
|
4
|
+
# @private
|
2
5
|
class Step
|
3
|
-
attr_reader :block, :args, :condition, :method_name, :shared_step
|
6
|
+
attr_reader :block, :args, :condition, :method_name, :shared_step
|
4
7
|
# metadata overrien by the step.
|
5
8
|
attr_accessor :metadata
|
6
9
|
|
7
|
-
def initialize(method_name, *args, condition: nil, shared_step: nil,
|
10
|
+
def initialize(method_name, *args, condition: nil, shared_step: nil, &block)
|
8
11
|
@method_name = method_name
|
9
12
|
@args = args
|
10
13
|
@block = block
|
11
14
|
@shared_step = shared_step
|
12
15
|
@condition = condition
|
13
|
-
@group = group
|
14
16
|
initialized! if defined? initialized!
|
15
17
|
end
|
16
18
|
|
17
19
|
def title
|
18
20
|
base_title = args.first
|
19
21
|
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
|
22
|
+
base_title
|
25
23
|
end
|
26
24
|
|
27
25
|
def execution_steps(scenario, groups: [])
|
@@ -31,7 +29,8 @@ module Lopata
|
|
31
29
|
end
|
32
30
|
end
|
33
31
|
|
34
|
-
#
|
32
|
+
# @private
|
33
|
+
# Used for action, setup, teardown, verify
|
35
34
|
class ActionStep < Step
|
36
35
|
def execution_steps(scenario, groups: [])
|
37
36
|
steps = []
|
@@ -67,14 +66,11 @@ module Lopata
|
|
67
66
|
end
|
68
67
|
|
69
68
|
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
|
69
|
+
shared_step && "#{method_name.capitalize} #{shared_step.name}" || "Untitled #{method_name}"
|
75
70
|
end
|
76
71
|
end
|
77
72
|
|
73
|
+
# @private
|
78
74
|
# Used for context
|
79
75
|
class GroupStep < Step
|
80
76
|
|
@@ -88,22 +84,26 @@ module Lopata
|
|
88
84
|
steps.reject { |s| s.teardown_group?(self) } + steps.select { |s| s.teardown_group?(self) }
|
89
85
|
end
|
90
86
|
|
87
|
+
def let_methods
|
88
|
+
@let_methods ||= {}
|
89
|
+
end
|
90
|
+
|
91
91
|
private
|
92
92
|
|
93
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
94
|
def initialized!
|
95
95
|
builder = Lopata::ScenarioBuilder.new(title)
|
96
|
-
builder.group = self
|
97
96
|
builder.instance_exec(&@block)
|
98
97
|
@steps = builder.steps
|
99
98
|
@block = nil
|
100
99
|
end
|
101
100
|
end
|
102
101
|
|
102
|
+
#@private
|
103
103
|
class StepExecution
|
104
104
|
attr_reader :step, :status, :exception, :block, :pending_message, :groups
|
105
105
|
extend Forwardable
|
106
|
-
def_delegators :step, :
|
106
|
+
def_delegators :step, :method_name
|
107
107
|
|
108
108
|
class PendingStepFixedError < StandardError; end
|
109
109
|
|
@@ -115,9 +115,13 @@ module Lopata
|
|
115
115
|
@groups = groups
|
116
116
|
end
|
117
117
|
|
118
|
+
def title
|
119
|
+
group_title = groups.map { |g| "#{g.title}: " }.join
|
120
|
+
"#{group_title}#{step.title}"
|
121
|
+
end
|
122
|
+
|
118
123
|
def run(scenario)
|
119
124
|
@status = :running
|
120
|
-
world.notify_observers(:step_started, self)
|
121
125
|
begin
|
122
126
|
run_step(scenario)
|
123
127
|
if pending?
|
@@ -130,7 +134,6 @@ module Lopata
|
|
130
134
|
@status = :failed unless pending?
|
131
135
|
@exception = e
|
132
136
|
end
|
133
|
-
world.notify_observers(:step_finished, self)
|
134
137
|
end
|
135
138
|
|
136
139
|
def run_step(scenario)
|
@@ -138,10 +141,6 @@ module Lopata
|
|
138
141
|
scenario.instance_exec(&block)
|
139
142
|
end
|
140
143
|
|
141
|
-
def world
|
142
|
-
@world ||= Lopata::Config.world
|
143
|
-
end
|
144
|
-
|
145
144
|
def failed?
|
146
145
|
status == :failed
|
147
146
|
end
|
@@ -181,7 +180,12 @@ module Lopata
|
|
181
180
|
|
182
181
|
# Step metadata is a combination of metadata given for step and all contexts (groups) the step included
|
183
182
|
def metadata
|
184
|
-
([step]
|
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) }
|
185
189
|
end
|
186
190
|
end
|
187
191
|
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.8
|
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-25 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.8
|
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
|
-
|