trailblazer-test 0.1.0 → 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 +1 -3
- data/CHANGES.md +4 -0
- data/README.md +62 -133
- data/lib/trailblazer/test/operation/helper.rb +16 -0
- data/lib/trailblazer/test/version.rb +1 -1
- data/trailblazer-test.gemspec +4 -1
- metadata +35 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 484e57db55ede663a53082654e62fc6d12b1384b1591718dfc7fc440c59dd86b
|
4
|
+
data.tar.gz: 5595d2f6daab154412e612e226474e1e88592e82ebdc8d8a1cdf8afc1849ae1e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 302594051f040ca9c3570ac2316cfb5c0a511814727fffc74727b9b2bd0d2adea2ee56a7037406af11c02c93b5c6fa91e7a0a28517352db72c2f6e99949b60c7
|
7
|
+
data.tar.gz: a510c4907ace3ba13e59872d698c8771705bd3047072e3296141381a9c0281ce36bae05759038052dc98a2e0e3421b8e5d3dae9ce28dc4249dab3289367e4ba0
|
data/.travis.yml
CHANGED
data/CHANGES.md
CHANGED
data/README.md
CHANGED
@@ -3,25 +3,19 @@
|
|
3
3
|
[](https://travis-ci.org/trailblazer/trailblazer-test)
|
4
4
|
[](http://badge.fury.io/rb/trailblazer-test)
|
5
5
|
|
6
|
-
##
|
7
|
-
|
8
|
-
Add this line to your application's Gemfile:
|
9
|
-
|
10
|
-
```ruby
|
11
|
-
gem 'trailblazer-test'
|
12
|
-
```
|
13
|
-
|
14
|
-
And then execute:
|
6
|
+
## Usage
|
15
7
|
|
16
|
-
|
8
|
+
Testing Trailblazer applications usually involves the following tests.
|
17
9
|
|
18
|
-
|
10
|
+
1. **Unit tests for operations**: They test all edge cases in a nice, fast unit test environment without any HTTP involved.
|
11
|
+
2. **Integration tests for controllers**: These Smoke tests only test the wiring between controller, operation and presentation layer. Usually, a coded click path simulates you manually clicking through your app and testing if it works. The preferred way here is using Rack-test and Capybara.
|
12
|
+
3. **Unit tests for cells** By invoking your cells with arbitrary data you functionally test the rendered markup using Capybara.
|
19
13
|
|
20
|
-
|
14
|
+
All the up to date details on the available assertions and helpers is available at [official documentation](http://2019.trailblazer.to/2.1/docs/trailblazer.html#trailblazer-test).
|
21
15
|
|
22
|
-
|
16
|
+
### Assertions
|
23
17
|
|
24
|
-
|
18
|
+
To use available assertions, add in your test `_helper` the following modules:
|
25
19
|
|
26
20
|
```ruby
|
27
21
|
include Trailblazer::Test::Assertions
|
@@ -36,176 +30,111 @@ require "trailblazer/test/deprecation/operation/assertions"
|
|
36
30
|
include Trailblazer::Test::Deprecation::Operation::Assertions # in your test class
|
37
31
|
```
|
38
32
|
|
39
|
-
|
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)`
|
33
|
+
[Learn more](http://2019.trailblazer.to/2.1/docs/trailblazer.html#trailblazer-test-assertions)
|
47
34
|
|
48
|
-
|
35
|
+
#### assert_pass
|
49
36
|
|
50
|
-
|
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`.
|
37
|
+
Use `assert_pass` to run an operation and assert it was successful, while checking if the attributes of the operation's `model` are what you're expecting.
|
62
38
|
|
63
39
|
```ruby
|
64
|
-
|
65
|
-
|
66
|
-
params(artist: 'My Artist') -> { params: { title: 'My title', artist: 'My Artist' } }
|
67
|
-
params(title: 'Other one') -> { params: { title: 'Other one' } }
|
40
|
+
it { assert_pass Blog::Operation::Create, { params: { title: "Ruby Soho" } }, title: "Ruby Soho" }
|
68
41
|
```
|
69
42
|
|
70
|
-
####
|
43
|
+
#### assert_fail
|
71
44
|
|
72
|
-
|
45
|
+
To test an unsuccessful outcome of an operation, use `assert_fail`. This is used for testing all kinds of validations. By passing insufficient or wrong data to the operation, it will fail and mark errors on the errors object.
|
73
46
|
|
74
47
|
```ruby
|
75
|
-
|
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' }
|
48
|
+
it { assert_fail Blog::Operation::Update, { params: { band: nil } }, expected_errors: [:band] }
|
80
49
|
```
|
81
50
|
|
82
|
-
|
51
|
+
#### assert_policy_fail
|
83
52
|
|
84
|
-
|
85
|
-
assert_pass(operation, ctx, expected_attributes)
|
86
|
-
```
|
53
|
+
This will test that the operation fails due to a policy failure.
|
87
54
|
|
88
|
-
Example:
|
89
55
|
```ruby
|
90
|
-
|
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' }
|
56
|
+
it { assert_policy_fail Blog::Operation::Delete, ctx({title: "Ruby Soho"}, current_user: not_allowed_user) }
|
95
57
|
```
|
96
58
|
|
97
|
-
|
59
|
+
#### assert_exposes
|
98
60
|
|
99
|
-
|
61
|
+
Test attributes of an arbitrary object.
|
100
62
|
|
101
63
|
```ruby
|
102
|
-
|
103
|
-
assert_equal "Smoko", result[:model].title
|
104
|
-
end
|
64
|
+
it { assert_exposes model, title: "Timebomb", band: "Rancid" }
|
105
65
|
```
|
106
66
|
|
107
|
-
###
|
67
|
+
### Helpers
|
108
68
|
|
109
|
-
|
110
|
-
|
111
|
-
```
|
69
|
+
There are several helpers to deal with operation tests and operations used as factories.
|
70
|
+
Add this in your `_helper.rb` file to use all available helpers.
|
112
71
|
|
113
|
-
Example:
|
114
72
|
```ruby
|
115
|
-
|
116
|
-
let(:default_options) { { current_user: user} }
|
117
|
-
let(:expected_attrs) { { band: 'The Chats'} }
|
118
|
-
|
119
|
-
it { assert_fail MyOp, ctx(title: 'Smoko') }
|
73
|
+
include Trailblazer::Test::Operation::Helper
|
120
74
|
```
|
121
75
|
|
122
|
-
|
76
|
+
[Learn more](http://2019.trailblazer.to/2.1/docs/trailblazer.html#trailblazer-test-helpers)
|
123
77
|
|
124
|
-
|
125
|
-
assert_fail MyOp, ctx(band: 'Justing Beaver'), expected_errors: [:band] # definitely wrong!!!!
|
126
|
-
```
|
78
|
+
#### call
|
127
79
|
|
128
|
-
|
80
|
+
Instead of manually invoking an operation, you can use the `call` helper.
|
129
81
|
|
130
82
|
```ruby
|
131
|
-
|
132
|
-
|
83
|
+
it do
|
84
|
+
result = call Blog::Operation::Create, params: {title: "Shipwreck", band: "Rancid"}
|
85
|
+
# use `result` object however you want
|
133
86
|
end
|
134
87
|
```
|
135
88
|
|
136
|
-
|
137
|
-
|
138
|
-
*We will improve this part and allowing to the test message directly without using a block*
|
139
|
-
|
89
|
+
#### factory
|
140
90
|
|
141
|
-
|
91
|
+
The `factory` method calls the operation and raises an error should the operation have failed. If successful, it will do the exact same thing `call` does.
|
142
92
|
|
143
|
-
Add this in your test file to be able to use it:
|
144
93
|
```ruby
|
145
|
-
|
94
|
+
it do
|
95
|
+
assert_raises do
|
96
|
+
factory Blog::Operation::Create, params: {title: "Shipwreck", band: "The Chats"}
|
97
|
+
end
|
98
|
+
end
|
146
99
|
```
|
147
100
|
|
148
|
-
|
149
|
-
assert_policy_fail(operation, ctx)
|
150
|
-
```
|
101
|
+
#### mock_step
|
151
102
|
|
152
|
-
This
|
103
|
+
This helper allows you to mock any step within a given or deeply nested activities. For example,
|
153
104
|
|
154
|
-
Example:
|
155
105
|
```ruby
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
106
|
+
class Show < Trailblazer::Operation
|
107
|
+
step :load_user
|
108
|
+
...
|
109
|
+
end
|
160
110
|
```
|
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
111
|
|
167
|
-
To
|
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
|
170
|
-
|
171
|
-
### Usage
|
172
|
-
|
173
|
-
Add this in your test `_helper.rb`:
|
112
|
+
To skip processing inside `:load_user` and use a mock instead, use `mock_step`.
|
174
113
|
|
175
114
|
```ruby
|
176
|
-
|
115
|
+
it do
|
116
|
+
new_activity = mock_step(Show, id: :load_user) do |ctx|
|
117
|
+
ctx[:user] = Struct.new(:name).new('Mocky')
|
118
|
+
end
|
119
|
+
|
120
|
+
assert_pass new_activity, {}, {} do |ctx|
|
121
|
+
assert_equal ctx[:user].name, 'Mocky'
|
122
|
+
end
|
123
|
+
end
|
177
124
|
```
|
178
125
|
|
179
|
-
|
126
|
+
## Installation
|
180
127
|
|
181
|
-
|
182
|
-
require "trailblazer/test/deprecation/operation/helper"
|
128
|
+
Add this line to your application's Gemfile:
|
183
129
|
|
184
|
-
|
130
|
+
```ruby
|
131
|
+
gem 'trailblazer-test'
|
185
132
|
```
|
186
133
|
|
187
|
-
|
134
|
+
And then execute:
|
188
135
|
|
189
|
-
|
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
|
136
|
+
$ bundle
|
200
137
|
|
201
|
-
|
202
|
-
let(:user) { factory(User::Create, params: params)[:model] }
|
138
|
+
Or install it yourself as:
|
203
139
|
|
204
|
-
|
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]
|
210
|
-
end
|
211
|
-
```
|
140
|
+
$ gem install trailblazer-test
|
@@ -8,6 +8,22 @@ module Trailblazer::Test::Operation
|
|
8
8
|
call!(operation_class, args.merge(raise_on_failure: true), &block)
|
9
9
|
end
|
10
10
|
|
11
|
+
def mock_step(operation_class, id:, subprocess: nil, subprocess_path: nil)
|
12
|
+
raise ArgumentError, "Missing block: `mock_step` requires a block." unless block_given?
|
13
|
+
|
14
|
+
block = ->(ctx, **) { yield(ctx) }
|
15
|
+
|
16
|
+
# If deeply nested step needs to be mocked, use the `patch` provided by Subprocess
|
17
|
+
if subprocess
|
18
|
+
return Class.new(operation_class) do
|
19
|
+
patch = { subprocess_path => ->() { step block, replace: id, id: id } }
|
20
|
+
step Subprocess(subprocess, patch: patch), replace: subprocess, id: subprocess
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
Class.new(operation_class) { step block, replace: id, id: id }
|
25
|
+
end
|
26
|
+
|
11
27
|
# @private
|
12
28
|
def call!(operation_class, raise_on_failure: false, **args)
|
13
29
|
operation_class.trace(**args).tap do |result|
|
data/trailblazer-test.gemspec
CHANGED
@@ -21,9 +21,12 @@ Gem::Specification.new do |spec|
|
|
21
21
|
|
22
22
|
spec.add_dependency "hashie"
|
23
23
|
|
24
|
-
spec.add_development_dependency "bundler"
|
24
|
+
spec.add_development_dependency "bundler"
|
25
25
|
spec.add_development_dependency "minitest", "~> 5.0"
|
26
26
|
spec.add_development_dependency "rake"
|
27
27
|
spec.add_development_dependency "rubocop"
|
28
28
|
spec.add_development_dependency "simplecov"
|
29
|
+
|
30
|
+
spec.add_dependency "trailblazer-activity", ">= 0.10.0"
|
31
|
+
spec.add_dependency "trailblazer-activity-dsl-linear", ">= 0.2.5"
|
29
32
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trailblazer-test
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Sutterer
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-04-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hashie
|
@@ -28,16 +28,16 @@ dependencies:
|
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: minitest
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,6 +94,34 @@ dependencies:
|
|
94
94
|
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: trailblazer-activity
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 0.10.0
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 0.10.0
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: trailblazer-activity-dsl-linear
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.2.5
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 0.2.5
|
97
125
|
description: Assertions, matchers, and helpers to test Trailblazer code.
|
98
126
|
email:
|
99
127
|
- apotonick@gmail.com
|
@@ -136,8 +164,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
136
164
|
- !ruby/object:Gem::Version
|
137
165
|
version: '0'
|
138
166
|
requirements: []
|
139
|
-
|
140
|
-
rubygems_version: 2.7.7
|
167
|
+
rubygems_version: 3.0.8
|
141
168
|
signing_key:
|
142
169
|
specification_version: 4
|
143
170
|
summary: Assertions, matchers, and helpers to test Trailblazer code.
|