trailblazer-operation 0.4.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +8 -0
  3. data/.rubocop_todo.yml +223 -0
  4. data/.travis.yml +6 -7
  5. data/CHANGES.md +16 -12
  6. data/Gemfile +5 -3
  7. data/README.md +13 -2
  8. data/Rakefile +2 -2
  9. data/lib/trailblazer/operation.rb +52 -67
  10. data/lib/trailblazer/operation/class_dependencies.rb +1 -1
  11. data/lib/trailblazer/operation/container.rb +14 -0
  12. data/lib/trailblazer/operation/deprecated_macro.rb +2 -2
  13. data/lib/trailblazer/operation/public_call.rb +23 -20
  14. data/lib/trailblazer/operation/railway.rb +2 -3
  15. data/lib/trailblazer/operation/railway/macaroni.rb +2 -2
  16. data/lib/trailblazer/operation/result.rb +14 -1
  17. data/lib/trailblazer/operation/trace.rb +9 -12
  18. data/lib/trailblazer/operation/version.rb +4 -2
  19. data/test/benchmark/skill_resolver_benchmark.rb +8 -9
  20. data/test/call_test.rb +57 -31
  21. data/test/callable_test.rb +147 -147
  22. data/test/class_dependencies_test.rb +6 -7
  23. data/test/docs/doormat_test.rb +13 -12
  24. data/test/docs/macaroni_test.rb +7 -9
  25. data/test/docs/operation_test.rb +69 -4
  26. data/test/docs/wiring_test.rb +85 -153
  27. data/test/dry_container_test.rb +4 -3
  28. data/test/fast_track_test.rb +24 -44
  29. data/test/inheritance_test.rb +13 -12
  30. data/test/introspect_test.rb +6 -6
  31. data/test/operation_test.rb +17 -25
  32. data/test/result_test.rb +4 -4
  33. data/test/ruby-2.0.0/operation_test.rb +9 -9
  34. data/test/ruby-2.0.0/step_test.rb +17 -16
  35. data/test/step_test.rb +55 -50
  36. data/test/test_helper.rb +7 -13
  37. data/test/trace_test.rb +27 -27
  38. data/test/wiring/defaults_test.rb +29 -33
  39. data/trailblazer-operation.gemspec +9 -7
  40. metadata +46 -27
  41. data/lib/trailblazer/operation/heritage.rb +0 -30
  42. data/lib/trailblazer/operation/inject.rb +0 -36
  43. data/lib/trailblazer/operation/inspect.rb +0 -79
  44. data/lib/trailblazer/operation/railway/fast_track.rb +0 -13
  45. data/lib/trailblazer/operation/railway/normalizer.rb +0 -58
  46. data/lib/trailblazer/operation/railway/task_builder.rb +0 -37
  47. data/test/inspect_test.rb +0 -43
  48. data/test/macro_test.rb +0 -60
  49. data/test/task_wrap_test.rb +0 -97
@@ -4,11 +4,11 @@ require 'trailblazer/operation/version'
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "trailblazer-operation"
7
- spec.version = Trailblazer::Operation::VERSION
7
+ spec.version = Trailblazer::Version::Operation::VERSION
8
8
  spec.authors = ["Nick Sutterer"]
9
9
  spec.email = ["apotonick@gmail.com"]
10
- spec.description = %q{Trailblazer's operation object.}
11
- spec.summary = %q{Trailblazer's operation object with railway flow and integrated error handling.}
10
+ spec.description = %q(Trailblazer's operation object.)
11
+ spec.summary = %q(Trailblazer's operation object with railway flow and integrated error handling.)
12
12
  spec.homepage = "http://trailblazer.to"
13
13
  spec.license = "MIT"
14
14
 
@@ -17,12 +17,14 @@ Gem::Specification.new do |spec|
17
17
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
18
  spec.require_paths = ["lib"]
19
19
 
20
- spec.add_dependency "trailblazer-activity", ">= 0.7.1", "< 0.8.0"
21
- spec.add_dependency "trailblazer-context", ">= 0.1.1", "< 0.3.0"
20
+ spec.add_dependency "trailblazer-activity-dsl-linear", ">= 0.2.1", "< 1.0.0"
21
+ spec.add_dependency "trailblazer-activity", ">= 0.10.0", "< 1.0.0"
22
+ spec.add_dependency "trailblazer-developer", ">= 0.0.8"
22
23
 
23
24
  spec.add_development_dependency "bundler"
24
- spec.add_development_dependency "rake"
25
25
  spec.add_development_dependency "minitest"
26
+ spec.add_development_dependency "rake"
27
+ spec.add_development_dependency "rubocop"
26
28
 
27
- spec.required_ruby_version = '>= 2.0.0'
29
+ spec.required_ruby_version = ">= 2.1.0"
28
30
  end
metadata CHANGED
@@ -1,55 +1,69 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trailblazer-operation
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Sutterer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-18 00:00:00.000000000 Z
11
+ date: 2019-09-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: trailblazer-activity
14
+ name: trailblazer-activity-dsl-linear
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.7.1
19
+ version: 0.2.1
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
- version: 0.8.0
22
+ version: 1.0.0
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: 0.7.1
29
+ version: 0.2.1
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: 0.8.0
32
+ version: 1.0.0
33
33
  - !ruby/object:Gem::Dependency
34
- name: trailblazer-context
34
+ name: trailblazer-activity
35
35
  requirement: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - ">="
38
38
  - !ruby/object:Gem::Version
39
- version: 0.1.1
39
+ version: 0.10.0
40
40
  - - "<"
41
41
  - !ruby/object:Gem::Version
42
- version: 0.3.0
42
+ version: 1.0.0
43
43
  type: :runtime
44
44
  prerelease: false
45
45
  version_requirements: !ruby/object:Gem::Requirement
46
46
  requirements:
47
47
  - - ">="
48
48
  - !ruby/object:Gem::Version
49
- version: 0.1.1
49
+ version: 0.10.0
50
50
  - - "<"
51
51
  - !ruby/object:Gem::Version
52
- version: 0.3.0
52
+ version: 1.0.0
53
+ - !ruby/object:Gem::Dependency
54
+ name: trailblazer-developer
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: 0.0.8
60
+ type: :runtime
61
+ prerelease: false
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: 0.0.8
53
67
  - !ruby/object:Gem::Dependency
54
68
  name: bundler
55
69
  requirement: !ruby/object:Gem::Requirement
@@ -64,6 +78,20 @@ dependencies:
64
78
  - - ">="
65
79
  - !ruby/object:Gem::Version
66
80
  version: '0'
81
+ - !ruby/object:Gem::Dependency
82
+ name: minitest
83
+ requirement: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
67
95
  - !ruby/object:Gem::Dependency
68
96
  name: rake
69
97
  requirement: !ruby/object:Gem::Requirement
@@ -79,7 +107,7 @@ dependencies:
79
107
  - !ruby/object:Gem::Version
80
108
  version: '0'
81
109
  - !ruby/object:Gem::Dependency
82
- name: minitest
110
+ name: rubocop
83
111
  requirement: !ruby/object:Gem::Requirement
84
112
  requirements:
85
113
  - - ">="
@@ -100,6 +128,8 @@ extensions: []
100
128
  extra_rdoc_files: []
101
129
  files:
102
130
  - ".gitignore"
131
+ - ".rubocop.yml"
132
+ - ".rubocop_todo.yml"
103
133
  - ".travis.yml"
104
134
  - CHANGES.md
105
135
  - Gemfile
@@ -108,16 +138,11 @@ files:
108
138
  - lib/trailblazer/operation.rb
109
139
  - lib/trailblazer/operation/callable.rb
110
140
  - lib/trailblazer/operation/class_dependencies.rb
141
+ - lib/trailblazer/operation/container.rb
111
142
  - lib/trailblazer/operation/deprecated_macro.rb
112
- - lib/trailblazer/operation/heritage.rb
113
- - lib/trailblazer/operation/inject.rb
114
- - lib/trailblazer/operation/inspect.rb
115
143
  - lib/trailblazer/operation/public_call.rb
116
144
  - lib/trailblazer/operation/railway.rb
117
- - lib/trailblazer/operation/railway/fast_track.rb
118
145
  - lib/trailblazer/operation/railway/macaroni.rb
119
- - lib/trailblazer/operation/railway/normalizer.rb
120
- - lib/trailblazer/operation/railway/task_builder.rb
121
146
  - lib/trailblazer/operation/result.rb
122
147
  - lib/trailblazer/operation/trace.rb
123
148
  - lib/trailblazer/operation/version.rb
@@ -136,16 +161,13 @@ files:
136
161
  - test/gemfiles/Gemfile.ruby-2.0.lock
137
162
  - test/gemfiles/Gemfile.ruby-2.3
138
163
  - test/inheritance_test.rb
139
- - test/inspect_test.rb
140
164
  - test/introspect_test.rb
141
- - test/macro_test.rb
142
165
  - test/operation_test.rb
143
166
  - test/result_test.rb
144
167
  - test/ruby-2.0.0/operation_test.rb
145
168
  - test/ruby-2.0.0/step_test.rb
146
169
  - test/skill_test.rb
147
170
  - test/step_test.rb
148
- - test/task_wrap_test.rb
149
171
  - test/test_helper.rb
150
172
  - test/trace_test.rb
151
173
  - test/wire_test.rb
@@ -164,7 +186,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
164
186
  requirements:
165
187
  - - ">="
166
188
  - !ruby/object:Gem::Version
167
- version: 2.0.0
189
+ version: 2.1.0
168
190
  required_rubygems_version: !ruby/object:Gem::Requirement
169
191
  requirements:
170
192
  - - ">="
@@ -172,7 +194,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
172
194
  version: '0'
173
195
  requirements: []
174
196
  rubyforge_project:
175
- rubygems_version: 2.7.3
197
+ rubygems_version: 2.7.6
176
198
  signing_key:
177
199
  specification_version: 4
178
200
  summary: Trailblazer's operation object with railway flow and integrated error handling.
@@ -192,16 +214,13 @@ test_files:
192
214
  - test/gemfiles/Gemfile.ruby-2.0.lock
193
215
  - test/gemfiles/Gemfile.ruby-2.3
194
216
  - test/inheritance_test.rb
195
- - test/inspect_test.rb
196
217
  - test/introspect_test.rb
197
- - test/macro_test.rb
198
218
  - test/operation_test.rb
199
219
  - test/result_test.rb
200
220
  - test/ruby-2.0.0/operation_test.rb
201
221
  - test/ruby-2.0.0/step_test.rb
202
222
  - test/skill_test.rb
203
223
  - test/step_test.rb
204
- - test/task_wrap_test.rb
205
224
  - test/test_helper.rb
206
225
  - test/trace_test.rb
207
226
  - test/wire_test.rb
@@ -1,30 +0,0 @@
1
- module Trailblazer
2
- # This is copied from the Declarative gem. This might get removed in favor of a real heritage gem.
3
- class Operation
4
- class Heritage < Array
5
- # Record inheritable assignments for replay in an inheriting class.
6
- def record(method, *args, &block)
7
- self << { method: method, args: args, block: block }
8
- end
9
-
10
- # Replay the recorded assignments on inheritor.
11
- # Accepts a block that will allow processing the arguments for every recorded statement.
12
- def call(inheritor, &block)
13
- each { |cfg| call!(inheritor, cfg, &block) }
14
- end
15
-
16
- private
17
- def call!(inheritor, cfg)
18
- yield cfg if block_given? # allow messing around with recorded arguments.
19
-
20
- inheritor.send(cfg[:method], *cfg[:args], &cfg[:block])
21
- end
22
-
23
- module Accessor
24
- def heritage
25
- @heritage ||= Heritage.new
26
- end
27
- end
28
- end
29
- end
30
- end
@@ -1,36 +0,0 @@
1
- module Trailblazer
2
- module Operation::Wrap
3
- module Inject
4
- # Returns an Alteration wirings that, when applied, inserts the {ReverseMergeDefaults} task
5
- # before the {Wrap::Call} task. This is meant for macros and steps that accept a dependency
6
- # injection but need a default parameter to be set if not injected.
7
- # @returns ADDS
8
- def self.Defaults(default_dependencies)
9
- Module.new do
10
- extend Activity::Path::Plan()
11
-
12
- task ReverseMergeDefaults.new( default_dependencies ),
13
- id: "ReverseMergeDefaults#{default_dependencies}",
14
- before: "task_wrap.call_task"
15
- end
16
- end
17
-
18
- # @api private
19
- # @returns Task
20
- # @param Hash list of key/value that should be set if not already assigned/set before (or injected from the outside).
21
- class ReverseMergeDefaults
22
- def initialize(defaults)
23
- @defaults = defaults
24
- end
25
-
26
- def call((wrap_ctx, original_args), **circuit_options)
27
- ctx = original_args[0][0]
28
-
29
- @defaults.each { |k, v| ctx[k] ||= v }
30
-
31
- return Activity::Right, [ wrap_ctx, original_args ]
32
- end
33
- end
34
- end # Inject
35
- end
36
- end
@@ -1,79 +0,0 @@
1
- module Trailblazer
2
- # Operation-specific circuit rendering. This is optimized for a linear railway circuit.
3
- #
4
- # @private
5
- #
6
- # NOTE: this is absolutely to be considered as prototyping and acts more like a test helper ATM as
7
- # Inspect is not a mission-critical part.
8
- class Operation
9
- def self.introspect(*args)
10
- Operation::Inspect.(*args)
11
- end
12
- end
13
-
14
- module Operation::Inspect
15
- module_function
16
-
17
- def call(operation, options={ style: :line })
18
- # TODO: better introspection API.
19
-
20
- alterations = Activity::Magnetic::Builder::Finalizer.adds_to_alterations(operation.to_h[:adds])
21
- # DISCUSS: any other way to retrieve the Alterations?
22
-
23
- # pp alterations
24
- railway = alterations.instance_variable_get(:@groups).instance_variable_get(:@groups)[:main]
25
-
26
- rows = railway.each_with_index.collect do |element, i|
27
- magnetic_to, task, plus_poles = element.configuration
28
-
29
- created_by =
30
- if magnetic_to == [:failure]
31
- :fail
32
- elsif plus_poles.size > 1
33
- plus_poles[0].color == plus_poles[1].color ? :pass : :step
34
- else
35
- :pass # this is wrong for Nested, sometimes
36
- end
37
-
38
- [ i, [ created_by, element.id ] ]
39
- end
40
-
41
- return inspect_line(rows) if options[:style] == :line
42
- return inspect_rows(rows)
43
- end
44
-
45
- def inspect_func(step)
46
- @inspect[step]
47
- end
48
-
49
- Operator = { :fail => "<<", :pass => ">>", :step => ">"}
50
-
51
- def inspect_line(names)
52
- string = names.collect { |i, (end_of_edge, name)| "#{Operator[end_of_edge]}#{name}" }.join(",")
53
- "[#{string}]"
54
- end
55
-
56
- def inspect_rows(names)
57
- string = names.collect do |i, (end_of_edge, name)|
58
- operator = Operator[end_of_edge]
59
-
60
- op = "#{operator}#{name}"
61
- padding = 38
62
-
63
- proc = if operator == "<<"
64
- sprintf("%- #{padding}s", op)
65
- elsif [">", ">>", "&"].include?(operator.to_s)
66
- sprintf("% #{padding}s", op)
67
- else
68
- pad = " " * ((padding - op.length) / 2)
69
- "#{pad}#{op}#{pad}"
70
- end
71
-
72
- proc = proc.gsub(" ", "=")
73
-
74
- sprintf("%2d %s", i, proc)
75
- end.join("\n")
76
- "\n#{string}"
77
- end
78
- end
79
- end
@@ -1,13 +0,0 @@
1
- module Trailblazer
2
- module Operation::Railway
3
- def self.fail! ; Activity::Left end
4
- def self.pass! ; Activity::Right end
5
- def self.fail_fast!; Activity::FastTrack::FailFast end
6
- def self.pass_fast!; Activity::FastTrack::PassFast end
7
-
8
- module End
9
- FailFast = Class.new(Operation::Railway::End::Failure)
10
- PassFast = Class.new(Operation::Railway::End::Success)
11
- end
12
- end
13
- end
@@ -1,58 +0,0 @@
1
- module Trailblazer
2
- module Operation::Railway
3
- # The {Normalizer} is called for every DSL call (step/pass/fail etc.) and normalizes/defaults
4
- # the user options, such as setting `:id`, connecting the task's outputs or wrapping the user's
5
- # task via {TaskBuilder} in order to translate true/false to `Right` or `Left`.
6
- #
7
- # The Normalizer sits in the `@builder`, which receives all DSL calls from the Operation subclass.
8
- module Normalizer
9
- Pipeline = Activity::Magnetic::Normalizer::Pipeline.clone
10
-
11
- Pipeline.module_eval do
12
- # Handle the :override option which is specific to Operation.
13
- def self.override(ctx, task:, options:, sequence_options:, **)
14
- options, locals = Activity::Magnetic::Options.normalize(options, [:override])
15
- sequence_options = sequence_options.merge( replace: options[:id] ) if locals[:override]
16
-
17
- ctx[:options], ctx[:sequence_options] = options, sequence_options
18
- end
19
-
20
- # TODO remove in 2.2
21
- def self.deprecate_macro_with_two_args(ctx, task:, **)
22
- return true unless task.is_a?(Array) # TODO remove in 2.2
23
-
24
- ctx[:options] = Operation::DeprecatedMacro.( *task )
25
- end
26
-
27
- # TODO remove in 2.2
28
- def self.deprecate_name(ctx, local_options:, connection_options:, **)
29
- connection_options, deprecated_options = Activity::Magnetic::Options.normalize(connection_options, [:name])
30
- local_options, _deprecated_options = Activity::Magnetic::Options.normalize(local_options, [:name])
31
-
32
- deprecated_options = deprecated_options.merge(_deprecated_options)
33
-
34
- local_options = local_options.merge( name: deprecated_options[:name] ) if deprecated_options[:name]
35
-
36
- local_options, locals = Activity::Magnetic::Options.normalize(local_options, [:name])
37
- if locals[:name]
38
- warn "[Trailblazer] The :name option for #step, #success and #failure has been renamed to :id."
39
- local_options = local_options.merge(id: locals[:name])
40
- end
41
-
42
- ctx[:local_options], ctx[:connection_options] = local_options, connection_options
43
- end
44
-
45
- def self.raise_on_missing_id(ctx, local_options:, **)
46
- raise "No :id given for #{local_options[:task]}" unless local_options[:id]
47
- true
48
- end
49
-
50
- # add more normalization tasks to the existing Magnetic::Normalizer::Pipeline
51
- task Activity::TaskBuilder::Binary( method(:deprecate_macro_with_two_args) ), before: "split_options"
52
- task Activity::TaskBuilder::Binary( method(:deprecate_name) )
53
- task Activity::TaskBuilder::Binary( method(:override) )
54
- task Activity::TaskBuilder::Binary( method(:raise_on_missing_id) )
55
- end
56
- end # Normalizer
57
- end
58
- end
@@ -1,37 +0,0 @@
1
- module Trailblazer
2
- module Operation::Railway
3
- # every step is wrapped by this proc/decider. this is executed in the circuit as the actual task.
4
- # Step calls step.(options, **options, flow_options)
5
- # Output direction binary: true=>Right, false=>Left.
6
- # Passes through all subclasses of Direction.~~~~~~~~~~~~~~~~~
7
- module TaskBuilder
8
- def self.call(user_proc)
9
- Task.new( Trailblazer::Option::KW( user_proc ), user_proc )
10
- end
11
-
12
- # Translates the return value of the user step into a valid signal.
13
- # Note that it passes through subclasses of {Signal}.
14
- def self.binary_direction_for(result, on_true, on_false)
15
- result.is_a?(Class) && result < Activity::Signal ? result : (result ? on_true : on_false)
16
- end
17
- end
18
-
19
- class Task
20
- def initialize(task, user_proc)
21
- @task = task
22
- @user_proc = user_proc
23
- freeze
24
- end
25
-
26
- def call( (options, *args), **circuit_args )
27
- # Execute the user step with TRB's kw args.
28
- result = @task.( options, **circuit_args ) # circuit_args contains :exec_context.
29
-
30
- # Return an appropriate signal which direction to go next.
31
- direction = TaskBuilder.binary_direction_for( result, Activity::Right, Activity::Left )
32
-
33
- [ direction, [ options, *args ], **circuit_args ]
34
- end
35
- end
36
- end
37
- end