lopata 0.1.6 → 0.1.7

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: 51ff4a162c7617388f8856b342449e1475f2438d8a44a6c58c6168373b144969
4
- data.tar.gz: 10580190d2a63826f971d1730523eacc34ed818b634329da1635db07d2627d27
3
+ metadata.gz: 7f4b4814d88cd3b9da3a34159e3c1c977d05cbb0504d3dc0b2ab8034044dfbf0
4
+ data.tar.gz: 378e5a3c346c64cb4430577dcfab31cfefd54a2c8e8ee30046609cf10e1bdba4
5
5
  SHA512:
6
- metadata.gz: 76f4fffc7d6755eb63d45a3297177c25b2e947c101dfad38b7a39e8bb474f00e3874d3b3fcf939a81d3ad550cc7d18335ac998104f0b0436db239d1f4688a0f5
7
- data.tar.gz: '086e6cb580e94035e78607daa4a5ba6a5caf2211e37bc0e5cd9aa7cb1e2579fc22889e6fb90e17e6b4f290016a70d76f86d1d93d307d19e964b7584a3bee0451'
6
+ metadata.gz: ff0498d9c9b665d52f5a8d1e65cdc6dc9078f0df1cd4f7fd831393af04ee564a5cf9a9f55305bd4423ff92062cdb7fd4a728bb2be657f196f91447faddffa941
7
+ data.tar.gz: 063a3914c5e5dd088ad56e37ea527c540e8dc82f0d56e7dca4564e61699541000e4d801a80898b2d89eb6719cfd4d1a887d3884a52335f0e6339ffc9a91569fb
@@ -0,0 +1 @@
1
+ --no-private
@@ -6,6 +6,7 @@ require 'lopata/scenario'
6
6
  require 'lopata/step'
7
7
  require 'lopata/shared_step'
8
8
 
9
+ # Namespace for all Lopata code.
9
10
  module Lopata
10
11
  # Define the scenario.
11
12
  # @see Lopata::ScenarioBuilder.define
@@ -34,7 +35,7 @@ module Lopata
34
35
  # end
35
36
  # end
36
37
  # @param name [String] shared step unique name
37
- # @param block shared step action sequence definition
38
+ # @param block [Block] shared step action sequence definition
38
39
  def self.shared_step(name, &block)
39
40
  Lopata::SharedStep.register(name, &block)
40
41
  end
@@ -71,6 +71,39 @@ module Lopata
71
71
  def reload(*objects)
72
72
  objects.flatten.compact.each(&:reload)
73
73
  end
74
+
75
+ # Marks object to be destroyed at the end of scenario
76
+ #
77
+ # @param object [ActiveRecord::Base] the object to be destoryed at the end of scenario
78
+ # @return the given object, so chains can be build
79
+ def cleanup_later(object)
80
+ return nil unless object
81
+ @created_objects ||= []
82
+ @created_objects << object
83
+ object
84
+ end
85
+
86
+ # Find ActiveRecord object of given class by params.
87
+ # Marks the returned object to be destroyed at the end of scenario.
88
+ #
89
+ # @example
90
+ # action do
91
+ # # UI actions creating the user
92
+ # @user = find_created(User, username: 'testuser')
93
+ # end
94
+ # it 'created' do
95
+ # expect(@user).to_not be_nil
96
+ # end
97
+ # # No cleanup needed
98
+ # # cleanup :user
99
+ #
100
+ # @param cls [Class] active record model class
101
+ # @param params [Hash] options for record finding
102
+ # @return [ActiveRecord::Base, nil] the object or nil if not found
103
+ # @see #cleanup_later called on the hood
104
+ def find_created(cls, params)
105
+ cleanup_later cls.where(params).take
106
+ end
74
107
  end
75
108
 
76
109
  # To be included in Lopata::ScenarioBuilder. The methods may be used in build time.
@@ -92,6 +125,10 @@ module Lopata
92
125
  end
93
126
  end
94
127
 
128
+ Lopata.configure do |c|
129
+ c.after_scenario { cleanup @created_objects }
130
+ end
131
+
95
132
  params = Lopata.environment['db']
96
133
  ActiveRecord::Base.establish_connection(params) if params
97
134
 
@@ -1,23 +1,63 @@
1
1
  require_relative 'active_record'
2
2
 
3
3
  module Lopata
4
+ # Helpers for FactoryBot usage in tests.
5
+ #
6
+ # Make helpers available in scenarios by
7
+ #
8
+ # require 'lopata/factory_bot'
9
+ #
10
+ # Automatically adds ActiveRecord helpers.
11
+ # @see Lopata::ActiveRecord
12
+ #
13
+ # Allows to create ActiveRecord object by FactoryBot definitions.
14
+ # All the objects created by FactoryBot helpers will be destroyed automatically
15
+ # at the end of scenario.
16
+ # @see Lopata::ActiveRecord::Methods#cleanup
17
+ #
18
+ # @example
19
+ #
20
+ # # Configure db connection at config/environments/qa.yml like rails:
21
+ # # db:
22
+ # # adapter: postgresql
23
+ # # host: your.database.host
24
+ # # username: username
25
+ # # password: password
26
+ # # database: database
27
+ # require 'active_record'
28
+ # require 'factory_bot'
29
+ # require 'lopata/facotory_bot'
30
+ #
31
+ # class User < ActiveRecord::Base; end
32
+ #
33
+ # FactoryBot.define do
34
+ # factory :user do
35
+ # username { 'testuser' }
36
+ # end
37
+ # end
38
+ #
39
+ # Lopata.define 'User creation' do
40
+ # setup do
41
+ # @user = create(:user)
42
+ # end
43
+ # # No cleanup needed - @user will be destroyed automatically
44
+ # # cleanup :user
45
+ #
46
+ # it 'works' do
47
+ # expect(@user).to_not be_nil
48
+ # end
49
+ # end
50
+ #
4
51
  module FactoryBot
5
52
  # To be included in Lopata::Scenario
6
53
  module Methods
54
+ # Wrapper for FactoryBot#create
55
+ # Calls the FactoryBot#create with given paramters and returns it result.
56
+ # Additionally store the created object for destroying at the end of scenario.
57
+ # @see Lopata::ActiveRecord::Methods#cleanup
7
58
  def create(*params)
8
59
  cleanup_later ::FactoryBot.create(*params)
9
60
  end
10
-
11
- def find_created(cls, params)
12
- cleanup_later cls.where(params).take
13
- end
14
-
15
- def cleanup_later(object)
16
- return nil unless object
17
- @created_objects ||= []
18
- @created_objects << object
19
- object
20
- end
21
61
  end
22
62
 
23
63
  # To be included in Lopata::ScenarioBuilder
@@ -29,8 +69,4 @@ end
29
69
  Lopata::Scenario.include Lopata::FactoryBot::Methods
30
70
  Lopata::ScenarioBuilder.include Lopata::FactoryBot::DSL
31
71
 
32
- Lopata.configure do |c|
33
- c.after_scenario { cleanup @created_objects }
34
- end
35
-
36
72
  ::FactoryBot.find_definitions
@@ -1,5 +1,7 @@
1
1
  module Lopata
2
+ # @private
2
3
  module Generators
4
+ # @private
3
5
  class App < Thor::Group
4
6
  include Thor::Actions
5
7
  argument :name
@@ -1,4 +1,5 @@
1
1
  module Lopata
2
+ # @private
2
3
  module Id
3
4
  extend self
4
5
 
@@ -1,3 +1,4 @@
1
+ # @private
1
2
  module Lopata::Loader
2
3
  extend self
3
4
 
@@ -20,6 +21,7 @@ module Lopata::Loader
20
21
  Dir["scenarios/**/*.rb"].each { |f| load File.expand_path(f) }
21
22
  end
22
23
 
24
+ # Loads all shared steps from predefined paths
23
25
  def load_shared_steps
24
26
  Dir["shared_steps/**/*rb"].each { |f| load File.expand_path(f) }
25
27
  end
@@ -1,3 +1,4 @@
1
+ # @private
1
2
  module Lopata::Observers
2
3
  autoload :BaseObserver, 'lopata/observers/base_observer.rb'
3
4
  autoload :ConsoleOutputObserver, 'lopata/observers/console_output_observer.rb'
@@ -39,7 +39,7 @@ module Lopata
39
39
 
40
40
  # Extracts error message from excetion
41
41
  #
42
- # @param exeption [Exception]
42
+ # @param exception [Exception]
43
43
  # @param include_backtrace [Boolean] whether to add formatted backtrace to output
44
44
  # @return [String] error message from excetion, incuding source code line.
45
45
  def error_message(exception, include_backtrace: false)
@@ -21,12 +21,12 @@ module Lopata
21
21
  end
22
22
 
23
23
  # Called before single scenario execution.
24
- # @param world [Lopata::Scenario::Execution]
24
+ # @param scenario [Lopata::Scenario::Execution]
25
25
  def scenario_started(scenario)
26
26
  end
27
27
 
28
28
  # Called after single scenario execution.
29
- # @param world [Lopata::Scenario::Execution]
29
+ # @param scenario [Lopata::Scenario::Execution]
30
30
  def scenario_finished(scenario)
31
31
  end
32
32
  end
@@ -19,9 +19,13 @@ module Lopata
19
19
  end
20
20
  end
21
21
 
22
+ # @private
22
23
  PASSED = 0
24
+ # @private
23
25
  FAILED = 1
26
+ # @private
24
27
  PENDING = 2
28
+ # @private
25
29
  SKIPPED = 5
26
30
 
27
31
  # @private
@@ -1,9 +1,33 @@
1
1
  module Lopata
2
+ # Adds ability to run scenarios by given user roles
3
+ #
4
+ # @example Usage
5
+ # require 'lopata/role'
6
+ # Lopata.configure do |c|
7
+ # c.role_descriptions = {
8
+ # user: 'User',
9
+ # admin: 'Admin'
10
+ # }
11
+ # c.default_role = :user
12
+ # c.before_scenaro 'setup user'
13
+ # end
14
+ # Lopata.shared_step 'setup user' do
15
+ # setup { @user = User.create(role: current_role) if current_role }
16
+ # cleanup :user
17
+ # end
18
+ # Lopata.define 'login' do
19
+ # # will generate 2 scenarios, one for :user and one for :admin
20
+ # as :user, :admin
21
+ # action 'login'
22
+ # # verify the user is logged in
23
+ # end
24
+ #
2
25
  # @see Lopata::Configuration#role_descriptions
3
26
  # @see Lopata::Configuration#default_role
4
27
  module Role
5
28
  # To be included in Lopata::Scenario
6
29
  module Methods
30
+ # @return [Symbol, nil] user role for current scenario or nil, if scenario is running without user.
7
31
  def current_role
8
32
  metadata[:as]
9
33
  end
@@ -11,30 +35,50 @@ module Lopata
11
35
 
12
36
  # To be included in Lopata::ScenarioBuilder
13
37
  module DSL
38
+ # Enumerate the roles the scenario to be runned under.
39
+ # If not invoked the default role only will be used.
40
+ #
41
+ # The scenario should be set to use the role via before_scenario step using #current_role param.
42
+ #
43
+ # @param args [Array<Symbol>] list of roles the scenario to be runned with.
44
+ # @param block [Block] the block to calculate role from scenario metadata.
14
45
  def as(*args, &block)
15
46
  @roles = args.flatten
16
47
  @roles << Lopata::ScenarioBuilder::CalculatedValue.new(&block) if block_given?
17
48
  @role_options = nil
18
49
  end
19
50
 
51
+ # @private
20
52
  def role_options
21
53
  @role_options ||= build_role_options
22
54
  end
23
55
 
56
+ # Marks scenario to be runned without user.
57
+ #
58
+ # @example
59
+ # Lopata.define 'scenario withou user' do
60
+ # without_user
61
+ # it 'does not define the user' do
62
+ # expect(current_role).to be_nil
63
+ # end
64
+ # end
24
65
  def without_user
25
66
  @without_user = true
26
67
  end
27
68
 
69
+ # @private
28
70
  def build_role_options
29
71
  return [] unless roles
30
72
  [Lopata::ScenarioBuilder::Diagonal.new(:as, roles.map { |r| [Lopata.configuration.role_descriptions[r], r] })]
31
73
  end
32
74
 
75
+ # @private
33
76
  def roles
34
77
  return false if @without_user
35
78
  @roles ||= [Lopata.configuration.default_role].compact
36
79
  end
37
80
 
81
+ # @private
38
82
  def diagonals
39
83
  super + role_options
40
84
  end
@@ -43,4 +87,5 @@ module Lopata
43
87
  end
44
88
 
45
89
  Lopata::Scenario.include Lopata::Role::Methods
90
+ # Prepend the module to overload #diagonals method
46
91
  Lopata::ScenarioBuilder.prepend Lopata::Role::DSL
@@ -7,6 +7,7 @@ require_relative 'observers'
7
7
  require_relative 'condition'
8
8
 
9
9
  module Lopata
10
+ # @private
10
11
  class Runner < Thor
11
12
  desc 'test', 'Run tests'
12
13
  option :env, default: :qa, aliases: 'e'
@@ -14,13 +15,14 @@ module Lopata
14
15
  option :keep, type: :boolean, aliases: 'k'
15
16
  option :text, aliases: 't'
16
17
  def test(*args)
18
+ trap_interrupt
17
19
  configure_from_options
18
20
  Lopata::Loader.load_shared_steps
19
21
  Lopata::Loader.load_scenarios(*args)
20
22
  world = Lopata.world
21
- world.start
23
+ world.notify_observers(:started, world)
22
24
  world.scenarios.each { |s| s.run }
23
- world.finish
25
+ world.notify_observers(:finished, world)
24
26
  end
25
27
 
26
28
  default_task :test
@@ -51,6 +53,10 @@ module Lopata
51
53
  to_rerun = Lopata::Client.new.to_rerun
52
54
  Lopata.configuration.filters << -> (scenario) { to_rerun.include?(scenario.title) }
53
55
  end
56
+
57
+ def trap_interrupt
58
+ trap('INT') { exit!(1) }
59
+ end
54
60
  end
55
61
  end
56
62
  end
@@ -1,25 +1,41 @@
1
1
  require 'rspec/expectations'
2
2
 
3
+ # Scenario runtime class.
4
+ #
5
+ # All the scenarios are running in context of separate Lopata::Scenario object.
6
+ #
3
7
  class Lopata::Scenario
4
8
  include RSpec::Matchers
5
9
 
10
+ # @private
6
11
  attr_reader :execution
7
12
 
13
+ # @private
8
14
  def initialize(execution)
9
15
  @execution = execution
10
16
  end
11
17
 
12
18
  # Marks current step as pending
19
+ # @example
20
+ # it 'pending step' do
21
+ # pending
22
+ # expect(1).to eq 2
23
+ # end
24
+ #
25
+ # Pending steps wont be failed
13
26
  def pending(message = nil)
14
27
  execution.current_step.pending!(message)
15
28
  end
16
29
 
30
+ # @return [Hash] metadata available for current step
31
+ # @note The metadata keys also availalbe as methods (via method_missing)
17
32
  def metadata
18
33
  execution.metadata
19
34
  end
20
35
 
21
36
  private
22
37
 
38
+ # @private
23
39
  def method_missing(method, *args, &block)
24
40
  if execution.let_methods.include?(method)
25
41
  instance_exec(*args, &execution.let_methods[method])
@@ -30,10 +46,13 @@ class Lopata::Scenario
30
46
  end
31
47
  end
32
48
 
49
+ # @private
33
50
  def respond_to_missing?(method, *)
34
51
  execution.let_methods.include?(method) or metadata.keys.include?(method) or super
35
52
  end
36
53
 
54
+ # @private
55
+ # Scenario execution and live-cycle information
37
56
  class Execution
38
57
  attr_reader :scenario, :status, :steps, :title, :current_step
39
58
 
@@ -1,19 +1,39 @@
1
+ # Context for scenario creation.
1
2
  class Lopata::ScenarioBuilder
3
+ # @private
2
4
  attr_reader :title, :common_metadata, :options, :diagonals
5
+ # @private
3
6
  attr_accessor :shared_step, :group
4
7
 
8
+ # Defines one or more scenarios.
9
+ #
10
+ # @example
11
+ # Lopata.define 'scenario' do
12
+ # setup 'test user'
13
+ # action 'login'
14
+ # verify 'home page displayed'
15
+ # end
16
+ #
17
+ # Given block will be calculated in context of the ScenarioBuilder
18
+ #
19
+ # @param title [String] scenario unique title
20
+ # @param metadata [Hash] metadata to be used within the scenario
21
+ # @param block [Block] the scenario definition
22
+ # @see Lopata.define
5
23
  def self.define(title, metadata = {}, &block)
6
24
  builder = new(title, metadata)
7
25
  builder.instance_exec &block
8
26
  builder.build
9
27
  end
10
28
 
29
+ # @private
11
30
  def initialize(title, metadata = {})
12
31
  @title, @common_metadata = title, metadata
13
32
  @diagonals = []
14
33
  @options = []
15
34
  end
16
35
 
36
+ # @private
17
37
  def build
18
38
  filters = Lopata.configuration.filters
19
39
  option_combinations.each do |option_set|
@@ -33,21 +53,104 @@ class Lopata::ScenarioBuilder
33
53
  end
34
54
  end
35
55
 
56
+ # @!group Defining variants
57
+
58
+ # Define option for the scenario.
59
+ #
60
+ # The scenario will be generated for all the options.
61
+ # If more then one option given, the scenarios for all options combinations will be generated.
62
+ #
63
+ # @param metadata_key [Symbol] the key to access option data via metadata.
64
+ # @param variants [Hash{String => Object}] variants for the option
65
+ # Keys are titles of the variant, values are metadata values.
66
+ #
67
+ # @example
68
+ # Lopata.define 'scenario' do
69
+ # option :one, 'one' => 1, 'two' => 2
70
+ # option :two, 'two' => 2, 'three' => 3
71
+ # # will generate 4 scenarios:
72
+ # # - 'scenario one two'
73
+ # # - 'scenario one three'
74
+ # # - 'scenario two two'
75
+ # # - 'scenario two three'
76
+ # end
77
+ #
78
+ # @see #diagonal
79
+ def option(metadata_key, variants)
80
+ @options << Option.new(metadata_key, variants)
81
+ end
82
+
83
+ # Define diagonal for the scenario.
84
+ #
85
+ # The scenario will be generated for all the variants of the diagonal.
86
+ # Each variant of diagonal will be selected for at least one scenario.
87
+ # It may be included in more then one scenario when other diagonal or option has more variants.
88
+ #
89
+ # @param metadata_key [Symbol] the key to access diagonal data via metadata.
90
+ # @param variants [Hash{String => Object}] variants for the diagonal.
91
+ # Keys are titles of the variant, values are metadata values.
92
+ #
93
+ # @example
94
+ # Lopata.define 'scenario' do
95
+ # option :one, 'one' => 1, 'two' => 2
96
+ # diagonal :two, 'two' => 2, 'three' => 3
97
+ # diagonal :three, 'three' => 3, 'four' => 4, 'five' => 5
98
+ # # will generate 3 scenarios:
99
+ # # - 'scenario one two three'
100
+ # # - 'scenario two three four'
101
+ # # - 'scenario one two five'
102
+ # end
103
+ #
104
+ # @see #option
105
+ def diagonal(metadata_key, variants)
106
+ @diagonals << Diagonal.new(metadata_key, variants)
107
+ end
108
+
109
+ # Define additional metadata for the scenario
110
+ #
111
+ # @example
112
+ # Lopata.define 'scenario' do
113
+ # metadata key: 'value'
114
+ # it 'metadata available' do
115
+ # expect(metadata[:key]).to eq 'value'
116
+ # end
117
+ # end
36
118
  def metadata(hash)
37
119
  raise 'metadata expected to be a Hash' unless hash.is_a?(Hash)
38
120
  @common_metadata ||= {}
39
121
  @common_metadata.merge! hash
40
122
  end
41
123
 
124
+ # Skip scenario for given variants combination
125
+ #
126
+ # @example
127
+ # Lopata.define 'multiple options' do
128
+ # option :one, 'one' => 1, 'two' => 2
129
+ # option :two, 'two' => 2, 'three' => 3
130
+ # skip_when { |opt| opt.metadata[:one] == opt.metadata[:two] }
131
+ # it 'not equal' do
132
+ # expect(one).to_not eq two
133
+ # end
134
+ # end
135
+ #
42
136
  def skip_when(&block)
43
137
  @skip_when = block
44
138
  end
45
139
 
140
+ # @private
46
141
  def skip?(option_set)
47
142
  @skip_when && @skip_when.call(option_set)
48
143
  end
49
144
 
50
- %i{ setup action it teardown verify context }.each do |name|
145
+ # @!endgroup
146
+
147
+ # @!group Defining Steps
148
+
149
+ # @private
150
+ # @macro [attach] define_step_method
151
+ # @!scope instance
152
+ # @method $1
153
+ def self.define_step_method(name)
51
154
  name_if = "%s_if" % name
52
155
  name_unless = "%s_unless" % name
53
156
  define_method name, ->(*args, **metadata, &block) { add_step(name, *args, metadata: metadata, &block) }
@@ -59,6 +162,124 @@ class Lopata::ScenarioBuilder
59
162
  }
60
163
  end
61
164
 
165
+ # Define setup step.
166
+ # @example
167
+ # setup do
168
+ # end
169
+ #
170
+ # # setup from named shared step
171
+ # setup 'create user'
172
+ #
173
+ # # setup with both shared step and code block
174
+ # setup 'create user' do
175
+ # @user.update(admin: true)
176
+ # end
177
+ #
178
+ # Setup step used for set test data.
179
+ # @overload setup(*steps, &block)
180
+ # @param steps [Array<String, Symbol, Proc>] the steps to be runned as a part of setup.
181
+ # String - name of shared step to be called.
182
+ # Symbol - metadata key, referenced to shared step name.
183
+ # Proc - in-place step implementation.
184
+ # @param block [Block] The implementation of the step.
185
+ define_step_method :setup
186
+
187
+ # Define action step.
188
+ # @example
189
+ # action do
190
+ # end
191
+ #
192
+ # # action from named shared step
193
+ # action 'login'
194
+ #
195
+ # # setup with both shared step and code block
196
+ # action 'login', 'go dashboard' do
197
+ # @user.update(admin: true)
198
+ # end
199
+ #
200
+ # Action step is used for emulate user or external system action
201
+ #
202
+ # @overload action(*steps, &block)
203
+ # @param steps [Array<String, Symbol, Proc>] the steps to be runned as a part of action.
204
+ # String - name of shared step to be called.
205
+ # Symbol - metadata key, referenced to shared step name.
206
+ # Proc - in-place step implementation.
207
+ # @param block [Block] The implementation of the step.
208
+ define_step_method :action
209
+
210
+ # Define teardown step.
211
+ # @example
212
+ # setup { @user = User.create! }
213
+ # teardown { @user.destroy }
214
+ # Teardown step will be called at the end of scenario running.
215
+ # But it suggested to be decared right after setup or action step which require teardown.
216
+ #
217
+ # @overload teardown(*steps, &block)
218
+ # @param steps [Array<String, Symbol, Proc>] the steps to be runned as a part of teardown.
219
+ # String - name of shared step to be called.
220
+ # Symbol - metadata key, referenced to shared step name.
221
+ # Proc - in-place step implementation.
222
+ # @param block [Block] The implementation of the step.
223
+ define_step_method :teardown
224
+
225
+ # Define verify steps.
226
+ # @example
227
+ # verify 'home page displayed' # call shared step.
228
+ # Usually for validation shared steps inclusion
229
+ #
230
+ # @overload verify(*steps, &block)
231
+ # @param steps [Array<String, Symbol, Proc>] the steps to be runned as a part of verification.
232
+ # String - name of shared step to be called.
233
+ # Symbol - metadata key, referenced to shared step name.
234
+ # Proc - in-place step implementation.
235
+ # @param block [Block] The implementation of the step.
236
+ define_step_method :verify
237
+
238
+ # Define group of steps.
239
+ # The metadata for the group may be overriden
240
+ # @example
241
+ # context 'the task', task: :created do
242
+ # verify 'task setup'
243
+ # it 'created' do
244
+ # expect(metadata[:task]).to eq :created
245
+ # end
246
+ # end
247
+ # Teardown steps within group will be called at the end of the group, not scenario
248
+ # @overload context(title, **metadata, &block)
249
+ # @param title [String] context title
250
+ # @param metadata [Hash] the step additional metadata
251
+ # @param block [Block] The implementation of the step.
252
+ define_step_method :context
253
+
254
+ # Define single validation step.
255
+ # @example
256
+ # it 'works' do
257
+ # expect(1).to eq 1
258
+ # end
259
+ # @overload it(title, &block)
260
+ # @param title [String] validation title
261
+ # @param block [Block] The implementation of the step.
262
+ define_step_method :it
263
+
264
+ # Define runtime method for the scenario.
265
+ #
266
+ # @note
267
+ # The method to be called via #method_missing, so it wont override already defined methods.
268
+ #
269
+ # @example
270
+ # let(:square) { |num| num * num }
271
+ # it 'calculated' do
272
+ # expect(square(4)).to eq 16
273
+ # end
274
+ def let(method_name, &block)
275
+ steps << Lopata::Step.new(:let) do
276
+ execution.let(method_name, &block)
277
+ end
278
+ end
279
+
280
+ # @!endgroup
281
+
282
+ # @private
62
283
  def add_step(method_name, *args, condition: nil, metadata: {}, &block)
63
284
  step_class =
64
285
  case method_name
@@ -71,10 +292,12 @@ class Lopata::ScenarioBuilder
71
292
  steps << step
72
293
  end
73
294
 
295
+ # @private
74
296
  def steps
75
297
  @steps ||= []
76
298
  end
77
299
 
300
+ # @private
78
301
  def steps_with_hooks
79
302
  s = []
80
303
  unless Lopata.configuration.before_scenario_steps.empty?
@@ -90,20 +313,7 @@ class Lopata::ScenarioBuilder
90
313
  s
91
314
  end
92
315
 
93
- def let(method_name, &block)
94
- steps << Lopata::Step.new(:let) do
95
- execution.let(method_name, &block)
96
- end
97
- end
98
-
99
- def option(metadata_key, variants)
100
- @options << Option.new(metadata_key, variants)
101
- end
102
-
103
- def diagonal(metadata_key, variants)
104
- @diagonals << Diagonal.new(metadata_key, variants)
105
- end
106
-
316
+ # @private
107
317
  def option_combinations
108
318
  combinations = combine([OptionSet.new], options + diagonals)
109
319
  while !diagonals.all?(&:complete?)
@@ -112,6 +322,7 @@ class Lopata::ScenarioBuilder
112
322
  combinations.reject { |option_set| skip?(option_set) }
113
323
  end
114
324
 
325
+ # @private
115
326
  def combine(source_combinations, rest_options)
116
327
  return source_combinations if rest_options.empty?
117
328
  combinations = []
@@ -124,40 +335,50 @@ class Lopata::ScenarioBuilder
124
335
  combine(combinations, rest_options)
125
336
  end
126
337
 
338
+ # @private
127
339
  def world
128
340
  Lopata.world
129
341
  end
130
342
 
131
- # Набор вариантов, собранный для одного теста
343
+ # Set of options for scenario
132
344
  class OptionSet
345
+ # @private
133
346
  attr_reader :variants
347
+
348
+ # @private
134
349
  def initialize(*variants)
135
350
  @variants = {}
136
351
  variants.compact.each { |v| self << v }
137
352
  end
138
353
 
354
+ # @private
139
355
  def +(other_set)
140
356
  self.class.new(*@variants.values).tap do |sum|
141
357
  other_set.each { |v| sum << v }
142
358
  end
143
359
  end
144
360
 
361
+ # @private
145
362
  def <<(variant)
146
363
  @variants[variant.key] = variant
147
364
  end
148
365
 
366
+ # @private
149
367
  def [](key)
150
368
  @variants[key]
151
369
  end
152
370
 
371
+ # @private
153
372
  def each(&block)
154
373
  @variants.values.each(&block)
155
374
  end
156
375
 
376
+ # @private
157
377
  def title
158
378
  @variants.values.map(&:title).compact.join(' ')
159
379
  end
160
380
 
381
+ # @return [Hash{Symbol => Object}] metadata for this option set
161
382
  def metadata
162
383
  @variants.values.inject({}) do |metadata, variant|
163
384
  metadata.merge(variant.metadata(self))
@@ -165,6 +386,7 @@ class Lopata::ScenarioBuilder
165
386
  end
166
387
  end
167
388
 
389
+ # @private
168
390
  class Variant
169
391
  attr_reader :key, :title, :value, :option
170
392
 
@@ -213,6 +435,7 @@ class Lopata::ScenarioBuilder
213
435
  end
214
436
  end
215
437
 
438
+ # @private
216
439
  class CalculatedValue
217
440
  def initialize(&block)
218
441
  @proc = block
@@ -223,6 +446,7 @@ class Lopata::ScenarioBuilder
223
446
  end
224
447
  end
225
448
 
449
+ # @private
226
450
  class Option
227
451
  attr_reader :variants, :key
228
452
  def initialize(key, variants)
@@ -258,6 +482,7 @@ class Lopata::ScenarioBuilder
258
482
  end
259
483
  end
260
484
 
485
+ # @private
261
486
  class Diagonal < Option
262
487
  def level_variants
263
488
  [next_variant]
@@ -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)
@@ -1,4 +1,5 @@
1
1
  module Lopata
2
+ # @private
2
3
  class Step
3
4
  attr_reader :block, :args, :condition, :method_name, :shared_step
4
5
  # metadata overrien by the step.
@@ -26,7 +27,8 @@ module Lopata
26
27
  end
27
28
  end
28
29
 
29
- # Used for action, setup, teardown
30
+ # @private
31
+ # Used for action, setup, teardown, verify
30
32
  class ActionStep < Step
31
33
  def execution_steps(scenario, groups: [])
32
34
  steps = []
@@ -66,6 +68,7 @@ module Lopata
66
68
  end
67
69
  end
68
70
 
71
+ # @private
69
72
  # Used for context
70
73
  class GroupStep < Step
71
74
 
@@ -94,6 +97,7 @@ module Lopata
94
97
  end
95
98
  end
96
99
 
100
+ #@private
97
101
  class StepExecution
98
102
  attr_reader :step, :status, :exception, :block, :pending_message, :groups
99
103
  extend Forwardable
@@ -1,5 +1,6 @@
1
1
  module Lopata
2
+ # @private
2
3
  module Version
3
- STRING = '0.1.6'
4
+ STRING = '0.1.7'
4
5
  end
5
6
  end
@@ -1,21 +1,15 @@
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
- def start
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
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.6
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-06-01 00:00:00.000000000 Z
11
+ date: 2020-06-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -87,6 +87,7 @@ 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
@@ -137,5 +138,5 @@ requirements: []
137
138
  rubygems_version: 3.0.3
138
139
  signing_key:
139
140
  specification_version: 4
140
- summary: lopata-0.1.6
141
+ summary: lopata-0.1.7
141
142
  test_files: []