nxt_vcr_harness 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +55 -0
- data/.ruby-version +1 -0
- data/Gemfile.lock +11 -2
- data/README.md +13 -5
- data/lib/nxt_vcr_harness.rb +33 -3
- data/lib/nxt_vcr_harness/cassette_name_by_example.rb +51 -41
- data/lib/nxt_vcr_harness/cassette_tracker.rb +32 -28
- data/lib/nxt_vcr_harness/version.rb +1 -1
- data/nxt_vcr_harness.gemspec +2 -0
- metadata +33 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 87aa2c86941c590ac6bcc4c0ba154fc14ff61dcf1f8098c8b58ff7d4c4605124
|
4
|
+
data.tar.gz: 7d8dfeac8e114a84883c48edbf18bf4ce6e91db551b2cc3ac2489f98061c2a4e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b7865bb0b8b4f3dd4443711af812563c458c5c79ef8060347f4afcaf930f731ecd03085022694460c12f0e6190996a55d4854f6f5c5e721ac16c652013c4f1a7
|
7
|
+
data.tar.gz: 9085bda4e0030897e6858db9b3e642e18c4a087c581dc61681bdb3bce18e4344de8f936009f5367610246c28087beb50d968e15cfe8f1ea39cc3fd6248e8f147
|
@@ -0,0 +1,55 @@
|
|
1
|
+
version: 2
|
2
|
+
|
3
|
+
jobs:
|
4
|
+
build:
|
5
|
+
working_directory: /home/circleci/app
|
6
|
+
docker:
|
7
|
+
- image: circleci/ruby:2.6.2-node
|
8
|
+
environment:
|
9
|
+
RACK_ENV: test
|
10
|
+
RAILS_ENV: test
|
11
|
+
COVERAGE: true
|
12
|
+
# CC_TEST_REPORTER_ID: YOUR_REPO_CC_TEST_REPORTER_ID # ENV var set in CircleCI user interface
|
13
|
+
steps:
|
14
|
+
- checkout
|
15
|
+
# libpq-dev: required for compiling the `pg` gem
|
16
|
+
# nodejs: required for asset compilation (see https://github.com/rails/execjs)
|
17
|
+
- run:
|
18
|
+
name: Install apt dependencies
|
19
|
+
command: |
|
20
|
+
sudo apt update -q \
|
21
|
+
&& sudo apt upgrade -q
|
22
|
+
- restore_cache:
|
23
|
+
key: v3-bundler-{{ checksum "Gemfile.lock" }}-{{ arch }}
|
24
|
+
- run: gem install bundler
|
25
|
+
- run: bundle config build.nokogiri --use-system-libraries
|
26
|
+
- run: bundle install --without staging:production --path=vendor/bundle --jobs=4 --retry=3
|
27
|
+
- save_cache:
|
28
|
+
key: v3-bundler-{{ checksum "Gemfile.lock" }}-{{ arch }}
|
29
|
+
paths:
|
30
|
+
- vendor/bundle
|
31
|
+
- run:
|
32
|
+
name: Collect and filter specs
|
33
|
+
command: |
|
34
|
+
mkdir -p tmp/circleci
|
35
|
+
circleci tests glob "spec/**/*_spec.rb" > tmp/circleci/all_tests.txt
|
36
|
+
circleci tests split --split-by=timings < tmp/circleci/all_tests.txt > tmp/circleci/tests_to_run.txt
|
37
|
+
echo "These specs will be run:"
|
38
|
+
cat tmp/circleci/tests_to_run.txt
|
39
|
+
- run:
|
40
|
+
name: Parallel RSpec
|
41
|
+
command: |
|
42
|
+
bundle exec rspec \
|
43
|
+
--color \
|
44
|
+
--format progress \
|
45
|
+
--require spec_helper \
|
46
|
+
--format RspecJunitFormatter --out /tmp/rspec/junit.xml \
|
47
|
+
$(cat tmp/circleci/tests_to_run.txt)
|
48
|
+
# actually not necessary for test results to be collected, but these files
|
49
|
+
# won't show up in the web UI otherwise
|
50
|
+
- store_artifacts:
|
51
|
+
path: /tmp/rspec/
|
52
|
+
destination: rspec
|
53
|
+
|
54
|
+
- store_test_results:
|
55
|
+
path: /tmp/rspec/
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.6.3
|
data/Gemfile.lock
CHANGED
@@ -1,14 +1,19 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
nxt_vcr_harness (0.1.
|
4
|
+
nxt_vcr_harness (0.1.1)
|
5
5
|
rspec (~> 3.0)
|
6
6
|
vcr (~> 4.0)
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
|
+
coderay (1.1.2)
|
11
12
|
diff-lcs (1.3)
|
13
|
+
method_source (0.9.2)
|
14
|
+
pry (0.12.2)
|
15
|
+
coderay (~> 1.1.0)
|
16
|
+
method_source (~> 0.9.0)
|
12
17
|
rake (10.5.0)
|
13
18
|
rspec (3.8.0)
|
14
19
|
rspec-core (~> 3.8.0)
|
@@ -23,6 +28,8 @@ GEM
|
|
23
28
|
diff-lcs (>= 1.2.0, < 2.0)
|
24
29
|
rspec-support (~> 3.8.0)
|
25
30
|
rspec-support (3.8.0)
|
31
|
+
rspec_junit_formatter (0.4.1)
|
32
|
+
rspec-core (>= 2, < 4, != 2.12.0)
|
26
33
|
vcr (4.0.0)
|
27
34
|
|
28
35
|
PLATFORMS
|
@@ -31,8 +38,10 @@ PLATFORMS
|
|
31
38
|
DEPENDENCIES
|
32
39
|
bundler (~> 1.17)
|
33
40
|
nxt_vcr_harness!
|
41
|
+
pry
|
34
42
|
rake (~> 10.0)
|
35
43
|
rspec (~> 3.0)
|
44
|
+
rspec_junit_formatter (~> 0.4.1)
|
36
45
|
|
37
46
|
BUNDLED WITH
|
38
|
-
1.17.
|
47
|
+
1.17.3
|
data/README.md
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
# NxtVcrHarness
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
TODO: Delete this and the text above, and describe your gem
|
3
|
+
NxtVcrHarness helps you with vcr cassette handling in RSpec.
|
6
4
|
|
7
5
|
## Installation
|
8
6
|
|
@@ -22,7 +20,17 @@ Or install it yourself as:
|
|
22
20
|
|
23
21
|
## Usage
|
24
22
|
|
25
|
-
|
23
|
+
NxtVcrHarness currently has two features. You can use it to find vcr cassettes that are not being used when you
|
24
|
+
run your test suite. Enable it by calling `NxtVcrHarness.track_cassettes`. Note that the output only makes sense when
|
25
|
+
you run your complete test suite. If you run only a subset all cassettes that are used by your other test will be included too.
|
26
|
+
|
27
|
+
The second feature is that you can enable your custom :vcr tag by calling `NxtVcrHarness.enable_vcr_tag`. This will
|
28
|
+
automatically name your vcr cassettes based on the your rspec example and the surrounding contexts. You can also
|
29
|
+
setup default cassette options for your vcr tag.
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
NxtVcrHarness.enable_vcr_tag(tag_name: :my_vcr_tag, default_cassette_options: { ... })
|
33
|
+
```
|
26
34
|
|
27
35
|
## Development
|
28
36
|
|
@@ -32,7 +40,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
32
40
|
|
33
41
|
## Contributing
|
34
42
|
|
35
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
43
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/nxt-insurance/nxt_vcr_harness.
|
36
44
|
|
37
45
|
## License
|
38
46
|
|
data/lib/nxt_vcr_harness.rb
CHANGED
@@ -3,13 +3,32 @@ require 'nxt_vcr_harness/cassette_name_by_example'
|
|
3
3
|
require 'nxt_vcr_harness/cassette_tracker'
|
4
4
|
|
5
5
|
module NxtVcrHarness
|
6
|
+
module VcrCassetteHelper
|
7
|
+
def with_vcr_cassette(example, **options, &block)
|
8
|
+
cassette_by_example_options = %i[prefix suffix]
|
9
|
+
cassette_path = CassetteNameByExample.new(example).call(options.slice(*cassette_by_example_options))
|
10
|
+
|
11
|
+
vcr_options = options.reject { |k,_| k.in?(cassette_by_example_options) }
|
12
|
+
|
13
|
+
::VCR.use_cassette(cassette_path, **vcr_options) do
|
14
|
+
block.call
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def hash_from_example(example, **options)
|
19
|
+
cassette_by_example_options = %i[prefix suffix]
|
20
|
+
name = CassetteNameByExample.new(example).call(options.slice(*cassette_by_example_options))
|
21
|
+
Digest::MD5.hexdigest(name)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
6
25
|
def enable_vcr_tag(options = {})
|
7
26
|
tag_name = options.fetch(:tag_name, :vcr_cassette)
|
8
27
|
default_cassette_options = options.fetch(:default_cassette_options, {})
|
9
28
|
|
10
29
|
RSpec.configure do |config|
|
11
30
|
config.around(:each, tag_name) do |example|
|
12
|
-
cassette_path = CassetteNameByExample.new(example).call
|
31
|
+
cassette_path = CassetteNameByExample.new(example).call(options.slice(:prefix, :suffix))
|
13
32
|
cassette_options = example.metadata[tag_name].is_a?(TrueClass) ? {} : example.metadata[tag_name]
|
14
33
|
cassette_options = default_cassette_options.merge(cassette_options)
|
15
34
|
|
@@ -20,11 +39,22 @@ module NxtVcrHarness
|
|
20
39
|
end
|
21
40
|
end
|
22
41
|
|
42
|
+
def enable_vcr_cassette_helper
|
43
|
+
RSpec.configure do |config|
|
44
|
+
config.include VcrCassetteHelper
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def track_cassettes_if(condition)
|
49
|
+
return unless condition
|
50
|
+
track_cassettes
|
51
|
+
end
|
52
|
+
|
23
53
|
def track_cassettes
|
24
54
|
RSpec.configure do |config|
|
25
55
|
config.after(:suite) do
|
26
56
|
CassetteTracker.instance.stats
|
27
|
-
CassetteTracker.instance.reveal_unused_cassettes(VCR.configuration.cassette_library_dir)
|
57
|
+
CassetteTracker.instance.reveal_unused_cassettes(::VCR.configuration.cassette_library_dir)
|
28
58
|
end
|
29
59
|
end
|
30
60
|
|
@@ -35,5 +65,5 @@ module NxtVcrHarness
|
|
35
65
|
end
|
36
66
|
end
|
37
67
|
|
38
|
-
module_function :enable_vcr_tag, :track_cassettes
|
68
|
+
module_function :enable_vcr_tag, :track_cassettes, :enable_vcr_cassette_helper
|
39
69
|
end
|
@@ -1,57 +1,67 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
module NxtVcrHarness
|
2
|
+
class CassetteNameByExample
|
3
|
+
def initialize(example)
|
4
|
+
@example = example
|
5
|
+
end
|
5
6
|
|
6
|
-
|
7
|
+
attr_reader :example
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
def call(**options)
|
10
|
+
cassette_name_and_path(options)
|
11
|
+
end
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
[spec_path, cassette_name_from_descriptions].join('/')
|
15
|
-
end
|
13
|
+
def cassette_name_and_path(options)
|
14
|
+
path = []
|
16
15
|
|
17
|
-
|
18
|
-
|
19
|
-
descriptions.map(&method(:gsub_whitespace)).map(&method(:remove_hash_tags))
|
20
|
-
end
|
16
|
+
path << options[:prefix]
|
17
|
+
spec_path = example.file_path.gsub(/\.rb$/, '').gsub('./spec/', '')
|
21
18
|
|
22
|
-
|
23
|
-
|
24
|
-
|
19
|
+
path << spec_path
|
20
|
+
path << cassette_name_from_descriptions
|
21
|
+
path << options[:suffix]
|
25
22
|
|
26
|
-
|
27
|
-
|
28
|
-
end
|
23
|
+
"/#{path.flatten.compact.join('/')}"
|
24
|
+
end
|
29
25
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
break acc if context[:vcr_cassette]
|
26
|
+
def cassette_name_from_descriptions
|
27
|
+
descriptions = context_hierarchy_with_vcr_cassette_tags.map { |c| c[:description] }
|
28
|
+
descriptions.map(&method(:gsub_whitespace)).map(&method(:remove_hash_tags))
|
29
|
+
end
|
35
30
|
|
36
|
-
|
37
|
-
|
31
|
+
def gsub_whitespace(name)
|
32
|
+
name.gsub(/\s+/, '_')
|
33
|
+
end
|
34
|
+
|
35
|
+
def remove_hash_tags(name)
|
36
|
+
name.delete('#')
|
38
37
|
end
|
39
|
-
end
|
40
38
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
39
|
+
def context_hierarchy_with_vcr_cassette_tags
|
40
|
+
@context_hierarchy_with_vcr_cassette_tags ||= begin
|
41
|
+
context_hierarchy.reverse.inject([]) do |acc, context|
|
42
|
+
acc << context
|
43
|
+
break acc if context[:vcr_cassette]
|
46
44
|
|
47
|
-
|
48
|
-
|
49
|
-
example_group = parent_example_group
|
45
|
+
acc
|
46
|
+
end
|
50
47
|
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def context_hierarchy
|
51
|
+
@context_hierarchy ||= begin
|
52
|
+
context_hierarchy = [example.metadata]
|
53
|
+
example_group = example.metadata[:example_group]
|
54
|
+
context_hierarchy << example_group
|
51
55
|
|
52
|
-
|
53
|
-
|
54
|
-
|
56
|
+
while parent_example_group = example_group[:parent_example_group] do
|
57
|
+
context_hierarchy << parent_example_group
|
58
|
+
example_group = parent_example_group
|
59
|
+
end
|
60
|
+
|
61
|
+
context_hierarchy
|
62
|
+
rescue StandardError => e
|
63
|
+
raise StandardError, "Failed to build context hierarchy for example: #{example} - Error was: #{e.inspect}"
|
64
|
+
end
|
55
65
|
end
|
56
66
|
end
|
57
67
|
end
|
@@ -1,37 +1,41 @@
|
|
1
|
-
|
2
|
-
include Singleton
|
1
|
+
require 'singleton'
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
module NxtVcrHarness
|
4
|
+
class CassetteTracker
|
5
|
+
include Singleton
|
7
6
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
end
|
7
|
+
def initialize
|
8
|
+
@cassettes = []
|
9
|
+
end
|
12
10
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
if unused_cassettes.any?
|
17
|
-
puts "The following cassettes are unused: "
|
18
|
-
puts unused_cassettes.join(' ')
|
19
|
-
else
|
20
|
-
puts "There are no unused cassettes"
|
11
|
+
def stats
|
12
|
+
puts '.'
|
13
|
+
puts "Stubbed #{playback_count} HTTP requests using #{cassette_file_names_from_used_cassettes.count} cassettes"
|
21
14
|
end
|
22
|
-
end
|
23
15
|
|
24
|
-
|
25
|
-
|
26
|
-
|
16
|
+
def reveal_unused_cassettes(library_dir)
|
17
|
+
all_cassette_paths = Dir.glob("#{library_dir}/**/*.yml")
|
18
|
+
unused_cassettes = (all_cassette_paths - cassette_file_names_from_used_cassettes)
|
19
|
+
if unused_cassettes.any?
|
20
|
+
puts "The following cassettes are unused: "
|
21
|
+
puts unused_cassettes.join(' ')
|
22
|
+
else
|
23
|
+
puts "There are no unused cassettes"
|
24
|
+
end
|
25
|
+
end
|
27
26
|
|
28
|
-
|
29
|
-
|
30
|
-
|
27
|
+
def cassette_file_names_from_used_cassettes
|
28
|
+
cassettes.map(&:file).uniq
|
29
|
+
end
|
31
30
|
|
32
|
-
|
33
|
-
|
34
|
-
|
31
|
+
def playback_count
|
32
|
+
cassettes.count
|
33
|
+
end
|
35
34
|
|
36
|
-
|
35
|
+
def track(cassette)
|
36
|
+
cassettes << cassette
|
37
|
+
end
|
38
|
+
|
39
|
+
attr_accessor :cassettes
|
40
|
+
end
|
37
41
|
end
|
data/nxt_vcr_harness.gemspec
CHANGED
@@ -41,4 +41,6 @@ Gem::Specification.new do |spec|
|
|
41
41
|
spec.add_development_dependency "bundler", "~> 1.17"
|
42
42
|
spec.add_development_dependency "rake", "~> 10.0"
|
43
43
|
spec.add_development_dependency "rspec", "~> 3.0"
|
44
|
+
spec.add_development_dependency "pry"
|
45
|
+
spec.add_development_dependency "rspec_junit_formatter", "~> 0.4.1"
|
44
46
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nxt_vcr_harness
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andreas Robecke
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date: 2019-
|
13
|
+
date: 2019-05-29 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rspec
|
@@ -82,6 +82,34 @@ dependencies:
|
|
82
82
|
- - "~>"
|
83
83
|
- !ruby/object:Gem::Version
|
84
84
|
version: '3.0'
|
85
|
+
- !ruby/object:Gem::Dependency
|
86
|
+
name: pry
|
87
|
+
requirement: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
|
+
type: :development
|
93
|
+
prerelease: false
|
94
|
+
version_requirements: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
- !ruby/object:Gem::Dependency
|
100
|
+
name: rspec_junit_formatter
|
101
|
+
requirement: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - "~>"
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: 0.4.1
|
106
|
+
type: :development
|
107
|
+
prerelease: false
|
108
|
+
version_requirements: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - "~>"
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: 0.4.1
|
85
113
|
description: Names your vcr cassettes based on your rspec examples and let's you pass
|
86
114
|
in options on the fly
|
87
115
|
email:
|
@@ -90,8 +118,10 @@ executables: []
|
|
90
118
|
extensions: []
|
91
119
|
extra_rdoc_files: []
|
92
120
|
files:
|
121
|
+
- ".circleci/config.yml"
|
93
122
|
- ".gitignore"
|
94
123
|
- ".rspec"
|
124
|
+
- ".ruby-version"
|
95
125
|
- ".travis.yml"
|
96
126
|
- Gemfile
|
97
127
|
- Gemfile.lock
|
@@ -127,7 +157,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
127
157
|
- !ruby/object:Gem::Version
|
128
158
|
version: '0'
|
129
159
|
requirements: []
|
130
|
-
rubygems_version: 3.0.
|
160
|
+
rubygems_version: 3.0.3
|
131
161
|
signing_key:
|
132
162
|
specification_version: 4
|
133
163
|
summary: Intuitive VCR cassette naming
|