trailblazer-macro 2.1.11 → 2.1.13
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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +6 -4
- data/.github/workflows/ci_jruby.yml +19 -0
- data/.github/workflows/ci_legacy.yml +19 -0
- data/.github/workflows/ci_truffleruby.yml +19 -0
- data/CHANGES.md +33 -0
- data/Gemfile +7 -5
- data/lib/trailblazer/macro/each.rb +187 -0
- data/lib/trailblazer/macro/model.rb +4 -5
- data/lib/trailblazer/macro/nested.rb +130 -68
- data/lib/trailblazer/macro/rescue.rb +2 -0
- data/lib/trailblazer/macro/strategy.rb +32 -0
- data/lib/trailblazer/macro/version.rb +1 -1
- data/lib/trailblazer/macro/wrap.rb +72 -65
- data/lib/trailblazer/macro.rb +53 -2
- data/test/docs/autogenerated/operation_each_test.rb +585 -0
- data/test/docs/autogenerated/operation_model_test.rb +263 -0
- data/test/docs/each_test.rb +940 -0
- data/test/docs/macro_test.rb +18 -0
- data/test/docs/model_test.rb +204 -88
- data/test/docs/nested_static_test.rb +730 -0
- data/test/docs/wrap_test.rb +348 -66
- data/test/test_helper.rb +29 -0
- data/trailblazer-macro.gemspec +2 -6
- metadata +21 -58
- data/.rubocop.yml +0 -6
- data/.rubocop_todo.yml +0 -423
- data/test/docs/nested_test.rb +0 -218
- data/test/operation/model_test.rb +0 -89
- data/test/operation/nested_test.rb +0 -98
data/test/docs/nested_test.rb
DELETED
@@ -1,218 +0,0 @@
|
|
1
|
-
require "test_helper"
|
2
|
-
|
3
|
-
class NestedInput < Minitest::Spec
|
4
|
-
let(:edit) do
|
5
|
-
edit = Class.new(Trailblazer::Operation) do
|
6
|
-
step :c
|
7
|
-
|
8
|
-
include T.def_steps(:c)
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
let(:update) do
|
13
|
-
edit = Class.new(Trailblazer::Operation) do
|
14
|
-
step :d
|
15
|
-
include T.def_steps(:d)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
class Validate < Trailblazer::Operation
|
20
|
-
step :validate
|
21
|
-
# ... more steps ...
|
22
|
-
include T.def_steps(:validate)
|
23
|
-
end
|
24
|
-
|
25
|
-
class JsonValidate < Validate
|
26
|
-
step :json
|
27
|
-
include T.def_steps(:json)
|
28
|
-
end
|
29
|
-
|
30
|
-
it "Nested(Edit), without any options" do
|
31
|
-
module A
|
32
|
-
|
33
|
-
create =
|
34
|
-
#:nested
|
35
|
-
class Create < Trailblazer::Operation
|
36
|
-
step :create
|
37
|
-
step Nested(Validate)
|
38
|
-
step :save
|
39
|
-
#~meths
|
40
|
-
include T.def_steps(:create, :save)
|
41
|
-
#~meths end
|
42
|
-
end
|
43
|
-
#:nested end
|
44
|
-
|
45
|
-
# this will print a DEPRECATION warning.
|
46
|
-
# success
|
47
|
-
create.(seq: []).inspect(:seq).must_equal %{<Result:true [[:create, :validate, :save]] >}
|
48
|
-
# failure in Nested
|
49
|
-
create.(seq: [], validate: false).inspect(:seq).must_equal %{<Result:false [[:create, :validate]] >}
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
it "Nested(Edit), with Output rewiring" do
|
54
|
-
edit = self.edit
|
55
|
-
|
56
|
-
create = Class.new(Trailblazer::Operation) do
|
57
|
-
step :a
|
58
|
-
step Nested( edit ), Output(:failure) => Track(:success)
|
59
|
-
step :b
|
60
|
-
|
61
|
-
include T.def_steps(:a, :b)
|
62
|
-
end
|
63
|
-
|
64
|
-
# success
|
65
|
-
create.(seq: []).inspect(:seq).must_equal %{<Result:true [[:a, :c, :b]] >}
|
66
|
-
# failure in Nested
|
67
|
-
create.(seq: [], c: false).inspect(:seq).must_equal %{<Result:true [[:a, :c, :b]] >}
|
68
|
-
end
|
69
|
-
|
70
|
-
it "Nested(:method)" do
|
71
|
-
module B
|
72
|
-
create =
|
73
|
-
#:nested-dynamic
|
74
|
-
class Create < Trailblazer::Operation
|
75
|
-
step :create
|
76
|
-
step Nested(:compute_nested)
|
77
|
-
step :save
|
78
|
-
|
79
|
-
def compute_nested(ctx, params:, **)
|
80
|
-
params.is_a?(Hash) ? Validate : JsonValidate
|
81
|
-
end
|
82
|
-
#~meths
|
83
|
-
include T.def_steps(:create, :save)
|
84
|
-
#~meths end
|
85
|
-
end
|
86
|
-
#:nested-dynamic end
|
87
|
-
# `edit` and `update` can be called from Nested()
|
88
|
-
|
89
|
-
# edit/success
|
90
|
-
create.(seq: [], params: {}).inspect(:seq).must_equal %{<Result:true [[:create, :validate, :save]] >}
|
91
|
-
|
92
|
-
# update/success
|
93
|
-
create.(seq: [], params: nil).inspect(:seq).must_equal %{<Result:true [[:create, :validate, :json, :save]] >}
|
94
|
-
|
95
|
-
|
96
|
-
# wiring of fail:
|
97
|
-
# edit/failure
|
98
|
-
create.(seq: [], params: {}, validate: false).inspect(:seq).must_equal %{<Result:false [[:create, :validate]] >}
|
99
|
-
# update/failure
|
100
|
-
create.(seq: [], params: nil, json: false).inspect(:seq).must_equal %{<Result:false [[:create, :validate, :json]] >}
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
it "Nested(:method), input: :my_input" do
|
105
|
-
module C
|
106
|
-
#:nested-dynamic
|
107
|
-
class Create < Trailblazer::Operation
|
108
|
-
step :create
|
109
|
-
step Nested(:compute_nested), input: ->(ctx, *) {{foo: :bar, seq: ctx[:seq]}}
|
110
|
-
step :save
|
111
|
-
|
112
|
-
def compute_nested(ctx, params:, **)
|
113
|
-
params.is_a?(Hash) ? Validate : JsonValidate
|
114
|
-
end
|
115
|
-
|
116
|
-
#~meths
|
117
|
-
include T.def_steps(:create, :save)
|
118
|
-
#~meths end
|
119
|
-
end
|
120
|
-
#:nested-dynamic end
|
121
|
-
|
122
|
-
# `edit` and `update` can be called from Nested()
|
123
|
-
end
|
124
|
-
|
125
|
-
C::Create.(seq: [], params: {}).inspect(:seq).must_equal %{<Result:true [[:create, :validate, :save]] >}
|
126
|
-
C::Create.(seq: [], params: nil).inspect(:seq).must_equal %{<Result:true [[:create, :validate, :json, :save]] >}
|
127
|
-
end
|
128
|
-
|
129
|
-
it "Nested(:method), with pass_fast returned from nested" do
|
130
|
-
class JustPassFast < Trailblazer::Operation
|
131
|
-
step :just_pass_fast, pass_fast: true
|
132
|
-
include T.def_steps(:just_pass_fast)
|
133
|
-
end
|
134
|
-
|
135
|
-
module D
|
136
|
-
|
137
|
-
create =
|
138
|
-
#:nested-with-pass-fast
|
139
|
-
class Create < Trailblazer::Operation
|
140
|
-
|
141
|
-
def compute_nested(ctx, **)
|
142
|
-
JustPassFast
|
143
|
-
end
|
144
|
-
|
145
|
-
step :create
|
146
|
-
step Nested(:compute_nested)
|
147
|
-
step :save
|
148
|
-
#~meths
|
149
|
-
include T.def_steps(:create, :save)
|
150
|
-
#~meths end
|
151
|
-
end
|
152
|
-
#:nested-with-pass-fast end
|
153
|
-
|
154
|
-
#= {#save} is still called because the {End.pass_fast} terminus is automatically wired to
|
155
|
-
#= the success "output" of Nested().
|
156
|
-
create.(seq: []).inspect(:seq).must_equal %{<Result:true [[:create, :just_pass_fast, :save]] >}
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
160
|
-
it "Nested(:method, auto_wire: *activities) with :pass_fast => End()" do
|
161
|
-
module E
|
162
|
-
class JsonValidate < Trailblazer::Operation
|
163
|
-
step :validate, Output(:failure) => End(:invalid_json)
|
164
|
-
step :save
|
165
|
-
include T.def_steps(:validate, :save)
|
166
|
-
end
|
167
|
-
|
168
|
-
#:nested-with-auto-wire
|
169
|
-
class Create < Trailblazer::Operation
|
170
|
-
step :create
|
171
|
-
step Nested(:compute_nested, auto_wire: [Validate, JsonValidate]),
|
172
|
-
Output(:invalid_json) => End(:jsoned)
|
173
|
-
|
174
|
-
#~meths
|
175
|
-
def compute_nested(ctx, what:, **)
|
176
|
-
what
|
177
|
-
end
|
178
|
-
|
179
|
-
include T.def_steps(:create)
|
180
|
-
#~meths end
|
181
|
-
end
|
182
|
-
#:nested-with-auto-wire end
|
183
|
-
|
184
|
-
|
185
|
-
#@ nested {JsonValidate} ends on {End.success}
|
186
|
-
result = Create.(seq: [], what: JsonValidate, validate: true)
|
187
|
-
|
188
|
-
result.inspect(:seq).must_equal %{<Result:true [[:create, :validate, :save]] >}
|
189
|
-
result.event.inspect.must_equal %{#<Trailblazer::Activity::Railway::End::Success semantic=:success>}
|
190
|
-
|
191
|
-
#@ nested {JsonValidate} ends on {End.invalid_json} because validate fails.
|
192
|
-
result = Create.(seq: [], what: JsonValidate, validate: false)
|
193
|
-
|
194
|
-
result.inspect(:seq).must_equal %{<Result:false [[:create, :validate]] >}
|
195
|
-
result.event.inspect.must_equal %{#<Trailblazer::Activity::End semantic=:jsoned>}
|
196
|
-
|
197
|
-
#@ nested {JsonValidate} ends on {End.failure} because save fails.
|
198
|
-
result = Create.(seq: [], what: JsonValidate, save: false)
|
199
|
-
|
200
|
-
result.inspect(:seq).must_equal %{<Result:false [[:create, :validate, :save]] >}
|
201
|
-
result.event.inspect.must_equal %{#<Trailblazer::Activity::Railway::End::Failure semantic=:failure>}
|
202
|
-
|
203
|
-
#@ nested {Validate} ends on {End.failure} because validate fails.
|
204
|
-
result = Create.(seq: [], what: Validate, validate: false)
|
205
|
-
|
206
|
-
result.inspect(:seq).must_equal %{<Result:false [[:create, :validate]] >}
|
207
|
-
result.event.inspect.must_equal %{#<Trailblazer::Activity::Railway::End::Failure semantic=:failure>}
|
208
|
-
|
209
|
-
#@ nested {Validate} ends on {End.success}.
|
210
|
-
result = Create.(seq: [], what: Validate)
|
211
|
-
|
212
|
-
result.inspect(:seq).must_equal %{<Result:true [[:create, :validate]] >}
|
213
|
-
result.event.inspect.must_equal %{#<Trailblazer::Activity::Railway::End::Success semantic=:success>}
|
214
|
-
end
|
215
|
-
end
|
216
|
-
end
|
217
|
-
|
218
|
-
# TODO: test with :input/:output, tracing
|
@@ -1,89 +0,0 @@
|
|
1
|
-
require "test_helper"
|
2
|
-
|
3
|
-
class ModelTest < Minitest::Spec
|
4
|
-
Song = Struct.new(:id, :title) do
|
5
|
-
def self.find(id); new(id) end
|
6
|
-
def self.find_by(args)
|
7
|
-
key, value = args.flatten
|
8
|
-
return nil if value.nil?
|
9
|
-
return new(value) if key == :id
|
10
|
-
new(2, value) if key == :title
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
#---
|
15
|
-
# use Model semantics, no customizations.
|
16
|
-
# class Create < Trailblazer::Operation
|
17
|
-
class Create < Trailblazer::Operation
|
18
|
-
step Trailblazer::Operation::Model( Song, :new )
|
19
|
-
end
|
20
|
-
|
21
|
-
# :new new.
|
22
|
-
it "initializes new model's instance" do
|
23
|
-
result = Create.()
|
24
|
-
result[:model].inspect.must_equal %{#<struct ModelTest::Song id=nil, title=nil>}
|
25
|
-
end
|
26
|
-
|
27
|
-
# class Update < Create
|
28
|
-
class Update < Trailblazer::Operation
|
29
|
-
step Trailblazer::Operation::Model( Song, :find )#, override: true
|
30
|
-
end
|
31
|
-
|
32
|
-
#---
|
33
|
-
#- inheritance
|
34
|
-
|
35
|
-
# :find it
|
36
|
-
it { Update.(params: { id: 1 })[:model].inspect.must_equal %{#<struct ModelTest::Song id=1, title=nil>} }
|
37
|
-
|
38
|
-
# inherited inspect is ok
|
39
|
-
it { Trailblazer::Developer.railway(Update).must_equal %{[>model.build]} }
|
40
|
-
|
41
|
-
#---
|
42
|
-
# :find_by, exceptionless.
|
43
|
-
# class Find < Trailblazer::Operation
|
44
|
-
class Find < Trailblazer::Operation
|
45
|
-
step Trailblazer::Operation::Model Song, :find_by
|
46
|
-
step :process
|
47
|
-
|
48
|
-
def process(options, **); options[:x] = true end
|
49
|
-
end
|
50
|
-
|
51
|
-
# :find_by, exceptionless.
|
52
|
-
# class FindByKey < Trailblazer::Operation
|
53
|
-
class FindByKey < Trailblazer::Operation
|
54
|
-
step Trailblazer::Operation::Model( Song, :find_by, :title )
|
55
|
-
step :process
|
56
|
-
|
57
|
-
def process(options, **); options[:x] = true end
|
58
|
-
end
|
59
|
-
|
60
|
-
# can't find model.
|
61
|
-
#- result object, model
|
62
|
-
it do
|
63
|
-
Find.(params: {id: nil})[:"result.model"].failure?.must_equal true
|
64
|
-
Find.(params: {id: nil})[:"x"].must_be_nil
|
65
|
-
Find.(params: {id: nil}).failure?.must_equal true
|
66
|
-
end
|
67
|
-
|
68
|
-
#- result object, model
|
69
|
-
it do
|
70
|
-
Find.(params: {id: 9})[:"result.model"].success?.must_equal true
|
71
|
-
Find.(params: {id: 9})[:"x"].must_equal true
|
72
|
-
Find.(params: {id: 9})[:model].inspect.must_equal %{#<struct ModelTest::Song id=9, title=nil>}
|
73
|
-
end
|
74
|
-
|
75
|
-
# can't find model by title.
|
76
|
-
#- result object, model
|
77
|
-
it do
|
78
|
-
FindByKey.(params: {title: nil})[:"result.model"].failure?.must_equal true
|
79
|
-
FindByKey.(params: {title: nil})[:"x"].must_be_nil
|
80
|
-
FindByKey.(params: {title: nil}).failure?.must_equal true
|
81
|
-
end
|
82
|
-
|
83
|
-
#- result object, model by title
|
84
|
-
it do
|
85
|
-
FindByKey.(params: {title: "Test"})[:"result.model"].success?.must_equal true
|
86
|
-
FindByKey.(params: {title: "Test"})[:"x"].must_equal true
|
87
|
-
FindByKey.(params: {title: "Test"})[:model].inspect.must_equal %{#<struct ModelTest::Song id=2, title="Test">}
|
88
|
-
end
|
89
|
-
end
|
@@ -1,98 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class NestedTest < Minitest::Spec
|
4
|
-
DatabaseError = Class.new(Trailblazer::Activity::Signal)
|
5
|
-
|
6
|
-
class SignUp < Trailblazer::Operation
|
7
|
-
def self.b(ctx, **)
|
8
|
-
ctx[:seq] << :b
|
9
|
-
return DatabaseError
|
10
|
-
end
|
11
|
-
|
12
|
-
step method(:b), Output(DatabaseError, :db_error) => End(:db_error)
|
13
|
-
end
|
14
|
-
|
15
|
-
class SignIn < Trailblazer::Operation
|
16
|
-
include T.def_steps(:c)
|
17
|
-
step :c
|
18
|
-
end
|
19
|
-
|
20
|
-
it "allows connection with custom output of a nested activity" do
|
21
|
-
create = Class.new(Trailblazer::Operation) do
|
22
|
-
include T.def_steps(:a, :d)
|
23
|
-
|
24
|
-
step :a
|
25
|
-
step Nested(SignUp), Output(:db_error) => Track(:no_user)
|
26
|
-
step :d, magnetic_to: :no_user
|
27
|
-
end
|
28
|
-
|
29
|
-
result = create.(seq: [])
|
30
|
-
result.inspect(:seq).must_equal %{<Result:true [[:a, :b, :d]] >}
|
31
|
-
result.event.inspect.must_equal %{#<Trailblazer::Activity::Railway::End::Success semantic=:success>}
|
32
|
-
end
|
33
|
-
|
34
|
-
it "allows connecting dynamically nested activities with custom output when auto wired" do
|
35
|
-
create = Class.new(Trailblazer::Operation) do
|
36
|
-
def compute_nested(ctx, what:, **)
|
37
|
-
what
|
38
|
-
end
|
39
|
-
|
40
|
-
include T.def_steps(:a, :d)
|
41
|
-
|
42
|
-
step :a
|
43
|
-
step Nested(:compute_nested, auto_wire: [SignUp, SignIn]), Output(:db_error) => Track(:no_user)
|
44
|
-
step :d, magnetic_to: :no_user
|
45
|
-
end
|
46
|
-
|
47
|
-
result = create.(seq: [], what: SignUp)
|
48
|
-
result.inspect(:seq).must_equal %{<Result:true [[:a, :b, :d]] >}
|
49
|
-
result.event.inspect.must_equal %{#<Trailblazer::Activity::Railway::End::Success semantic=:success>}
|
50
|
-
end
|
51
|
-
|
52
|
-
#@ unit test
|
53
|
-
# TODO: make me a non-Operation test.
|
54
|
-
it "allows using multiple Nested() per operation" do
|
55
|
-
create = Class.new(Trailblazer::Operation) do
|
56
|
-
def compute_nested(ctx, what:, **)
|
57
|
-
what
|
58
|
-
end
|
59
|
-
|
60
|
-
step Nested(:compute_nested)
|
61
|
-
step Nested(:compute_nested), id: :compute_nested_again
|
62
|
-
end
|
63
|
-
|
64
|
-
#@ we want both Nested executed
|
65
|
-
result = create.(seq: [], what: SignIn)
|
66
|
-
result.inspect(:seq).must_equal %{<Result:true [[:c, :c]] >}
|
67
|
-
result.event.inspect.must_equal %{#<Trailblazer::Activity::Railway::End::Success semantic=:success>}
|
68
|
-
|
69
|
-
result = create.wtf?(seq: [], what: SignUp)
|
70
|
-
result.inspect(:seq).must_equal %{<Result:false [[:b]] >}
|
71
|
-
result.event.inspect.must_equal %{#<Trailblazer::Activity::Railway::End::Failure semantic=:failure>}
|
72
|
-
end
|
73
|
-
|
74
|
-
it "raises RuntimeError if dynamically nested activities with custom output are not auto wired" do
|
75
|
-
exception = assert_raises RuntimeError do
|
76
|
-
Class.new(Trailblazer::Operation) do
|
77
|
-
def compute_nested(ctx, what:, **)
|
78
|
-
what
|
79
|
-
end
|
80
|
-
|
81
|
-
step Nested(:compute_nested), Output(:db_error) => Track(:no_user)
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
exception.inspect.must_match 'No `db_error` output found'
|
86
|
-
end
|
87
|
-
|
88
|
-
it "shows warning if `Nested()` is being used instead of `Subprocess()` for static activities" do
|
89
|
-
_, warnings = capture_io do
|
90
|
-
Class.new(Trailblazer::Operation) do
|
91
|
-
step Nested(SignUp)
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
warnings.must_equal %Q{[Trailblazer]#{__FILE__}: Using the `Nested()` macro with operations and activities is deprecated. Replace `Nested(NestedTest::SignUp)` with `Subprocess(NestedTest::SignUp)`.
|
96
|
-
}
|
97
|
-
end
|
98
|
-
end
|