flow_object 0.1.3 → 0.2.2

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
- SHA1:
3
- metadata.gz: 74bf64f4ae1291bc4ac749eaf751442f618ae5bf
4
- data.tar.gz: 4772e89577086adcd91047779428ad16e51870e0
2
+ SHA256:
3
+ metadata.gz: ba086a330b400754a93c5b3bf51ee3b99962ca1bc93667393bd22cd6a777678f
4
+ data.tar.gz: b940309b02b78f47cf6f73b683ea71e02b5ddb53673b4f29142f8d62590727c6
5
5
  SHA512:
6
- metadata.gz: be3a91acca1a2d6dcf4e7858ec66ca03e833a7ccc7272ef33fb1e32f3789f765f4b5f0d68435330b01b505d0e4ad0eebfef9bdb08f1be7e8c8bf8887d6e8deab
7
- data.tar.gz: d4210cb44b45caa9866a367ade7bff0d18ce250b8d89442c881133720e2e38565eea3aef20ea724d5cad39c60bf3c4b543abc4579c5ede365da834d4a18e8552
6
+ metadata.gz: a620ce7783b9e53d0ebcc87eb1ffa1dfdc07a9b198a3e98b5f96c83cc55fc15c981274cd7cad234fba2576711d26b086c6446e65e0beb3edb081c8a07773eede
7
+ data.tar.gz: f1426f0bcef2a4f68ea5b60db7fbcdf586a1c38096e6f4e2e3a4692718286729c26fa86ead423631df55f54ada3a78d33590c0aa0f027a9e5461cb7781c9f272
data/Gemfile.lock CHANGED
@@ -1,8 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- flow_object (0.1.3)
5
- mature_factory (~> 0.2.12)
4
+ flow_object (0.2.2)
5
+ mature_factory (~> 0.2.15)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
@@ -10,9 +10,8 @@ GEM
10
10
  coderay (1.1.3)
11
11
  diff-lcs (1.4.4)
12
12
  dry-inflector (0.1.2)
13
- mature_factory (0.2.12)
13
+ mature_factory (0.2.15)
14
14
  dry-inflector (~> 0.1)
15
- simple_facade (~> 0.2)
16
15
  method_source (1.0.0)
17
16
  pry (0.13.1)
18
17
  coderay (~> 1.1)
@@ -33,7 +32,6 @@ GEM
33
32
  rspec-support (3.9.3)
34
33
  rspec_vars_helper (0.1.0)
35
34
  rspec (>= 2.4)
36
- simple_facade (0.2.1)
37
35
 
38
36
  PLATFORMS
39
37
  ruby
data/flow_object.gemspec CHANGED
@@ -36,7 +36,7 @@ Gem::Specification.new do |spec|
36
36
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
37
37
  spec.require_paths = ['lib']
38
38
 
39
- spec.add_dependency 'mature_factory', '~> 0.2.12'
39
+ spec.add_dependency 'mature_factory', '~> 0.2.15'
40
40
 
41
41
  spec.add_development_dependency 'bundler', '~> 1.17'
42
42
  spec.add_development_dependency 'pry'
data/lib/flow_object.rb CHANGED
@@ -1,4 +1,6 @@
1
1
  require 'mature_factory'
2
+ require 'flow_object/callbacks'
3
+ require 'flow_object/runner'
2
4
  require 'flow_object/base'
3
5
  require 'flow_object/version'
4
6
 
@@ -3,109 +3,138 @@ module FlowObject
3
3
  include MatureFactory
4
4
  include MatureFactory::Features::Assemble
5
5
 
6
- composed_of :stages, :inputs, :outputs
6
+ produces :stages, :inputs, :outputs
7
7
 
8
8
  class << self
9
- attr_accessor :in, :out, :initial_values
9
+ extend Forwardable
10
+ attr_reader :in, :out, :initial_values
11
+ def_delegators :callbacks, :after_input_initialize, :after_flow_initialize,
12
+ :after_input_check, :after_flow_check, :after_output_initialize
10
13
  end
11
14
 
12
- attr_reader :output, :given
15
+ attr_reader :output
13
16
 
14
- def initialize(given)
15
- @given = given
16
- @output = self.class.__fo_wrap_output__
17
+ def initialize(flow, step_name = :flow)
18
+ @output = self.class.send(:__fo_wrap_output__)
19
+ self.class.link_with_delegation(@output, flow, step_name, true)
20
+ self.class.after_output_initialize.call(@output)
17
21
  end
18
22
 
19
- def inherited(subclass)
20
- subclass.from(self.in)
21
- subclass.to(self.out)
23
+ def on_failure(failed_step = nil)
24
+ # NOOP
22
25
  end
23
26
 
24
- def self.from(input)
25
- self.in = input
26
- self
27
+ def on_success
28
+ # NOOP
27
29
  end
28
30
 
29
- def self.to(output)
30
- self.out = output
31
- self
32
- end
31
+ module ClassMethods
32
+ def inherited(subclass)
33
+ super
34
+ subclass.from(self.in)
35
+ subclass.to(self.out)
36
+ subclass.after_input_initialize(&self.after_input_initialize)
37
+ subclass.after_flow_initialize(&self.after_flow_initialize)
38
+ subclass.after_input_check(&self.after_input_check)
39
+ subclass.after_flow_check(&self.after_flow_check)
40
+ subclass.after_output_initialize(&self.after_output_initialize)
41
+ end
33
42
 
34
- def self.__fo_wrap_input__
35
- return initial_values if self.in.nil?
36
- input_class = public_send(:"#{self.in}_input_class")
37
- return initial_values if input_class.nil?
38
- public_send(:"new_#{self.in}_input_instance", *initial_values)
39
- end
43
+ def callbacks
44
+ @callbacks ||= Callbacks.new
45
+ end
40
46
 
41
- def self.__fo_wrap_output__
42
- # rescue NoMethodError => ex
43
- # "You have not define output class. Please add `output :#{self.out}`"
44
- return if self.out.nil?
45
- return unless self.respond_to?(:"#{self.out}_output_class")
46
- output_class = public_send(:"#{self.out}_output_class")
47
- return if output_class.nil?
48
- public_send(:"new_#{self.out}_output_instance")
49
- end
47
+ def from(input)
48
+ @in = input
49
+ self
50
+ end
50
51
 
51
- def self.accept(*values)
52
- self.initial_values = values
53
- self
54
- end
52
+ def to(output)
53
+ @out = output
54
+ self
55
+ end
55
56
 
56
- def self.__fo_resolve_cascade__(cascade, step, failure)
57
- new(cascade).tap do |flow|
58
- if failure
59
- __fo_notify_error__(flow, step)
60
- else
61
- __fo_notify_success__(flow)
62
- end
57
+ def accept(*values)
58
+ @initial_values = values
59
+ self
63
60
  end
64
- end
65
61
 
66
- def self.__fo_notify_error__(flow, step)
67
- if flow.output.respond_to?(:"on_#{step}_failure")
68
- flow.output.public_send(:"on_#{step}_failure", flow.given)
69
- elsif flow.output.respond_to?(:on_failure)
70
- flow.output.on_failure(flow.given, step)
71
- elsif flow.respond_to?(:"on_#{step}_failure")
72
- flow.public_send(:"on_#{step}_failure")
73
- else
74
- flow.on_failure(step)
62
+ def call(flow: :main)
63
+ __fo_resolve__(__fo_process__(flow: flow))
75
64
  end
76
- end
77
65
 
78
- def self.__fo_notify_success__(flow)
79
- if flow.output.respond_to?(:on_success)
80
- flow.output.on_success(flow.given)
81
- else
82
- flow.on_success
66
+ def flow(name = :main, &block)
67
+ wrap(name, delegate: true, &block)
83
68
  end
84
- end
85
69
 
86
- def self.call(flow: :main)
87
- failure, previous_step, object = false, :"#{self.in}_input", __fo_wrap_input__
88
- plan = public_send(:"build_#{flow}", previous_step, object)
89
- cascade = plan.call do |object, id|
90
- previous_step = id.to_sym
91
- if !object.valid?
92
- failure = true
93
- throw :halt
94
- end
95
- end
96
- __fo_resolve_cascade__(cascade, previous_step, failure)
97
- end
70
+ def link_with_delegation(target, object, accessor, delegate)
71
+ MatureFactory::Features::Assemble::AbstractBuilder
72
+ .link_with_delegation(target, object, accessor, delegate)
73
+ end
98
74
 
99
- def self.flow(name = 'main', &block)
100
- wrap(name, delegate: true, &block)
101
- end
75
+ private
102
76
 
103
- def on_failure(failed_step = nil)
104
- # NOOP
105
- end
77
+ def halt_flow?(object, id)
78
+ false
79
+ end
106
80
 
107
- def on_success
108
- # NOOP
81
+ def __fo_process__(flow: :main)
82
+ plan = __fo_build_flow__(flow, self.in, :input, __fo_wrap_input__)
83
+ Runner.new(plan, callbacks, method(:halt_flow?)).execute_plan
84
+ end
85
+
86
+ def __fo_build_flow__(flow, step_name, group, object)
87
+ public_send(:"build_#{flow}", title: step_name, group: group, object: object)
88
+ end
89
+
90
+ def __fo_wrap_input__
91
+ return initial_values if self.in.nil?
92
+ input_class = public_send(:"#{self.in}_input_class")
93
+ return initial_values if input_class.nil?
94
+ public_send(:"new_#{self.in}_input_instance", *initial_values)
95
+ end
96
+
97
+ def __fo_wrap_output__
98
+ # rescue NoMethodError => ex
99
+ # "You have not define output class. Please add `output :#{self.out}`"
100
+ return if self.out.nil?
101
+ return unless self.respond_to?(:"#{self.out}_output_class")
102
+ output_class = public_send(:"#{self.out}_output_class")
103
+ return if output_class.nil?
104
+ public_send(:"new_#{self.out}_output_instance")
105
+ end
106
+
107
+ def __fo_resolve__(runner)
108
+ new(runner.flow, runner.step_name).tap do |handler|
109
+ if runner.failure
110
+ __fo_notify_error__(handler, runner.step_name)
111
+ else
112
+ __fo_notify_success__(handler)
113
+ end
114
+ end
115
+ end
116
+
117
+ def __fo_notify_error__(handler, step)
118
+ if handler.output.respond_to?(:"on_#{step}_failure")
119
+ handler.output.public_send(:"on_#{step}_failure")
120
+ elsif handler.output.respond_to?(:on_failure)
121
+ handler.output.on_failure(step)
122
+ elsif handler.respond_to?(:"on_#{step}_failure")
123
+ handler.public_send(:"on_#{step}_failure")
124
+ else
125
+ handler.on_failure(step)
126
+ end
127
+ end
128
+
129
+ def __fo_notify_success__(handler)
130
+ if handler.output.respond_to?(:on_success)
131
+ handler.output.on_success
132
+ else
133
+ handler.on_success
134
+ end
135
+ end
109
136
  end
137
+
138
+ extend ClassMethods
110
139
  end
111
140
  end
@@ -0,0 +1,29 @@
1
+ module FlowObject
2
+ class Callbacks
3
+ SUPPORTED = %i[
4
+ after_input_initialize
5
+ after_flow_initialize
6
+ after_input_check
7
+ after_flow_check
8
+ after_output_initialize
9
+ ].freeze
10
+
11
+ NOOP = proc {}.freeze
12
+
13
+ def initialize
14
+ @callbacks = Hash.new { |hash, key| hash[key] = NOOP }
15
+ end
16
+
17
+ def method_missing(name, *_attrs, &block)
18
+ if SUPPORTED.include?(name)
19
+ block_given? ? @callbacks[name] = block : @callbacks[name]
20
+ else
21
+ super
22
+ end
23
+ end
24
+
25
+ def respond_to_missing?(name, *)
26
+ SUPPORTED.include?(name)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,67 @@
1
+ module FlowObject
2
+ class Runner
3
+ attr_reader :step_name, :failure, :flow
4
+
5
+ def initialize(plan, callbacks, halt_if_proc)
6
+ @plan = plan
7
+ @flow = flow
8
+ @failure = false
9
+ @step_name = nil
10
+ @callbacks = callbacks
11
+ @step_index = 0
12
+ @halt_if_proc = halt_if_proc
13
+ end
14
+
15
+ def execute_plan
16
+ @flow = call_flow_builder
17
+ after_flow_check(flow.public_send(@step_name))
18
+ self
19
+ end
20
+
21
+ private
22
+
23
+ def call_flow_builder
24
+ @plan.call do |object, id|
25
+ handle_step(object, id) { throw :halt }
26
+ end
27
+ end
28
+
29
+ def after_flow_check(object)
30
+ @callbacks.after_flow_check.call(object)
31
+ end
32
+
33
+ def after_input_initialize(object)
34
+ @callbacks.after_input_initialize.call(object)
35
+ end
36
+
37
+ def after_flow_initialize(object)
38
+ @callbacks.after_flow_initialize.call(object)
39
+ end
40
+
41
+ def after_input_check(object)
42
+ @callbacks.after_input_check.call(object)
43
+ end
44
+
45
+ def second_step?
46
+ @step_index == 1
47
+ end
48
+
49
+ def input_step?(id)
50
+ id.group == :input
51
+ end
52
+
53
+ def flow_step?(id)
54
+ id.group == :stage
55
+ end
56
+
57
+ def handle_step(object, id)
58
+ after_input_initialize(object) if input_step?(id)
59
+ after_flow_initialize(object) if second_step? && flow_step?(id)
60
+ @step_name = id.title
61
+ @step_index += 1
62
+ yield if @failure = @halt_if_proc.call(object, id)
63
+ after_input_check(object) if input_step?(id)
64
+ end
65
+
66
+ end
67
+ end
@@ -1,3 +1,3 @@
1
1
  module FlowObject
2
- VERSION = '0.1.3'.freeze
2
+ VERSION = '0.2.2'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flow_object
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrii Baran
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-01-08 00:00:00.000000000 Z
11
+ date: 2021-04-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mature_factory
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.2.12
19
+ version: 0.2.15
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.2.12
26
+ version: 0.2.15
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -116,6 +116,8 @@ files:
116
116
  - flow_object.gemspec
117
117
  - lib/flow_object.rb
118
118
  - lib/flow_object/base.rb
119
+ - lib/flow_object/callbacks.rb
120
+ - lib/flow_object/runner.rb
119
121
  - lib/flow_object/version.rb
120
122
  homepage: https://github.com/andriy-baran/flow_object
121
123
  licenses:
@@ -139,8 +141,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
139
141
  - !ruby/object:Gem::Version
140
142
  version: '0'
141
143
  requirements: []
142
- rubyforge_project:
143
- rubygems_version: 2.5.1
144
+ rubygems_version: 3.2.16
144
145
  signing_key:
145
146
  specification_version: 4
146
147
  summary: Create objects for storing application flows