trailblazer-operation 0.0.13 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +5 -3
  3. data/CHANGES.md +44 -0
  4. data/Gemfile +13 -2
  5. data/Rakefile +8 -6
  6. data/lib/trailblazer/operation.rb +86 -12
  7. data/lib/trailblazer/operation/deprecated_macro.rb +19 -0
  8. data/lib/trailblazer/operation/inject.rb +34 -0
  9. data/lib/trailblazer/operation/inspect.rb +80 -0
  10. data/lib/trailblazer/operation/public_call.rb +62 -0
  11. data/lib/trailblazer/operation/railway.rb +32 -0
  12. data/lib/trailblazer/operation/railway/fast_track.rb +13 -0
  13. data/lib/trailblazer/operation/railway/normalizer.rb +73 -0
  14. data/lib/trailblazer/operation/railway/task_builder.rb +44 -0
  15. data/lib/trailblazer/operation/result.rb +6 -4
  16. data/lib/trailblazer/operation/skill.rb +8 -24
  17. data/lib/trailblazer/operation/task_wrap.rb +68 -0
  18. data/lib/trailblazer/operation/trace.rb +49 -0
  19. data/lib/trailblazer/operation/variable_mapping.rb +91 -0
  20. data/lib/trailblazer/operation/version.rb +1 -1
  21. data/test/call_test.rb +27 -8
  22. data/test/class_dependencies_test.rb +16 -0
  23. data/test/docs/doormat_test.rb +189 -0
  24. data/test/docs/wiring_test.rb +421 -0
  25. data/test/dry_container_test.rb +4 -0
  26. data/test/fast_track_test.rb +197 -0
  27. data/test/gemfiles/Gemfile.ruby-2.0 +1 -2
  28. data/test/gemfiles/Gemfile.ruby-2.0.lock +40 -0
  29. data/test/inheritance_test.rb +1 -1
  30. data/test/inspect_test.rb +43 -0
  31. data/test/introspect_test.rb +50 -0
  32. data/test/macro_test.rb +61 -0
  33. data/test/operation_test.rb +94 -0
  34. data/test/result_test.rb +14 -8
  35. data/test/ruby-2.0.0/operation_test.rb +73 -0
  36. data/test/ruby-2.0.0/step_test.rb +136 -0
  37. data/test/skill_test.rb +66 -48
  38. data/test/step_test.rb +228 -0
  39. data/test/task_wrap_test.rb +91 -0
  40. data/test/test_helper.rb +37 -0
  41. data/test/trace_test.rb +62 -0
  42. data/test/variable_mapping_test.rb +66 -0
  43. data/test/wire_test.rb +113 -0
  44. data/test/wiring/defaults_test.rb +197 -0
  45. data/test/wiring/subprocess_test.rb +70 -0
  46. data/trailblazer-operation.gemspec +3 -5
  47. metadata +62 -36
  48. data/lib/trailblazer/operation/1.9.3/option.rb +0 -36
  49. data/lib/trailblazer/operation/generic.rb +0 -12
  50. data/lib/trailblazer/operation/option.rb +0 -54
  51. data/lib/trailblazer/operation/pipetree.rb +0 -142
  52. data/lib/trailblazer/skill.rb +0 -70
  53. data/test/2.0.0-pipetree_test.rb +0 -100
  54. data/test/2.1.0-pipetree_test.rb +0 -100
  55. data/test/operation_skill_test.rb +0 -89
  56. data/test/pipetree_test.rb +0 -185
@@ -0,0 +1,16 @@
1
+ require "test_helper"
2
+
3
+ class ClassDependenciesTest < Minitest::Spec
4
+
5
+ #- Operation[] and Operation[]=
6
+
7
+ class Index < Trailblazer::Operation
8
+ extend ClassDependencies
9
+
10
+ self["model.class"] = Module
11
+
12
+ step ->(options, **) { options["a"] = options["model.class"] }
13
+ end
14
+
15
+ it { Index.({}).inspect("a", "model.class").must_equal %{<Result:true [Module, Module] >} }
16
+ end
@@ -0,0 +1,189 @@
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 { Memo::Create.(params: {}, "b_return" => false,
53
+ ).inspect("row").must_equal %{<Result:true [[:a, :l, :b, :c, :z]] >} }
54
+ end
55
+
56
+ class DoormatWithGroupTest < Minitest::Spec
57
+ module Memo; end
58
+
59
+ #:doormat-group
60
+ class Memo::Create < Trailblazer::Operation
61
+ step :create_model
62
+ step :log_success, group: :end, before: "End.success"
63
+
64
+ step :validate
65
+ step :save
66
+
67
+ fail :log_errors, group: :end, before: "End.failure"
68
+ #~methods
69
+ def create_model(options, **)
70
+ options["row"] = [:a]
71
+ end
72
+
73
+ # our success "end":
74
+ def log_success(options, **)
75
+ options["row"] << :z
76
+ end
77
+
78
+ # 2
79
+ def validate(options, **)
80
+ options["row"] << :b
81
+ end
82
+
83
+ # 3
84
+ def save(options, **)
85
+ options["row"] << :c
86
+ end
87
+
88
+ def log_errors(options, **)
89
+ options["row"] << :f
90
+ end
91
+ #~methods end
92
+ end
93
+ #:doormat-group end
94
+
95
+ # it { pp F['__sequence__'].to_a }
96
+ it { Memo::Create.(params: {}, "b_return" => false,
97
+ ).inspect("row").must_equal %{<Result:true [[:a, :b, :c, :z]] >} }
98
+ end
99
+
100
+ class DoormatStepDocsTest < Minitest::Spec
101
+ module Memo; end
102
+
103
+ #:doormat-before
104
+ class Memo::Create < Trailblazer::Operation
105
+ step :create_model
106
+ step :log_success
107
+
108
+ step :validate, before: :log_success
109
+ step :save, before: :log_success
110
+
111
+ fail :log_errors
112
+ #~im
113
+ def create_model(options, **)
114
+ options["row"] = [:a]
115
+ end
116
+
117
+ # our success "end":
118
+ def log_success(options, **)
119
+ options["row"] << :z
120
+ end
121
+
122
+ # 2
123
+ def validate(options, **)
124
+ options["row"] << :b
125
+ end
126
+
127
+ # 3
128
+ def save(options, **)
129
+ options["row"] << :c
130
+ end
131
+
132
+ def log_errors(options, **)
133
+ options["row"] << :f
134
+ end
135
+ #~im end
136
+ end
137
+ #:doormat-before end
138
+
139
+ # it { pp F['__sequence__'].to_a }
140
+ it { Memo::Create.(params: {}, "b_return" => false,
141
+ ).inspect("row").must_equal %{<Result:true [[:a, :b, :c, :z]] >} }
142
+ end
143
+
144
+ class DoormatInheritanceTest < Minitest::Spec
145
+ #:doormatx-before-inheritance
146
+ class Base < Trailblazer::Operation
147
+ step :log_success!
148
+ fail :log_errors!
149
+ #~ignored
150
+ # our success "end":
151
+ def log_success!(options, **)
152
+ options["row"] << :z
153
+ end
154
+
155
+ def log_errors!(options, **)
156
+ options["row"] << :f
157
+ end
158
+ #~ignored end
159
+ end
160
+ #:doormatx-before-inheritance end
161
+
162
+ #:doormat-before-inheritance-sub
163
+ class Create < Base
164
+ step :first, before: :log_success!
165
+ step :second, before: :log_success!
166
+ step :third, before: :log_success!
167
+ #~ignoredd
168
+ def first(options, **)
169
+ options["row"] = [:a]
170
+ end
171
+
172
+ # 2
173
+ def second(options, **)
174
+ options["row"] << :b
175
+ end
176
+
177
+ # 3
178
+ def third(options, **)
179
+ options["row"] << :c
180
+ end
181
+ #~ignoredd end
182
+ end
183
+ #:doormat-before-inheritance-sub end
184
+
185
+ # it { pp F['__sequence__'].to_a }
186
+ it { Create.({}, "b_return" => false,
187
+ ).inspect("row").must_equal %{<Result:true [[:a, :b, :c, :z]] >} }
188
+ end
189
+
@@ -0,0 +1,421 @@
1
+ require "test_helper"
2
+
3
+ class WiringDocsTest < Minitest::Spec
4
+ class Memo
5
+ def initialize(options={})
6
+ @options
7
+ end
8
+
9
+ def inspect
10
+ %{#<Memo text=#{text.inspect}>}
11
+ end
12
+
13
+ attr_accessor :id, :text
14
+ end
15
+
16
+ # _"Everything's a memo."_
17
+
18
+ module Step
19
+ #:memo-op
20
+ class Memo::Create < Trailblazer::Operation
21
+ step :create_model
22
+ step :validate
23
+ fail :assign_errors
24
+ step :index
25
+ pass :uuid
26
+ step :save
27
+ fail :log_errors
28
+ #~memo-methods
29
+ def create_model(options, **)
30
+ end
31
+ def validate(options, **)
32
+ end
33
+ def assign_errors(options, **)
34
+ end
35
+ def index(options, **)
36
+ end
37
+ def uuid(options, **)
38
+ end
39
+ def save(options, **)
40
+ end
41
+ def log_errors(options, **)
42
+ end
43
+ #~memo-methods end
44
+ end
45
+ #:memo-op end
46
+
47
+ end
48
+
49
+ it do
50
+ result = Memo::Create.( text: "Punk is not dead." )
51
+ end
52
+
53
+
54
+ module PassFast
55
+ #:pf-op
56
+ class Memo::Create < Trailblazer::Operation
57
+ step :create_model
58
+ step :validate, pass_fast: true
59
+ fail :assign_errors
60
+ step :index
61
+ pass :uuid
62
+ step :save
63
+ fail :log_errors
64
+ #~pf-methods
65
+ def create_model(options, **)
66
+ end
67
+ def validate(options, **)
68
+ end
69
+ def assign_errors(options, **)
70
+ end
71
+ def index(options, **)
72
+ end
73
+ def uuid(options, **)
74
+ end
75
+ def save(options, **)
76
+ end
77
+ def log_errors(options, **)
78
+ end
79
+ #~pf-methods end
80
+ end
81
+ #:pf-op end
82
+
83
+ end
84
+
85
+ module FailFast
86
+ #:ff-op
87
+ class Memo::Create < Trailblazer::Operation
88
+ step :create_model
89
+ step :validate
90
+ fail :assign_errors, fail_fast: true
91
+ step :index
92
+ pass :uuid
93
+ step :save
94
+ fail :log_errors
95
+ #~ff-methods
96
+ def create_model(options, **)
97
+ end
98
+ def validate(options, **)
99
+ end
100
+ def assign_errors(options, **)
101
+ end
102
+ def index(options, **)
103
+ end
104
+ def uuid(options, **)
105
+ end
106
+ def save(options, **)
107
+ end
108
+ def log_errors(options, **)
109
+ end
110
+ #~ff-methods end
111
+ end
112
+ #:ff-op end
113
+
114
+ end
115
+
116
+ module FailFast
117
+ #:ff-step-op
118
+ class Memo::Create < Trailblazer::Operation
119
+ step :create_model
120
+ step :validate
121
+ fail :assign_errors, fail_fast: true
122
+ step :index, fail_fast: true
123
+ pass :uuid
124
+ step :save
125
+ fail :log_errors
126
+ #~ff-step-methods
127
+ def create_model(options, **)
128
+ end
129
+ def validate(options, **)
130
+ end
131
+ def assign_errors(options, **)
132
+ end
133
+ def index(options, **)
134
+ end
135
+ def uuid(options, **)
136
+ end
137
+ def save(options, **)
138
+ end
139
+ def log_errors(options, **)
140
+ end
141
+ #~ff-step-methods end
142
+ end
143
+ #:ff-step-op end
144
+ end
145
+
146
+ =begin
147
+ describe all options :pass_fast, :fast_track and emiting signals directly, like Left.
148
+ =end
149
+ module FastTrack
150
+ class Memo < WiringDocsTest::Memo; end
151
+
152
+ #:ft-step-op
153
+ class Memo::Create < Trailblazer::Operation
154
+ step :create_model, fast_track: true
155
+ step :validate
156
+ fail :assign_errors, fast_track: true
157
+ step :index
158
+ pass :uuid
159
+ step :save
160
+ fail :log_errors
161
+ #~ft-step-methods
162
+ #:ft-create
163
+ def create_model(options, create_empty_model:false, **)
164
+ options[:model] = Memo.new
165
+ create_empty_model ? Railway.pass_fast! : true
166
+ end
167
+ #:ft-create end
168
+ #:signal-validate
169
+ def validate(options, params: {}, **)
170
+ if params[:text].nil?
171
+ Trailblazer::Activity::Left #=> left track, failure
172
+ else
173
+ Trailblazer::Activity::Right #=> right track, success
174
+ end
175
+ end
176
+ #:signal-validate end
177
+ def assign_errors(options, model:, **)
178
+ options[:errors] = "Something went wrong!"
179
+
180
+ model.id.nil? ? Railway.fail_fast! : false
181
+ end
182
+ def index(options, model:, **)
183
+ true
184
+ end
185
+ def uuid(options, **)
186
+ true
187
+ end
188
+ def save(options, model:, **)
189
+ model.id = 1
190
+ end
191
+ def log_errors(options, **)
192
+ end
193
+ #~ft-step-methods end
194
+ end
195
+ #:ft-step-op end
196
+
197
+ class Memo::Create2 < Memo::Create
198
+ #:signalhelper-validate
199
+ def validate(options, params: {}, **)
200
+ if params[:text].nil?
201
+ Railway.fail! #=> left track, failure
202
+ else
203
+ Railway.pass! #=> right track, success
204
+ end
205
+ end
206
+ #:signalhelper-validate end
207
+ end
208
+ end
209
+
210
+ it "runs #create_model, only" do
211
+ Memo = FastTrack::Memo
212
+ #:ft-call
213
+ result = Memo::Create.( create_empty_model: true )
214
+ puts result.success? #=> true
215
+ puts result[:model].inspect #=> #<Memo text=nil>
216
+ #:ft-call end
217
+
218
+ result.success?.must_equal true
219
+ result[:model].id.must_be_nil
220
+ end
221
+
222
+ it "fast-tracks in #assign_errors" do
223
+ Memo = FastTrack::Memo
224
+ #:ft-call-err
225
+ result = Memo::Create.( {} )
226
+ puts result.success? #=> false
227
+ puts result[:model].inspect #=> #<Memo text=nil>
228
+ puts result[:errors].inspect #=> "Something went wrong!"
229
+ #:ft-call-err end
230
+
231
+ result.success?.must_equal false
232
+ result[:model].id.must_be_nil
233
+ result[:errors].must_equal "Something went wrong!"
234
+ end
235
+
236
+ it "goes till #save by emitting signals directly" do
237
+ Memo = FastTrack::Memo
238
+ result = Memo::Create.( params: { text: "Punk is not dead!" } )
239
+ result.success?.must_equal true
240
+ result[:model].id.must_equal 1
241
+ result[:errors].must_be_nil
242
+ end
243
+
244
+ it "goes till #save by using signal helper" do
245
+ Memo = FastTrack::Memo
246
+ result = Memo::Create2.( params: { text: "Punk is not dead!" } )
247
+ result.success?.must_equal true
248
+ result[:model].id.must_equal 1
249
+ result[:errors].must_be_nil
250
+ end
251
+ end
252
+
253
+ =begin
254
+ :before, :after, :replace, :delete, :group, :id
255
+ =end
256
+ class WiringsDocSeqOptionsTest < Minitest::Spec
257
+ module Id
258
+ class Memo < WiringDocsTest::Memo; end
259
+
260
+ #:id
261
+ class Memo::Create < Trailblazer::Operation
262
+ step :create_model, id: "create_memo"
263
+ step :validate, id: "validate_params"
264
+ step :save
265
+ #~id-methods
266
+ def create_model(options, **)
267
+ end
268
+ def validate(options, **)
269
+ end
270
+ def save(options, **)
271
+ end
272
+ #~id-methods end
273
+ end
274
+ #:id end
275
+
276
+ #:delete
277
+ class Memo::Create::Admin < Memo::Create
278
+ step nil, delete: "validate_params", id: ""
279
+ end
280
+ #:delete end
281
+
282
+ #:before
283
+ class Memo::Create::Authorized < Memo::Create
284
+ step :policy, before: "create_memo"
285
+ #~before-methods
286
+ def policy(options, **)
287
+ end
288
+ #~before-methods end
289
+ end
290
+ #:before end
291
+
292
+ #:after
293
+ class Memo::Create::Logging < Memo::Create
294
+ step :logger, after: "validate_params"
295
+ #~after-methods
296
+ def logger(options, **)
297
+ end
298
+ #~after-methods end
299
+ end
300
+ #:after end
301
+
302
+ #:replace
303
+ class Memo::Update < Memo::Create
304
+ step :find_model, replace: "create_memo", id: "update_memo"
305
+ #~replace-methods
306
+ def find_model(options, **)
307
+ end
308
+ #~replace-methods end
309
+ end
310
+ #:replace end
311
+ end
312
+
313
+ it ":id shows up in introspect" do
314
+ Memo = Id::Memo
315
+ #:id-inspect
316
+ Trailblazer::Operation.introspect( Memo::Create )
317
+ #=> [>create_model,>validate_params,>save]
318
+ #:id-inspect end
319
+
320
+ Trailblazer::Operation.introspect( Memo::Create ).must_equal %{[>create_memo,>validate_params,>save]}
321
+ end
322
+
323
+ it ":delete removes step" do
324
+ Memo = Id::Memo
325
+ #:delete-inspect
326
+ Trailblazer::Operation.introspect( Memo::Create::Admin )
327
+ #=> [>create_model,>save]
328
+ #:delete-inspect end
329
+
330
+ Trailblazer::Operation.introspect( Memo::Create::Admin ).must_equal %{[>create_memo,>save]}
331
+ end
332
+
333
+ it ":before inserts" do
334
+ Memo = Id::Memo
335
+ #:before-inspect
336
+ Trailblazer::Operation.introspect( Memo::Create::Authorized )
337
+ #=> [>create_model,>save]
338
+ #:before-inspect end
339
+
340
+ Trailblazer::Operation.introspect( Memo::Create::Authorized ).must_equal %{[>policy,>create_memo,>validate_params,>save]}
341
+ end
342
+
343
+ it ":after inserts" do
344
+ Memo = Id::Memo
345
+ #:after-inspect
346
+ Trailblazer::Operation.introspect( Memo::Create::Logging )
347
+ #=> [>create_memo,>validate_params,>logger,>save]
348
+ #:after-inspect end
349
+
350
+ Trailblazer::Operation.introspect( Memo::Create::Logging ).must_equal %{[>create_memo,>validate_params,>logger,>save]}
351
+ end
352
+
353
+ it ":replace inserts" do
354
+ Memo = Id::Memo
355
+ #:replace-inspect
356
+ Trailblazer::Operation.introspect( Memo::Update )
357
+ #=> [>update_memo,>validate_params,>save]
358
+ #:replace-inspect end
359
+
360
+ Trailblazer::Operation.introspect( Memo::Update ).must_equal %{[>update_memo,>validate_params,>save]}
361
+ end
362
+ end
363
+
364
+ # @see https://github.com/trailblazer/trailblazer/issues/190#issuecomment-326992255
365
+ class WiringsDocRecoverTest < Minitest::Spec
366
+ Memo = WiringDocsTest::Memo
367
+
368
+ #:fail-success
369
+ class Memo::Upload < Trailblazer::Operation
370
+ step :upload_to_s3
371
+ fail :upload_to_azure, Output(:success) => :success
372
+ fail :upload_to_b2, Output(:success) => :success
373
+ fail :log_problem
374
+ #~fail-success-methods
375
+ #:fail-success-s3
376
+ def upload_to_s3(options, s3:, **)
377
+ options[:s3] = s3 # the actual upload is dispatched here and result collected.
378
+ end
379
+ #:fail-success-s3 end
380
+
381
+ def upload_to_azure(options, azure:, **)
382
+ options[:azure] = azure
383
+ end
384
+
385
+ def upload_to_b2(options, b2:, **)
386
+ options[:b2] = b2
387
+ end
388
+
389
+ def log_problem(options, **)
390
+ options[:problem] = "All uploads failed."
391
+ end
392
+ #~fail-success-methods end
393
+ end
394
+ #:fail-success end
395
+
396
+ let(:my_image) { "beautiful landscape" }
397
+
398
+ it "works for S3" do
399
+ result = Memo::Upload.( image: my_image, s3: true )
400
+
401
+ [ result.success?, result[:s3], result[:azure], result[:b2], result[:problem] ].must_equal [ true, true, nil, nil, nil ]
402
+ end
403
+
404
+ it "works for Azure" do
405
+ result = Memo::Upload.( image: my_image, azure: true, s3: false )
406
+
407
+ [ result.success?, result[:s3], result[:azure], result[:b2], result[:problem] ].must_equal [ true, false, true, nil, nil ]
408
+ end
409
+
410
+ it "works for B2" do
411
+ result = Memo::Upload.( image: my_image, b2: true, azure: false, s3: false )
412
+
413
+ [ result.success?, result[:s3], result[:azure], result[:b2], result[:problem] ].must_equal [ true, false, false, true, nil ]
414
+ end
415
+
416
+ it "fails for all" do
417
+ result = Memo::Upload.( image: my_image, b2: false, azure: false, s3: false )
418
+
419
+ [ result.success?, result[:s3], result[:azure], result[:b2], result[:problem] ].must_equal [ false, false, false, false, "All uploads failed." ]
420
+ end
421
+ end