vcr 3.0.3 → 4.0.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 +4 -4
- data/lib/vcr.rb +18 -1
- data/lib/vcr/cassette.rb +11 -3
- data/lib/vcr/cassette/persisters/file_system.rb +1 -1
- data/lib/vcr/configuration.rb +3 -5
- data/lib/vcr/deprecations.rb +0 -62
- data/lib/vcr/errors.rb +16 -0
- data/lib/vcr/library_hooks/typhoeus.rb +37 -8
- data/lib/vcr/middleware/faraday.rb +5 -1
- data/lib/vcr/structs.rb +1 -1
- data/lib/vcr/util/hooks.rb +1 -0
- data/lib/vcr/version.rb +1 -1
- metadata +9 -249
- data/features/CHANGELOG.md +0 -710
- data/features/CONTRIBUTING.md +0 -26
- data/features/LICENSE.md +0 -20
- data/features/README.md +0 -339
- data/features/Upgrade.md +0 -289
- data/features/about_these_examples.md +0 -18
- data/features/cassettes/allow_unused_http_interactions.feature +0 -100
- data/features/cassettes/automatic_re_recording.feature +0 -72
- data/features/cassettes/decompress.feature +0 -74
- data/features/cassettes/dynamic_erb.feature +0 -100
- data/features/cassettes/exclusive.feature +0 -126
- data/features/cassettes/format.feature +0 -411
- data/features/cassettes/freezing_time.feature +0 -68
- data/features/cassettes/naming.feature +0 -28
- data/features/cassettes/no_cassette.feature +0 -152
- data/features/cassettes/update_content_length_header.feature +0 -112
- data/features/configuration/allow_http_connections_when_no_cassette.feature +0 -55
- data/features/configuration/cassette_library_dir.feature +0 -31
- data/features/configuration/debug_logging.feature +0 -58
- data/features/configuration/default_cassette_options.feature +0 -100
- data/features/configuration/filter_sensitive_data.feature +0 -153
- data/features/configuration/hook_into.feature +0 -172
- data/features/configuration/ignore_request.feature +0 -192
- data/features/configuration/preserve_exact_body_bytes.feature +0 -108
- data/features/configuration/query_parser.feature +0 -84
- data/features/configuration/uri_parser.feature +0 -93
- data/features/getting_started.md +0 -82
- data/features/hooks/after_http_request.feature +0 -58
- data/features/hooks/around_http_request.feature +0 -57
- data/features/hooks/before_http_request.feature +0 -63
- data/features/hooks/before_playback.feature +0 -184
- data/features/hooks/before_record.feature +0 -172
- data/features/http_libraries/em_http_request.feature +0 -250
- data/features/http_libraries/net_http.feature +0 -179
- data/features/middleware/faraday.feature +0 -56
- data/features/middleware/rack.feature +0 -92
- data/features/record_modes/all.feature +0 -82
- data/features/record_modes/new_episodes.feature +0 -79
- data/features/record_modes/none.feature +0 -72
- data/features/record_modes/once.feature +0 -95
- data/features/request_matching/README.md +0 -30
- data/features/request_matching/body.feature +0 -91
- data/features/request_matching/body_as_json.feature +0 -90
- data/features/request_matching/custom_matcher.feature +0 -135
- data/features/request_matching/headers.feature +0 -85
- data/features/request_matching/host.feature +0 -95
- data/features/request_matching/identical_request_sequence.feature +0 -89
- data/features/request_matching/method.feature +0 -96
- data/features/request_matching/path.feature +0 -96
- data/features/request_matching/playback_repeats.feature +0 -98
- data/features/request_matching/query.feature +0 -97
- data/features/request_matching/uri.feature +0 -94
- data/features/request_matching/uri_without_param.feature +0 -101
- data/features/step_definitions/cli_steps.rb +0 -199
- data/features/support/env.rb +0 -46
- data/features/support/http_lib_filters.rb +0 -46
- data/features/test_frameworks/cucumber.feature +0 -211
- data/features/test_frameworks/rspec_macro.feature +0 -81
- data/features/test_frameworks/rspec_metadata.feature +0 -150
- data/features/test_frameworks/test_unit.feature +0 -49
- data/lib/vcr/extensions/net_http_response.rb +0 -36
- data/lib/vcr/library_hooks/fakeweb.rb +0 -197
- data/spec/acceptance/concurrency_spec.rb +0 -51
- data/spec/acceptance/threading_spec.rb +0 -34
- data/spec/fixtures/cassette_spec/1_x_cassette.yml +0 -110
- data/spec/fixtures/cassette_spec/empty.yml +0 -0
- data/spec/fixtures/cassette_spec/example.yml +0 -111
- data/spec/fixtures/cassette_spec/with_localhost_requests.yml +0 -111
- data/spec/fixtures/fake_example_responses.yml +0 -110
- data/spec/fixtures/match_requests_on.yml +0 -187
- data/spec/lib/vcr/cassette/erb_renderer_spec.rb +0 -53
- data/spec/lib/vcr/cassette/http_interaction_list_spec.rb +0 -295
- data/spec/lib/vcr/cassette/migrator_spec.rb +0 -196
- data/spec/lib/vcr/cassette/persisters/file_system_spec.rb +0 -75
- data/spec/lib/vcr/cassette/persisters_spec.rb +0 -39
- data/spec/lib/vcr/cassette/serializers_spec.rb +0 -182
- data/spec/lib/vcr/cassette_spec.rb +0 -618
- data/spec/lib/vcr/configuration_spec.rb +0 -326
- data/spec/lib/vcr/deprecations_spec.rb +0 -85
- data/spec/lib/vcr/errors_spec.rb +0 -178
- data/spec/lib/vcr/extensions/net_http_response_spec.rb +0 -86
- data/spec/lib/vcr/library_hooks/excon_spec.rb +0 -104
- data/spec/lib/vcr/library_hooks/fakeweb_spec.rb +0 -169
- data/spec/lib/vcr/library_hooks/faraday_spec.rb +0 -68
- data/spec/lib/vcr/library_hooks/typhoeus_0.4_spec.rb +0 -36
- data/spec/lib/vcr/library_hooks/typhoeus_spec.rb +0 -162
- data/spec/lib/vcr/library_hooks/webmock_spec.rb +0 -117
- data/spec/lib/vcr/library_hooks_spec.rb +0 -51
- data/spec/lib/vcr/middleware/faraday_spec.rb +0 -181
- data/spec/lib/vcr/middleware/rack_spec.rb +0 -115
- data/spec/lib/vcr/request_ignorer_spec.rb +0 -70
- data/spec/lib/vcr/request_matcher_registry_spec.rb +0 -345
- data/spec/lib/vcr/structs_spec.rb +0 -732
- data/spec/lib/vcr/test_frameworks/cucumber_spec.rb +0 -107
- data/spec/lib/vcr/test_frameworks/rspec_spec.rb +0 -94
- data/spec/lib/vcr/util/hooks_spec.rb +0 -158
- data/spec/lib/vcr/util/internet_connection_spec.rb +0 -37
- data/spec/lib/vcr/util/version_checker_spec.rb +0 -31
- data/spec/lib/vcr/version_spec.rb +0 -27
- data/spec/lib/vcr_spec.rb +0 -354
- data/spec/monkey_patches.rb +0 -186
- data/spec/spec_helper.rb +0 -63
- data/spec/support/configuration_stubbing.rb +0 -8
- data/spec/support/cucumber_helpers.rb +0 -39
- data/spec/support/fixnum_extension.rb +0 -10
- data/spec/support/http_library_adapters.rb +0 -289
- data/spec/support/limited_uri.rb +0 -21
- data/spec/support/ruby_interpreter.rb +0 -7
- data/spec/support/shared_example_groups/excon.rb +0 -63
- data/spec/support/shared_example_groups/hook_into_http_library.rb +0 -594
- data/spec/support/shared_example_groups/request_hooks.rb +0 -59
- data/spec/support/sinatra_app.rb +0 -86
- data/spec/support/vcr_localhost_server.rb +0 -76
- data/spec/support/vcr_stub_helpers.rb +0 -17
| @@ -1,53 +0,0 @@ | |
| 1 | 
            -
            require 'spec_helper'
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            describe VCR::Cassette::ERBRenderer do
         | 
| 4 | 
            -
              describe '#render' do
         | 
| 5 | 
            -
                def render(*args)
         | 
| 6 | 
            -
                  described_class.new(*args).render
         | 
| 7 | 
            -
                end
         | 
| 8 | 
            -
             | 
| 9 | 
            -
                let(:no_vars_content) { '<%= 3 + 4 %>. Some ERB' }
         | 
| 10 | 
            -
                let(:vars_content) { '<%= var1 %>. ERB with Vars! <%= var2 %>' }
         | 
| 11 | 
            -
             | 
| 12 | 
            -
                context 'when ERB is disabled' do
         | 
| 13 | 
            -
                  it 'returns the given template' do
         | 
| 14 | 
            -
                    expect(render(no_vars_content, false)).to eq(no_vars_content)
         | 
| 15 | 
            -
                    expect(render(no_vars_content, nil)).to eq(no_vars_content)
         | 
| 16 | 
            -
                  end
         | 
| 17 | 
            -
                end
         | 
| 18 | 
            -
             | 
| 19 | 
            -
                context 'when ERB is enabled but no variables are passed' do
         | 
| 20 | 
            -
                  it 'renders the file content as ERB' do
         | 
| 21 | 
            -
                    expect(render(no_vars_content, true)).to eq("7. Some ERB")
         | 
| 22 | 
            -
                  end
         | 
| 23 | 
            -
             | 
| 24 | 
            -
                  it 'raises an appropriate error when the ERB template needs variables' do
         | 
| 25 | 
            -
                    expect {
         | 
| 26 | 
            -
                      render(vars_content, true, "vars")
         | 
| 27 | 
            -
                    }.to raise_error(VCR::Errors::MissingERBVariableError,
         | 
| 28 | 
            -
                      %{The ERB in the vars cassette file references undefined variable var1.  } +
         | 
| 29 | 
            -
                      %{Pass it to the cassette using :erb => #{ {:var1=>"some value"}.inspect }.}
         | 
| 30 | 
            -
                    )
         | 
| 31 | 
            -
                  end
         | 
| 32 | 
            -
             | 
| 33 | 
            -
                  it 'gracefully handles the template being nil' do
         | 
| 34 | 
            -
                    expect(render(nil, true)).to be_nil
         | 
| 35 | 
            -
                  end
         | 
| 36 | 
            -
                end
         | 
| 37 | 
            -
             | 
| 38 | 
            -
                context 'when ERB is enabled and variables are passed' do
         | 
| 39 | 
            -
                  it 'renders the file content as ERB with the passed variables' do
         | 
| 40 | 
            -
                    expect(render(vars_content, :var1 => 'foo', :var2 => 'bar')).to eq('foo. ERB with Vars! bar')
         | 
| 41 | 
            -
                  end
         | 
| 42 | 
            -
             | 
| 43 | 
            -
                  it 'raises an appropriate error when one or more of the needed variables are not passed' do
         | 
| 44 | 
            -
                    expect {
         | 
| 45 | 
            -
                      render(vars_content, { :var1 => 'foo' }, "vars")
         | 
| 46 | 
            -
                    }.to raise_error(VCR::Errors::MissingERBVariableError,
         | 
| 47 | 
            -
                      %{The ERB in the vars cassette file references undefined variable var2.  } +
         | 
| 48 | 
            -
                      %{Pass it to the cassette using :erb => #{ {:var1 => "foo", :var2 => "some value"}.inspect }.}
         | 
| 49 | 
            -
                    )
         | 
| 50 | 
            -
                  end
         | 
| 51 | 
            -
                end
         | 
| 52 | 
            -
              end
         | 
| 53 | 
            -
            end
         | 
| @@ -1,295 +0,0 @@ | |
| 1 | 
            -
            require 'vcr/util/logger'
         | 
| 2 | 
            -
            require 'vcr/cassette/http_interaction_list'
         | 
| 3 | 
            -
            require 'vcr/request_matcher_registry'
         | 
| 4 | 
            -
            require 'vcr/structs'
         | 
| 5 | 
            -
            require 'support/configuration_stubbing'
         | 
| 6 | 
            -
             | 
| 7 | 
            -
            module VCR
         | 
| 8 | 
            -
              class Cassette
         | 
| 9 | 
            -
                describe HTTPInteractionList do
         | 
| 10 | 
            -
                  include_context "configuration stubbing"
         | 
| 11 | 
            -
             | 
| 12 | 
            -
                  ::RSpec::Matchers.define :respond_with do |expected|
         | 
| 13 | 
            -
                    match { |a| expected.nil? ? a.nil? : a.body == expected }
         | 
| 14 | 
            -
                  end
         | 
| 15 | 
            -
             | 
| 16 | 
            -
                  before(:each) do
         | 
| 17 | 
            -
                    allow(VCR).to receive(:request_matchers).and_return(VCR::RequestMatcherRegistry.new)
         | 
| 18 | 
            -
                    allow(config).to receive(:logger).and_return(double.as_null_object)
         | 
| 19 | 
            -
                  end
         | 
| 20 | 
            -
             | 
| 21 | 
            -
                  def request_with(values)
         | 
| 22 | 
            -
                    VCR::Request.new.tap do |request|
         | 
| 23 | 
            -
                      values.each do |name, value|
         | 
| 24 | 
            -
                        request.send("#{name}=", value)
         | 
| 25 | 
            -
                      end
         | 
| 26 | 
            -
                    end
         | 
| 27 | 
            -
                  end
         | 
| 28 | 
            -
             | 
| 29 | 
            -
                  def response(body)
         | 
| 30 | 
            -
                    VCR::Response.new.tap do |r|
         | 
| 31 | 
            -
                      r.body = body
         | 
| 32 | 
            -
                      r.status = VCR::ResponseStatus.new(200)
         | 
| 33 | 
            -
                    end
         | 
| 34 | 
            -
                  end
         | 
| 35 | 
            -
             | 
| 36 | 
            -
                  def interaction(body, request_values)
         | 
| 37 | 
            -
                    VCR::HTTPInteraction.new \
         | 
| 38 | 
            -
                      request_with(request_values),
         | 
| 39 | 
            -
                      response(body)
         | 
| 40 | 
            -
                  end
         | 
| 41 | 
            -
             | 
| 42 | 
            -
                  let(:original_list_array) do [
         | 
| 43 | 
            -
                    interaction('put response', :method => :put),
         | 
| 44 | 
            -
                    interaction('post response 1', :method => :post),
         | 
| 45 | 
            -
                    interaction('post response 2', :method => :post)
         | 
| 46 | 
            -
                  ] end
         | 
| 47 | 
            -
             | 
| 48 | 
            -
                  let(:allow_playback_repeats) { false } # the default
         | 
| 49 | 
            -
                  let(:list) { HTTPInteractionList.new(original_list_array, [:method], allow_playback_repeats) }
         | 
| 50 | 
            -
             | 
| 51 | 
            -
                  describe "#has_used_interaction_matching?" do
         | 
| 52 | 
            -
                    it 'returns false when no interactions have been used' do
         | 
| 53 | 
            -
                      expect(list).not_to have_used_interaction_matching(request_with(:method => :put))
         | 
| 54 | 
            -
                    end
         | 
| 55 | 
            -
             | 
| 56 | 
            -
                    it 'returns true when there is a matching used interaction (even if there is also an unused one that matches)' do
         | 
| 57 | 
            -
                      list.response_for(request_with(:method => :post))
         | 
| 58 | 
            -
                      expect(list).to have_used_interaction_matching(request_with(:method => :post))
         | 
| 59 | 
            -
                    end
         | 
| 60 | 
            -
             | 
| 61 | 
            -
                    it 'returns false when none of the used interactions match' do
         | 
| 62 | 
            -
                      list.response_for(request_with(:method => :put))
         | 
| 63 | 
            -
                      expect(list).not_to have_used_interaction_matching(request_with(:method => :post))
         | 
| 64 | 
            -
                    end
         | 
| 65 | 
            -
                  end
         | 
| 66 | 
            -
             | 
| 67 | 
            -
                  describe "#remaining_unused_interaction_count" do
         | 
| 68 | 
            -
                    it 'returns the number of unused interactions' do
         | 
| 69 | 
            -
                      expect(list.remaining_unused_interaction_count).to eq(3)
         | 
| 70 | 
            -
             | 
| 71 | 
            -
                      list.response_for(request_with(:method => :get))
         | 
| 72 | 
            -
                      expect(list.remaining_unused_interaction_count).to eq(3)
         | 
| 73 | 
            -
             | 
| 74 | 
            -
                      list.response_for(request_with(:method => :put))
         | 
| 75 | 
            -
                      expect(list.remaining_unused_interaction_count).to eq(2)
         | 
| 76 | 
            -
             | 
| 77 | 
            -
                      list.response_for(request_with(:method => :put))
         | 
| 78 | 
            -
                      expect(list.remaining_unused_interaction_count).to eq(2)
         | 
| 79 | 
            -
             | 
| 80 | 
            -
                      list.response_for(request_with(:method => :post))
         | 
| 81 | 
            -
                      expect(list.remaining_unused_interaction_count).to eq(1)
         | 
| 82 | 
            -
             | 
| 83 | 
            -
                      list.response_for(request_with(:method => :post))
         | 
| 84 | 
            -
                      expect(list.remaining_unused_interaction_count).to eq(0)
         | 
| 85 | 
            -
             | 
| 86 | 
            -
                      list.response_for(request_with(:method => :post))
         | 
| 87 | 
            -
                      expect(list.remaining_unused_interaction_count).to eq(0)
         | 
| 88 | 
            -
                    end
         | 
| 89 | 
            -
                  end
         | 
| 90 | 
            -
             | 
| 91 | 
            -
                  describe "#assert_no_unused_interactions?" do
         | 
| 92 | 
            -
                    it 'should raise a SkippedHTTPRequestError when there are unused interactions left' do
         | 
| 93 | 
            -
                      expect {
         | 
| 94 | 
            -
                        list.assert_no_unused_interactions!
         | 
| 95 | 
            -
                      }.to raise_error(Errors::UnusedHTTPInteractionError)
         | 
| 96 | 
            -
             | 
| 97 | 
            -
                      list.response_for(request_with(:method => :put))
         | 
| 98 | 
            -
                      expect {
         | 
| 99 | 
            -
                        list.assert_no_unused_interactions!
         | 
| 100 | 
            -
                      }.to raise_error(Errors::UnusedHTTPInteractionError)
         | 
| 101 | 
            -
                    end
         | 
| 102 | 
            -
             | 
| 103 | 
            -
                    it 'should raise nothing when there are no unused interactions left' do
         | 
| 104 | 
            -
                      [:put, :post, :post].each do |method|
         | 
| 105 | 
            -
                        list.response_for(request_with(:method => method))
         | 
| 106 | 
            -
                      end
         | 
| 107 | 
            -
             | 
| 108 | 
            -
                      expect {
         | 
| 109 | 
            -
                        list.assert_no_unused_interactions!
         | 
| 110 | 
            -
                      }.not_to raise_error
         | 
| 111 | 
            -
                    end
         | 
| 112 | 
            -
             | 
| 113 | 
            -
                    context 'when the null logger is in use' do
         | 
| 114 | 
            -
                      before { allow(config).to receive(:logger).and_return(Logger::Null) }
         | 
| 115 | 
            -
             | 
| 116 | 
            -
                      it 'includes formatted request details in the error message' do
         | 
| 117 | 
            -
                        expect {
         | 
| 118 | 
            -
                          list.assert_no_unused_interactions!
         | 
| 119 | 
            -
                        }.to raise_error(/\[put/)
         | 
| 120 | 
            -
                      end
         | 
| 121 | 
            -
             | 
| 122 | 
            -
                      it 'includes formatted response details in the error message' do
         | 
| 123 | 
            -
                        expect {
         | 
| 124 | 
            -
                          list.assert_no_unused_interactions!
         | 
| 125 | 
            -
                        }.to raise_error(/\[200 "put response"\]/)
         | 
| 126 | 
            -
                      end
         | 
| 127 | 
            -
                    end
         | 
| 128 | 
            -
                  end
         | 
| 129 | 
            -
             | 
| 130 | 
            -
                  describe "has_interaction_matching?" do
         | 
| 131 | 
            -
                    it 'returns false when the list is empty' do
         | 
| 132 | 
            -
                      expect(HTTPInteractionList.new([], [:method])).not_to have_interaction_matching(double)
         | 
| 133 | 
            -
                    end
         | 
| 134 | 
            -
             | 
| 135 | 
            -
                    it 'returns false when there is no matching interaction' do
         | 
| 136 | 
            -
                      expect(list).not_to have_interaction_matching(request_with(:method => :get))
         | 
| 137 | 
            -
                    end
         | 
| 138 | 
            -
             | 
| 139 | 
            -
                    it 'returns true when there is a matching interaction' do
         | 
| 140 | 
            -
                      expect(list).to have_interaction_matching(request_with(:method => :post))
         | 
| 141 | 
            -
                    end
         | 
| 142 | 
            -
             | 
| 143 | 
            -
                    it 'does not consume the interactions when they match' do
         | 
| 144 | 
            -
                      expect(list).to have_interaction_matching(request_with(:method => :post))
         | 
| 145 | 
            -
                      expect(list.remaining_unused_interaction_count).to eq(3)
         | 
| 146 | 
            -
                      expect(list).to have_interaction_matching(request_with(:method => :post))
         | 
| 147 | 
            -
                      expect(list.remaining_unused_interaction_count).to eq(3)
         | 
| 148 | 
            -
                    end
         | 
| 149 | 
            -
             | 
| 150 | 
            -
                    it 'invokes each matcher block to find the matching interaction' do
         | 
| 151 | 
            -
                      VCR.request_matchers.register(:foo) { |r1, r2| true }
         | 
| 152 | 
            -
                      VCR.request_matchers.register(:bar) { |r1, r2| true }
         | 
| 153 | 
            -
             | 
| 154 | 
            -
                      calls = 0
         | 
| 155 | 
            -
                      VCR.request_matchers.register(:baz) { |r1, r2| calls += 1; calls == 2 }
         | 
| 156 | 
            -
             | 
| 157 | 
            -
                      list = HTTPInteractionList.new([
         | 
| 158 | 
            -
                        interaction('response', :method => :put)
         | 
| 159 | 
            -
                      ], [:foo, :bar, :baz])
         | 
| 160 | 
            -
             | 
| 161 | 
            -
                      expect(list).not_to have_interaction_matching(request_with(:method => :post))
         | 
| 162 | 
            -
                      expect(list).to     have_interaction_matching(request_with(:method => :post))
         | 
| 163 | 
            -
                    end
         | 
| 164 | 
            -
             | 
| 165 | 
            -
                    it "delegates to the parent list when it can't find a matching interaction" do
         | 
| 166 | 
            -
                      parent_list = double(:has_interaction_matching? => true)
         | 
| 167 | 
            -
                      expect(HTTPInteractionList.new( [], [:method], false, parent_list)).to have_interaction_matching(double)
         | 
| 168 | 
            -
                      parent_list = double(:has_interaction_matching? => false)
         | 
| 169 | 
            -
                      expect(HTTPInteractionList.new( [], [:method], false, parent_list)).not_to have_interaction_matching(double)
         | 
| 170 | 
            -
                    end
         | 
| 171 | 
            -
             | 
| 172 | 
            -
                    context 'when allow_playback_repeats is set to true' do
         | 
| 173 | 
            -
                      let(:allow_playback_repeats) { true }
         | 
| 174 | 
            -
             | 
| 175 | 
            -
                      it 'considers used interactions' do
         | 
| 176 | 
            -
                        list.response_for(request_with(:method => :put))
         | 
| 177 | 
            -
             | 
| 178 | 
            -
                        results = 10.times.map do
         | 
| 179 | 
            -
                          list.has_interaction_matching?(request_with(:method => :put))
         | 
| 180 | 
            -
                        end
         | 
| 181 | 
            -
             | 
| 182 | 
            -
                        expect(results).to eq([true] * 10)
         | 
| 183 | 
            -
                      end
         | 
| 184 | 
            -
                    end
         | 
| 185 | 
            -
             | 
| 186 | 
            -
                    context 'when allow_playback_repeats is set to false' do
         | 
| 187 | 
            -
                      let(:allow_playback_repeats) { false }
         | 
| 188 | 
            -
             | 
| 189 | 
            -
                      it 'does not consider used interactions' do
         | 
| 190 | 
            -
                        list.response_for(request_with(:method => :put))
         | 
| 191 | 
            -
             | 
| 192 | 
            -
                        result = 10.times.map do
         | 
| 193 | 
            -
                          list.has_interaction_matching?(request_with(:method => :put))
         | 
| 194 | 
            -
                        end
         | 
| 195 | 
            -
             | 
| 196 | 
            -
                        expect(result).to eq([false] * 10)
         | 
| 197 | 
            -
                      end
         | 
| 198 | 
            -
                    end
         | 
| 199 | 
            -
                  end
         | 
| 200 | 
            -
             | 
| 201 | 
            -
                  describe "#response_for" do
         | 
| 202 | 
            -
                    it 'returns nil when the list is empty' do
         | 
| 203 | 
            -
                      expect(HTTPInteractionList.new([], [:method]).response_for(double)).to respond_with(nil)
         | 
| 204 | 
            -
                    end
         | 
| 205 | 
            -
             | 
| 206 | 
            -
                    it 'returns nil when there is no matching interaction' do
         | 
| 207 | 
            -
                      response = HTTPInteractionList.new([
         | 
| 208 | 
            -
                        interaction('foo', :method => :post),
         | 
| 209 | 
            -
                        interaction('foo', :method => :put)
         | 
| 210 | 
            -
                      ], [:method]).response_for(
         | 
| 211 | 
            -
                        request_with(:method => :get)
         | 
| 212 | 
            -
                      )
         | 
| 213 | 
            -
             | 
| 214 | 
            -
                      expect(response).to respond_with(nil)
         | 
| 215 | 
            -
                    end
         | 
| 216 | 
            -
             | 
| 217 | 
            -
                    it 'returns the first matching interaction' do
         | 
| 218 | 
            -
                      list = HTTPInteractionList.new([
         | 
| 219 | 
            -
                        interaction('put response', :method => :put),
         | 
| 220 | 
            -
                        interaction('post response 1', :method => :post),
         | 
| 221 | 
            -
                        interaction('post response 2', :method => :post)
         | 
| 222 | 
            -
                      ], [:method])
         | 
| 223 | 
            -
             | 
| 224 | 
            -
                      expect(list.response_for(request_with(:method => :post))).to respond_with("post response 1")
         | 
| 225 | 
            -
                    end
         | 
| 226 | 
            -
             | 
| 227 | 
            -
                    it 'invokes each matcher block to find the matching interaction' do
         | 
| 228 | 
            -
                      VCR.request_matchers.register(:foo) { |r1, r2| true }
         | 
| 229 | 
            -
                      VCR.request_matchers.register(:bar) { |r1, r2| true }
         | 
| 230 | 
            -
             | 
| 231 | 
            -
                      calls = 0
         | 
| 232 | 
            -
                      VCR.request_matchers.register(:baz) { |r1, r2| calls += 1; calls == 2 }
         | 
| 233 | 
            -
             | 
| 234 | 
            -
                      list = HTTPInteractionList.new([
         | 
| 235 | 
            -
                        interaction('response', :method => :put)
         | 
| 236 | 
            -
                      ], [:foo, :bar, :baz])
         | 
| 237 | 
            -
             | 
| 238 | 
            -
                      expect(list.response_for(request_with(:method => :post))).to respond_with(nil)
         | 
| 239 | 
            -
                      expect(list.response_for(request_with(:method => :post))).to respond_with('response')
         | 
| 240 | 
            -
                    end
         | 
| 241 | 
            -
             | 
| 242 | 
            -
                    it "delegates to the parent list when it can't find a matching interaction" do
         | 
| 243 | 
            -
                      parent_list = double(:response_for => response('parent'))
         | 
| 244 | 
            -
                      result = HTTPInteractionList.new(
         | 
| 245 | 
            -
                        [], [:method], false, parent_list
         | 
| 246 | 
            -
                      ).response_for(double)
         | 
| 247 | 
            -
             | 
| 248 | 
            -
                      expect(result).to respond_with('parent')
         | 
| 249 | 
            -
                    end
         | 
| 250 | 
            -
             | 
| 251 | 
            -
                    it 'consumes the first matching interaction so that it will not be used again' do
         | 
| 252 | 
            -
                      expect(list.response_for(request_with(:method => :post)).body).to eq("post response 1")
         | 
| 253 | 
            -
                      expect(list.response_for(request_with(:method => :post)).body).to eq("post response 2")
         | 
| 254 | 
            -
                    end
         | 
| 255 | 
            -
             | 
| 256 | 
            -
                    context 'when allow_playback_repeats is set to true' do
         | 
| 257 | 
            -
                      let(:allow_playback_repeats) { true }
         | 
| 258 | 
            -
             | 
| 259 | 
            -
                      it 'continues to return the response from the last matching interaction when there are no more' do
         | 
| 260 | 
            -
                        list.response_for(request_with(:method => :post))
         | 
| 261 | 
            -
             | 
| 262 | 
            -
                        results = 10.times.map do
         | 
| 263 | 
            -
                          response = list.response_for(request_with(:method => :post))
         | 
| 264 | 
            -
                          response ? response.body : nil
         | 
| 265 | 
            -
                        end
         | 
| 266 | 
            -
             | 
| 267 | 
            -
                        expect(results).to eq(["post response 2"] * 10)
         | 
| 268 | 
            -
                      end
         | 
| 269 | 
            -
                    end
         | 
| 270 | 
            -
             | 
| 271 | 
            -
                    context 'when allow_playback_repeats is set to false' do
         | 
| 272 | 
            -
                      let(:allow_playback_repeats) { false }
         | 
| 273 | 
            -
             | 
| 274 | 
            -
                      it 'returns nil when there are no more unused interactions' do
         | 
| 275 | 
            -
                        list.response_for(request_with(:method => :post))
         | 
| 276 | 
            -
                        list.response_for(request_with(:method => :post))
         | 
| 277 | 
            -
             | 
| 278 | 
            -
                        results = 10.times.map do
         | 
| 279 | 
            -
                          list.response_for(request_with(:method => :post))
         | 
| 280 | 
            -
                        end
         | 
| 281 | 
            -
             | 
| 282 | 
            -
                        expect(results).to eq([nil] * 10)
         | 
| 283 | 
            -
                      end
         | 
| 284 | 
            -
                    end
         | 
| 285 | 
            -
             | 
| 286 | 
            -
                    it 'does not modify the original interaction array the list was initialized with' do
         | 
| 287 | 
            -
                      original_dup = original_list_array.dup
         | 
| 288 | 
            -
                      list.response_for(request_with(:method => :post))
         | 
| 289 | 
            -
                      expect(original_list_array).to eq original_dup
         | 
| 290 | 
            -
                    end
         | 
| 291 | 
            -
                  end
         | 
| 292 | 
            -
                end
         | 
| 293 | 
            -
              end
         | 
| 294 | 
            -
            end
         | 
| 295 | 
            -
             | 
| @@ -1,196 +0,0 @@ | |
| 1 | 
            -
            require 'tmpdir'
         | 
| 2 | 
            -
            require 'vcr/cassette/migrator'
         | 
| 3 | 
            -
            require 'yaml'
         | 
| 4 | 
            -
             | 
| 5 | 
            -
            describe VCR::Cassette::Migrator do
         | 
| 6 | 
            -
              let(:original_contents) { <<-EOF
         | 
| 7 | 
            -
            ---
         | 
| 8 | 
            -
            - !ruby/struct:VCR::HTTPInteraction
         | 
| 9 | 
            -
              request: !ruby/struct:VCR::Request
         | 
| 10 | 
            -
                method: :get
         | 
| 11 | 
            -
                uri: http://example.com:80/foo
         | 
| 12 | 
            -
                body:
         | 
| 13 | 
            -
                headers:
         | 
| 14 | 
            -
              response: !ruby/struct:VCR::Response
         | 
| 15 | 
            -
                status: !ruby/struct:VCR::ResponseStatus
         | 
| 16 | 
            -
                  code: 200
         | 
| 17 | 
            -
                  message: OK
         | 
| 18 | 
            -
                headers:
         | 
| 19 | 
            -
                  content-type:
         | 
| 20 | 
            -
                  - text/html;charset=utf-8
         | 
| 21 | 
            -
                  content-length:
         | 
| 22 | 
            -
                  - "9"
         | 
| 23 | 
            -
                body: Hello foo
         | 
| 24 | 
            -
                http_version: "1.1"
         | 
| 25 | 
            -
            - !ruby/struct:VCR::HTTPInteraction
         | 
| 26 | 
            -
              request: !ruby/struct:VCR::Request
         | 
| 27 | 
            -
                method: :get
         | 
| 28 | 
            -
                uri: http://localhost:7777/bar
         | 
| 29 | 
            -
                body:
         | 
| 30 | 
            -
                headers:
         | 
| 31 | 
            -
              response: !ruby/struct:VCR::Response
         | 
| 32 | 
            -
                status: !ruby/struct:VCR::ResponseStatus
         | 
| 33 | 
            -
                  code: 200
         | 
| 34 | 
            -
                  message: OK
         | 
| 35 | 
            -
                headers:
         | 
| 36 | 
            -
                  content-type:
         | 
| 37 | 
            -
                  - text/html;charset=utf-8
         | 
| 38 | 
            -
                  content-length:
         | 
| 39 | 
            -
                  - "9"
         | 
| 40 | 
            -
                body: Hello bar
         | 
| 41 | 
            -
                http_version: "1.1"
         | 
| 42 | 
            -
            EOF
         | 
| 43 | 
            -
              }
         | 
| 44 | 
            -
             | 
| 45 | 
            -
              let(:updated_contents) { <<-EOF
         | 
| 46 | 
            -
            ---
         | 
| 47 | 
            -
            http_interactions:
         | 
| 48 | 
            -
            - request:
         | 
| 49 | 
            -
                method: get
         | 
| 50 | 
            -
                uri: http://example.com/foo
         | 
| 51 | 
            -
                body:
         | 
| 52 | 
            -
                  encoding: US-ASCII
         | 
| 53 | 
            -
                  string: ""
         | 
| 54 | 
            -
                headers: {}
         | 
| 55 | 
            -
             | 
| 56 | 
            -
              response:
         | 
| 57 | 
            -
                status:
         | 
| 58 | 
            -
                  code: 200
         | 
| 59 | 
            -
                  message: OK
         | 
| 60 | 
            -
                headers:
         | 
| 61 | 
            -
                  Content-Type:
         | 
| 62 | 
            -
                  - text/html;charset=utf-8
         | 
| 63 | 
            -
                  Content-Length:
         | 
| 64 | 
            -
                  - "9"
         | 
| 65 | 
            -
                body:
         | 
| 66 | 
            -
                  encoding: UTF-8
         | 
| 67 | 
            -
                  string: Hello foo
         | 
| 68 | 
            -
                http_version: "1.1"
         | 
| 69 | 
            -
              recorded_at: Wed, 04 May 2011 12:30:00 GMT
         | 
| 70 | 
            -
            - request:
         | 
| 71 | 
            -
                method: get
         | 
| 72 | 
            -
                uri: http://localhost:7777/bar
         | 
| 73 | 
            -
                body:
         | 
| 74 | 
            -
                  encoding: US-ASCII
         | 
| 75 | 
            -
                  string: ""
         | 
| 76 | 
            -
                headers: {}
         | 
| 77 | 
            -
             | 
| 78 | 
            -
              response:
         | 
| 79 | 
            -
                status:
         | 
| 80 | 
            -
                  code: 200
         | 
| 81 | 
            -
                  message: OK
         | 
| 82 | 
            -
                headers:
         | 
| 83 | 
            -
                  Content-Type:
         | 
| 84 | 
            -
                  - text/html;charset=utf-8
         | 
| 85 | 
            -
                  Content-Length:
         | 
| 86 | 
            -
                  - "9"
         | 
| 87 | 
            -
                body:
         | 
| 88 | 
            -
                  encoding: UTF-8
         | 
| 89 | 
            -
                  string: Hello bar
         | 
| 90 | 
            -
                http_version: "1.1"
         | 
| 91 | 
            -
              recorded_at: Wed, 04 May 2011 12:30:00 GMT
         | 
| 92 | 
            -
            recorded_with: VCR #{VCR.version}
         | 
| 93 | 
            -
            EOF
         | 
| 94 | 
            -
              }
         | 
| 95 | 
            -
             | 
| 96 | 
            -
              let(:dir) { './tmp/migrator' }
         | 
| 97 | 
            -
             | 
| 98 | 
            -
              before(:each) do
         | 
| 99 | 
            -
                # ensure the directory is empty
         | 
| 100 | 
            -
                FileUtils.rm_rf dir
         | 
| 101 | 
            -
                FileUtils.mkdir_p dir
         | 
| 102 | 
            -
              end
         | 
| 103 | 
            -
             | 
| 104 | 
            -
              before(:each) do
         | 
| 105 | 
            -
                # the encoding won't be set on rubies that don't support it
         | 
| 106 | 
            -
                updated_contents.gsub!(/^\s+encoding:.*$/, '')
         | 
| 107 | 
            -
              end unless ''.respond_to?(:encoding)
         | 
| 108 | 
            -
             | 
| 109 | 
            -
              # JRuby serializes YAML with some slightly different whitespace.
         | 
| 110 | 
            -
              before(:each) do
         | 
| 111 | 
            -
                [original_contents, updated_contents].each do |contents|
         | 
| 112 | 
            -
                  contents.gsub!(/^(\s+)-/, '\1  -')
         | 
| 113 | 
            -
                end
         | 
| 114 | 
            -
                updated_contents.gsub!(/^(- |  )/, '  \1')
         | 
| 115 | 
            -
              end if RUBY_PLATFORM == 'java'
         | 
| 116 | 
            -
             | 
| 117 | 
            -
              # Use syck on all rubies for consistent results...
         | 
| 118 | 
            -
              around(:each) do |example|
         | 
| 119 | 
            -
                YAML::ENGINE.yamler = 'syck'
         | 
| 120 | 
            -
                begin
         | 
| 121 | 
            -
                  example.call
         | 
| 122 | 
            -
                ensure
         | 
| 123 | 
            -
                  YAML::ENGINE.yamler = 'psych'
         | 
| 124 | 
            -
                end
         | 
| 125 | 
            -
              end if defined?(YAML::ENGINE) && RUBY_VERSION.to_f < 2.0
         | 
| 126 | 
            -
             | 
| 127 | 
            -
              let(:filemtime) { Time.utc(2011, 5, 4, 12, 30) }
         | 
| 128 | 
            -
              let(:out_io)    { StringIO.new }
         | 
| 129 | 
            -
              let(:file_name) { File.join(dir, "example.yml") }
         | 
| 130 | 
            -
              let(:output)    { out_io.rewind; out_io.read }
         | 
| 131 | 
            -
             | 
| 132 | 
            -
              subject { described_class.new(dir, out_io) }
         | 
| 133 | 
            -
             | 
| 134 | 
            -
              before(:each) do
         | 
| 135 | 
            -
                allow(File).to receive(:mtime).with(file_name).and_return(filemtime)
         | 
| 136 | 
            -
              end
         | 
| 137 | 
            -
             | 
| 138 | 
            -
              it 'migrates a cassette from the 1.x to 2.x format' do
         | 
| 139 | 
            -
                File.open(file_name, 'w') { |f| f.write(original_contents) }
         | 
| 140 | 
            -
                subject.migrate!
         | 
| 141 | 
            -
                expect(YAML.load_file(file_name)).to eq(YAML.load(updated_contents))
         | 
| 142 | 
            -
                expect(output).to match(/Migrated example.yml/)
         | 
| 143 | 
            -
              end
         | 
| 144 | 
            -
             | 
| 145 | 
            -
              it 'ignores files that do not contain arrays' do
         | 
| 146 | 
            -
                File.open(file_name, 'w') { |f| f.write(true.to_yaml) }
         | 
| 147 | 
            -
                subject.migrate!
         | 
| 148 | 
            -
                expect(File.read(file_name)).to eq(true.to_yaml)
         | 
| 149 | 
            -
                expect(output).to match(/Ignored example.yml since it does not appear to be a valid VCR 1.x cassette/)
         | 
| 150 | 
            -
              end
         | 
| 151 | 
            -
             | 
| 152 | 
            -
              it 'ignores files that contain YAML arrays of other things' do
         | 
| 153 | 
            -
                File.open(file_name, 'w') { |f| f.write([{}, {}].to_yaml) }
         | 
| 154 | 
            -
                subject.migrate!
         | 
| 155 | 
            -
                expect(File.read(file_name)).to eq([{}, {}].to_yaml)
         | 
| 156 | 
            -
                expect(output).to match(/Ignored example.yml since it does not appear to be a valid VCR 1.x cassette/)
         | 
| 157 | 
            -
              end
         | 
| 158 | 
            -
             | 
| 159 | 
            -
              it 'ignores URIs that have sensitive data substitutions' do
         | 
| 160 | 
            -
                modified_contents = original_contents.gsub('example.com', '<HOST>')
         | 
| 161 | 
            -
                File.open(file_name, 'w') { |f| f.write(modified_contents) }
         | 
| 162 | 
            -
                subject.migrate!
         | 
| 163 | 
            -
                expect(YAML.load_file(file_name)).to eq(YAML.load(updated_contents.gsub('example.com', '<HOST>:80')))
         | 
| 164 | 
            -
              end
         | 
| 165 | 
            -
             | 
| 166 | 
            -
              it 'ignores files that are empty' do
         | 
| 167 | 
            -
                File.open(file_name, 'w') { |f| f.write('') }
         | 
| 168 | 
            -
                subject.migrate!
         | 
| 169 | 
            -
                expect(File.read(file_name)).to eq('')
         | 
| 170 | 
            -
                expect(output).to match(/Ignored example.yml since it could not be parsed as YAML/)
         | 
| 171 | 
            -
              end
         | 
| 172 | 
            -
             | 
| 173 | 
            -
              shared_examples_for "ignoring invalid YAML" do
         | 
| 174 | 
            -
                it 'ignores files that cannot be parsed as valid YAML (such as ERB cassettes)' do
         | 
| 175 | 
            -
                  modified_contents = original_contents.gsub(/\A---/, "---\n<% 3.times do %>")
         | 
| 176 | 
            -
                  modified_contents = modified_contents.gsub(/\z/, "<% end %>")
         | 
| 177 | 
            -
                  File.open(file_name, 'w') { |f| f.write(modified_contents) }
         | 
| 178 | 
            -
                  subject.migrate!
         | 
| 179 | 
            -
                  expect(File.read(file_name)).to eq(modified_contents)
         | 
| 180 | 
            -
                  expect(output).to match(/Ignored example.yml since it could not be parsed as YAML/)
         | 
| 181 | 
            -
                end
         | 
| 182 | 
            -
              end
         | 
| 183 | 
            -
             | 
| 184 | 
            -
              context 'with syck' do
         | 
| 185 | 
            -
                it_behaves_like "ignoring invalid YAML"
         | 
| 186 | 
            -
              end
         | 
| 187 | 
            -
             | 
| 188 | 
            -
              context 'with psych' do
         | 
| 189 | 
            -
                before(:each) do
         | 
| 190 | 
            -
                  YAML::ENGINE.yamler = 'psych'
         | 
| 191 | 
            -
                end
         | 
| 192 | 
            -
             | 
| 193 | 
            -
                it_behaves_like "ignoring invalid YAML"
         | 
| 194 | 
            -
              end if defined?(YAML::ENGINE)
         | 
| 195 | 
            -
            end
         | 
| 196 | 
            -
             |