radius-spec 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardopts +1 -0
- data/CHANGELOG.md +42 -1
- data/Gemfile +1 -1
- data/README.md +330 -31
- data/benchmarks/bm_setup.rb +1 -0
- data/common_rubocop.yml +23 -3
- data/common_rubocop_rails.yml +60 -1
- data/lib/radius/spec/model_factory.rb +35 -22
- data/lib/radius/spec/rails.rb +1 -1
- 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 -1
- metadata +9 -7
- 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: 229205333f0d39f679032b076188c7a18013408c034486de29c4f4a684ddcf74
|
4
|
+
data.tar.gz: 37aa800e6bfdb5b273de8837cbe62f87ca8f4f6b3a93bce091b7bbe6867cd64e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a0dde94d3cb6579e8faf68027cf1f77c1d8268d4d7c1979b05c5554e4e000769e2b6240f398d396558d0c71c2c717ead0062c5f236d4d03a49981fa91c8a95ca
|
7
|
+
data.tar.gz: 027ef0ac9fcbc76dbaa374382035829e7607c4d3dc2979f2bbc8413b7cbd032961760ed798ac1bda7b83fba9899127c82c96743e8d716fca50f2fb93e01bb0bd
|
data/.yardopts
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,44 @@
|
|
1
|
+
## 0.5.0 (September 26, 2018)
|
2
|
+
|
3
|
+
[Full Changelog](https://github.com/RadiusNetworks/radius-spec/compare/v0.4.0...v0.5.0)
|
4
|
+
|
5
|
+
### Enhancements
|
6
|
+
|
7
|
+
- Add common VCR configuration (Aaron Kromer, #16)
|
8
|
+
- Filters out `Authorization` headers
|
9
|
+
- Filters out the following sensitive/environment varying `ENV` values, as
|
10
|
+
well as their URL and form encoded variants:
|
11
|
+
- `AWS_ACCESS_KEY_ID`
|
12
|
+
- `AWS_SECRET_ACCESS_KEY`
|
13
|
+
- `GOOGLE_CLIENT_ID`
|
14
|
+
- `GOOGLE_CLIENT_SECRET`
|
15
|
+
- `RADIUS_OAUTH_PROVIDER_APP_ID`
|
16
|
+
- `RADIUS_OAUTH_PROVIDER_APP_SECRET`
|
17
|
+
- `RADIUS_OAUTH_PROVIDER_URL`
|
18
|
+
- Add "temp file" helpers for working with file stubs (Aaron Kromer, #15)
|
19
|
+
- Upgrade to Rubocop 0.59.x (Aaron Kromer, #14)
|
20
|
+
- Adjust common Rubocop configuration (Aaron Kromer, #14)
|
21
|
+
- `Layout/EmptyLineAfterGuardClause` is enabled by default
|
22
|
+
- Enable `Rails/SaveBang` to highlight potential lurking issues
|
23
|
+
- Expand `Rails/FindBy` and `Rails/FindEach` to check all `/app` and `/lib`
|
24
|
+
- Add more functional methods
|
25
|
+
- `default_scope`
|
26
|
+
- `filter_sensitive_data`
|
27
|
+
- Add `build!` factory method to compliment `build` to help resolving Rubocop
|
28
|
+
violations for `Rails/SaveBang` (Aaron Kromer, #14)
|
29
|
+
- Load model factory for specs tagged with 'type: :mailer' (Aaron Kromer, #11)
|
30
|
+
- Include the following negated RSpec matchers (Aaron Kromer, #12)
|
31
|
+
- `exclude` / `excluding`
|
32
|
+
- `not_eq`
|
33
|
+
- `not_change`
|
34
|
+
- `not_raise_error` / `not_raise_exception`
|
35
|
+
|
36
|
+
### Bug Fixes
|
37
|
+
|
38
|
+
- Fix `NoMethodError: undefined method 'strip'` when the fixture path is a
|
39
|
+
`Pathname` object (Aaron Kromer, #13)
|
40
|
+
|
41
|
+
|
1
42
|
## 0.4.0 (July 10, 2018)
|
2
43
|
|
3
44
|
[Full Changelog](https://github.com/RadiusNetworks/radius-spec/compare/v0.3.0...v0.4.0)
|
@@ -88,7 +129,7 @@
|
|
88
129
|
|
89
130
|
### Bug Fixes
|
90
131
|
|
91
|
-
- Fix `NameError: undefined local variable or method
|
132
|
+
- Fix `NameError: undefined local variable or method config` for Rails RSpec
|
92
133
|
configuration (Aaron Kromer, #1)
|
93
134
|
- Fix model factory build issue in which registered template attributes, which
|
94
135
|
use symbol keys, are not replaced by custom attributes using string keys
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -249,7 +249,7 @@ constant so no changes need to be made if that's your preference.
|
|
249
249
|
|
250
250
|
Attribute keys may be defined using either strings or symbols. However, they
|
251
251
|
will be stored internally as symbols. This means that when an object instance
|
252
|
-
is
|
252
|
+
is created using the factory the attribute hash will be provided to `new` with
|
253
253
|
symbol keys.
|
254
254
|
|
255
255
|
##### Dynamic Attribute Values (i.e. Generators)
|
@@ -418,26 +418,26 @@ There are a few behaviors to note for using the builder:
|
|
418
418
|
|
419
419
|
##### Optional Block
|
420
420
|
|
421
|
-
Both `build` and `
|
421
|
+
Both `build` and `build!` support providing an optional block. This block is
|
422
422
|
passed directly to `new` when creating the object. This is to support the
|
423
423
|
common Ruby idiom of yielding `self` within initialize:
|
424
424
|
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
end
|
425
|
+
```ruby
|
426
|
+
class AnyClass
|
427
|
+
def initialize(attrs = {})
|
428
|
+
# setup attrs
|
429
|
+
yield self if block_given?
|
431
430
|
end
|
431
|
+
end
|
432
432
|
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
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
|
439
438
|
end
|
440
|
-
|
439
|
+
end
|
440
|
+
```
|
441
441
|
|
442
442
|
Since Ruby always supports passing a block to a method, even if the method does
|
443
443
|
not use the block, it's possible the block will not run if the class being
|
@@ -451,29 +451,328 @@ this feature.
|
|
451
451
|
|
452
452
|
We suggest that you create instances using the following syntax:
|
453
453
|
|
454
|
-
|
455
|
-
|
456
|
-
```
|
454
|
+
```ruby
|
455
|
+
let(:an_instance) { build("AnyClass") }
|
457
456
|
|
458
|
-
|
457
|
+
before do
|
458
|
+
an_instance.save!
|
459
|
+
end
|
460
|
+
```
|
459
461
|
|
460
|
-
|
461
|
-
let(:an_instance) { build("AnyClass") }
|
462
|
+
Or alternatively:
|
462
463
|
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
464
|
+
```ruby
|
465
|
+
created_instance = build("AnyClass")
|
466
|
+
created_instance.save!
|
467
|
+
```
|
467
468
|
|
468
469
|
This way it is explicit what objects need to be persisted and in what order.
|
469
470
|
|
470
|
-
|
471
|
-
|
472
|
-
|
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
|
473
773
|
|
474
|
-
|
475
|
-
|
476
|
-
```
|
774
|
+
This allows projects to overwrite common settings if they need to, as well,
|
775
|
+
as add on addition settings or filtering of data.
|
477
776
|
|
478
777
|
## Development
|
479
778
|
|
data/benchmarks/bm_setup.rb
CHANGED
data/common_rubocop.yml
CHANGED
@@ -106,6 +106,10 @@ Metrics/BlockLength:
|
|
106
106
|
- 'spec/spec_helper.rb'
|
107
107
|
- 'spec/**/*_spec.rb'
|
108
108
|
- 'spec/support/model_factories.rb'
|
109
|
+
ExcludedMethods:
|
110
|
+
- 'refine'
|
111
|
+
- 'RSpec.configure'
|
112
|
+
- 'VCR.configure'
|
109
113
|
|
110
114
|
# We generally prefer to use the default line length of 80. Though sometimes
|
111
115
|
# we just need a little extra space because it makes it easier to read.
|
@@ -266,7 +270,9 @@ Style/BlockDelimiters:
|
|
266
270
|
- create!
|
267
271
|
- build
|
268
272
|
- build!
|
273
|
+
- default_scope
|
269
274
|
- each_with_object
|
275
|
+
- filter_sensitive_data
|
270
276
|
- find
|
271
277
|
- git_source
|
272
278
|
- let
|
@@ -280,6 +286,19 @@ Style/BlockDelimiters:
|
|
280
286
|
- proc
|
281
287
|
- it
|
282
288
|
|
289
|
+
# Prefer `Time` over `DateTime`.
|
290
|
+
#
|
291
|
+
# While these are not necessarily interchangeable we prefer `Time`. According
|
292
|
+
# to the Ruby docs `DateTime` is meant more for historical dates; it also does
|
293
|
+
# not consider leap seconds or summer time rules.
|
294
|
+
#
|
295
|
+
# Lastly, `DateTime` is part of the stdlib which is written in Ruby; where as
|
296
|
+
# `Time` is part of core and written in C.
|
297
|
+
#
|
298
|
+
# Configuration parameters: AllowCoercion
|
299
|
+
Style/DateTime:
|
300
|
+
Enabled: true
|
301
|
+
|
283
302
|
# The double negation idiom is a common Ruby-ism. All languages have various
|
284
303
|
# idioms and part of learning the language is learning the common idioms. Once
|
285
304
|
# learning the meaning it is not cryptic as Rubocop implies.
|
@@ -391,9 +410,10 @@ Style/MethodCalledOnDoEndBlock:
|
|
391
410
|
Style/MultilineBlockChain:
|
392
411
|
Enabled: false
|
393
412
|
|
394
|
-
# Context for this cop is too dependent.
|
395
|
-
#
|
396
|
-
# comparison is
|
413
|
+
# Context for this cop is too dependent.
|
414
|
+
#
|
415
|
+
# Often using the numeric comparison is faster. Also, depending on the context
|
416
|
+
# a numeric comparison may produce a more consistent style:
|
397
417
|
#
|
398
418
|
# # numeric comparison is more natural and consistent
|
399
419
|
# if n < 0
|
data/common_rubocop_rails.yml
CHANGED
@@ -106,6 +106,34 @@ Rails/ApplicationRecord:
|
|
106
106
|
Rails/CreateTableWithTimestamps:
|
107
107
|
Enabled: false
|
108
108
|
|
109
|
+
# Usage of `find_by` is more expressive of intent than `where.first`. We should
|
110
|
+
# check all app code, not just the models to improve intent expression.
|
111
|
+
#
|
112
|
+
# Since rake tasks often live in `lib` we also check all of lib as well.
|
113
|
+
#
|
114
|
+
# Configuration parameters: Include.
|
115
|
+
# Include: app/models/**/*.rb
|
116
|
+
Rails/FindBy:
|
117
|
+
Enabled: true
|
118
|
+
Include:
|
119
|
+
- 'app/**/*.rb'
|
120
|
+
- 'lib/**/*.rb'
|
121
|
+
|
122
|
+
# Usage of `each` for large datasets can be a performance issue; specially a
|
123
|
+
# drain on system memory. When possible it's better to use `find_each` so that
|
124
|
+
# chunks of data are evaluated at a time.
|
125
|
+
#
|
126
|
+
# We should check all app code, not just the models to help prevent this. Since
|
127
|
+
# rake tasks often live in `lib` we also check all of lib as well.
|
128
|
+
#
|
129
|
+
# Configuration parameters: Include.
|
130
|
+
# Include: app/models/**/*.rb
|
131
|
+
Rails/FindEach:
|
132
|
+
Enabled: true
|
133
|
+
Include:
|
134
|
+
- 'app/**/*.rb'
|
135
|
+
- 'lib/**/*.rb'
|
136
|
+
|
109
137
|
# We understand the trade-offs for using the through model versus a lookup
|
110
138
|
# table. As such this cop is just noise as it flags only those cases we really
|
111
139
|
# do want a lookup table.
|
@@ -122,7 +150,7 @@ Rails/HasAndBelongsToMany:
|
|
122
150
|
# For most of us `unless blank?` reads just as easily as `if present?`.
|
123
151
|
# Sometimes contextually, it can read better depending on the branch logic and
|
124
152
|
# surrounding context. As `if present?` requires an additional negation and
|
125
|
-
# method call it is technically slower. In the general case the perf
|
153
|
+
# method call it is technically slower. In the general case the perf difference
|
126
154
|
# isn't much but in some cases it matters. Thus, we are not enforcing changing
|
127
155
|
# `unless blank?` to `if present?` and are leaving it up to the context to
|
128
156
|
# decide which is a better fit.
|
@@ -144,6 +172,37 @@ Rails/Present:
|
|
144
172
|
Rails/ReadWriteAttribute:
|
145
173
|
Enabled: false
|
146
174
|
|
175
|
+
# This ensures we do not ignore potential validation issues in the code. Doing
|
176
|
+
# so can lead to strange and surprising bugs where records are expected to
|
177
|
+
# be created, or be modified, but are not.
|
178
|
+
#
|
179
|
+
# # If author is a new record the book may not be created since the FK is
|
180
|
+
# # invalid. Perhaps omitting other fields, maybe new required fields, is
|
181
|
+
# # an oversight in the book creation as well.
|
182
|
+
# author.save
|
183
|
+
# Book.create(author: author)
|
184
|
+
#
|
185
|
+
# Or side effects are expected to occur but they do not:
|
186
|
+
#
|
187
|
+
# # This is a condensed default Rails scaffold controller for `destroy`.
|
188
|
+
# #
|
189
|
+
# # Once a `has_many` or `has_one` associations is added which specifies
|
190
|
+
# # `dependent: :restrict_with_error` this no longer behaves as expected.
|
191
|
+
# # Given such associations are often added much later in time errors in
|
192
|
+
# # this action are an all to common oversight in Rails.
|
193
|
+
# def destroy
|
194
|
+
# @book.destroy
|
195
|
+
# respond_to do |format|
|
196
|
+
# format.html do
|
197
|
+
# redirect_to books_url, notice: 'Book was successfully destroyed.'
|
198
|
+
# end
|
199
|
+
# end
|
200
|
+
# end
|
201
|
+
#
|
202
|
+
# Configuration parameters: AllowImplicitReturn, AllowedReceivers.
|
203
|
+
Rails/SaveBang:
|
204
|
+
Enabled: true
|
205
|
+
|
147
206
|
# According to the Rails docs while the following methods skip validations they
|
148
207
|
# only update the specified (single) attribute reducing risks. We'd rather not
|
149
208
|
# warn for those cases:
|
@@ -268,6 +268,7 @@ module Radius
|
|
268
268
|
def safe_transform(value)
|
269
269
|
return value.call if value.is_a?(Proc)
|
270
270
|
return value if value.frozen?
|
271
|
+
|
271
272
|
value.dup
|
272
273
|
end
|
273
274
|
|
@@ -426,44 +427,56 @@ module Radius
|
|
426
427
|
|
427
428
|
# Convenience wrapper for building, and persisting, a model template.
|
428
429
|
#
|
429
|
-
# This is a thin wrapper around
|
430
|
-
# persistence message `save!` will only be called on objects which
|
431
|
-
# respond to it.
|
432
|
-
#
|
433
|
-
# ### Avoid for New Code
|
430
|
+
# This is a thin wrapper around:
|
434
431
|
#
|
435
|
-
#
|
436
|
-
#
|
437
|
-
#
|
432
|
+
# ```ruby
|
433
|
+
# build(name, attrs, &block).tap(&:save!)
|
434
|
+
# ```
|
438
435
|
#
|
439
|
-
#
|
440
|
-
#
|
436
|
+
# The persistence message `save!` will only be called on objects which
|
437
|
+
# respond to it.
|
441
438
|
#
|
442
|
-
#
|
443
|
-
#
|
439
|
+
# @note It is generally suggested that you avoid using `build!` for new
|
440
|
+
# code. Instead be explicit about when and how objects are persisted.
|
441
|
+
# This allows you to have fine grain control over how your data is
|
442
|
+
# setup.
|
444
443
|
#
|
445
|
-
#
|
446
|
-
#
|
447
|
-
# end
|
448
|
-
# ```
|
444
|
+
# We suggest that you create instances which need to be persisted
|
445
|
+
# before your specs using the following syntax:
|
449
446
|
#
|
450
|
-
#
|
451
|
-
#
|
447
|
+
# ```ruby
|
448
|
+
# let(:an_instance) { build("AnyClass") }
|
452
449
|
#
|
453
|
-
#
|
454
|
-
#
|
455
|
-
#
|
450
|
+
# before do
|
451
|
+
# an_instance.save!
|
452
|
+
# end
|
453
|
+
# ```
|
456
454
|
#
|
457
455
|
# @param (see .build)
|
458
456
|
# @return (see .build)
|
459
457
|
# @raise (see .build)
|
460
458
|
# @see .build
|
461
459
|
# @see .define_factory
|
462
|
-
|
460
|
+
# @since 0.5.0
|
461
|
+
def build!(name, custom_attrs = {}, &block)
|
463
462
|
instance = build(name, custom_attrs, &block)
|
464
463
|
instance.save! if instance.respond_to?(:save!)
|
465
464
|
instance
|
466
465
|
end
|
466
|
+
|
467
|
+
# Legacy helper provided for backwards compatibility support.
|
468
|
+
#
|
469
|
+
# This provides the same behavior as {.build!} and will be removed in a
|
470
|
+
# future release.
|
471
|
+
#
|
472
|
+
# @param (see .build)
|
473
|
+
# @return (see .build)
|
474
|
+
# @raise (see .build)
|
475
|
+
# @see .build
|
476
|
+
# @see .define_factory
|
477
|
+
def create(name, custom_attrs = {}, &block)
|
478
|
+
build!(name, custom_attrs, &block)
|
479
|
+
end
|
467
480
|
end
|
468
481
|
end
|
469
482
|
end
|
data/lib/radius/spec/rails.rb
CHANGED
@@ -7,7 +7,7 @@ require 'rspec/rails'
|
|
7
7
|
|
8
8
|
RSpec.configure do |config|
|
9
9
|
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
|
10
|
-
config.fixture_path = ::Rails.root.join("spec", "fixtures")
|
10
|
+
config.fixture_path = ::Rails.root.join("spec", "fixtures").to_path
|
11
11
|
|
12
12
|
# If you're not using ActiveRecord, or you'd prefer not to run each of your
|
13
13
|
# examples within a transaction, remove the following line or assign false
|
data/lib/radius/spec/rspec.rb
CHANGED
@@ -109,6 +109,11 @@ RSpec.configure do |config|
|
|
109
109
|
config.include Radius::Spec::ModelFactory, :model_factory, :model_factories
|
110
110
|
end
|
111
111
|
|
112
|
+
config.when_first_matching_example_defined(:tempfile, :tmpfile) do
|
113
|
+
require 'radius/spec/tempfile'
|
114
|
+
config.include Radius::Spec::Tempfile, :tempfile, :tmpfile
|
115
|
+
end
|
116
|
+
|
112
117
|
config.when_first_matching_example_defined(type: :controller) do
|
113
118
|
require 'radius/spec/model_factory'
|
114
119
|
config.include Radius::Spec::ModelFactory, type: :controller
|
@@ -124,6 +129,11 @@ RSpec.configure do |config|
|
|
124
129
|
config.include Radius::Spec::ModelFactory, type: :job
|
125
130
|
end
|
126
131
|
|
132
|
+
config.when_first_matching_example_defined(type: :mailer) do
|
133
|
+
require 'radius/spec/model_factory'
|
134
|
+
config.include Radius::Spec::ModelFactory, type: :mailer
|
135
|
+
end
|
136
|
+
|
127
137
|
config.when_first_matching_example_defined(type: :model) do
|
128
138
|
require 'radius/spec/model_factory'
|
129
139
|
config.include Radius::Spec::ModelFactory, type: :model
|
@@ -138,4 +148,14 @@ RSpec.configure do |config|
|
|
138
148
|
require 'radius/spec/model_factory'
|
139
149
|
config.include Radius::Spec::ModelFactory, type: :system
|
140
150
|
end
|
151
|
+
|
152
|
+
config.when_first_matching_example_defined(:webmock) do
|
153
|
+
require 'webmock/rspec'
|
154
|
+
end
|
155
|
+
|
156
|
+
config.when_first_matching_example_defined(:vcr, :vcr_record, :vcr_record_new) do
|
157
|
+
require 'radius/spec/vcr'
|
158
|
+
end
|
141
159
|
end
|
160
|
+
|
161
|
+
require 'radius/spec/rspec/negated_matchers'
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Define negated matchers for use with composable matchers and compound
|
4
|
+
# expectations.
|
5
|
+
#
|
6
|
+
# @see https://relishapp.com/rspec/rspec-expectations/v/3-8/docs/composing-matchers
|
7
|
+
# @see https://relishapp.com/rspec/rspec-expectations/v/3-8/docs/compound-expectations
|
8
|
+
RSpec::Matchers.define_negated_matcher :exclude, :include
|
9
|
+
RSpec::Matchers.define_negated_matcher :excluding, :including
|
10
|
+
RSpec::Matchers.define_negated_matcher :not_eq, :eq
|
11
|
+
|
12
|
+
# Allows us to check that a block doesn't raise an exception while also
|
13
|
+
# checking for other changes using compound expectations; since you can't chain
|
14
|
+
# a negative (`not_to`) with any other matchers
|
15
|
+
#
|
16
|
+
# @see https://relishapp.com/rspec/rspec-expectations/v/3-8/docs/compound-expectations
|
17
|
+
RSpec::Matchers.define_negated_matcher :not_change, :change
|
18
|
+
RSpec::Matchers.define_negated_matcher :not_raise_error, :raise_error
|
19
|
+
RSpec::Matchers.define_negated_matcher :not_raise_exception, :raise_exception
|
@@ -0,0 +1,162 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'pathname'
|
4
|
+
require 'tempfile'
|
5
|
+
|
6
|
+
module Radius
|
7
|
+
module Spec
|
8
|
+
# Temporary file helpers
|
9
|
+
#
|
10
|
+
# These helpers are meant to ease the creation of temporary files to either
|
11
|
+
# stub the data out or provide a location for data to be saved then
|
12
|
+
# verified.
|
13
|
+
#
|
14
|
+
# In the case of file stubs, using these helpers allows you to co-locate
|
15
|
+
# the file data with the specs. This makes it easy for someone to read the
|
16
|
+
# spec and understand the test case; instead of having to find a fixture
|
17
|
+
# file and look at its data. This also makes it easy to change the data
|
18
|
+
# between specs, allowing them to focus on just what they need.
|
19
|
+
#
|
20
|
+
# To make these helpers available require them after the gem:
|
21
|
+
#
|
22
|
+
# ```ruby
|
23
|
+
# require 'radius/spec'
|
24
|
+
# require 'radius/spec/tempfile'
|
25
|
+
# ```
|
26
|
+
#
|
27
|
+
# ### Including Helpers in Specs
|
28
|
+
#
|
29
|
+
# There are multiple ways you can use these helpers. Which method you
|
30
|
+
# choose depends on how much perceived magic/syntactic sugar you want:
|
31
|
+
#
|
32
|
+
# - call the helpers directly on the module
|
33
|
+
# - manually include the helper methods in the specs
|
34
|
+
# - use metadata to auto load this feature and include it in the specs
|
35
|
+
#
|
36
|
+
# When using the metadata option you do not need to explicitly require the
|
37
|
+
# module. This gem registers metadata with the RSpec configuration when it
|
38
|
+
# loads and `RSpec` is defined. When the matching metadata is first used it
|
39
|
+
# will automatically require and include the helpers.
|
40
|
+
#
|
41
|
+
# Any of following metadata will include the factory helpers:
|
42
|
+
#
|
43
|
+
# - `:tempfile`
|
44
|
+
# - `:tmpfile`
|
45
|
+
#
|
46
|
+
# @example use a helper directly in specs
|
47
|
+
# require 'radius/spec/tempfile'
|
48
|
+
#
|
49
|
+
# RSpec.describe AnyClass do
|
50
|
+
# it "includes the file helpers" do
|
51
|
+
# Radius::Spec::Tempfile.using_tempfile do |pathname|
|
52
|
+
# code_under_test pathname
|
53
|
+
# expect(pathname.read).to eq "Any written data"
|
54
|
+
# end
|
55
|
+
# end
|
56
|
+
# end
|
57
|
+
# @example manually include the helpers
|
58
|
+
# require 'radius/spec/tempfile'
|
59
|
+
#
|
60
|
+
# RSpec.describe AnyClass do
|
61
|
+
# include Radius::Spec::Tempfile
|
62
|
+
# it "includes the file helpers" do
|
63
|
+
# using_tempfile do |pathname|
|
64
|
+
# code_under_test pathname
|
65
|
+
# expect(pathname.read).to eq "Any written data"
|
66
|
+
# end
|
67
|
+
# end
|
68
|
+
# end
|
69
|
+
# @example use metadata to auto include the helpers
|
70
|
+
# RSpec.describe AnyClass do
|
71
|
+
# it "includes the file helpers", :tempfile do
|
72
|
+
# using_tempfile do |pathname|
|
73
|
+
# code_under_test pathname
|
74
|
+
# expect(pathname.read).to eq "Any written data"
|
75
|
+
# end
|
76
|
+
# end
|
77
|
+
# end
|
78
|
+
# @since 0.5.0
|
79
|
+
module Tempfile
|
80
|
+
module_function
|
81
|
+
|
82
|
+
# Convenience wrapper for managaing temporary files.
|
83
|
+
#
|
84
|
+
# This creates a temporary file and yields its path to the provided
|
85
|
+
# block. When the block returns the temporary file is deleted.
|
86
|
+
#
|
87
|
+
# ### Optional Parameters
|
88
|
+
#
|
89
|
+
# The block is required. All other parameters are optional. All
|
90
|
+
# parameters except `data` are Ruby version dependent and will be
|
91
|
+
# forwarded directly to the stdlib's
|
92
|
+
# {https://ruby-doc.org/stdlib/libdoc/tempfile/rdoc/Tempfile.html#method-c-create
|
93
|
+
# `Tempfile.create`}. The when the `data` parameter is provided it's
|
94
|
+
# contents will be written to the temporary file prior to yielding to the
|
95
|
+
# block.
|
96
|
+
#
|
97
|
+
# @example creating a tempfile to pass to code
|
98
|
+
# def write_hello_world(filepath)
|
99
|
+
# File.write filepath, "Hello World"
|
100
|
+
# end
|
101
|
+
#
|
102
|
+
# Radius::Spec::Tempfile.using_tempfile do |pathname|
|
103
|
+
# write_hello_world pathname
|
104
|
+
# end
|
105
|
+
# @example creating a file stub
|
106
|
+
# stub_data = "Any file stub data text."
|
107
|
+
# Radius::Spec::Tempfile.using_tempfile(data: stub_data) do |stubpath|
|
108
|
+
# # File.read(stubpath)
|
109
|
+
# # => "Any file stub data text."
|
110
|
+
# code_under_test stubpath
|
111
|
+
# end
|
112
|
+
# @example creating a file stub inline
|
113
|
+
# Radius::Spec::Tempfile.using_tempfile(data: <<~TEXT) do |stubpath|
|
114
|
+
# Any file stub data text.
|
115
|
+
# TEXT
|
116
|
+
# # File.read(stubpath)
|
117
|
+
# # => "Any file stub data text.\n"
|
118
|
+
# code_under_test stubpath
|
119
|
+
# end
|
120
|
+
# @example creating a file stub inline without trailing newline
|
121
|
+
# Radius::Spec::Tempfile.using_tempfile(data: <<~TEXT.chomp) do |stubpath|
|
122
|
+
# Any file stub data text.
|
123
|
+
# TEXT
|
124
|
+
# # File.read(stubpath)
|
125
|
+
# # => "Any file stub data text."
|
126
|
+
# code_under_test stubpath
|
127
|
+
# end
|
128
|
+
# @example writing binary data inline
|
129
|
+
# Radius::Spec::Tempfile.using_tempfile(encoding: Encoding::BINARY, data: <<~BIN.chomp) do |binpath|
|
130
|
+
# \xC8\x90\xC5\x9D\xE1\xB9\x95\xC4\x93\xC4\x89
|
131
|
+
# BIN
|
132
|
+
# # File.read(binpath)
|
133
|
+
# # => "Ȑŝṕēĉ"
|
134
|
+
# code_under_test binpath
|
135
|
+
# end
|
136
|
+
# @param args [Object] addition file creation options
|
137
|
+
#
|
138
|
+
# Passed directly to {https://ruby-doc.org/stdlib/libdoc/tempfile/rdoc/Tempfile.html#method-c-create
|
139
|
+
# `Tempfile.create`}; see the stdlib docs for details on available
|
140
|
+
# options.
|
141
|
+
# @param data [String] stub data to write to the file before yielding
|
142
|
+
# @param kwargs [Hash{Symbol => Object}] addition file creation options
|
143
|
+
#
|
144
|
+
# Passed directly to {https://ruby-doc.org/stdlib/libdoc/tempfile/rdoc/Tempfile.html#method-c-create
|
145
|
+
# `Tempfile.create`}; see the stdlib docs for details on available
|
146
|
+
# options.
|
147
|
+
# @yieldparam pathname [Pathname] {https://ruby-doc.org/stdlib/libdoc/pathname/rdoc/Pathname.html path}
|
148
|
+
# of the created temporary file
|
149
|
+
# @note A block must be provided
|
150
|
+
# @see https://ruby-doc.org/stdlib/libdoc/pathname/rdoc/Pathname.html Pathname
|
151
|
+
# @see https://ruby-doc.org/stdlib/libdoc/tempfile/rdoc/Tempfile.html Tempfile
|
152
|
+
def using_tempfile(*args, data: nil, **kwargs)
|
153
|
+
args << 'tmpfile' if args.empty?
|
154
|
+
::Tempfile.create(*args, **kwargs) do |f|
|
155
|
+
f.write(data)
|
156
|
+
f.close
|
157
|
+
yield Pathname(f.path)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'webmock/rspec'
|
4
|
+
require 'vcr'
|
5
|
+
|
6
|
+
VCR.configure do |config|
|
7
|
+
config.cassette_library_dir = "spec/cassettes"
|
8
|
+
config.hook_into :webmock
|
9
|
+
config.configure_rspec_metadata!
|
10
|
+
config.ignore_localhost = true
|
11
|
+
|
12
|
+
record_mode = case
|
13
|
+
when RSpec.configuration.files_to_run.one?
|
14
|
+
# When developing new features we often run new specs in
|
15
|
+
# isolation as we write the code. This is the time to allow
|
16
|
+
# creating the cassettes.
|
17
|
+
:once
|
18
|
+
when ENV['CI']
|
19
|
+
# Never let CI record
|
20
|
+
:none
|
21
|
+
else
|
22
|
+
# Default to blocking new requests to catch issues
|
23
|
+
:none
|
24
|
+
end
|
25
|
+
config.default_cassette_options = {
|
26
|
+
record: record_mode,
|
27
|
+
|
28
|
+
# Required for working proxy
|
29
|
+
update_content_length_header: true,
|
30
|
+
|
31
|
+
# Raise errors when recorded cassettes no longer match interactions
|
32
|
+
allow_unused_http_interactions: false,
|
33
|
+
}
|
34
|
+
|
35
|
+
# Filter out common sensitive or environment specific data
|
36
|
+
%w[
|
37
|
+
AWS_ACCESS_KEY_ID
|
38
|
+
AWS_SECRET_ACCESS_KEY
|
39
|
+
GOOGLE_CLIENT_ID
|
40
|
+
GOOGLE_CLIENT_SECRET
|
41
|
+
RADIUS_OAUTH_PROVIDER_APP_ID
|
42
|
+
RADIUS_OAUTH_PROVIDER_APP_SECRET
|
43
|
+
RADIUS_OAUTH_PROVIDER_URL
|
44
|
+
].each do |secret|
|
45
|
+
config.filter_sensitive_data("<#{secret}>") { ENV[secret] }
|
46
|
+
|
47
|
+
config.filter_sensitive_data("<#{secret}_FORM>") {
|
48
|
+
URI.encode_www_form_component(ENV[secret]) if ENV[secret]
|
49
|
+
}
|
50
|
+
|
51
|
+
config.filter_sensitive_data("<#{secret}_URI>") {
|
52
|
+
ERB::Util.url_encode(ENV[secret]) if ENV[secret]
|
53
|
+
}
|
54
|
+
|
55
|
+
config.filter_sensitive_data('<AUTHORIZATION_HEADER>') { |interaction|
|
56
|
+
interaction.request.headers['Authorization']&.first
|
57
|
+
}
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
RSpec.configure do |config|
|
62
|
+
{
|
63
|
+
vcr_record: :once,
|
64
|
+
vcr_record_new: :new_episodes,
|
65
|
+
}.each do |tag, record_mode|
|
66
|
+
config.define_derived_metadata(tag) do |metadata|
|
67
|
+
case metadata[:vcr]
|
68
|
+
when nil, true
|
69
|
+
metadata[:vcr] = { record: record_mode }
|
70
|
+
when Hash
|
71
|
+
metadata[:vcr][:record] = record_mode
|
72
|
+
else
|
73
|
+
raise "Unknown VCR metadata value: #{metadata[:vcr].inspect}"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
config.define_derived_metadata(:focus) do |metadata|
|
79
|
+
# VCR is flagged as falsey
|
80
|
+
next if metadata.key?(:vcr) && !metadata[:vcr]
|
81
|
+
|
82
|
+
case metadata[:vcr]
|
83
|
+
when nil, true
|
84
|
+
metadata[:vcr] = { record: :once }
|
85
|
+
when Hash
|
86
|
+
metadata[:vcr][:record] ||= :once
|
87
|
+
else
|
88
|
+
raise "Unknown VCR metadata value: #{metadata[:vcr].inspect}"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Try to any custom VCR config for the app
|
94
|
+
# rubocop:disable Lint/HandleExceptions
|
95
|
+
begin
|
96
|
+
require 'support/vcr'
|
97
|
+
rescue LoadError
|
98
|
+
# Ignore as this is an optional convenience feature
|
99
|
+
end
|
100
|
+
# rubocop:enable Lint/HandleExceptions
|
data/lib/radius/spec/version.rb
CHANGED
data/radius-spec.gemspec
CHANGED
@@ -31,7 +31,7 @@ Gem::Specification.new do |spec|
|
|
31
31
|
spec.required_ruby_version = ">= 2.5"
|
32
32
|
|
33
33
|
spec.add_runtime_dependency "rspec", "~> 3.7"
|
34
|
-
spec.add_runtime_dependency "rubocop", "~> 0.
|
34
|
+
spec.add_runtime_dependency "rubocop", "~> 0.59.1"
|
35
35
|
|
36
36
|
spec.add_development_dependency "bundler", "~> 1.16"
|
37
37
|
spec.add_development_dependency "rake", "~> 12.0"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: radius-spec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Radius Networks
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2018-
|
12
|
+
date: 2018-09-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -31,14 +31,14 @@ dependencies:
|
|
31
31
|
requirements:
|
32
32
|
- - "~>"
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version: 0.
|
34
|
+
version: 0.59.1
|
35
35
|
type: :runtime
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
39
|
- - "~>"
|
40
40
|
- !ruby/object:Gem::Version
|
41
|
-
version: 0.
|
41
|
+
version: 0.59.1
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
43
|
name: bundler
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
@@ -109,7 +109,6 @@ files:
|
|
109
109
|
- bin/rspec
|
110
110
|
- bin/rubocop
|
111
111
|
- bin/setup
|
112
|
-
- bin/travis
|
113
112
|
- bin/yard
|
114
113
|
- common_rubocop.yml
|
115
114
|
- common_rubocop_rails.yml
|
@@ -117,6 +116,9 @@ files:
|
|
117
116
|
- lib/radius/spec/model_factory.rb
|
118
117
|
- lib/radius/spec/rails.rb
|
119
118
|
- lib/radius/spec/rspec.rb
|
119
|
+
- lib/radius/spec/rspec/negated_matchers.rb
|
120
|
+
- lib/radius/spec/tempfile.rb
|
121
|
+
- lib/radius/spec/vcr.rb
|
120
122
|
- lib/radius/spec/version.rb
|
121
123
|
- radius-spec.gemspec
|
122
124
|
homepage: https://github.com/RadiusNetworks/radius-spec
|
@@ -124,8 +126,8 @@ licenses:
|
|
124
126
|
- Apache-2.0
|
125
127
|
metadata:
|
126
128
|
bug_tracker_uri: https://github.com/RadiusNetworks/radius-spec/issues
|
127
|
-
changelog_uri: https://github.com/RadiusNetworks/radius-spec/blob/v0.
|
128
|
-
source_code_uri: https://github.com/RadiusNetworks/radius-spec/tree/v0.
|
129
|
+
changelog_uri: https://github.com/RadiusNetworks/radius-spec/blob/v0.5.0/CHANGELOG.md
|
130
|
+
source_code_uri: https://github.com/RadiusNetworks/radius-spec/tree/v0.5.0
|
129
131
|
post_install_message:
|
130
132
|
rdoc_options: []
|
131
133
|
require_paths:
|
data/bin/travis
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
#
|
5
|
-
# This file was generated by Bundler.
|
6
|
-
#
|
7
|
-
# The application 'travis' is installed as part of a gem, and
|
8
|
-
# this file is here to facilitate running it.
|
9
|
-
#
|
10
|
-
|
11
|
-
require "pathname"
|
12
|
-
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
13
|
-
Pathname.new(__FILE__).realpath)
|
14
|
-
|
15
|
-
bundle_binstub = File.expand_path("../bundle", __FILE__)
|
16
|
-
|
17
|
-
if File.file?(bundle_binstub)
|
18
|
-
if File.read(bundle_binstub, 150) =~ /This file was generated by Bundler/
|
19
|
-
load(bundle_binstub)
|
20
|
-
else
|
21
|
-
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
22
|
-
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
require "rubygems"
|
27
|
-
require "bundler/setup"
|
28
|
-
|
29
|
-
load Gem.bin_path("travis", "travis")
|