vcr-log_unmatched_cassettes 0.0.1
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 +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +39 -0
- data/Rakefile +8 -0
- data/lib/vcr/log_unmatched_cassettes/version.rb +7 -0
- data/lib/vcr/log_unmatched_cassettes.rb +122 -0
- metadata +145 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 5715a8e1d849e98faea2e124290b2fa5d4b74a3e75f7feced17ad4b64457e115
|
|
4
|
+
data.tar.gz: 7a51740f8bcae35c1ddb986e143a21b5182a9e7b9c38e17a4257428958b18269
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: e2cd3c15a2d8a73d93e6a9d78d64cf09436c43191a8dad13064f2f4b13287920e276ac397d41b2b438f9c0a5c413d146deb34df4f1731ab7ad062f8caad213eb
|
|
7
|
+
data.tar.gz: 67c3705c67566b056274f65fa397b82c95692c8fc5ee2db8de5f6233010be4251d11b719d005dd08f9699fb0f4aceb7fa313b923ae7ed07f49f93ca7d462f51b
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 sshaw
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# VCR::LogUnmatchedCassettes
|
|
2
|
+
|
|
3
|
+
Make finding and re-recording unmatched [VCR cassettes](https://github.com/vcr/vcr) (test that fail due to `VCR::Errors::UnhandledHTTPRequestError`)
|
|
4
|
+
easier by logging the test and unmatched cassette paths to a CSV.
|
|
5
|
+
|
|
6
|
+
## Usage
|
|
7
|
+
|
|
8
|
+
In your `Gemfile`
|
|
9
|
+
|
|
10
|
+
```rb
|
|
11
|
+
gem "vcr-log_unmatched_cassettes", :group => "test"
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
In your spec configuration, after loading VCR, call:
|
|
15
|
+
```rb
|
|
16
|
+
VCR::LogUnmatchedCassettes.install
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Now tests that fails due to VCR being able to unmatch the request (`VCR::Errors::UnhandledHTTPRequestError`) will be output to the system's temp directory in a CSV.
|
|
20
|
+
If you're using Rails it will be output to `./tmp`.
|
|
21
|
+
|
|
22
|
+
## Why?
|
|
23
|
+
|
|
24
|
+
When tests fail due to unmatched HTTP requests the path is output within a large blob of text. This may be fine for a couple of tests but
|
|
25
|
+
with large amounts of tests the path can be a pain track down. This becomes worse when one needs the paths for multiple tests.
|
|
26
|
+
|
|
27
|
+
Often one needs the path solely to delete the cassette and re-record it. This is often preferred to using VCR's `record: :all` globally as `:all` is a bit heavy-handed.
|
|
28
|
+
|
|
29
|
+
`record: :all` can be applied per test, but this requires modifying the test so that it can be scoped to `:all`.
|
|
30
|
+
|
|
31
|
+
Remove all cassettes is an option but this can clutter your git history with needless and _very_ bloated diffs.
|
|
32
|
+
|
|
33
|
+
## License
|
|
34
|
+
|
|
35
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
36
|
+
|
|
37
|
+
## Author
|
|
38
|
+
|
|
39
|
+
Skye Shaw [sshaw AT gmail.com]
|
data/Rakefile
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "vcr"
|
|
4
|
+
require "fileutils"
|
|
5
|
+
require "tmpdir"
|
|
6
|
+
require "csv"
|
|
7
|
+
|
|
8
|
+
module VCR
|
|
9
|
+
module LogUnmatchedCassettes
|
|
10
|
+
module MinitestHook # :nodoc:
|
|
11
|
+
# Minitest stores the test's exception by running it through
|
|
12
|
+
# `sanitize_exception` in `capture_exceptions`. A marshable exception is
|
|
13
|
+
# kept as-is, but VCR::Errors::UnhandledHTTPRequestError is not marshable
|
|
14
|
+
# (it memoizes the active cassette), so Minitest "neuters" it into a
|
|
15
|
+
# generic RuntimeError, losing the class and any `cause` chain. Capture
|
|
16
|
+
# the original exception here so it can still be identified in
|
|
17
|
+
# `after_teardown` (where `$!` is nil).
|
|
18
|
+
def sanitize_exception(error)
|
|
19
|
+
@vcr_unmatched_error = error
|
|
20
|
+
super
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def after_teardown
|
|
24
|
+
super
|
|
25
|
+
|
|
26
|
+
vcr_error = VCR::LogUnmatchedCassettes.find_vcr_error(@vcr_unmatched_error)
|
|
27
|
+
return unless vcr_error
|
|
28
|
+
|
|
29
|
+
cassette = VCR.current_cassette
|
|
30
|
+
return unless cassette
|
|
31
|
+
|
|
32
|
+
location = "#{self.class.name}##{name}"
|
|
33
|
+
path = cassette.respond_to?(:file) ? cassette.file : cassette.name.to_s
|
|
34
|
+
|
|
35
|
+
VCR::LogUnmatchedCassettes.record(location, path)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
class << self
|
|
40
|
+
attr_accessor :enabled, :output_dir
|
|
41
|
+
|
|
42
|
+
def install
|
|
43
|
+
self.enabled = true if enabled.nil?
|
|
44
|
+
self.output_dir = defined?(Rails) && Rails.respond_to?(:root) ? Rails.root.join("tmp").to_s : Dir.tmpdir
|
|
45
|
+
|
|
46
|
+
@failures = []
|
|
47
|
+
|
|
48
|
+
if defined?(::RSpec)
|
|
49
|
+
install_rspec
|
|
50
|
+
elsif defined?(Minitest)
|
|
51
|
+
install_minitest
|
|
52
|
+
else
|
|
53
|
+
raise "VCR::LogUnmatchedCassettes requires RSpec or Minitest. Neither was found."
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def record(location, cassette_path)
|
|
58
|
+
return if !enabled || cassette_path.nil? || cassette_path.empty?
|
|
59
|
+
|
|
60
|
+
@failures << [location, cassette_path]
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def write_report
|
|
64
|
+
return if @failures.empty?
|
|
65
|
+
|
|
66
|
+
FileUtils.mkdir_p(output_dir)
|
|
67
|
+
|
|
68
|
+
timestamp = Time.now.strftime("%Y%m%d%H%M%S")
|
|
69
|
+
filename = File.join(output_dir, "vcr-unmatched-cassettes.#{timestamp}.csv")
|
|
70
|
+
|
|
71
|
+
CSV.open(filename, "w") do |csv|
|
|
72
|
+
csv << %w[test cassette]
|
|
73
|
+
|
|
74
|
+
@failures.each do |test, cassette|
|
|
75
|
+
csv << [test, cassette]
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
warn "\n[VCR::LogUnmatchedCassettes] Wrote #{@failures.size} failed cassette(s) to: #{filename}"
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Walks the exception + cause chain looking for UnhandledHTTPRequestError
|
|
83
|
+
def find_vcr_error(exception)
|
|
84
|
+
current = exception
|
|
85
|
+
|
|
86
|
+
while current
|
|
87
|
+
return current if current.is_a?(VCR::Errors::UnhandledHTTPRequestError)
|
|
88
|
+
current = current.cause
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
nil
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
private
|
|
95
|
+
|
|
96
|
+
def install_rspec
|
|
97
|
+
::RSpec.configure do |config|
|
|
98
|
+
config.after(:each) do |example|
|
|
99
|
+
vcr_error = VCR::LogUnmatchedCassettes.find_vcr_error(example.exception)
|
|
100
|
+
next unless vcr_error
|
|
101
|
+
|
|
102
|
+
cassette = VCR.current_cassette
|
|
103
|
+
next unless cassette
|
|
104
|
+
|
|
105
|
+
# :location is "./spec/foo_spec.rb:42"
|
|
106
|
+
VCR::LogUnmatchedCassettes.record(example.metadata[:location], cassette.file)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
config.after(:suite) do
|
|
110
|
+
VCR::LogUnmatchedCassettes.write_report
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def install_minitest
|
|
116
|
+
Minitest::Test.prepend(MinitestHook)
|
|
117
|
+
|
|
118
|
+
Minitest.after_run { VCR::LogUnmatchedCassettes.write_report }
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: vcr-log_unmatched_cassettes
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Skye Shaw
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 2026-10-22 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: vcr
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '0'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '0'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: bundler
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '0'
|
|
33
|
+
type: :development
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '0'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: csv
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - ">="
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '0'
|
|
47
|
+
type: :development
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - ">="
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '0'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: minitest
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '0'
|
|
61
|
+
type: :development
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - ">="
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '0'
|
|
68
|
+
- !ruby/object:Gem::Dependency
|
|
69
|
+
name: rake
|
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - ">="
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '0'
|
|
75
|
+
type: :development
|
|
76
|
+
prerelease: false
|
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - ">="
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '0'
|
|
82
|
+
- !ruby/object:Gem::Dependency
|
|
83
|
+
name: rspec
|
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
|
85
|
+
requirements:
|
|
86
|
+
- - ">="
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: '0'
|
|
89
|
+
type: :development
|
|
90
|
+
prerelease: false
|
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - ">="
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: '0'
|
|
96
|
+
- !ruby/object:Gem::Dependency
|
|
97
|
+
name: vcr
|
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
|
99
|
+
requirements:
|
|
100
|
+
- - ">="
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: '0'
|
|
103
|
+
type: :development
|
|
104
|
+
prerelease: false
|
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
106
|
+
requirements:
|
|
107
|
+
- - ">="
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: '0'
|
|
110
|
+
email:
|
|
111
|
+
- skye.shaw@gmail.com
|
|
112
|
+
executables: []
|
|
113
|
+
extensions: []
|
|
114
|
+
extra_rdoc_files: []
|
|
115
|
+
files:
|
|
116
|
+
- LICENSE.txt
|
|
117
|
+
- README.md
|
|
118
|
+
- Rakefile
|
|
119
|
+
- lib/vcr/log_unmatched_cassettes.rb
|
|
120
|
+
- lib/vcr/log_unmatched_cassettes/version.rb
|
|
121
|
+
homepage: https://github.com/sshaw/vcr-log_unmatched_cassettes
|
|
122
|
+
licenses:
|
|
123
|
+
- MIT
|
|
124
|
+
metadata:
|
|
125
|
+
homepage_uri: https://github.com/sshaw/vcr-log_unmatched_cassettes
|
|
126
|
+
source_code_uri: https://github.com/sshaw/vcr-log_unmatched_cassettes
|
|
127
|
+
rdoc_options: []
|
|
128
|
+
require_paths:
|
|
129
|
+
- lib
|
|
130
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
131
|
+
requirements:
|
|
132
|
+
- - ">="
|
|
133
|
+
- !ruby/object:Gem::Version
|
|
134
|
+
version: '2.7'
|
|
135
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
136
|
+
requirements:
|
|
137
|
+
- - ">="
|
|
138
|
+
- !ruby/object:Gem::Version
|
|
139
|
+
version: '0'
|
|
140
|
+
requirements: []
|
|
141
|
+
rubygems_version: 3.6.2
|
|
142
|
+
specification_version: 4
|
|
143
|
+
summary: Make finding and re-recording unmatched VCR cassettes easier by logging the
|
|
144
|
+
test and unmatched cassette paths to a CSV
|
|
145
|
+
test_files: []
|