vcr 2.0.0.rc1 → 2.0.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. data/.gitignore +2 -0
  2. data/.limited_red +1 -0
  3. data/.travis.yml +10 -1
  4. data/.yardopts +9 -0
  5. data/CHANGELOG.md +51 -1
  6. data/Gemfile +5 -1
  7. data/LICENSE +1 -1
  8. data/README.md +23 -28
  9. data/Rakefile +63 -18
  10. data/Upgrade.md +200 -0
  11. data/features/.nav +2 -0
  12. data/features/cassettes/automatic_re_recording.feature +19 -15
  13. data/features/cassettes/dynamic_erb.feature +12 -4
  14. data/features/cassettes/exclusive.feature +31 -23
  15. data/features/cassettes/format.feature +54 -30
  16. data/features/cassettes/naming.feature +1 -1
  17. data/features/cassettes/update_content_length_header.feature +16 -12
  18. data/features/configuration/allow_http_connections_when_no_cassette.feature +1 -1
  19. data/features/configuration/debug_logging.feature +52 -0
  20. data/features/configuration/filter_sensitive_data.feature +4 -4
  21. data/features/configuration/hook_into.feature +5 -2
  22. data/features/configuration/ignore_request.feature +5 -3
  23. data/features/configuration/preserve_exact_body_bytes.feature +103 -0
  24. data/features/hooks/after_http_request.feature +17 -4
  25. data/features/hooks/around_http_request.feature +2 -1
  26. data/features/hooks/before_http_request.feature +25 -8
  27. data/features/hooks/before_playback.feature +16 -12
  28. data/features/hooks/before_record.feature +2 -2
  29. data/features/http_libraries/em_http_request.feature +82 -58
  30. data/features/http_libraries/net_http.feature +6 -6
  31. data/features/middleware/faraday.feature +2 -1
  32. data/features/middleware/rack.feature +2 -2
  33. data/features/record_modes/all.feature +19 -15
  34. data/features/record_modes/new_episodes.feature +17 -13
  35. data/features/record_modes/none.feature +15 -11
  36. data/features/record_modes/once.feature +16 -12
  37. data/features/request_matching/body.feature +28 -20
  38. data/features/request_matching/custom_matcher.feature +28 -20
  39. data/features/request_matching/headers.feature +34 -26
  40. data/features/request_matching/host.feature +28 -20
  41. data/features/request_matching/identical_request_sequence.feature +28 -20
  42. data/features/request_matching/method.feature +28 -20
  43. data/features/request_matching/path.feature +28 -20
  44. data/features/request_matching/playback_repeats.feature +28 -20
  45. data/features/request_matching/uri.feature +28 -20
  46. data/features/request_matching/uri_without_param.feature +28 -20
  47. data/features/support/env.rb +7 -6
  48. data/features/support/vcr_cucumber_helpers.rb +1 -0
  49. data/features/test_frameworks/cucumber.feature +8 -8
  50. data/features/test_frameworks/rspec_macro.feature +4 -4
  51. data/features/test_frameworks/rspec_metadata.feature +6 -6
  52. data/features/test_frameworks/shoulda.feature +1 -1
  53. data/features/test_frameworks/test_unit.feature +1 -1
  54. data/lib/vcr.rb +156 -5
  55. data/lib/vcr/cassette.rb +80 -30
  56. data/lib/vcr/cassette/http_interaction_list.rb +33 -4
  57. data/lib/vcr/cassette/migrator.rb +2 -3
  58. data/lib/vcr/cassette/reader.rb +1 -0
  59. data/lib/vcr/cassette/serializers.rb +22 -0
  60. data/lib/vcr/cassette/serializers/json.rb +27 -2
  61. data/lib/vcr/cassette/serializers/psych.rb +26 -2
  62. data/lib/vcr/cassette/serializers/syck.rb +28 -2
  63. data/lib/vcr/cassette/serializers/yaml.rb +28 -2
  64. data/lib/vcr/configuration.rb +348 -10
  65. data/lib/vcr/deprecations.rb +8 -0
  66. data/lib/vcr/errors.rb +40 -0
  67. data/lib/vcr/extensions/net_http_response.rb +12 -11
  68. data/lib/vcr/library_hooks.rb +1 -0
  69. data/lib/vcr/library_hooks/excon.rb +24 -3
  70. data/lib/vcr/library_hooks/fakeweb.rb +32 -16
  71. data/lib/vcr/library_hooks/faraday.rb +3 -0
  72. data/lib/vcr/library_hooks/typhoeus.rb +40 -37
  73. data/lib/vcr/library_hooks/webmock.rb +54 -34
  74. data/lib/vcr/middleware/faraday.rb +13 -0
  75. data/lib/vcr/middleware/rack.rb +35 -0
  76. data/lib/vcr/request_handler.rb +60 -8
  77. data/lib/vcr/request_ignorer.rb +1 -0
  78. data/lib/vcr/request_matcher_registry.rb +28 -0
  79. data/lib/vcr/structs.rb +245 -38
  80. data/lib/vcr/test_frameworks/cucumber.rb +10 -0
  81. data/lib/vcr/test_frameworks/rspec.rb +26 -1
  82. data/lib/vcr/util/hooks.rb +29 -27
  83. data/lib/vcr/util/internet_connection.rb +2 -0
  84. data/lib/vcr/util/logger.rb +25 -0
  85. data/lib/vcr/util/variable_args_block_caller.rb +1 -0
  86. data/lib/vcr/util/version_checker.rb +1 -0
  87. data/lib/vcr/version.rb +8 -1
  88. data/spec/capture_warnings.rb +3 -3
  89. data/spec/monkey_patches.rb +28 -13
  90. data/spec/spec_helper.rb +17 -0
  91. data/spec/support/http_library_adapters.rb +7 -4
  92. data/spec/support/shared_example_groups/hook_into_http_library.rb +96 -32
  93. data/spec/support/shared_example_groups/request_hooks.rb +9 -8
  94. data/spec/support/sinatra_app.rb +3 -1
  95. data/spec/support/vcr_localhost_server.rb +1 -0
  96. data/spec/vcr/cassette/http_interaction_list_spec.rb +119 -54
  97. data/spec/vcr/cassette/migrator_spec.rb +19 -6
  98. data/spec/vcr/cassette/serializers_spec.rb +51 -6
  99. data/spec/vcr/cassette_spec.rb +44 -19
  100. data/spec/vcr/configuration_spec.rb +91 -6
  101. data/spec/vcr/library_hooks/excon_spec.rb +54 -16
  102. data/spec/vcr/library_hooks/fakeweb_spec.rb +12 -21
  103. data/spec/vcr/library_hooks/typhoeus_spec.rb +2 -29
  104. data/spec/vcr/library_hooks/webmock_spec.rb +4 -18
  105. data/spec/vcr/middleware/faraday_spec.rb +1 -16
  106. data/spec/vcr/structs_spec.rb +194 -61
  107. data/spec/vcr/test_frameworks/rspec_spec.rb +10 -0
  108. data/spec/vcr/util/hooks_spec.rb +104 -56
  109. data/spec/vcr/util/version_checker_spec.rb +45 -0
  110. data/spec/vcr_spec.rb +11 -0
  111. data/vcr.gemspec +30 -34
  112. metadata +149 -95
  113. data/spec/support/shared_example_groups/version_checking.rb +0 -34
data/.gitignore CHANGED
@@ -35,3 +35,5 @@ features/Upgrade.md
35
35
  features/CONTRIBUTING.md
36
36
 
37
37
  .rvmrc
38
+ .yardoc
39
+ doc
data/.limited_red ADDED
@@ -0,0 +1 @@
1
+ project name: vcr
data/.travis.yml CHANGED
@@ -1,3 +1,4 @@
1
+ language: ruby
1
2
  env: CUCUMBER_FORMAT=progress
2
3
  bundler_args: --without extras
3
4
  script: "bundle exec rake ci:build --trace"
@@ -6,10 +7,18 @@ rvm:
6
7
  - 1.9.2
7
8
  - 1.9.3
8
9
  - ree
9
- - jruby
10
+ - jruby-18mode
11
+ - jruby-19mode
12
+ - rbx-18mode
13
+ - rbx-19mode
10
14
  branches:
11
15
  only:
12
16
  - master
13
17
  - 1-x-stable
14
18
  - travis-testing
19
+ matrix:
20
+ allow_failures:
21
+ - rvm: jruby-19mode
22
+ - rvm: rbx-18mode
23
+ - rvm: rbx-19mode
15
24
 
data/.yardopts ADDED
@@ -0,0 +1,9 @@
1
+ --no-private
2
+ --exclude features
3
+ --markup markdown
4
+ --hide-void-return
5
+ -
6
+ CHANGELOG.md
7
+ CONTRIBUTING.md
8
+ LICENSE
9
+ Upgrade.md
data/CHANGELOG.md CHANGED
@@ -1,6 +1,56 @@
1
1
  ## In git
2
2
 
3
- [Full Changelog](http://github.com/myronmarston/vcr/compare/v2.0.0.rc1...master)
3
+ [Full Changelog](http://github.com/myronmarston/vcr/compare/v2.0.0.rc2...master)
4
+
5
+ ## 2.0.0 RC 2 (February 23, 2012)
6
+
7
+ [Full Changelog](http://github.com/myronmarston/vcr/compare/v2.0.0.rc1...v2.0.0.rc2)
8
+
9
+ ## New Features
10
+
11
+ * Add YARD documentation for the public API. Thanks to
12
+ [Ben Oakes](https://github.com/benjaminoakes) for help with setting
13
+ this up.
14
+ * Fix `around_http_request` hook so that `request.proceed` returns
15
+ the response.
16
+ * Resolve `cassette_library_dir` to an absolute path. Thanks to
17
+ [Nate Clark](https://github.com/heythisisnate) for the suggestion.
18
+ * Add to the `VCR::Request` API in `before_http_request` and
19
+ `after_http_request` hooks so the request has query methods like
20
+ `#real?`, `#recordable?`, `#ignored?`, etc. Thanks to
21
+ [Nate Clark](https://github.com/heythisisnate) for the idea.
22
+ * Allow filters (objects that respond to `#to_proc`) to be passed
23
+ to `before_http_request` and `after_http_request`. This allows
24
+ an API like `before_http_request(:real?)` or
25
+ `after_http_request(lambda { |req| req.uri =~ /amazon/ })`.
26
+ * Add `debug_logger` config option. This can be used to
27
+ troubleshoot what VCR is doing.
28
+ * Update WebMock to version (1.8.0) that supports Excon stubbing.
29
+ * Store the encoding with the request & response bodies in the
30
+ serialized cassette.
31
+ * Add new `preserve_exact_body_bytes` option that base64 encodes the
32
+ request or response body in order to preserve the bytes exactly.
33
+ Thanks to [Jeff Pollard](https://github.com/Fluxx) for help
34
+ designing this feature and for code reviewing it.
35
+ * Update to and require latest Excon (0.9.6).
36
+
37
+ ## Bug Fixes
38
+
39
+ * Fix rspec metadata integration to allow the cassette name to be set
40
+ at the example group level and apply to multiple examples. Thanks to
41
+ [Paul Russell](https://github.com/pauljamesrussell) for reporting the
42
+ bug.
43
+ * Add missing `require 'vcr/version'` to the cassette migrator task.
44
+ If you tried the migration rake task with 2.0.0.rc1 and got a
45
+ `NoMethodError`, it should be fixed now.
46
+ * Update Excon dependency to 0.9.5; 0.9.5 includes an important bug
47
+ fix needed by VCR.
48
+ * Ensure the excon retry limit is honored properly.
49
+ * Ensure that the correct error class is raised by excon when stubbing
50
+ an unexpected status.
51
+ * Fix FakeWeb library hook so that it records the request body when
52
+ using `Net::HTTP.post_form`. Thanks to
53
+ [Retistic](https://github.com/Retistic) for reporting the bug.
4
54
 
5
55
  ## 2.0.0 RC 1 (December 8, 2011)
6
56
 
data/Gemfile CHANGED
@@ -7,6 +7,8 @@ group :development do
7
7
  end
8
8
  end
9
9
 
10
+ gem 'yard'
11
+
10
12
  # Additional gems that are useful, but not required for development.
11
13
  group :extras do
12
14
  gem 'guard-rspec'
@@ -15,8 +17,10 @@ group :extras do
15
17
  gem 'fuubar'
16
18
  gem 'fuubar-cucumber'
17
19
 
20
+ gem 'redcarpet', '~> 1.17.2'
21
+ gem 'github-markup'
22
+
18
23
  platforms :mri do
19
- gem 'rcov'
20
24
  gem 'rb-fsevent'
21
25
  end
22
26
 
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2010-2011 Myron Marston
1
+ Copyright (c) 2010-2012 Myron Marston
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -52,17 +52,19 @@ maintenance) and accurate (the response will contain the same headers and body y
52
52
  * [Faraday](https://github.com/technoweenie/faraday)
53
53
  * And of course any library built on Net::HTTP, such as [Mechanize](http://github.com/tenderlove/mechanize),
54
54
  [HTTParty](http://github.com/jnunemaker/httparty) or [Rest Client](http://github.com/archiloque/rest-client).
55
- * Request matching is configurable based on HTTP method, URI, host, path, body and headers.
55
+ * Request matching is configurable based on HTTP method, URI, host, path, body and headers, or you can easily
56
+ implement a custom request matcher to handle any need.
56
57
  * The same request can receive different responses in different tests--just use different cassettes.
57
- * The recorded requests and responses are stored on disk as YAML and can easily be inspected and edited.
58
+ * The recorded requests and responses are stored on disk in a serialization format of your choice
59
+ (currently YAML and JSON are built in, and you can easily implement your own custom serializer)
60
+ and can easily be inspected and edited.
58
61
  * Dynamic responses are supported using ERB.
59
62
  * Automatically re-records cassettes on a configurable regular interval to keep them fresh and current.
60
63
  * Disables all HTTP requests that you don't explicitly allow.
61
64
  * Simple cucumber integration is provided using tags.
62
- * Includes convenient RSpec macro.
65
+ * Includes convenient RSpec macro and integration with RSpec 2 metadata.
63
66
  * Known to work well with many popular ruby libraries including RSpec 1 & 2, Cucumber, Test::Unit,
64
67
  Capybara, Mechanize, Rest-Client and HTTParty.
65
- * Extensively tested on 7 different ruby interpretters.
66
68
  * Includes Rack and Faraday middleware.
67
69
 
68
70
  ## Usage
@@ -87,28 +89,8 @@ VCR has been tested on the following ruby interpreters:
87
89
  * MRI 1.8.7
88
90
  * MRI 1.9.2
89
91
  * REE 1.8.7
90
- * JRuby 1.5.6
91
- * Rubinius 1.2.1
92
-
93
- ## Known Issues
94
-
95
- * VCR uses YAML to serialize the HTTP interactions to disk in a
96
- human-readable, human-editable format. Unfortunately there are bugs
97
- in Syck, Ruby's default YAML engine, that cause it to modify strings
98
- when serializing them. It appears the the bug is limited to entire
99
- lines of whitespace. A string such as `"1\n \n2"` will get changed
100
- to `"1\n\n2"` (see [this gist](https://gist.github.com/815754) for
101
- example code). In practice, this usually isn't so bad, but it can
102
- occassionally cause problems, especially when the recorded
103
- response includes a `content_length` header and you are using an
104
- HTTP client that relies on this. Mechanize will raise an `EOFError`
105
- when the `content_length` header does not match the response body
106
- length. One solution is to use Psych, the new YAML engine included
107
- in Ruby 1.9. VCR attempts to use Psych if possible, but you may have
108
- to [re-compile ruby 1.9](http://rhnh.net/2011/01/31/psych-yaml-in-ruby-1-9-2-with-rvm-and-snow-leopard-osx)
109
- to use it. See [this issue](https://github.com/myronmarston/vcr/issues#issue/43)
110
- for more info. You can also use the `:update_content_length_header`
111
- cassette option to ensure the header has the correct value.
92
+ * JRuby
93
+ * Rubinius
112
94
 
113
95
  ## Development
114
96
 
@@ -119,6 +101,12 @@ VCR has been tested on the following ruby interpreters:
119
101
  and create a topic branch for every separate change you make.
120
102
  * See the [Contributing](https://github.com/myronmarston/vcr/blob/master/CONTRIBUTING.md)
121
103
  guide for instructions on running the specs and features.
104
+ * Documentation is generated with [YARD](http://yardoc.org/) ([cheat sheet](http://cheat.errtheblog.com/s/yard/)).
105
+ To generate while developing:
106
+
107
+ ```
108
+ yard server --reload
109
+ ```
122
110
 
123
111
  If you find VCR useful, please recommend me on [working with rails](http://workingwithrails.com/person/16590-myron-marston).
124
112
 
@@ -139,13 +127,16 @@ Thanks also to the following people who have contributed patches or helpful sugg
139
127
  * [Aaron Brethorst](http://github.com/aaronbrethorst)
140
128
  * [Avdi Grimm](https://github.com/avdi)
141
129
  * [Bartosz Blimke](http://github.com/bblimke)
130
+ * [Benjamin Oakes](https://github.com/benjaminoakes)
142
131
  * [Ben Hutton](http://github.com/benhutton)
143
132
  * [Bradley Isotope](https://github.com/bradleyisotope)
144
133
  * [Carlos Kirkconnell](https://github.com/kirkconnell)
145
134
  * [Eric Allam](http://github.com/rubymaverick)
146
135
  * [Flaviu Simihaian](https://github.com/closedbracket)
136
+ * [Jeff Pollard](https://github.com/Fluxx)
147
137
  * [Justin Smestad](https://github.com/jsmestad)
148
138
  * [Karl Baum](https://github.com/kbaum)
139
+ * [Michael Lavrisha](https://github.com/vrish88)
149
140
  * [Nathaniel Bibler](https://github.com/nbibler)
150
141
  * [Oliver Searle-Barnes](https://github.com/opsb)
151
142
  * [Paco Guzmán](https://github.com/pacoguzman)
@@ -156,11 +147,15 @@ Thanks also to the following people who have contributed patches or helpful sugg
156
147
  ## Similar Libraries
157
148
 
158
149
  * [Betamax](https://github.com/robfletcher/betamax) (Groovy)
159
- * [Ephemeral Response](https://github.com/sandro/ephemeral_response) (Ruby)
150
+ * [VCR.js](https://github.com/elcuervo/vcr.js) (JavaScript)
151
+ * [TapeDeck.js](https://github.com/EndangeredMassa/TapeDeck.js) (JavaScript)
160
152
  * [Mimic](https://github.com/acoulton/mimic) (PHP/Kohana)
153
+ * [Ephemeral Response](https://github.com/sandro/ephemeral_response) (Ruby)
154
+ * [Net::HTTP Spy](http://github.com/martinbtt/net-http-spy) (Ruby)
161
155
  * [NetRecorder](https://github.com/chrisyoung/netrecorder) (Ruby)
162
156
  * [Stale Fish](https://github.com/jsmestad/stale_fish) (Ruby)
157
+ * [WebFixtures](http://github.com/trydionel/web_fixtures) (Ruby)
163
158
 
164
159
  ## Copyright
165
160
 
166
- Copyright (c) 2010-2011 Myron Marston. See LICENSE for details.
161
+ Copyright (c) 2010-2012 Myron Marston. See LICENSE for details.
data/Rakefile CHANGED
@@ -18,21 +18,36 @@ RSpec::Core::RakeTask.new(:spec) do |t|
18
18
  t.rspec_opts = %w[--format progress] if (ENV['FULL_BUILD'] || !using_git)
19
19
  end
20
20
 
21
- desc "Run all examples using rcov"
22
- RSpec::Core::RakeTask.new :rcov => :cleanup_rcov_files do |t|
23
- t.rcov = true
24
- t.rcov_opts = %[-Ilib -Ispec --exclude "spec/*,gems/*,ping,basic_object" --text-report --sort coverage --aggregate coverage.data]
25
- end
26
-
27
- task :cleanup_rcov_files do
28
- rm_rf 'coverage.data'
29
- end
30
-
31
21
  require 'cucumber/rake/task'
32
22
  Cucumber::Rake::Task.new
33
23
 
34
24
  task :default => [:spec, :cucumber]
35
25
 
26
+ desc "Ensures we keep up 100% YARD coverage"
27
+ task :yard_coverage do
28
+ coverage_stats = `yard stats --list-undoc 2>&1`
29
+ if coverage_stats.include?('100.00% documented')
30
+ puts "Nice work! 100% documentation coverage"
31
+ else
32
+ puts coverage_stats
33
+ raise "Documentation coverage is less than 100%"
34
+ end
35
+ end
36
+
37
+ desc "Checks the spec coverage and fails if it is less than 100%"
38
+ task :check_code_coverage do
39
+ if RUBY_VERSION < '1.9' || RUBY_ENGINE != 'ruby'
40
+ puts "Cannot check code coverage--simplecov is not supported on this platform"
41
+ else
42
+ percent = File.read("./coverage/coverage_percent.txt").to_f
43
+ if percent < 98.0
44
+ raise "Spec coverage was not high enough: #{percent.round(2)}%"
45
+ else
46
+ puts "Nice job! Spec coverage is still above 98%"
47
+ end
48
+ end
49
+ end
50
+
36
51
  namespace :ci do
37
52
  desc "Sets things up for a ci build on travis-ci.org"
38
53
  task :setup do
@@ -51,7 +66,7 @@ namespace :ci do
51
66
  end
52
67
 
53
68
  desc "Run a ci build"
54
- task :build => [:setup, :spec, :cucumber]
69
+ task :build => [:setup, :spec, :cucumber, :yard_coverage, :check_code_coverage]
55
70
  end
56
71
 
57
72
  def ensure_relish_doc_symlinked(filename)
@@ -107,9 +122,23 @@ end
107
122
 
108
123
  desc "Migrate cucumber cassettes"
109
124
  task :migrate_cucumber_cassettes do
110
- sh "git checkout cb3559d6ffcb36cb823ae96a677e380e5b86ed80 -- features"
111
- require 'vcr/cassette/migrator'
125
+ require 'vcr'
126
+ require 'ruby-debug'
127
+
128
+ VCR.configure do |c|
129
+ c.cassette_library_dir = 'tmp/migrate'
130
+ c.default_cassette_options = { :serialize_with => :syck }
131
+ end
132
+
133
+ # We want 2.0.0 in the cucumber cassettes instead of 2.0.0.rc1
134
+ def VCR.version
135
+ "2.0.0"
136
+ end
137
+
112
138
  Dir["features/**/*.feature"].each do |feature_file|
139
+ # The ERB cassettes can't be migrated automatically.
140
+ next if feature_file.include?('dynamic_erb')
141
+
113
142
  puts " - Migrating #{feature_file}"
114
143
  contents = File.read(feature_file)
115
144
 
@@ -120,15 +149,22 @@ task :migrate_cucumber_cassettes do
120
149
  cassette_yml = capture.gsub(/^#{indentation}/, '')
121
150
  new_yml = nil
122
151
 
123
- Dir.mktmpdir do |dir|
124
- file_name = "#{dir}/cassette.yml"
125
- File.open(file_name, 'w') { |f| f.write(cassette_yml) }
126
- VCR::Cassette::Migrator.new(dir, StringIO.new).migrate!
127
- new_yml = File.read(file_name)
152
+ file_name = "tmp/migrate/cassette.yml"
153
+ File.open(file_name, 'w') { |f| f.write(cassette_yml) }
154
+ cassette = VCR::Cassette.new('cassette')
155
+
156
+ hash = begin
157
+ cassette.serializable_hash
158
+ rescue => e
159
+ puts " Skipping #{capture[0, 80]}"
160
+ next
128
161
  end
129
162
 
163
+ new_yml = VCR::Cassette::Serializers::Syck.serialize(hash)
164
+
130
165
  new_yml.gsub!(/^/, indentation)
131
166
  new_yml << indentation
167
+ new_yml.gsub!(/^\s+\n(\s+response:)/, '\1')
132
168
  contents.gsub!(capture, new_yml)
133
169
  end
134
170
 
@@ -147,3 +183,12 @@ task :run_last_cuke do
147
183
  end
148
184
  end
149
185
 
186
+ desc "Boot test app"
187
+ task :boot_test_app do
188
+ require './spec/support/vcr_localhost_server'
189
+ require './spec/support/sinatra_app'
190
+ VCR::SinatraApp.boot
191
+ puts "Booted sinatra app on port: #{VCR::SinatraApp.port}"
192
+ loop { }
193
+ puts "Shutting down."
194
+ end
data/Upgrade.md CHANGED
@@ -1,6 +1,10 @@
1
1
  See the [Changelog](changelog) for a complete list of changes from VCR
2
2
  1.x to 2.0. This file simply lists the most pertinent ones to upgrading.
3
3
 
4
+ ## Supported Rubies
5
+
6
+ Ruby 1.8.6 and 1.9.1 are no longer supported.
7
+
4
8
  ## Configuration Changes
5
9
 
6
10
  In VCR 1.x, your configuration block would be something like this:
@@ -43,3 +47,199 @@ that VCR 2.0 does less normalization then before, it may not be able to
43
47
  migrate the cassette perfectly. It's recommended that you delete and
44
48
  re-record your cassettes if you are able.
45
49
 
50
+ ## Custom Request Matchers
51
+
52
+ VCR 2.0 allows any callable (an object that responds to #call, such as a lambda)
53
+ to be used as a request matcher:
54
+
55
+ ``` ruby
56
+ VCR.configure do |c|
57
+ c.register_request_matcher :port do |request_1, request_2|
58
+ URI(request_1.uri).port == URI(request_2.uri).port
59
+ end
60
+ end
61
+ ```
62
+
63
+ In addition, a helper method is provided for generating a custom
64
+ matcher that ignores one or more query parameters:
65
+
66
+ ``` ruby
67
+ uri_without_timestamp = VCR.request_matchers.uri_without_param(:timestamp)
68
+ VCR.configure do |c|
69
+ c.register_request_matcher(:uri_without_timestamp, &uri_without_timestamp)
70
+ end
71
+ ```
72
+
73
+ ## Custom Serializers
74
+
75
+ VCR 2.0 supports multiple serializers. `:yaml`, `:json`, `:psych` and
76
+ `:syck` are supported out of the box, and it's easy to implement your
77
+ own:
78
+
79
+ ``` ruby
80
+ VCR.use_cassette("example", :serialize_with => :json) do
81
+ # make an HTTP request
82
+ end
83
+
84
+ marshal_serializer = Object.new
85
+ marshal_serializer.instance_eval do
86
+ def file_extension
87
+ "marsh"
88
+ end
89
+
90
+ def serialize(hash)
91
+ Marshal.dump(hash)
92
+ end
93
+
94
+ def deserialize(string)
95
+ Marshal.load(string)
96
+ end
97
+ end
98
+
99
+ VCR.configure do |c|
100
+ c.cassette_serializers[:marshal] = serializer
101
+ c.default_cassette_options = { :serialize_with => :marshal }
102
+ end
103
+ ```
104
+
105
+ ## Request Hooks
106
+
107
+ VCR 2.0 has new request hooks, allowing you to inject custom logic
108
+ before an HTTP request, after an HTTP request, or around an HTTP
109
+ request:
110
+
111
+ ``` ruby
112
+ VCR.configure do |c|
113
+ c.before_http_request do |request|
114
+ # do something with the request
115
+ end
116
+
117
+ c.after_http_request do |request, response|
118
+ # do something with the request or response
119
+ end
120
+
121
+ # around_http_request only works on ruby 1.9
122
+ VCR.configure do |c|
123
+ c.around_http_request do |request|
124
+ uri = URI(request.uri)
125
+ if uri.host == 'api.geocoder.com'
126
+ # extract an address like "1700 E Pine St, Seattle, WA"
127
+ # from a query like "address=1700+E+Pine+St%2C+Seattle%2C+WA"
128
+ address = CGI.unescape(uri.query.split('=').last)
129
+ VCR.use_cassette("geocoding/#{address}", &request)
130
+ else
131
+ request.proceed
132
+ end
133
+ end
134
+ end
135
+ end
136
+ ```
137
+
138
+ ## Ignore a Request Based on Anything
139
+
140
+ You can now define what requests get ignored using a block. This
141
+ gives you the flexibility to ignore a requets based on anything.
142
+
143
+ ``` ruby
144
+ VCR.configure do |c|
145
+ c.ignore_request do |request|
146
+ uri = URI(request.uri)
147
+ uri.host == 'localhost' && uri.port == 7500
148
+ end
149
+ end
150
+ ```
151
+
152
+ ## Integration with RSpec 2 Metadata
153
+
154
+ VCR can integrate directly with RSpec metadata:
155
+
156
+ ``` ruby
157
+ VCR.configure do |c|
158
+ c.configure_rspec_metadata!
159
+ end
160
+
161
+ RSpec.configure do |c|
162
+ # so we can use `:vcr` rather than `:vcr => true`;
163
+ # in RSpec 3 this will no longer be necessary.
164
+ c.treat_symbols_as_metadata_keys_with_true_values = true
165
+ end
166
+
167
+ # apply it to an example group
168
+ describe MyAPIWrapper, :vcr do
169
+ end
170
+
171
+ describe MyAPIWrapper do
172
+ # apply it to an individual example
173
+ it "does something", :vcr do
174
+ end
175
+
176
+ # set some cassette options
177
+ it "does something", :vcr => { :record => :new_episodes } do
178
+ end
179
+
180
+ # override the cassette name
181
+ it "does something", :vcr => { :cassette_name => "something" } do
182
+ end
183
+ end
184
+ ```
185
+
186
+ ## Improved Faraday Integration
187
+
188
+ VCR 1.x integrated with Faraday but required that you insert
189
+ `VCR::Middleware::Faraday` into your middleware stack and configure
190
+ `stub_with :faraday`. VCR 2 now takes care of inserting itself
191
+ into the Faraday middleware stack if you configure `hook_into :faraday`.
192
+
193
+ ## Improved Unhandled Error Messages
194
+
195
+ When VCR is unsure how to handle a request, the error message now contains
196
+ suggestions for how you can configure VCR or your test so it can handle
197
+ the request.
198
+
199
+ ## Debug Logger
200
+
201
+ VCR 2.0 has a new configuration option that will turn on a logging mode
202
+ so you can get more insight into what VCR is doing, for troubleshooting
203
+ purposes:
204
+
205
+ ``` ruby
206
+ VCR.configure do |c|
207
+ c.debug_logger = File.open('log/vcr.log')
208
+ # or...
209
+ c.debug_logger = $stderr
210
+ end
211
+ ```
212
+
213
+ ## Playback Changes
214
+
215
+ In VCR 1.x, a single HTTP interaction could be played back multiple
216
+ times. This was mostly due to how VCR was implemented using FakeWeb
217
+ and WebMock, and was not really by design. It's more in keeping with
218
+ the philosophy of VCR to record the entire sequence of HTTP interactions
219
+ (including the duplicate requests). In VCR 2, each recorded HTTP
220
+ interaction can only be played back once unless you use the new
221
+ `:allow_playback_repeats` option.
222
+
223
+ ## Preserve Exact Body Bytes
224
+
225
+ Sometimes the request or response body of an HTTP interaction cannot
226
+ be serialized and deserialized properly. Usually this is due to the body
227
+ having invalid UTF-8 bytes. This new option configures VCR to base64
228
+ encode the body in order to preserve the bytes exactly. It can either
229
+ be configured globally with a block, or set on individual cassettes:
230
+
231
+ ``` ruby
232
+ VCR.configure do |c|
233
+ c.preserve_exact_body_bytes do |http_message|
234
+ http_message.body.encoding.name == 'ASCII-8BIT' ||
235
+ !http_message.body.valid_encoding?
236
+ end
237
+ end
238
+
239
+ # or....
240
+
241
+ VCR.use_cassette("my_cassette", :preserve_exact_body_bytes => true) do
242
+ # ...
243
+ end
244
+ ```
245
+