mustwin-vcr 2.9.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/features/about_these_examples.md +18 -0
- data/features/cassettes/allow_unused_http_interactions.feature +100 -0
- data/features/cassettes/automatic_re_recording.feature +72 -0
- data/features/cassettes/decompress.feature +74 -0
- data/features/cassettes/dynamic_erb.feature +100 -0
- data/features/cassettes/exclusive.feature +126 -0
- data/features/cassettes/format.feature +323 -0
- data/features/cassettes/freezing_time.feature +68 -0
- data/features/cassettes/naming.feature +28 -0
- data/features/cassettes/no_cassette.feature +152 -0
- data/features/cassettes/update_content_length_header.feature +112 -0
- data/features/configuration/allow_http_connections_when_no_cassette.feature +55 -0
- data/features/configuration/cassette_library_dir.feature +31 -0
- data/features/configuration/debug_logging.feature +59 -0
- data/features/configuration/default_cassette_options.feature +100 -0
- data/features/configuration/filter_sensitive_data.feature +153 -0
- data/features/configuration/hook_into.feature +172 -0
- data/features/configuration/ignore_request.feature +192 -0
- data/features/configuration/preserve_exact_body_bytes.feature +108 -0
- data/features/configuration/query_parser.feature +84 -0
- data/features/configuration/uri_parser.feature +89 -0
- data/features/getting_started.md +82 -0
- data/features/hooks/after_http_request.feature +58 -0
- data/features/hooks/around_http_request.feature +57 -0
- data/features/hooks/before_http_request.feature +63 -0
- data/features/hooks/before_playback.feature +184 -0
- data/features/hooks/before_record.feature +172 -0
- data/features/http_libraries/em_http_request.feature +250 -0
- data/features/http_libraries/net_http.feature +179 -0
- data/features/middleware/faraday.feature +56 -0
- data/features/middleware/rack.feature +92 -0
- data/features/record_modes/all.feature +82 -0
- data/features/record_modes/new_episodes.feature +79 -0
- data/features/record_modes/none.feature +72 -0
- data/features/record_modes/once.feature +95 -0
- data/features/request_matching/README.md +30 -0
- data/features/request_matching/body.feature +91 -0
- data/features/request_matching/body_as_json.feature +90 -0
- data/features/request_matching/custom_matcher.feature +135 -0
- data/features/request_matching/headers.feature +85 -0
- data/features/request_matching/host.feature +95 -0
- data/features/request_matching/identical_request_sequence.feature +89 -0
- data/features/request_matching/method.feature +96 -0
- data/features/request_matching/path.feature +96 -0
- data/features/request_matching/playback_repeats.feature +98 -0
- data/features/request_matching/query.feature +97 -0
- data/features/request_matching/uri.feature +94 -0
- data/features/request_matching/uri_without_param.feature +101 -0
- data/features/step_definitions/cli_steps.rb +193 -0
- data/features/support/env.rb +44 -0
- data/features/support/http_lib_filters.rb +53 -0
- data/features/test_frameworks/cucumber.feature +211 -0
- data/features/test_frameworks/rspec_macro.feature +81 -0
- data/features/test_frameworks/rspec_metadata.feature +150 -0
- data/features/test_frameworks/test_unit.feature +49 -0
- data/lib/vcr.rb +347 -0
- data/lib/vcr/cassette.rb +291 -0
- data/lib/vcr/cassette/erb_renderer.rb +55 -0
- data/lib/vcr/cassette/http_interaction_list.rb +108 -0
- data/lib/vcr/cassette/migrator.rb +118 -0
- data/lib/vcr/cassette/persisters.rb +42 -0
- data/lib/vcr/cassette/persisters/file_system.rb +64 -0
- data/lib/vcr/cassette/serializers.rb +57 -0
- data/lib/vcr/cassette/serializers/json.rb +48 -0
- data/lib/vcr/cassette/serializers/psych.rb +48 -0
- data/lib/vcr/cassette/serializers/syck.rb +61 -0
- data/lib/vcr/cassette/serializers/yaml.rb +50 -0
- data/lib/vcr/configuration.rb +555 -0
- data/lib/vcr/deprecations.rb +109 -0
- data/lib/vcr/errors.rb +266 -0
- data/lib/vcr/extensions/net_http_response.rb +36 -0
- data/lib/vcr/library_hooks.rb +18 -0
- data/lib/vcr/library_hooks/excon.rb +27 -0
- data/lib/vcr/library_hooks/fakeweb.rb +196 -0
- data/lib/vcr/library_hooks/faraday.rb +51 -0
- data/lib/vcr/library_hooks/typhoeus.rb +120 -0
- data/lib/vcr/library_hooks/typhoeus_0.4.rb +103 -0
- data/lib/vcr/library_hooks/webmock.rb +164 -0
- data/lib/vcr/middleware/excon.rb +221 -0
- data/lib/vcr/middleware/excon/legacy_methods.rb +33 -0
- data/lib/vcr/middleware/faraday.rb +118 -0
- data/lib/vcr/middleware/rack.rb +79 -0
- data/lib/vcr/request_handler.rb +114 -0
- data/lib/vcr/request_ignorer.rb +43 -0
- data/lib/vcr/request_matcher_registry.rb +149 -0
- data/lib/vcr/structs.rb +578 -0
- data/lib/vcr/tasks/vcr.rake +9 -0
- data/lib/vcr/test_frameworks/cucumber.rb +64 -0
- data/lib/vcr/test_frameworks/rspec.rb +47 -0
- data/lib/vcr/util/hooks.rb +61 -0
- data/lib/vcr/util/internet_connection.rb +43 -0
- data/lib/vcr/util/logger.rb +59 -0
- data/lib/vcr/util/variable_args_block_caller.rb +13 -0
- data/lib/vcr/util/version_checker.rb +48 -0
- data/lib/vcr/version.rb +34 -0
- data/spec/acceptance/threading_spec.rb +34 -0
- data/spec/fixtures/cassette_spec/1_x_cassette.yml +110 -0
- data/spec/fixtures/cassette_spec/empty.yml +0 -0
- data/spec/fixtures/cassette_spec/example.yml +111 -0
- data/spec/fixtures/cassette_spec/with_localhost_requests.yml +111 -0
- data/spec/fixtures/fake_example_responses.yml +110 -0
- data/spec/fixtures/match_requests_on.yml +187 -0
- data/spec/lib/vcr/cassette/erb_renderer_spec.rb +53 -0
- data/spec/lib/vcr/cassette/http_interaction_list_spec.rb +295 -0
- data/spec/lib/vcr/cassette/migrator_spec.rb +195 -0
- data/spec/lib/vcr/cassette/persisters/file_system_spec.rb +69 -0
- data/spec/lib/vcr/cassette/persisters_spec.rb +39 -0
- data/spec/lib/vcr/cassette/serializers_spec.rb +176 -0
- data/spec/lib/vcr/cassette_spec.rb +618 -0
- data/spec/lib/vcr/configuration_spec.rb +326 -0
- data/spec/lib/vcr/deprecations_spec.rb +85 -0
- data/spec/lib/vcr/errors_spec.rb +162 -0
- data/spec/lib/vcr/extensions/net_http_response_spec.rb +86 -0
- data/spec/lib/vcr/library_hooks/excon_spec.rb +104 -0
- data/spec/lib/vcr/library_hooks/fakeweb_spec.rb +169 -0
- data/spec/lib/vcr/library_hooks/faraday_spec.rb +68 -0
- data/spec/lib/vcr/library_hooks/typhoeus_0.4_spec.rb +36 -0
- data/spec/lib/vcr/library_hooks/typhoeus_spec.rb +162 -0
- data/spec/lib/vcr/library_hooks/webmock_spec.rb +118 -0
- data/spec/lib/vcr/library_hooks_spec.rb +51 -0
- data/spec/lib/vcr/middleware/faraday_spec.rb +182 -0
- data/spec/lib/vcr/middleware/rack_spec.rb +115 -0
- data/spec/lib/vcr/request_ignorer_spec.rb +70 -0
- data/spec/lib/vcr/request_matcher_registry_spec.rb +345 -0
- data/spec/lib/vcr/structs_spec.rb +732 -0
- data/spec/lib/vcr/test_frameworks/cucumber_spec.rb +107 -0
- data/spec/lib/vcr/test_frameworks/rspec_spec.rb +83 -0
- data/spec/lib/vcr/util/hooks_spec.rb +158 -0
- data/spec/lib/vcr/util/internet_connection_spec.rb +37 -0
- data/spec/lib/vcr/util/version_checker_spec.rb +31 -0
- data/spec/lib/vcr/version_spec.rb +27 -0
- data/spec/lib/vcr_spec.rb +349 -0
- data/spec/monkey_patches.rb +182 -0
- data/spec/spec_helper.rb +62 -0
- data/spec/support/configuration_stubbing.rb +8 -0
- data/spec/support/cucumber_helpers.rb +35 -0
- data/spec/support/fixnum_extension.rb +10 -0
- data/spec/support/http_library_adapters.rb +289 -0
- data/spec/support/limited_uri.rb +21 -0
- data/spec/support/ruby_interpreter.rb +7 -0
- data/spec/support/shared_example_groups/excon.rb +63 -0
- data/spec/support/shared_example_groups/hook_into_http_library.rb +594 -0
- data/spec/support/shared_example_groups/request_hooks.rb +59 -0
- data/spec/support/sinatra_app.rb +86 -0
- data/spec/support/vcr_localhost_server.rb +76 -0
- data/spec/support/vcr_stub_helpers.rb +17 -0
- metadata +677 -0
@@ -0,0 +1,9 @@
|
|
1
|
+
namespace :vcr do
|
2
|
+
desc "Migrate cassettes from the VCR 1.x format to the VCR 2.x format."
|
3
|
+
task :migrate_cassettes do
|
4
|
+
dir = ENV.fetch('DIR') { raise "You must pass the cassette library directory as DIR=<directory>" }
|
5
|
+
require 'vcr/cassette/migrator'
|
6
|
+
VCR::Cassette::Migrator.new(dir).migrate!
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module VCR
|
2
|
+
# Provides integration with Cucumber using tags.
|
3
|
+
class CucumberTags
|
4
|
+
class << self
|
5
|
+
# @private
|
6
|
+
def tags
|
7
|
+
@tags.dup
|
8
|
+
end
|
9
|
+
|
10
|
+
# @private
|
11
|
+
def add_tag(tag)
|
12
|
+
@tags << tag
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
@tags = []
|
17
|
+
|
18
|
+
# @private
|
19
|
+
def initialize(main_object)
|
20
|
+
@main_object = main_object
|
21
|
+
end
|
22
|
+
|
23
|
+
# Adds `Before` and `After` cucumber hooks for the named tags that
|
24
|
+
# will cause a VCR cassette to be used for scenarios with matching tags.
|
25
|
+
#
|
26
|
+
# @param [Array<String>] tag_names the cucumber scenario tags
|
27
|
+
# @param [(optional) Hash] options the cassette options. Specify
|
28
|
+
# `:use_scenario_name => true` to automatically name the
|
29
|
+
# cassette according to the scenario name.
|
30
|
+
def tags(*tag_names)
|
31
|
+
original_options = tag_names.last.is_a?(::Hash) ? tag_names.pop : {}
|
32
|
+
tag_names.each do |tag_name|
|
33
|
+
tag_name = "@#{tag_name}" unless tag_name =~ /\A@/
|
34
|
+
|
35
|
+
# It would be nice to use an Around hook here, but
|
36
|
+
# cucumber has a bug: background steps do not run
|
37
|
+
# within an around hook.
|
38
|
+
# https://gist.github.com/652968
|
39
|
+
@main_object.Before(tag_name) do |scenario|
|
40
|
+
options = original_options.dup
|
41
|
+
|
42
|
+
cassette_name = if options.delete(:use_scenario_name)
|
43
|
+
feature = scenario.respond_to?(:scenario_outline) ? scenario.scenario_outline.feature : scenario.feature
|
44
|
+
name = feature.name.split("\n").first
|
45
|
+
name << "/#{scenario.scenario_outline.name}" if scenario.respond_to?(:scenario_outline)
|
46
|
+
name << "/#{scenario.name.split("\n").first}"
|
47
|
+
name
|
48
|
+
else
|
49
|
+
"cucumber_tags/#{tag_name.gsub(/\A@/, '')}"
|
50
|
+
end
|
51
|
+
|
52
|
+
VCR.insert_cassette(cassette_name, options)
|
53
|
+
end
|
54
|
+
|
55
|
+
@main_object.After(tag_name) do |scenario|
|
56
|
+
VCR.eject_cassette(:skip_no_unused_interactions_assertion => scenario.failed?)
|
57
|
+
end
|
58
|
+
|
59
|
+
self.class.add_tag(tag_name)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
alias :tag :tags
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module VCR
|
2
|
+
# Integrates VCR with RSpec.
|
3
|
+
module RSpec
|
4
|
+
# @private
|
5
|
+
module Metadata
|
6
|
+
extend self
|
7
|
+
|
8
|
+
def configure!
|
9
|
+
::RSpec.configure do |config|
|
10
|
+
vcr_cassette_name_for = lambda do |metadata|
|
11
|
+
description = metadata[:description]
|
12
|
+
example_group = if metadata.key?(:example_group)
|
13
|
+
metadata[:example_group]
|
14
|
+
else
|
15
|
+
metadata[:parent_example_group]
|
16
|
+
end
|
17
|
+
|
18
|
+
if example_group
|
19
|
+
[vcr_cassette_name_for[example_group], description].join('/')
|
20
|
+
else
|
21
|
+
description
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
when_tagged_with_vcr = { :vcr => lambda { |v| !!v } }
|
26
|
+
|
27
|
+
config.before(:each, when_tagged_with_vcr) do |ex|
|
28
|
+
example = ex.respond_to?(:metadata) ? ex : ex.example
|
29
|
+
|
30
|
+
options = example.metadata[:vcr]
|
31
|
+
options = options.is_a?(Hash) ? options.dup : {} # in case it's just :vcr => true
|
32
|
+
|
33
|
+
cassette_name = options.delete(:cassette_name) ||
|
34
|
+
vcr_cassette_name_for[example.metadata]
|
35
|
+
VCR.insert_cassette(cassette_name, options)
|
36
|
+
end
|
37
|
+
|
38
|
+
config.after(:each, when_tagged_with_vcr) do |ex|
|
39
|
+
example = ex.respond_to?(:metadata) ? ex : ex.example
|
40
|
+
VCR.eject_cassette(:skip_no_unused_interactions_assertion => !!example.exception)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'vcr/util/variable_args_block_caller'
|
2
|
+
|
3
|
+
module VCR
|
4
|
+
# @private
|
5
|
+
module Hooks
|
6
|
+
include VariableArgsBlockCaller
|
7
|
+
|
8
|
+
FilteredHook = Struct.new(:hook, :filters) do
|
9
|
+
include VariableArgsBlockCaller
|
10
|
+
|
11
|
+
def conditionally_invoke(*args)
|
12
|
+
filters = Array(self.filters)
|
13
|
+
return if filters.any? { |f| !call_block(f.to_proc, *args) }
|
14
|
+
call_block(hook, *args)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.included(klass)
|
19
|
+
klass.class_eval do
|
20
|
+
extend ClassMethods
|
21
|
+
hooks_module = Module.new
|
22
|
+
const_set("DefinedHooks", hooks_module)
|
23
|
+
include hooks_module
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def invoke_hook(hook_type, *args)
|
28
|
+
hooks[hook_type].map do |hook|
|
29
|
+
hook.conditionally_invoke(*args)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def clear_hooks
|
34
|
+
hooks.clear
|
35
|
+
end
|
36
|
+
|
37
|
+
def hooks
|
38
|
+
@hooks ||= Hash.new do |hash, hook_type|
|
39
|
+
hash[hook_type] = []
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def has_hooks_for?(hook_type)
|
44
|
+
hooks[hook_type].any?
|
45
|
+
end
|
46
|
+
|
47
|
+
# @private
|
48
|
+
module ClassMethods
|
49
|
+
def define_hook(hook_type, prepend = false)
|
50
|
+
placement_method = prepend ? :unshift : :<<
|
51
|
+
|
52
|
+
# Put the hook methods in a module so we can override and super to these methods.
|
53
|
+
self::DefinedHooks.module_eval do
|
54
|
+
define_method hook_type do |*filters, &hook|
|
55
|
+
hooks[hook_type].send(placement_method, FilteredHook.new(hook, filters))
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module VCR
|
2
|
+
# Ruby 1.8 provides Ping.pingecho, but it was removed in 1.9.
|
3
|
+
# So we try requiring it, and if that fails, define it ourselves.
|
4
|
+
begin
|
5
|
+
require 'ping'
|
6
|
+
Ping = ::Ping
|
7
|
+
rescue LoadError
|
8
|
+
# This is copied, verbatim, from Ruby 1.8.7's ping.rb.
|
9
|
+
require 'timeout'
|
10
|
+
require "socket"
|
11
|
+
|
12
|
+
# @private
|
13
|
+
module Ping
|
14
|
+
def pingecho(host, timeout=5, service="echo")
|
15
|
+
begin
|
16
|
+
timeout(timeout) do
|
17
|
+
s = TCPSocket.new(host, service)
|
18
|
+
s.close
|
19
|
+
end
|
20
|
+
rescue Errno::ECONNREFUSED
|
21
|
+
return true
|
22
|
+
rescue Timeout::Error, StandardError
|
23
|
+
return false
|
24
|
+
end
|
25
|
+
return true
|
26
|
+
end
|
27
|
+
module_function :pingecho
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# @private
|
32
|
+
module InternetConnection
|
33
|
+
extend self
|
34
|
+
|
35
|
+
EXAMPLE_HOST = "example.com"
|
36
|
+
|
37
|
+
def available?
|
38
|
+
@available = VCR::Ping.pingecho(EXAMPLE_HOST, 1, 80) unless defined?(@available)
|
39
|
+
@available
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module VCR
|
2
|
+
# @private
|
3
|
+
# Provides log message formatting helper methods.
|
4
|
+
class Logger
|
5
|
+
def initialize(stream)
|
6
|
+
@stream = stream
|
7
|
+
end
|
8
|
+
|
9
|
+
def log(message, log_prefix, indentation_level = 0)
|
10
|
+
indentation = ' ' * indentation_level
|
11
|
+
log_message = indentation + log_prefix + message
|
12
|
+
@stream.puts log_message
|
13
|
+
end
|
14
|
+
|
15
|
+
def request_summary(request, request_matchers)
|
16
|
+
attributes = [request.method, request.uri]
|
17
|
+
attributes << request.body.to_s[0, 80].inspect if request_matchers.include?(:body)
|
18
|
+
attributes << request.headers.inspect if request_matchers.include?(:headers)
|
19
|
+
"[#{attributes.join(" ")}]"
|
20
|
+
end
|
21
|
+
|
22
|
+
def response_summary(response)
|
23
|
+
"[#{response.status.code} #{response.body[0, 80].inspect}]"
|
24
|
+
end
|
25
|
+
|
26
|
+
# @private
|
27
|
+
# A null-object version of the Logger. Used when
|
28
|
+
# a `debug_logger` has not been set.
|
29
|
+
#
|
30
|
+
# @note We used to use a null object for the `debug_logger` itself,
|
31
|
+
# but some users noticed a negative perf impact from having the
|
32
|
+
# logger formatting logic still executing in that case, so we
|
33
|
+
# moved the null object interface up a layer to here.
|
34
|
+
module Null
|
35
|
+
module_function
|
36
|
+
|
37
|
+
def log(*); end
|
38
|
+
def request_summary(*); end
|
39
|
+
def response_summary(*); end
|
40
|
+
end
|
41
|
+
|
42
|
+
# @private
|
43
|
+
# Provides common logger helper methods that simply delegate to
|
44
|
+
# the underlying logger object.
|
45
|
+
module Mixin
|
46
|
+
def log(message, indentation_level = 0)
|
47
|
+
VCR.configuration.logger.log(message, log_prefix, indentation_level)
|
48
|
+
end
|
49
|
+
|
50
|
+
def request_summary(*args)
|
51
|
+
VCR.configuration.logger.request_summary(*args)
|
52
|
+
end
|
53
|
+
|
54
|
+
def response_summary(*args)
|
55
|
+
VCR.configuration.logger.response_summary(*args)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module VCR
|
2
|
+
# @private
|
3
|
+
class VersionChecker
|
4
|
+
def initialize(library_name, library_version, min_version)
|
5
|
+
@library_name = library_name
|
6
|
+
@library_version = library_version
|
7
|
+
@min_version = min_version
|
8
|
+
|
9
|
+
@major, @minor, @patch = parse_version(library_version)
|
10
|
+
@min_major, @min_minor, @min_patch = parse_version(min_version)
|
11
|
+
end
|
12
|
+
|
13
|
+
def check_version!
|
14
|
+
raise_too_low_error if too_low?
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def too_low?
|
20
|
+
compare_version == :too_low
|
21
|
+
end
|
22
|
+
|
23
|
+
def raise_too_low_error
|
24
|
+
raise Errors::LibraryVersionTooLowError,
|
25
|
+
"You are using #{@library_name} #{@library_version}. " +
|
26
|
+
"VCR requires version #{version_requirement}."
|
27
|
+
end
|
28
|
+
|
29
|
+
def compare_version
|
30
|
+
case
|
31
|
+
when @major < @min_major then :too_low
|
32
|
+
when @major > @min_major then :ok
|
33
|
+
when @minor < @min_minor then :too_low
|
34
|
+
when @minor > @min_minor then :ok
|
35
|
+
when @patch < @min_patch then :too_low
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def version_requirement
|
40
|
+
">= #{@min_version}"
|
41
|
+
end
|
42
|
+
|
43
|
+
def parse_version(version)
|
44
|
+
version.split('.').map { |v| v.to_i }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
data/lib/vcr/version.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
module VCR
|
2
|
+
extend self
|
3
|
+
|
4
|
+
# @return [String] the current VCR version.
|
5
|
+
# @note This string also has singleton methods:
|
6
|
+
#
|
7
|
+
# * `major` [Integer] The major version.
|
8
|
+
# * `minor` [Integer] The minor version.
|
9
|
+
# * `patch` [Integer] The patch version.
|
10
|
+
# * `parts` [Array<Integer>] List of the version parts.
|
11
|
+
def version
|
12
|
+
@version ||= begin
|
13
|
+
string = '2.9.3'
|
14
|
+
|
15
|
+
def string.parts
|
16
|
+
split('.').map { |p| p.to_i }
|
17
|
+
end
|
18
|
+
|
19
|
+
def string.major
|
20
|
+
parts[0]
|
21
|
+
end
|
22
|
+
|
23
|
+
def string.minor
|
24
|
+
parts[1]
|
25
|
+
end
|
26
|
+
|
27
|
+
def string.patch
|
28
|
+
parts[2]
|
29
|
+
end
|
30
|
+
|
31
|
+
string
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe VCR do
|
4
|
+
context 'when used in a multithreaded environment', :with_monkey_patches => :excon do
|
5
|
+
def preload_yaml_serializer_to_avoid_circular_require_warning_race_condition
|
6
|
+
VCR.cassette_serializers[:yaml]
|
7
|
+
end
|
8
|
+
|
9
|
+
before { preload_yaml_serializer_to_avoid_circular_require_warning_race_condition }
|
10
|
+
|
11
|
+
def recorded_content_for(name)
|
12
|
+
VCR.cassette_persisters[:file_system]["#{name}.yml"].to_s
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'can use a cassette in an #around_http_request hook', :if => (RUBY_VERSION.to_f > 1.8) do
|
16
|
+
VCR.configure do |vcr|
|
17
|
+
vcr.around_http_request do |req|
|
18
|
+
VCR.use_cassette(req.parsed_uri.path, &req)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
thread = Thread.start do
|
23
|
+
Excon.get "http://localhost:#{VCR::SinatraApp.port}/search?q=thread"
|
24
|
+
end
|
25
|
+
|
26
|
+
Excon.get "http://localhost:#{VCR::SinatraApp.port}/foo",
|
27
|
+
:response_block => Proc.new { thread.join }
|
28
|
+
|
29
|
+
expect(recorded_content_for("search") +
|
30
|
+
recorded_content_for("foo")).to include("query: thread", "FOO!")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
@@ -0,0 +1,110 @@
|
|
1
|
+
---
|
2
|
+
- !ruby/struct:VCR::HTTPInteraction
|
3
|
+
request: !ruby/struct:VCR::Request
|
4
|
+
method: :get
|
5
|
+
uri: http://example.com:80/
|
6
|
+
body:
|
7
|
+
headers:
|
8
|
+
response: !ruby/struct:VCR::Response
|
9
|
+
status: !ruby/struct:VCR::ResponseStatus
|
10
|
+
code: 200
|
11
|
+
message: OK
|
12
|
+
headers:
|
13
|
+
last-modified:
|
14
|
+
- Tue, 15 Nov 2005 13:24:10 GMT
|
15
|
+
connection:
|
16
|
+
- Keep-Alive
|
17
|
+
date:
|
18
|
+
- Thu, 25 Feb 2010 07:52:38 GMT
|
19
|
+
content-type:
|
20
|
+
- text/html; charset=UTF-8
|
21
|
+
etag:
|
22
|
+
- "\"24ec5-1b6-4059a80bfd280\""
|
23
|
+
server:
|
24
|
+
- Apache/2.2.3 (CentOS)
|
25
|
+
content-length:
|
26
|
+
- "438"
|
27
|
+
age:
|
28
|
+
- "3009"
|
29
|
+
accept-ranges:
|
30
|
+
- bytes
|
31
|
+
body: |
|
32
|
+
<HTML>
|
33
|
+
<HEAD>
|
34
|
+
<TITLE>Example Web Page</TITLE>
|
35
|
+
</HEAD>
|
36
|
+
<body>
|
37
|
+
<p>You have reached this web page by typing "example.com",
|
38
|
+
"example.net",
|
39
|
+
or "example.org" into your web browser.</p>
|
40
|
+
<p>These domain names are reserved for use in documentation and are not available
|
41
|
+
for registration. See <a href="http://www.rfc-editor.org/rfc/rfc2606.txt">RFC
|
42
|
+
2606</a>, Section 3.</p>
|
43
|
+
</BODY>
|
44
|
+
</HTML>
|
45
|
+
|
46
|
+
http_version: "1.1"
|
47
|
+
- !ruby/struct:VCR::HTTPInteraction
|
48
|
+
request: !ruby/struct:VCR::Request
|
49
|
+
method: :get
|
50
|
+
uri: http://example.com:80/foo
|
51
|
+
body:
|
52
|
+
headers:
|
53
|
+
response: !ruby/struct:VCR::Response
|
54
|
+
status: !ruby/struct:VCR::ResponseStatus
|
55
|
+
code: 404
|
56
|
+
message: Not Found
|
57
|
+
headers:
|
58
|
+
connection:
|
59
|
+
- close
|
60
|
+
content-type:
|
61
|
+
- text/html; charset=iso-8859-1
|
62
|
+
date:
|
63
|
+
- Thu, 25 Feb 2010 07:52:38 GMT
|
64
|
+
server:
|
65
|
+
- Apache/2.2.3 (CentOS)
|
66
|
+
content-length:
|
67
|
+
- "277"
|
68
|
+
body: |
|
69
|
+
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
|
70
|
+
<html><head>
|
71
|
+
<title>404 Not Found</title>
|
72
|
+
</head><body>
|
73
|
+
<h1>Not Found</h1>
|
74
|
+
<p>The requested URL /foo was not found on this server.</p>
|
75
|
+
<hr>
|
76
|
+
<address>Apache/2.2.3 (CentOS) Server at example.com Port 80</address>
|
77
|
+
</body></html>
|
78
|
+
|
79
|
+
http_version: "1.1"
|
80
|
+
- !ruby/struct:VCR::HTTPInteraction
|
81
|
+
request: !ruby/struct:VCR::Request
|
82
|
+
method: :get
|
83
|
+
uri: http://example.com:80/
|
84
|
+
body:
|
85
|
+
headers:
|
86
|
+
response: !ruby/struct:VCR::Response
|
87
|
+
status: !ruby/struct:VCR::ResponseStatus
|
88
|
+
code: 200
|
89
|
+
message: OK
|
90
|
+
headers:
|
91
|
+
last-modified:
|
92
|
+
- Tue, 15 Nov 2005 13:24:10 GMT
|
93
|
+
connection:
|
94
|
+
- Keep-Alive
|
95
|
+
date:
|
96
|
+
- Thu, 25 Feb 2010 07:52:38 GMT
|
97
|
+
content-type:
|
98
|
+
- text/html; charset=UTF-8
|
99
|
+
etag:
|
100
|
+
- "\"24ec5-1b6-4059a80bfd280\""
|
101
|
+
server:
|
102
|
+
- Apache/2.2.3 (CentOS)
|
103
|
+
content-length:
|
104
|
+
- "438"
|
105
|
+
age:
|
106
|
+
- "3009"
|
107
|
+
accept-ranges:
|
108
|
+
- bytes
|
109
|
+
body: Another example.com response
|
110
|
+
http_version: "1.1"
|