radius-spec 0.2.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +6 -0
- data/.travis.yml +4 -5
- data/.yardopts +1 -0
- data/CHANGELOG.md +122 -1
- data/Gemfile +9 -5
- data/README.md +352 -34
- data/benchmarks/bm_setup.rb +70 -0
- data/benchmarks/call_vs_yield.rb +181 -0
- data/benchmarks/case_equality_vs_class_check.rb +73 -0
- data/benchmarks/casecmp_vs_downcase.rb +488 -0
- data/benchmarks/cover_vs_include.rb +106 -0
- data/benchmarks/delete_vs_tr.rb +100 -0
- data/benchmarks/double_negation.rb +167 -0
- data/benchmarks/empty_literal.rb +75 -0
- data/benchmarks/format_string.rb +58 -0
- data/benchmarks/format_string_token.rb +160 -0
- data/benchmarks/gsub_vs_tr.rb +95 -0
- data/benchmarks/hash_merge.rb +112 -0
- data/benchmarks/kwargs.rb +159 -0
- data/benchmarks/max_ternary.rb +105 -0
- data/benchmarks/max_ternary_micro.rb +129 -0
- data/benchmarks/unfreeze_string.rb +86 -0
- data/benchmarks/unpack_first.rb +54 -0
- data/bin/ci +2 -2
- data/bin/ci-code-review +28 -0
- data/common_rubocop.yml +270 -32
- data/common_rubocop_rails.yml +127 -13
- data/lib/radius/spec/model_factory.rb +35 -22
- data/lib/radius/spec/rails.rb +2 -2
- data/lib/radius/spec/rspec.rb +20 -0
- data/lib/radius/spec/rspec/negated_matchers.rb +19 -0
- data/lib/radius/spec/tempfile.rb +162 -0
- data/lib/radius/spec/vcr.rb +100 -0
- data/lib/radius/spec/version.rb +1 -1
- data/radius-spec.gemspec +1 -0
- metadata +43 -10
- data/bin/travis +0 -29
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a6155ce5b3b86485b3a2011fbf15cd2ad268e0f74639986260057d1fcfccdff8
|
4
|
+
data.tar.gz: 0556fe666ef3b4522f32e5f1edaa004ef344bc7a7f47283cc7b49656d3c04950
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fdc10a35535a2b7b39e2ae261fa98d45fbc87c6579366861935c04cc5d15d317182b00c0daaf1414ef457f3e26952fde8cf7b728db924c9befea0c9fd8238d1a
|
7
|
+
data.tar.gz: 176adf989c35360f4e137da3757aeda641414fe29ee50800c69c3d2091342451375e03ed8db3987a3cee5f6d7841ec58da71e8bee4d67854f5a4e043527f7477
|
data/.rubocop.yml
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
inherit_mode:
|
2
2
|
merge:
|
3
3
|
- Exclude
|
4
|
+
- IgnoredPatterns
|
4
5
|
|
5
6
|
inherit_from: common_rubocop.yml
|
6
7
|
|
7
8
|
# Configuration parameters: CountComments, ExcludedMethods.
|
8
9
|
Metrics/BlockLength:
|
9
10
|
Exclude:
|
11
|
+
- 'benchmarks/**/*'
|
10
12
|
- 'lib/radius/spec/rspec.rb'
|
11
13
|
|
12
14
|
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
|
@@ -14,3 +16,7 @@ Metrics/BlockLength:
|
|
14
16
|
Metrics/LineLength:
|
15
17
|
Exclude:
|
16
18
|
- 'radius-spec.gemspec'
|
19
|
+
|
20
|
+
Style/Documentation:
|
21
|
+
Exclude:
|
22
|
+
- 'benchmarks/**/*'
|
data/.travis.yml
CHANGED
@@ -1,15 +1,14 @@
|
|
1
|
-
sudo: false
|
2
1
|
language: ruby
|
3
2
|
cache: bundler
|
4
|
-
before_install:
|
5
|
-
- gem update --system
|
6
|
-
- gem install bundler
|
7
3
|
bundler_args: --jobs=3 --retry=3 --without documentation debug
|
4
|
+
before_script:
|
5
|
+
- "bin/ci-code-review"
|
8
6
|
script: bin/ci
|
9
7
|
rvm:
|
8
|
+
- 2.6
|
10
9
|
- 2.5
|
11
10
|
- ruby-head
|
12
|
-
|
11
|
+
jobs:
|
13
12
|
allow_failures:
|
14
13
|
- rvm: ruby-head
|
15
14
|
fast_finish: true
|
data/.yardopts
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,124 @@
|
|
1
|
+
## 0.6.0 (August 6, 2020)
|
2
|
+
|
3
|
+
[Full Changelog](https://github.com/RadiusNetworks/radius-spec/compare/v0.5.0...v0.6.0)
|
4
|
+
|
5
|
+
### Enhancements
|
6
|
+
|
7
|
+
- Exclude more bundler binstubs from Rubocop (Aaron Kromer, #18, #20)
|
8
|
+
- Exclude `chdir` and `Capybara.register_driver` configuration blocks from
|
9
|
+
`Metrics/BlockLength` checks (Aaron Kromer, #18)
|
10
|
+
- Exclude gem specs from block and line length metrics (Aaron Kromer, #20)
|
11
|
+
- Standardize on key style of `Layout/AlignHash` (Aaron Kromer, #18)
|
12
|
+
- Upgrade to Rubocop 0.62.x (Aaron Kromer, #21)
|
13
|
+
|
14
|
+
### Bug Fixes
|
15
|
+
|
16
|
+
None
|
17
|
+
|
18
|
+
|
19
|
+
## 0.5.0 (September 26, 2018)
|
20
|
+
|
21
|
+
[Full Changelog](https://github.com/RadiusNetworks/radius-spec/compare/v0.4.0...v0.5.0)
|
22
|
+
|
23
|
+
### Enhancements
|
24
|
+
|
25
|
+
- Add common VCR configuration (Aaron Kromer, #16)
|
26
|
+
- Filters out `Authorization` headers
|
27
|
+
- Filters out the following sensitive/environment varying `ENV` values, as
|
28
|
+
well as their URL and form encoded variants:
|
29
|
+
- `AWS_ACCESS_KEY_ID`
|
30
|
+
- `AWS_SECRET_ACCESS_KEY`
|
31
|
+
- `GOOGLE_CLIENT_ID`
|
32
|
+
- `GOOGLE_CLIENT_SECRET`
|
33
|
+
- `RADIUS_OAUTH_PROVIDER_APP_ID`
|
34
|
+
- `RADIUS_OAUTH_PROVIDER_APP_SECRET`
|
35
|
+
- `RADIUS_OAUTH_PROVIDER_URL`
|
36
|
+
- Add "temp file" helpers for working with file stubs (Aaron Kromer, #15)
|
37
|
+
- Upgrade to Rubocop 0.59.x (Aaron Kromer, #14)
|
38
|
+
- Adjust common Rubocop configuration (Aaron Kromer, #14)
|
39
|
+
- `Layout/EmptyLineAfterGuardClause` is enabled by default
|
40
|
+
- Enable `Rails/SaveBang` to highlight potential lurking issues
|
41
|
+
- Expand `Rails/FindBy` and `Rails/FindEach` to check all `/app` and `/lib`
|
42
|
+
- Add more functional methods
|
43
|
+
- `default_scope`
|
44
|
+
- `filter_sensitive_data`
|
45
|
+
- Add `build!` factory method to compliment `build` to help resolving Rubocop
|
46
|
+
violations for `Rails/SaveBang` (Aaron Kromer, #14)
|
47
|
+
- Load model factory for specs tagged with 'type: :mailer' (Aaron Kromer, #11)
|
48
|
+
- Include the following negated RSpec matchers (Aaron Kromer, #12)
|
49
|
+
- `exclude` / `excluding`
|
50
|
+
- `not_eq`
|
51
|
+
- `not_change`
|
52
|
+
- `not_raise_error` / `not_raise_exception`
|
53
|
+
|
54
|
+
### Bug Fixes
|
55
|
+
|
56
|
+
- Fix `NoMethodError: undefined method 'strip'` when the fixture path is a
|
57
|
+
`Pathname` object (Aaron Kromer, #13)
|
58
|
+
|
59
|
+
|
60
|
+
## 0.4.0 (July 10, 2018)
|
61
|
+
|
62
|
+
[Full Changelog](https://github.com/RadiusNetworks/radius-spec/compare/v0.3.0...v0.4.0)
|
63
|
+
|
64
|
+
### Enhancements
|
65
|
+
|
66
|
+
- Upgrade to Rubocop 0.58.x (Aaron Kromer, #10)
|
67
|
+
- Add more custom extra details for customized cops (Aaron Kromer, #10)
|
68
|
+
- Adjust common Rubocop configuration
|
69
|
+
- Disable `Naming/BinaryOperatorParameterName` (Aaron Kromer, #7)
|
70
|
+
- Disable `Style/RedundantReturn` (Aaron Kromer, #7)
|
71
|
+
- Allow optional leading underscores for memoized instance variable names to
|
72
|
+
support modules wanting to reduce conflicts / collisions. (Aaron Kromer, #10)
|
73
|
+
- Adjust common Rubocop Rails configuration (Aaron Kromer, #7)
|
74
|
+
- Exclude Rails controllers from Rubocop's `Metrics/MethodLength` due to
|
75
|
+
`respond_to` / `format` and permitted params methods
|
76
|
+
- Disable `Rails/HasAndBelongsToMany`
|
77
|
+
- Exclude Rails app `config/routes.rb` from `Metrics/BlockLength`
|
78
|
+
|
79
|
+
### Bug Fixes
|
80
|
+
|
81
|
+
- Add more functional methods to Rubocop config (Aaron Kromer, #7)
|
82
|
+
- `create`
|
83
|
+
- `create!`
|
84
|
+
- `build`
|
85
|
+
- `build!`
|
86
|
+
- Support running system specs in isolation (Aaron Kromer, #9)
|
87
|
+
|
88
|
+
|
89
|
+
## 0.3.0 (June 15, 2018)
|
90
|
+
|
91
|
+
[Full Changelog](https://github.com/RadiusNetworks/radius-spec/compare/v0.2.1...v0.3.0)
|
92
|
+
|
93
|
+
### Breaking Change
|
94
|
+
|
95
|
+
- Lock Rubocop to a minor release version in gemspec (Aaron Kromer, #5)
|
96
|
+
|
97
|
+
### Enhancements
|
98
|
+
|
99
|
+
- Adjust common Rubocop configuration (Aaron Kromer, #5)
|
100
|
+
- Customize `Style/AndOr` to flag only conditionals allowing `and` / `or` for
|
101
|
+
control flow
|
102
|
+
- Add `find` to functional method blocks
|
103
|
+
- Disable `Style/DoubleNegation` as this is a common Ruby idiom
|
104
|
+
- Disable `Style/StringLiteralsInInterpolation` to stay consistent with our
|
105
|
+
no preferences for single versus double quotes
|
106
|
+
|
107
|
+
### Bug Fixes
|
108
|
+
|
109
|
+
- Remove `Include` from common Rubocop all cops configuration to fix issues
|
110
|
+
with Rubocop 0.56.0+ not seeing all expected files. (Aaron Kromer, #5)
|
111
|
+
|
112
|
+
|
113
|
+
## 0.2.1 (May 17, 2018)
|
114
|
+
|
115
|
+
[Full Changelog](https://github.com/RadiusNetworks/radius-spec/compare/v0.2.0...v0.2.1)
|
116
|
+
|
117
|
+
### Bug Fixes
|
118
|
+
|
119
|
+
- Fix warning about overriding parameter (Aaron Kromer, #4)
|
120
|
+
|
121
|
+
|
1
122
|
## 0.2.0 (May 17, 2018)
|
2
123
|
|
3
124
|
[Full Changelog](https://github.com/RadiusNetworks/radius-spec/compare/v0.1.1...v0.2.0)
|
@@ -26,7 +147,7 @@
|
|
26
147
|
|
27
148
|
### Bug Fixes
|
28
149
|
|
29
|
-
- Fix `NameError: undefined local variable or method
|
150
|
+
- Fix `NameError: undefined local variable or method config` for Rails RSpec
|
30
151
|
configuration (Aaron Kromer, #1)
|
31
152
|
- Fix model factory build issue in which registered template attributes, which
|
32
153
|
use symbol keys, are not replaced by custom attributes using string keys
|
data/Gemfile
CHANGED
@@ -7,16 +7,20 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
|
7
7
|
# Specify your gem's dependencies in radius-spec.gemspec
|
8
8
|
gemspec
|
9
9
|
|
10
|
-
group :
|
11
|
-
gem
|
12
|
-
gem
|
10
|
+
group :benchmark, optional: true do
|
11
|
+
gem 'activesupport', require: false
|
12
|
+
gem 'benchmark-ips', require: false
|
13
|
+
# TODO: See if this gem has an update in the future as it's gemspec is too
|
14
|
+
# strict and it was blocking other gems from installing / updating
|
15
|
+
gem 'kalibera', require: false, git: 'https://github.com/cupakromer/libkalibera.git'
|
13
16
|
end
|
14
17
|
|
15
|
-
group :
|
16
|
-
gem "
|
18
|
+
group :debug do
|
19
|
+
gem "pry-byebug", "~> 3.6", require: false
|
17
20
|
end
|
18
21
|
|
19
22
|
group :documentation do
|
23
|
+
gem 'redcarpet', require: false
|
20
24
|
gem 'yard', '~> 0.9', require: false
|
21
25
|
end
|
22
26
|
|
data/README.md
CHANGED
@@ -92,11 +92,20 @@ end
|
|
92
92
|
|
93
93
|
### Common Rubocop Config
|
94
94
|
|
95
|
-
Projects can inherit from the [base Rubocop config](.rubocop.yml)
|
96
|
-
either the remote raw URL or dependency gem formats
|
95
|
+
Projects can inherit from the [base Rubocop config](.rubocop.yml). This can be
|
96
|
+
accomplished by using either the remote raw URL or dependency gem formats. With
|
97
|
+
either method we also strongly suggest setting the `inherit_mode` to `merge`
|
98
|
+
for both `Exclude` and `IgnoredPatterns`. This way you can append additional
|
99
|
+
exceptions without overwriting the defaults.
|
100
|
+
|
101
|
+
#### Inherit from Gem (Recommended Method)
|
97
102
|
|
98
103
|
```yaml
|
99
|
-
|
104
|
+
inherit_mode:
|
105
|
+
merge:
|
106
|
+
- Exclude
|
107
|
+
- IgnoredPatterns
|
108
|
+
|
100
109
|
inherit_gem:
|
101
110
|
radius-spec:
|
102
111
|
- common_rubocop.yml
|
@@ -104,7 +113,14 @@ inherit_gem:
|
|
104
113
|
- common_rubocop_rails.yml
|
105
114
|
```
|
106
115
|
|
116
|
+
#### Inherit from URL
|
117
|
+
|
107
118
|
```yaml
|
119
|
+
inherit_mode:
|
120
|
+
merge:
|
121
|
+
- Exclude
|
122
|
+
- IgnoredPatterns
|
123
|
+
|
108
124
|
# Available for projects which cannot include this gem (i.e. Ruby < 2.5)
|
109
125
|
inherit_from:
|
110
126
|
- https://raw.githubusercontent.com/RadiusNetworks/radius-spec/master/common_rubocop.yml
|
@@ -120,6 +136,8 @@ When using the raw URL you may need to add the following to the project's
|
|
120
136
|
.rubocop-https---raw-githubusercontent-com-RadiusNetworks-radius-spec-master-common-rubocop-yml
|
121
137
|
```
|
122
138
|
|
139
|
+
#### General Inheritance Notes
|
140
|
+
|
123
141
|
Be sure to include the project's local `.rubocop_todo.yml` **after** inheriting
|
124
142
|
the base configuration so that they take precedence. Also, use the directive
|
125
143
|
`inherit_mode` to specify which array configurations to merge together instead
|
@@ -137,6 +155,7 @@ inherit_from: .rubocop_todo.yml
|
|
137
155
|
inherit_mode:
|
138
156
|
merge:
|
139
157
|
- Exclude
|
158
|
+
- IgnoredPatterns
|
140
159
|
|
141
160
|
Style/For:
|
142
161
|
inherit_mode:
|
@@ -230,7 +249,7 @@ constant so no changes need to be made if that's your preference.
|
|
230
249
|
|
231
250
|
Attribute keys may be defined using either strings or symbols. However, they
|
232
251
|
will be stored internally as symbols. This means that when an object instance
|
233
|
-
is
|
252
|
+
is created using the factory the attribute hash will be provided to `new` with
|
234
253
|
symbol keys.
|
235
254
|
|
236
255
|
##### Dynamic Attribute Values (i.e. Generators)
|
@@ -399,26 +418,26 @@ There are a few behaviors to note for using the builder:
|
|
399
418
|
|
400
419
|
##### Optional Block
|
401
420
|
|
402
|
-
Both `build` and `
|
421
|
+
Both `build` and `build!` support providing an optional block. This block is
|
403
422
|
passed directly to `new` when creating the object. This is to support the
|
404
423
|
common Ruby idiom of yielding `self` within initialize:
|
405
424
|
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
end
|
425
|
+
```ruby
|
426
|
+
class AnyClass
|
427
|
+
def initialize(attrs = {})
|
428
|
+
# setup attrs
|
429
|
+
yield self if block_given?
|
412
430
|
end
|
431
|
+
end
|
413
432
|
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
end
|
433
|
+
RSpec.describe AnyClass, :model_factory do
|
434
|
+
it "passes the block to the object initializer" do
|
435
|
+
block_capture = nil
|
436
|
+
an_object = build("AnyClass") { |instance| block_capture = instance }
|
437
|
+
expect(block_capture).to be an_object
|
420
438
|
end
|
421
|
-
|
439
|
+
end
|
440
|
+
```
|
422
441
|
|
423
442
|
Since Ruby always supports passing a block to a method, even if the method does
|
424
443
|
not use the block, it's possible the block will not run if the class being
|
@@ -432,29 +451,328 @@ this feature.
|
|
432
451
|
|
433
452
|
We suggest that you create instances using the following syntax:
|
434
453
|
|
435
|
-
|
436
|
-
|
437
|
-
|
454
|
+
```ruby
|
455
|
+
let(:an_instance) { build("AnyClass") }
|
456
|
+
|
457
|
+
before do
|
458
|
+
an_instance.save!
|
459
|
+
end
|
460
|
+
```
|
438
461
|
|
439
462
|
Or alternatively:
|
440
463
|
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
an_instance.save!
|
446
|
-
end
|
447
|
-
```
|
464
|
+
```ruby
|
465
|
+
created_instance = build("AnyClass")
|
466
|
+
created_instance.save!
|
467
|
+
```
|
448
468
|
|
449
469
|
This way it is explicit what objects need to be persisted and in what order.
|
450
470
|
|
451
|
-
|
452
|
-
|
453
|
-
|
471
|
+
This can get tedious at times, especially for those who only need to create an
|
472
|
+
object to embed as an attribute of another object:
|
473
|
+
|
474
|
+
```ruby
|
475
|
+
collaborator = build("AnotherClass")
|
476
|
+
collaborator.save!
|
477
|
+
|
478
|
+
# collaborator is not used against directly after this line
|
479
|
+
created_instance = build("AnyClass", collaborator: collaborator)
|
480
|
+
created_instance.save!
|
481
|
+
```
|
482
|
+
|
483
|
+
For these cases the `build!` helper is available. This is simply an alias for
|
484
|
+
`build.tap(&:save!)`, but it supports omitting the `save!` call for objects
|
485
|
+
which do not support it. While it provides a safety guarantee that `save!` will
|
486
|
+
be called (instead of potentially `save`) it is less explicit.
|
487
|
+
|
488
|
+
```ruby
|
489
|
+
created_instance = build("AnyClass", collaborator: build!("AnotherClass"))
|
490
|
+
created_instance.save!
|
491
|
+
```
|
492
|
+
|
493
|
+
We still discourage the use of `build!` directly in `let` blocks for all of the
|
494
|
+
above mentioned reasons.
|
495
|
+
|
496
|
+
##### Legacy "Creating" Instances
|
497
|
+
|
498
|
+
Many of our existing projects use a legacy `create` helper. This is simply an
|
499
|
+
alias for `build!`. It is provided only for backwards compatibility support and
|
500
|
+
will be removed in a future release. New code should not use this method.
|
501
|
+
|
502
|
+
```ruby
|
503
|
+
created_instance = create("AnyClass")
|
504
|
+
```
|
505
|
+
|
506
|
+
### Negated Matchers
|
507
|
+
|
508
|
+
This gem defines the following [negated matchers](https://relishapp.com/rspec/rspec-expectations/v/3-8/docs/define-negated-matcher)
|
509
|
+
to allow for use [composing matchers](https://relishapp.com/rspec/rspec-expectations/v/3-8/docs/composing-matchers)
|
510
|
+
and with [compound expectations](https://relishapp.com/rspec/rspec-expectations/v/3-8/docs/compound-expectations).
|
511
|
+
|
512
|
+
| Matcher | Inverse Of |
|
513
|
+
|-----------------------|------------|
|
514
|
+
| `exclude` | [`include`](https://relishapp.com/rspec/rspec-expectations/v/3-8/docs/built-in-matchers/include-matcher) |
|
515
|
+
| `excluding` | [`including`](https://relishapp.com/rspec/rspec-expectations/v/3-8/docs/built-in-matchers/include-matcher) |
|
516
|
+
| `not_eq` | [`eq`](https://relishapp.com/rspec/rspec-expectations/v/3-8/docs/built-in-matchers/equality-matchers#compare-using-eq-(==)) |
|
517
|
+
| `not_change` | [`change`](https://relishapp.com/rspec/rspec-expectations/v/3-8/docs/built-in-matchers/change-matcher) |
|
518
|
+
| `not_raise_error` | [`raise_error`](https://relishapp.com/rspec/rspec-expectations/v/3-8/docs/built-in-matchers/raise-error-matcher) |
|
519
|
+
| `not_raise_exception` | [`raise_exception`](https://relishapp.com/rspec/rspec-expectations/v/3-8/docs/built-in-matchers/raise-error-matcher) |
|
520
|
+
|
521
|
+
#### Composing Matchers
|
522
|
+
|
523
|
+
There is no equivalent of `not_to` for composed matchers when only a subset of
|
524
|
+
the values needs to be negated. The negated matchers allow this type of fine
|
525
|
+
grain comparison:
|
526
|
+
|
527
|
+
```ruby
|
528
|
+
x = [1, 2, :value]
|
529
|
+
expect(x).to contain_exactly(be_odd, be_even, not_eq(:target))
|
530
|
+
```
|
531
|
+
|
532
|
+
This also works for verifying / stubbing a message with argument constraints:
|
533
|
+
|
534
|
+
```ruby
|
535
|
+
allow(obj).to receive(:meth).with(1, 2, not_eq(5))
|
536
|
+
obj.meth(1, 2, 3)
|
537
|
+
expect(obj).to have_received(:meth).with(not_eq(2), 2, 3)
|
538
|
+
```
|
539
|
+
|
540
|
+
This is great for verifying option hashes:
|
541
|
+
|
542
|
+
```ruby
|
543
|
+
expect(obj).to have_received(:meth).with(
|
544
|
+
some_value,
|
545
|
+
excluding(:some_opt, :another_opt),
|
546
|
+
)
|
547
|
+
```
|
548
|
+
|
549
|
+
#### Compound Negated Matchers
|
550
|
+
|
551
|
+
Normally it's not possible to chain to a negative match:
|
552
|
+
|
553
|
+
```ruby
|
554
|
+
a = b = 0
|
555
|
+
expect {
|
556
|
+
a = 1
|
557
|
+
}.not_to change {
|
558
|
+
b
|
559
|
+
}.from(0).and change {
|
560
|
+
a
|
561
|
+
}.to(1)
|
562
|
+
```
|
563
|
+
|
564
|
+
Fails with:
|
565
|
+
|
566
|
+
NotImplementedError:
|
567
|
+
`expect(...).not_to matcher.and matcher` is not supported, since it creates
|
568
|
+
a bit of an ambiguity. Instead, define negated versions of whatever
|
569
|
+
matchers you wish to negate with `RSpec::Matchers.define_negated_matcher`
|
570
|
+
and use `expect(...).to matcher.and matcher`.
|
571
|
+
|
572
|
+
Per the error the negated matcher allows for the following:
|
573
|
+
|
574
|
+
```ruby
|
575
|
+
a = b = 0
|
576
|
+
expect {
|
577
|
+
a = 1
|
578
|
+
}.to change {
|
579
|
+
a
|
580
|
+
}.to(1).and not_change {
|
581
|
+
b
|
582
|
+
}.from(0)
|
583
|
+
```
|
584
|
+
|
585
|
+
Similarly, complex expectations can be set on lists:
|
586
|
+
|
587
|
+
```ruby
|
588
|
+
a = %i[red blue green]
|
589
|
+
expect(a).to include(:red).and exclude(:yellow)
|
590
|
+
expect(a).to exclude(:yellow).and include(:red)
|
591
|
+
```
|
592
|
+
|
593
|
+
### Working with Temp Files
|
594
|
+
|
595
|
+
These helpers are meant to ease the creation of temporary files to either stub
|
596
|
+
the data out or provide a location for data to be saved then verified.
|
597
|
+
|
598
|
+
In the case of file stubs, using these helpers allows you to co-locate the file
|
599
|
+
data with the specs. This makes it easy for someone to read the spec and
|
600
|
+
understand the test case; instead of having to find a fixture file and look at
|
601
|
+
its data. This also makes it easy to change the data between specs, allowing
|
602
|
+
them to focus on just what they need.
|
603
|
+
|
604
|
+
#### Usage
|
605
|
+
|
606
|
+
There are multiple ways you can use these helpers. Which method you choose
|
607
|
+
depends on how much perceived magic/syntactic sugar you want:
|
608
|
+
|
609
|
+
- Call the helpers directly on the module:
|
610
|
+
|
611
|
+
```ruby
|
612
|
+
require 'radius/spec/tempfile'
|
613
|
+
|
614
|
+
def write_hello_world(filepath)
|
615
|
+
File.write filepath, "Hello World"
|
616
|
+
end
|
617
|
+
|
618
|
+
Radius::Spec::Tempfile.using_tempfile do |pathname|
|
619
|
+
write_hello_world pathname
|
620
|
+
File.read(pathname)
|
621
|
+
# => "Hello World"
|
622
|
+
end
|
623
|
+
```
|
624
|
+
- Include the helper methods explicitly:
|
625
|
+
|
626
|
+
```ruby
|
627
|
+
require 'radius/spec/tempfile'
|
628
|
+
|
629
|
+
RSpec.describe AnyClass do
|
630
|
+
include Radius::Spec::Tempfile
|
631
|
+
|
632
|
+
it "includes the file helpers" do
|
633
|
+
using_tempfile do |pathname|
|
634
|
+
code_under_test pathname
|
635
|
+
expect(pathname.read).to eq "Any written data"
|
636
|
+
end
|
637
|
+
end
|
638
|
+
end
|
639
|
+
```
|
640
|
+
- Include the helper methods via metadata:
|
641
|
+
|
642
|
+
```ruby
|
643
|
+
RSpec.describe AnyClass do
|
644
|
+
it "includes the file helpers", :tempfile do
|
645
|
+
using_tempfile do |pathname|
|
646
|
+
code_under_test pathname
|
647
|
+
expect(pathname.read).to eq "Any written data"
|
648
|
+
end
|
649
|
+
end
|
650
|
+
end
|
651
|
+
```
|
652
|
+
|
653
|
+
When using this metadata option you do not need to explicitly require the
|
654
|
+
tempfile feature. This gem registers metadata with the RSpec configuration
|
655
|
+
when it loads and `RSpec` is defined. When the metadata is first used it
|
656
|
+
will automatically require the tempfile feature and include the helpers.
|
657
|
+
|
658
|
+
Any of following metadata will include the factory helpers:
|
659
|
+
|
660
|
+
- `:tempfile`
|
661
|
+
- `:tmpfile`
|
662
|
+
|
663
|
+
There are a few additional behaviors to note:
|
664
|
+
|
665
|
+
- Data can be stubbed by the helper through the `data` keyword arg:
|
666
|
+
|
667
|
+
```ruby
|
668
|
+
stub_data = "Any file stub data text."
|
669
|
+
Radius::Spec::Tempfile.using_tempfile(data: stub_data) do |stubpath|
|
670
|
+
File.read(stubpath)
|
671
|
+
# => "Any file stub data text."
|
672
|
+
end
|
673
|
+
```
|
674
|
+
|
675
|
+
It can even be inlined using heredocs:
|
676
|
+
|
677
|
+
```ruby
|
678
|
+
Radius::Spec::Tempfile.using_tempfile(data: <<~TEXT) do |stubpath|
|
679
|
+
Any file stub data text.
|
680
|
+
TEXT
|
681
|
+
# Yard formats heredoc args oddly
|
682
|
+
File.read(stubpath)
|
683
|
+
# => "Any file stub data text.\n"
|
684
|
+
end
|
685
|
+
```
|
686
|
+
|
687
|
+
> NOTE: That when inlining like this heredocs add an extra new line. To
|
688
|
+
> remove it use `.chomp` on the kwarg:
|
689
|
+
>
|
690
|
+
> ```ruby
|
691
|
+
> using_tempfile(data: <<~TEXT.chomp) do |pathname|
|
692
|
+
> This has no newline.
|
693
|
+
> TEXT
|
694
|
+
> # ...
|
695
|
+
> end
|
696
|
+
> ```
|
697
|
+
|
698
|
+
- Additional arguments and options are forwarded directly to
|
699
|
+
[Tempfile.create](https://ruby-doc.org/stdlib/libdoc/tempfile/rdoc/Tempfile.html#method-c-create)
|
700
|
+
|
701
|
+
This allows you to set custom file extensions:
|
702
|
+
|
703
|
+
```ruby
|
704
|
+
Radius::Spec::Tempfile.using_tempfile(%w[custom_name .myext]) do |pathname|
|
705
|
+
pathname.extname
|
706
|
+
# => ".myext"
|
707
|
+
end
|
708
|
+
```
|
709
|
+
|
710
|
+
Or change the file encoding:
|
711
|
+
|
712
|
+
```ruby
|
713
|
+
Radius::Spec::Tempfile.using_tempfile(encoding: "ISO-8859-1", data: <<~DATA) do |pathname|
|
714
|
+
Résumé
|
715
|
+
DATA
|
716
|
+
# Yard formats heredoc args oddly
|
717
|
+
File.read(pathname)
|
718
|
+
# => "R\xE9sum\xE9\n"
|
719
|
+
end
|
720
|
+
```
|
721
|
+
|
722
|
+
### Common VCR Configuration
|
723
|
+
|
724
|
+
A project must include both [`vcr`](https://rubygems.org/gems/vcr) and
|
725
|
+
[`webmock`](https://rubygems.org/gems/webmock) to use this configuration.
|
726
|
+
Neither of those gems will be installed as dependencies of this gem. This is
|
727
|
+
intended to give projects more flexibility in choosing which additional features
|
728
|
+
they will use.
|
729
|
+
|
730
|
+
The main `radius/spec/rspec` setup will load the common VCR configuration
|
731
|
+
automatically when a spec is tagged with the `:vcr` metadata. This will
|
732
|
+
configure VCR to:
|
733
|
+
|
734
|
+
- save specs to `/spec/cassettes`
|
735
|
+
|
736
|
+
- use record mode `once` when a single spec or spec file is run
|
737
|
+
|
738
|
+
This helps ease the development of new specs without requiring any
|
739
|
+
configuration / setting changes.
|
740
|
+
|
741
|
+
- uses record mode `none` otherwise, along setting VCR to fail when unused
|
742
|
+
interactions remain in a cassette
|
743
|
+
|
744
|
+
This is intended to better alert developers to unexpected side effects of
|
745
|
+
changes as any addition or removal of a request will cause a failure.
|
746
|
+
|
747
|
+
- all `Authorization` HTTP headers are filtered by default
|
748
|
+
|
749
|
+
This is a common oversight when recording specs. Often token based
|
750
|
+
authentication is picked up by the other filtered environment settings, but
|
751
|
+
basic authentication is not. Additionally, certain types of digest
|
752
|
+
authentication may cause specs to leak state. This filtering guards all of
|
753
|
+
these cases from accidental credential leak.
|
754
|
+
|
755
|
+
- the following common sensitive, or often environment variable, settings are
|
756
|
+
filtered
|
757
|
+
|
758
|
+
Those settings which often change between developer machines, and even the
|
759
|
+
CI server, can cause for flaky specs. It may also be frustrating for
|
760
|
+
developers to have to adjust their local systems to match others just to
|
761
|
+
get a few specs to pass. This is intended to help mitigate those issues:
|
762
|
+
|
763
|
+
- `AWS_ACCESS_KEY_ID`
|
764
|
+
- `AWS_SECRET_ACCESS_KEY`
|
765
|
+
- `GOOGLE_CLIENT_ID`
|
766
|
+
- `GOOGLE_CLIENT_SECRET`
|
767
|
+
- `RADIUS_OAUTH_PROVIDER_APP_ID`
|
768
|
+
- `RADIUS_OAUTH_PROVIDER_APP_SECRET`
|
769
|
+
- `RADIUS_OAUTH_PROVIDER_URL`
|
770
|
+
|
771
|
+
- a project's local `support/vcr.rb` file will be loaded after the common
|
772
|
+
VCR configuration loads; if it's available
|
454
773
|
|
455
|
-
|
456
|
-
|
457
|
-
```
|
774
|
+
This allows projects to overwrite common settings if they need to, as well,
|
775
|
+
as add on addition settings or filtering of data.
|
458
776
|
|
459
777
|
## Development
|
460
778
|
|