rspec-cassette 0.1.0 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a295971bad6b1f3461dd25a592349835c0944f587d6276098e53c3ac64468267
4
- data.tar.gz: 4bde9b73040304c11eef974d844f11ffc97737989eabbe0ed8c9b1a3098c32a0
3
+ metadata.gz: 81ec6b2f1d492c9ed7a6aa19fcb7b2c4ad0b3eaed666158425cf271a96ddf485
4
+ data.tar.gz: 218103dde5699758cb6a0d313208ae980403c1ee802dba5606e1c62dbb436a6b
5
5
  SHA512:
6
- metadata.gz: ef495ef8f33774e6433f6f5bcf1a97391bf056487562e52bb44e63f04e842faed96c3b84cef48e28f920acb6fc77523b4f5b725a0f412f578725c732a3fa0562
7
- data.tar.gz: a8299f4c8a17f80c80f6dc7731017b4466fdcbc0e683fca9aa255d2d94985b209bf7216f945694d9a5f46944cd95ece2bb158dcd92aa0412fd9dcc8cad9f5d20
6
+ metadata.gz: 50b1d99905f0ef3dd2911cebb3a1a51d68b886dbda1c6f746ce3636357c47eceb98bac05cc0e5997e3a2dd702eb5c09be4ab37e57cc1603e7328f5abe5c5a89d
7
+ data.tar.gz: c15f0926711bd33265db8c142a50dc54c32f65a097d83c320bee452c2f96147d64355301000c2dd12a8650180e775e2d3544ea4986d4d030fa0f7ad64e8ae025
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.0 (2026-02-17)
4
+
5
+ - Add MetadataResolver to support VCR-compatible `vcr:` metadata alongside existing `use_cassette:` metadata.
6
+
3
7
  ## 0.1.0 (2026-02-16)
4
8
 
5
9
  - Initial release.
data/README.md CHANGED
@@ -23,7 +23,7 @@ Require the RSpec integration in your `spec_helper.rb` or `rails_helper.rb`:
23
23
  ```ruby
24
24
  require "rspec/cassette/rspec_helper"
25
25
 
26
- Rspec::Cassette.configure do |config|
26
+ RSpec::Cassette.configure do |config|
27
27
  config.cassettes_dir = "spec/fixtures/cassettes"
28
28
  config.default_match_on = %i[method uri]
29
29
  end
@@ -48,6 +48,18 @@ it "fetches users", use_cassette: "users/index" do
48
48
  end
49
49
  ```
50
50
 
51
+ VCR metadata compatibility style:
52
+
53
+ ```ruby
54
+ it "fetches users", vcr: true do
55
+ # cassette name is auto-generated from example descriptions
56
+ end
57
+
58
+ it "matches request body", vcr: { cassette_name: "users/index", match_requests_on: %i[method uri body] } do
59
+ # ...
60
+ end
61
+ ```
62
+
51
63
  To pass match options per example:
52
64
 
53
65
  ```ruby
@@ -0,0 +1,113 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RSpec
4
+ module Cassette
5
+ class MetadataResolver
6
+ def initialize(example)
7
+ @example = example
8
+ end
9
+
10
+ def resolve
11
+ return resolved_from_use_cassette if metadata.key?(:use_cassette)
12
+
13
+ resolved_from_vcr_metadata
14
+ end
15
+
16
+ private
17
+
18
+ attr_reader :example
19
+
20
+ def metadata
21
+ example.metadata
22
+ end
23
+
24
+ def resolved_from_use_cassette
25
+ return nil unless metadata.key?(:use_cassette)
26
+
27
+ cassette_name = metadata[:use_cassette]
28
+ return nil unless cassette_name
29
+
30
+ {
31
+ cassette_name: cassette_name,
32
+ cassette_options: normalize_cassette_options(metadata[:cassette_options])
33
+ }
34
+ end
35
+
36
+ def resolved_from_vcr_metadata
37
+ vcr_metadata = metadata[:vcr]
38
+ return nil if vcr_metadata.nil? || vcr_metadata == false
39
+
40
+ return resolved_from_vcr_hash(vcr_metadata) if vcr_metadata.is_a?(Hash)
41
+
42
+ {
43
+ cassette_name: build_vcr_compatible_cassette_name,
44
+ cassette_options: {}
45
+ }
46
+ end
47
+
48
+ def resolved_from_vcr_hash(vcr_metadata)
49
+ cassette_name = fetch_vcr_cassette_name(vcr_metadata)
50
+ cassette_options = normalize_vcr_options(vcr_metadata)
51
+
52
+ {
53
+ cassette_name: cassette_name || build_vcr_compatible_cassette_name,
54
+ cassette_options: cassette_options
55
+ }
56
+ end
57
+
58
+ def normalize_vcr_options(vcr_metadata)
59
+ options = copy_hash_without_keys(vcr_metadata, :cassette_name, "cassette_name")
60
+ normalized_options = symbolize_hash_keys(options)
61
+
62
+ if normalized_options.key?(:match_requests_on)
63
+ normalized_options[:match_on] = normalized_options[:match_requests_on] unless normalized_options.key?(:match_on)
64
+ normalized_options.delete(:match_requests_on)
65
+ end
66
+
67
+ normalized_options
68
+ end
69
+
70
+ def fetch_vcr_cassette_name(vcr_metadata)
71
+ return vcr_metadata[:cassette_name] if vcr_metadata.key?(:cassette_name)
72
+ return vcr_metadata["cassette_name"] if vcr_metadata.key?("cassette_name")
73
+
74
+ nil
75
+ end
76
+
77
+ def normalize_cassette_options(options)
78
+ return {} unless options.is_a?(Hash)
79
+
80
+ symbolize_hash_keys(options)
81
+ end
82
+
83
+ def symbolize_hash_keys(hash)
84
+ hash.each_with_object({}) do |(key, value), normalized|
85
+ normalized[key.is_a?(String) ? key.to_sym : key] = value
86
+ end
87
+ end
88
+
89
+ def copy_hash_without_keys(hash, *keys)
90
+ hash.each_with_object({}) do |(key, value), copied|
91
+ copied[key] = value unless keys.include?(key)
92
+ end
93
+ end
94
+
95
+ def build_vcr_compatible_cassette_name
96
+ parts = example.example_group.parent_groups.reverse.map(&:description)
97
+ parts << example.description
98
+
99
+ parts
100
+ .compact
101
+ .map(&:to_s)
102
+ .map(&:strip)
103
+ .reject(&:empty?)
104
+ .map { |part| normalize_cassette_name_part(part) }
105
+ .join("/")
106
+ end
107
+
108
+ def normalize_cassette_name_part(part)
109
+ part.split("/").map { |segment| segment.gsub(/[^\w]+/, "_") }.join("/")
110
+ end
111
+ end
112
+ end
113
+ end
@@ -24,9 +24,8 @@ RSpec.configure do |config|
24
24
  config.include RSpec::Cassette::RSpecHelper
25
25
 
26
26
  config.around(:each) do |example|
27
- cassette_name = example.metadata[:use_cassette]
28
- options = example.metadata[:cassette_options] || {}
29
- use_cassette(cassette_name, **options) if cassette_name
27
+ resolved = RSpec::Cassette::MetadataResolver.new(example).resolve
28
+ use_cassette(resolved[:cassette_name], **resolved[:cassette_options]) if resolved
30
29
  example.run
31
30
  end
32
31
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RSpec
4
4
  module Cassette
5
- VERSION = "0.1.0"
5
+ VERSION = "0.2.0"
6
6
  end
7
7
  end
@@ -5,6 +5,7 @@ require_relative "cassette/errors"
5
5
  require_relative "cassette/configuration"
6
6
  require_relative "cassette/cassette"
7
7
  require_relative "cassette/interaction"
8
+ require_relative "cassette/metadata_resolver"
8
9
  require_relative "cassette/stub_registrar"
9
10
 
10
11
  module RSpec
@@ -41,5 +41,10 @@ module RSpec
41
41
  def initialize: (Cassette cassette, ?match_on: Array[Symbol] | nil) -> void
42
42
  def register!: () -> void
43
43
  end
44
+
45
+ class MetadataResolver
46
+ def initialize: (untyped example) -> void
47
+ def resolve: () -> Hash[Symbol, untyped]?
48
+ end
44
49
  end
45
50
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-cassette
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yudai Takada
@@ -53,6 +53,7 @@ files:
53
53
  - lib/rspec/cassette/configuration.rb
54
54
  - lib/rspec/cassette/errors.rb
55
55
  - lib/rspec/cassette/interaction.rb
56
+ - lib/rspec/cassette/metadata_resolver.rb
56
57
  - lib/rspec/cassette/rspec_helper.rb
57
58
  - lib/rspec/cassette/stub_registrar.rb
58
59
  - lib/rspec/cassette/version.rb