trailblazer-operation 0.2.2 → 0.2.3

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: 3374814d5a9e505e40d20d3598a3d67fd868a476659ab7a1c73685aa7a8cc375
4
- data.tar.gz: 1e26729cfc2319be1644de1bdb38bcf35715f25adc355ecdb386d7abc5cb158f
3
+ metadata.gz: 9087723ae9650669c304ea1451156be3a8b1d42cb04a46bd228ab7060b8b321c
4
+ data.tar.gz: 193d554218c156f0817692a6841ea55ddf5b87b537bc52957b586de5a6487826
5
5
  SHA512:
6
- metadata.gz: 3d4b658f8f3c97d2b011949fbc19b2e58ea8e2b5ce192dd280540a6040429b20536ddb400f29c0a6be19a7588ab360f928071d2bcef6c69d88c84a24a9470abe
7
- data.tar.gz: 05fc186cec428608351635c2e33f196489e4a813913574019ad1f95a1d90d0b974a2e0b33154ed0feb9d785eee962e7fc8205f11c364bf423e058ce484894398
6
+ metadata.gz: c60ef931a4c9f45be7285700d29e8ac5f5d912634df7fdbae07014283d1c60731469eececbe2aeecfa1bb8c3531ed9703b00d21e99be1d5f4c705624a1ff7821
7
+ data.tar.gz: d3684f685583bc322efd275fc8b14653cc408c4d56c18ab099753480166b0ad6882ad4cf9fa103bb781ca8d73b4f164f331abd7bc8396c7085bf748e828c3be3
data/Gemfile CHANGED
@@ -20,4 +20,4 @@ gem "benchmark-ips"
20
20
 
21
21
  # gem "declarative", path: "../declarative"
22
22
 
23
- gem "trailblazer-activity"#, path: "../circuit"
23
+ gem "trailblazer-activity", path: "../trailblazer-circuit"
@@ -6,10 +6,11 @@ require "trailblazer/context"
6
6
  require "trailblazer/container_chain"
7
7
 
8
8
  require "trailblazer/activity"
9
- require "trailblazer/activity/magnetic"
9
+ require "trailblazer/activity/dsl/magnetic"
10
10
 
11
11
 
12
12
  require "trailblazer/operation/variable_mapping"
13
+ require "trailblazer/operation/callable"
13
14
 
14
15
  require "trailblazer/operation/heritage"
15
16
  require "trailblazer/operation/public_call" # TODO: Remove in 3.0.
@@ -78,7 +79,7 @@ module Trailblazer
78
79
 
79
80
  class << self
80
81
  extend Forwardable # TODO: test those helpers
81
- def_delegators :@activity, :Path, :Output, :End
82
+ def_delegators :@activity, :Path, :Output, :End, :Track
82
83
  def_delegators :@activity, :outputs, :debug
83
84
 
84
85
  def step(task, options={}, &block); add_task!(:step, task, options, &block) end
@@ -0,0 +1,42 @@
1
+ module Trailblazer
2
+ class Operation
3
+ # Use {Callable} if you have an operation or any other callable object that does
4
+ # _not_ expose an {Activity interface}. For example, {Operation.call} isn't compatible
5
+ # with activities, hence you need to decorate it using {Callable}. The returned object
6
+ # exposes an {Activity interface}.
7
+ #
8
+ # @param :call [Symbol] Method name to call
9
+ # @param options [Hash] Hash to merge into {circuit_options}, e.g. {:start_task}.
10
+ #
11
+ # @example Create and use a Callable instance.
12
+ # callable = Trailblazer::Operation::Callable( Memo::Create, call: :__call__ )
13
+ # callable.( [ctx, {}] ) #=> Activity interface, ::call will invoke Memo::Create.__call__.
14
+ def self.Callable(*args)
15
+ Callable.new(*args)
16
+ end
17
+
18
+ # Subprocess allows to have tasks with a different call interface and start event.
19
+ # @param activity any object with an {Activity interface}
20
+ class Callable
21
+ include Activity::Interface
22
+
23
+ def initialize(activity, call: :call, **options)
24
+ @activity = activity
25
+ @options = options
26
+ @call = call
27
+ end
28
+
29
+ def call(args, **circuit_options)
30
+ @activity.public_send(@call, args, circuit_options.merge(@options))
31
+ end
32
+
33
+ extend Forwardable
34
+ # @private
35
+ def_delegators :@activity, :to_h, :debug
36
+
37
+ def to_s
38
+ %{#<Trailblazer::Activity::Callable activity=#{@activity}>}
39
+ end
40
+ end
41
+ end
42
+ end
@@ -1,5 +1,5 @@
1
1
  module Trailblazer
2
2
  class Operation
3
- VERSION = "0.2.2"
3
+ VERSION = "0.2.3"
4
4
  end
5
5
  end
@@ -0,0 +1,147 @@
1
+ require "test_helper"
2
+
3
+ class CallableHelper < Minitest::Spec
4
+ Operation = Trailblazer::Operation
5
+ Activity = Trailblazer::Activity
6
+
7
+ module Blog
8
+ Read = ->((options, *args), *) { options["Read"] = 1; [ Activity::Right, [options, *args] ] }
9
+ Next = ->((options, *args), *) { options["NextPage"] = []; [ options["return"], [options, *args] ] }
10
+ Comment = ->((options, *args), *) { options["Comment"] = 2; [ Activity::Right, [options, *args] ] }
11
+ end
12
+
13
+ module User
14
+ Relax = ->((options, *args), *) { options["Relax"]=true; [ Activity::Right, [options, *args] ] }
15
+ end
16
+
17
+ ### Callable( )
18
+ ###
19
+ describe "circuit with 1 level of nesting" do # TODO: test this kind of configuration in dsl_tests somewhere.
20
+ let(:blog) do
21
+ Module.new do
22
+ extend Activity::Path()
23
+
24
+ task task: Blog::Read
25
+ task task: Blog::Next, Output(Activity::Right, :done) => "End.success", Output(Activity::Left, :success) => Track(:success)
26
+ task task: Blog::Comment
27
+ end
28
+ end
29
+
30
+ let(:user) do
31
+ _blog = blog
32
+
33
+ Module.new do
34
+ extend Activity::Path()
35
+
36
+ task task: _blog, _blog.outputs[:success] => Track(:success)
37
+ task task: User::Relax
38
+ end
39
+ end
40
+
41
+ it "ends before comment, on next_page" do
42
+ user.( [options = { "return" => Activity::Right }] ).must_equal(
43
+ [user.outputs[:success].signal, [{"return"=>Trailblazer::Activity::Right, "Read"=>1, "NextPage"=>[], "Relax"=>true}]]
44
+ )
45
+
46
+ options.must_equal({"return"=>Trailblazer::Activity::Right, "Read"=>1, "NextPage"=>[], "Relax"=>true})
47
+ end
48
+ end
49
+
50
+ ### Callable( End1, End2 )
51
+ ###
52
+ describe "circuit with 2 end events in the nested process" do
53
+ let(:blog) do
54
+ Module.new do
55
+ extend Activity::Path()
56
+
57
+ task task: Blog::Read
58
+ task task: Blog::Next, Output(Activity::Right, :success___) => :__success, Output(Activity::Left, :retry___) => _retry=End(:retry)
59
+ end
60
+ end
61
+
62
+ let(:user) do
63
+ _blog = blog
64
+
65
+ Module.new do
66
+ extend Activity::Path()
67
+
68
+ task task: _blog, _blog.outputs[:success] => Track(:success), _blog.outputs[:retry] => "End.success"
69
+ task task: User::Relax
70
+ end
71
+ end
72
+
73
+ it "runs from Callable->default to Relax" do
74
+ user.( [ options = { "return" => Activity::Right } ] ).must_equal [
75
+ user.outputs[:success].signal,
76
+ [ {"return"=>Activity::Right, "Read"=>1, "NextPage"=>[], "Relax"=>true} ]
77
+ ]
78
+
79
+ options.must_equal({"return"=>Activity::Right, "Read"=>1, "NextPage"=>[], "Relax"=>true})
80
+ end
81
+
82
+ it "runs from other Callable end" do
83
+ user.( [ options = { "return" => Activity::Left } ] ).must_equal [
84
+ user.outputs[:success].signal,
85
+ [ {"return"=>Activity::Left, "Read"=>1, "NextPage"=>[]} ]
86
+ ]
87
+
88
+ options.must_equal({"return"=>Activity::Left, "Read"=>1, "NextPage"=>[]})
89
+ end
90
+
91
+ #---
92
+ #- Callable( activity, start_at )
93
+ let(:with_nested_and_start_at) do
94
+ _blog = blog
95
+
96
+ Module.new do
97
+ extend Activity::Path()
98
+
99
+ task task: Operation::Callable( _blog, task: Blog::Next ), _blog.outputs[:success] => Track(:success)
100
+ task task: User::Relax
101
+ end
102
+ end
103
+
104
+ it "runs Callable from alternative start" do
105
+ with_nested_and_start_at.( [options = { "return" => Activity::Right }] ).
106
+ must_equal [
107
+ with_nested_and_start_at.outputs[:success].signal,
108
+ [ {"return"=>Activity::Right, "NextPage"=>[], "Relax"=>true} ]
109
+ ]
110
+
111
+ options.must_equal({"return"=>Activity::Right, "NextPage"=>[], "Relax"=>true})
112
+ end
113
+
114
+ #---
115
+ #- Callable( activity, call: :__call__ ) { ... }
116
+ describe "Callable with :call option" do
117
+ let(:process) do
118
+ class Workout
119
+ def self.__call__((options, *args), *)
120
+ options[:workout] = 9
121
+
122
+ return Activity::Right, [options, *args]
123
+ end
124
+ end
125
+
126
+ subprocess = Operation::Callable( Workout, call: :__call__ )
127
+
128
+ Module.new do
129
+ extend Activity::Path()
130
+
131
+ task task: subprocess
132
+ task task: User::Relax
133
+ end
134
+ end
135
+
136
+ it "runs Callable process with __call__" do
137
+ process.( [options = { "return" => Activity::Right }] ).
138
+ must_equal [
139
+ process.outputs[:success].signal,
140
+ [{"return"=>Activity::Right, :workout=>9, "Relax"=>true}]
141
+ ]
142
+
143
+ options.must_equal({"return"=>Activity::Right, :workout=>9, "Relax"=>true})
144
+ end
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,23 @@
1
+ require "test_helper"
2
+
3
+ class DocsActivityTest < Minitest::Spec
4
+ Memo = Struct.new(:body)
5
+
6
+ class Memo::Create < Trailblazer::Operation
7
+ step :create_model
8
+ def create_model(ctx, params:, **)
9
+ ctx[:model] = Memo.new(params[:body])
10
+ end
11
+ end
12
+
13
+ #:describe
14
+ describe Memo::Create do
15
+ it "creates a sane Memo instance" do
16
+ result = Memo::Create.( params: { body: "Enjoy an IPA" } )
17
+
18
+ result.success?.must_equal true
19
+ result[:model].body.must_equal "Enjoy an IPA"
20
+ end
21
+ end
22
+ #:describe end
23
+ end
@@ -314,7 +314,7 @@ class WiringsDocSeqOptionsTest < Minitest::Spec
314
314
  Memo = Id::Memo
315
315
  #:id-inspect
316
316
  Trailblazer::Operation.introspect( Memo::Create )
317
- #=> [>create_model,>validate_params,>save]
317
+ #=> [>create_memo,>validate_params,>save]
318
318
  #:id-inspect end
319
319
 
320
320
  Trailblazer::Operation.introspect( Memo::Create ).must_equal %{[>create_memo,>validate_params,>save]}
@@ -368,10 +368,10 @@ class WiringsDocRecoverTest < Minitest::Spec
368
368
  #:fail-success
369
369
  class Memo::Upload < Trailblazer::Operation
370
370
  step :upload_to_s3
371
- fail :upload_to_azure, Output(:success) => :success
372
- fail :upload_to_b2, Output(:success) => :success
371
+ fail :upload_to_azure, Output(:success) => Track(:success)
372
+ fail :upload_to_b2, Output(:success) => Track(:success)
373
373
  fail :log_problem
374
- #~fail-success-methods
374
+ #~methods
375
375
  #:fail-success-s3
376
376
  def upload_to_s3(options, s3:, **)
377
377
  options[:s3] = s3 # the actual upload is dispatched here and result collected.
@@ -389,7 +389,7 @@ class WiringsDocRecoverTest < Minitest::Spec
389
389
  def log_problem(options, **)
390
390
  options[:problem] = "All uploads failed."
391
391
  end
392
- #~fail-success-methods end
392
+ #~methods end
393
393
  end
394
394
  #:fail-success end
395
395
 
@@ -477,11 +477,11 @@ class WiringsDocDeciderTest < Minitest::Spec
477
477
 
478
478
  #:decider
479
479
  class Memo::Upsert < Trailblazer::Operation
480
- step :find_model, Output(:failure) => :create_route
480
+ step :find_model, Output(:failure) => Track(:create_route)
481
481
  step :update
482
482
  step :create, magnetic_to: [:create_route]
483
483
  step :save
484
- #~decm
484
+ #~methods
485
485
  def find_model(options, id:nil, **)
486
486
  options[:model] = Memo.find(id)
487
487
  end
@@ -498,7 +498,7 @@ class WiringsDocDeciderTest < Minitest::Spec
498
498
  def save(options, **)
499
499
  options[:save] = true
500
500
  end
501
- #~decm end
501
+ #~methods end
502
502
  end
503
503
  #:decider end
504
504
 
@@ -126,8 +126,8 @@ class NestedFastTrackTest < Minitest::Spec
126
126
  describe "Nested, fast_track: true and all its outputs given" do
127
127
  let(:update) do
128
128
  Class.new(Trailblazer::Operation) do
129
- step task: Trailblazer::Activity::Subprocess( Edit, call: :__call__ ), id: "Subprocess/",
130
- plus_poles: Trailblazer::Activity::Magnetic::DSL::PlusPoles::from_outputs( Edit.outputs ),
129
+ step task: Trailblazer::Operation::Callable( Edit, call: :__call__ ), id: "Callable/",
130
+ outputs: Edit.outputs ,
131
131
  fast_track: true
132
132
  step :b
133
133
  fail :f
@@ -151,8 +151,8 @@ class NestedFastTrackTest < Minitest::Spec
151
151
  Class.new(Trailblazer::Operation) do
152
152
  include Steps
153
153
 
154
- step task: Trailblazer::Activity::Subprocess( Edit, call: :__call__ ), id: "Subprocess/",
155
- plus_poles: Trailblazer::Activity::Magnetic::DSL::PlusPoles::from_outputs( Edit.outputs ) # all outputs given means it "works"
154
+ step task: Trailblazer::Operation::Callable( Edit, call: :__call__ ), id: "Callable/",
155
+ outputs: Edit.outputs # all outputs given means it "works"
156
156
  step :b
157
157
  fail :f
158
158
  end
@@ -173,9 +173,9 @@ class NestedFastTrackTest < Minitest::Spec
173
173
  Class.new(Trailblazer::Operation) do
174
174
  include Steps
175
175
 
176
- step({task: Trailblazer::Activity::Subprocess( Edit, call: :__call__ ), id: "Subprocess/",
177
- plus_poles: Trailblazer::Activity::Magnetic::DSL::PlusPoles::from_outputs( Edit.outputs )},
178
- {Output(:pass_fast) => :success, Output(:fail_fast) => :failure} )# manually rewire the fast-track outputs to "conventional" railway ends.
176
+ step({task: Trailblazer::Operation::Callable( Edit, call: :__call__ ), id: "Callable/",
177
+ outputs: Edit.outputs },
178
+ {Output(:pass_fast) => Track(:success), Output(:fail_fast) => Track(:failure)} )# manually rewire the fast-track outputs to "conventional" railway ends.
179
179
 
180
180
  step :b
181
181
  fail :f
@@ -31,9 +31,9 @@ class InspectTest < Minitest::Spec
31
31
  5 ============================>finalize!}
32
32
  end
33
33
 
34
- describe "step with only one plus pole (happens with Nested)" do
34
+ describe "step with only one output (happens with Nested)" do
35
35
  class Present < Trailblazer::Operation
36
- pass :ok!, plus_poles: Trailblazer::Activity::Magnetic::DSL::PlusPoles::from_outputs( :success => Trailblazer::Activity.Output("signal", :success) )
36
+ pass :ok!, outputs: {:success => Trailblazer::Activity::Output("signal", :success)}
37
37
  end
38
38
 
39
39
  it do
@@ -5,8 +5,6 @@ require "test_helper"
5
5
  # macro [ task, {name}, { alteration: }, {task_outputs} ] # for eg. nested
6
6
 
7
7
  class MacroTest < Minitest::Spec
8
- PlusPoles = Trailblazer::Activity::Magnetic::DSL::PlusPoles
9
-
10
8
  MacroB = ->(( options, *args ), **) do
11
9
  options[:B] = true # we were here!
12
10
 
@@ -26,7 +24,7 @@ class MacroTest < Minitest::Spec
26
24
 
27
25
  class Create < Trailblazer::Operation
28
26
  step :a
29
- step( task: MacroB, id: :MacroB, plus_poles: Test.plus_poles_for("Allgood" => :success, "Fail!" => :failure, "Winning" => :pass_fast) )
27
+ step task: MacroB, id: :MacroB, outputs: { :success => Activity::Output("Allgood", :success), :failure => Activity::Output("Fail!", :failure), :pass_fast => Activity::Output("Winning", :pass_fast) }
30
28
  step :c
31
29
 
32
30
  def a(options, **); options[:a] = true end
@@ -42,10 +40,11 @@ class MacroTest < Minitest::Spec
42
40
 
43
41
  #- user overrides :plus_poles
44
42
  class Update < Trailblazer::Operation
45
- macro = { task: MacroB, id: :MacroB, plus_poles: Test.plus_poles_for("Allgood" => :success, "Fail!" => :failure, "Winning" => :pass_fast) }
43
+ macro = { task: MacroB, id: :MacroB, outputs: { :success => Activity::Output("Allgood", :success), :failure => Activity::Output("Fail!", :failure), :pass_fast => Activity::Output("Winning", :pass_fast) } }
46
44
 
47
45
  step :a
48
- step macro, plus_poles: Test.plus_poles_for("Allgood" => :failure, "Fail!" => :success, "Winning" => :fail_fast)
46
+ step macro, outputs: { :success => Activity::Output("Fail!", :success), :fail_fast => Activity::Output("Winning", :fail_fast), :failure => Activity::Output("Allgood", :failure) }
47
+ # plus_poles: Test.plus_poles_for("Allgood" => :failure, "Fail!" => :success, "Winning" => :fail_fast)
49
48
  step :c
50
49
 
51
50
  def a(options, **); options[:a] = true end
@@ -35,5 +35,5 @@ module Test
35
35
  end
36
36
 
37
37
  Minitest::Spec.class_eval do
38
-
38
+ Activity = Trailblazer::Activity
39
39
  end
@@ -12,7 +12,7 @@ class TraceTest < Minitest::Spec
12
12
 
13
13
  class Create < Trailblazer::Operation
14
14
  step ->(options, a_return:, **) { options[:a] = a_return }, id: "Create.task.a"
15
- step( {task: B, id: "MyNested"}, B.outputs[:success] => :success )
15
+ step( {task: B, id: "MyNested"}, B.outputs[:success] => Track(:success) )
16
16
  step ->(options, **) { options[:c] = true }, id: "Create.task.c"
17
17
  step ->(options, params:, **) { params.any? }, id: "Create.task.params"
18
18
 
@@ -79,8 +79,8 @@ require "test_helper"
79
79
  class WireDefaultsEarlyExitSuccessTest < Minitest::Spec
80
80
  class Create < Trailblazer::Operation
81
81
  step :a
82
- fail :b, Output(:success) => :success #{}"End.success"
83
- fail :c, Output(:success) => :success
82
+ fail :b, Output(:success) => Track(:success) #{}"End.success"
83
+ fail :c, Output(:success) => Track(:success)
84
84
 
85
85
  Test.step(self, :a, :b, :c)
86
86
  end
@@ -99,7 +99,7 @@ class WireDefaultsEarlyExitSuccessTest < Minitest::Spec
99
99
 
100
100
 
101
101
  # #---
102
- # # with => :success, steps can still be added before End.success and they will be executed.
102
+ # # with => Track(:success), steps can still be added before End.success and they will be executed.
103
103
  class Update < Create
104
104
  pass :d
105
105
 
@@ -17,7 +17,7 @@ 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.4.2", "< 0.5.0"
20
+ spec.add_dependency "trailblazer-activity", ">= 0.5.0", "< 0.7.0"
21
21
  spec.add_dependency "trailblazer-context", ">= 0.1.1", "< 0.3.0"
22
22
 
23
23
  spec.add_development_dependency "bundler"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trailblazer-operation
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.3
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-01-24 00:00:00.000000000 Z
11
+ date: 2018-03-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: trailblazer-activity
@@ -16,20 +16,20 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.4.2
19
+ version: 0.5.0
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
- version: 0.5.0
22
+ version: 0.7.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.4.2
29
+ version: 0.5.0
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: 0.5.0
32
+ version: 0.7.0
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: trailblazer-context
35
35
  requirement: !ruby/object:Gem::Requirement
@@ -106,6 +106,7 @@ files:
106
106
  - README.md
107
107
  - Rakefile
108
108
  - lib/trailblazer/operation.rb
109
+ - lib/trailblazer/operation/callable.rb
109
110
  - lib/trailblazer/operation/deprecated_macro.rb
110
111
  - lib/trailblazer/operation/heritage.rb
111
112
  - lib/trailblazer/operation/inject.rb
@@ -123,9 +124,11 @@ files:
123
124
  - lib/trailblazer/operation/version.rb
124
125
  - test/benchmark/skill_resolver_benchmark.rb
125
126
  - test/call_test.rb
127
+ - test/callable_test.rb
126
128
  - test/class_dependencies_test.rb
127
129
  - test/docs/doormat_test.rb
128
130
  - test/docs/macaroni_test.rb
131
+ - test/docs/operation_test.rb
129
132
  - test/docs/wiring_test.rb
130
133
  - test/dry_container_test.rb
131
134
  - test/fast_track_test.rb
@@ -178,9 +181,11 @@ summary: Trailblazer's operation object with railway flow and integrated error h
178
181
  test_files:
179
182
  - test/benchmark/skill_resolver_benchmark.rb
180
183
  - test/call_test.rb
184
+ - test/callable_test.rb
181
185
  - test/class_dependencies_test.rb
182
186
  - test/docs/doormat_test.rb
183
187
  - test/docs/macaroni_test.rb
188
+ - test/docs/operation_test.rb
184
189
  - test/docs/wiring_test.rb
185
190
  - test/dry_container_test.rb
186
191
  - test/fast_track_test.rb