trailblazer-test 0.1.0 → 1.0.0

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: 02bdfafb7d0c3648980cf33724a89d9954428fbd8466fd0f58df7fe0366b8d25
4
- data.tar.gz: 2753cb581aa889d898f5b23bff1daa44e802150e877087d32faf7e3a46357f90
3
+ metadata.gz: 25326dbdb940038e49c6830ac6c4c833583c13db2d5f11782cac2b457f0836cb
4
+ data.tar.gz: e0639ac0cacc534a105138840e15f1019c9136c30042d8ef5d28c80eeb4800fa
5
5
  SHA512:
6
- metadata.gz: 9e999f603f7944601d56d17c18e1cbfebe43234fa539e5c7ce9176ca5cf3e1aa2e211bcc1097569b372776020a9b63c6fb86a0f8a350968bea4b0dc755a2eafb
7
- data.tar.gz: 4701ebcfbb62202dcac8bbcc13149779c63add90ab9471484f1495a5a3a7ca682ee2e17c9210e8c70543f0707939edb3c4bda9d2de46283a54e9e91e5f0a024f
6
+ metadata.gz: 00332de32685126953eff6bfc0f1384f497e431e4ec1038a2f33a04cd3b37f762c8612c6834757a81095633ceaf55c748a799bf925ce27c923b5a391e8d2481d
7
+ data.tar.gz: a09347b703bf1eb6298f63b3e0c3b4481590e92b29b3d8abfb7e192e28a1986a94e2eafb1ff1d18792fc9693c94bcc4cad0cbec922ff9aff637e8ac2cc12fb4f
@@ -0,0 +1,20 @@
1
+ ## This file is managed by Terraform.
2
+ ## Do not modify this file directly, as it may be overwritten.
3
+ ## Please open an issue instead.
4
+ name: CI
5
+ on: [push, pull_request]
6
+ jobs:
7
+ test:
8
+ strategy:
9
+ fail-fast: false
10
+ matrix:
11
+ # commenting out 2.7 because of dry.
12
+ ruby: ['3.0', '3.1', '3.2', "3.3", "head", "jruby"]
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@v3
16
+ - uses: ruby/setup-ruby@v1
17
+ with:
18
+ ruby-version: ${{ matrix.ruby }}
19
+ bundler-cache: true
20
+ - run: bundle exec rake
data/CHANGES.md CHANGED
@@ -1,3 +1,11 @@
1
+ # 1.0.0
2
+
3
+ * Releasing the first stable version.
4
+
5
+ # 0.1.1
6
+
7
+ * Added `mock_step` helper to mock activity's or nested activity's step
8
+
1
9
  # 0.1.0
2
10
 
3
11
  * `ctx` and `params` helper methods implemented
data/Gemfile CHANGED
@@ -2,3 +2,10 @@ source "https://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in trailblazer-test.gemspec
4
4
  gemspec
5
+
6
+ # gem "reform-rails", path: "../reform-rails"
7
+
8
+ gem "trailblazer-endpoint", path: "../trailblazer-endpoint"
9
+ # gem "trailblazer-core-utils", path: "../trailblazer-core-utils"
10
+ # gem "trailblazer-endpoint", github: "trailblazer/trailblazer-endpoint"
11
+ gem "ostruct"
data/README.md CHANGED
@@ -1,211 +1,45 @@
1
1
  # Trailblazer::Test
2
2
 
3
- [![Build Status](https://travis-ci.org/trailblazer/trailblazer-test.svg)](https://travis-ci.org/trailblazer/trailblazer-test)
4
- [![Gem Version](https://badge.fury.io/rb/trailblazer-test.svg)](http://badge.fury.io/rb/trailblazer-test)
3
+ _Assertions and helpers for operation unit tests._
5
4
 
6
- ## Installation
7
-
8
- Add this line to your application's Gemfile:
9
-
10
- ```ruby
11
- gem 'trailblazer-test'
12
- ```
13
-
14
- And then execute:
15
-
16
- $ bundle
17
-
18
- Or install it yourself as:
19
-
20
- $ gem install trailblazer-test
21
-
22
- ## Usage
23
-
24
- Add in your test `_helper` the following modules:
25
-
26
- ```ruby
27
- include Trailblazer::Test::Assertions
28
- include Trailblazer::Test::Operation::Assertions
29
- ```
30
-
31
- If you are using Trailblazer v2.0 you need to add also:
32
-
33
- ```ruby
34
- require "trailblazer/test/deprecation/operation/assertions"
35
-
36
- include Trailblazer::Test::Deprecation::Operation::Assertions # in your test class
37
- ```
38
-
39
- To be able to test an operation we need 3 auxiliary methods which have to be defined at the start of your tests:
40
- * `default_params` (**required**): hash of params which will be always passed to the operation unless overriden by `params` or `ctx`
41
- * `expected_attrs` (**required**): hash always used to assert model attributes
42
- * `default_options` (**required if using `ctx`**): hash of options which will be always passed to the operation unless overriden by `ctx`
43
-
44
- We are also providing 2 helper methods:
45
- * `params(new_params)`
46
- * `ctx(new_params, options)`
47
-
48
- Those will merge params and options for you and return the final inputs which then can be passed to the operation under testing.
49
-
50
- Pass `deep_merge: false` to the helper methods to disable the default deep merging of params and options.
51
-
52
- *Same API for Trailblazer v2.0 and v2.1.*
53
-
54
- Finally, using the built-in assertions you are able to test your operations in a fast and easy way:
55
- * `assert_pass` -> your operation is successful and model has the correct attributes
56
- * `assert_fail` -> your operation fails and returns some specific errors
57
- * `assert_policy_fail` -> your operation fails because policy fails
58
-
59
- #### params
60
-
61
- `params` accepts one argument which is merged into `default_params`.
62
-
63
- ```ruby
64
- let(:default_params) { { title: 'My title' } }
65
-
66
- params(artist: 'My Artist') -> { params: { title: 'My title', artist: 'My Artist' } }
67
- params(title: 'Other one') -> { params: { title: 'Other one' } }
68
- ```
69
-
70
- #### ctx
71
-
72
- `ctx` accepts 2 arguments, first one will be merged into the `default_params` and the second one will be merged into `default_options`
73
-
74
- ```ruby
75
- let(:default_params) { { title: 'My title' } }
76
- let(:default_options) { { current_user: 'me' } }
77
-
78
- ctx(artist: 'My Artist') -> { params: { title: 'My title', artist: 'My Artist' }, current_user: 'me' }
79
- ctx({title: 'Other one'}, current_user: 'you') -> { params: { title: 'Other one' }, current_user: 'you' }
80
- ```
81
-
82
- ### assert_pass
83
-
84
- ```ruby
85
- assert_pass(operation, ctx, expected_attributes)
86
- ```
87
-
88
- Example:
89
- ```ruby
90
- let(:default_params) { { band: 'The Chats'} }
91
- let(:default_options) { { current_user: user} }
92
- let(:expected_attrs) { { band: 'The Chats'} }
93
-
94
- it { assert_pass MyOp, ctx(title: 'Smoko'), title: 'Smoko' }
95
- ```
96
-
97
- Pass `deep_merge: false` to disable the deep merging of the third argument `expected_attributes` and the auxiliary method `expected_attrs`.
98
-
99
- It's also possible to test in a more detailed way using a block:
100
-
101
- ```ruby
102
- assert_pass MyOp, ctx(title: 'Smoko'), {} do |result|
103
- assert_equal "Smoko", result[:model].title
104
- end
105
- ```
106
-
107
- ### assert_fail
108
-
109
- ```ruby
110
- assert_fail(operation, ctx)
111
- ```
112
-
113
- Example:
114
- ```ruby
115
- let(:default_params) { { band: 'The Chats'} }
116
- let(:default_options) { { current_user: user} }
117
- let(:expected_attrs) { { band: 'The Chats'} }
118
-
119
- it { assert_fail MyOp, ctx(title: 'Smoko') }
120
- ```
121
-
122
- This will just test that the operation fails instead passing `expected_errors` as an array of symbols will also test that specific attribute has an error:
123
-
124
- ```ruby
125
- assert_fail MyOp, ctx(band: 'Justing Beaver'), expected_errors: [:band] # definitely wrong!!!!
126
- ```
127
-
128
- Using the block here will allow to test the error message:
129
-
130
- ```ruby
131
- assert_fail MyOp, ctx(band: 'Justing Beaver') do |result|
132
- assert_equal 'You cannot listen Justing Beaver', result['contract.default'].errors.messages[:band]
133
- end
134
- ```
135
-
136
- Change contract name using `contract_name`.
5
+ The [comprehensive docs are here](https://trailblazer.to/2.1/docs/test/).
137
6
 
138
- *We will improve this part and allowing to the test message directly without using a block*
7
+ Read our introducing blog post for a better overview.
139
8
 
9
+ ## Installation
140
10
 
141
- ### assert_policy_fail
142
-
143
- Add this in your test file to be able to use it:
144
- ```ruby
145
- include Trailblazer::Test::Operation::PolicyAssertions
146
- ```
147
-
148
- ```ruby
149
- assert_policy_fail(operation, ctx)
150
- ```
151
-
152
- This will test that the operation fails due to a policy failure.
11
+ Add the following line to your project's `Gemfile`.
153
12
 
154
- Example:
155
13
  ```ruby
156
- let(:default_params) { { band: 'The Chats'} }
157
- let(:default_options) { { current_user: user} }
158
-
159
- it { assert_policy_fail MyOp, ctx({title: 'Smoko'}, current_user: another) }
14
+ gem "trailblazer-test", ">= 1.0.0", "< 2.0.0"
160
15
  ```
161
- Change policy name using `policy_name`.
162
-
163
- ## Test Setup
164
-
165
- It is obviously crucial to test your operation in the correct test enviroment calling operation instead of using `FactoryBot` or simply `Model.create`.
166
16
 
167
- To do so we provide 2 helper methods:
168
- * `call`: will call the operation and **will not raise** an error in case of failure
169
- * `factory`: will call the operation and **will raise** an error in case of failure returning also the trace and a validate error message in case exists
17
+ ## Overview
170
18
 
171
- ### Usage
19
+ This gem adds the following assertions and helpers:
172
20
 
173
- Add this in your test `_helper.rb`:
21
+ * `#assert_pass` to test an operation terminating with success.
22
+ * `#assert_fail` to assert validation errors and the like.
23
+ * `#mock_step` helping the replace steps with stubs.
174
24
 
175
- ```ruby
176
- include Trailblazer::Test::Operation::Helper
177
- ```
25
+ ## Example
178
26
 
179
- In case you use are Trailblazer v2.0, you need to add this instead:
27
+ An example test case checking if an operation passed and created a model could look as follows.
180
28
 
181
29
  ```ruby
182
- require "trailblazer/test/deprecation/operation/helper"
30
+ # test/operation/memo_test.rb
183
31
 
184
- include Trailblazer::Test::Deprecation::Operation::Helper
185
- ```
186
-
187
- *Same API for both Trailblazer v2.0 and v2.1*
188
-
189
- Examples:
190
- ```ruby
191
- # call
192
- let(:user) { call(User::Create, params: params)[:model] }
193
-
194
- # call with block
195
- let(:user) do
196
- call User::Create, params: params do |result|
197
- # run some code to reproduce some async jobs (for example)
198
- end[:model]
199
- end
32
+ require "test_helper"
200
33
 
201
- # factory - this will raise an error if User::Create fails
202
- let(:user) { factory(User::Create, params: params)[:model] }
34
+ class MemoOperationTest < Minitest::Spec
35
+ Trailblazer::Test.module!(self) # install our helpers.
203
36
 
204
- # factory - this will raise an error if User::Create fails
205
- let(:user) do
206
- factory User::Create, params: params do |result|
207
- # this block will be yield only if User::Create is successful
208
- # run some code to reproduce some async jobs (for example)
209
- end[:model]
37
+ it "passes with valid input" do
38
+ # ...
39
+ assert_pass Memo::Operation::Create, input,
40
+ content: "Stock up beer",
41
+ persisted?: true,
42
+ id: ->(asserted:, **) { asserted.id > 0 }
43
+ end
210
44
  end
211
45
  ```
data/Rakefile CHANGED
@@ -1,8 +1,5 @@
1
1
  require "bundler/gem_tasks"
2
2
  require "rake/testtask"
3
- require "rubocop/rake_task"
4
-
5
- RuboCop::RakeTask.new(:rubocop)
6
3
 
7
4
  Rake::TestTask.new(:test) do |t|
8
5
  t.libs << "test"
@@ -0,0 +1,73 @@
1
+ module Trailblazer
2
+ module Test
3
+ module Assertion
4
+ module AssertExposes
5
+ # Test if all `tuples` values on `asserted` match the expected values.
6
+ # @param asserted Object Object that exposes attributes to test
7
+ # @param tuples Hash Key/value attribute pairs to test
8
+ # @param options Hash Default :reader is `asserted.{name}`,
9
+ # TODO: test err msgs!
10
+ def assert_exposes(asserted, expected=nil, reader: nil, **options)
11
+ expected = options.any? ? options : expected # allow passing {expected} as kwargs, too.
12
+
13
+ _assert_exposes_for(asserted, expected, reader: reader)
14
+ end
15
+
16
+ # def assert_exposes_hash(asserted, expected)
17
+ # _assert_exposes_for(asserted, expected, reader: :[])
18
+ # end
19
+
20
+ # @private
21
+ def _assert_exposes_for(asserted, expected, **options)
22
+ passed, matches, last_failed = Assert.assert_attributes(asserted, expected, **options) do |_matches, last_failed|
23
+ name, expected_value, actual_value, _passed, is_eq, error_msg = last_failed
24
+
25
+ is_eq ? assert_equal(expected_value, actual_value, error_msg) : assert(expected_value, error_msg)
26
+
27
+ return false
28
+ end
29
+
30
+ return true
31
+ end
32
+
33
+ module Assert
34
+ module_function
35
+
36
+ # Yields {block} if tuples don't match/failed.
37
+ def assert_attributes(asserted, expected, reader: false, &block)
38
+ passed, matches, last_failed = match_tuples(asserted, expected, reader: reader)
39
+
40
+ yield matches, last_failed unless passed
41
+
42
+ return passed, matches, last_failed
43
+ end
44
+
45
+ # Test if all properties match using our own {#test_equal}.
46
+ # @private
47
+ def match_tuples(asserted, expected, reader:)
48
+ passed = true # goes {false} if one or more attributes didn't match.
49
+
50
+ matches = expected.collect do |k, v|
51
+ actual = Test::Assertion.actual(asserted, reader, k)
52
+ expected, is_eq = Test::Assertion.expected(asserted, v, actual)
53
+
54
+ is_eq ?
55
+ [k, expected, actual, passed &= test_equal(expected, actual), is_eq, "Property [#{k}] mismatch"] :
56
+ [k, expected, actual, passed &= test_true(expected, actual), is_eq, "Actual: #{actual.inspect}."]
57
+ end
58
+
59
+ [passed, matches, matches.find { |k, v, actual, passed, *| !passed }]
60
+ end
61
+
62
+ def test_equal(expected, actual)
63
+ expected == actual
64
+ end
65
+
66
+ def test_true(expected, actual)
67
+ !! expected
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,58 @@
1
+ module Trailblazer
2
+ module Test
3
+ module Assertion
4
+ module AssertFail
5
+ module_function
6
+
7
+ extend AssertPass::Utils
8
+
9
+ # {expected_errors} can be nil when using the {#assert_fail} block syntax.
10
+ def call(activity, ctx, expected_errors=nil, test:, invoke:, **kws)
11
+ signal, ctx, _ = invoke.(activity, ctx)
12
+
13
+ assert_fail_with_model(signal, ctx, expected_errors: expected_errors, test: test, operation: activity, **kws)
14
+ end
15
+
16
+ # @private
17
+ def assert_fail_with_model(signal, ctx, test:, **options)
18
+ assert_after_call(ctx, **options) do |ctx|
19
+
20
+ test.assert_equal *arguments_for_assert_fail(signal), error_message_for_assert_fail_after_call(signal, ctx, **options)
21
+
22
+ if options[:expected_errors]
23
+ # TODO: allow error messages from somewhere else.
24
+ # only test _if_ errors are present, not the content.
25
+ colored_errors = AssertPass::Errors.colored_errors_for(ctx)
26
+
27
+ test.assert_equal *arguments_for_assert_contract_errors(signal, ctx, contract_name: :default, **options), "Actual contract errors: #{colored_errors}"
28
+ end
29
+ end
30
+ end
31
+
32
+ def arguments_for_assert_fail(signal)
33
+ return false, Assertion::SUCCESS_TERMINI.include?(signal.to_h[:semantic]) # FIXME: same logic as in {#assert_pass}.
34
+ end
35
+
36
+ def arguments_for_assert_contract_errors(signal, ctx, contract_name:, expected_errors:, **)
37
+ with_messages = expected_errors.is_a?(Hash)
38
+
39
+ raise ExpectedErrorsTypeError, "expected_errors has to be an Array or Hash" unless expected_errors.is_a?(Array) || with_messages # TODO: test me!
40
+
41
+ errors = ctx[:"contract.#{contract_name}"].errors.messages # TODO: this will soon change with the operation Errors object.
42
+
43
+ if with_messages
44
+ expected_errors = expected_errors.collect { |k, v| [k, Array(v)] }.to_h
45
+
46
+ return expected_errors, errors
47
+ else
48
+ return expected_errors.sort, errors.keys.sort
49
+ end
50
+ end
51
+
52
+ def error_message_for_assert_fail_after_call(signal, ctx, operation:, **)
53
+ %{{#{operation}} didn't fail, it passed}
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,101 @@
1
+ module Trailblazer
2
+ module Test
3
+ module Assertion
4
+ module AssertPass
5
+ module_function
6
+
7
+ def call(activity, ctx, invoke:, **options)
8
+ signal, ctx, _ = invoke.(activity, ctx)
9
+
10
+ assert_pass_with_model(signal, ctx, operation: activity, **options)
11
+ end
12
+
13
+ def assert_pass_with_model(signal, ctx, **options)
14
+ assert_after_call(ctx, **options) do |ctx|
15
+ Passed.new.call(signal, ctx, **options)
16
+ PassedWithAttributes.new.call(signal, ctx, **options)
17
+ end
18
+ end
19
+
20
+ class Passed
21
+ # Check if the operation terminates on {:success}.
22
+ # @semi-public Used in rspec-trailblazer
23
+ def call(signal, ctx, **options)
24
+ expected_outcome, actual_outcome = arguments_for_assertion(signal)
25
+ error_msg = error_message(signal, ctx, **options) # DISCUSS: compute error message before there was an error?
26
+
27
+ outcome = assertion(expected_outcome, actual_outcome, error_msg, **options)
28
+ return outcome, error_msg
29
+ end
30
+
31
+ # What needs to be compared?
32
+ def arguments_for_assertion(signal)
33
+ return true, Assertion::SUCCESS_TERMINI.include?(signal.to_h[:semantic])
34
+ end
35
+
36
+ def error_message(signal, ctx, operation:, **)
37
+ colored_errors = Errors.colored_errors_for(ctx)
38
+
39
+ %{{#{operation}} failed: #{colored_errors}} # FIXME: only if contract's there!
40
+ end
41
+
42
+ def assertion(expected_outcome, actual_outcome, error_msg, test:, **)
43
+ test.assert_equal(
44
+ expected_outcome,
45
+ actual_outcome,
46
+ error_msg
47
+ )
48
+ end
49
+ end
50
+
51
+ # @semi-public Used in rspec-trailblazer
52
+ class PassedWithAttributes
53
+ def call(signal, ctx, **options)
54
+ model = model_for(ctx, **options)
55
+
56
+ outcome, error_msg = assertion(ctx, **options, model: model)
57
+ return outcome, error_msg
58
+ end
59
+
60
+ # DISCUSS: should we default options like {:model_at} here?
61
+ def model_for(ctx, model_at: :model, **)
62
+ ctx[model_at]
63
+ end
64
+
65
+ def assertion(ctx, model:, expected_model_attributes:, test:, **)
66
+ test.assert_exposes(model, expected_model_attributes)
67
+ end
68
+ end
69
+
70
+ module Utils
71
+ # @private
72
+ def assert_after_call(ctx, user_block:, **kws)
73
+ yield(ctx)
74
+
75
+ user_block.call(ctx) if user_block
76
+
77
+ ctx
78
+ end
79
+ end # Utils
80
+
81
+ module Errors
82
+ module_function
83
+
84
+ def colored_errors_for(ctx)
85
+ # TODO: generic errors object "finding"
86
+ errors =
87
+ if ctx[:"contract.default"]
88
+ ctx[:"contract.default"].errors.messages.inspect
89
+ else
90
+ ""
91
+ end
92
+
93
+ colored_errors = %{\e[33m#{errors}\e[0m}
94
+ end
95
+ end
96
+
97
+ extend Utils
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,114 @@
1
+ module Trailblazer
2
+ module Test
3
+ # Top-level entry points for end users.
4
+ # These methods expose the end user syntax, not the logic.
5
+ module Assertion
6
+ def self.module!(receiver, activity: false, suite: false, spec: true)
7
+ modules = [Helper::MockStep, AssertExposes]
8
+ if suite
9
+ modules += [Suite, Suite::Spec] if spec
10
+ modules += [Suite, Suite::Test] if suite && !spec
11
+ else
12
+ modules += [Assertion]
13
+ end
14
+
15
+ modules += [Assertion::Activity] if activity
16
+
17
+ receiver.include(*modules.reverse)
18
+ end
19
+
20
+ SUCCESS_TERMINI = [:success, :pass_fast] # DISCUSS: where should this be defined?
21
+
22
+ # @private
23
+ # Invoker for Operation
24
+ def self.invoke_operation(operation, ctx)
25
+ result = operation.call(ctx)
26
+
27
+ return result.terminus, result # translate the holy {Operation::Result} object back to a normal "circuit interface" return value.
28
+ end
29
+
30
+ # @private
31
+ # Invoker with debugging for Operation
32
+ def self.invoke_operation_with_wtf(operation, ctx)
33
+ result = operation.wtf?(ctx)
34
+
35
+ return result.terminus, result
36
+ end
37
+
38
+ # Evaluate value if it's a lambda, and let the caller know whether we need an
39
+ # assert_equal or an assert.
40
+ def self.expected(asserted, value, actual)
41
+ value.is_a?(Proc) ? [value.(actual: actual, asserted: asserted), false] : [value, true]
42
+ end
43
+
44
+ # # Read the actual value from the asserted object (e.g. a model).
45
+ def self.actual(asserted, reader, name)
46
+ reader ? asserted.public_send(reader, name) : asserted.public_send(name)
47
+ end
48
+
49
+ # DISCUSS: move to Assertion::Minitest?
50
+ # Test case instance method. Specific to Minitest.
51
+ def assert_pass(activity, options, invoke: Assertion.method(:invoke_operation), model_at: :model, **kws, &block)
52
+ # DISCUSS: {:model_at} and {:invoke_method} block actual attributes.
53
+ AssertPass.(activity, options,
54
+ test: self,
55
+ user_block: block,
56
+ expected_model_attributes: kws,
57
+ model_at: model_at,
58
+ invoke: invoke,
59
+ ) # Forward {#assert_pass} to {AssertPass.call} or wherever your implementation sits.
60
+ end
61
+
62
+ # DISCUSS: move to Assertion::Minitest?
63
+ # Test case instance method. Specific to Minitest.
64
+ def assert_fail(activity, options, *args, invoke: Assertion.method(:invoke_operation), **kws, &block)
65
+ AssertFail.(activity, options, *args, test: self, user_block: block, invoke: invoke, **kws) # Forward {#assert_fail} to {AssertFail.call} or wherever your implementation sits.
66
+ end
67
+
68
+ def assert_pass?(*args, **options, &block)
69
+ assert_pass(*args, **options, invoke: Assertion.method(:invoke_operation_with_wtf), &block)
70
+ end
71
+
72
+ def assert_fail?(*args, **options, &block)
73
+ assert_fail(*args, **options, invoke: Assertion.method(:invoke_operation_with_wtf), &block)
74
+ end
75
+
76
+ # Assertions for Activity, not for Operation.
77
+ module Activity
78
+ def self.invoke_activity(activity, ctx)
79
+ signal, (ctx, _) = activity.call([ctx, {}]) # call with circuit interface. https://trailblazer.to/2.1/docs/operation/#operation-internals-circuit-interface
80
+
81
+ return signal, ctx
82
+ end
83
+
84
+ def self.invoke_activity_with_task_wrap(activity, ctx)
85
+ signal, (ctx, _) = ::Trailblazer::Activity::TaskWrap.invoke(activity, [ctx, {}]) # call with circuit interface. https://trailblazer.to/2.1/docs/operation/#operation-internals-circuit-interface
86
+
87
+ return signal, ctx
88
+ end
89
+
90
+ def self.invoke_activity_with_tracing(activity, ctx)
91
+ signal, (ctx, _) = Developer::Wtf.invoke(activity, [ctx, {}])
92
+
93
+ return signal, ctx
94
+ end
95
+
96
+ def assert_pass(*args, invoke: Activity.method(:invoke_activity_with_task_wrap), **options, &block)
97
+ super(*args, **options, invoke: invoke, &block)
98
+ end
99
+
100
+ def assert_fail(*args, invoke: Activity.method(:invoke_activity_with_task_wrap), **options, &block)
101
+ super(*args, **options, invoke: invoke, &block)
102
+ end
103
+
104
+ def assert_pass?(*args, **options, &block)
105
+ assert_pass(*args, **options, invoke: Activity.method(:invoke_activity_with_tracing), &block)
106
+ end
107
+
108
+ def assert_fail?(*args, **options, &block)
109
+ assert_fail(*args, **options, invoke: Activity.method(:invoke_activity_with_tracing), &block)
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,5 @@
1
+ module Trailblazer::Test
2
+ class Context < Hash
3
+ # TODO: override {#inspect}
4
+ end
5
+ end