trailblazer-operation 0.6.5 → 0.7.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2908ffe1d690d0bd75b1e936b1351a4139405ed43ea43ce560c5b44c6c782e73
4
- data.tar.gz: ee5ee4538ea0d59e266c7600f2ff2de20c79a9d66209063f1bdcb8530e296243
3
+ metadata.gz: b2bed59ccc4a6af470ef0413dfd4c5132c138a2ed68e1e7ed390ea7637c8db4e
4
+ data.tar.gz: '074982e69ce025d63cc256964b8c334ad6405f792357201778beea2694668f93'
5
5
  SHA512:
6
- metadata.gz: a15078c7427fe6927af8e9782dbd919f60115fa5b4fb7c5aed039c5b3e3cb0ef2737373c797f0937a689b10c50e5089850a1c95d6ba6085483cc6a26d07e718b
7
- data.tar.gz: 5e1a92c16c7ed05500dc28dfa1dccbc352a0d0d9efea28663cb93ff56a4b6e583474fa66062eb88b9fd6008dc84bd56008ebe2f83c8f73d76a688ddaf1fe7fb3
6
+ metadata.gz: 9b74fd06391e9035c5a82ff85b281e4b87445f18b0c238d5f939dfdb80e4541cd484743523a474371dfa2dd803068c6bb415732a40bea25dfa67fd777134dc3c
7
+ data.tar.gz: 79eb31f4211e4a6521c3c06f879df49bf32b57f5b020b0f3a4273efb8c12fc047812f9a75f0987034c78fc6952945d5e4e24d08ac820b6c31222657490d4ea68
@@ -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,26 @@
1
+ ## 0.7.3
2
+
3
+ * Revert trailblazer-developer to a runtime dependency.
4
+
5
+ ## 0.7.2
6
+
7
+ * Bugfix: when calling `Operation.call(params: {}, "current_user" => user)` the stringified variables got lost in Ruby < 3.
8
+
9
+ ## 0.7.1
10
+
11
+ * 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.
12
+
13
+ ## 0.7.0
14
+
15
+ * Compatible with Ruby 2.4-3.0.
16
+ * Add `Operation.wtf?`.
17
+ * Add `Operation.call_with_flow_options` to allow using explicit aliasing in Ruby < 3.0.
18
+
19
+ ## 0.6.6
20
+
21
+ * Rename `Operation.flow_options` to `Operation.flow_options_for_public_call`.
22
+ * Operations can also accept `flow_options` at run-time now :beers:, giving them precedence over `Operation.flow_options_for_public_call`.
23
+
1
24
  ## 0.6.5
2
25
 
3
26
  * Upgrade `trailblazer-activity` & `trailblazer-activity-dsl-linear` versions to utilise new `trailblazer-context` :drum:
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]
@@ -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, **flow_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,21 +13,33 @@ 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 = {}, *args)
17
- return call_with_circuit_interface(options, *args) 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/__call__ thing as we're fading out Operation::call anyway.
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/__call__ thing as we're fading out Operation::call anyway.
18
18
 
19
- call_with_public_interface(options, *args)
19
+ call_with_public_interface(options, flow_options, **circuit_options)
20
20
  end
21
21
 
22
- def call_with_public_interface(*args)
23
- ctx = options_for_public_call(*args, flow_options())
22
+ # Default {@activity} call interface which doesn't accept {circuit_options}
23
+ #
24
+ # @param [Array] args => [ctx, flow_options]
25
+ #
26
+ # @return [Operation::Railway::Result]
27
+ #
28
+ # @private
29
+ def call_with_public_interface(options, flow_options, invoke_class: Activity::TaskWrap, **circuit_options)
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
+
36
+ ctx = options_for_public_call(options, flow_options)
24
37
 
25
38
  # call the activity.
26
39
  # This will result in invoking {::call_with_circuit_interface}.
27
- # last_signal, (options, flow_options) = Activity::TaskWrap.invoke(self, [ctx, {}], {})
28
- signal, (ctx, flow_options) = Activity::TaskWrap.invoke(
29
- @activity,
30
- [ctx, flow_options()],
40
+ signal, (ctx, flow_options) = invoke_class.invoke(
41
+ self,
42
+ [ctx, flow_options],
31
43
  exec_context: new
32
44
  )
33
45
 
@@ -36,8 +48,15 @@ module Trailblazer
36
48
  end
37
49
 
38
50
  # This interface is used for all nested OPs (and the outer-most, too).
39
- def call_with_circuit_interface(args, circuit_options)
40
- strategy_call(args, circuit_options) # FastTrack#call
51
+ #
52
+ # @param [Array] args - Contains [ctx, flow_options]
53
+ # @param [Hash] circuit_options - Options to configure activity circuit
54
+ #
55
+ # @return [signal, [ctx, flow_options]]
56
+ #
57
+ # @private
58
+ def call_with_circuit_interface(args, **circuit_options)
59
+ strategy_call(args, **circuit_options) # FastTrack#call
41
60
  end
42
61
 
43
62
  def options_for_public_call(*args)
@@ -46,13 +65,19 @@ module Trailblazer
46
65
 
47
66
  # Compile a Context object to be passed into the Activity::call.
48
67
  # @private
49
- def self.options_for_public_call(options, **flow_options)
68
+ def self.options_for_public_call(options, flow_options = {})
50
69
  Trailblazer::Context(options, {}, flow_options[:context_options])
51
70
  end
52
71
 
53
72
  # @semi=public
54
- def flow_options
55
- {}
73
+ def flow_options_for_public_call(options = {})
74
+ options
75
+ end
76
+
77
+ # TODO: remove when we stop supporting < 3.0.
78
+ def call_with_flow_options(options, flow_options)
79
+ 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")
80
+ call_with_public_interface(options, flow_options, {invoke_class: Activity::TaskWrap})
56
81
  end
57
82
  end
58
83
  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
@@ -1,7 +1,7 @@
1
1
  module Trailblazer
2
2
  module Version
3
3
  module Operation
4
- VERSION = "0.6.5"
4
+ VERSION = "0.7.3"
5
5
  end
6
6
  end
7
7
  end
@@ -1,31 +1,31 @@
1
- require "test_helper"
1
+ # require "test_helper"
2
2
 
3
- class MacaroniTaskBuilderTest < Minitest::Spec
4
- Memo = Struct.new(:title) do
5
- def save
6
- self.title = title[:title].reverse
7
- end
8
- end
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
- #: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
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
- def save(model:, **)
22
- model.save
23
- end
24
- #~methods end
25
- end
26
- #:create end
21
+ # def save(model:, **)
22
+ # model.save
23
+ # end
24
+ # #~methods end
25
+ # end
26
+ # #:create end
27
27
 
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
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
@@ -24,7 +24,6 @@ class DocsActivityTest < Minitest::Spec
24
24
  signal.inspect.must_equal %{#<Trailblazer::Activity::Railway::End::Success semantic=:success>}
25
25
  end
26
26
 
27
- #:describe
28
27
  describe Memo::Create do
29
28
  it "creates a sane Memo instance" do
30
29
  #:call-public
@@ -39,8 +38,69 @@ class DocsActivityTest < Minitest::Spec
39
38
  result.success?.must_equal true
40
39
  result[:model].text.must_equal "Enjoy an IPA"
41
40
  end
41
+
42
+ it "allows indifferent access for ctx keys" do
43
+ #:ctx-indifferent-access
44
+ result = Memo::Create.(params: { text: "Enjoy an IPA" })
45
+
46
+ result[:params] # => { text: "Enjoy an IPA" }
47
+ result['params'] # => { text: "Enjoy an IPA" }
48
+ #:ctx-indifferent-access end
49
+
50
+ result.success?.must_equal true
51
+ result[:params].must_equal({ text: "Enjoy an IPA" })
52
+ result['params'].must_equal({ text: "Enjoy an IPA" })
53
+ end
54
+
55
+ it "allows defining aliases for ctx keys" do
56
+ module AliasesExample
57
+ Memo = Struct.new(:text)
58
+
59
+ module Memo::Contract
60
+ Create = Struct.new(:sync)
61
+ end
62
+
63
+ #:ctx-aliases-step
64
+ class Memo::Create < Trailblazer::Operation
65
+ #~flow
66
+ step ->(ctx, **) { ctx[:'contract.default'] = Memo::Contract::Create.new }
67
+ #~flow end
68
+
69
+ pass :sync
70
+
71
+ def sync(ctx, contract:, **)
72
+ # ctx['contract.default'] == ctx[:contract]
73
+ contract.sync
74
+ end
75
+ end
76
+ #:ctx-aliases-step end
77
+ end
78
+
79
+ #:ctx-aliases
80
+ options = { params: { text: "Enjoy an IPA" } }
81
+ flow_options = {
82
+ context_options: {
83
+ aliases: { 'contract.default': :contract, 'policy.default': :policy },
84
+ container_class: Trailblazer::Context::Container::WithAliases,
85
+ }
86
+ }
87
+
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
94
+
95
+ result['contract.default'] # => Memo::Contract::Create
96
+ result[:contract] # => Memo::Contract::Create
97
+ #:ctx-aliases end
98
+
99
+ result.success?.must_equal true
100
+ _(result[:contract].class).must_equal AliasesExample::Memo::Contract::Create
101
+ _(result['contract.default']).must_equal result[:contract]
102
+ end
42
103
  end
43
- #:describe end
44
104
 
45
105
  it do
46
106
  module J
@@ -79,8 +79,74 @@ class DeclarativeApiTest < Minitest::Spec
79
79
  step ->(options, **) { options["e"] = 2 }
80
80
  end
81
81
 
82
+ class Aliases < Update
83
+ def self.flow_options_for_public_call(*)
84
+ {
85
+ context_options: {
86
+ aliases: { 'b' => :settle },
87
+ container_class: Trailblazer::Context::Container::WithAliases,
88
+ }
89
+ }
90
+ end
91
+ end
92
+
82
93
  it "allows to inherit" do
83
94
  Upsert.("params" => {decide: true}).inspect("a", "b", "c", "d", "e").must_equal %{<Result:true [false, true, nil, 1, nil] >}
84
95
  Unset. ("params" => {decide: true}).inspect("a", "b", "c", "d", "e").must_equal %{<Result:true [false, true, nil, 1, 2] >}
85
96
  end
97
+
98
+ # Mixing keywords and string keys in {Operation.call}.
99
+ # Test that {.(params: {}, "current_user" => user)} is processed properly
100
+ class Collect < Trailblazer::Operation
101
+ # step ->(ctx, **) { ctx[:keys] }
102
+ end
103
+
104
+ it "contains all keys from {call}" do
105
+ result = Collect.(params: {}, "current_user" => Module)
106
+ _(result.inspect).must_equal %{<Result:true #<Trailblazer::Context::Container wrapped_options={:params=>{}, \"current_user\"=>Module} mutable_options={}> >}
107
+ end
108
+
109
+ #---
110
+ #- ctx container
111
+ it do
112
+ options = { "params" => {decide: true} }
113
+
114
+ # Default call
115
+ result = Update.(options)
116
+ result.inspect("a", "b", "c").must_equal %{<Result:true [false, true, nil] >}
117
+
118
+ # Circuit interface call
119
+ signal, (ctx, _) = Update.([Update.options_for_public_call(options), {}], **{})
120
+
121
+ signal.inspect.must_equal %{#<Trailblazer::Activity::Railway::End::Success semantic=:success>}
122
+ ctx.inspect.must_equal %{#<Trailblazer::Context::Container wrapped_options={\"params\"=>{:decide=>true}} mutable_options={\"a\"=>false, \"b\"=>true}>}
123
+
124
+ # Call by passing aliases as an argument.
125
+ if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3.0.0")
126
+ result = Update.(
127
+ options,
128
+ {
129
+ context_options: {
130
+ aliases: { 'b' => :settle },
131
+ container_class: Trailblazer::Context::Container::WithAliases,
132
+ }
133
+ }
134
+ )
135
+ else
136
+ result = Update.call_with_flow_options(
137
+ options,
138
+ {
139
+ context_options: {
140
+ aliases: { 'b' => :settle },
141
+ container_class: Trailblazer::Context::Container::WithAliases,
142
+ }
143
+ },
144
+ )
145
+ end
146
+
147
+ result[:settle].must_equal true
148
+ # Set aliases by overriding `flow_options` at the compile time.
149
+ result = Aliases.(options)
150
+ result[:settle].must_equal true
151
+ end
86
152
  end
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
- it { Trailblazer::Developer.railway(Create).gsub(/0x.+?step_test.rb/, "").must_equal %{[>#<Proc::30 (lambda)>,>StepTest::Callable,>#<Method: StepTest::Implementation.c>,>d,>MyMacro]} }
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
- Class.new(Trailblazer::Operation) do
181
+ class InvalidStep < Trailblazer::Operation
178
182
  step :a, before: "I don't exist!"
179
183
  end
180
184
  end
181
- assert_match /<Trailblazer::Activity::DSL::Linear::Sequence::IndexError: "I don't exist!" is not a valid step ID. Did you mean any of these ?/, op.inspect
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 < Create
211
+ class New < Index
199
212
  end
200
213
 
201
- it { Trailblazer::Developer.railway(New).gsub(/0x.+?step_test.rb/, "").must_equal %{[>#<Proc::30 (lambda)>,>StepTest::Callable,>#<Method: StepTest::Implementation.c>,>d,>MyMacro]} }
214
+ it { Trailblazer::Developer.railway(New).must_equal %{[>my validate,>persist!,>I win!,>No, I do!]} }
202
215
 
203
- class Update < Create
204
- step :after_save!
216
+ class Update < Index
217
+ step :after_save
205
218
  end
206
219
 
207
- it { Trailblazer::Developer.railway(Update).gsub(/0x.+?step_test.rb/, "").must_equal %{[>#<Proc::30 (lambda)>,>StepTest::Callable,>#<Method: StepTest::Implementation.c>,>d,>MyMacro,>after_save!]} }
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,8 @@ 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.3.2", "< 1.0.0"
21
- spec.add_dependency "trailblazer-activity", ">= 0.11.2", "< 1.0.0"
22
- spec.add_dependency "trailblazer-developer", ">= 0.0.8"
20
+ spec.add_dependency "trailblazer-activity-dsl-linear", ">= 0.4.0", "< 1.0.0"
21
+ spec.add_dependency "trailblazer-developer", ">= 0.0.21", "< 1.0.0"
23
22
 
24
23
  spec.add_development_dependency "bundler"
25
24
  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.6.5
4
+ version: 0.7.3
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: 2020-08-20 00:00:00.000000000 Z
11
+ date: 2021-03-12 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.3.2
19
+ version: 0.4.0
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
22
  version: 1.0.0
@@ -26,17 +26,17 @@ dependencies:
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: 0.3.2
29
+ version: 0.4.0
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
32
  version: 1.0.0
33
33
  - !ruby/object:Gem::Dependency
34
- name: trailblazer-activity
34
+ name: trailblazer-developer
35
35
  requirement: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - ">="
38
38
  - !ruby/object:Gem::Version
39
- version: 0.11.2
39
+ version: 0.0.21
40
40
  - - "<"
41
41
  - !ruby/object:Gem::Version
42
42
  version: 1.0.0
@@ -46,24 +46,10 @@ dependencies:
46
46
  requirements:
47
47
  - - ">="
48
48
  - !ruby/object:Gem::Version
49
- version: 0.11.2
49
+ version: 0.0.21
50
50
  - - "<"
51
51
  - !ruby/object:Gem::Version
52
52
  version: 1.0.0
53
- - !ruby/object:Gem::Dependency
54
- name: trailblazer-developer
55
- requirement: !ruby/object:Gem::Requirement
56
- requirements:
57
- - - ">="
58
- - !ruby/object:Gem::Version
59
- version: 0.0.8
60
- type: :runtime
61
- prerelease: false
62
- version_requirements: !ruby/object:Gem::Requirement
63
- requirements:
64
- - - ">="
65
- - !ruby/object:Gem::Version
66
- version: 0.0.8
67
53
  - !ruby/object:Gem::Dependency
68
54
  name: bundler
69
55
  requirement: !ruby/object:Gem::Requirement
@@ -127,10 +113,10 @@ executables: []
127
113
  extensions: []
128
114
  extra_rdoc_files: []
129
115
  files:
116
+ - ".github/workflows/ci.yml"
130
117
  - ".gitignore"
131
118
  - ".rubocop.yml"
132
119
  - ".rubocop_todo.yml"
133
- - ".travis.yml"
134
120
  - CHANGES.md
135
121
  - Gemfile
136
122
  - README.md
@@ -163,8 +149,6 @@ files:
163
149
  - test/introspect_test.rb
164
150
  - test/operation_test.rb
165
151
  - test/result_test.rb
166
- - test/ruby-2.0.0/operation_test.rb
167
- - test/ruby-2.0.0/step_test.rb
168
152
  - test/skill_test.rb
169
153
  - test/step_test.rb
170
154
  - test/test_helper.rb
@@ -177,7 +161,7 @@ homepage: http://trailblazer.to
177
161
  licenses:
178
162
  - MIT
179
163
  metadata: {}
180
- post_install_message:
164
+ post_install_message:
181
165
  rdoc_options: []
182
166
  require_paths:
183
167
  - lib
@@ -193,7 +177,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
193
177
  version: '0'
194
178
  requirements: []
195
179
  rubygems_version: 3.0.8
196
- signing_key:
180
+ signing_key:
197
181
  specification_version: 4
198
182
  summary: Trailblazer's operation object with railway flow and integrated error handling.
199
183
  test_files:
@@ -215,8 +199,6 @@ test_files:
215
199
  - test/introspect_test.rb
216
200
  - test/operation_test.rb
217
201
  - test/result_test.rb
218
- - test/ruby-2.0.0/operation_test.rb
219
- - test/ruby-2.0.0/step_test.rb
220
202
  - test/skill_test.rb
221
203
  - test/step_test.rb
222
204
  - test/test_helper.rb
data/.travis.yml DELETED
@@ -1,13 +0,0 @@
1
- language: ruby
2
- before_install:
3
- - gem install bundler -v 1.17.3
4
- rvm:
5
- - ruby-head
6
- - 2.7
7
- - 2.6
8
- - 2.5
9
- - 2.4
10
- jobs:
11
- allow_failures:
12
- - rvm: ruby-head
13
- - rvm: 2.7
@@ -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