trailblazer-operation 0.10.0 → 0.11.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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +2 -2
  3. data/CHANGES.md +15 -0
  4. data/lib/trailblazer/operation/class_dependencies.rb +1 -1
  5. data/lib/trailblazer/operation/public_call.rb +24 -14
  6. data/lib/trailblazer/operation/railway.rb +13 -7
  7. data/lib/trailblazer/operation/version.rb +1 -1
  8. data/lib/trailblazer/operation/wtf.rb +11 -0
  9. data/lib/trailblazer/operation.rb +2 -2
  10. data/test/call_test.rb +32 -10
  11. data/test/class_dependencies_test.rb +8 -4
  12. data/test/docs/autogenerated/activity_basics_test.rb +72 -0
  13. data/test/docs/autogenerated/composable_variable_mapping_test.rb +880 -0
  14. data/test/docs/autogenerated/fast_track_layout_test.rb +76 -0
  15. data/test/docs/autogenerated/mechanics_test.rb +382 -0
  16. data/test/docs/autogenerated/sequence_options_test.rb +202 -0
  17. data/test/docs/autogenerated/subprocess_test.rb +257 -0
  18. data/test/docs/autogenerated/wiring_api_test.rb +435 -0
  19. data/test/docs/developer_test.rb +27 -0
  20. data/test/docs/public_call_monkeypatching_test.rb +96 -0
  21. data/test/docs/result_test.rb +38 -0
  22. data/test/docs/step_dsl_test.rb +93 -0
  23. data/test/operation_test.rb +53 -13
  24. data/test/result_test.rb +1 -1
  25. data/test/test_helper.rb +17 -5
  26. data/test/trace_test.rb +3 -19
  27. data/trailblazer-operation.gemspec +3 -2
  28. metadata +50 -25
  29. data/lib/trailblazer/operation/trace.rb +0 -53
  30. data/test/callable_test.rb +0 -147
  31. data/test/docs/doormat_test.rb +0 -190
  32. data/test/docs/macaroni_test.rb +0 -31
  33. data/test/skill_test.rb +0 -66
  34. data/test/wire_test.rb +0 -113
  35. data/test/wiring/defaults_test.rb +0 -193
  36. data/test/wiring/subprocess_test.rb +0 -70
@@ -1,147 +0,0 @@
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, start_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
@@ -1,190 +0,0 @@
1
- require "test_helper"
2
-
3
- class TemplateWithGroupTest < Minitest::Spec
4
- module Memo; end
5
-
6
- #:template
7
- class Memo::Operation < Trailblazer::Operation
8
- step :log_call, group: :start
9
- step :log_success, group: :end, before: "End.success"
10
- fail :log_errors, group: :end, before: "End.failure"
11
- #~tmethods
12
-
13
- # our success "end":
14
- def log_call(options, **)
15
- options["row"] = [:a]
16
- end
17
-
18
- # our success "end":
19
- def log_success(options, **)
20
- options["row"] << :z
21
- end
22
-
23
- def log_errors(options, **)
24
- options["row"] << :f
25
- end
26
- #~tmethods end
27
- end
28
- #:template end
29
-
30
- #:template-user
31
- class Memo::Create < Memo::Operation
32
- step :create_model
33
- step :validate
34
- step :save
35
- #~meths
36
- def create_model(options, **)
37
- options["row"] << :l
38
- end
39
-
40
- def validate(options, **)
41
- options["row"] << :b
42
- end
43
-
44
- def save(options, **)
45
- options["row"] << :c
46
- end
47
- #~meths end
48
- end
49
- #:template-user end
50
-
51
- # it { pp F['__sequence__'].to_a }
52
- it {
53
- skip
54
- Memo::Create.(params: {}, "b_return" => false).inspect("row").must_equal %{<Result:true [[:a, :l, :b, :c, :z]] >}
55
- }
56
- end
57
-
58
- class DoormatWithGroupTest < Minitest::Spec
59
- module Memo; end
60
-
61
- #:doormat-group
62
- class Memo::Create < Trailblazer::Operation
63
- step :create_model
64
- step :log_success, group: :end, before: "End.success"
65
-
66
- step :validate
67
- step :save
68
-
69
- fail :log_errors, group: :end, before: "End.failure"
70
- #~methods
71
- def create_model(options, **)
72
- options["row"] = [:a]
73
- end
74
-
75
- # our success "end":
76
- def log_success(options, **)
77
- options["row"] << :z
78
- end
79
-
80
- # 2
81
- def validate(options, **)
82
- options["row"] << :b
83
- end
84
-
85
- # 3
86
- def save(options, **)
87
- options["row"] << :c
88
- end
89
-
90
- def log_errors(options, **)
91
- options["row"] << :f
92
- end
93
- #~methods end
94
- end
95
- #:doormat-group end
96
-
97
- # it { pp F['__sequence__'].to_a }
98
- it {
99
- skip
100
- Memo::Create.(params: {}, "b_return" => false).inspect("row").must_equal %{<Result:true [[:a, :b, :c, :z]] >}
101
- }
102
- end
103
-
104
- class DoormatStepDocsTest < Minitest::Spec
105
- module Memo; end
106
-
107
- #:doormat-before
108
- class Memo::Create < Trailblazer::Operation
109
- step :create_model
110
- step :log_success
111
-
112
- step :validate, before: :log_success
113
- step :save, before: :log_success
114
-
115
- fail :log_errors
116
- #~im
117
- def create_model(options, **)
118
- options["row"] = [:a]
119
- end
120
-
121
- # our success "end":
122
- def log_success(options, **)
123
- options["row"] << :z
124
- end
125
-
126
- # 2
127
- def validate(options, **)
128
- options["row"] << :b
129
- end
130
-
131
- # 3
132
- def save(options, **)
133
- options["row"] << :c
134
- end
135
-
136
- def log_errors(options, **)
137
- options["row"] << :f
138
- end
139
- #~im end
140
- end
141
- #:doormat-before end
142
-
143
- # it { pp F['__sequence__'].to_a }
144
- it { Memo::Create.(params: {}, "b_return" => false).inspect("row").must_equal %{<Result:true [[:a, :b, :c, :z]] >} }
145
- end
146
-
147
- class DoormatInheritanceTest < Minitest::Spec
148
- #:doormatx-before-inheritance
149
- class Base < Trailblazer::Operation
150
- step :log_success!
151
- fail :log_errors!
152
- #~ignored
153
- # our success "end":
154
- def log_success!(options, **)
155
- options["row"] << :z
156
- end
157
-
158
- def log_errors!(options, **)
159
- options["row"] << :f
160
- end
161
- #~ignored end
162
- end
163
- #:doormatx-before-inheritance end
164
-
165
- #:doormat-before-inheritance-sub
166
- class Create < Base
167
- step :first, before: :log_success!
168
- step :second, before: :log_success!
169
- step :third, before: :log_success!
170
- #~ignoredd
171
- def first(options, **)
172
- options["row"] = [:a]
173
- end
174
-
175
- # 2
176
- def second(options, **)
177
- options["row"] << :b
178
- end
179
-
180
- # 3
181
- def third(options, **)
182
- options["row"] << :c
183
- end
184
- #~ignoredd end
185
- end
186
- #:doormat-before-inheritance-sub end
187
-
188
- # it { pp F['__sequence__'].to_a }
189
- it { Create.("b_return" => false).inspect("row").must_equal %{<Result:true [[:a, :b, :c, :z]] >} }
190
- end
@@ -1,31 +0,0 @@
1
- # require "test_helper"
2
-
3
- # class MacaroniTaskBuilderTest < Minitest::Spec
4
- # Memo = Struct.new(:title) do
5
- # def save
6
- # self.title = title[:title].reverse
7
- # end
8
- # end
9
-
10
- # #:create
11
- # class Memo::Create < Trailblazer::Operation(step_interface_builder: Trailblazer::Operation::Railway::KwSignature)
12
- # #~ign
13
- # step :create_model
14
- # step :save
15
- # #~ign end
16
- # #~methods
17
- # def create_model(params:, options:, **)
18
- # options[:model] = Memo.new(title: params[:title])
19
- # end
20
-
21
- # def save(model:, **)
22
- # model.save
23
- # end
24
- # #~methods end
25
- # end
26
- # #:create end
27
-
28
- # it "allows optional macaroni call style" do
29
- # Memo::Create.(params: {title: "Wow!"}).inspect(:model).must_equal %{<Result:true [#<struct MacaroniTaskBuilderTest::Memo title=\"!woW\">] >}
30
- # end
31
- # end
data/test/skill_test.rb DELETED
@@ -1,66 +0,0 @@
1
- # require "test_helper"
2
- # require "trailblazer/skill"
3
-
4
- # class SkillTest < Minitest::Spec
5
- # it "wraps one" do
6
- # options = { params: "Hello!" }
7
-
8
- # skill = Trailblazer::Skill.new(options)
9
-
10
- # skill[:params].must_equal "Hello!"
11
-
12
- # skill.to_hash.must_equal( {params: "Hello!"} )
13
-
14
- # options.inspect.must_equal %{{:params=>"Hello!"}}
15
- # end
16
- # # FIXME: do we actually want key?
17
- # it "what" do
18
- # skills = Trailblazer::Skill.new({ "a" => false, "b" => nil })
19
- # (!!skills.key?("a")).must_equal true
20
- # (!!skills.key?("b")).must_equal true
21
- # end
22
-
23
- # describe "Skill" do
24
- # it do
25
- # class_level_container = {
26
- # "contract.class" => Object,
27
- # "model.class" => String
28
- # }
29
-
30
- # runtime_skills = {
31
- # "contract" => MyContract=Class.new,
32
- # "model.class" => Integer
33
- # }
34
-
35
- # skill = Trailblazer::Skill.new(runtime_skills, class_level_container)
36
-
37
- # # non-existent key.
38
- # skill[:nope].must_be_nil
39
-
40
- # # from runtime.
41
- # skill["contract"].must_equal MyContract
42
- # # from compile-time.
43
- # skill["contract.class"].must_equal Object
44
- # # runtime supersedes compile-time.
45
- # skill["model.class"].must_equal Integer
46
-
47
- # skill["model.class"] = Fixnum
48
- # skill["model.class"].must_equal Fixnum
49
-
50
- # # add new tuple.
51
- # skill["user.current"] = "Todd"
52
-
53
- # # original container don't get changed
54
- # class_level_container.inspect.must_equal %{{"contract.class"=>Object, "model.class"=>String}}
55
- # runtime_skills.inspect.must_equal %{{"contract"=>SkillTest::MyContract, "model.class"=>Integer}}
56
-
57
- # # setting false.
58
- # skill[:valid] = false
59
- # skill[:valid].must_equal false
60
-
61
- # # setting nil.
62
- # skill[:valid] = nil
63
- # skill[:valid].must_be_nil
64
- # end
65
- # end
66
- # end
data/test/wire_test.rb DELETED
@@ -1,113 +0,0 @@
1
- # require "test_helper"
2
- # # require "trailblazer/developer"
3
-
4
- # class WireTest < Minitest::Spec
5
- # Circuit = Trailblazer::Circuit
6
- # ExceptionFromD = Class.new # custom signal
7
-
8
- # D = ->((options, *args), *) do
9
- # options["D"] = [ options["a"], options["b"], options["c"] ]
10
-
11
- # signal = options["D_return"]
12
- # [ signal, [ options, *args ] ]
13
- # end
14
-
15
- # #---
16
- # #- step providing all :outputs manually.
17
- # class Create < Trailblazer::Operation
18
- # step ->(options, **) { options["a"] = 1 }
19
- # step ->(options, **) { options["b"] = 2 }, name: "b"
20
-
21
- # step( { task: D,
22
- # outputs: { Circuit::Right => :success, Circuit::Left => :failure, ExceptionFromD => :exception }, # any outputs and their polarization, generic.
23
- # id: :d,
24
- # },
25
- # :exception => MyEnd = End("End.ExceptionFromD_happened")
26
- # )
27
-
28
- # fail ->(options, **) { options["f"] = 4 }, id: "f"
29
- # step ->(options, **) { options["c"] = 3 }, id: "c"
30
- # end
31
-
32
- # # myend ==> d
33
- # it { Trailblazer::Operation::Inspect.(Create).gsub(/0x.+?wire_test.rb/, "").must_equal %{[>#<Proc::18 (lambda)>,>b,>d,<<f,>c]} }
34
-
35
- # # normal flow as D sits on the Right track.
36
- # it do
37
- # result = Create.({}, "D_return" => Circuit::Right)
38
-
39
- # result.inspect("a", "b", "c", "D", "f").must_equal %{<Result:true [1, 2, 3, [1, 2, nil], nil] >}
40
- # result.event.must_equal Create.outputs.keys[1]
41
- # end
42
-
43
- # # ends on MyEnd, without hitting fail.
44
- # it do
45
- # result = Create.({}, "D_return" => ExceptionFromD)
46
-
47
- # result.event.must_equal Create::MyEnd
48
- # result.inspect("a", "b", "c", "D", "f").must_equal %{<Result:false [1, 2, nil, [1, 2, nil], nil] >}
49
- # end
50
-
51
- # # normal flow to left track.
52
- # it do
53
- # result = Create.({}, "D_return" => Circuit::Left)
54
-
55
- # result.inspect("a", "b", "c", "D", "f").must_equal %{<Result:false [1, 2, nil, [1, 2, nil], 4] >}
56
- # result.event.must_equal Create.outputs.keys[0]
57
- # end
58
-
59
- # #---
60
- # #- step with Merge
61
- # class CreateWithDefaults < Trailblazer::Operation
62
- # step ->(options, **) { options["a"] = 1 }
63
- # step ->(options, **) { options["b"] = 2 }, name: "b"
64
-
65
- # step( { task: D,
66
- # outputs: Merge( ExceptionFromD => { role: :exception } ), # any outputs and their polarization, generic.
67
- # id: :d,
68
- # },
69
- # :exception => MyEnd = End("End.ExceptionFromD_happened")
70
- # )
71
-
72
- # fail ->(options, **) { options["f"] = 4 }, id: "f"
73
- # step ->(options, **) { options["c"] = 3 }, id: "c"
74
- # end
75
-
76
- # # normal flow as D sits on the Right track.
77
- # it do
78
- # result = CreateWithDefaults.({}, "D_return" => Circuit::Right)
79
-
80
- # result.inspect("a", "b", "c", "D", "f").must_equal %{<Result:true [1, 2, 3, [1, 2, nil], nil] >}
81
- # result.event.must_equal CreateWithDefaults.outputs.keys[1]
82
- # end
83
-
84
- # # ends on MyEnd, without hitting fail.
85
- # it do
86
- # result = CreateWithDefaults.({}, "D_return" => ExceptionFromD)
87
-
88
- # result.event.must_equal CreateWithDefaults::MyEnd
89
- # result.inspect("a", "b", "c", "D", "f").must_equal %{<Result:false [1, 2, nil, [1, 2, nil], nil] >}
90
- # end
91
-
92
- # # normal flow to left track.
93
- # it do
94
- # result = CreateWithDefaults.({}, "D_return" => Circuit::Left)
95
-
96
- # result.inspect("a", "b", "c", "D", "f").must_equal %{<Result:false [1, 2, nil, [1, 2, nil], 4] >}
97
- # result.event.must_equal CreateWithDefaults.outputs.keys[0]
98
- # end
99
-
100
- # end
101
-
102
- # class WireExceptionTest < Minitest::Spec
103
- # # role in :outputs can't be connected because not in :connect_to.
104
- # it do
105
- # exception = assert_raises do
106
- # class Create < Trailblazer::Operation
107
- # step :a, outputs: { "some" => { role: :success } }, connect_to: { :not_existent => "End.success" }
108
- # end
109
- # end
110
-
111
- # exception.message.must_equal %{Couldn't map output role :success for {:not_existent=>"End.success"}}
112
- # end
113
- # end