radius-spec 0.4.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +28 -0
- data/.github/workflows/reviewdog.yml +21 -0
- data/.rubocop.yml +9 -5
- data/.yardopts +1 -0
- data/CHANGELOG.md +111 -1
- data/Gemfile +3 -4
- data/README.md +335 -37
- data/benchmarks/bm_setup.rb +1 -0
- data/benchmarks/call_vs_yield.rb +33 -2
- data/benchmarks/casecmp_vs_downcase.rb +488 -0
- data/benchmarks/cover_vs_include.rb +2 -2
- data/benchmarks/format_string.rb +3 -3
- data/benchmarks/hash_each.rb +305 -0
- data/benchmarks/hash_merge.rb +1 -1
- data/benchmarks/hash_transform.rb +455 -0
- data/benchmarks/unfreeze_string.rb +0 -2
- data/bin/ci +1 -1
- data/common_rubocop.yml +168 -41
- data/common_rubocop_rails.yml +107 -21
- data/lib/radius/spec/model_factory.rb +35 -24
- data/lib/radius/spec/rails.rb +1 -1
- data/lib/radius/spec/rspec/negated_matchers.rb +19 -0
- data/lib/radius/spec/rspec.rb +20 -0
- data/lib/radius/spec/tempfile.rb +162 -0
- data/lib/radius/spec/vcr.rb +98 -0
- data/lib/radius/spec/version.rb +1 -1
- data/radius-spec.gemspec +8 -7
- metadata +44 -20
- data/.travis.yml +0 -17
- data/bin/ci-code-review +0 -28
- 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: c90e6b5072e71e6bb5c5ef37ccbbc9f0b874c151d156bdb3e9af92aeba0caeb1
|
4
|
+
data.tar.gz: 2781ec9668af9583f4ac7c73de5de2f52e634e3d063e94feb305095de4b36f75
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9b685ea0852391ce5a52c1810bd10d923ff007d9968a4dce483ca147d2057c0e320c15c413abcef900c810cb241dc98b2e633d7b65176a87fbc863d5f2dad26b
|
7
|
+
data.tar.gz: 97ea01566899ea8641f86771f54147875e649eb18669871b2f6db640d6bce912982e5e53690b051b70aece3cd231275fe38c074c3e28cdc5670860c04d6579e4
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# This workflow uses actions that are not certified by GitHub.
|
2
|
+
# They are provided by a third-party and are governed by
|
3
|
+
# separate terms of service, privacy policy, and support
|
4
|
+
# documentation.
|
5
|
+
# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
|
6
|
+
# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
|
7
|
+
|
8
|
+
name: Ruby
|
9
|
+
|
10
|
+
on: [push, pull_request]
|
11
|
+
|
12
|
+
jobs:
|
13
|
+
test:
|
14
|
+
|
15
|
+
runs-on: ubuntu-latest
|
16
|
+
strategy:
|
17
|
+
matrix:
|
18
|
+
ruby-version: ['2.5', '2.6', '2.7']
|
19
|
+
|
20
|
+
steps:
|
21
|
+
- uses: actions/checkout@v2
|
22
|
+
- name: Set up Ruby
|
23
|
+
uses: ruby/setup-ruby@v1
|
24
|
+
with:
|
25
|
+
ruby-version: ${{ matrix.ruby-version }}
|
26
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
27
|
+
- name: Run tests
|
28
|
+
run: ./bin/ci
|
@@ -0,0 +1,21 @@
|
|
1
|
+
name: Review Dog
|
2
|
+
on: [pull_request]
|
3
|
+
jobs:
|
4
|
+
rubocop:
|
5
|
+
name: Rubocop
|
6
|
+
runs-on: ubuntu-latest
|
7
|
+
steps:
|
8
|
+
- name: Check out code
|
9
|
+
uses: actions/checkout@v1
|
10
|
+
- uses: ruby/setup-ruby@v1 # ruby-version pulled .ruby-version file automatically
|
11
|
+
with:
|
12
|
+
ruby-version: '2.7'
|
13
|
+
bundler-cache: true
|
14
|
+
- name: rubocop
|
15
|
+
uses: reviewdog/action-rubocop@v1
|
16
|
+
with:
|
17
|
+
github_token: ${{ secrets.github_token }}
|
18
|
+
reporter: github-pr-review # Default is github-pr-check
|
19
|
+
rubocop_version: gemfile
|
20
|
+
rubocop_extensions: rubocop-rails:gemfile
|
21
|
+
|
data/.rubocop.yml
CHANGED
@@ -3,7 +3,13 @@ inherit_mode:
|
|
3
3
|
- Exclude
|
4
4
|
- IgnoredPatterns
|
5
5
|
|
6
|
-
inherit_from:
|
6
|
+
inherit_from: common_rubocop_rails.yml
|
7
|
+
|
8
|
+
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
|
9
|
+
# URISchemes: http, https
|
10
|
+
Layout/LineLength:
|
11
|
+
Exclude:
|
12
|
+
- 'radius-spec.gemspec'
|
7
13
|
|
8
14
|
# Configuration parameters: CountComments, ExcludedMethods.
|
9
15
|
Metrics/BlockLength:
|
@@ -11,8 +17,6 @@ Metrics/BlockLength:
|
|
11
17
|
- 'benchmarks/**/*'
|
12
18
|
- 'lib/radius/spec/rspec.rb'
|
13
19
|
|
14
|
-
|
15
|
-
# URISchemes: http, https
|
16
|
-
Metrics/LineLength:
|
20
|
+
Style/Documentation:
|
17
21
|
Exclude:
|
18
|
-
- '
|
22
|
+
- 'benchmarks/**/*'
|
data/.yardopts
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,113 @@
|
|
1
|
+
## 0.8.0 (August 26, 2021)
|
2
|
+
|
3
|
+
[Full Changelog](https://github.com/RadiusNetworks/radius-spec/compare/v0.7.0...v0.8.0)
|
4
|
+
|
5
|
+
### Enhancements
|
6
|
+
|
7
|
+
- Upgrade to Rubocop 0.82.x (Aaron Hill, Aaron Kromer, Ben Reynolds, Chris
|
8
|
+
Hoffman, James Nebeker, JC Avena #26)
|
9
|
+
- Upgrade to Rubocop Rails 2.5.x (Aaron Hill, Aaron Kromer, Ben Reynolds, Chris
|
10
|
+
Hoffman, James Nebeker, JC Avena #26)
|
11
|
+
- Adjust common Rubocop configuration (Aaron Hill, Aaron Kromer, Ben Reynolds,
|
12
|
+
Chris Hoffman, James Nebeker, JC Avena #26)
|
13
|
+
- Rename metrics/configuration parameters per version upgrade requirements
|
14
|
+
- Use the stricter `always_true` check for `Style/FrozenStringLiteralComment`
|
15
|
+
- Opt-in to new cops/checks behaving per their default settings
|
16
|
+
- Adjust common Rubocop Rails configuration (Aaron Hill, Aaron Kromer, Ben
|
17
|
+
Reynolds, Chris Hoffman, James Nebeker, JC Avena #26)
|
18
|
+
- Disable `Rails/IndexBy` by default
|
19
|
+
- Disable `Rails/IndexWith` by default
|
20
|
+
|
21
|
+
### Bug Fixes
|
22
|
+
|
23
|
+
None
|
24
|
+
|
25
|
+
|
26
|
+
## 0.7.0 (July 23, 2021)
|
27
|
+
|
28
|
+
[Full Changelog](https://github.com/RadiusNetworks/radius-spec/compare/v0.6.0...0.7.0)
|
29
|
+
|
30
|
+
### Enhancements
|
31
|
+
|
32
|
+
- Upgrade to Rubocop 0.73.x (Aaron Hill, Aaron Kromer, Ben Reynolds, Chris
|
33
|
+
Hoffman, James Nebeker #24)
|
34
|
+
- Upgrade to Rubocop Rails 2.2.x (Aaron Hill, Aaron Kromer, Ben Reynolds, Chris
|
35
|
+
Hoffman, James Nebeker #24)
|
36
|
+
- Adjust common Rubocop configuration (Aaron Hill, Aaron Kromer, Ben Reynolds,
|
37
|
+
Chris Hoffman, James Nebeker #24)
|
38
|
+
- Target Ruby 2.7 by default
|
39
|
+
- Enable `Lint/HeredocMethodCallPosition` by default
|
40
|
+
- Use `StandardError` for the suggested parent classes of errors
|
41
|
+
- Bump metric check maximums to provide a little more wiggle room
|
42
|
+
- Disable `Naming/RescuedExceptionsVariableName` by default
|
43
|
+
- Adjust common Rubocop Rails configuration (Aaron Hill, Aaron Kromer, Ben
|
44
|
+
Reynolds, Chris Hoffman, James Nebeker #24)
|
45
|
+
- Disable `Rails/IgnoredSkipActionFilterOption` by default
|
46
|
+
|
47
|
+
### Bug Fixes
|
48
|
+
|
49
|
+
None
|
50
|
+
|
51
|
+
|
52
|
+
## 0.6.0 (August 6, 2020)
|
53
|
+
|
54
|
+
[Full Changelog](https://github.com/RadiusNetworks/radius-spec/compare/v0.5.0...v0.6.0)
|
55
|
+
|
56
|
+
### Enhancements
|
57
|
+
|
58
|
+
- Exclude more bundler binstubs from Rubocop (Aaron Kromer, #18, #20)
|
59
|
+
- Exclude `chdir` and `Capybara.register_driver` configuration blocks from
|
60
|
+
`Metrics/BlockLength` checks (Aaron Kromer, #18)
|
61
|
+
- Exclude gem specs from block and line length metrics (Aaron Kromer, #20)
|
62
|
+
- Standardize on key style of `Layout/AlignHash` (Aaron Kromer, #18)
|
63
|
+
- Upgrade to Rubocop 0.62.x (Aaron Kromer, #21)
|
64
|
+
|
65
|
+
### Bug Fixes
|
66
|
+
|
67
|
+
None
|
68
|
+
|
69
|
+
|
70
|
+
## 0.5.0 (September 26, 2018)
|
71
|
+
|
72
|
+
[Full Changelog](https://github.com/RadiusNetworks/radius-spec/compare/v0.4.0...v0.5.0)
|
73
|
+
|
74
|
+
### Enhancements
|
75
|
+
|
76
|
+
- Add common VCR configuration (Aaron Kromer, #16)
|
77
|
+
- Filters out `Authorization` headers
|
78
|
+
- Filters out the following sensitive/environment varying `ENV` values, as
|
79
|
+
well as their URL and form encoded variants:
|
80
|
+
- `AWS_ACCESS_KEY_ID`
|
81
|
+
- `AWS_SECRET_ACCESS_KEY`
|
82
|
+
- `GOOGLE_CLIENT_ID`
|
83
|
+
- `GOOGLE_CLIENT_SECRET`
|
84
|
+
- `RADIUS_OAUTH_PROVIDER_APP_ID`
|
85
|
+
- `RADIUS_OAUTH_PROVIDER_APP_SECRET`
|
86
|
+
- `RADIUS_OAUTH_PROVIDER_URL`
|
87
|
+
- Add "temp file" helpers for working with file stubs (Aaron Kromer, #15)
|
88
|
+
- Upgrade to Rubocop 0.59.x (Aaron Kromer, #14)
|
89
|
+
- Adjust common Rubocop configuration (Aaron Kromer, #14)
|
90
|
+
- `Layout/EmptyLineAfterGuardClause` is enabled by default
|
91
|
+
- Enable `Rails/SaveBang` to highlight potential lurking issues
|
92
|
+
- Expand `Rails/FindBy` and `Rails/FindEach` to check all `/app` and `/lib`
|
93
|
+
- Add more functional methods
|
94
|
+
- `default_scope`
|
95
|
+
- `filter_sensitive_data`
|
96
|
+
- Add `build!` factory method to compliment `build` to help resolving Rubocop
|
97
|
+
violations for `Rails/SaveBang` (Aaron Kromer, #14)
|
98
|
+
- Load model factory for specs tagged with 'type: :mailer' (Aaron Kromer, #11)
|
99
|
+
- Include the following negated RSpec matchers (Aaron Kromer, #12)
|
100
|
+
- `exclude` / `excluding`
|
101
|
+
- `not_eq`
|
102
|
+
- `not_change`
|
103
|
+
- `not_raise_error` / `not_raise_exception`
|
104
|
+
|
105
|
+
### Bug Fixes
|
106
|
+
|
107
|
+
- Fix `NoMethodError: undefined method 'strip'` when the fixture path is a
|
108
|
+
`Pathname` object (Aaron Kromer, #13)
|
109
|
+
|
110
|
+
|
1
111
|
## 0.4.0 (July 10, 2018)
|
2
112
|
|
3
113
|
[Full Changelog](https://github.com/RadiusNetworks/radius-spec/compare/v0.3.0...v0.4.0)
|
@@ -88,7 +198,7 @@
|
|
88
198
|
|
89
199
|
### Bug Fixes
|
90
200
|
|
91
|
-
- Fix `NameError: undefined local variable or method
|
201
|
+
- Fix `NameError: undefined local variable or method config` for Rails RSpec
|
92
202
|
configuration (Aaron Kromer, #1)
|
93
203
|
- Fix model factory build issue in which registered template attributes, which
|
94
204
|
use symbol keys, are not replaced by custom attributes using string keys
|
data/Gemfile
CHANGED
@@ -8,18 +8,17 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
|
8
8
|
gemspec
|
9
9
|
|
10
10
|
group :benchmark, optional: true do
|
11
|
+
gem 'activesupport', require: false
|
11
12
|
gem 'benchmark-ips', require: false
|
12
|
-
|
13
|
-
# strict and it was blocking other gems from installing / updating
|
14
|
-
gem 'kalibera', require: false, git: 'https://github.com/cupakromer/libkalibera.git'
|
13
|
+
gem 'kalibera', require: false
|
15
14
|
end
|
16
15
|
|
17
16
|
group :debug do
|
18
17
|
gem "pry-byebug", "~> 3.6", require: false
|
19
|
-
gem "travis", require: false
|
20
18
|
end
|
21
19
|
|
22
20
|
group :documentation do
|
21
|
+
gem 'redcarpet', require: false
|
23
22
|
gem 'yard', '~> 0.9', require: false
|
24
23
|
end
|
25
24
|
|
data/README.md
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# Common RSpec Setup and Plug-ins
|
2
2
|
|
3
|
-
[![Build Status](https://travis-ci.org/RadiusNetworks/radius-spec.svg?branch=master)](https://travis-ci.org/RadiusNetworks/radius-spec)
|
4
3
|
[![Maintainability](https://api.codeclimate.com/v1/badges/701295df43d53e25eafe/maintainability)](https://codeclimate.com/github/RadiusNetworks/radius-spec/maintainability)
|
5
4
|
[![Gem Version](https://badge.fury.io/rb/radius-spec.svg)](https://badge.fury.io/rb/radius-spec)
|
6
5
|
|
@@ -123,17 +122,17 @@ inherit_mode:
|
|
123
122
|
|
124
123
|
# Available for projects which cannot include this gem (i.e. Ruby < 2.5)
|
125
124
|
inherit_from:
|
126
|
-
- https://raw.githubusercontent.com/RadiusNetworks/radius-spec/
|
125
|
+
- https://raw.githubusercontent.com/RadiusNetworks/radius-spec/main/common_rubocop.yml
|
127
126
|
# Use the following instead if it is a Rails project
|
128
|
-
- https://raw.githubusercontent.com/RadiusNetworks/radius-spec/
|
127
|
+
- https://raw.githubusercontent.com/RadiusNetworks/radius-spec/main/common_rubocop_rails.yml
|
129
128
|
```
|
130
129
|
|
131
130
|
When using the raw URL you may need to add the following to the project's
|
132
131
|
`.gitignore` file:
|
133
132
|
|
134
133
|
```
|
135
|
-
.rubocop-https---raw-githubusercontent-com-RadiusNetworks-radius-spec-
|
136
|
-
.rubocop-https---raw-githubusercontent-com-RadiusNetworks-radius-spec-
|
134
|
+
.rubocop-https---raw-githubusercontent-com-RadiusNetworks-radius-spec-main-common-rubocop-rails-yml
|
135
|
+
.rubocop-https---raw-githubusercontent-com-RadiusNetworks-radius-spec-main-common-rubocop-yml
|
137
136
|
```
|
138
137
|
|
139
138
|
#### General Inheritance Notes
|
@@ -249,7 +248,7 @@ constant so no changes need to be made if that's your preference.
|
|
249
248
|
|
250
249
|
Attribute keys may be defined using either strings or symbols. However, they
|
251
250
|
will be stored internally as symbols. This means that when an object instance
|
252
|
-
is
|
251
|
+
is created using the factory the attribute hash will be provided to `new` with
|
253
252
|
symbol keys.
|
254
253
|
|
255
254
|
##### Dynamic Attribute Values (i.e. Generators)
|
@@ -418,26 +417,26 @@ There are a few behaviors to note for using the builder:
|
|
418
417
|
|
419
418
|
##### Optional Block
|
420
419
|
|
421
|
-
Both `build` and `
|
420
|
+
Both `build` and `build!` support providing an optional block. This block is
|
422
421
|
passed directly to `new` when creating the object. This is to support the
|
423
422
|
common Ruby idiom of yielding `self` within initialize:
|
424
423
|
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
end
|
424
|
+
```ruby
|
425
|
+
class AnyClass
|
426
|
+
def initialize(attrs = {})
|
427
|
+
# setup attrs
|
428
|
+
yield self if block_given?
|
431
429
|
end
|
430
|
+
end
|
432
431
|
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
end
|
432
|
+
RSpec.describe AnyClass, :model_factory do
|
433
|
+
it "passes the block to the object initializer" do
|
434
|
+
block_capture = nil
|
435
|
+
an_object = build("AnyClass") { |instance| block_capture = instance }
|
436
|
+
expect(block_capture).to be an_object
|
439
437
|
end
|
440
|
-
|
438
|
+
end
|
439
|
+
```
|
441
440
|
|
442
441
|
Since Ruby always supports passing a block to a method, even if the method does
|
443
442
|
not use the block, it's possible the block will not run if the class being
|
@@ -451,29 +450,328 @@ this feature.
|
|
451
450
|
|
452
451
|
We suggest that you create instances using the following syntax:
|
453
452
|
|
454
|
-
|
455
|
-
|
456
|
-
```
|
453
|
+
```ruby
|
454
|
+
let(:an_instance) { build("AnyClass") }
|
457
455
|
|
458
|
-
|
456
|
+
before do
|
457
|
+
an_instance.save!
|
458
|
+
end
|
459
|
+
```
|
459
460
|
|
460
|
-
|
461
|
-
let(:an_instance) { build("AnyClass") }
|
461
|
+
Or alternatively:
|
462
462
|
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
463
|
+
```ruby
|
464
|
+
created_instance = build("AnyClass")
|
465
|
+
created_instance.save!
|
466
|
+
```
|
467
467
|
|
468
468
|
This way it is explicit what objects need to be persisted and in what order.
|
469
469
|
|
470
|
-
|
471
|
-
|
472
|
-
|
470
|
+
This can get tedious at times, especially for those who only need to create an
|
471
|
+
object to embed as an attribute of another object:
|
472
|
+
|
473
|
+
```ruby
|
474
|
+
collaborator = build("AnotherClass")
|
475
|
+
collaborator.save!
|
476
|
+
|
477
|
+
# collaborator is not used against directly after this line
|
478
|
+
created_instance = build("AnyClass", collaborator: collaborator)
|
479
|
+
created_instance.save!
|
480
|
+
```
|
481
|
+
|
482
|
+
For these cases the `build!` helper is available. This is simply an alias for
|
483
|
+
`build.tap(&:save!)`, but it supports omitting the `save!` call for objects
|
484
|
+
which do not support it. While it provides a safety guarantee that `save!` will
|
485
|
+
be called (instead of potentially `save`) it is less explicit.
|
486
|
+
|
487
|
+
```ruby
|
488
|
+
created_instance = build("AnyClass", collaborator: build!("AnotherClass"))
|
489
|
+
created_instance.save!
|
490
|
+
```
|
491
|
+
|
492
|
+
We still discourage the use of `build!` directly in `let` blocks for all of the
|
493
|
+
above mentioned reasons.
|
494
|
+
|
495
|
+
##### Legacy "Creating" Instances
|
496
|
+
|
497
|
+
Many of our existing projects use a legacy `create` helper. This is simply an
|
498
|
+
alias for `build!`. It is provided only for backwards compatibility support and
|
499
|
+
will be removed in a future release. New code should not use this method.
|
500
|
+
|
501
|
+
```ruby
|
502
|
+
created_instance = create("AnyClass")
|
503
|
+
```
|
504
|
+
|
505
|
+
### Negated Matchers
|
506
|
+
|
507
|
+
This gem defines the following [negated matchers](https://relishapp.com/rspec/rspec-expectations/v/3-8/docs/define-negated-matcher)
|
508
|
+
to allow for use [composing matchers](https://relishapp.com/rspec/rspec-expectations/v/3-8/docs/composing-matchers)
|
509
|
+
and with [compound expectations](https://relishapp.com/rspec/rspec-expectations/v/3-8/docs/compound-expectations).
|
510
|
+
|
511
|
+
| Matcher | Inverse Of |
|
512
|
+
|-----------------------|------------|
|
513
|
+
| `exclude` | [`include`](https://relishapp.com/rspec/rspec-expectations/v/3-8/docs/built-in-matchers/include-matcher) |
|
514
|
+
| `excluding` | [`including`](https://relishapp.com/rspec/rspec-expectations/v/3-8/docs/built-in-matchers/include-matcher) |
|
515
|
+
| `not_eq` | [`eq`](https://relishapp.com/rspec/rspec-expectations/v/3-8/docs/built-in-matchers/equality-matchers#compare-using-eq-(==)) |
|
516
|
+
| `not_change` | [`change`](https://relishapp.com/rspec/rspec-expectations/v/3-8/docs/built-in-matchers/change-matcher) |
|
517
|
+
| `not_raise_error` | [`raise_error`](https://relishapp.com/rspec/rspec-expectations/v/3-8/docs/built-in-matchers/raise-error-matcher) |
|
518
|
+
| `not_raise_exception` | [`raise_exception`](https://relishapp.com/rspec/rspec-expectations/v/3-8/docs/built-in-matchers/raise-error-matcher) |
|
519
|
+
|
520
|
+
#### Composing Matchers
|
521
|
+
|
522
|
+
There is no equivalent of `not_to` for composed matchers when only a subset of
|
523
|
+
the values needs to be negated. The negated matchers allow this type of fine
|
524
|
+
grain comparison:
|
525
|
+
|
526
|
+
```ruby
|
527
|
+
x = [1, 2, :value]
|
528
|
+
expect(x).to contain_exactly(be_odd, be_even, not_eq(:target))
|
529
|
+
```
|
530
|
+
|
531
|
+
This also works for verifying / stubbing a message with argument constraints:
|
532
|
+
|
533
|
+
```ruby
|
534
|
+
allow(obj).to receive(:meth).with(1, 2, not_eq(5))
|
535
|
+
obj.meth(1, 2, 3)
|
536
|
+
expect(obj).to have_received(:meth).with(not_eq(2), 2, 3)
|
537
|
+
```
|
538
|
+
|
539
|
+
This is great for verifying option hashes:
|
540
|
+
|
541
|
+
```ruby
|
542
|
+
expect(obj).to have_received(:meth).with(
|
543
|
+
some_value,
|
544
|
+
excluding(:some_opt, :another_opt),
|
545
|
+
)
|
546
|
+
```
|
547
|
+
|
548
|
+
#### Compound Negated Matchers
|
549
|
+
|
550
|
+
Normally it's not possible to chain to a negative match:
|
551
|
+
|
552
|
+
```ruby
|
553
|
+
a = b = 0
|
554
|
+
expect {
|
555
|
+
a = 1
|
556
|
+
}.not_to change {
|
557
|
+
b
|
558
|
+
}.from(0).and change {
|
559
|
+
a
|
560
|
+
}.to(1)
|
561
|
+
```
|
562
|
+
|
563
|
+
Fails with:
|
564
|
+
|
565
|
+
NotImplementedError:
|
566
|
+
`expect(...).not_to matcher.and matcher` is not supported, since it creates
|
567
|
+
a bit of an ambiguity. Instead, define negated versions of whatever
|
568
|
+
matchers you wish to negate with `RSpec::Matchers.define_negated_matcher`
|
569
|
+
and use `expect(...).to matcher.and matcher`.
|
570
|
+
|
571
|
+
Per the error the negated matcher allows for the following:
|
572
|
+
|
573
|
+
```ruby
|
574
|
+
a = b = 0
|
575
|
+
expect {
|
576
|
+
a = 1
|
577
|
+
}.to change {
|
578
|
+
a
|
579
|
+
}.to(1).and not_change {
|
580
|
+
b
|
581
|
+
}.from(0)
|
582
|
+
```
|
583
|
+
|
584
|
+
Similarly, complex expectations can be set on lists:
|
585
|
+
|
586
|
+
```ruby
|
587
|
+
a = %i[red blue green]
|
588
|
+
expect(a).to include(:red).and exclude(:yellow)
|
589
|
+
expect(a).to exclude(:yellow).and include(:red)
|
590
|
+
```
|
591
|
+
|
592
|
+
### Working with Temp Files
|
593
|
+
|
594
|
+
These helpers are meant to ease the creation of temporary files to either stub
|
595
|
+
the data out or provide a location for data to be saved then verified.
|
596
|
+
|
597
|
+
In the case of file stubs, using these helpers allows you to co-locate the file
|
598
|
+
data with the specs. This makes it easy for someone to read the spec and
|
599
|
+
understand the test case; instead of having to find a fixture file and look at
|
600
|
+
its data. This also makes it easy to change the data between specs, allowing
|
601
|
+
them to focus on just what they need.
|
602
|
+
|
603
|
+
#### Usage
|
604
|
+
|
605
|
+
There are multiple ways you can use these helpers. Which method you choose
|
606
|
+
depends on how much perceived magic/syntactic sugar you want:
|
607
|
+
|
608
|
+
- Call the helpers directly on the module:
|
609
|
+
|
610
|
+
```ruby
|
611
|
+
require 'radius/spec/tempfile'
|
612
|
+
|
613
|
+
def write_hello_world(filepath)
|
614
|
+
File.write filepath, "Hello World"
|
615
|
+
end
|
616
|
+
|
617
|
+
Radius::Spec::Tempfile.using_tempfile do |pathname|
|
618
|
+
write_hello_world pathname
|
619
|
+
File.read(pathname)
|
620
|
+
# => "Hello World"
|
621
|
+
end
|
622
|
+
```
|
623
|
+
- Include the helper methods explicitly:
|
624
|
+
|
625
|
+
```ruby
|
626
|
+
require 'radius/spec/tempfile'
|
627
|
+
|
628
|
+
RSpec.describe AnyClass do
|
629
|
+
include Radius::Spec::Tempfile
|
630
|
+
|
631
|
+
it "includes the file helpers" do
|
632
|
+
using_tempfile do |pathname|
|
633
|
+
code_under_test pathname
|
634
|
+
expect(pathname.read).to eq "Any written data"
|
635
|
+
end
|
636
|
+
end
|
637
|
+
end
|
638
|
+
```
|
639
|
+
- Include the helper methods via metadata:
|
640
|
+
|
641
|
+
```ruby
|
642
|
+
RSpec.describe AnyClass do
|
643
|
+
it "includes the file helpers", :tempfile do
|
644
|
+
using_tempfile do |pathname|
|
645
|
+
code_under_test pathname
|
646
|
+
expect(pathname.read).to eq "Any written data"
|
647
|
+
end
|
648
|
+
end
|
649
|
+
end
|
650
|
+
```
|
651
|
+
|
652
|
+
When using this metadata option you do not need to explicitly require the
|
653
|
+
tempfile feature. This gem registers metadata with the RSpec configuration
|
654
|
+
when it loads and `RSpec` is defined. When the metadata is first used it
|
655
|
+
will automatically require the tempfile feature and include the helpers.
|
656
|
+
|
657
|
+
Any of following metadata will include the factory helpers:
|
658
|
+
|
659
|
+
- `:tempfile`
|
660
|
+
- `:tmpfile`
|
661
|
+
|
662
|
+
There are a few additional behaviors to note:
|
663
|
+
|
664
|
+
- Data can be stubbed by the helper through the `data` keyword arg:
|
665
|
+
|
666
|
+
```ruby
|
667
|
+
stub_data = "Any file stub data text."
|
668
|
+
Radius::Spec::Tempfile.using_tempfile(data: stub_data) do |stubpath|
|
669
|
+
File.read(stubpath)
|
670
|
+
# => "Any file stub data text."
|
671
|
+
end
|
672
|
+
```
|
673
|
+
|
674
|
+
It can even be inlined using heredocs:
|
675
|
+
|
676
|
+
```ruby
|
677
|
+
Radius::Spec::Tempfile.using_tempfile(data: <<~TEXT) do |stubpath|
|
678
|
+
Any file stub data text.
|
679
|
+
TEXT
|
680
|
+
# Yard formats heredoc args oddly
|
681
|
+
File.read(stubpath)
|
682
|
+
# => "Any file stub data text.\n"
|
683
|
+
end
|
684
|
+
```
|
685
|
+
|
686
|
+
> NOTE: That when inlining like this heredocs add an extra new line. To
|
687
|
+
> remove it use `.chomp` on the kwarg:
|
688
|
+
>
|
689
|
+
> ```ruby
|
690
|
+
> using_tempfile(data: <<~TEXT.chomp) do |pathname|
|
691
|
+
> This has no newline.
|
692
|
+
> TEXT
|
693
|
+
> # ...
|
694
|
+
> end
|
695
|
+
> ```
|
696
|
+
|
697
|
+
- Additional arguments and options are forwarded directly to
|
698
|
+
[Tempfile.create](https://ruby-doc.org/stdlib/libdoc/tempfile/rdoc/Tempfile.html#method-c-create)
|
699
|
+
|
700
|
+
This allows you to set custom file extensions:
|
701
|
+
|
702
|
+
```ruby
|
703
|
+
Radius::Spec::Tempfile.using_tempfile(%w[custom_name .myext]) do |pathname|
|
704
|
+
pathname.extname
|
705
|
+
# => ".myext"
|
706
|
+
end
|
707
|
+
```
|
708
|
+
|
709
|
+
Or change the file encoding:
|
710
|
+
|
711
|
+
```ruby
|
712
|
+
Radius::Spec::Tempfile.using_tempfile(encoding: "ISO-8859-1", data: <<~DATA) do |pathname|
|
713
|
+
Résumé
|
714
|
+
DATA
|
715
|
+
# Yard formats heredoc args oddly
|
716
|
+
File.read(pathname)
|
717
|
+
# => "R\xE9sum\xE9\n"
|
718
|
+
end
|
719
|
+
```
|
720
|
+
|
721
|
+
### Common VCR Configuration
|
722
|
+
|
723
|
+
A project must include both [`vcr`](https://rubygems.org/gems/vcr) and
|
724
|
+
[`webmock`](https://rubygems.org/gems/webmock) to use this configuration.
|
725
|
+
Neither of those gems will be installed as dependencies of this gem. This is
|
726
|
+
intended to give projects more flexibility in choosing which additional features
|
727
|
+
they will use.
|
728
|
+
|
729
|
+
The main `radius/spec/rspec` setup will load the common VCR configuration
|
730
|
+
automatically when a spec is tagged with the `:vcr` metadata. This will
|
731
|
+
configure VCR to:
|
732
|
+
|
733
|
+
- save specs to `/spec/cassettes`
|
734
|
+
|
735
|
+
- use record mode `once` when a single spec or spec file is run
|
736
|
+
|
737
|
+
This helps ease the development of new specs without requiring any
|
738
|
+
configuration / setting changes.
|
739
|
+
|
740
|
+
- uses record mode `none` otherwise, along setting VCR to fail when unused
|
741
|
+
interactions remain in a cassette
|
742
|
+
|
743
|
+
This is intended to better alert developers to unexpected side effects of
|
744
|
+
changes as any addition or removal of a request will cause a failure.
|
745
|
+
|
746
|
+
- all `Authorization` HTTP headers are filtered by default
|
747
|
+
|
748
|
+
This is a common oversight when recording specs. Often token based
|
749
|
+
authentication is picked up by the other filtered environment settings, but
|
750
|
+
basic authentication is not. Additionally, certain types of digest
|
751
|
+
authentication may cause specs to leak state. This filtering guards all of
|
752
|
+
these cases from accidental credential leak.
|
753
|
+
|
754
|
+
- the following common sensitive, or often environment variable, settings are
|
755
|
+
filtered
|
756
|
+
|
757
|
+
Those settings which often change between developer machines, and even the
|
758
|
+
CI server, can cause for flaky specs. It may also be frustrating for
|
759
|
+
developers to have to adjust their local systems to match others just to
|
760
|
+
get a few specs to pass. This is intended to help mitigate those issues:
|
761
|
+
|
762
|
+
- `AWS_ACCESS_KEY_ID`
|
763
|
+
- `AWS_SECRET_ACCESS_KEY`
|
764
|
+
- `GOOGLE_CLIENT_ID`
|
765
|
+
- `GOOGLE_CLIENT_SECRET`
|
766
|
+
- `RADIUS_OAUTH_PROVIDER_APP_ID`
|
767
|
+
- `RADIUS_OAUTH_PROVIDER_APP_SECRET`
|
768
|
+
- `RADIUS_OAUTH_PROVIDER_URL`
|
769
|
+
|
770
|
+
- a project's local `support/vcr.rb` file will be loaded after the common
|
771
|
+
VCR configuration loads; if it's available
|
473
772
|
|
474
|
-
|
475
|
-
|
476
|
-
```
|
773
|
+
This allows projects to overwrite common settings if they need to, as well,
|
774
|
+
as add on addition settings or filtering of data.
|
477
775
|
|
478
776
|
## Development
|
479
777
|
|
@@ -499,4 +797,4 @@ conduct.
|
|
499
797
|
|
500
798
|
Everyone interacting in the Radius::Spec project’s codebases, issue trackers,
|
501
799
|
chat rooms and mailing lists is expected to follow the [code of
|
502
|
-
conduct](https://github.com/RadiusNetworks/radius-spec/blob/
|
800
|
+
conduct](https://github.com/RadiusNetworks/radius-spec/blob/main/CODE_OF_CONDUCT.md).
|