trailblazer-test 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 02bdfafb7d0c3648980cf33724a89d9954428fbd8466fd0f58df7fe0366b8d25
4
+ data.tar.gz: 2753cb581aa889d898f5b23bff1daa44e802150e877087d32faf7e3a46357f90
5
+ SHA512:
6
+ metadata.gz: 9e999f603f7944601d56d17c18e1cbfebe43234fa539e5c7ce9176ca5cf3e1aa2e211bcc1097569b372776020a9b63c6fb86a0f8a350968bea4b0dc755a2eafb
7
+ data.tar.gz: 4701ebcfbb62202dcac8bbcc13149779c63add90ab9471484f1495a5a3a7ca682ee2e17c9210e8c70543f0707939edb3c4bda9d2de46283a54e9e91e5f0a024f
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
@@ -0,0 +1,115 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.5.0
3
+ DisplayCopNames: true
4
+ Layout/CaseIndentation:
5
+ IndentOneStep: true
6
+ Layout/FirstArrayElementLineBreak:
7
+ Enabled: true
8
+ Layout/FirstHashElementLineBreak:
9
+ Enabled: true
10
+ Layout/FirstMethodArgumentLineBreak:
11
+ Enabled: true
12
+ Layout/FirstMethodParameterLineBreak:
13
+ Enabled: true
14
+ Layout/MultilineAssignmentLayout:
15
+ Enabled: true
16
+ EnforcedStyle: same_line
17
+ Layout/SpaceInsideHashLiteralBraces:
18
+ EnforcedStyle: no_space
19
+ Metrics/LineLength:
20
+ Max: 130
21
+ Metrics/ParameterLists:
22
+ Max: 5
23
+ Naming/VariableNumber:
24
+ EnforcedStyle: snake_case
25
+ Style/AndOr:
26
+ EnforcedStyle: conditionals
27
+ Style/AutoResourceCleanup:
28
+ Enabled: true
29
+ Style/CollectionMethods:
30
+ Enabled: true
31
+ Style/Documentation:
32
+ Enabled: false
33
+ Style/EmptyLiteral:
34
+ Enabled: false
35
+ Style/EmptyMethod:
36
+ EnforcedStyle: expanded
37
+ Style/FormatStringToken:
38
+ EnforcedStyle: template
39
+ Style/ImplicitRuntimeError:
40
+ Enabled: true
41
+ Style/MethodCalledOnDoEndBlock:
42
+ Enabled: true
43
+ Style/MethodDefParentheses:
44
+ EnforcedStyle: require_parentheses
45
+ Style/MissingElse:
46
+ Enabled: true
47
+ EnforcedStyle: case
48
+ Style/NumericLiterals:
49
+ Enabled: false
50
+ Style/OptionHash:
51
+ Enabled: true
52
+ Style/PercentLiteralDelimiters:
53
+ PreferredDelimiters:
54
+ "%w": "[]"
55
+ "%W": "[]"
56
+ "%i": "[]"
57
+ "%I": "[]"
58
+ "%r": "()"
59
+ Style/ReturnNil:
60
+ Enabled: true
61
+ Style/SafeNavigation:
62
+ Enabled: false
63
+ Style/Send:
64
+ Enabled: true
65
+ Style/SignalException:
66
+ EnforcedStyle: semantic
67
+ Style/StringLiterals:
68
+ EnforcedStyle: double_quotes
69
+ Style/StringLiteralsInInterpolation:
70
+ EnforcedStyle: double_quotes
71
+ Style/StringMethods:
72
+ Enabled: true
73
+ Style/SymbolArray:
74
+ Enabled: true
75
+ # this allows in rspec to have expect { } with multiple lines
76
+ Style/BlockDelimiters:
77
+ EnforcedStyle: braces_for_chaining
78
+ Layout/EndOfLine:
79
+ Enabled: false
80
+ # don't need these checks in test folders
81
+ Metrics/ModuleLength:
82
+ Exclude:
83
+ - "spec/**/*"
84
+ - "test/**/*"
85
+ Metrics/BlockLength:
86
+ Exclude:
87
+ - "spec/**/*"
88
+ - "test/**/*"
89
+ - "*.gemspec" # definitely not in the gemspec
90
+ Metrics/MethodLength:
91
+ Max: 20
92
+ Lint/UnreachableCode:
93
+ Description: 'Unreachable code.'
94
+ Enabled: false
95
+ Lint/Void:
96
+ Enabled: false
97
+ Layout/AlignHash:
98
+ EnforcedLastArgumentHashStyle: ignore_implicit
99
+ Metrics/AbcSize:
100
+ Max: 25
101
+ Style/LambdaCall:
102
+ Enabled: false
103
+ Style/Semicolon:
104
+ Enabled: false
105
+ Naming/UncommunicativeMethodParamName:
106
+ Enabled: false
107
+ Style/ClassAndModuleChildren:
108
+ Enabled: false
109
+ Layout/LeadingCommentSpace:
110
+ Exclude:
111
+ - 'test/docs/**/*'
112
+ Layout/AlignHash:
113
+ EnforcedHashRocketStyle: table
114
+ Style/FrozenStringLiteralComment:
115
+ Enabled: false
data/.rubocop.yml ADDED
@@ -0,0 +1,17 @@
1
+ inherit_from:
2
+ - https://raw.githubusercontent.com/trailblazer/meta/master/rubocop.yml
3
+
4
+ Style/SignalException:
5
+ Exclude:
6
+ - lib/trailblazer/test/operation/assertions.rb
7
+ - lib/trailblazer/test/operation/helper.rb
8
+ - lib/trailblazer/test/deprecation/operation/helper.rb
9
+
10
+ Metrics/ParameterLists:
11
+ Exclude:
12
+ - lib/trailblazer/test/operation/assertions.rb
13
+
14
+ Metrics/LineLength:
15
+ Exclude:
16
+ - lib/trailblazer/test/operation/assertions.rb
17
+
data/.travis.yml ADDED
@@ -0,0 +1,16 @@
1
+ language: ruby
2
+ before_install:
3
+ - gem install bundler
4
+ matrix:
5
+ include:
6
+ - rvm: 2.1
7
+ gemfile: Gemfile
8
+ - rvm: 2.2
9
+ gemfile: Gemfile
10
+ - rvm: 2.3.1
11
+ gemfile: Gemfile
12
+ - rvm: 2.4.1
13
+ gemfile: Gemfile
14
+ - rvm: 2.5.0
15
+ gemfile: Gemfile
16
+ script: bundle exec rake test && rake rubocop
data/CHANGES.md ADDED
@@ -0,0 +1,8 @@
1
+ # 0.1.0
2
+
3
+ * `ctx` and `params` helper methods implemented
4
+ * `call` and `factory` improved
5
+ * auxiliary methods renamed:
6
+ * `params_pass` -> `default_params`
7
+ * `options_pass` -> `default_options`
8
+ * `attr_pass` -> `expected_attrs`
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in trailblazer-test.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,211 @@
1
+ # Trailblazer::Test
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)
5
+
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`.
137
+
138
+ *We will improve this part and allowing to the test message directly without using a block*
139
+
140
+
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.
153
+
154
+ Example:
155
+ ```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) }
160
+ ```
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
+
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
170
+
171
+ ### Usage
172
+
173
+ Add this in your test `_helper.rb`:
174
+
175
+ ```ruby
176
+ include Trailblazer::Test::Operation::Helper
177
+ ```
178
+
179
+ In case you use are Trailblazer v2.0, you need to add this instead:
180
+
181
+ ```ruby
182
+ require "trailblazer/test/deprecation/operation/helper"
183
+
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
200
+
201
+ # factory - this will raise an error if User::Create fails
202
+ let(:user) { factory(User::Create, params: params)[:model] }
203
+
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]
210
+ end
211
+ ```
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+ require "rubocop/rake_task"
4
+
5
+ RuboCop::RakeTask.new(:rubocop)
6
+
7
+ Rake::TestTask.new(:test) do |t|
8
+ t.libs << "test"
9
+ t.libs << "lib"
10
+ t.test_files = FileList["test/**/*_test.rb"]
11
+ end
12
+
13
+ task default: :test
@@ -0,0 +1,12 @@
1
+ require "trailblazer/test/version"
2
+
3
+ module Trailblazer
4
+ module Test
5
+ # Your code goes here...
6
+ end
7
+ end
8
+
9
+ require "trailblazer/test/assertions"
10
+ require "trailblazer/test/operation/helper"
11
+ require "trailblazer/test/operation/assertions"
12
+ require "trailblazer/test/operation/policy_assertions"
@@ -0,0 +1,37 @@
1
+ # module MiniTest::Assertions
2
+ module Trailblazer
3
+ module Test
4
+ # Evaluate value if it's a lambda, and let the caller know whether we need an
5
+ # assert_equal or an assert.
6
+ def self.expected(asserted, value, actual)
7
+ value.is_a?(Proc) ? [value.(actual: actual, asserted: asserted), false] : [value, true]
8
+ end
9
+
10
+ # Read the actual value from the asserted object (e.g. a model).
11
+ def self.actual(asserted, reader, name)
12
+ reader ? asserted.public_send(reader, name) : asserted.public_send(name)
13
+ end
14
+
15
+ module Assertions
16
+ module_function
17
+
18
+ # tuples = defaults.merge(overrides) # FIXME: merge with above!
19
+
20
+ # Test if all `tuples` values on `asserted` match the expected values.
21
+ # @param asserted Object Object that exposes attributes to test
22
+ # @param tuples Hash Key/value attribute pairs to test
23
+ # @param options Hash Default :reader is `asserted.{name}`,
24
+ # TODO: test err msgs!
25
+ def assert_exposes(asserted, tuples, reader: nil)
26
+ tuples.each do |k, v|
27
+ actual = Test.actual(asserted, reader, k)
28
+ expected, is_eq = Test.expected(asserted, v, actual)
29
+
30
+ is_eq ? assert_equal(expected, actual, "Property [#{k}] mismatch") : assert(expected, "Actual: #{actual.inspect}.")
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ # Trailblazer::Operation::Result.infect_an_assertion :assert_result_matches, :must_match, :do_not_flip
37
+ # Object.infect_an_assertion :assert_exposes, :must_expose, :do_not_flip
@@ -0,0 +1,42 @@
1
+ module Trailblazer::Test
2
+ module Deprecation
3
+ module Operation
4
+ module Assertions
5
+ include Trailblazer::Test::Operation::Assertions
6
+
7
+ # @needs default_params
8
+ # @needs default_options
9
+
10
+ def params(default_params: self.default_params, deep_merge: true, **new_params)
11
+ [merge_for(default_params, new_params, deep_merge), {}]
12
+ end
13
+
14
+ def ctx(new_params, *options)
15
+ # need *options to allow user to do something like:
16
+ # ctx({yeah: 'nah'}, "current_user" => Object, some: 'other' )
17
+
18
+ # this is not greate but seems necessary using *options
19
+ new_options = options.first || {}
20
+ deep_merge = new_options[:deep_merge].nil? ? true : deep_merge
21
+ new_options.delete(:deep_merge)
22
+
23
+ ctx = merge_for(_default_options, options.first || {}, deep_merge)
24
+ [merge_for(params[0], new_params, deep_merge), ctx]
25
+ end
26
+
27
+ def _default_options(options: default_options)
28
+ options
29
+ end
30
+
31
+ # compatibility call for TRB 2.0
32
+ def _call_operation(operation_class, *args)
33
+ operation_class.(args[0][0], args[0][1])
34
+ end
35
+
36
+ def _model(result)
37
+ result["model"]
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,28 @@
1
+ module Trailblazer::Test
2
+ module Deprecation
3
+ module Operation
4
+ module Helper
5
+ def call(operation_class, *args, &block)
6
+ call!(operation_class, args, &block)
7
+ end
8
+
9
+ def factory(operation_class, *args, &block)
10
+ call!(operation_class, args, raise_on_failure: true, &block)
11
+ end
12
+
13
+ # @private
14
+ def call!(operation_class, args, raise_on_failure: false)
15
+ operation_class.(*args).tap do |result|
16
+ unless result.success?
17
+ yield result if block_given?
18
+
19
+ raise OperationFailedError, "factory(#{operation_class}) failed." if raise_on_failure
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ class OperationFailedError < RuntimeError; end
27
+ end
28
+ end
@@ -0,0 +1,89 @@
1
+ require "hashie"
2
+
3
+ module Trailblazer::Test::Operation
4
+ module Assertions
5
+ # @needs default_params
6
+ # @needs default_options
7
+ # @needs expected_attrs
8
+
9
+ def params(default_params: self.default_params, deep_merge: true, **new_params)
10
+ {params: merge_for(default_params, new_params, deep_merge)}
11
+ end
12
+
13
+ def ctx(new_params, default_options: self.default_options, deep_merge: true, **options)
14
+ new_params = merge_for(params[:params], new_params, deep_merge)
15
+ new_options = merge_for(default_options, options, deep_merge)
16
+
17
+ {params: new_params, **new_options}
18
+ end
19
+
20
+ def assert_pass(operation_class, operation_inputs, expected_attributes, default_attributes: expected_attrs, deep_merge: true, &block)
21
+ expected_attributes = merge_for(default_attributes, expected_attributes, deep_merge)
22
+
23
+ assert_pass_with_model(operation_class, operation_inputs, expected_model_attributes: expected_attributes, &block)
24
+ end
25
+
26
+ def assert_fail(operation_class, operation_inputs, expected_errors: nil, contract_name: "default", &block)
27
+ assert_fail_with_model(operation_class, operation_inputs, expected_errors: expected_errors, contract_name: contract_name, &block)
28
+ end
29
+
30
+ # @private
31
+ # TODO: test expected_attributes default param and explicit!
32
+ def assert_pass_with_model(operation_class, operation_inputs, expected_model_attributes: {}, &user_block)
33
+ _assert_call(operation_class, operation_inputs, user_block: user_block) do |result|
34
+ assert_equal true, result.success?
35
+ assert_exposes(_model(result), expected_model_attributes)
36
+ end
37
+ end
38
+
39
+ # @private
40
+ def assert_fail_with_model(operation_class, operation_inputs, expected_errors: nil, contract_name: raise, &user_block)
41
+ _assert_call(operation_class, operation_inputs, user_block: user_block) do |result|
42
+ assert_equal true, result.failure?
43
+
44
+ raise ExpectedErrorsTypeError, "expected_errors has to be an Array" unless expected_errors.is_a?(Array)
45
+
46
+ # only test _if_ errors are present, not the content.
47
+ errors = result["contract.#{contract_name}"].errors.messages # TODO: this will soon change with the operation Errors object.
48
+
49
+ assert_equal expected_errors.sort, errors.keys.sort
50
+ end
51
+ end
52
+
53
+ # @private
54
+ def _assert_call(operation_class, operation_inputs, user_block: raise)
55
+ result = _call_operation(operation_class, operation_inputs)
56
+
57
+ return user_block.call(result) if user_block # DISCUSS: result or model?
58
+
59
+ yield(result)
60
+
61
+ result
62
+ end
63
+
64
+ # @private
65
+ class ExpectedErrorsTypeError < RuntimeError; end
66
+
67
+ # @private
68
+ class CtxHash < Hash
69
+ include Hashie::Extensions::DeepMerge
70
+ end
71
+
72
+ # @private
73
+ def merge_for(dest, source, deep_merge)
74
+ return dest.merge(source) unless deep_merge
75
+
76
+ CtxHash[dest].deep_merge(CtxHash[source])
77
+ end
78
+
79
+ # @private
80
+ def _call_operation(operation_class, operation_inputs)
81
+ operation_class.(operation_inputs)
82
+ end
83
+
84
+ # @private
85
+ def _model(result)
86
+ result[:model]
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,38 @@
1
+ module Trailblazer::Test::Operation
2
+ module Helper
3
+ def call(operation_class, **args, &block)
4
+ call!(operation_class, args, &block)
5
+ end
6
+
7
+ def factory(operation_class, **args, &block)
8
+ call!(operation_class, args.merge(raise_on_failure: true), &block)
9
+ end
10
+
11
+ # @private
12
+ def call!(operation_class, raise_on_failure: false, **args)
13
+ operation_class.trace(**args).tap do |result|
14
+ unless result.success?
15
+
16
+ msg = "factory(#{operation_class}) has failed"
17
+
18
+ unless result["contract.default"].nil? # should we allow to change contract name?
19
+ if result["contract.default"].errors.messages.any?
20
+ msg += " due to validation errors: #{result["contract.default"].errors.messages}"
21
+ end
22
+ end
23
+
24
+ if raise_on_failure
25
+ result.wtf?
26
+ raise OperationFailedError, msg
27
+ end
28
+ end
29
+
30
+ yield result if block_given?
31
+
32
+ result
33
+ end
34
+ end
35
+
36
+ class OperationFailedError < RuntimeError; end
37
+ end
38
+ end
@@ -0,0 +1,13 @@
1
+ module Trailblazer::Test::Operation
2
+ module PolicyAssertions
3
+ include Assertions
4
+ # @needs params_pass
5
+ # @needs options_pass
6
+ def assert_policy_fail(operation_class, ctx, policy_name: "default")
7
+ _assert_call(operation_class, ctx, user_block: nil) do |result|
8
+ assert_equal true, result.failure?
9
+ assert_equal true, result["result.policy.#{policy_name}"].failure?
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ module Trailblazer
2
+ module Test
3
+ VERSION = "0.1.0".freeze
4
+ end
5
+ end
@@ -0,0 +1,29 @@
1
+ lib = File.expand_path("lib", __dir__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "trailblazer/test/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "trailblazer-test"
7
+ spec.version = Trailblazer::Test::VERSION
8
+ spec.authors = ["Nick Sutterer"]
9
+ spec.email = ["apotonick@gmail.com"]
10
+
11
+ spec.summary = "Assertions, matchers, and helpers to test Trailblazer code."
12
+ spec.description = "Assertions, matchers, and helpers to test Trailblazer code."
13
+ spec.homepage = "http://trailblazer.to"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
16
+ f.match(%r{^(test|spec|features)/})
17
+ end
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r(^exe/)) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_dependency "hashie"
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.15"
25
+ spec.add_development_dependency "minitest", "~> 5.0"
26
+ spec.add_development_dependency "rake"
27
+ spec.add_development_dependency "rubocop"
28
+ spec.add_development_dependency "simplecov"
29
+ end
metadata ADDED
@@ -0,0 +1,144 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: trailblazer-test
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Nick Sutterer
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-12-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: hashie
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.15'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.15'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: simplecov
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: Assertions, matchers, and helpers to test Trailblazer code.
98
+ email:
99
+ - apotonick@gmail.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - ".gitignore"
105
+ - ".rubocop-https---raw-githubusercontent-com-trailblazer-meta-master-rubocop-yml"
106
+ - ".rubocop.yml"
107
+ - ".travis.yml"
108
+ - CHANGES.md
109
+ - Gemfile
110
+ - README.md
111
+ - Rakefile
112
+ - lib/trailblazer/test.rb
113
+ - lib/trailblazer/test/assertions.rb
114
+ - lib/trailblazer/test/deprecation/operation/assertions.rb
115
+ - lib/trailblazer/test/deprecation/operation/helper.rb
116
+ - lib/trailblazer/test/operation/assertions.rb
117
+ - lib/trailblazer/test/operation/helper.rb
118
+ - lib/trailblazer/test/operation/policy_assertions.rb
119
+ - lib/trailblazer/test/version.rb
120
+ - trailblazer-test.gemspec
121
+ homepage: http://trailblazer.to
122
+ licenses: []
123
+ metadata: {}
124
+ post_install_message:
125
+ rdoc_options: []
126
+ require_paths:
127
+ - lib
128
+ required_ruby_version: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ required_rubygems_version: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ requirements: []
139
+ rubyforge_project:
140
+ rubygems_version: 2.7.7
141
+ signing_key:
142
+ specification_version: 4
143
+ summary: Assertions, matchers, and helpers to test Trailblazer code.
144
+ test_files: []