mustwin-vcr 2.9.3
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/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"
|