trailblazer-operation 0.0.13 → 0.4.1

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 (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.