yaso 1.1.0 → 1.2.0
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/.rubocop.yml +1 -0
- data/Gemfile.lock +1 -1
- data/benchmark/Gemfile +1 -0
- data/benchmark/index.rb +3 -0
- data/benchmark/shared/simple_command_service.rb +11 -0
- data/benchmark/step/benchmark.rb +2 -0
- data/benchmark/step/simple_command.rb +77 -0
- data/lib/yaso/errors.rb +6 -0
- data/lib/yaso/{invokable.rb → invocable.rb} +7 -7
- data/lib/yaso/logic/base.rb +2 -2
- data/lib/yaso/logic/failure.rb +1 -1
- data/lib/yaso/logic/pass.rb +1 -1
- data/lib/yaso/logic/rollback.rb +40 -0
- data/lib/yaso/logic/step.rb +1 -1
- data/lib/yaso/logic/step_builder.rb +9 -6
- data/lib/yaso/logic/switch.rb +2 -2
- data/lib/yaso/logic/wrap.rb +1 -1
- data/lib/yaso/logic.rb +7 -1
- data/lib/yaso/service.rb +16 -7
- data/lib/yaso/stepable.rb +11 -4
- data/lib/yaso/version.rb +1 -1
- data/lib/yaso.rb +1 -1
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 293839b577b5832d54938e07a07729d49ddd74fd226f0077076fe6f4986340ae
|
4
|
+
data.tar.gz: 72d9d2bde9edbc0050f1473e3efc33a9c81952fe78906eaeb35acbba2ccc80bf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a54b6acc15d5d8e71b25a4273ce87816ae58a1e63bd815e4cf338d671b5b71b3378016c076d9db44122e7612619e69e06c60e63cf7afd388b0de7509ad42ac0f
|
7
|
+
data.tar.gz: 55a031ce994ac21ed04e659d70b2871cae67ed64d088799e26663b1d5e2ac5f76593d0ea4d0e3e181ff72b63fed7aa626abf67b063eed696be4418e74930e9e8
|
data/.rubocop.yml
CHANGED
data/Gemfile.lock
CHANGED
data/benchmark/Gemfile
CHANGED
@@ -5,6 +5,7 @@ source 'https://rubygems.org'
|
|
5
5
|
gem 'benchmark-ips', '~> 2.10.0'
|
6
6
|
gem 'interactor', '~> 3.1.2'
|
7
7
|
gem 'kalibera', '~> 0.1.2'
|
8
|
+
gem 'simple_command', RUBY_VERSION.include?('2.5') ? '~> 0.2.0' : '~> 1.0.1'
|
8
9
|
gem 'trailblazer', '~> 2.1.0'
|
9
10
|
|
10
11
|
gem 'active_interaction', %w[2.5 2.6].any? { |version| RUBY_VERSION.include?(version) } ? '~> 4.1.0' : '~> 5.1.0'
|
data/benchmark/index.rb
CHANGED
@@ -9,10 +9,12 @@ RUBY_VERSION.include?('2.5') || require('decouplio')
|
|
9
9
|
require 'interactor'
|
10
10
|
require 'active_interaction'
|
11
11
|
require 'trailblazer'
|
12
|
+
require 'simple_command'
|
12
13
|
|
13
14
|
require_relative 'shared/yaso_service'
|
14
15
|
RUBY_VERSION.include?('2.5') || require_relative('shared/decouplio_service')
|
15
16
|
require_relative 'shared/pure_service'
|
17
|
+
require_relative 'shared/simple_command_service'
|
16
18
|
require_relative 'shared/interactor_service'
|
17
19
|
require_relative 'shared/active_interaction_service'
|
18
20
|
require_relative 'shared/trailblazer_service'
|
@@ -21,6 +23,7 @@ require_relative 'shared/callable_step'
|
|
21
23
|
require_relative 'step/yaso'
|
22
24
|
RUBY_VERSION.include?('2.5') || require_relative('step/decouplio')
|
23
25
|
require_relative 'step/pure'
|
26
|
+
require_relative 'step/simple_command'
|
24
27
|
require_relative 'step/interactor'
|
25
28
|
require_relative 'step/active_interaction'
|
26
29
|
require_relative 'step/trailblazer'
|
data/benchmark/step/benchmark.rb
CHANGED
@@ -7,6 +7,7 @@ Benchmark.ips do |x|
|
|
7
7
|
x.config(stats: :bootstrap, confidence: 95)
|
8
8
|
|
9
9
|
x.report('Pure Service') { PureStepsService.call }
|
10
|
+
x.report('SimpleCommand') { SimpleCommandStepsService.call }
|
10
11
|
x.report('Yaso') { YasoStepsService.call }
|
11
12
|
x.report('Decouplio') { DecouplioStepsService.call } unless RUBY_VERSION.include?('2.5')
|
12
13
|
x.report('Interactor') { InteractorStepsService.call }
|
@@ -21,6 +22,7 @@ Benchmark.ips do |x|
|
|
21
22
|
x.config(stats: :bootstrap, confidence: 95)
|
22
23
|
|
23
24
|
x.report('Pure Service') { PureCallablesService.call }
|
25
|
+
x.report('SimpleCommand') { SimpleCommandCallablesService.call }
|
24
26
|
x.report('Yaso') { YasoCallablesService.call }
|
25
27
|
x.report('Decouplio') { DecouplioCallablesService.call } unless RUBY_VERSION.include?('2.5')
|
26
28
|
x.report('Interactor') { InteractorCallablesService.call }
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class SimpleCommandStepsService < SimpleCommandService
|
4
|
+
# rubocop:disable Metrics/MethodLength
|
5
|
+
def call
|
6
|
+
one
|
7
|
+
two
|
8
|
+
three
|
9
|
+
four
|
10
|
+
five
|
11
|
+
six
|
12
|
+
seven
|
13
|
+
eight
|
14
|
+
nine
|
15
|
+
ten
|
16
|
+
ctx
|
17
|
+
end
|
18
|
+
# rubocop:enable Metrics/MethodLength
|
19
|
+
|
20
|
+
def one
|
21
|
+
ctx[:one] = true
|
22
|
+
end
|
23
|
+
|
24
|
+
def two
|
25
|
+
ctx[:two] = true
|
26
|
+
end
|
27
|
+
|
28
|
+
def three
|
29
|
+
ctx[:three] = true
|
30
|
+
end
|
31
|
+
|
32
|
+
def four
|
33
|
+
ctx[:four] = true
|
34
|
+
end
|
35
|
+
|
36
|
+
def five
|
37
|
+
ctx[:five] = true
|
38
|
+
end
|
39
|
+
|
40
|
+
def six
|
41
|
+
ctx[:six] = true
|
42
|
+
end
|
43
|
+
|
44
|
+
def seven
|
45
|
+
ctx[:seven] = true
|
46
|
+
end
|
47
|
+
|
48
|
+
def eight
|
49
|
+
ctx[:eight] = true
|
50
|
+
end
|
51
|
+
|
52
|
+
def nine
|
53
|
+
ctx[:nine] = true
|
54
|
+
end
|
55
|
+
|
56
|
+
def ten
|
57
|
+
ctx[:ten] = true
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class SimpleCommandCallablesService < SimpleCommandService
|
62
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
63
|
+
def call
|
64
|
+
CallableStep.call(ctx, key: :one, value: true)
|
65
|
+
CallableStep.call(ctx, key: :two, value: true)
|
66
|
+
CallableStep.call(ctx, key: :three, value: true)
|
67
|
+
CallableStep.call(ctx, key: :four, value: true)
|
68
|
+
CallableStep.call(ctx, key: :five, value: true)
|
69
|
+
CallableStep.call(ctx, key: :six, value: true)
|
70
|
+
CallableStep.call(ctx, key: :seven, value: true)
|
71
|
+
CallableStep.call(ctx, key: :eight, value: true)
|
72
|
+
CallableStep.call(ctx, key: :nine, value: true)
|
73
|
+
CallableStep.call(ctx, key: :ten, value: true)
|
74
|
+
ctx
|
75
|
+
end
|
76
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
77
|
+
end
|
data/lib/yaso/errors.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Yaso
|
4
|
-
class
|
4
|
+
class Invocable
|
5
5
|
METHOD = :method
|
6
6
|
CALLABLE = :callable
|
7
7
|
YASO = :yaso
|
@@ -9,23 +9,23 @@ module Yaso
|
|
9
9
|
class << self
|
10
10
|
def call(object, options: {}, **)
|
11
11
|
type = object_type(object)
|
12
|
-
|
12
|
+
invocable = case type
|
13
13
|
when YASO then proc { |context, _| object.call(context.clone).success? }
|
14
14
|
when CALLABLE then proc { |context, _, &block| object.call(context, **options, &block) }
|
15
|
-
else
|
15
|
+
else method_invocable(object)
|
16
16
|
end
|
17
|
-
[type,
|
17
|
+
[type, invocable]
|
18
18
|
end
|
19
19
|
|
20
20
|
private
|
21
21
|
|
22
22
|
def object_type(object)
|
23
|
-
return
|
23
|
+
return Invocable::METHOD unless object.is_a?(Class)
|
24
24
|
|
25
|
-
object < ::Yaso::Service ?
|
25
|
+
object < ::Yaso::Service ? Invocable::YASO : Invocable::CALLABLE
|
26
26
|
end
|
27
27
|
|
28
|
-
def
|
28
|
+
def method_invocable(object)
|
29
29
|
instance_eval <<-RUBY, __FILE__, __LINE__ + 1
|
30
30
|
proc { |context, instance, &block| # proc { |context, instance, &block|
|
31
31
|
instance.#{object}(context, **context.data, &block) # instance.<method_name>(context, **context.data, &block)
|
data/lib/yaso/logic/base.rb
CHANGED
@@ -5,9 +5,9 @@ module Yaso
|
|
5
5
|
class Base
|
6
6
|
attr_reader :name, :on_success, :on_failure
|
7
7
|
|
8
|
-
def initialize(name:,
|
8
|
+
def initialize(name:, invocable:, **options)
|
9
9
|
@name = name
|
10
|
-
@
|
10
|
+
@invocable = invocable
|
11
11
|
@fast = options[:fast]
|
12
12
|
@on_success = options[:on_success]
|
13
13
|
@on_failure = options[:on_failure]
|
data/lib/yaso/logic/failure.rb
CHANGED
data/lib/yaso/logic/pass.rb
CHANGED
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Yaso
|
4
|
+
module Logic
|
5
|
+
class Rollback < Classic
|
6
|
+
def call
|
7
|
+
super
|
8
|
+
logicals.detect { |step| !step.is_a?(Failure) }
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def link_step(step, index)
|
14
|
+
next_success = step.on_success ? find_step(step.on_success) : next_step(index)
|
15
|
+
next_failure = if step.on_failure then find_step(step.on_failure)
|
16
|
+
else
|
17
|
+
step.is_a?(Pass) ? next_success : previous_failure(index)
|
18
|
+
end
|
19
|
+
|
20
|
+
step.add_next_step(next_success)
|
21
|
+
step.add_failure(next_failure)
|
22
|
+
end
|
23
|
+
|
24
|
+
def link_previous_steps(failure, index)
|
25
|
+
prev_failure = previous_failure(index)
|
26
|
+
|
27
|
+
failure.add_failure(prev_failure) unless failure.on_failure
|
28
|
+
failure.add_next_step(prev_failure) unless failure.on_success
|
29
|
+
end
|
30
|
+
|
31
|
+
def next_step(index)
|
32
|
+
logicals[index.next..-1].detect { |next_node| !next_node.is_a?(Failure) }
|
33
|
+
end
|
34
|
+
|
35
|
+
def previous_failure(index)
|
36
|
+
logicals[0...index].reverse_each.detect { |previous_step| previous_step.is_a?(Failure) }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/yaso/logic/step.rb
CHANGED
@@ -16,13 +16,13 @@ module Yaso
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def call(object:, category:, block:, **opts)
|
19
|
-
|
19
|
+
invocable_type, invocable = Invocable.call(object, **opts)
|
20
20
|
logic_class = CATEGORIES[category]
|
21
|
-
if
|
21
|
+
if invocable_type == Invocable::METHOD
|
22
22
|
opts[:name] = logic_class == Switch ? build_switch(object, **opts, &block) : build_method(object, &block)
|
23
23
|
end
|
24
24
|
opts[:wrapper] = build_wrapper(&block) if logic_class == Wrap
|
25
|
-
logic_class.new(
|
25
|
+
logic_class.new(invocable: invocable, **opts)
|
26
26
|
end
|
27
27
|
|
28
28
|
private
|
@@ -45,14 +45,17 @@ module Yaso
|
|
45
45
|
|
46
46
|
def build_wrapper(&block)
|
47
47
|
wrapper_class = Class.new { extend Stepable }
|
48
|
+
build_wrapper_methods(wrapper_class, @klass)
|
48
49
|
wrapper_class.instance_exec(&block)
|
49
|
-
build_wrapper_call(wrapper_class, @klass)
|
50
50
|
wrapper_class
|
51
51
|
end
|
52
52
|
|
53
|
-
def
|
53
|
+
def build_wrapper_methods(wrapper_class, service_class)
|
54
|
+
wrapper_class.define_singleton_method(:flow) do
|
55
|
+
service_class.flow
|
56
|
+
end
|
54
57
|
wrapper_class.define_singleton_method(:call) do |context, instance|
|
55
|
-
@entry ||=
|
58
|
+
@entry ||= flow.call(service_class, steps)
|
56
59
|
step = @entry
|
57
60
|
step = step.call(context, instance) while step
|
58
61
|
context
|
data/lib/yaso/logic/switch.rb
CHANGED
@@ -5,9 +5,9 @@ module Yaso
|
|
5
5
|
class Switch < Base
|
6
6
|
def call(context, instance)
|
7
7
|
context.success = true
|
8
|
-
switch_case = @
|
8
|
+
switch_case = @invocable.call(context, instance) || raise(UnhandledSwitchCaseError, instance.class)
|
9
9
|
|
10
|
-
if
|
10
|
+
if Invocable.call(switch_case).last.call(context, instance)
|
11
11
|
@next_step
|
12
12
|
else
|
13
13
|
context.success = false
|
data/lib/yaso/logic/wrap.rb
CHANGED
@@ -10,7 +10,7 @@ module Yaso
|
|
10
10
|
|
11
11
|
def call(context, instance)
|
12
12
|
context.success = true
|
13
|
-
if @
|
13
|
+
if @invocable.call(context, instance) { @wrapper.call(context, instance).success? }
|
14
14
|
@next_step
|
15
15
|
else
|
16
16
|
context.success = false
|
data/lib/yaso/logic.rb
CHANGED
@@ -8,7 +8,13 @@ require_relative 'logic/wrap'
|
|
8
8
|
require_relative 'logic/switch'
|
9
9
|
require_relative 'logic/step_builder'
|
10
10
|
require_relative 'logic/classic'
|
11
|
+
require_relative 'logic/rollback'
|
11
12
|
|
12
13
|
module Yaso
|
13
|
-
module Logic
|
14
|
+
module Logic
|
15
|
+
FLOWS = {
|
16
|
+
classic: Logic::Classic,
|
17
|
+
rollback: Logic::Rollback
|
18
|
+
}.freeze
|
19
|
+
end
|
14
20
|
end
|
data/lib/yaso/service.rb
CHANGED
@@ -4,13 +4,22 @@ module Yaso
|
|
4
4
|
class Service
|
5
5
|
extend Stepable
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
7
|
+
class << self
|
8
|
+
def call(context = {})
|
9
|
+
context = context.is_a?(Context) ? context : Context.new(context)
|
10
|
+
@entry ||= flow.call(self, steps)
|
11
|
+
step = @entry
|
12
|
+
instance = new
|
13
|
+
step = step.call(context, instance) while step
|
14
|
+
context
|
15
|
+
end
|
16
|
+
|
17
|
+
def flow(name = nil)
|
18
|
+
@flow ||= Logic::FLOWS[:classic] if self == Yaso::Service
|
19
|
+
return @flow || Yaso::Service.flow if name.nil?
|
20
|
+
|
21
|
+
@flow = Logic::FLOWS[name] || raise(UnknownFlowError.new(self, name))
|
22
|
+
end
|
14
23
|
end
|
15
24
|
end
|
16
25
|
end
|
data/lib/yaso/stepable.rb
CHANGED
@@ -6,15 +6,22 @@ module Yaso
|
|
6
6
|
@steps ||= []
|
7
7
|
end
|
8
8
|
|
9
|
-
%i[step pass
|
10
|
-
define_method(category) do |object, options
|
11
|
-
raise InvalidFirstStepError, category if category == :failure && steps.empty?
|
12
|
-
|
9
|
+
%i[step pass wrap switch].each do |category|
|
10
|
+
define_method(category) do |object, **options, &block|
|
13
11
|
steps << {
|
14
12
|
object: object, category: category, fast: options.delete(:fast), on_success: options.delete(:on_success),
|
15
13
|
on_failure: options.delete(:on_failure), options: options, block: block, name: options.delete(:name)
|
16
14
|
}
|
17
15
|
end
|
18
16
|
end
|
17
|
+
|
18
|
+
def failure(object, **options, &block)
|
19
|
+
raise InvalidFirstStepError, :failure if flow == Logic::Classic && steps.empty?
|
20
|
+
|
21
|
+
steps << {
|
22
|
+
object: object, category: :failure, fast: options.delete(:fast), on_success: options.delete(:on_success),
|
23
|
+
on_failure: options.delete(:on_failure), options: options, block: block, name: options.delete(:name)
|
24
|
+
}
|
25
|
+
end
|
19
26
|
end
|
20
27
|
end
|
data/lib/yaso/version.rb
CHANGED
data/lib/yaso.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
require_relative 'yaso/version'
|
4
4
|
require_relative 'yaso/errors'
|
5
5
|
require_relative 'yaso/context'
|
6
|
-
require_relative 'yaso/
|
6
|
+
require_relative 'yaso/invocable'
|
7
7
|
require_relative 'yaso/stepable'
|
8
8
|
require_relative 'yaso/logic'
|
9
9
|
require_relative 'yaso/service'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yaso
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Artem Shevchenko
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-08-
|
11
|
+
date: 2022-08-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffaker
|
@@ -197,6 +197,7 @@ files:
|
|
197
197
|
- benchmark/shared/decouplio_service.rb
|
198
198
|
- benchmark/shared/interactor_service.rb
|
199
199
|
- benchmark/shared/pure_service.rb
|
200
|
+
- benchmark/shared/simple_command_service.rb
|
200
201
|
- benchmark/shared/trailblazer_service.rb
|
201
202
|
- benchmark/shared/yaso_service.rb
|
202
203
|
- benchmark/step/active_interaction.rb
|
@@ -204,18 +205,20 @@ files:
|
|
204
205
|
- benchmark/step/decouplio.rb
|
205
206
|
- benchmark/step/interactor.rb
|
206
207
|
- benchmark/step/pure.rb
|
208
|
+
- benchmark/step/simple_command.rb
|
207
209
|
- benchmark/step/trailblazer.rb
|
208
210
|
- benchmark/step/yaso.rb
|
209
211
|
- lefthook.yml
|
210
212
|
- lib/yaso.rb
|
211
213
|
- lib/yaso/context.rb
|
212
214
|
- lib/yaso/errors.rb
|
213
|
-
- lib/yaso/
|
215
|
+
- lib/yaso/invocable.rb
|
214
216
|
- lib/yaso/logic.rb
|
215
217
|
- lib/yaso/logic/base.rb
|
216
218
|
- lib/yaso/logic/classic.rb
|
217
219
|
- lib/yaso/logic/failure.rb
|
218
220
|
- lib/yaso/logic/pass.rb
|
221
|
+
- lib/yaso/logic/rollback.rb
|
219
222
|
- lib/yaso/logic/step.rb
|
220
223
|
- lib/yaso/logic/step_builder.rb
|
221
224
|
- lib/yaso/logic/switch.rb
|