trailblazer-operation 0.6.6 → 0.7.4
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 +17 -0
- data/CHANGES.md +22 -0
- data/Gemfile +2 -1
- data/Rakefile +1 -12
- data/lib/trailblazer/operation.rb +1 -1
- data/lib/trailblazer/operation/class_dependencies.rb +4 -4
- data/lib/trailblazer/operation/public_call.rb +40 -10
- data/lib/trailblazer/operation/trace.rb +5 -0
- data/lib/trailblazer/operation/version.rb +1 -1
- data/test/docs/macaroni_test.rb +27 -27
- data/test/docs/operation_test.rb +6 -1
- data/test/operation_test.rb +55 -10
- data/test/step_test.rb +21 -8
- data/test/trace_test.rb +24 -0
- data/trailblazer-operation.gemspec +3 -3
- metadata +18 -16
- data/.travis.yml +0 -13
- data/test/ruby-2.0.0/operation_test.rb +0 -61
- data/test/ruby-2.0.0/step_test.rb +0 -137
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3c9a1ed221f6890d00d284c9a183e5082c1611cbcfc1cf9b37ec07dc09653258
|
4
|
+
data.tar.gz: 186a35a1414ee1d97f76d4950732272e1e171b6a89fa265a07e529686b35b27a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f914f13cd0f1126c386026b62605a99c32126d7add2b917e685a14d76344b0ab9882d4727f3d6ec42550910b8b4507fac1b0b491315d067c6b5caddba4f06df6
|
7
|
+
data.tar.gz: 3b70bd25571a44f791a6d693d94c67156310741642769c84948310a291be905048fd7ce099a4769f648e9fa6c98276afbe82941291e40fbea5a663676e3d6831
|
@@ -0,0 +1,17 @@
|
|
1
|
+
name: CI
|
2
|
+
on: [push, pull_request]
|
3
|
+
jobs:
|
4
|
+
test:
|
5
|
+
strategy:
|
6
|
+
fail-fast: false
|
7
|
+
matrix:
|
8
|
+
# Due to https://github.com/actions/runner/issues/849, we have to use quotes for '3.0'
|
9
|
+
ruby: [2.5, 2.6, 2.7, '3.0', head, jruby, jruby-head]
|
10
|
+
runs-on: ubuntu-latest
|
11
|
+
steps:
|
12
|
+
- uses: actions/checkout@v2
|
13
|
+
- uses: ruby/setup-ruby@v1
|
14
|
+
with:
|
15
|
+
ruby-version: ${{ matrix.ruby }}
|
16
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
17
|
+
- run: bundle exec rake
|
data/CHANGES.md
CHANGED
@@ -1,3 +1,25 @@
|
|
1
|
+
## 0.7.4
|
2
|
+
|
3
|
+
* Fix `Operation.call` being called twice before delegating to `call_with_circuit_interface`. This is done via a special `call_task` in the operation's taskWrap.
|
4
|
+
|
5
|
+
## 0.7.3
|
6
|
+
|
7
|
+
* Revert trailblazer-developer to a runtime dependency.
|
8
|
+
|
9
|
+
## 0.7.2
|
10
|
+
|
11
|
+
* Bugfix: when calling `Operation.call(params: {}, "current_user" => user)` the stringified variables got lost in Ruby < 3.
|
12
|
+
|
13
|
+
## 0.7.1
|
14
|
+
|
15
|
+
* In `Operation.call_with_public_interface`, pass `self` and not `@activity` to the `invoke`r. This fixes tracing as it now catches the actual Operation class, not an activity instance.
|
16
|
+
|
17
|
+
## 0.7.0
|
18
|
+
|
19
|
+
* Compatible with Ruby 2.4-3.0.
|
20
|
+
* Add `Operation.wtf?`.
|
21
|
+
* Add `Operation.call_with_flow_options` to allow using explicit aliasing in Ruby < 3.0.
|
22
|
+
|
1
23
|
## 0.6.6
|
2
24
|
|
3
25
|
* Rename `Operation.flow_options` to `Operation.flow_options_for_public_call`.
|
data/Gemfile
CHANGED
@@ -10,8 +10,9 @@ gem "dry-auto_inject"
|
|
10
10
|
gem "benchmark-ips"
|
11
11
|
gem "minitest-line"
|
12
12
|
|
13
|
-
# gem "trailblazer-developer", path: "../developer"
|
13
|
+
# gem "trailblazer-developer", path: "../trailblazer-developer"
|
14
14
|
# gem "trailblazer-developer", git: "https://github.com/trailblazer/trailblazer-developer"
|
15
15
|
# gem "trailblazer-activity", path: "../trailblazer-activity"
|
16
|
+
# gem "trailblazer-context", path: "../trailblazer-context"
|
16
17
|
# gem "trailblazer-activity-dsl-linear", path: "../trailblazer-activity-dsl-linear"
|
17
18
|
# gem "trailblazer-activity", github: "trailblazer/trailblazer-activity"
|
data/Rakefile
CHANGED
@@ -4,18 +4,7 @@ require "rake/testtask"
|
|
4
4
|
Rake::TestTask.new(:test) do |test|
|
5
5
|
test.libs << "test"
|
6
6
|
test.verbose = true
|
7
|
-
|
8
|
-
test_files = FileList["test/**/*_test.rb"]
|
9
|
-
|
10
|
-
if RUBY_VERSION == "2.0.0"
|
11
|
-
# test_files = test_files - %w{test/dry_container_test.rb test/2.1.0-pipetree_test.rb}
|
12
|
-
test_files = test_files - %w{test/step_test.rb} + %w{test/ruby-2.0.0/step_test.rb}
|
13
|
-
test_files = test_files - %w{test/operation_test.rb} + %w{test/ruby-2.0.0/operation_test.rb}
|
14
|
-
else
|
15
|
-
test_files -= FileList["test/ruby-2.0.0/*"]
|
16
|
-
end
|
17
|
-
|
18
|
-
test.test_files = test_files
|
7
|
+
test.test_files = FileList["test/**/*_test.rb"]
|
19
8
|
end
|
20
9
|
|
21
10
|
task :default => %i[test]
|
@@ -47,7 +47,7 @@ module Trailblazer
|
|
47
47
|
end
|
48
48
|
|
49
49
|
require "trailblazer/operation/public_call" # TODO: Remove in 3.0.
|
50
|
-
extend PublicCall # ::call(params
|
50
|
+
extend PublicCall # ::call(params: .., current_user: ..)
|
51
51
|
|
52
52
|
require "trailblazer/operation/trace"
|
53
53
|
extend Trace # ::trace
|
@@ -12,9 +12,9 @@ class Trailblazer::Operation
|
|
12
12
|
@state.update_options(options)
|
13
13
|
end
|
14
14
|
|
15
|
-
def options_for_public_call(options,
|
15
|
+
def options_for_public_call(options, flow_options)
|
16
16
|
ctx = super
|
17
|
-
context_for_fields(class_fields, [ctx, flow_options]
|
17
|
+
context_for_fields(class_fields, [ctx, flow_options])
|
18
18
|
end
|
19
19
|
|
20
20
|
private def class_fields
|
@@ -26,9 +26,9 @@ class Trailblazer::Operation
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def call_with_circuit_interface((ctx, flow_options), **circuit_options)
|
29
|
-
ctx_with_fields = context_for_fields(class_fields, [ctx, flow_options], circuit_options)
|
29
|
+
ctx_with_fields = context_for_fields(class_fields, [ctx, flow_options], **circuit_options)
|
30
30
|
|
31
|
-
super([ctx_with_fields, flow_options], circuit_options) # FIXME: should we unwrap here?
|
31
|
+
super([ctx_with_fields, flow_options], **circuit_options) # FIXME: should we unwrap here?
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
@@ -13,10 +13,10 @@ module Trailblazer
|
|
13
13
|
#
|
14
14
|
# @note Do not override this method as it will be removed in future versions. Also, you will break tracing.
|
15
15
|
# @return Operation::Railway::Result binary result object
|
16
|
-
def call(options = {},
|
17
|
-
return call_with_circuit_interface(options,
|
16
|
+
def call(options = {}, flow_options = {}, **circuit_options)
|
17
|
+
return call_with_circuit_interface(options, **circuit_options) if options.is_a?(Array) # This is kind of a hack that could be well hidden if Ruby had method overloading. Goal is to simplify the call thing as we're fading out Operation::public_call anyway.
|
18
18
|
|
19
|
-
call_with_public_interface(options,
|
19
|
+
call_with_public_interface(options, flow_options, **circuit_options)
|
20
20
|
end
|
21
21
|
|
22
22
|
# Default {@activity} call interface which doesn't accept {circuit_options}
|
@@ -26,17 +26,22 @@ module Trailblazer
|
|
26
26
|
# @return [Operation::Railway::Result]
|
27
27
|
#
|
28
28
|
# @private
|
29
|
-
def call_with_public_interface(options, flow_options
|
29
|
+
def call_with_public_interface(options, flow_options, invoke_class: Activity::TaskWrap, **circuit_options)
|
30
30
|
flow_options = flow_options_for_public_call(flow_options)
|
31
|
+
|
32
|
+
# In Ruby < 3, calling Op.(params: {}, "current_user" => user) results in both {circuit_options} and {options} containing variables.
|
33
|
+
# In Ruby 3.0, **circuit_options is always empty.
|
34
|
+
options = circuit_options.any? ? circuit_options.merge(options) : options
|
35
|
+
|
31
36
|
ctx = options_for_public_call(options, flow_options)
|
32
37
|
|
33
38
|
# call the activity.
|
34
39
|
# This will result in invoking {::call_with_circuit_interface}.
|
35
|
-
|
36
|
-
|
37
|
-
@activity,
|
40
|
+
signal, (ctx, flow_options) = invoke_class.invoke(
|
41
|
+
self,
|
38
42
|
[ctx, flow_options],
|
39
|
-
exec_context: new
|
43
|
+
exec_context: new,
|
44
|
+
wrap_static: initial_wrap_static,
|
40
45
|
)
|
41
46
|
|
42
47
|
# Result is successful if the activity ended with an End event derived from Railway::End::Success.
|
@@ -51,8 +56,8 @@ module Trailblazer
|
|
51
56
|
# @return [signal, [ctx, flow_options]]
|
52
57
|
#
|
53
58
|
# @private
|
54
|
-
def call_with_circuit_interface(args, circuit_options)
|
55
|
-
strategy_call(args, circuit_options) # FastTrack#call
|
59
|
+
def call_with_circuit_interface(args, **circuit_options)
|
60
|
+
strategy_call(args, **circuit_options) # FastTrack#call
|
56
61
|
end
|
57
62
|
|
58
63
|
def options_for_public_call(*args)
|
@@ -69,5 +74,30 @@ module Trailblazer
|
|
69
74
|
def flow_options_for_public_call(options = {})
|
70
75
|
options
|
71
76
|
end
|
77
|
+
|
78
|
+
# TODO: remove when we stop supporting < 3.0.
|
79
|
+
def call_with_flow_options(options, flow_options)
|
80
|
+
raise "[Trailblazer] `Operation.call_with_flow_options is deprecated in Ruby 3.0. Use `Operation.(options, flow_options)`" if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3.0.0")
|
81
|
+
call_with_public_interface(options, flow_options, {invoke_class: Activity::TaskWrap})
|
82
|
+
end
|
83
|
+
|
84
|
+
def initial_wrap_static(*)
|
85
|
+
Activity::TaskWrap::Pipeline.new([["task_wrap.call_task", method(:call_task)]])
|
86
|
+
end
|
87
|
+
|
88
|
+
def call_task(wrap_ctx, original_args) # DISCUSS: copied from {TaskWrap.call_task}.
|
89
|
+
op = wrap_ctx[:task]
|
90
|
+
|
91
|
+
original_arguments, original_circuit_options = original_args
|
92
|
+
|
93
|
+
# Call the actual task we're wrapping here.
|
94
|
+
# puts "~~~~wrap.call: #{task}"
|
95
|
+
return_signal, return_args = op.call_with_circuit_interface(original_arguments, **original_circuit_options)
|
96
|
+
|
97
|
+
# DISCUSS: do we want original_args here to be passed on, or the "effective" return_args which are different to original_args now?
|
98
|
+
wrap_ctx = wrap_ctx.merge(return_signal: return_signal, return_args: return_args)
|
99
|
+
|
100
|
+
return wrap_ctx, original_args
|
101
|
+
end
|
72
102
|
end
|
73
103
|
end
|
@@ -6,6 +6,7 @@ module Trailblazer
|
|
6
6
|
module Trace
|
7
7
|
# @note The problem in this method is, we have redundancy with Operation::PublicCall
|
8
8
|
def self.call(operation, options)
|
9
|
+
# warn %{Trailblazer: `Operation.trace` is deprecated. Please use `Operation.wtf?`.} # DISCUSS: should this be deprecated?
|
9
10
|
ctx = PublicCall.options_for_public_call(options) # redundant with PublicCall::call.
|
10
11
|
|
11
12
|
stack, signal, (ctx, _flow_options) = Developer::Trace.(operation, [ctx, {}])
|
@@ -25,6 +26,10 @@ module Trailblazer
|
|
25
26
|
Trace.(self, options)
|
26
27
|
end
|
27
28
|
|
29
|
+
def wtf?(options)
|
30
|
+
call_with_public_interface(options, {}, invoke_class: Developer::Wtf)
|
31
|
+
end
|
32
|
+
|
28
33
|
# Presentation of the traced stack via the returned result object.
|
29
34
|
# This object is wrapped around the original result in {Trace.call}.
|
30
35
|
class Result < ::SimpleDelegator
|
data/test/docs/macaroni_test.rb
CHANGED
@@ -1,31 +1,31 @@
|
|
1
|
-
require "test_helper"
|
1
|
+
# require "test_helper"
|
2
2
|
|
3
|
-
class MacaroniTaskBuilderTest < Minitest::Spec
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
3
|
+
# class MacaroniTaskBuilderTest < Minitest::Spec
|
4
|
+
# Memo = Struct.new(:title) do
|
5
|
+
# def save
|
6
|
+
# self.title = title[:title].reverse
|
7
|
+
# end
|
8
|
+
# end
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
10
|
+
# #:create
|
11
|
+
# class Memo::Create < Trailblazer::Operation(step_interface_builder: Trailblazer::Operation::Railway::KwSignature)
|
12
|
+
# #~ign
|
13
|
+
# step :create_model
|
14
|
+
# step :save
|
15
|
+
# #~ign end
|
16
|
+
# #~methods
|
17
|
+
# def create_model(params:, options:, **)
|
18
|
+
# options[:model] = Memo.new(title: params[:title])
|
19
|
+
# end
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
21
|
+
# def save(model:, **)
|
22
|
+
# model.save
|
23
|
+
# end
|
24
|
+
# #~methods end
|
25
|
+
# end
|
26
|
+
# #:create end
|
27
27
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
end
|
28
|
+
# it "allows optional macaroni call style" do
|
29
|
+
# Memo::Create.(params: {title: "Wow!"}).inspect(:model).must_equal %{<Result:true [#<struct MacaroniTaskBuilderTest::Memo title=\"!woW\">] >}
|
30
|
+
# end
|
31
|
+
# end
|
data/test/docs/operation_test.rb
CHANGED
@@ -85,7 +85,12 @@ class DocsActivityTest < Minitest::Spec
|
|
85
85
|
}
|
86
86
|
}
|
87
87
|
|
88
|
-
|
88
|
+
# Sorry, this feature is only reliable in Ruby > 2.7
|
89
|
+
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3.0.0")
|
90
|
+
result = AliasesExample::Memo::Create.(options, flow_options)
|
91
|
+
else # Ruby 2.6 etc
|
92
|
+
result = AliasesExample::Memo::Create.call_with_flow_options(options, flow_options)
|
93
|
+
end
|
89
94
|
|
90
95
|
result['contract.default'] # => Memo::Contract::Create
|
91
96
|
result[:contract] # => Memo::Contract::Create
|
data/test/operation_test.rb
CHANGED
@@ -1,6 +1,28 @@
|
|
1
1
|
require "test_helper"
|
2
2
|
|
3
3
|
class DeclarativeApiTest < Minitest::Spec
|
4
|
+
it "doesn't invoke {call} twice when using public interface" do
|
5
|
+
class MyOp < Trailblazer::Operation
|
6
|
+
@@GLOBAL = []
|
7
|
+
def self.global; @@GLOBAL; end
|
8
|
+
|
9
|
+
|
10
|
+
def self.call(*args)
|
11
|
+
@@GLOBAL << :call
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
pass :model
|
16
|
+
|
17
|
+
def model(ctx, **)
|
18
|
+
@@GLOBAL << :model
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
MyOp.({})
|
23
|
+
MyOp.global.inspect.must_equal %{[:call, :model]}
|
24
|
+
end
|
25
|
+
|
4
26
|
#---
|
5
27
|
#- step, pass, fail
|
6
28
|
|
@@ -95,6 +117,17 @@ class DeclarativeApiTest < Minitest::Spec
|
|
95
117
|
Unset. ("params" => {decide: true}).inspect("a", "b", "c", "d", "e").must_equal %{<Result:true [false, true, nil, 1, 2] >}
|
96
118
|
end
|
97
119
|
|
120
|
+
# Mixing keywords and string keys in {Operation.call}.
|
121
|
+
# Test that {.(params: {}, "current_user" => user)} is processed properly
|
122
|
+
class Collect < Trailblazer::Operation
|
123
|
+
# step ->(ctx, **) { ctx[:keys] }
|
124
|
+
end
|
125
|
+
|
126
|
+
it "contains all keys from {call}" do
|
127
|
+
result = Collect.(params: {}, "current_user" => Module)
|
128
|
+
_(result.inspect).must_equal %{<Result:true #<Trailblazer::Context::Container wrapped_options={:params=>{}, \"current_user\"=>Module} mutable_options={}> >}
|
129
|
+
end
|
130
|
+
|
98
131
|
#---
|
99
132
|
#- ctx container
|
100
133
|
it do
|
@@ -105,23 +138,35 @@ class DeclarativeApiTest < Minitest::Spec
|
|
105
138
|
result.inspect("a", "b", "c").must_equal %{<Result:true [false, true, nil] >}
|
106
139
|
|
107
140
|
# Circuit interface call
|
108
|
-
signal, (ctx, _) = Update.([Update.options_for_public_call(options), {}], {})
|
141
|
+
signal, (ctx, _) = Update.([Update.options_for_public_call(options), {}], **{})
|
109
142
|
|
110
143
|
signal.inspect.must_equal %{#<Trailblazer::Activity::Railway::End::Success semantic=:success>}
|
111
144
|
ctx.inspect.must_equal %{#<Trailblazer::Context::Container wrapped_options={\"params\"=>{:decide=>true}} mutable_options={\"a\"=>false, \"b\"=>true}>}
|
112
145
|
|
113
146
|
# Call by passing aliases as an argument.
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
147
|
+
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3.0.0")
|
148
|
+
result = Update.(
|
149
|
+
options,
|
150
|
+
{
|
151
|
+
context_options: {
|
152
|
+
aliases: { 'b' => :settle },
|
153
|
+
container_class: Trailblazer::Context::Container::WithAliases,
|
154
|
+
}
|
120
155
|
}
|
121
|
-
|
122
|
-
|
123
|
-
|
156
|
+
)
|
157
|
+
else
|
158
|
+
result = Update.call_with_flow_options(
|
159
|
+
options,
|
160
|
+
{
|
161
|
+
context_options: {
|
162
|
+
aliases: { 'b' => :settle },
|
163
|
+
container_class: Trailblazer::Context::Container::WithAliases,
|
164
|
+
}
|
165
|
+
},
|
166
|
+
)
|
167
|
+
end
|
124
168
|
|
169
|
+
result[:settle].must_equal true
|
125
170
|
# Set aliases by overriding `flow_options` at the compile time.
|
126
171
|
result = Aliases.(options)
|
127
172
|
result[:settle].must_equal true
|
data/test/step_test.rb
CHANGED
@@ -40,7 +40,11 @@ class StepTest < Minitest::Spec
|
|
40
40
|
|
41
41
|
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] >" }
|
42
42
|
|
43
|
-
|
43
|
+
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.7.0")
|
44
|
+
it { Trailblazer::Developer.railway(Create).gsub(/0x.+?step_test.rb/, "").gsub(/\)\s.+?step_test.rb/, ") test/step_test.rb").must_equal %{[>#<Proc::30 (lambda)>,>StepTest::Callable,>#<Method: StepTest::Implementation.c(options, c: ..., **) test/step_test.rb:18>,>d,>MyMacro]} }
|
45
|
+
else
|
46
|
+
it { Trailblazer::Developer.railway(Create).gsub(/0x.+?step_test.rb/, "").must_equal %{[>#<Proc::30 (lambda)>,>StepTest::Callable,>#<Method: StepTest::Implementation.c>,>d,>MyMacro]} }
|
47
|
+
end
|
44
48
|
|
45
49
|
#---
|
46
50
|
#- :before, :after, :replace, :delete, :override
|
@@ -174,11 +178,20 @@ class StepTest < Minitest::Spec
|
|
174
178
|
# not existent :name
|
175
179
|
it do
|
176
180
|
op = assert_raises Trailblazer::Activity::DSL::Linear::Sequence::IndexError do
|
177
|
-
|
181
|
+
class InvalidStep < Trailblazer::Operation
|
178
182
|
step :a, before: "I don't exist!"
|
179
183
|
end
|
180
184
|
end
|
181
|
-
|
185
|
+
|
186
|
+
error_message = %{#<Trailblazer::Activity::DSL::Linear::Sequence::IndexError: StepTest::InvalidStep:
|
187
|
+
\e[31m\"I don't exist!\" is not a valid step ID. Did you mean any of these ?\e[0m
|
188
|
+
\e[32m\"Start.default\"
|
189
|
+
\"End.success\"
|
190
|
+
\"End.pass_fast\"
|
191
|
+
\"End.fail_fast\"
|
192
|
+
\"End.failure\"\e[0m>}
|
193
|
+
|
194
|
+
assert_match error_message, op.inspect
|
182
195
|
end
|
183
196
|
|
184
197
|
#---
|
@@ -195,16 +208,16 @@ class StepTest < Minitest::Spec
|
|
195
208
|
|
196
209
|
#---
|
197
210
|
#- inheritance
|
198
|
-
class New <
|
211
|
+
class New < Index
|
199
212
|
end
|
200
213
|
|
201
|
-
it { Trailblazer::Developer.railway(New).
|
214
|
+
it { Trailblazer::Developer.railway(New).must_equal %{[>my validate,>persist!,>I win!,>No, I do!]} }
|
202
215
|
|
203
|
-
class Update <
|
204
|
-
step :after_save
|
216
|
+
class Update < Index
|
217
|
+
step :after_save
|
205
218
|
end
|
206
219
|
|
207
|
-
it { Trailblazer::Developer.railway(Update).
|
220
|
+
it { Trailblazer::Developer.railway(Update).must_equal %{[>my validate,>persist!,>I win!,>No, I do!,>after_save]} }
|
208
221
|
end
|
209
222
|
|
210
223
|
#---
|
data/test/trace_test.rb
CHANGED
@@ -49,4 +49,28 @@ class TraceTest < Minitest::Spec
|
|
49
49
|
|-- Create.task.params
|
50
50
|
`-- End.success}
|
51
51
|
end
|
52
|
+
|
53
|
+
it "Operation.wtf?" do
|
54
|
+
result = nil
|
55
|
+
output, = capture_io do
|
56
|
+
result = Create.wtf?(params: {x: 1}, a_return: true)
|
57
|
+
end
|
58
|
+
|
59
|
+
output.gsub(/0x\w+/, "").gsub(/@.+_test/, "").must_equal %{`-- TraceTest::Create
|
60
|
+
|-- \e[32mStart.default\e[0m
|
61
|
+
|-- \e[32mCreate.task.a\e[0m
|
62
|
+
|-- MyNested
|
63
|
+
| |-- \e[32mStart.default\e[0m
|
64
|
+
| |-- \e[32mB.task.b\e[0m
|
65
|
+
| |-- \e[32mB.task.e\e[0m
|
66
|
+
| `-- End.success
|
67
|
+
|-- \e[32mCreate.task.c\e[0m
|
68
|
+
|-- \e[32mCreate.task.params\e[0m
|
69
|
+
`-- End.success
|
70
|
+
}
|
71
|
+
|
72
|
+
result.success?.must_equal true
|
73
|
+
result[:a_return].must_equal true
|
74
|
+
result[:params].inspect.must_equal %{{:x=>1}}
|
75
|
+
end
|
52
76
|
end
|
@@ -17,9 +17,9 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.test_files = spec.files.grep(%r{^(test)/})
|
18
18
|
spec.require_paths = ["lib"]
|
19
19
|
|
20
|
-
spec.add_dependency "trailblazer-activity-dsl-linear", ">= 0.
|
21
|
-
spec.add_dependency "trailblazer-activity", ">= 0.
|
22
|
-
spec.add_dependency "trailblazer-developer", ">= 0.0.
|
20
|
+
spec.add_dependency "trailblazer-activity-dsl-linear", ">= 0.4.0", "< 1.0.0"
|
21
|
+
spec.add_dependency "trailblazer-activity", ">= 0.12.1", "< 1.0.0"
|
22
|
+
spec.add_dependency "trailblazer-developer", ">= 0.0.21", "< 1.0.0"
|
23
23
|
|
24
24
|
spec.add_development_dependency "bundler"
|
25
25
|
spec.add_development_dependency "minitest"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trailblazer-operation
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Sutterer
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-03-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: trailblazer-activity-dsl-linear
|
@@ -16,7 +16,7 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
19
|
+
version: 0.4.0
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
22
|
version: 1.0.0
|
@@ -26,7 +26,7 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: 0.
|
29
|
+
version: 0.4.0
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: 1.0.0
|
@@ -36,7 +36,7 @@ dependencies:
|
|
36
36
|
requirements:
|
37
37
|
- - ">="
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version: 0.
|
39
|
+
version: 0.12.1
|
40
40
|
- - "<"
|
41
41
|
- !ruby/object:Gem::Version
|
42
42
|
version: 1.0.0
|
@@ -46,7 +46,7 @@ dependencies:
|
|
46
46
|
requirements:
|
47
47
|
- - ">="
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version: 0.
|
49
|
+
version: 0.12.1
|
50
50
|
- - "<"
|
51
51
|
- !ruby/object:Gem::Version
|
52
52
|
version: 1.0.0
|
@@ -56,14 +56,20 @@ dependencies:
|
|
56
56
|
requirements:
|
57
57
|
- - ">="
|
58
58
|
- !ruby/object:Gem::Version
|
59
|
-
version: 0.0.
|
59
|
+
version: 0.0.21
|
60
|
+
- - "<"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 1.0.0
|
60
63
|
type: :runtime
|
61
64
|
prerelease: false
|
62
65
|
version_requirements: !ruby/object:Gem::Requirement
|
63
66
|
requirements:
|
64
67
|
- - ">="
|
65
68
|
- !ruby/object:Gem::Version
|
66
|
-
version: 0.0.
|
69
|
+
version: 0.0.21
|
70
|
+
- - "<"
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: 1.0.0
|
67
73
|
- !ruby/object:Gem::Dependency
|
68
74
|
name: bundler
|
69
75
|
requirement: !ruby/object:Gem::Requirement
|
@@ -127,10 +133,10 @@ executables: []
|
|
127
133
|
extensions: []
|
128
134
|
extra_rdoc_files: []
|
129
135
|
files:
|
136
|
+
- ".github/workflows/ci.yml"
|
130
137
|
- ".gitignore"
|
131
138
|
- ".rubocop.yml"
|
132
139
|
- ".rubocop_todo.yml"
|
133
|
-
- ".travis.yml"
|
134
140
|
- CHANGES.md
|
135
141
|
- Gemfile
|
136
142
|
- README.md
|
@@ -163,8 +169,6 @@ files:
|
|
163
169
|
- test/introspect_test.rb
|
164
170
|
- test/operation_test.rb
|
165
171
|
- test/result_test.rb
|
166
|
-
- test/ruby-2.0.0/operation_test.rb
|
167
|
-
- test/ruby-2.0.0/step_test.rb
|
168
172
|
- test/skill_test.rb
|
169
173
|
- test/step_test.rb
|
170
174
|
- test/test_helper.rb
|
@@ -177,7 +181,7 @@ homepage: http://trailblazer.to
|
|
177
181
|
licenses:
|
178
182
|
- MIT
|
179
183
|
metadata: {}
|
180
|
-
post_install_message:
|
184
|
+
post_install_message:
|
181
185
|
rdoc_options: []
|
182
186
|
require_paths:
|
183
187
|
- lib
|
@@ -193,7 +197,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
193
197
|
version: '0'
|
194
198
|
requirements: []
|
195
199
|
rubygems_version: 3.0.8
|
196
|
-
signing_key:
|
200
|
+
signing_key:
|
197
201
|
specification_version: 4
|
198
202
|
summary: Trailblazer's operation object with railway flow and integrated error handling.
|
199
203
|
test_files:
|
@@ -215,8 +219,6 @@ test_files:
|
|
215
219
|
- test/introspect_test.rb
|
216
220
|
- test/operation_test.rb
|
217
221
|
- test/result_test.rb
|
218
|
-
- test/ruby-2.0.0/operation_test.rb
|
219
|
-
- test/ruby-2.0.0/step_test.rb
|
220
222
|
- test/skill_test.rb
|
221
223
|
- test/step_test.rb
|
222
224
|
- test/test_helper.rb
|
data/.travis.yml
DELETED
@@ -1,61 +0,0 @@
|
|
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
|
-
|
31
|
-
def return_false!(options, **_o); options["c"] = false end
|
32
|
-
end
|
33
|
-
|
34
|
-
it { Create.({}, decide: true).inspect("a", "x", "y", "b", "c").must_equal %{<Result:true [true, true, false, nil, nil] >} }
|
35
|
-
it { Create.({}, decide: false).inspect("a", "x", "y", "b", "c").must_equal %{<Result:false [true, nil, nil, true, false] >} }
|
36
|
-
|
37
|
-
#---
|
38
|
-
#- trace
|
39
|
-
|
40
|
-
it do
|
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
|
@@ -1,137 +0,0 @@
|
|
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
|
-
|
18
|
-
def c(options, c: nil, **_o)
|
19
|
-
options["c"] = c
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
MyMacro = ->(direction, options, flow_options) do
|
24
|
-
options["e"] = options[:e]
|
25
|
-
|
26
|
-
[direction, options, flow_options]
|
27
|
-
end
|
28
|
-
|
29
|
-
class Create < Trailblazer::Operation
|
30
|
-
step ->(options, a: nil, **_o) { options["a"] = a }
|
31
|
-
step Callable
|
32
|
-
step Implementation.method(:c)
|
33
|
-
step :d
|
34
|
-
step [MyMacro, {}] # doesn't provide runner_options.
|
35
|
-
|
36
|
-
def d(options, d: nil, **_o)
|
37
|
-
options["d"] = d
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
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] >" }
|
42
|
-
|
43
|
-
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)>, {}]]} }
|
44
|
-
# poor test to make sure we pass debug information to Activity.
|
45
|
-
it { Create["__activity__"].graph.find_all(:d).first[:id].must_equal :d }
|
46
|
-
|
47
|
-
#---
|
48
|
-
#- :before, :after, :replace, :delete, :override
|
49
|
-
class A < Trailblazer::Operation
|
50
|
-
step :a!
|
51
|
-
def a!(options, **_o); options["a"] = 1; end
|
52
|
-
def a!(options, **_o); options["a"] = 1; end if RUBY_VERSION == "2.0.0"
|
53
|
-
end
|
54
|
-
|
55
|
-
class B < A
|
56
|
-
step :b!, before: :a!
|
57
|
-
step :c!, before: :a!
|
58
|
-
step :d!, after: :b!
|
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
|
-
end
|
67
|
-
|
68
|
-
it { Trailblazer::Operation::Inspect.(C).must_equal %{[>b!,>e!,>a!]} }
|
69
|
-
|
70
|
-
class D < Trailblazer::Operation
|
71
|
-
step :a!
|
72
|
-
step :b!
|
73
|
-
step :b!, override: true
|
74
|
-
end
|
75
|
-
|
76
|
-
it { Trailblazer::Operation::Inspect.(D).must_equal %{[>a!,>b!]} }
|
77
|
-
|
78
|
-
# not existent :name
|
79
|
-
it do
|
80
|
-
err = assert_raises Trailblazer::Operation::Railway::Sequence::IndexError do
|
81
|
-
class E < Trailblazer::Operation
|
82
|
-
step :a, before: "I don't exist!"
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
err.inspect.must_equal "#<Trailblazer::Operation::Railway::Sequence::IndexError: I don't exist!>"
|
87
|
-
end
|
88
|
-
|
89
|
-
#---
|
90
|
-
#- :name
|
91
|
-
#- step :whatever, name: :validate
|
92
|
-
class Index < Trailblazer::Operation
|
93
|
-
step :validate!, name: "my validate"
|
94
|
-
step :persist!
|
95
|
-
step [MyMacro, name: "I win!"]
|
96
|
-
step [MyMacro, name: "I win!"], name: "No, I do!"
|
97
|
-
end
|
98
|
-
|
99
|
-
it { Trailblazer::Operation::Inspect.(Index).must_equal %{[>my validate,>persist!,>I win!,>No, I do!]} }
|
100
|
-
|
101
|
-
#---
|
102
|
-
#- inheritance
|
103
|
-
class New < Create
|
104
|
-
end
|
105
|
-
|
106
|
-
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)>, {}]]} }
|
107
|
-
|
108
|
-
class Update < Create
|
109
|
-
step :after_save!
|
110
|
-
end
|
111
|
-
|
112
|
-
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!]} }
|
113
|
-
end
|
114
|
-
|
115
|
-
#---
|
116
|
-
#- Macros with the old `input` arg.
|
117
|
-
# step [ ->(input, options) { } ]
|
118
|
-
# TODO: remove me in 2.2.
|
119
|
-
class StepWithDeprecatedMacroTest < Minitest::Spec
|
120
|
-
class Create < Trailblazer::Operation
|
121
|
-
MyOutdatedMacro = ->(input, options) {
|
122
|
-
options["x"] = input.class
|
123
|
-
}
|
124
|
-
|
125
|
-
class AnotherOldMacro
|
126
|
-
def self.call(input, options)
|
127
|
-
options["y"] = input.class
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
step [MyOutdatedMacro, name: :outdated]
|
132
|
-
step [AnotherOldMacro, name: :oldie]
|
133
|
-
end
|
134
|
-
|
135
|
-
it { Trailblazer::Operation::Inspect.(Create).gsub(/0x.+?step_test.rb/, "").must_equal %{[>outdated,>oldie]} }
|
136
|
-
it { Create.().inspect("x", "y").must_equal %{<Result:true [StepWithDeprecatedMacroTest::Create, StepWithDeprecatedMacroTest::Create] >} }
|
137
|
-
end
|