trailblazer-operation 0.0.13 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +5 -3
  3. data/CHANGES.md +100 -0
  4. data/Gemfile +4 -2
  5. data/Rakefile +8 -6
  6. data/lib/trailblazer/operation.rb +80 -13
  7. data/lib/trailblazer/operation/callable.rb +42 -0
  8. data/lib/trailblazer/operation/class_dependencies.rb +25 -0
  9. data/lib/trailblazer/operation/deprecated_macro.rb +19 -0
  10. data/lib/trailblazer/operation/heritage.rb +30 -0
  11. data/lib/trailblazer/operation/inject.rb +36 -0
  12. data/lib/trailblazer/operation/inspect.rb +79 -0
  13. data/lib/trailblazer/operation/public_call.rb +55 -0
  14. data/lib/trailblazer/operation/railway.rb +32 -0
  15. data/lib/trailblazer/operation/railway/fast_track.rb +13 -0
  16. data/lib/trailblazer/operation/railway/macaroni.rb +23 -0
  17. data/lib/trailblazer/operation/railway/normalizer.rb +58 -0
  18. data/lib/trailblazer/operation/railway/task_builder.rb +37 -0
  19. data/lib/trailblazer/operation/result.rb +6 -4
  20. data/lib/trailblazer/operation/trace.rb +46 -0
  21. data/lib/trailblazer/operation/version.rb +1 -1
  22. data/test/call_test.rb +27 -8
  23. data/test/callable_test.rb +147 -0
  24. data/test/class_dependencies_test.rb +16 -0
  25. data/test/docs/doormat_test.rb +189 -0
  26. data/test/docs/macaroni_test.rb +33 -0
  27. data/test/docs/operation_test.rb +23 -0
  28. data/test/docs/wiring_test.rb +559 -0
  29. data/test/dry_container_test.rb +4 -0
  30. data/test/fast_track_test.rb +197 -0
  31. data/test/gemfiles/Gemfile.ruby-2.0 +1 -2
  32. data/test/gemfiles/Gemfile.ruby-2.0.lock +40 -0
  33. data/test/inheritance_test.rb +1 -1
  34. data/test/inspect_test.rb +43 -0
  35. data/test/introspect_test.rb +51 -0
  36. data/test/macro_test.rb +60 -0
  37. data/test/operation_test.rb +94 -0
  38. data/test/result_test.rb +14 -8
  39. data/test/ruby-2.0.0/operation_test.rb +61 -0
  40. data/test/ruby-2.0.0/step_test.rb +136 -0
  41. data/test/skill_test.rb +66 -48
  42. data/test/step_test.rb +228 -0
  43. data/test/task_wrap_test.rb +97 -0
  44. data/test/test_helper.rb +37 -0
  45. data/test/trace_test.rb +57 -0
  46. data/test/wire_test.rb +113 -0
  47. data/test/wiring/defaults_test.rb +197 -0
  48. data/test/wiring/subprocess_test.rb +70 -0
  49. data/trailblazer-operation.gemspec +3 -5
  50. metadata +68 -37
  51. data/lib/trailblazer/operation/1.9.3/option.rb +0 -36
  52. data/lib/trailblazer/operation/generic.rb +0 -12
  53. data/lib/trailblazer/operation/option.rb +0 -54
  54. data/lib/trailblazer/operation/pipetree.rb +0 -142
  55. data/lib/trailblazer/operation/skill.rb +0 -41
  56. data/lib/trailblazer/skill.rb +0 -70
  57. data/test/2.0.0-pipetree_test.rb +0 -100
  58. data/test/2.1.0-pipetree_test.rb +0 -100
  59. data/test/operation_skill_test.rb +0 -89
  60. data/test/pipetree_test.rb +0 -185
@@ -1,26 +1,32 @@
1
- require "test_helper"
1
+ require "test_helper"
2
+
3
+ class RailwayResultTest < Minitest::Spec
4
+ Result = Trailblazer::Operation::Railway::Result
5
+ Success = Trailblazer::Operation::Railway::End::Success
6
+
7
+ let(:event) { Success.new(semantic: nil) }
8
+ let (:success) { Result.new(true, { "x"=> String }, event) }
2
9
 
3
- class ResultTest < Minitest::Spec
4
- Result = Trailblazer::Operation::Result
5
- let (:success) { Result.new(true, "x"=> String) }
6
10
  it { success.success?.must_equal true }
7
11
  it { success.failure?.must_equal false }
12
+ it { success.event.must_equal event }
13
+
8
14
  # it { success["success?"].must_equal true }
9
15
  # it { success["failure?"].must_equal false }
10
16
  it { success["x"].must_equal String }
11
- it { success["not-existant"].must_equal nil }
17
+ it { success["not-existant"].must_be_nil }
12
18
  it { success.slice("x").must_equal [String] }
13
19
 
14
20
  #---
15
21
  # inspect
16
22
  it { success.inspect.must_equal %{<Result:true {\"x\"=>String} >} }
17
- it { Result.new(true, "x"=> true, "y"=>1, "z"=>2).inspect("z", "y").must_equal %{<Result:true [2, 1] >} }
23
+ it { Result.new(true, { "x"=> true, "y"=>1, "z"=>2 }, event).inspect("z", "y").must_equal %{<Result:true [2, 1] >} }
18
24
 
19
25
  class Create < Trailblazer::Operation
20
26
  success :call
21
27
 
22
- def call(*)
23
- self[:message] = "Result objects are actually quite handy!"
28
+ def call(options, **)
29
+ options[:message] = "Result objects are actually quite handy!"
24
30
  end
25
31
  end
26
32
 
@@ -0,0 +1,61 @@
1
+ require "test_helper"
2
+
3
+ class DeclarativeApiTest < Minitest::Spec
4
+ #---
5
+ #- step, pass, fail
6
+
7
+ # Test: step/pass/fail
8
+ # * do they deviate properly?
9
+ class Create < Trailblazer::Operation
10
+ step :decide!
11
+ success :wasnt_ok!
12
+ success :was_ok!
13
+ failure :return_true!
14
+ failure :return_false!
15
+
16
+ def decide!(options, decide:raise, **o)
17
+ options["a"] = true
18
+ decide
19
+ end
20
+
21
+ def wasnt_ok!(options, **o)
22
+ options["y"] = false
23
+ end
24
+
25
+ def was_ok!(options, **o)
26
+ options["x"] = true
27
+ end
28
+
29
+ def return_true! (options, **o); options["b"] = true end
30
+ def return_false!(options, **o); options["c"] = false end
31
+ end
32
+
33
+ it { Create.({}, decide: true).inspect("a", "x", "y", "b", "c").must_equal %{<Result:true [true, true, false, nil, nil] >} }
34
+ it { Create.({}, decide: false).inspect("a", "x", "y", "b", "c").must_equal %{<Result:false [true, nil, nil, true, false] >} }
35
+
36
+ #---
37
+ #- trace
38
+
39
+ it do
40
+
41
+ end
42
+
43
+ #---
44
+ #- empty class
45
+ class Noop < Trailblazer::Operation
46
+ end
47
+
48
+ it { Noop.().inspect("params").must_equal %{<Result:true [{}] >} }
49
+
50
+ #---
51
+ #- pass
52
+ #- fail
53
+ class Update < Trailblazer::Operation
54
+ pass ->(options, **o) { options["a"] = false }
55
+ step ->(options, params:raise, **o) { options["b"] = params[:decide] }
56
+ fail ->(options, **o) { options["c"] = true }
57
+ end
58
+
59
+ it { Update.(decide: true).inspect("a", "b", "c").must_equal %{<Result:true [false, true, nil] >} }
60
+ it { Update.(decide: false).inspect("a", "b", "c").must_equal %{<Result:false [false, false, true] >} }
61
+ end
@@ -0,0 +1,136 @@
1
+ require "test_helper"
2
+
3
+ # Tests
4
+ # --- step ->(*o) { snippet }
5
+ # --- step Callable
6
+ # --- step :method
7
+ # --- step MyMacro
8
+ class StepTest < Minitest::Spec
9
+ class Callable
10
+ def self.call(options, b:nil, **o)
11
+ options["b"] = b
12
+ end
13
+ end
14
+
15
+ module Implementation
16
+ module_function
17
+ def c(options, c:nil, **o)
18
+ options["c"] = c
19
+ end
20
+ end
21
+
22
+ MyMacro = ->( direction, options, flow_options ) do
23
+ options["e"] = options[:e]
24
+
25
+ [ direction, options, flow_options ]
26
+ end
27
+
28
+ class Create < Trailblazer::Operation
29
+ step ->(options, a:nil, **o) { options["a"] = a }
30
+ step Callable
31
+ step Implementation.method(:c)
32
+ step :d
33
+ step [ MyMacro, {} ] # doesn't provide runner_options.
34
+
35
+ def d(options, d:nil, **o)
36
+ options["d"] = d
37
+ end
38
+ end
39
+
40
+ it { Create.({}, a: 1, b: 2, c: 3, d: 4, e: 5).inspect("a", "b", "c", "d", "e").must_equal "<Result:true [1, 2, 3, 4, 5] >" }
41
+
42
+ it { Trailblazer::Operation::Inspect.(Create).gsub(/0x.+?step_test.rb/, "").must_equal %{[>#<Proc::29 (lambda)>,>StepTest::Callable,>#<Method: StepTest::Implementation.c>,>d,>[#<Proc::22 (lambda)>, {}]]} }
43
+ # poor test to make sure we pass debug information to Activity.
44
+ it { Create["__activity__"].graph.find_all(:d).first[:id].must_equal :d }
45
+
46
+ #---
47
+ #- :before, :after, :replace, :delete, :override
48
+ class A < Trailblazer::Operation
49
+ step :a!
50
+ def a!(options, **o); options["a"] = 1; end
51
+ def a!(options, **o); options["a"] = 1; end if RUBY_VERSION == "2.0.0"
52
+ end
53
+
54
+ class B < A
55
+ step :b!, before: :a!
56
+ step :c!, before: :a!
57
+ step :d!, after: :b!
58
+ end
59
+
60
+ it { Trailblazer::Operation::Inspect.(B).must_equal %{[>b!,>d!,>c!,>a!]} }
61
+
62
+ class C < B
63
+ step :e!, replace: :c!
64
+ step nil, delete: :d!
65
+ end
66
+
67
+ it { Trailblazer::Operation::Inspect.(C).must_equal %{[>b!,>e!,>a!]} }
68
+
69
+ class D < Trailblazer::Operation
70
+ step :a!
71
+ step :b!
72
+ step :b!, override: true
73
+ end
74
+
75
+ it { Trailblazer::Operation::Inspect.(D).must_equal %{[>a!,>b!]} }
76
+
77
+ # not existent :name
78
+ it do
79
+ err = assert_raises Trailblazer::Operation::Railway::Sequence::IndexError do
80
+ class E < Trailblazer::Operation
81
+ step :a, before: "I don't exist!"
82
+ end
83
+ end
84
+
85
+ err.inspect.must_equal "#<Trailblazer::Operation::Railway::Sequence::IndexError: I don't exist!>"
86
+ end
87
+
88
+ #---
89
+ #- :name
90
+ #- step :whatever, name: :validate
91
+ class Index < Trailblazer::Operation
92
+ step :validate!, name: "my validate"
93
+ step :persist!
94
+ step [ MyMacro, name: "I win!" ]
95
+ step [ MyMacro, name: "I win!" ], name: "No, I do!"
96
+ end
97
+
98
+ it { Trailblazer::Operation::Inspect.(Index).must_equal %{[>my validate,>persist!,>I win!,>No, I do!]} }
99
+
100
+ #---
101
+ #- inheritance
102
+ class New < Create
103
+ end
104
+
105
+ it { Trailblazer::Operation::Inspect.(New).gsub(/0x.+?step_test.rb/, "").must_equal %{[>#<Proc::29 (lambda)>,>StepTest::Callable,>#<Method: StepTest::Implementation.c>,>d,>[#<Proc::22 (lambda)>, {}]]} }
106
+
107
+ class Update < Create
108
+ step :after_save!
109
+ end
110
+
111
+ it { Trailblazer::Operation::Inspect.(Update).gsub(/0x.+?step_test.rb/, "").must_equal %{[>#<Proc::29 (lambda)>,>StepTest::Callable,>#<Method: StepTest::Implementation.c>,>d,>[#<Proc::22 (lambda)>, {}],>after_save!]} }
112
+ end
113
+
114
+ #---
115
+ #- Macros with the old `input` arg.
116
+ # step [ ->(input, options) { } ]
117
+ class StepWithDeprecatedMacroTest < Minitest::Spec # TODO: remove me in 2.2.
118
+ class Create < Trailblazer::Operation
119
+ MyOutdatedMacro = ->(input, options) {
120
+ options["x"] = input.class
121
+ }
122
+
123
+ class AnotherOldMacro
124
+ def self.call(input, options)
125
+ options["y"] = input.class
126
+ end
127
+ end
128
+
129
+ step [ MyOutdatedMacro, name: :outdated ]
130
+ step [ AnotherOldMacro, name: :oldie ]
131
+ end
132
+
133
+ it { Trailblazer::Operation::Inspect.(Create).gsub(/0x.+?step_test.rb/, "").must_equal %{[>outdated,>oldie]} }
134
+ it { Create.().inspect("x", "y").must_equal %{<Result:true [StepWithDeprecatedMacroTest::Create, StepWithDeprecatedMacroTest::Create] >} }
135
+ end
136
+
@@ -1,48 +1,66 @@
1
- require "test_helper"
2
- require "trailblazer/skill"
3
-
4
- class SkillTest < Minitest::Spec
5
- describe "Skill" do
6
- it do
7
- class_level_container = {
8
- "contract.class" => Object,
9
- "model.class" => String
10
- }
11
-
12
- runtime_skills = {
13
- "contract" => MyContract=Class.new,
14
- "model.class" => Integer
15
- }
16
-
17
- skill = Trailblazer::Skill.new(runtime_skills, class_level_container)
18
-
19
- # non-existent key.
20
- skill[:nope].must_equal nil
21
-
22
- # from runtime.
23
- skill["contract"].must_equal MyContract
24
- # from compile-time.
25
- skill["contract.class"].must_equal Object
26
- # runtime supersedes compile-time.
27
- skill["model.class"].must_equal Integer
28
-
29
- skill["model.class"] = Fixnum
30
- skill["model.class"].must_equal Fixnum
31
-
32
- # add new tuple.
33
- skill["user.current"] = "Todd"
34
-
35
- # original container don't get changed
36
- class_level_container.inspect.must_equal %{{"contract.class"=>Object, "model.class"=>String}}
37
- runtime_skills.inspect.must_equal %{{"contract"=>SkillTest::MyContract, "model.class"=>Integer}}
38
-
39
- # setting false.
40
- skill[:valid] = false
41
- skill[:valid].must_equal false
42
-
43
- # setting nil.
44
- skill[:valid] = nil
45
- skill[:valid].must_equal nil
46
- end
47
- end
48
- end
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
@@ -0,0 +1,228 @@
1
+ require "test_helper"
2
+
3
+ # Tests
4
+ # --- step ->(*) { snippet }
5
+ # --- step Callable
6
+ # --- step :method
7
+ # --- step MyMacro
8
+ class StepTest < Minitest::Spec
9
+ class Callable
10
+ def self.call(options, b:nil, **)
11
+ options["b"] = b
12
+ end
13
+ end
14
+
15
+ module Implementation
16
+ module_function
17
+ def c(options, c:nil, **)
18
+ options["c"] = c
19
+ end
20
+ end
21
+
22
+ MyMacro = ->( (options, flow_options), * ) do
23
+ options["e"] = options[:e]
24
+
25
+ [ Trailblazer::Activity::Right, options, flow_options ]
26
+ end
27
+
28
+ class Create < Trailblazer::Operation
29
+ step ->(options, a:nil, **) { options["a"] = a }
30
+ step Callable
31
+ step Implementation.method(:c)
32
+ step :d
33
+ step( { task: MyMacro, id: "MyMacro" } ) # doesn't provide `runner_options` and `outputs`.
34
+
35
+ def d(options, d:nil, **)
36
+ options["d"] = d
37
+ end
38
+ end
39
+
40
+ it { Create.(a: 1, b: 2, c: 3, d: 4, e: 5).inspect("a", "b", "c", "d", "e").must_equal "<Result:true [1, 2, 3, 4, 5] >" }
41
+
42
+ it { Trailblazer::Operation::Inspect.(Create).gsub(/0x.+?step_test.rb/, "").must_equal %{[>#<Proc::29 (lambda)>,>StepTest::Callable,>#<Method: StepTest::Implementation.c>,>d,>MyMacro]} }
43
+
44
+ #---
45
+ #- :before, :after, :replace, :delete, :override
46
+ class A < Trailblazer::Operation
47
+ step :a!
48
+ def a!(options, **); options["order"] << "a" ; end
49
+ end
50
+
51
+ class B < A
52
+ step :b!, before: :a!
53
+ step :c!, before: :a!
54
+ step :d!, after: :b!
55
+
56
+ def b!(options, **); options["order"] << "b" ; end
57
+ def c!(options, **); options["order"] << "c" ; end
58
+ def d!(options, **); options["order"] << "d" ; end
59
+ end
60
+
61
+ it { Trailblazer::Operation::Inspect.(B).must_equal %{[>b!,>d!,>c!,>a!]} }
62
+
63
+ class C < B
64
+ step :e!, replace: :c!
65
+ step "nil", delete: :d!
66
+ def e!(options, **); options["order"] << "e" ; end
67
+ end
68
+
69
+ it { Trailblazer::Operation::Inspect.(C).must_equal %{[>b!,>e!,>a!]} }
70
+ it { C.("order"=>[]).inspect("order").must_equal %{<Result:true [["b", "e", "a"]] >} }
71
+
72
+ #---
73
+ #- override: true
74
+ class D < Trailblazer::Operation
75
+ step :a!
76
+ step :add!
77
+ step :add!, id: :another_add!#, override: true
78
+
79
+ def a!(options, **); options["a"] = []; end
80
+ def add!(options, **); options["a"] << :b; end
81
+ end
82
+
83
+ it { Trailblazer::Operation::Inspect.(D).must_equal %{[>a!,>add!,>another_add!]} }
84
+ it { D.().inspect("a").must_equal %{<Result:true [[:b, :b]] >} }
85
+
86
+ class E < Trailblazer::Operation
87
+ step :a!
88
+ step :add!
89
+ step :add!, override: true
90
+
91
+ def a!(options, **); options["a"] = []; end
92
+ def add!(options, **); options["a"] << :b; end
93
+ end
94
+
95
+ it { Trailblazer::Operation::Inspect.(E).must_equal %{[>a!,>add!]} }
96
+ it { E.().inspect("a").must_equal %{<Result:true [[:b]] >} }
97
+
98
+ #- with proc
99
+ class F < Trailblazer::Operation
100
+ step :a!
101
+ step ->(options, **) { options["a"] << :b }, id: "add"
102
+ step ->(options, **) { options["a"] << :b }, replace: "add", id: "add!!!"
103
+
104
+ def a!(options, **); options["a"] = []; end
105
+ end
106
+
107
+ it { Trailblazer::Operation::Inspect.(F).must_equal %{[>a!,>add!!!]} }
108
+ it { F.().inspect("a").must_equal %{<Result:true [[:b]] >} }
109
+
110
+ #- with macro
111
+ class G < Trailblazer::Operation
112
+ MyMacro1 = ->((options, flow_options), *) { options["a"] << :b; [ Trailblazer::Activity::Right, options, flow_options ] }
113
+ MyMacro2 = ->((options, flow_options), *) { options["a"] << :b; [ Trailblazer::Activity::Right, options, flow_options ] }
114
+ # MyMacro3 = ->(options, flow_options) { options["a"] << :b; [ Trailblazer::Activity::Right, options, flow_options ] }
115
+
116
+ step :a!
117
+ step( { task: MyMacro1, id: "add" })
118
+ step( { task: MyMacro2, id: "add" }, replace: "add")
119
+ # step [ MyMacro3, {id: "add"}, {} ], override: true
120
+
121
+ def a!(options, **); options["a"] = []; end
122
+ end
123
+
124
+ it { Trailblazer::Operation::Inspect.(G).must_equal %{[>a!,>add]} }
125
+ it { G.().inspect("a").must_equal %{<Result:true [[:b]] >} }
126
+
127
+ # override: true in inherited class with macro
128
+ class Go < G
129
+ MyMacro = ->((options, flow_options), *) { options["a"] << :m; [ Trailblazer::Activity::Right, options, flow_options ] }
130
+ step task: MyMacro, override: true, id: "add"
131
+ end
132
+
133
+ it { Trailblazer::Operation::Inspect.(Go).must_equal %{[>a!,>add]} }
134
+ it { Go.().inspect("a").must_equal %{<Result:true [[:m]] >} }
135
+
136
+ #- with inheritance
137
+ class H < Trailblazer::Operation
138
+ step :a!
139
+ step :add!
140
+
141
+ def a!(options, **); options["a"] = []; end
142
+ def add!(options, **); options["a"] << :b; end
143
+ end
144
+
145
+ class Hh < H
146
+ step :_add!, replace: :add!
147
+
148
+ def _add!(options, **); options["a"] << :hh; end
149
+ end
150
+
151
+ it { Trailblazer::Operation::Inspect.(Hh).must_equal %{[>a!,>_add!]} }
152
+ it { Hh.().inspect("a").must_equal %{<Result:true [[:hh]] >} }
153
+
154
+ #- inheritance unit test
155
+ class I < Trailblazer::Operation
156
+ step :a
157
+ end
158
+
159
+ class Ii < I
160
+ step :a, override: true
161
+ end
162
+
163
+ # FIXME: we have all fast track ends here.
164
+ it { skip;Ii["__activity__"].circuit.instance_variable_get(:@map).size.must_equal 6 }
165
+
166
+ #---
167
+ #-
168
+ # not existent :name
169
+ it do
170
+ assert_raises Trailblazer::Activity::Schema::Sequence::IndexError do
171
+
172
+ Class.new(Trailblazer::Operation) do
173
+ step :a, before: "I don't exist!"
174
+ end
175
+
176
+ end.inspect.must_equal "#<Trailblazer::Activity::Schema::Sequence::IndexError: I don't exist!>"
177
+ end
178
+
179
+ #---
180
+ #- :name
181
+ #- step :whatever, id: :validate
182
+ class Index < Trailblazer::Operation
183
+ step :validate!, id: "my validate"
184
+ step :persist!
185
+ step( { task: MyMacro, id: "I win!" })
186
+ step( { task: MyMacro, id: "I win!" }, id: "No, I do!")
187
+ end
188
+
189
+ it { Trailblazer::Operation::Inspect.(Index).must_equal %{[>my validate,>persist!,>I win!,>No, I do!]} }
190
+
191
+ #---
192
+ #- inheritance
193
+ class New < Create
194
+ end
195
+
196
+ it { Trailblazer::Operation::Inspect.(New).gsub(/0x.+?step_test.rb/, "").must_equal %{[>#<Proc::29 (lambda)>,>StepTest::Callable,>#<Method: StepTest::Implementation.c>,>d,>MyMacro]} }
197
+
198
+ class Update < Create
199
+ step :after_save!
200
+ end
201
+
202
+ it { Trailblazer::Operation::Inspect.(Update).gsub(/0x.+?step_test.rb/, "").must_equal %{[>#<Proc::29 (lambda)>,>StepTest::Callable,>#<Method: StepTest::Implementation.c>,>d,>MyMacro,>after_save!]} }
203
+ end
204
+
205
+ #---
206
+ #- Macros with the old `input` arg.
207
+ # step [ ->(input, options) { } ]
208
+ class StepWithDeprecatedMacroTest < Minitest::Spec # TODO: remove me in 2.2.
209
+ class Create < Trailblazer::Operation
210
+ MyOutdatedMacro = ->(input, options) {
211
+ options["x"] = input.class
212
+ }
213
+
214
+ class AnotherOldMacro
215
+ def self.call(input, options)
216
+ options["y"] = input.class
217
+ end
218
+ end
219
+
220
+ step [ MyOutdatedMacro, id: :outdated ]
221
+ step [ AnotherOldMacro, id: :oldie ]
222
+ end
223
+
224
+ it { Trailblazer::Operation::Inspect.(Create).gsub(/0x.+?step_test.rb/, "").must_equal %{[>outdated,>oldie]} }
225
+ it { Create.().inspect("x", "y").must_equal %{<Result:true [StepWithDeprecatedMacroTest::Create, StepWithDeprecatedMacroTest::Create] >} }
226
+ end
227
+
228
+ # TODO: test failure and success aliases properly.