trailblazer-operation 0.0.13 → 0.1.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.
- checksums.yaml +4 -4
- data/.travis.yml +5 -3
- data/CHANGES.md +44 -0
- data/Gemfile +13 -2
- data/Rakefile +8 -6
- data/lib/trailblazer/operation.rb +86 -12
- data/lib/trailblazer/operation/deprecated_macro.rb +19 -0
- data/lib/trailblazer/operation/inject.rb +34 -0
- data/lib/trailblazer/operation/inspect.rb +80 -0
- data/lib/trailblazer/operation/public_call.rb +62 -0
- data/lib/trailblazer/operation/railway.rb +32 -0
- data/lib/trailblazer/operation/railway/fast_track.rb +13 -0
- data/lib/trailblazer/operation/railway/normalizer.rb +73 -0
- data/lib/trailblazer/operation/railway/task_builder.rb +44 -0
- data/lib/trailblazer/operation/result.rb +6 -4
- data/lib/trailblazer/operation/skill.rb +8 -24
- data/lib/trailblazer/operation/task_wrap.rb +68 -0
- data/lib/trailblazer/operation/trace.rb +49 -0
- data/lib/trailblazer/operation/variable_mapping.rb +91 -0
- data/lib/trailblazer/operation/version.rb +1 -1
- data/test/call_test.rb +27 -8
- data/test/class_dependencies_test.rb +16 -0
- data/test/docs/doormat_test.rb +189 -0
- data/test/docs/wiring_test.rb +421 -0
- data/test/dry_container_test.rb +4 -0
- data/test/fast_track_test.rb +197 -0
- data/test/gemfiles/Gemfile.ruby-2.0 +1 -2
- data/test/gemfiles/Gemfile.ruby-2.0.lock +40 -0
- data/test/inheritance_test.rb +1 -1
- data/test/inspect_test.rb +43 -0
- data/test/introspect_test.rb +50 -0
- data/test/macro_test.rb +61 -0
- data/test/operation_test.rb +94 -0
- data/test/result_test.rb +14 -8
- data/test/ruby-2.0.0/operation_test.rb +73 -0
- data/test/ruby-2.0.0/step_test.rb +136 -0
- data/test/skill_test.rb +66 -48
- data/test/step_test.rb +228 -0
- data/test/task_wrap_test.rb +91 -0
- data/test/test_helper.rb +37 -0
- data/test/trace_test.rb +62 -0
- data/test/variable_mapping_test.rb +66 -0
- data/test/wire_test.rb +113 -0
- data/test/wiring/defaults_test.rb +197 -0
- data/test/wiring/subprocess_test.rb +70 -0
- data/trailblazer-operation.gemspec +3 -5
- metadata +62 -36
- data/lib/trailblazer/operation/1.9.3/option.rb +0 -36
- data/lib/trailblazer/operation/generic.rb +0 -12
- data/lib/trailblazer/operation/option.rb +0 -54
- data/lib/trailblazer/operation/pipetree.rb +0 -142
- data/lib/trailblazer/skill.rb +0 -70
- data/test/2.0.0-pipetree_test.rb +0 -100
- data/test/2.1.0-pipetree_test.rb +0 -100
- data/test/operation_skill_test.rb +0 -89
- data/test/pipetree_test.rb +0 -185
data/lib/trailblazer/skill.rb
DELETED
@@ -1,70 +0,0 @@
|
|
1
|
-
# TODO: mark/make all but mutable_options as frozen.
|
2
|
-
# The idea of Skill is to have a generic, ordered read/write interface that
|
3
|
-
# collects mutable runtime-computed data while providing access to compile-time
|
4
|
-
# information.
|
5
|
-
# The runtime-data takes precedence over the class data.
|
6
|
-
module Trailblazer
|
7
|
-
class Skill
|
8
|
-
def initialize(*containers)
|
9
|
-
@mutable_options = {}
|
10
|
-
@resolver = Resolver.new(@mutable_options, *containers)
|
11
|
-
end
|
12
|
-
|
13
|
-
def [](name)
|
14
|
-
@resolver[name]
|
15
|
-
end
|
16
|
-
|
17
|
-
def []=(name, value)
|
18
|
-
@mutable_options[name] = value
|
19
|
-
end
|
20
|
-
|
21
|
-
# THIS METHOD IS CONSIDERED PRIVATE AND MIGHT BE REMOVED.
|
22
|
-
# Options from ::call (e.g. "user.current"), containers, etc.
|
23
|
-
# NO mutual data from the caller operation. no class state.
|
24
|
-
def to_runtime_data
|
25
|
-
@resolver.instance_variable_get(:@containers).slice(1..-2)
|
26
|
-
end
|
27
|
-
|
28
|
-
# THIS METHOD IS CONSIDERED PRIVATE AND MIGHT BE REMOVED.
|
29
|
-
def to_mutable_data
|
30
|
-
@mutable_options
|
31
|
-
end
|
32
|
-
|
33
|
-
# Called when Ruby transforms options into kw args, via **options.
|
34
|
-
# TODO: this method has massive potential for speed improvements.
|
35
|
-
# The `tmp_options` argument is experimental. It allows adding temporary options
|
36
|
-
# to the kw args.
|
37
|
-
#:private:
|
38
|
-
def to_hash(tmp_options={})
|
39
|
-
{}.tap do |h|
|
40
|
-
arr = to_runtime_data << to_mutable_data << tmp_options
|
41
|
-
|
42
|
-
arr.each { |hsh|
|
43
|
-
hsh.each { |k, v| h[k.to_sym] = v }
|
44
|
-
}
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
# Look through a list of containers until you find the skill.
|
49
|
-
class Resolver
|
50
|
-
# alternative implementation:
|
51
|
-
# containers.reverse.each do |container| @mutable_options.merge!(container) end
|
52
|
-
#
|
53
|
-
# benchmark, merging in #initialize vs. this resolver.
|
54
|
-
# merge 39.678k (± 9.1%) i/s - 198.700k in 5.056653s
|
55
|
-
# resolver 68.928k (± 6.4%) i/s - 342.836k in 5.001610s
|
56
|
-
def initialize(*containers)
|
57
|
-
@containers = containers
|
58
|
-
end
|
59
|
-
|
60
|
-
def [](name)
|
61
|
-
@containers.find { |container| container.key?(name) && (return container[name]) }
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
# private API.
|
66
|
-
def inspect
|
67
|
-
"<Skill #{@resolver.instance_variable_get(:@containers).collect { |c| c.inspect }.join(" ")}>"
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
data/test/2.0.0-pipetree_test.rb
DELETED
@@ -1,100 +0,0 @@
|
|
1
|
-
require "test_helper"
|
2
|
-
|
3
|
-
class KWBugsTest < Minitest::Spec
|
4
|
-
Merchant = Struct.new(:id)
|
5
|
-
|
6
|
-
class Merchant::New < Trailblazer::Operation
|
7
|
-
step ->(options) {
|
8
|
-
options["model"] = 1
|
9
|
-
options["bla"] = true # this breaks Ruby 2.2.2.
|
10
|
-
}
|
11
|
-
|
12
|
-
step :add!
|
13
|
-
def add!(yo:nil, model:nil, **)
|
14
|
-
raise if model.nil?
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
it { Merchant::New.( {}, { "yo"=> nil } ) }
|
19
|
-
end
|
20
|
-
|
21
|
-
class KWOptionsTest < Minitest::Spec
|
22
|
-
X = Trailblazer::Operation::Option::KW.( ->(options, **) { options["x"] = true } )
|
23
|
-
Y = Trailblazer::Operation::Option::KW.( ->(options, params:nil, **) { options["y"] = params } )
|
24
|
-
Z = Trailblazer::Operation::Option::KW.( ->(options, params:nil, z:nil, **) { options["kw_z"] = z } )
|
25
|
-
A = Trailblazer::Operation::Option::KW.( ->(options, params:nil, z:nil, **) { options["options_z"] = options["z"] } )
|
26
|
-
|
27
|
-
class Create < Trailblazer::Operation
|
28
|
-
step [ ->(input, options) { X.(input, options, z: "Z!") }, name: "X" ]
|
29
|
-
step [ ->(input, options) { Y.(input, options, z: "Z!") }, name: "Y" ]
|
30
|
-
step [ ->(input, options) { Z.(input, options, z: "Z!") }, name: "Z" ]
|
31
|
-
step [ ->(input, options) { A.(input, options, z: "Z!") }, name: "A" ]
|
32
|
-
end
|
33
|
-
|
34
|
-
it { Create.({ params: "yo" }, "z" => 1).inspect("x", "y", "kw_z", "options_z").must_equal %{<Result:true [true, {:params=>\"yo\"}, "Z!", 1] >} }
|
35
|
-
end
|
36
|
-
|
37
|
-
|
38
|
-
class Ruby200PipetreeTest < Minitest::Spec
|
39
|
-
class Create < Trailblazer::Operation
|
40
|
-
step ->(*, params:nil, **) { params["run"] } # only test kws.
|
41
|
-
step ->(options, params:nil, **) { options["x"] = params["run"] } # read and write.
|
42
|
-
step ->(options) { options["y"] = options["params"]["run"] } # old API.
|
43
|
-
end
|
44
|
-
|
45
|
-
it { Create.("run" => false).inspect("x", "y").must_equal %{<Result:false [nil, nil] >} }
|
46
|
-
it { Create.("run" => true).inspect("x", "y").must_equal %{<Result:true [true, true] >} }
|
47
|
-
|
48
|
-
#- instance methods
|
49
|
-
class Update < Trailblazer::Operation
|
50
|
-
step :params! # only test kws.
|
51
|
-
step :x! # read and write.
|
52
|
-
step :y! # old API.
|
53
|
-
|
54
|
-
def params!(*, params:nil, **)
|
55
|
-
params["run"]
|
56
|
-
end
|
57
|
-
|
58
|
-
def x!(options, params:nil, **)
|
59
|
-
options["x"] = params["run"]
|
60
|
-
end
|
61
|
-
|
62
|
-
def y!(options)
|
63
|
-
options["y"] = options["params"]["run"]
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
it { Update.("run" => false).inspect("x", "y").must_equal %{<Result:false [nil, nil] >} }
|
68
|
-
it { Update.("run" => true).inspect("x", "y").must_equal %{<Result:true [true, true] >} }
|
69
|
-
|
70
|
-
|
71
|
-
class Delete < Trailblazer::Operation
|
72
|
-
class Params
|
73
|
-
extend Uber::Callable
|
74
|
-
def self.call(*, params:nil, **)
|
75
|
-
params["run"]
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
class X
|
80
|
-
extend Uber::Callable
|
81
|
-
def self.call(options, params:nil, **)
|
82
|
-
options["x"] = params["run"]
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
class Y
|
87
|
-
extend Uber::Callable
|
88
|
-
def self.call(options)
|
89
|
-
options["y"] = options["params"]["run"]
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
step Params
|
94
|
-
step X
|
95
|
-
step Y
|
96
|
-
end
|
97
|
-
|
98
|
-
it { Delete.("run" => false).inspect("x", "y").must_equal %{<Result:false [nil, nil] >} }
|
99
|
-
it { Delete.("run" => true).inspect("x", "y").must_equal %{<Result:true [true, true] >} }
|
100
|
-
end
|
data/test/2.1.0-pipetree_test.rb
DELETED
@@ -1,100 +0,0 @@
|
|
1
|
-
require "test_helper"
|
2
|
-
|
3
|
-
class KWBugsTest < Minitest::Spec
|
4
|
-
Merchant = Struct.new(:id)
|
5
|
-
|
6
|
-
class Merchant::New < Trailblazer::Operation
|
7
|
-
step ->(options) {
|
8
|
-
options["model"] = 1
|
9
|
-
options["bla"] = true # this breaks Ruby 2.2.2.
|
10
|
-
}
|
11
|
-
|
12
|
-
step :add!
|
13
|
-
def add!(yo:, model:, **)
|
14
|
-
raise if model.nil?
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
it { Merchant::New.( {}, { "yo"=> nil } ) }
|
19
|
-
end
|
20
|
-
|
21
|
-
class KWOptionsTest < Minitest::Spec
|
22
|
-
X = Trailblazer::Operation::Option::KW.( ->(options, **) { options["x"] = true } )
|
23
|
-
Y = Trailblazer::Operation::Option::KW.( ->(options, params:, **) { options["y"] = params } )
|
24
|
-
Z = Trailblazer::Operation::Option::KW.( ->(options, params:, z:, **) { options["kw_z"] = z } )
|
25
|
-
A = Trailblazer::Operation::Option::KW.( ->(options, params:, z:, **) { options["options_z"] = options["z"] } )
|
26
|
-
|
27
|
-
class Create < Trailblazer::Operation
|
28
|
-
step [ ->(input, options) { X.(input, options, z: "Z!") }, name: "X" ]
|
29
|
-
step [ ->(input, options) { Y.(input, options, z: "Z!") }, name: "Y" ]
|
30
|
-
step [ ->(input, options) { Z.(input, options, z: "Z!") }, name: "Z" ]
|
31
|
-
step [ ->(input, options) { A.(input, options, z: "Z!") }, name: "A" ]
|
32
|
-
end
|
33
|
-
|
34
|
-
it { Create.({ params: "yo" }, "z" => 1).inspect("x", "y", "kw_z", "options_z").must_equal %{<Result:true [true, {:params=>\"yo\"}, "Z!", 1] >} }
|
35
|
-
end
|
36
|
-
|
37
|
-
|
38
|
-
class Ruby200PipetreeTest < Minitest::Spec
|
39
|
-
class Create < Trailblazer::Operation
|
40
|
-
step ->(*, params:, **) { params["run"] } # only test kws.
|
41
|
-
step ->(options, params:nil, **) { options["x"] = params["run"] } # read and write.
|
42
|
-
step ->(options) { options["y"] = options["params"]["run"] } # old API.
|
43
|
-
end
|
44
|
-
|
45
|
-
it { Create.("run" => false).inspect("x", "y").must_equal %{<Result:false [nil, nil] >} }
|
46
|
-
it { Create.("run" => true).inspect("x", "y").must_equal %{<Result:true [true, true] >} }
|
47
|
-
|
48
|
-
#- instance methods
|
49
|
-
class Update < Trailblazer::Operation
|
50
|
-
step :params! # only test kws.
|
51
|
-
step :x! # read and write.
|
52
|
-
step :y! # old API.
|
53
|
-
|
54
|
-
def params!(*, params:, **)
|
55
|
-
params["run"]
|
56
|
-
end
|
57
|
-
|
58
|
-
def x!(options, params:nil, **)
|
59
|
-
options["x"] = params["run"]
|
60
|
-
end
|
61
|
-
|
62
|
-
def y!(options)
|
63
|
-
options["y"] = options["params"]["run"]
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
it { Update.("run" => false).inspect("x", "y").must_equal %{<Result:false [nil, nil] >} }
|
68
|
-
it { Update.("run" => true).inspect("x", "y").must_equal %{<Result:true [true, true] >} }
|
69
|
-
|
70
|
-
|
71
|
-
class Delete < Trailblazer::Operation
|
72
|
-
class Params
|
73
|
-
extend Uber::Callable
|
74
|
-
def self.call(*, params:, **)
|
75
|
-
params["run"]
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
class X
|
80
|
-
extend Uber::Callable
|
81
|
-
def self.call(options, params:nil, **)
|
82
|
-
options["x"] = params["run"]
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
class Y
|
87
|
-
extend Uber::Callable
|
88
|
-
def self.call(options)
|
89
|
-
options["y"] = options["params"]["run"]
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
step Params
|
94
|
-
step X
|
95
|
-
step Y
|
96
|
-
end
|
97
|
-
|
98
|
-
it { Delete.("run" => false).inspect("x", "y").must_equal %{<Result:false [nil, nil] >} }
|
99
|
-
it { Delete.("run" => true).inspect("x", "y").must_equal %{<Result:true [true, true] >} }
|
100
|
-
end
|
@@ -1,89 +0,0 @@
|
|
1
|
-
require "test_helper"
|
2
|
-
|
3
|
-
class OperationSkillTest < Minitest::Spec
|
4
|
-
class Create < Trailblazer::Operation
|
5
|
-
end
|
6
|
-
|
7
|
-
# no dependencies provided.
|
8
|
-
it { Create.()[:not_existent].must_equal nil }
|
9
|
-
# dependencies provided.
|
10
|
-
it { Create.({}, contract: Object)[:not_existent].must_equal nil }
|
11
|
-
it { Create.({}, contract: Object)[:contract].must_equal Object }
|
12
|
-
end
|
13
|
-
|
14
|
-
class OperationCompetenceTest < Minitest::Spec
|
15
|
-
# Operation#[]
|
16
|
-
# Operation#[]=
|
17
|
-
# arbitrary options can be saved via Op#[].
|
18
|
-
class Create < Trailblazer::Operation
|
19
|
-
success :call
|
20
|
-
|
21
|
-
def call(*)
|
22
|
-
self["drink"] = "Little Creatures"
|
23
|
-
self["drink"]
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
it { Create.()["drink"].must_equal "Little Creatures" }
|
28
|
-
# instance can override constructor options.
|
29
|
-
it { Create.({}, "drink" => "Four Pines")["drink"].must_equal "Little Creatures" }
|
30
|
-
# original hash doesn't get changed.
|
31
|
-
it do
|
32
|
-
Create.({}, hash = { "drink" => "Four Pines" })
|
33
|
-
hash.must_equal( { "drink" => "Four Pines" })
|
34
|
-
end
|
35
|
-
|
36
|
-
|
37
|
-
# Operation::[]
|
38
|
-
# Operation::[]=
|
39
|
-
class Update < Trailblazer::Operation
|
40
|
-
success :call
|
41
|
-
|
42
|
-
self["drink"] = "Beer"
|
43
|
-
|
44
|
-
def call(*)
|
45
|
-
self["drink"]
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
it { Update["drink"].must_equal "Beer" }
|
50
|
-
|
51
|
-
# class-level are available on instance-level via Op#[]
|
52
|
-
it { Update.()["drink"].must_equal "Beer" }
|
53
|
-
|
54
|
-
# runtime constructor options can override class-level.
|
55
|
-
it { Update.({}, "drink" => "Little Creatures")["drink"].must_equal "Little Creatures" }
|
56
|
-
|
57
|
-
# instance can override class-level
|
58
|
-
class Delete < Trailblazer::Operation
|
59
|
-
success :call
|
60
|
-
|
61
|
-
self["drink"] = "Beer"
|
62
|
-
|
63
|
-
def call(*)
|
64
|
-
self["drink"] = "Little Creatures"
|
65
|
-
self["drink"]
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
# Op#[]= can override class-level...
|
70
|
-
it { Delete.()["drink"].must_equal "Little Creatures" }
|
71
|
-
# ...but it doesn't change class-level.
|
72
|
-
it { Delete["drink"].must_equal "Beer" }
|
73
|
-
|
74
|
-
# we don't really need this test.
|
75
|
-
class Reward < Trailblazer::Operation
|
76
|
-
self["drink"] = "Beer"
|
77
|
-
end
|
78
|
-
|
79
|
-
it { Reward.()["drink"].must_equal "Beer" }
|
80
|
-
end
|
81
|
-
|
82
|
-
# {
|
83
|
-
# user_repository: ..,
|
84
|
-
# current_user: ..,
|
85
|
-
# }
|
86
|
-
|
87
|
-
|
88
|
-
# 1. initialize(params, {})
|
89
|
-
# 2. extend AutoInject[] shouldn't override constructor but simply pass injected dependencies in second arg (by adding dependencies to hash).
|
data/test/pipetree_test.rb
DELETED
@@ -1,185 +0,0 @@
|
|
1
|
-
require "test_helper"
|
2
|
-
|
3
|
-
class PipetreeTest < Minitest::Spec
|
4
|
-
def self.Validate
|
5
|
-
step = ->{ snippet }
|
6
|
-
|
7
|
-
[ step, name: "validate", before: "operation.new" ]
|
8
|
-
end
|
9
|
-
|
10
|
-
# without options
|
11
|
-
class Create < Trailblazer::Operation
|
12
|
-
step PipetreeTest::Validate()
|
13
|
-
step PipetreeTest::Validate(), name: "VALIDATE!"
|
14
|
-
end
|
15
|
-
|
16
|
-
it { Create["pipetree"].inspect.must_equal %{[>validate,>VALIDATE!,>operation.new]} }
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
# with options
|
21
|
-
class Update < Trailblazer::Operation
|
22
|
-
step PipetreeTest::Validate(), after: "operation.new"
|
23
|
-
end
|
24
|
-
|
25
|
-
it { Update["pipetree"].inspect.must_equal %{[>operation.new,>validate]} }
|
26
|
-
|
27
|
-
#---
|
28
|
-
# ::step
|
29
|
-
|
30
|
-
#-
|
31
|
-
#- with :symbol
|
32
|
-
class Delete < Trailblazer::Operation
|
33
|
-
step :call!
|
34
|
-
|
35
|
-
def call!(options)
|
36
|
-
self["x"] = options["params"]
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
it { Delete.("yo")["x"].must_equal "yo" }
|
41
|
-
|
42
|
-
#- inheritance
|
43
|
-
class Remove < Delete
|
44
|
-
end
|
45
|
-
|
46
|
-
it { Remove.("yo")["x"].must_equal "yo" }
|
47
|
-
|
48
|
-
# proc arguments
|
49
|
-
class Forward < Trailblazer::Operation
|
50
|
-
step ->(input, options) { puts "@@@@@ #{input.inspect}"; puts "@@@@@ #{options.inspect}" }
|
51
|
-
end
|
52
|
-
|
53
|
-
it { skip; Forward.({ id: 1 }) }
|
54
|
-
|
55
|
-
#---
|
56
|
-
# ::>, ::<, ::>>, :&
|
57
|
-
# with proc, method, callable.
|
58
|
-
class Right < Trailblazer::Operation
|
59
|
-
MyProc = ->(*) { }
|
60
|
-
success ->(options) { options[">"] = options["params"][:id] }, better_api: true
|
61
|
-
|
62
|
-
success :method_name!
|
63
|
-
def method_name!(options); self["method_name!"] = options["params"][:id] end
|
64
|
-
|
65
|
-
class MyCallable
|
66
|
-
include Uber::Callable
|
67
|
-
def call(options); options["callable"] = options["params"][:id] end
|
68
|
-
end
|
69
|
-
success MyCallable.new
|
70
|
-
end
|
71
|
-
|
72
|
-
it { Right.( id: 1 ).slice(">", "method_name!", "callable").must_equal [1, 1, 1] }
|
73
|
-
it { Right["pipetree"].inspect.must_equal %{[>operation.new,>pipetree_test.rb:60,>method_name!,>PipetreeTest::Right::MyCallable]} }
|
74
|
-
|
75
|
-
#---
|
76
|
-
# inheritance
|
77
|
-
class Righter < Right
|
78
|
-
success ->(options) { options["righter"] = true }
|
79
|
-
end
|
80
|
-
|
81
|
-
it { Righter.( id: 1 ).slice(">", "method_name!", "callable", "righter").must_equal [1, 1, 1, true] }
|
82
|
-
end
|
83
|
-
|
84
|
-
|
85
|
-
class FailPassFastOptionTest < Minitest::Spec
|
86
|
-
# #failure fails fast.
|
87
|
-
class Create < Trailblazer::Operation
|
88
|
-
step ->(options, *) { options["x"] = options["dont_fail"] }
|
89
|
-
failure ->(options, *) { options["a"] = true; options["fail_fast"] }, fail_fast: true
|
90
|
-
failure ->(options, *) { options["b"] = true }
|
91
|
-
step ->(options, *) { options["y"] = true }
|
92
|
-
end
|
93
|
-
|
94
|
-
it { Create.({}, "fail_fast" => true, "dont_fail" => true ).inspect("x", "a", "b", "y").must_equal %{<Result:true [true, nil, nil, true] >} }
|
95
|
-
it { Create.({}, "fail_fast" => true ).inspect("x", "a", "b", "y").must_equal %{<Result:false [nil, true, nil, nil] >} }
|
96
|
-
it { Create.({}, "fail_fast" => false ).inspect("x", "a", "b", "y").must_equal %{<Result:false [nil, true, nil, nil] >} }
|
97
|
-
|
98
|
-
# #success passes fast.
|
99
|
-
class Retrieve < Trailblazer::Operation
|
100
|
-
success ->(options, *) { options["x"] = options["dont_fail"] }, pass_fast: true
|
101
|
-
failure ->(options, *) { options["b"] = true }
|
102
|
-
step ->(options, *) { options["y"] = true }
|
103
|
-
end
|
104
|
-
|
105
|
-
it { Retrieve.({}, "dont_fail" => true ).inspect("x", "b", "y").must_equal %{<Result:true [true, nil, nil] >} }
|
106
|
-
it { Retrieve.({}, "dont_fail" => false ).inspect("x", "b", "y").must_equal %{<Result:true [false, nil, nil] >} }
|
107
|
-
|
108
|
-
# #step fails fast if option set and returns false.
|
109
|
-
class Update < Trailblazer::Operation
|
110
|
-
step ->(options, *) { options["x"] = true }
|
111
|
-
step ->(options, *) { options["a"] = options["dont_fail"] }, fail_fast: true # only on false.
|
112
|
-
failure ->(options, *) { options["b"] = true }
|
113
|
-
step ->(options, *) { options["y"] = true }
|
114
|
-
end
|
115
|
-
|
116
|
-
it { Update.({}, "dont_fail" => true).inspect("x", "a", "b", "y").must_equal %{<Result:true [true, true, nil, true] >} }
|
117
|
-
it { Update.({} ).inspect("x", "a", "b", "y").must_equal %{<Result:false [true, nil, nil, nil] >} }
|
118
|
-
|
119
|
-
# #step passes fast if option set and returns true.
|
120
|
-
class Delete < Trailblazer::Operation
|
121
|
-
step ->(options, *) { options["x"] = true }
|
122
|
-
step ->(options, *) { options["a"] = options["dont_fail"] }, pass_fast: true # only on true.
|
123
|
-
failure ->(options, *) { options["b"] = true }
|
124
|
-
step ->(options, *) { options["y"] = true }
|
125
|
-
end
|
126
|
-
|
127
|
-
it { Delete.({}, "dont_fail" => true).inspect("x", "a", "b", "y").must_equal %{<Result:true [true, true, nil, nil] >} }
|
128
|
-
it { Delete.({} ).inspect("x", "a", "b", "y").must_equal %{<Result:false [true, nil, true, nil] >} }
|
129
|
-
end
|
130
|
-
|
131
|
-
class FailBangTest < Minitest::Spec
|
132
|
-
class Create < Trailblazer::Operation
|
133
|
-
step ->(options, *) { options["x"] = true; Railway.fail! }
|
134
|
-
step ->(options, *) { options["y"] = true }
|
135
|
-
failure ->(options, *) { options["a"] = true }
|
136
|
-
end
|
137
|
-
|
138
|
-
it { Create.().inspect("x", "y", "a").must_equal %{<Result:false [true, nil, true] >} }
|
139
|
-
end
|
140
|
-
|
141
|
-
class PassBangTest < Minitest::Spec
|
142
|
-
class Create < Trailblazer::Operation
|
143
|
-
step ->(options, *) { options["x"] = true; Railway.pass! }
|
144
|
-
step ->(options, *) { options["y"] = true }
|
145
|
-
failure ->(options, *) { options["a"] = true }
|
146
|
-
end
|
147
|
-
|
148
|
-
it { Create.().inspect("x", "y", "a").must_equal %{<Result:true [true, true, nil] >} }
|
149
|
-
end
|
150
|
-
|
151
|
-
class FailFastBangTest < Minitest::Spec
|
152
|
-
class Create < Trailblazer::Operation
|
153
|
-
step ->(options, *) { options["x"] = true; Railway.fail_fast! }
|
154
|
-
step ->(options, *) { options["y"] = true }
|
155
|
-
failure ->(options, *) { options["a"] = true }
|
156
|
-
end
|
157
|
-
|
158
|
-
it { Create.().inspect("x", "y", "a").must_equal %{<Result:false [true, nil, nil] >} }
|
159
|
-
end
|
160
|
-
|
161
|
-
class PassFastBangTest < Minitest::Spec
|
162
|
-
class Create < Trailblazer::Operation
|
163
|
-
step ->(options, *) { options["x"] = true; Railway.pass_fast! }
|
164
|
-
step ->(options, *) { options["y"] = true }
|
165
|
-
failure ->(options, *) { options["a"] = true }
|
166
|
-
end
|
167
|
-
|
168
|
-
it { Create.().inspect("x", "y", "a").must_equal %{<Result:true [true, nil, nil] >} }
|
169
|
-
end
|
170
|
-
|
171
|
-
|
172
|
-
class OverrideTest < Minitest::Spec
|
173
|
-
class Create < Trailblazer::Operation
|
174
|
-
step :a
|
175
|
-
step :b
|
176
|
-
end
|
177
|
-
|
178
|
-
class Update < Create
|
179
|
-
step :a, override: true
|
180
|
-
end
|
181
|
-
|
182
|
-
# FIXME: also test Macro
|
183
|
-
it { Create["pipetree"].inspect.must_equal %{[>operation.new,>a,>b]} }
|
184
|
-
it { Update["pipetree"].inspect.must_equal %{[>operation.new,>a,>b]} }
|
185
|
-
end
|