vcr 1.0.3 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,18 @@
1
1
  #Changelog
2
2
 
3
+ ## 1.1.0 (August 22, 2010)
4
+
5
+ * Added `:match_requests_on` cassette option, which determines how VCR matches requests.
6
+ * Removed VCR::TaskRunner and the corresponding rake task definition. The rake task migrated cassettes from the
7
+ 0.3.1 format to the 0.4+ format. If you are still on 0.3.1 or earlier, I recommend you upgrade to 0.4.1 first,
8
+ migrate your cassettes and deal with migration warnings, then upgrade to the current release.
9
+ * Added some code to VCR::Cassette.new to check the options passed to the cassette and raise an error if any
10
+ invalid options are passed.
11
+ * Optimized ERB rendering a bit. Rather than creating a new struct subclass for each time we render an ERB
12
+ cassette with locals, we keep a cache of reusable struct subclasses based on the desired attributes.
13
+ [Benchmarking](http://gist.github.com/512948) reveals this is about 28% faster.
14
+ * Upgraded tests to use em-http-request 0.2.10 rather than 0.2.7.
15
+
3
16
  ## 1.0.3 (August 5, 2010)
4
17
 
5
18
  * Upgraded VCR specs to RSpec 2.
data/README.md CHANGED
@@ -47,11 +47,15 @@ maintenance) and accurate (the response from example.com will contain the same h
47
47
  (all HTTP stubbing libraries), [Patron](http://github.com/toland/patron) (WebMock only),
48
48
  [HTTPClient](http://github.com/nahi/httpclient) (WebMock only) and
49
49
  [em-http-request](http://github.com/igrigorik/em-http-request) (WebMock only).
50
+ * Request matching is configurable based on HTTP method, URI, host, body and headers.
50
51
  * The same request can receive different responses in different tests--just use different cassettes.
51
52
  * The recorded requests and responses are stored on disk as YAML and can easily be inspected and edited.
52
53
  * Dynamic responses are supported using ERB.
53
54
  * Disables all HTTP requests that you don't explicitly allow.
54
55
  * Simple cucumber integration is provided using tags.
56
+ * Known to work well with many popular ruby libraries including RSpec, Cucumber, Test::Unit, Capybara, Mechanize and
57
+ Rest-Client.
58
+ * Extensively tested on 5 different ruby interpretters.
55
59
 
56
60
  ## Development
57
61
 
@@ -74,6 +78,7 @@ Each cassette can be configured with a couple options:
74
78
 
75
79
  * `:record`: Specifies a record mode for this cassette.
76
80
  * `:erb`: Used for dynamic cassettes (see below for more details).
81
+ * `:match_requests_on`: An array of request attributes to match on (see below for more details).
77
82
 
78
83
  ## Record modes
79
84
 
@@ -84,12 +89,42 @@ and a per-cassette record mode when inserting a cassette. The record modes are:
84
89
  * `:all`: Previously recorded HTTP interactions will be ignored. All HTTP interactions will be recorded.
85
90
  * `:none`: Previously recorded HTTP interactions will be replayed. New HTTP interactions will result in an error.
86
91
 
92
+ ## Request Matching
93
+
94
+ In order to properly replay previously recorded requests, VCR must match new HTTP requests to a previously
95
+ recorded one. By default, it matches on HTTP method and URI, since that is usually deterministic and
96
+ fully identifies the resource and action for typical RESTful APIs. In some cases (such as SOAP webservices)
97
+ this may not work so well, and VCR allows you to customize how requests are matched.
98
+
99
+ Cassettes take a `:match_requests_on` option that expects an array of request attributes to match on.
100
+ Supported attributes are:
101
+
102
+ * `:method`: The HTTP method (i.e. GET, POST, PUT or DELETE) of the request.
103
+ * `:uri`: The full URI of the request.
104
+ * `:host`: The host of the URI. You can use this (alone, or in combination with `:path`) as an alternative
105
+ to `:uri` to cause VCR to match using a regex that matches the host.
106
+ * `:path`: The path of the URI. You can use this (alone, or in combination with `:host`) as an alternative
107
+ to `:uri` to cause VCR to match using a regex that matches the path.
108
+ * `:body`: The body of the request.
109
+ * `:headers`: The request headers.
110
+
111
+ By default, VCR uses a `:match_requests_on` option like:
112
+
113
+ :match_requests_on => [:uri, :method]
114
+
115
+ If you want to match on another attribute, just add it to the array:
116
+
117
+ :match_requests_on => [:uri, :method, :body]
118
+
119
+ Note that FakeWeb cannot match on `:body` or `:headers`. In general, it is recommended that you configure
120
+ your cassettes to match on the most specific set of attributes that is deterministic.
121
+
87
122
  ## Configuration
88
123
 
89
124
  require 'vcr'
90
125
 
91
126
  VCR.config do |c|
92
- c.cassette_library_dir = File.join(Rails.root, 'features', 'fixtures', 'cassette_library')
127
+ c.cassette_library_dir = 'fixtures/cassette_library'
93
128
  c.http_stubbing_library = :fakeweb
94
129
  c.ignore_localhost = true
95
130
  c.default_cassette_options = { :record => :none }
@@ -99,7 +134,10 @@ This can go pretty much wherever, as long as this code is run before your tests,
99
134
  to put it in `spec/support/vcr.rb`, `test/support/vcr.rb` or `features/support/vcr.rb`. You can set the following
100
135
  configuration options:
101
136
 
102
- * `cassette_library_dir`: VCR will save the cassette YAML files to this directory.
137
+ * `cassette_library_dir`: VCR will save the cassette YAML files to this directory. If you are using Rails 3 and
138
+ ActiveRecord YAML fixtures, you will probably want to avoid putting VCR cassettes in a sub-directory of
139
+ `RAILS_ROOT/test/fixtures`. Rails will assume your cassette YAML files are ActiveRecord fixtures and raise an
140
+ error when the content doesn't conform to its expectations.
103
141
  * `http_stubbing_library`: Which http stubbing library to use. Currently `:fakeweb` and `:webmock` are supported.
104
142
  This is currently optional--VCR will try to guess based on the presence or absence of the `FakeWeb` or `WebMock`
105
143
  constants, but this is mostly done to assist users upgrading from VCR 0.3.1, which only worked with fakeweb and
@@ -166,8 +204,8 @@ Then let VCR know about this tag, in `features/support/vcr.rb` (or some similar
166
204
  t.tags '@another_scenario_tag'
167
205
  end
168
206
 
169
- For each of the tags you specify in your `cucumber_tags` block, VCR will set up the appropriate
170
- [Before and After hooks](http://wiki.github.com/aslakhellesoy/cucumber/hooks) to use a cassette
207
+ For each of the tags you specify in your `cucumber_tags` block, VCR will set up an appropriate
208
+ [After hook](http://wiki.github.com/aslakhellesoy/cucumber/hooks) to use a cassette
171
209
  for the entire scenario. The tag (minus the '@') will be used as the cassette name, and it'll
172
210
  go in the `cucumber_tags` subdirectory of the configured cassette library directory.
173
211
 
@@ -202,6 +240,10 @@ Edit your cassette file:
202
240
  body:
203
241
  headers:
204
242
 
243
+ Note that it may be simpler (and better!) to use the `:match_requests_on` cassette option with `:host` and/or `:path`,
244
+ as that gives you a a URL regex without the need to manually edit the cassette file. If you do change a url to a regex
245
+ in a cassette file, VCR will use it, regardless of the `:match_requests_on` setting.
246
+
205
247
  ## Dynamic Cassettes
206
248
 
207
249
  VCR's default recording and replaying is static. The exact response that is initially recorded will
@@ -235,7 +277,7 @@ In your cassette:
235
277
  ## FakeWeb or WebMock?
236
278
 
237
279
  VCR works fine with either FakeWeb or WebMock. Overall, WebMock has more features, and you'll need to use
238
- WebMock if you want to use VCR with an HTTP library besides `Net::HTTP`. However, FakeWeb is currently
280
+ WebMock if you want to use VCR with an HTTP library besides Net::HTTP. However, FakeWeb is currently
239
281
  about three times faster than WebMock, so you may want to stick with FakeWeb if you don't need WebMock's
240
282
  additional features. You can see the
241
283
  [benchmarks](http://github.com/myronmarston/vcr/blob/master/benchmarks/http_stubbing_libraries.rb) for
@@ -289,10 +331,10 @@ blocks of code in `VCR.use_cassette` and record logically grouped sets of reques
289
331
 
290
332
  VCR has been tested on the following ruby interpreters:
291
333
 
292
- * MRI 1.8.6
293
- * MRI 1.8.7
294
- * MRI 1.9.1
295
- * MRI 1.9.2 preview 3
334
+ * MRI 1.8.6-p399
335
+ * MRI 1.8.7-p302
336
+ * MRI 1.9.1-p378
337
+ * MRI 1.9.2
296
338
  * JRuby 1.5.1
297
339
 
298
340
  ## Notes, etc.
data/lib/vcr.rb CHANGED
@@ -2,6 +2,7 @@ require 'vcr/cassette'
2
2
  require 'vcr/config'
3
3
  require 'vcr/cucumber_tags'
4
4
  require 'vcr/deprecations'
5
+ require 'vcr/request_matcher'
5
6
  require 'vcr/structs'
6
7
  require 'vcr/version'
7
8
 
@@ -8,14 +8,17 @@ module VCR
8
8
 
9
9
  VALID_RECORD_MODES = [:all, :none, :new_episodes].freeze
10
10
 
11
- attr_reader :name, :record_mode
11
+ attr_reader :name, :record_mode, :match_requests_on
12
12
 
13
13
  def initialize(name, options = {})
14
14
  options = VCR::Config.default_cassette_options.merge(options)
15
+ invalid_options = options.keys - [:record, :erb, :allow_real_http, :match_requests_on]
15
16
 
16
- @name = name
17
- @record_mode = options[:record]
18
- @erb = options[:erb]
17
+ if invalid_options.size > 0
18
+ raise ArgumentError.new("You passed the following invalid options to VCR::Cassette.new: #{invalid_options.inspect}.")
19
+ end
20
+
21
+ @name, @record_mode, @erb, @match_requests_on = name, options[:record], options[:erb], options[:match_requests_on]
19
22
 
20
23
  deprecate_old_cassette_options(options)
21
24
  raise_error_unless_valid_record_mode(record_mode)
@@ -96,7 +99,11 @@ module VCR
96
99
  recorded_interactions.replace(@original_recorded_interactions)
97
100
  end
98
101
 
99
- VCR.http_stubbing_adapter.stub_requests(recorded_interactions)
102
+ VCR.http_stubbing_adapter.stub_requests(recorded_interactions, match_requests_on)
103
+ end
104
+
105
+ @@struct_cache = Hash.new do |hash, attributes|
106
+ hash[attributes] = Struct.new(*attributes)
100
107
  end
101
108
 
102
109
  def raw_yaml_content
@@ -109,7 +116,7 @@ module VCR
109
116
  return template.result unless @erb.is_a?(Hash)
110
117
 
111
118
  # create an object with methods for each desired local variable...
112
- local_variables = Struct.new(*@erb.keys).new(*@erb.values)
119
+ local_variables = @@struct_cache[@erb.keys].new(*@erb.values)
113
120
 
114
121
  # instance_eval seems to be the only way to get the binding for ruby 1.9: http://redmine.ruby-lang.org/issues/show/2161
115
122
  template.result(local_variables.instance_eval { binding })
@@ -132,4 +139,4 @@ module VCR
132
139
  end
133
140
  end
134
141
  end
135
- end
142
+ end
@@ -12,6 +12,8 @@ module VCR
12
12
  attr_writer :default_cassette_options
13
13
  def default_cassette_options
14
14
  @default_cassette_options ||= {}
15
+ @default_cassette_options.merge!(:match_requests_on => RequestMatcher::DEFAULT_MATCH_ATTRIBUTES) unless @default_cassette_options.has_key?(:match_requests_on)
16
+ @default_cassette_options
15
17
  end
16
18
 
17
19
  attr_writer :http_stubbing_library
@@ -2,7 +2,9 @@ require 'net/http'
2
2
 
3
3
  module Net
4
4
  class HTTP
5
- def request_with_vcr(request, body = nil, &block)
5
+ alias_method :request_without_vcr, :request
6
+
7
+ def request(request, body = nil, &block)
6
8
  uri = URI.parse(VCR.http_stubbing_adapter.request_uri(self, request))
7
9
 
8
10
  if VCR::LOCALHOST_ALIASES.include?(uri.host) && VCR.http_stubbing_adapter.ignore_localhost?
@@ -11,19 +13,17 @@ module Net
11
13
  end
12
14
  end
13
15
 
16
+ vcr_request = VCR::Request.from_net_http_request(self, request)
14
17
  response = request_without_vcr(request, body)
15
18
 
16
- if started? && !VCR.http_stubbing_adapter.request_stubbed?(request.method.downcase.to_sym, uri)
17
- http_interaction = VCR::HTTPInteraction.from_net_http_objects(self, request, response)
19
+ match_attributes = (cass = VCR.current_cassette) ? cass.match_requests_on : VCR::RequestMatcher::DEFAULT_MATCH_ATTRIBUTES
20
+ if started? && !VCR.http_stubbing_adapter.request_stubbed?(vcr_request, match_attributes)
21
+ VCR.record_http_interaction VCR::HTTPInteraction.new(vcr_request, VCR::Response.from_net_http_response(response))
18
22
  response.extend VCR::Net::HTTPResponse # "unwind" the response
19
-
20
- VCR.record_http_interaction(http_interaction)
21
23
  end
22
24
 
23
25
  yield response if block_given?
24
26
  response
25
27
  end
26
- alias_method :request_without_vcr, :request
27
- alias_method :request, :request_with_vcr
28
28
  end
29
29
  end
@@ -3,6 +3,8 @@ module VCR
3
3
  autoload :FakeWeb, 'vcr/http_stubbing_adapters/fakeweb'
4
4
  autoload :WebMock, 'vcr/http_stubbing_adapters/webmock'
5
5
 
6
+ class UnsupportedRequestMatchAttributeError < ArgumentError; end
7
+
6
8
  class Base
7
9
  class << self
8
10
  def with_http_connections_allowed_set_to(value)
@@ -5,6 +5,8 @@ module VCR
5
5
  module HttpStubbingAdapters
6
6
  class FakeWeb < Base
7
7
  class << self
8
+ UNSUPPORTED_REQUEST_MATCH_ATTRIBUTES = [:body, :headers].freeze
9
+
8
10
  def check_version!
9
11
  unless meets_version_requirement?(::FakeWeb::VERSION, '1.2.8')
10
12
  raise "You are using FakeWeb #{::FakeWeb::VERSION}. VCR requires version 1.2.8 or greater."
@@ -19,15 +21,20 @@ module VCR
19
21
  ::FakeWeb.allow_net_connect = value
20
22
  end
21
23
 
22
- def stub_requests(http_interactions)
24
+ def stub_requests(http_interactions, match_attributes = RequestMatcher::DEFAULT_MATCH_ATTRIBUTES)
25
+ validate_match_attributes(match_attributes)
23
26
  requests = Hash.new([])
24
27
 
25
28
  http_interactions.each do |i|
26
- requests[[i.request.method, i.request.uri]] += [i.response]
29
+ requests[i.request.matcher(match_attributes)] += [i.response]
27
30
  end
28
31
 
29
- requests.each do |request, responses|
30
- ::FakeWeb.register_uri(request.first, request.last, responses.map{ |r| response_hash(r) })
32
+ requests.each do |request_matcher, responses|
33
+ ::FakeWeb.register_uri(
34
+ request_matcher.method || :any,
35
+ request_matcher.uri,
36
+ responses.map{ |r| response_hash(r) }
37
+ )
31
38
  end
32
39
  end
33
40
 
@@ -39,8 +46,9 @@ module VCR
39
46
  ::FakeWeb::Registry.instance.uri_map = checkpoints.delete(checkpoint_name)
40
47
  end
41
48
 
42
- def request_stubbed?(method, uri)
43
- ::FakeWeb.registered_uri?(method, uri)
49
+ def request_stubbed?(request, match_attributes)
50
+ validate_match_attributes(match_attributes)
51
+ ::FakeWeb.registered_uri?(request.method, request.uri)
44
52
  end
45
53
 
46
54
  def request_uri(net_http, request)
@@ -77,6 +85,13 @@ module VCR
77
85
  :status => [response.status.code.to_s, response.status.message]
78
86
  )
79
87
  end
88
+
89
+ def validate_match_attributes(match_attributes)
90
+ invalid_attributes = match_attributes & UNSUPPORTED_REQUEST_MATCH_ATTRIBUTES
91
+ if invalid_attributes.size > 0
92
+ raise UnsupportedRequestMatchAttributeError.new("FakeWeb does not support matching requests on #{invalid_attributes.join(' or ')}")
93
+ end
94
+ end
80
95
  end
81
96
  end
82
97
  end
@@ -21,17 +21,20 @@ module VCR
21
21
  ::WebMock::Config.instance.allow_net_connect = value
22
22
  end
23
23
 
24
- def stub_requests(recorded_responses)
24
+ def stub_requests(http_interactions, match_attributes = RequestMatcher::DEFAULT_MATCH_ATTRIBUTES)
25
25
  requests = Hash.new([])
26
26
 
27
- # TODO: use the entire request signature, but make it configurable.
28
- recorded_responses.each do |rr|
29
- requests[[rr.method, rr.uri]] += [rr.response]
27
+ http_interactions.each do |i|
28
+ requests[i.request.matcher(match_attributes)] += [i.response]
30
29
  end
31
30
 
32
- requests.each do |request, responses|
33
- ::WebMock.stub_request(request.first, request.last).
34
- to_return(responses.map{ |r| response_hash(r) })
31
+ requests.each do |request_matcher, responses|
32
+ stub = ::WebMock.stub_request(request_matcher.method || :any, request_matcher.uri)
33
+
34
+ with_hash = request_signature_hash(request_matcher)
35
+ stub = stub.with(with_hash) if with_hash.size > 0
36
+
37
+ stub.to_return(responses.map{ |r| response_hash(r) })
35
38
  end
36
39
  end
37
40
 
@@ -43,8 +46,9 @@ module VCR
43
46
  ::WebMock::RequestRegistry.instance.request_stubs = checkpoints.delete(checkpoint_name)
44
47
  end
45
48
 
46
- def request_stubbed?(method, uri)
47
- !!::WebMock.registered_request?(::WebMock::RequestSignature.new(method, uri.to_s))
49
+ def request_stubbed?(request, match_attributes)
50
+ matcher = request.matcher(match_attributes)
51
+ !!::WebMock.registered_request?(::WebMock::RequestSignature.new(matcher.method || :any, request.uri, request_signature_hash(matcher)))
48
52
  end
49
53
 
50
54
  def request_uri(net_http, request)
@@ -61,6 +65,13 @@ module VCR
61
65
 
62
66
  private
63
67
 
68
+ def request_signature_hash(request_matcher)
69
+ signature = {}
70
+ signature[:body] = request_matcher.body if request_matcher.match_requests_on?(:body)
71
+ signature[:headers] = request_matcher.headers if request_matcher.match_requests_on?(:headers)
72
+ signature
73
+ end
74
+
64
75
  def response_hash(response)
65
76
  {
66
77
  :body => response.body,
@@ -0,0 +1,75 @@
1
+ require 'set'
2
+
3
+ module VCR
4
+ class RequestMatcher
5
+ VALID_MATCH_ATTRIBUTES = [:method, :uri, :host, :path, :headers, :body].freeze
6
+ DEFAULT_MATCH_ATTRIBUTES = [:method, :uri].freeze
7
+
8
+ attr_reader :request, :match_attributes
9
+
10
+ def initialize(request = nil, match_attributes = [])
11
+ if (match_attributes - VALID_MATCH_ATTRIBUTES).size > 0
12
+ raise ArgumentError.new("The only valid match_attributes options are: #{VALID_MATCH_ATTRIBUTES.inspect}. You passed: #{match_attributes.inspect}.")
13
+ end
14
+
15
+ @request, self.match_attributes = request, match_attributes
16
+ end
17
+
18
+ def match_attributes=(attributes)
19
+ # Unfortunately, 1.9.2 doesn't give the same hash code
20
+ # for two sets of the same elements unless they are ordered
21
+ # the same, so we sort the attributes here.
22
+ attributes = attributes.sort { |a, b| a.to_s <=> b.to_s }
23
+ @match_attributes = Set.new(attributes)
24
+ end
25
+
26
+ def uri
27
+ return request.uri unless request.uri.is_a?(String)
28
+ uri_matchers = match_attributes.to_a & [:uri, :host, :path]
29
+
30
+ case Set.new(uri_matchers)
31
+ when Set.new then /.*/
32
+ when Set.new([:uri]) then request.uri
33
+ when Set.new([:host]) then %r{\Ahttps?://((\w+:)?\w+@)?#{Regexp.escape(URI(request.uri).host)}(:\d+)?/}i
34
+ when Set.new([:path]) then %r{\Ahttps?://[^/]+#{Regexp.escape(URI(request.uri).path)}/?(\?.*)?\z}i
35
+ when Set.new([:host, :path])
36
+ uri = URI(request.uri)
37
+ %r{\Ahttps?://((\w+:)?\w+@)?#{Regexp.escape(uri.host)}(:\d+)?#{Regexp.escape(uri.path)}/?(\?.*)?\z}i
38
+ else raise ArgumentError.new("match_attributes cannot include #{uri_matchers.join(' and ')}")
39
+ end
40
+ end
41
+
42
+ def method
43
+ request.method if match_requests_on?(:method)
44
+ end
45
+
46
+ def headers
47
+ request.headers if match_requests_on?(:headers)
48
+ end
49
+
50
+ def body
51
+ request.body if match_requests_on?(:body)
52
+ end
53
+
54
+ def match_requests_on?(attribute)
55
+ match_attributes.include?(attribute)
56
+ end
57
+
58
+ def eql?(other)
59
+ self == other
60
+ end
61
+
62
+ def ==(other)
63
+ %w( class match_attributes method uri headers body ).all? do |attr|
64
+ send(attr) == other.send(attr)
65
+ end
66
+ end
67
+
68
+ def hash
69
+ # on Ruby 1.8.6, identical sets have different hash values,
70
+ # but identical arrays have the same hash values,
71
+ # so we convert match_attributes to an array here.
72
+ [match_attributes.to_a, method, uri, headers, body].hash
73
+ end
74
+ end
75
+ end
@@ -35,6 +35,10 @@ module VCR
35
35
  request.to_hash
36
36
  )
37
37
  end
38
+
39
+ def matcher(match_attributes)
40
+ RequestMatcher.new(self, match_attributes)
41
+ end
38
42
  end
39
43
 
40
44
  class ResponseStatus < Struct.new(:code, :message)
@@ -69,14 +73,6 @@ module VCR
69
73
 
70
74
  class HTTPInteraction < Struct.new(:request, :response)
71
75
  extend ::Forwardable
72
-
73
76
  def_delegators :request, :uri, :method
74
-
75
- def self.from_net_http_objects(net_http, request, response)
76
- new(
77
- Request.from_net_http_request(net_http, request),
78
- Response.from_net_http_response(response)
79
- )
80
- end
81
77
  end
82
78
  end
@@ -3,7 +3,7 @@ module VCR
3
3
 
4
4
  def version
5
5
  @version ||= begin
6
- string = [1, 0, 3].join('.')
6
+ string = [1, 1, 0].join('.')
7
7
 
8
8
  def string.parts; VCR.version.split('.').map { |p| p.to_i }; end
9
9
  def string.major; parts[0]; end
@@ -115,16 +115,17 @@ x
115
115
  7
116
116
  version
117
117
  i
118
- 73
118
+ 74
119
119
  39
120
120
  0
121
121
  13
122
122
  10
123
- 72
123
+ 73
124
124
  15
125
125
  79
126
126
  78
127
- 80
127
+ 4
128
+ 3
128
129
  35
129
130
  3
130
131
  7
@@ -501,27 +502,27 @@ I
501
502
  I
502
503
  6
503
504
  I
504
- 14
505
+ 15
505
506
  I
506
507
  8
507
508
  I
508
- 20
509
+ 21
509
510
  I
510
511
  9
511
512
  I
512
- 2c
513
+ 2d
513
514
  I
514
515
  a
515
516
  I
516
- 38
517
+ 39
517
518
  I
518
519
  b
519
520
  I
520
- 44
521
+ 45
521
522
  I
522
523
  d
523
524
  I
524
- 49
525
+ 4a
525
526
  x
526
527
  43
527
528
  /Users/mmarston/code/vcr/lib/vcr/version.rb
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vcr
3
3
  version: !ruby/object:Gem::Version
4
- hash: 17
4
+ hash: 19
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
+ - 1
8
9
  - 0
9
- - 3
10
- version: 1.0.3
10
+ version: 1.1.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Myron Marston
@@ -15,13 +15,10 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-08-05 00:00:00 -07:00
18
+ date: 2010-08-22 00:00:00 -07:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
- type: :development
23
- prerelease: false
24
- name: rspec
25
22
  version_requirements: &id001 !ruby/object:Gem::Requirement
26
23
  none: false
27
24
  requirements:
@@ -36,11 +33,39 @@ dependencies:
36
33
  - 19
37
34
  version: 2.0.0.beta.19
38
35
  requirement: *id001
39
- - !ruby/object:Gem::Dependency
40
36
  type: :development
37
+ name: rspec
41
38
  prerelease: false
42
- name: cucumber
39
+ - !ruby/object:Gem::Dependency
43
40
  version_requirements: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 3
46
+ segments:
47
+ - 0
48
+ version: "0"
49
+ requirement: *id002
50
+ type: :development
51
+ name: rspec-core
52
+ prerelease: false
53
+ - !ruby/object:Gem::Dependency
54
+ version_requirements: &id003 !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ hash: 3
60
+ segments:
61
+ - 0
62
+ version: "0"
63
+ requirement: *id003
64
+ type: :development
65
+ name: rspec-expectations
66
+ prerelease: false
67
+ - !ruby/object:Gem::Dependency
68
+ version_requirements: &id004 !ruby/object:Gem::Requirement
44
69
  none: false
45
70
  requirements:
46
71
  - - ">="
@@ -51,12 +76,12 @@ dependencies:
51
76
  - 8
52
77
  - 5
53
78
  version: 0.8.5
54
- requirement: *id002
55
- - !ruby/object:Gem::Dependency
79
+ requirement: *id004
56
80
  type: :development
81
+ name: cucumber
57
82
  prerelease: false
58
- name: fakeweb
59
- version_requirements: &id003 !ruby/object:Gem::Requirement
83
+ - !ruby/object:Gem::Dependency
84
+ version_requirements: &id005 !ruby/object:Gem::Requirement
60
85
  none: false
61
86
  requirements:
62
87
  - - ~>
@@ -67,12 +92,12 @@ dependencies:
67
92
  - 2
68
93
  - 8
69
94
  version: 1.2.8
70
- requirement: *id003
71
- - !ruby/object:Gem::Dependency
95
+ requirement: *id005
72
96
  type: :development
97
+ name: fakeweb
73
98
  prerelease: false
74
- name: webmock
75
- version_requirements: &id004 !ruby/object:Gem::Requirement
99
+ - !ruby/object:Gem::Dependency
100
+ version_requirements: &id006 !ruby/object:Gem::Requirement
76
101
  none: false
77
102
  requirements:
78
103
  - - ~>
@@ -83,12 +108,12 @@ dependencies:
83
108
  - 3
84
109
  - 3
85
110
  version: 1.3.3
86
- requirement: *id004
87
- - !ruby/object:Gem::Dependency
111
+ requirement: *id006
88
112
  type: :development
113
+ name: webmock
89
114
  prerelease: false
90
- name: httpclient
91
- version_requirements: &id005 !ruby/object:Gem::Requirement
115
+ - !ruby/object:Gem::Dependency
116
+ version_requirements: &id007 !ruby/object:Gem::Requirement
92
117
  none: false
93
118
  requirements:
94
119
  - - ~>
@@ -100,12 +125,12 @@ dependencies:
100
125
  - 5
101
126
  - 2
102
127
  version: 2.1.5.2
103
- requirement: *id005
104
- - !ruby/object:Gem::Dependency
128
+ requirement: *id007
105
129
  type: :development
130
+ name: httpclient
106
131
  prerelease: false
107
- name: capybara
108
- version_requirements: &id006 !ruby/object:Gem::Requirement
132
+ - !ruby/object:Gem::Dependency
133
+ version_requirements: &id008 !ruby/object:Gem::Requirement
109
134
  none: false
110
135
  requirements:
111
136
  - - ~>
@@ -116,12 +141,12 @@ dependencies:
116
141
  - 3
117
142
  - 9
118
143
  version: 0.3.9
119
- requirement: *id006
120
- - !ruby/object:Gem::Dependency
144
+ requirement: *id008
121
145
  type: :development
146
+ name: capybara
122
147
  prerelease: false
123
- name: rack
124
- version_requirements: &id007 !ruby/object:Gem::Requirement
148
+ - !ruby/object:Gem::Dependency
149
+ version_requirements: &id009 !ruby/object:Gem::Requirement
125
150
  none: false
126
151
  requirements:
127
152
  - - "="
@@ -132,12 +157,12 @@ dependencies:
132
157
  - 2
133
158
  - 0
134
159
  version: 1.2.0
135
- requirement: *id007
136
- - !ruby/object:Gem::Dependency
160
+ requirement: *id009
137
161
  type: :development
162
+ name: rack
138
163
  prerelease: false
139
- name: rake
140
- version_requirements: &id008 !ruby/object:Gem::Requirement
164
+ - !ruby/object:Gem::Dependency
165
+ version_requirements: &id010 !ruby/object:Gem::Requirement
141
166
  none: false
142
167
  requirements:
143
168
  - - ~>
@@ -148,12 +173,12 @@ dependencies:
148
173
  - 8
149
174
  - 7
150
175
  version: 0.8.7
151
- requirement: *id008
152
- - !ruby/object:Gem::Dependency
176
+ requirement: *id010
153
177
  type: :development
178
+ name: rake
154
179
  prerelease: false
155
- name: patron
156
- version_requirements: &id009 !ruby/object:Gem::Requirement
180
+ - !ruby/object:Gem::Dependency
181
+ version_requirements: &id011 !ruby/object:Gem::Requirement
157
182
  none: false
158
183
  requirements:
159
184
  - - ~>
@@ -164,15 +189,15 @@ dependencies:
164
189
  - 4
165
190
  - 6
166
191
  version: 0.4.6
167
- requirement: *id009
168
- - !ruby/object:Gem::Dependency
192
+ requirement: *id011
169
193
  type: :development
194
+ name: patron
170
195
  prerelease: false
171
- name: em-http-request
172
- version_requirements: &id010 !ruby/object:Gem::Requirement
196
+ - !ruby/object:Gem::Dependency
197
+ version_requirements: &id012 !ruby/object:Gem::Requirement
173
198
  none: false
174
199
  requirements:
175
- - - "="
200
+ - - ~>
176
201
  - !ruby/object:Gem::Version
177
202
  hash: 25
178
203
  segments:
@@ -180,7 +205,10 @@ dependencies:
180
205
  - 2
181
206
  - 7
182
207
  version: 0.2.7
183
- requirement: *id010
208
+ requirement: *id012
209
+ type: :development
210
+ name: em-http-request
211
+ prerelease: false
184
212
  description: VCR provides helpers to record your test suite's HTTP interactions and replay them during future test runs for fast, deterministic, accurate tests. It works with any ruby testing framework, and provides built-in support for cucumber.
185
213
  email: myron.marston@gmail.com
186
214
  executables: []
@@ -199,9 +227,8 @@ files:
199
227
  - lib/vcr/http_stubbing_adapters/base.rb
200
228
  - lib/vcr/http_stubbing_adapters/fakeweb.rb
201
229
  - lib/vcr/http_stubbing_adapters/webmock.rb
230
+ - lib/vcr/request_matcher.rb
202
231
  - lib/vcr/structs.rb
203
- - lib/vcr/task_runner.rb
204
- - lib/vcr/tasks/vcr.rake
205
232
  - lib/vcr/version.rb
206
233
  - lib/vcr/version.rbc
207
234
  - lib/vcr.rb
@@ -1,47 +0,0 @@
1
- require 'vcr'
2
-
3
- module VCR
4
- module TaskRunner
5
- extend self
6
-
7
- def migrate_cassettes(dir)
8
- with_recorded_response_defined do
9
- FileUtils.cp_r(dir, "#{dir}-backup")
10
-
11
- Dir.glob(dir + '/**/*.yml').each do |cassette_file|
12
- recorded_responses = YAML.load(File.read(cassette_file))
13
- next unless recorded_responses.is_a?(Enumerable) && recorded_responses.all? { |rr| rr.is_a?(VCR::RecordedResponse) }
14
-
15
- interactions = recorded_responses.map do |recorded_response|
16
- http_interaction(recorded_response)
17
- end
18
-
19
- File.open(cassette_file, 'w') { |f| f.write(interactions.to_yaml) }
20
- end
21
- end
22
- end
23
-
24
- private
25
-
26
- def http_interaction(recorded_response)
27
- VCR::HTTPInteraction.new(
28
- request(recorded_response),
29
- VCR::Response.from_net_http_response(recorded_response.response)
30
- )
31
- end
32
-
33
- def request(recorded_response)
34
- VCR::Request.new(recorded_response.method, recorded_response.uri)
35
- end
36
-
37
- def with_recorded_response_defined
38
- VCR.const_set(:RecordedResponse, Class.new(Struct.new(:method, :uri, :response, :request_body, :request_headers)))
39
-
40
- begin
41
- yield
42
- ensure
43
- VCR.send(:remove_const, :RecordedResponse)
44
- end
45
- end
46
- end
47
- end
@@ -1,9 +0,0 @@
1
- require 'vcr/task_runner'
2
-
3
- namespace :vcr do
4
- desc 'Migrates your VCR cassettes in DIR from the 0.3.1 format to the 0.4+ format'
5
- task :migrate_cassettes do
6
- raise "You must pass the cassette library directory as DIR" if ENV['DIR'].to_s == ''
7
- VCR::TaskRunner.migrate_cassettes(ENV['DIR'])
8
- end
9
- end