radius-spec 0.4.0 → 0.8.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 +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
|
-
[](https://travis-ci.org/RadiusNetworks/radius-spec)
|
4
3
|
[](https://codeclimate.com/github/RadiusNetworks/radius-spec/maintainability)
|
5
4
|
[](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).
|