vcr 2.0.0.beta1 → 2.0.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. data/.gitignore +1 -0
  2. data/.travis.yml +3 -0
  3. data/CHANGELOG.md +37 -2
  4. data/Gemfile +2 -2
  5. data/README.md +10 -1
  6. data/Rakefile +43 -7
  7. data/Upgrade.md +45 -0
  8. data/features/.nav +1 -0
  9. data/features/cassettes/automatic_re_recording.feature +19 -17
  10. data/features/cassettes/dynamic_erb.feature +32 -28
  11. data/features/cassettes/exclusive.feature +28 -24
  12. data/features/cassettes/format.feature +213 -31
  13. data/features/cassettes/update_content_length_header.feature +20 -18
  14. data/features/configuration/filter_sensitive_data.feature +4 -4
  15. data/features/configuration/hooks.feature +27 -23
  16. data/features/http_libraries/em_http_request.feature +79 -75
  17. data/features/record_modes/all.feature +14 -14
  18. data/features/record_modes/new_episodes.feature +15 -15
  19. data/features/record_modes/none.feature +15 -15
  20. data/features/record_modes/once.feature +15 -15
  21. data/features/request_matching/body.feature +25 -23
  22. data/features/request_matching/custom_matcher.feature +25 -23
  23. data/features/request_matching/headers.feature +32 -36
  24. data/features/request_matching/host.feature +27 -25
  25. data/features/request_matching/identical_request_sequence.feature +27 -25
  26. data/features/request_matching/method.feature +27 -25
  27. data/features/request_matching/path.feature +27 -25
  28. data/features/request_matching/playback_repeats.feature +27 -25
  29. data/features/request_matching/uri.feature +27 -25
  30. data/features/request_matching/uri_without_param.feature +28 -26
  31. data/features/step_definitions/cli_steps.rb +71 -17
  32. data/features/support/env.rb +3 -1
  33. data/features/support/http_lib_filters.rb +6 -3
  34. data/features/support/vcr_cucumber_helpers.rb +4 -2
  35. data/lib/vcr.rb +6 -2
  36. data/lib/vcr/cassette.rb +75 -51
  37. data/lib/vcr/cassette/migrator.rb +111 -0
  38. data/lib/vcr/cassette/serializers.rb +35 -0
  39. data/lib/vcr/cassette/serializers/json.rb +23 -0
  40. data/lib/vcr/cassette/serializers/psych.rb +24 -0
  41. data/lib/vcr/cassette/serializers/syck.rb +35 -0
  42. data/lib/vcr/cassette/serializers/yaml.rb +24 -0
  43. data/lib/vcr/configuration.rb +6 -1
  44. data/lib/vcr/errors.rb +1 -1
  45. data/lib/vcr/library_hooks/excon.rb +1 -7
  46. data/lib/vcr/library_hooks/typhoeus.rb +6 -22
  47. data/lib/vcr/library_hooks/webmock.rb +1 -1
  48. data/lib/vcr/middleware/faraday.rb +1 -1
  49. data/lib/vcr/request_matcher_registry.rb +43 -30
  50. data/lib/vcr/structs.rb +209 -0
  51. data/lib/vcr/tasks/vcr.rake +9 -0
  52. data/lib/vcr/version.rb +1 -1
  53. data/spec/fixtures/cassette_spec/1_x_cassette.yml +110 -0
  54. data/spec/fixtures/cassette_spec/example.yml +79 -78
  55. data/spec/fixtures/cassette_spec/with_localhost_requests.yml +79 -77
  56. data/spec/fixtures/fake_example.com_responses.yml +78 -76
  57. data/spec/fixtures/match_requests_on.yml +147 -145
  58. data/spec/monkey_patches.rb +5 -5
  59. data/spec/support/http_library_adapters.rb +48 -0
  60. data/spec/support/shared_example_groups/hook_into_http_library.rb +53 -20
  61. data/spec/support/sinatra_app.rb +12 -0
  62. data/spec/vcr/cassette/http_interaction_list_spec.rb +1 -1
  63. data/spec/vcr/cassette/migrator_spec.rb +183 -0
  64. data/spec/vcr/cassette/serializers_spec.rb +122 -0
  65. data/spec/vcr/cassette_spec.rb +147 -83
  66. data/spec/vcr/configuration_spec.rb +11 -1
  67. data/spec/vcr/library_hooks/typhoeus_spec.rb +3 -3
  68. data/spec/vcr/library_hooks/webmock_spec.rb +7 -1
  69. data/spec/vcr/request_ignorer_spec.rb +1 -1
  70. data/spec/vcr/request_matcher_registry_spec.rb +46 -4
  71. data/spec/vcr/structs_spec.rb +309 -0
  72. data/spec/vcr_spec.rb +7 -0
  73. data/vcr.gemspec +9 -12
  74. metadata +75 -61
  75. data/lib/vcr/structs/http_interaction.rb +0 -58
  76. data/lib/vcr/structs/normalizers/body.rb +0 -24
  77. data/lib/vcr/structs/normalizers/header.rb +0 -64
  78. data/lib/vcr/structs/normalizers/status_message.rb +0 -17
  79. data/lib/vcr/structs/normalizers/uri.rb +0 -34
  80. data/lib/vcr/structs/request.rb +0 -13
  81. data/lib/vcr/structs/response.rb +0 -13
  82. data/lib/vcr/structs/response_status.rb +0 -5
  83. data/lib/vcr/util/yaml.rb +0 -11
  84. data/spec/support/shared_example_groups/normalizers.rb +0 -94
  85. data/spec/vcr/structs/http_interaction_spec.rb +0 -89
  86. data/spec/vcr/structs/request_spec.rb +0 -39
  87. data/spec/vcr/structs/response_spec.rb +0 -44
  88. data/spec/vcr/structs/response_status_spec.rb +0 -9
data/.gitignore CHANGED
@@ -31,5 +31,6 @@ Gemfile.lock
31
31
  features/README.md
32
32
  features/CHANGELOG.md
33
33
  features/LICENSE.md
34
+ features/Upgrade.md
34
35
 
35
36
  .rvmrc
data/.travis.yml CHANGED
@@ -7,8 +7,11 @@ rvm:
7
7
  - 1.9.3
8
8
  - ree
9
9
  - jruby
10
+ - rbx
11
+ - rbx-2.0
10
12
  branches:
11
13
  only:
12
14
  - master
13
15
  - 1-x-stable
16
+ - travis-testing
14
17
 
data/CHANGELOG.md CHANGED
@@ -1,12 +1,47 @@
1
1
  ## In git
2
2
 
3
- [Full Changelog](http://github.com/myronmarston/vcr/compare/v2.0.0.beta1...master)
3
+ [Full Changelog](http://github.com/myronmarston/vcr/compare/v2.0.0.beta2...master)
4
+
5
+ ## 2.0.0 Beta 2 (November 6, 2011)
6
+
7
+ [Full Changelog](http://github.com/myronmarston/vcr/compare/v2.0.0.beta1...v2.0.0.beta2)
8
+
9
+ * Update to (and require) Typhoeus 0.3.2.
10
+ * Fix a bug with `VCR.request_matchers.uri_without_param(:some_param)`
11
+ so that it properly handles URIs that have no parameters. Thanks to
12
+ [Sathya Sekaran](https://github.com/sfsekaran) for this fix.
13
+ * The cassette format has changed significantly:
14
+ * The HTTPInteractions are no longer normalized in a lossy fashion.
15
+ VCR 1.x converted all HTTP header keys to lowercase. VCR 2.0 no
16
+ longer does this because it is impossible to know what the original
17
+ casing was (i.e. given `etag`, was it originally `etag`, `ETag` or
18
+ `Etag`?). Also, some HTTP libraries add particular request headers
19
+ to every request, and these used to be ignored. The aren't anymore.
20
+ * The ruby struct objects are not directly serialized anymore.
21
+ Instead, only primitives (hashes, arrays, strings, integers) are
22
+ serialized. This allows swappable serializers and will allow other
23
+ tools to read and use a VCR cassette.
24
+ * Add new serializer API. VCR ships with YAML, Syck, Psych and JSON
25
+ serializers, and it is very simple to implement your own. The
26
+ serializer can be configured on a per-cassette basis.
27
+ * New `vcr:migrate_cassettes DIR=path/to/cassettes` rake task assists
28
+ with upgrading from VCR 1.x to 2.0.
29
+ * Cassettes now contain a `recorded_with` attribute. This should
30
+ allow the cassette structure to be updated more easily in the future
31
+ as the version number provides a means for easily migrating
32
+ cassettes.
33
+ * Add `recorded_at` to data serialized with an HTTPInteraction. This
34
+ allows the `:re_record_interval` cassette option to work more
35
+ accurately and no longer rely on the file modification time.
36
+
37
+ Note that VCR 1.x cassettes cannot be used with VCR 2.0. See the
38
+ upgrade notes for more info.
4
39
 
5
40
  ## 2.0.0 Beta 1 (October 8, 2011)
6
41
 
7
42
  [Full Changelog](http://github.com/myronmarston/vcr/compare/v1.11.3...v2.0.0.beta1)
8
43
 
9
- ### Changes
44
+ ### Changed
10
45
 
11
46
  * Previously, the last matching response in a cassette would
12
47
  repeatedly playback if the same request kept being made. This is
data/Gemfile CHANGED
@@ -6,8 +6,8 @@ group :development do
6
6
  platforms :ruby do
7
7
  gem 'patron', '~> 0.4.15'
8
8
  gem 'em-http-request', '~> 0.3.0'
9
- gem 'curb', '~> 0.7.15'
10
- gem 'typhoeus', '~> 0.2.1'
9
+ gem 'curb', '0.7.15'
10
+ gem 'typhoeus', '~> 0.3.2'
11
11
  end
12
12
 
13
13
  platforms :jruby do
data/README.md CHANGED
@@ -135,6 +135,7 @@ If you find VCR useful, please recommend me on [working with rails](http://worki
135
135
  Thanks also to the following people who have contributed patches or helpful suggestions:
136
136
 
137
137
  * [Aaron Brethorst](http://github.com/aaronbrethorst)
138
+ * [Avdi Grimm](https://github.com/avdi)
138
139
  * [Bartosz Blimke](http://github.com/bblimke)
139
140
  * [Ben Hutton](http://github.com/benhutton)
140
141
  * [Bradley Isotope](https://github.com/bradleyisotope)
@@ -143,8 +144,16 @@ Thanks also to the following people who have contributed patches or helpful sugg
143
144
  * [Karl Baum](https://github.com/kbaum)
144
145
  * [Nathaniel Bibler](https://github.com/nbibler)
145
146
  * [Oliver Searle-Barnes](https://github.com/opsb)
147
+ * [Sathya Sekaran](https://github.com/sfsekaran)
146
148
  * [Wesley Beary](https://github.com/geemus)
147
- * [Avdi Grimm](https://github.com/avdi)
149
+
150
+ ## Similar Libraries
151
+
152
+ * [Betamax](https://github.com/robfletcher/betamax) (Groovy)
153
+ * [Ephemeral Response](https://github.com/sandro/ephemeral_response) (Ruby)
154
+ * [Mimic](https://github.com/acoulton/mimic) (PHP/Kohana)
155
+ * [NetRecorder](https://github.com/chrisyoung/netrecorder) (Ruby)
156
+ * [Stale Fish](https://github.com/jsmestad/stale_fish) (Ruby)
148
157
 
149
158
  ## Copyright
150
159
 
data/Rakefile CHANGED
@@ -15,10 +15,6 @@ RSpec::Core::RakeTask.new(:spec) do |t|
15
15
  # we require spec_helper so we don't get an RSpec warning about
16
16
  # examples being defined before configuration.
17
17
  t.ruby_opts = "-w -I./spec -r./spec/capture_warnings -rspec_helper"
18
-
19
- # I'm not sure why, but bundler seems to silence warnings...
20
- t.skip_bundler = true
21
-
22
18
  t.rspec_opts = %w[--format progress] if (ENV['FULL_BUILD'] || !using_git)
23
19
  end
24
20
 
@@ -51,8 +47,6 @@ namespace :ci do
51
47
  # we require spec_helper so we don't get an RSpec warning about
52
48
  # examples being defined before configuration.
53
49
  t.ruby_opts = "-w -I./spec -r./spec/capture_warnings -rspec_helper"
54
- # I'm not sure why, but bundler seems to silence warnings...
55
- t.skip_bundler = true
56
50
  t.rspec_opts = %w[--format progress --backtrace]
57
51
  end
58
52
 
@@ -78,7 +72,7 @@ end
78
72
 
79
73
  desc "Push cukes to relishapp using the relish-client-gem"
80
74
  task :relish do
81
- %w[ README.md CHANGELOG.md LICENSE ].each do |file|
75
+ %w[ README.md CHANGELOG.md Upgrade.md LICENSE ].each do |file|
82
76
  ensure_relish_doc_symlinked(file)
83
77
  end
84
78
 
@@ -100,3 +94,45 @@ task :release => [:require_ruby_18, :prep_relish_release, :relish]
100
94
  # For gem-test: http://gem-testers.org/
101
95
  task :test => :spec
102
96
 
97
+ load './lib/vcr/tasks/vcr.rake'
98
+ namespace :vcr do
99
+ task :reset_spec_cassettes do
100
+ ENV['DIR'] = 'spec/fixtures'
101
+ def VCR.version; "2.0.0"; end
102
+ sh "git checkout v2.0.0.beta1 -- spec/fixtures"
103
+ end
104
+
105
+ task :migrate_cassettes => :reset_spec_cassettes
106
+ end
107
+
108
+ desc "Migrate cucumber cassettes"
109
+ task :migrate_cucumber_cassettes do
110
+ sh "git checkout cb3559d6ffcb36cb823ae96a677e380e5b86ed80 -- features"
111
+ require 'vcr/cassette/migrator'
112
+ Dir["features/**/*.feature"].each do |feature_file|
113
+ puts " - Migrating #{feature_file}"
114
+ contents = File.read(feature_file)
115
+
116
+ # http://rubular.com/r/gjzkoaYX2O
117
+ contents.scan(/:\n^\s+"""\n([\s\S]+?)"""/).each do |captures|
118
+ capture = captures.first
119
+ indentation = capture[/^ +/]
120
+ cassette_yml = capture.gsub(/^#{indentation}/, '')
121
+ new_yml = nil
122
+
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)
128
+ end
129
+
130
+ new_yml.gsub!(/^/, indentation)
131
+ new_yml << indentation
132
+ contents.gsub!(capture, new_yml)
133
+ end
134
+
135
+ File.open(feature_file, 'w') { |f| f.write(contents) }
136
+ end
137
+ end
138
+
data/Upgrade.md ADDED
@@ -0,0 +1,45 @@
1
+ See the [Changelog](changelog) for a complete list of changes from VCR
2
+ 1.x to 2.0. This file simply lists the most pertinent ones to upgrading.
3
+
4
+ ## Configuration Changes
5
+
6
+ In VCR 1.x, your configuration block would be something like this:
7
+
8
+ ``` ruby
9
+ VCR.config do |c|
10
+ c.cassette_library_dir = 'cassettes'
11
+ c.stub_with :fakeweb, :typhoeus
12
+ end
13
+ ```
14
+
15
+ This will continue to work in VCR 2.0 but will generate deprecation
16
+ warnings. Instead, you should change this to:
17
+
18
+ ``` ruby
19
+ VCR.configure do |c|
20
+ c.cassette_library_dir = 'cassettes'
21
+ c.hook_into :fakeweb, :typhoeus
22
+ end
23
+ ```
24
+
25
+ ## New Cassette Format
26
+
27
+ The cassette format has changed between VCR 1.x and VCR 2.0.
28
+ VCR 1.x cassettes cannot be used with VCR 2.0.
29
+
30
+ The easiest way to upgrade is to simply delete your cassettes and
31
+ re-record all of them. VCR also provides a rake task that attempts
32
+ to upgrade your 1.x cassettes to the new 2.0 format. To use it, add
33
+ the following line to your Rakefile:
34
+
35
+ ``` ruby
36
+ load 'vcr/tasks/vcr.rake'
37
+ ```
38
+
39
+ Then run `rake vcr:migrate_cassettes DIR=path/to/your/cassettes/directory` to
40
+ upgrade your cassettes. Note that this rake task may be unable to
41
+ upgrade some cassettes that make extensive use of ERB. In addition, now
42
+ that VCR 2.0 does less normalization then before, it may not be able to
43
+ migrate the cassette perfectly. It's recommended that you delete and
44
+ re-record your cassettes if you are able.
45
+
data/features/.nav CHANGED
@@ -1,4 +1,5 @@
1
1
  - getting_started.md (Getting Started)
2
+ - Upgrade.md (Upgrade)
2
3
  - CHANGELOG.md (Changelog)
3
4
  - about_these_examples.md (About These Examples)
4
5
  - LICENSE.md (License)
@@ -6,29 +6,31 @@ Feature: Automatic Re-recording
6
6
 
7
7
  The value provided should be an interval (expressed in seconds) that
8
8
  determines how often VCR will re-record the cassette. When a cassette
9
- is used, VCR checks the file modification time; if more time than the
10
- interval has passed, VCR will use the `:all` record mode to cause it be
11
- re-recorded.
9
+ is used, VCR checks the earliest `recorded_at` timestamp in the cassette;
10
+ if more time than the interval has passed since that timestamp,
11
+ VCR will use the `:all` record mode to cause it be re-recorded.
12
12
 
13
13
  Background:
14
14
  Given a previously recorded cassette file "cassettes/example.yml" with:
15
15
  """
16
- ---
17
- - !ruby/struct:VCR::HTTPInteraction
18
- request: !ruby/struct:VCR::Request
19
- method: :get
16
+ ---
17
+ http_interactions:
18
+ - request:
19
+ method: get
20
20
  uri: http://localhost:7777/
21
- body:
22
- headers:
23
- response: !ruby/struct:VCR::Response
24
- status: !ruby/struct:VCR::ResponseStatus
21
+ body: ''
22
+ headers: {}
23
+ response:
24
+ status:
25
25
  code: 200
26
26
  message: OK
27
- headers:
28
- content-length:
29
- - "12"
27
+ headers:
28
+ Content-Length:
29
+ - '12'
30
30
  body: Old Response
31
- http_version: "1.1"
31
+ http_version: '1.1'
32
+ recorded_at: Tue, 01 Nov 2011 04:58:44 GMT
33
+ recorded_with: VCR 2.0.0
32
34
  """
33
35
  And a file named "re_record.rb" with:
34
36
  """ruby
@@ -49,7 +51,7 @@ Feature: Automatic Re-recording
49
51
  """
50
52
 
51
53
  Scenario: Cassette is not re-recorded when not enough time has passed
52
- Given 6 days have passed since the cassette was recorded
54
+ Given it is Tue, 07 Nov 2011
53
55
  When I run `ruby re_record.rb`
54
56
  Then the output should contain "Old Response"
55
57
  But the output should not contain "New Response"
@@ -57,7 +59,7 @@ Feature: Automatic Re-recording
57
59
  But the file "cassettes/example.yml" should not contain "body: New Response"
58
60
 
59
61
  Scenario: Cassette is re-recorded when enough time has passed
60
- Given 8 days have passed since the cassette was recorded
62
+ Given it is Tue, 09 Nov 2011
61
63
  When I run `ruby re_record.rb`
62
64
  Then the output should contain "New Response"
63
65
  But the output should not contain "Old Response"
@@ -12,24 +12,26 @@ Feature: Dynamic ERB cassettes
12
12
  Scenario: Enable dynamic ERB cassette evalutation using :erb => true
13
13
  Given a previously recorded cassette file "cassettes/dynamic.yml" with:
14
14
  """
15
- ---
16
- - !ruby/struct:VCR::HTTPInteraction
17
- request: !ruby/struct:VCR::Request
18
- method: :get
19
- uri: http://example.com:80/foo?a=<%= 'b' * 3 %>
20
- body:
21
- headers:
22
- response: !ruby/struct:VCR::Response
23
- status: !ruby/struct:VCR::ResponseStatus
15
+ ---
16
+ http_interactions:
17
+ - request:
18
+ method: get
19
+ uri: http://example.com/foo?a=<%= 'b' * 3 %>
20
+ body: ''
21
+ headers: {}
22
+ response:
23
+ status:
24
24
  code: 200
25
25
  message: OK
26
- headers:
27
- content-type:
26
+ headers:
27
+ Content-Type:
28
28
  - text/html;charset=utf-8
29
- content-length:
30
- - "9"
29
+ Content-Length:
30
+ - '9'
31
31
  body: Hello <%= 'bar'.next %>
32
- http_version: "1.1"
32
+ http_version: '1.1'
33
+ recorded_at: Tue, 01 Nov 2011 04:58:44 GMT
34
+ recorded_with: VCR 2.0.0
33
35
  """
34
36
  And a file named "dynamic_erb_example.rb" with:
35
37
  """ruby
@@ -51,24 +53,26 @@ Feature: Dynamic ERB cassettes
51
53
  Scenario: Pass arguments to the ERB using :erb => { ... }
52
54
  Given a previously recorded cassette file "cassettes/dynamic.yml" with:
53
55
  """
54
- ---
55
- - !ruby/struct:VCR::HTTPInteraction
56
- request: !ruby/struct:VCR::Request
57
- method: :get
58
- uri: http://example.com:80/foo?a=<%= arg1 %>
59
- body:
60
- headers:
61
- response: !ruby/struct:VCR::Response
62
- status: !ruby/struct:VCR::ResponseStatus
56
+ ---
57
+ http_interactions:
58
+ - request:
59
+ method: get
60
+ uri: http://example.com/foo?a=<%= arg1 %>
61
+ body: ''
62
+ headers: {}
63
+ response:
64
+ status:
63
65
  code: 200
64
66
  message: OK
65
- headers:
66
- content-type:
67
+ headers:
68
+ Content-Type:
67
69
  - text/html;charset=utf-8
68
- content-length:
69
- - "9"
70
+ Content-Length:
71
+ - '9'
70
72
  body: Hello <%= arg2 %>
71
- http_version: "1.1"
73
+ http_version: '1.1'
74
+ recorded_at: Tue, 01 Nov 2011 04:58:44 GMT
75
+ recorded_with: VCR 2.0.0
72
76
  """
73
77
  And a file named "dynamic_erb_example.rb" with:
74
78
  """ruby
@@ -17,41 +17,45 @@ Feature: exclusive cassette
17
17
  Background:
18
18
  Given a previously recorded cassette file "cassettes/outer.yml" with:
19
19
  """
20
- ---
21
- - !ruby/struct:VCR::HTTPInteraction
22
- request: !ruby/struct:VCR::Request
23
- method: :get
20
+ ---
21
+ http_interactions:
22
+ - request:
23
+ method: get
24
24
  uri: http://localhost:7777/outer
25
- body:
26
- headers:
27
- response: !ruby/struct:VCR::Response
28
- status: !ruby/struct:VCR::ResponseStatus
25
+ body: ''
26
+ headers: {}
27
+ response:
28
+ status:
29
29
  code: 200
30
30
  message: OK
31
- headers:
32
- content-length:
33
- - "18"
31
+ headers:
32
+ Content-Length:
33
+ - '18'
34
34
  body: Old outer response
35
- http_version: "1.1"
35
+ http_version: '1.1'
36
+ recorded_at: Tue, 01 Nov 2011 04:58:44 GMT
37
+ recorded_with: VCR 2.0.0
36
38
  """
37
39
  And a previously recorded cassette file "cassettes/inner.yml" with:
38
40
  """
39
- ---
40
- - !ruby/struct:VCR::HTTPInteraction
41
- request: !ruby/struct:VCR::Request
42
- method: :get
41
+ ---
42
+ http_interactions:
43
+ - request:
44
+ method: get
43
45
  uri: http://localhost:7777/inner
44
- body:
45
- headers:
46
- response: !ruby/struct:VCR::Response
47
- status: !ruby/struct:VCR::ResponseStatus
46
+ body: ''
47
+ headers: {}
48
+ response:
49
+ status:
48
50
  code: 200
49
51
  message: OK
50
- headers:
51
- content-length:
52
- - "18"
52
+ headers:
53
+ Content-Length:
54
+ - '18'
53
55
  body: Old inner response
54
- http_version: "1.1"
56
+ http_version: '1.1'
57
+ recorded_at: Tue, 01 Nov 2011 04:58:44 GMT
58
+ recorded_with: VCR 2.0.0
55
59
  """
56
60
  And a file named "setup.rb" with:
57
61
  """ruby