vcr-log_unmatched_cassettes 0.0.1 → 0.0.2
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
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6d72754d5764e97b62b6ea59ee4a147d4a9534dc8aafd00d22d57c461ebc1a71
|
|
4
|
+
data.tar.gz: 1811f85b5fd64fdfbc75d6f4c5baf1e609b57d0864cf5c883c1bd7ee7904b0b9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 38e933db7f083f77c926580f00c75fbb058fb8c175769d6f7852427384272a947f2af3a0ae3b33b5884bc3ebfba6192436a0b8730257789e5700ffe06ddeb973
|
|
7
|
+
data.tar.gz: f164ffa88ca3f56c519d2b1fb08774e428e44be35ee811ef1936ac58911e38dda155debb876e6248579df72358314eb962ad060dcc7ef78d15d14f2b603e6594
|
data/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# VCR::LogUnmatchedCassettes
|
|
2
2
|
|
|
3
|
+
[](https://github.com/sshaw/vcr-log_unmatched_cassettes/actions/workflows/main.yml)
|
|
4
|
+
|
|
3
5
|
Make finding and re-recording unmatched [VCR cassettes](https://github.com/vcr/vcr) (test that fail due to `VCR::Errors::UnhandledHTTPRequestError`)
|
|
4
6
|
easier by logging the test and unmatched cassette paths to a CSV.
|
|
5
7
|
|
|
@@ -8,7 +10,8 @@ easier by logging the test and unmatched cassette paths to a CSV.
|
|
|
8
10
|
In your `Gemfile`
|
|
9
11
|
|
|
10
12
|
```rb
|
|
11
|
-
|
|
13
|
+
# development for Rake task access
|
|
14
|
+
gem "vcr-log_unmatched_cassettes", :group => %w[test development]
|
|
12
15
|
```
|
|
13
16
|
|
|
14
17
|
In your spec configuration, after loading VCR, call:
|
|
@@ -16,9 +19,26 @@ In your spec configuration, after loading VCR, call:
|
|
|
16
19
|
VCR::LogUnmatchedCassettes.install
|
|
17
20
|
```
|
|
18
21
|
|
|
19
|
-
Now tests that
|
|
22
|
+
Now tests that fail 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
23
|
If you're using Rails it will be output to `./tmp`.
|
|
21
24
|
|
|
25
|
+
## Deleting Cassettes
|
|
26
|
+
|
|
27
|
+
Load the Rake task to delete cassettes listed in the `cassette` column of the latest report:
|
|
28
|
+
|
|
29
|
+
```rb
|
|
30
|
+
# Rakefile
|
|
31
|
+
require "vcr/log_unmatched_cassettes/rake"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Then run:
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
rake vcr:log_unmatched_cassettes:delete_cassettes
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Under Rails it is loaded automatically via a Railtie.
|
|
41
|
+
|
|
22
42
|
## Why?
|
|
23
43
|
|
|
24
44
|
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
|
|
@@ -28,7 +48,11 @@ Often one needs the path solely to delete the cassette and re-record it. This is
|
|
|
28
48
|
|
|
29
49
|
`record: :all` can be applied per test, but this requires modifying the test so that it can be scoped to `:all`.
|
|
30
50
|
|
|
31
|
-
|
|
51
|
+
Removing all cassettes is an option but this can clutter your git history with needless and _very_ bloated diffs.
|
|
52
|
+
|
|
53
|
+
## See Also
|
|
54
|
+
|
|
55
|
+
[vcr-unused_cassettes](https://github.com/jbockler/vcr-unused_cassettes) - Find unused VCR cassettes
|
|
32
56
|
|
|
33
57
|
## License
|
|
34
58
|
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rake"
|
|
4
|
+
require "csv"
|
|
5
|
+
require "fileutils"
|
|
6
|
+
require "vcr/log_unmatched_cassettes"
|
|
7
|
+
|
|
8
|
+
module VCR
|
|
9
|
+
module LogUnmatchedCassettes
|
|
10
|
+
module Rake
|
|
11
|
+
class << self
|
|
12
|
+
# Deletes the files listed in the +cassette+ column of the latest
|
|
13
|
+
# report and returns the paths that were removed.
|
|
14
|
+
def delete_cassettes(report = latest_report_file)
|
|
15
|
+
return [] unless report && File.file?(report)
|
|
16
|
+
|
|
17
|
+
report_path = File.expand_path(report)
|
|
18
|
+
deleted = []
|
|
19
|
+
|
|
20
|
+
CSV.foreach(report, headers: true) do |row|
|
|
21
|
+
path = row["cassette"]
|
|
22
|
+
next if path.nil? || path.strip.empty?
|
|
23
|
+
|
|
24
|
+
path = File.expand_path(path)
|
|
25
|
+
next if path == report_path || deleted.include?(path) || !File.file?(path)
|
|
26
|
+
|
|
27
|
+
FileUtils.rm(path)
|
|
28
|
+
deleted << path
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
deleted
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
# The most recently written report. Reports from previous runs are
|
|
37
|
+
# ignored, as their cassettes have presumably been dealt with already.
|
|
38
|
+
def latest_report_file
|
|
39
|
+
Dir[File.join(report_dir, "#{REPORT_PREFIX}.*.csv")]
|
|
40
|
+
.select { |path| File.file?(path) }
|
|
41
|
+
.max_by { |path| [File.mtime(path), File.basename(path)] }
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def report_dir
|
|
45
|
+
LogUnmatchedCassettes.output_dir || LogUnmatchedCassettes.default_output_dir
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
namespace :vcr do
|
|
53
|
+
namespace :log_unmatched_cassettes do
|
|
54
|
+
desc "Delete the cassettes listed in the latest vcr-unmatched-cassettes report"
|
|
55
|
+
task :delete_cassettes do
|
|
56
|
+
log = VCR::LogUnmatchedCassettes
|
|
57
|
+
tasks = VCR::LogUnmatchedCassettes::Rake
|
|
58
|
+
|
|
59
|
+
if log.enabled == false
|
|
60
|
+
warn "[VCR::LogUnmatchedCassettes] Disabled, not deleting anything."
|
|
61
|
+
next
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
dir = log.output_dir || log.default_output_dir
|
|
65
|
+
deleted = tasks.delete_cassettes
|
|
66
|
+
|
|
67
|
+
if deleted.empty?
|
|
68
|
+
warn "[VCR::LogUnmatchedCassettes] Nothing to delete from the latest report in #{dir}."
|
|
69
|
+
next
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
warn "[VCR::LogUnmatchedCassettes] Deleted #{deleted.size} cassette(s) from the latest report in #{dir}:"
|
|
73
|
+
|
|
74
|
+
deleted.each { |path| warn " #{path}" }
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
@@ -7,6 +7,13 @@ require "csv"
|
|
|
7
7
|
|
|
8
8
|
module VCR
|
|
9
9
|
module LogUnmatchedCassettes
|
|
10
|
+
REPORT_PREFIX = "vcr-unmatched-cassettes"
|
|
11
|
+
|
|
12
|
+
# Sentinels from VCR's UnhandledHTTPRequestError message. Used as a fallback
|
|
13
|
+
# when the exception class itself can no longer be reached (see
|
|
14
|
+
# `find_vcr_error`).
|
|
15
|
+
UNHANDLED_REQUEST_MESSAGE = "An HTTP request has been made that VCR does not know how to handle"
|
|
16
|
+
|
|
10
17
|
module MinitestHook # :nodoc:
|
|
11
18
|
# Minitest stores the test's exception by running it through
|
|
12
19
|
# `sanitize_exception` in `capture_exceptions`. A marshable exception is
|
|
@@ -41,7 +48,7 @@ module VCR
|
|
|
41
48
|
|
|
42
49
|
def install
|
|
43
50
|
self.enabled = true if enabled.nil?
|
|
44
|
-
self.output_dir =
|
|
51
|
+
self.output_dir = default_output_dir
|
|
45
52
|
|
|
46
53
|
@failures = []
|
|
47
54
|
|
|
@@ -54,6 +61,14 @@ module VCR
|
|
|
54
61
|
end
|
|
55
62
|
end
|
|
56
63
|
|
|
64
|
+
def default_output_dir
|
|
65
|
+
if defined?(Rails) && Rails.respond_to?(:root) && Rails.root
|
|
66
|
+
Rails.root.join("tmp").to_s
|
|
67
|
+
else
|
|
68
|
+
Dir.tmpdir
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
57
72
|
def record(location, cassette_path)
|
|
58
73
|
return if !enabled || cassette_path.nil? || cassette_path.empty?
|
|
59
74
|
|
|
@@ -66,7 +81,7 @@ module VCR
|
|
|
66
81
|
FileUtils.mkdir_p(output_dir)
|
|
67
82
|
|
|
68
83
|
timestamp = Time.now.strftime("%Y%m%d%H%M%S")
|
|
69
|
-
filename = File.join(output_dir, "
|
|
84
|
+
filename = File.join(output_dir, "#{REPORT_PREFIX}.#{timestamp}.csv")
|
|
70
85
|
|
|
71
86
|
CSV.open(filename, "w") do |csv|
|
|
72
87
|
csv << %w[test cassette]
|
|
@@ -79,12 +94,20 @@ module VCR
|
|
|
79
94
|
warn "\n[VCR::LogUnmatchedCassettes] Wrote #{@failures.size} failed cassette(s) to: #{filename}"
|
|
80
95
|
end
|
|
81
96
|
|
|
82
|
-
# Walks the exception + cause chain looking for UnhandledHTTPRequestError
|
|
97
|
+
# Walks the exception + cause chain looking for UnhandledHTTPRequestError.
|
|
98
|
+
#
|
|
99
|
+
# Some frameworks re-raise VCR's error as a different class after it has
|
|
100
|
+
# crossed a thread boundary (e.g. Capybara's app server). Re-raising a
|
|
101
|
+
# fresh exception object replaces the cause chain, so the VCR error is no
|
|
102
|
+
# longer reachable via `cause`. In that case the only thing left is its
|
|
103
|
+
# message, which VCR's wrapper embeds into its own message. Match on the
|
|
104
|
+
# message as a fallback.
|
|
83
105
|
def find_vcr_error(exception)
|
|
84
106
|
current = exception
|
|
85
107
|
|
|
86
108
|
while current
|
|
87
109
|
return current if current.is_a?(VCR::Errors::UnhandledHTTPRequestError)
|
|
110
|
+
return current if current.message.to_s.include?(UNHANDLED_REQUEST_MESSAGE)
|
|
88
111
|
current = current.cause
|
|
89
112
|
end
|
|
90
113
|
|
|
@@ -120,3 +143,5 @@ module VCR
|
|
|
120
143
|
end
|
|
121
144
|
end
|
|
122
145
|
end
|
|
146
|
+
|
|
147
|
+
require "vcr/log_unmatched_cassettes/railtie" if defined?(::Rails::Railtie)
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: vcr-log_unmatched_cassettes
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Skye Shaw
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-10-
|
|
10
|
+
date: 2026-10-23 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: vcr
|
|
@@ -117,6 +117,8 @@ files:
|
|
|
117
117
|
- README.md
|
|
118
118
|
- Rakefile
|
|
119
119
|
- lib/vcr/log_unmatched_cassettes.rb
|
|
120
|
+
- lib/vcr/log_unmatched_cassettes/railtie.rb
|
|
121
|
+
- lib/vcr/log_unmatched_cassettes/rake.rb
|
|
120
122
|
- lib/vcr/log_unmatched_cassettes/version.rb
|
|
121
123
|
homepage: https://github.com/sshaw/vcr-log_unmatched_cassettes
|
|
122
124
|
licenses:
|