vcr 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/History.rdoc CHANGED
@@ -1,3 +1,14 @@
1
+ == 0.3.0 March 24, 2010
2
+ * Renamed a bunch of methods, replacing them with method names that more clearly fit the VCR/cassette metaphor:
3
+ * VCR.create_cassette! => VCR.insert_cassette
4
+ * VCR.destroy_cassette! => VCR.eject_cassette
5
+ * VCR.with_cassette => VCR.use_cassette
6
+ * VCR::Cassette#destroy! => VCR::Cassette#eject
7
+ * VCR::Cassette#cache_file => VCR::Cassette#file
8
+ * VCR::Config.cache_dir => VCR::Config.cassette_library_dir
9
+ * :unregistered record mode => :new_episodes record mode
10
+ * All the old methods still work, but you'll get deprecation warnings.
11
+
1
12
  == 0.2.0 March 9, 2010
2
13
  * Added <tt>:allow_real_http</tt> cassette option, which allows VCR to work with capybara and a javascript driver.
3
14
  Bug reported by {Ben Hutton}[http://github.com/benhutton].
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2009 Myron Marston
1
+ Copyright (c) 2010 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.rdoc CHANGED
@@ -15,26 +15,26 @@ VCR was inspired by {NetRecorder}[http://github.com/chrisyoung/netrecorder], but
15
15
  localized recording and replaying, rather than the global recording and replaying of NetRecorder. In general, I believe that
16
16
  tests should not rely upon anything global. You're coupling your test to something outside of it that may later change and
17
17
  break the test. It's far better to localize things to each test, as much as possible. VCR, in combination with FakeWeb,
18
- makes it easy to do this with the recording and replying of HTTP responses.
18
+ makes it easy to do this with the recording and replaying of HTTP responses.
19
19
 
20
20
  == Cassettes
21
21
 
22
22
  Cassettes are central to the way VCR works. They are a similar to VHS cassettes--your library of cassettes
23
- is your library of previously recorded responses that can be replayed. When you create a cassette, it does
23
+ is your library of previously recorded responses that can be replayed. When you insert a cassette, it does
24
24
  the following:
25
25
 
26
- * It loads the previously recorded responses from the cache file corresponding to the cassette name.
26
+ * It loads the previously recorded responses from the library file corresponding to the cassette name.
27
27
  * It register these responses with fakeweb (depending on the cassette's :record option--see below)
28
28
  * It sets the <tt>FakeWeb.allow_net_connect</tt> setting based on the cassette's :record option.
29
29
 
30
30
  While a cassette is active, any HTTP requests to a URL of a previously recorded response will use
31
31
  the recorded response. New HTTP requests (i.e. HTTP requests that have not been previously recorded)
32
- will be recorded to the same cache file, depending on your :record option. When you destroy a cassette,
32
+ will be recorded to the same library file, depending on your :record option. When you eject a cassette,
33
33
  it does the following:
34
34
 
35
- * It saves all of the recorded responses (both old and new) to a cached yml file corresponding to the cassette name.
35
+ * It saves all of the recorded responses (both old and new) to a yml library file corresponding to the cassette name.
36
36
  * It removes the registrations it made with fakeweb, to prevent "leakage" into other tests.
37
- * It reverts the <tt>FakeWeb.allow_net_connect</tt> back to whatever it was before the cassette was created.
37
+ * It reverts the <tt>FakeWeb.allow_net_connect</tt> back to whatever it was before the cassette was inserted.
38
38
 
39
39
  == Record modes
40
40
 
@@ -42,20 +42,20 @@ VCR supports 3 record modes, which configure when it records new responses. You
42
42
  record mode in your configuration (see below) and a per-cassette record mode when creating a cassette. The record
43
43
  modes are:
44
44
 
45
+ * <tt>:new_episodes</tt> - This will use the previously recorded responses, and record any new requests that are not registered with
46
+ fakeweb. The previously recorded responses will be registered with fakeweb. <tt>FakeWeb.allow_net_connect</tt> will be
47
+ set to true, so that VCR will record any new HTTP requests within the cassette. Use this when it's ok for external HTTP
48
+ requests to be made without you explicitly allowing it. New requests will get saved to the cassette's yml library file, and
49
+ automatically get used in the future.
45
50
  * <tt>:all</tt> - This will cause VCR to re-record all HTTP requests that occur.
46
51
  When the cassette is created, it will not register any of the cached responses with fakeweb.
47
52
  <tt>FakeWeb.allow_net_connect</tt> will be set to true, so it can record the requests. Use this
48
53
  when you want to re-record all of the HTTP requests for a cassette. Alternately, you can simply
49
- delete the corresponding cache file and use the :unregistered record mode, described below.
54
+ delete the corresponding library file and use the :new_episodes record mode, described above.
50
55
  * <tt>:none</tt> - This will prevent VCR from recording, or even allowing, any new HTTP requests.
51
56
  The previously recorded responses will be registered with fakeweb. <tt>FakeWeb.allow_net_connect</tt> will be set to
52
57
  false, so that no new HTTP connections are allowed. Use this when you want to guarantee that no external
53
58
  HTTP requests will be made while the given cassette is active. Fakeweb will raise an error in this case.
54
- * <tt>:unregistered</tt> - This will use the previously recorded responses, and record any new requests that are not registered with
55
- fakeweb. The previously recorded responses will be registered with fakeweb. <tt>FakeWeb.allow_net_connect</tt> will be
56
- set to true, so that VCR will record any new HTTP requests within the cassette. Use this when it's ok for external HTTP
57
- requests to be made without you explicitly allowing it. New requests will get saved to the cassettes yml file, and
58
- automatically get used in the future.
59
59
 
60
60
  == Configuration
61
61
 
@@ -66,8 +66,8 @@ modes are:
66
66
  FakeWeb.allow_net_connect = false
67
67
 
68
68
  VCR.config do |c|
69
- # the cache_dir is where the cassette yml files will be saved.
70
- c.cache_dir = File.join(Rails.root, 'features', 'fixtures', 'vcr_cassettes')
69
+ # the cassette_library_dir is where the cassette yml files will be saved.
70
+ c.cassette_library_dir = File.join(Rails.root, 'features', 'fixtures', 'cassette_library')
71
71
 
72
72
  # these options will be used as defaults for your cassettes, but you can override them in each individual cassette.
73
73
  c.default_cassette_options = {
@@ -81,33 +81,33 @@ to put it in spec/support/vcr.rb, test/support/vcr.rb or features/support/vcr.rb
81
81
 
82
82
  == Usage with your favorite test/spec framework
83
83
 
84
- VCR can easily be used with any ruby test or spec framework. Usually, you'll want to use <tt>VCR.with_cassette</tt>:
84
+ VCR can easily be used with any ruby test or spec framework. Usually, you'll want to use <tt>VCR.use_cassette</tt>:
85
85
 
86
- VCR.with_cassette('geocoding/Seattle, WA', :record => :unregistered) do
86
+ VCR.use_cassette('geocoding/Seattle, WA', :record => :new_episodes) do
87
87
  # do something that causes an HTTP request.
88
88
  end
89
89
 
90
- Alternately, you can create and destroy the cassette with individual method calls from setup/before and teardown/after:
90
+ Alternately, you can insert and eject the cassette with individual method calls from setup/before and teardown/after:
91
91
 
92
92
  describe "Something that makes an HTTP request" do
93
93
  before(:each) do
94
- VCR.create_cassette!('geocoding/Seattle, WA', :record => :unregistered)
94
+ VCR.insert_cassette('geocoding/Seattle, WA', :record => :new_episodes)
95
95
  end
96
96
 
97
97
  it "should do something that makes an HTTP request"
98
98
 
99
99
  after(:each) do
100
- VCR.destroy_cassette!
100
+ VCR.eject_cassette
101
101
  end
102
102
  end
103
103
 
104
104
  In both of these cases, VCR would use the file geocoding/Seattle_WA.yml within the configured
105
- cache dir. The :record setting is optional--if you leave it blank, your configured default will be used.
105
+ cassette library dir. The :record setting is optional--if you leave it blank, your configured default will be used.
106
106
 
107
107
  Besides the :record option, cassettes also support the :allow_real_http option. You can use this to make the cassette
108
108
  allow some real HTTP requests. You can specify it with a lambda:
109
109
 
110
- VCR.with_cassette('my cassette', :allow_real_http => lambda { |uri| uri.host == 'google.com' }) do
110
+ VCR.use_cassette('my cassette', :allow_real_http => lambda { |uri| uri.host == 'google.com' }) do
111
111
  # do something that causes an HTTP request.
112
112
  end
113
113
 
@@ -115,7 +115,7 @@ In this case, any google HTTP requests will be made for real, regardless of your
115
115
  your current record mode, and whether or not you are recording or replaying this cassette. Non-google requests will do
116
116
  the appropriate recording/replaying as usual. You can also use the special <tt>:localhost</tt> option:
117
117
 
118
- VCR.with_cassette('my cassette', :allow_real_http => :localhost) do
118
+ VCR.use_cassette('my cassette', :allow_real_http => :localhost) do
119
119
  # do something that causes an HTTP request.
120
120
  end
121
121
 
@@ -127,7 +127,7 @@ This is needed for using VCR with {capybara}[http://github.com/jnicklas/capybara
127
127
 
128
128
  == Usage with Cucumber
129
129
 
130
- VCR provides special support for cucumber. You can of course use <tt>VCR.with_cassette</tt> within a step definition,
130
+ VCR provides special support for cucumber. You can of course use <tt>VCR.use_cassette</tt> within a step definition,
131
131
  and that's the recommended way for any of your step definitions. But many times I find myself using generic step definitions
132
132
  provided by another library (such as the webrat/capybara web steps generated by cucumber-rails), and I don't want to modify
133
133
  these. VCR provides cucumber tagging support to help in these cases.
@@ -147,7 +147,7 @@ Then let VCR know about this tag, in features/support/vcr.rb (or some similar su
147
147
  For each of the tags you specify in your cucumber_tags block, VCR will set up the appropriate
148
148
  {Before and After hooks}[http://wiki.github.com/aslakhellesoy/cucumber/hooks] to use a cassette
149
149
  for the entire scenario. The tag (minus the '@') will be used as the cassette name, and it'll
150
- go in the cucumber_tags subdirectory of the configured cache dir.
150
+ go in the cucumber_tags subdirectory of the configured cassette library dir.
151
151
 
152
152
  == Usage with Capybara
153
153
 
@@ -157,8 +157,7 @@ it'll need to ping the app running on localhost. You can use the <tt>:allow_rea
157
157
  == Suggested Workflow
158
158
 
159
159
  First, configure VCR and FakeWeb as I have above. I like setting <tt>FakeWeb.allow_net_connect</tt> to <tt>false</tt>
160
- and VCR's <tt>default_cassette_record_mode</tt> to <tt>:none</tt> so that no new HTTP requests are made without me
161
- explicitly allowing it.
160
+ and the default record mode to <tt>:none</tt> so that no new HTTP requests are made without me explicitly allowing it.
162
161
 
163
162
  When an HTTP request is made, you'll get an {error from FakeWeb}[http://github.com/chrisk/fakeweb/blob/fakeweb-1.2.8/lib/fake_web/ext/net_http.rb#L62-63],
164
163
  such as:
@@ -166,37 +165,37 @@ such as:
166
165
  FakeWeb::NetConnectNotAllowedError: Real HTTP connections are disabled. Unregistered request: get http://example.com
167
166
 
168
167
  Find the place that is making the HTTP request (the backtrace should help here). If you've already recorded this HTTP
169
- request to a cassette from a different test, you can simply re-use the cassette. Use <tt>VCR.with_cassette</tt>, as
168
+ request to a cassette from a different test, you can simply re-use the cassette. Use <tt>VCR.use_cassette</tt>, as
170
169
  shown above. You may also want to refactor this into a helper method that sets up the VCR cassette and does whatever
171
170
  makes the HTTP request:
172
171
 
173
172
  def set_user_address(user, address, city, state)
174
- VCR.with_cassette("geocoding/#{address}, #{city}, #{state}", :record => :unregistered) do
173
+ VCR.use_cassette("geocoding/#{address}, #{city}, #{state}", :record => :new_episodes) do
175
174
  user.address.update_attributes!(:address => address, :city => city, :state => state)
176
175
  end
177
176
  end
178
177
 
179
178
  In this case, I've used a dynamic cassette name based on the address being geocoded. That way, each separate address
180
179
  gets a different cassette, and tests that set the same user address will reuse the same cassette. I've also set
181
- the record mode to <tt>:unregistered</tt> so that VCR will automatically record geocoding requests for a new address
180
+ the record mode to <tt>:new_episodes</tt> so that VCR will automatically record geocoding requests for a new address
182
181
  to a new cassette, without me having to do anything.
183
182
 
184
- If the HTTP request that triggered the error is new, you'll have to record it for the first time. Simply use <tt>VCR.with_cassette</tt>
185
- with the record mode set to <tt>:unregistered</tt> or <tt>:all</tt>. Run the test again, and VCR will record the HTTP response. I usually
183
+ If the HTTP request that triggered the error is new, you'll have to record it for the first time. Simply use <tt>VCR.use_cassette</tt>
184
+ with the record mode set to <tt>:new_episodes</tt> or <tt>:all</tt>. Run the test again, and VCR will record the HTTP response. I usually
186
185
  remove the record mode at this point so that it uses the default of <tt>:none</tt> in the future. Future test runs will use the
187
186
  recorded response, and if your code changes so that it is making a new HTTP request, you'll get the same FakeWeb error as shown above.
188
187
 
189
188
  == Ruby Version Compatibility
190
189
 
191
- specs.should pass if RUBY_VERSION =~ /^1.(8.6|8.7|9.1)$/
190
+ VCR works on ruby {1.8.6}[http://integrity186.heroku.com/vcr], {1.8.7}[http://integrity187.heroku.com/vcr] and {1.9.1}[http://integrity191.heroku.com/vcr].
192
191
 
193
192
  == Notes, etc.
194
193
 
195
- * The cassette name determines the name of the cache file for the given cassette. Strings or symbols are fine,
194
+ * The cassette name determines the name of the library file for the given cassette. Strings or symbols are fine,
196
195
  and you can include any characters, but spaces and invalid file name characters will be removed
197
- before the cassette reads or writes to the file.
196
+ before the cassette reads or writes to its library file.
198
197
  * You can use a directory separator (i.e. '/') in your cassette names to cause it to use a subdirectory
199
- of the cache_dir. The cucumber tagging support uses this.
198
+ of the cassette_library_dir. The cucumber tagging support uses this.
200
199
  * VCR maintains a simple stack of cassettes. This allows you to nest them as deeply as you want.
201
200
  This is particularly useful when you have a cucumber step definition that uses a cassette, and
202
201
  you also want to use a cassette for the entire scenario using the tagging support.
data/Rakefile CHANGED
@@ -6,7 +6,7 @@ begin
6
6
  Jeweler::Tasks.new do |gem|
7
7
  gem.name = "vcr"
8
8
  gem.summary = %Q{Use VCR to record HTTP responses and replay them using fakeweb.}
9
- gem.description = %Q{VCR provides helpers to record HTTP requests for URIs that are not registered with fakeweb, and replay them later. It provides built-in support for cucumber, but works with any ruby testing framework.}
9
+ gem.description = %Q{VCR provides helpers to record HTTP requests for URIs that are not registered with fakeweb, and replay them later. It works with any ruby testing framework, and provides built-in support for cucumber.}
10
10
  gem.email = "myron.marston@gmail.com"
11
11
  gem.homepage = "http://github.com/myronmarston/vcr"
12
12
  gem.authors = ["Myron Marston"]
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 0.3.0
@@ -3,21 +3,21 @@ Feature: Record response
3
3
  As a TDD/BDD developer
4
4
  I want to record responses for requests to URIs that are not registered with fakeweb so I can use them with fakeweb in the future
5
5
 
6
- Scenario: Record a response using VCR.with_cassette
6
+ Scenario: Record a response using VCR.use_cassette
7
7
  Given we do not have a "temp/cassette" cassette
8
8
  When I make an HTTP get request to "http://example.com" within the "temp/cassette" cassette
9
- Then the "temp/cassette" cache file should have a response for "http://example.com" that matches /You have reached this web page by typing.*example\.com/
9
+ Then the "temp/cassette" library file should have a response for "http://example.com" that matches /You have reached this web page by typing.*example\.com/
10
10
 
11
11
  @record_cassette1
12
12
  Scenario: Record a response using a tagged scenario
13
13
  Given we do not have a "cucumber_tags/record_cassette1" cassette
14
14
  And this scenario is tagged with the vcr cassette tag: "@record_cassette1"
15
15
  When I make an HTTP get request to "http://example.com"
16
- Then I can test the scenario cassette's recorded responses in the next scenario, after the cassette has been destroyed
16
+ Then I can test the scenario cassette's recorded responses in the next scenario, after the cassette has been ejected
17
17
 
18
18
  Scenario: Check the recorded response for the previous scenario
19
19
  Given the previous scenario was tagged with the vcr cassette tag: "@record_cassette1"
20
- Then the "cucumber_tags/record_cassette1" cache file should have a response for "http://example.com" that matches /You have reached this web page by typing.*example\.com/
20
+ Then the "cucumber_tags/record_cassette1" library file should have a response for "http://example.com" that matches /You have reached this web page by typing.*example\.com/
21
21
 
22
22
  @record_cassette2
23
23
  Scenario: Use both a tagged scenario cassette and a nested cassette within a single step definition
@@ -27,46 +27,46 @@ Feature: Record response
27
27
  When I make an HTTP get request to "http://example.com/before_nested"
28
28
  And I make an HTTP get request to "http://example.com/nested" within the "temp/nested" cassette
29
29
  And I make an HTTP get request to "http://example.com/after_nested"
30
- Then I can test the scenario cassette's recorded responses in the next scenario, after the cassette has been destroyed
31
- And the "temp/nested" cache file should have a response for "http://example.com/nested" that matches /The requested URL \/nested was not found/
30
+ Then I can test the scenario cassette's recorded responses in the next scenario, after the cassette has been ejected
31
+ And the "temp/nested" library file should have a response for "http://example.com/nested" that matches /The requested URL \/nested was not found/
32
32
 
33
33
  Scenario: Check the recorded response for the previous scenario
34
34
  Given the previous scenario was tagged with the vcr cassette tag: "@record_cassette2"
35
- Then the "cucumber_tags/record_cassette2" cache file should have a response for "http://example.com/before_nested" that matches /The requested URL \/before_nested was not found/
36
- And the "cucumber_tags/record_cassette2" cache file should have a response for "http://example.com/after_nested" that matches /The requested URL \/after_nested was not found/
35
+ Then the "cucumber_tags/record_cassette2" library file should have a response for "http://example.com/before_nested" that matches /The requested URL \/before_nested was not found/
36
+ And the "cucumber_tags/record_cassette2" library file should have a response for "http://example.com/after_nested" that matches /The requested URL \/after_nested was not found/
37
37
 
38
38
  Scenario: Make an HTTP request in a cassette with record mode set to :all
39
39
  Given we do not have a "temp/record_all_cassette" cassette
40
40
  When I make an HTTP get request to "http://example.com" within the "temp/record_all_cassette" all cassette
41
- Then the "temp/record_all_cassette" cache file should have a response for "http://example.com" that matches /You have reached this web page by typing.*example\.com/
41
+ Then the "temp/record_all_cassette" library file should have a response for "http://example.com" that matches /You have reached this web page by typing.*example\.com/
42
42
 
43
43
  Scenario: Make an HTTP request in a cassette with record mode set to :none
44
44
  Given we do not have a "temp/record_none_cassette" cassette
45
45
  When I make an HTTP get request to "http://example.com" within the "temp/record_none_cassette" none cassette
46
46
  Then the HTTP get request to "http://example.com" should result in a fakeweb error that mentions VCR
47
- And there should not be a "temp/record_none_cassette" cache file
47
+ And there should not be a "temp/record_none_cassette" library file
48
48
 
49
49
  @copy_not_the_real_response_to_temp
50
- Scenario: Make an HTTP request in a cassette with record mode set to :unregistered
51
- Given we have a "temp/not_the_real_response" file with a previously recorded response for "http://example.com"
52
- And we have a "temp/not_the_real_response" file with no previously recorded response for "http://example.com/foo"
53
- When I make HTTP get requests to "http://example.com" and "http://example.com/foo" within the "temp/not_the_real_response" unregistered cassette
54
- Then the "temp/not_the_real_response" cache file should have a response for "http://example.com" that matches /This is not the real response from example\.com/
55
- And the "temp/not_the_real_response" cache file should have a response for "http://example.com/foo" that matches /The requested URL \/foo was not found/
50
+ Scenario: Make an HTTP request in a cassette with record mode set to :new_episodes
51
+ Given we have a "temp/not_the_real_response" library file with a previously recorded response for "http://example.com"
52
+ And we have a "temp/not_the_real_response" library file with no previously recorded response for "http://example.com/foo"
53
+ When I make HTTP get requests to "http://example.com" and "http://example.com/foo" within the "temp/not_the_real_response" new_episodes cassette
54
+ Then the "temp/not_the_real_response" library file should have a response for "http://example.com" that matches /This is not the real response from example\.com/
55
+ And the "temp/not_the_real_response" library file should have a response for "http://example.com/foo" that matches /The requested URL \/foo was not found/
56
56
 
57
57
  Scenario: Record an asynchronous request (such as for mechanize)
58
58
  Given we do not have a "temp/asynchronous" cassette
59
- When I make an asynchronous HTTP get request to "http://example.com" within the "temp/asynchronous" unregistered cassette
60
- Then the "temp/asynchronous" cache file should have a response for "http://example.com" that matches /You have reached this web page by typing.*example\.com/
59
+ When I make an asynchronous HTTP get request to "http://example.com" within the "temp/asynchronous" new_episodes cassette
60
+ Then the "temp/asynchronous" library file should have a response for "http://example.com" that matches /You have reached this web page by typing.*example\.com/
61
61
 
62
62
  Scenario: Record a recursive post request
63
63
  Given we do not have a "temp/recursive_post" cassette
64
- When I make a recursive HTTP post request to "http://example.com" within the "temp/recursive_post" unregistered cassette
65
- Then the "temp/recursive_post" cache file should have a response for "http://example.com" that matches /You have reached this web page by typing.*example\.com/
66
- And the "temp/recursive_post" cache file should have exactly 1 response
64
+ When I make a recursive HTTP post request to "http://example.com" within the "temp/recursive_post" new_episodes cassette
65
+ Then the "temp/recursive_post" library file should have a response for "http://example.com" that matches /You have reached this web page by typing.*example\.com/
66
+ And the "temp/recursive_post" library file should have exactly 1 response
67
67
 
68
68
  Scenario: Make an allowed HTTP request in a cassette with record mode set to :none
69
69
  Given we do not have a "temp/record_none_cassette" cassette
70
70
  When I make an HTTP get request to "http://example.com" within the "temp/record_none_cassette" none cassette, allowing requests matching /example.com/
71
71
  Then the response for "http://example.com" should match /You have reached this web page by typing.*example\.com/
72
- And there should not be a "temp/record_none_cassette" cache file
72
+ And there should not be a "temp/record_none_cassette" library file
@@ -3,24 +3,24 @@ Feature: Replay recorded response
3
3
  As a TDD/BDD developer
4
4
  I want to replay responses for requests I have previously recorded
5
5
 
6
- Scenario: Replay recorded response for a request in a VCR.with_cassette block
7
- Given the "not_the_real_response" cache file has a response for "http://example.com" that matches /This is not the real response from example\.com/
6
+ Scenario: Replay recorded response for a request in a VCR.use_cassette block
7
+ Given the "not_the_real_response" library file has a response for "http://example.com" that matches /This is not the real response from example\.com/
8
8
  When I make an HTTP get request to "http://example.com" within the "not_the_real_response" cassette
9
9
  Then the response for "http://example.com" should match /This is not the real response from example\.com/
10
10
 
11
11
  @replay_cassette1
12
12
  Scenario: Replay recorded response for a request within a tagged scenario
13
13
  Given this scenario is tagged with the vcr cassette tag: "@replay_cassette1"
14
- And the "cucumber_tags/replay_cassette1" cache file has a response for "http://example.com" that matches /This is not the real response from example\.com/
14
+ And the "cucumber_tags/replay_cassette1" library file has a response for "http://example.com" that matches /This is not the real response from example\.com/
15
15
  When I make an HTTP get request to "http://example.com"
16
16
  Then the response for "http://example.com" should match /This is not the real response from example\.com/
17
17
 
18
18
  @replay_cassette2
19
19
  Scenario: Use both a tagged scenario cassette and a nested cassette within a single step definition
20
20
  Given this scenario is tagged with the vcr cassette tag: "@replay_cassette2"
21
- And the "cucumber_tags/replay_cassette2" cache file has a response for "http://example.com/before_nested" that matches /The before_nested response/
22
- And the "nested_replay_cassette" cache file has a response for "http://example.com/nested" that matches /The nested response/
23
- And the "cucumber_tags/replay_cassette2" cache file has a response for "http://example.com/after_nested" that matches /The after_nested response/
21
+ And the "cucumber_tags/replay_cassette2" library file has a response for "http://example.com/before_nested" that matches /The before_nested response/
22
+ And the "nested_replay_cassette" library file has a response for "http://example.com/nested" that matches /The nested response/
23
+ And the "cucumber_tags/replay_cassette2" library file has a response for "http://example.com/after_nested" that matches /The after_nested response/
24
24
  When I make an HTTP get request to "http://example.com/before_nested"
25
25
  And I make an HTTP get request to "http://example.com/nested" within the "nested_replay_cassette" cassette
26
26
  And I make an HTTP get request to "http://example.com/after_nested"
@@ -30,34 +30,40 @@ Feature: Replay recorded response
30
30
 
31
31
  @copy_not_the_real_response_to_temp
32
32
  Scenario: Make an HTTP request in a cassette with record mode set to :all
33
- Given we have a "temp/not_the_real_response" file with a previously recorded response for "http://example.com"
34
- And we have a "temp/not_the_real_response" file with no previously recorded response for "http://example.com/foo"
33
+ Given we have a "temp/not_the_real_response" library file with a previously recorded response for "http://example.com"
34
+ And we have a "temp/not_the_real_response" library file with no previously recorded response for "http://example.com/foo"
35
35
  When I make HTTP get requests to "http://example.com" and "http://example.com/foo" within the "temp/not_the_real_response" all cassette
36
36
  Then the response for "http://example.com" should match /You have reached this web page by typing.*example\.com/
37
37
  And the response for "http://example.com/foo" should match /The requested URL \/foo was not found/
38
38
 
39
39
  @copy_not_the_real_response_to_temp
40
40
  Scenario: Make an HTTP request in a cassette with record mode set to :none
41
- Given we have a "temp/not_the_real_response" file with a previously recorded response for "http://example.com"
42
- And we have a "temp/not_the_real_response" file with no previously recorded response for "http://example.com/foo"
41
+ Given we have a "temp/not_the_real_response" library file with a previously recorded response for "http://example.com"
42
+ And we have a "temp/not_the_real_response" library file with no previously recorded response for "http://example.com/foo"
43
43
  When I make HTTP get requests to "http://example.com" and "http://example.com/foo" within the "temp/not_the_real_response" none cassette
44
44
  Then the response for "http://example.com" should match /This is not the real response from example\.com/
45
45
  And the HTTP get request to "http://example.com/foo" should result in a fakeweb error that mentions VCR
46
46
 
47
47
  @copy_not_the_real_response_to_temp
48
- Scenario: Make an HTTP request in a cassette with record mode set to :unregistered
49
- Given we have a "temp/not_the_real_response" file with a previously recorded response for "http://example.com"
50
- And we have a "temp/not_the_real_response" file with no previously recorded response for "http://example.com/foo"
51
- When I make HTTP get requests to "http://example.com" and "http://example.com/foo" within the "temp/not_the_real_response" unregistered cassette
48
+ Scenario: Make an HTTP request in a cassette with record mode set to :new_episodes
49
+ Given we have a "temp/not_the_real_response" library file with a previously recorded response for "http://example.com"
50
+ And we have a "temp/not_the_real_response" library file with no previously recorded response for "http://example.com/foo"
51
+ When I make HTTP get requests to "http://example.com" and "http://example.com/foo" within the "temp/not_the_real_response" new_episodes cassette
52
52
  Then the response for "http://example.com" should match /This is not the real response from example\.com/
53
53
  And the response for "http://example.com/foo" should match /The requested URL \/foo was not found/
54
54
 
55
55
  @replay_cassette3
56
56
  Scenario: Replay multiple different recorded responses for requests to the same URL
57
57
  Given this scenario is tagged with the vcr cassette tag: "@replay_cassette3"
58
- And the "cucumber_tags/replay_cassette3" cache file has a response for "http://example.com" that matches /This is not the real response from example\.com/
59
- And the "cucumber_tags/replay_cassette3" cache file has a response for "http://example.com" that matches /This is another fake response from example\.com/
58
+ And the "cucumber_tags/replay_cassette3" library file has a response for "http://example.com" that matches /This is not the real response from example\.com/
59
+ And the "cucumber_tags/replay_cassette3" library file has a response for "http://example.com" that matches /This is another fake response from example\.com/
60
60
  When I make an HTTP get request to "http://example.com"
61
61
  And I make an HTTP get request to "http://example.com"
62
62
  Then response 1 for "http://example.com" should match /This is not the real response from example\.com/
63
63
  And response 2 for "http://example.com" should match /This is another fake response from example\.com/
64
+
65
+ @copy_not_the_real_response_to_temp
66
+ Scenario: Replay a response for an asynchronous request (such as for mechanize)
67
+ Given the "temp/not_the_real_response" library file has a response for "http://example.com" that matches /This is not the real response from example\.com/
68
+ When I make a replayed asynchronous HTTP get request to "http://example.com" within the "temp/not_the_real_response" new_episodes cassette
69
+ Then the response for "http://example.com" should match /This is not the real response from example\.com/
@@ -10,29 +10,41 @@ module VCRHelpers
10
10
  end
11
11
 
12
12
  def recorded_responses_for(cassette_name)
13
- yaml_file = File.join(VCR::Config.cache_dir, "#{cassette_name}.yml")
13
+ yaml_file = File.join(VCR::Config.cassette_library_dir, "#{cassette_name}.yml")
14
14
  yaml = File.open(yaml_file, 'r') { |f| f.read }
15
15
  responses = YAML.load(yaml)
16
16
  end
17
+
18
+ def capture_response(url)
19
+ @http_requests ||= Hash.new([])
20
+ uri = URI.parse(url)
21
+ path = uri.path.to_s == '' ? '/' : uri.path
22
+ begin
23
+ result = yield uri, path
24
+ rescue => e
25
+ result = e
26
+ end
27
+ @http_requests[url] += [result]
28
+ end
17
29
  end
18
30
  World(VCRHelpers)
19
31
 
20
32
  Given /^we do not have a "([^\"]*)" cassette$/ do |cassette_name|
21
- fixture_file = File.join(VCR::Config.cache_dir, "#{cassette_name}.yml")
33
+ fixture_file = File.join(VCR::Config.cassette_library_dir, "#{cassette_name}.yml")
22
34
  File.exist?(fixture_file).should be_false
23
35
  end
24
36
 
25
- Given /^we have a "([^\"]*)" file with (a|no) previously recorded response for "([^\"]*)"$/ do |file_name, a_or_no, url|
26
- fixture_file = File.join(VCR::Config.cache_dir, "#{file_name}.yml")
37
+ Given /^we have a "([^\"]*)" library file with (a|no) previously recorded response for "([^\"]*)"$/ do |file_name, a_or_no, url|
38
+ fixture_file = File.join(VCR::Config.cassette_library_dir, "#{file_name}.yml")
27
39
  File.exist?(fixture_file).should be_true
28
40
  responses = File.open(fixture_file, 'r') { |f| YAML.load(f.read) }
29
41
  should_method = a_or_no == 'a' ? :should : :should_not
30
42
  responses.map{ |r| URI.parse(r.uri) }.send(should_method, include(URI.parse(url)))
31
43
  end
32
44
 
33
- Given /^the "([^\"]*)" cache file has a response for "([^\"]*)" that matches \/(.+)\/$/ do |cassette_name, url, regex_str|
34
- Given %{we have a "#{cassette_name}" file with a previously recorded response for "#{url}"}
35
- Then %{the "#{cassette_name}" cache file should have a response for "#{url}" that matches /#{regex_str}/}
45
+ Given /^the "([^\"]*)" library file has a response for "([^\"]*)" that matches \/(.+)\/$/ do |cassette_name, url, regex_str|
46
+ Given %{we have a "#{cassette_name}" library file with a previously recorded response for "#{url}"}
47
+ Then %{the "#{cassette_name}" library file should have a response for "#{url}" that matches /#{regex_str}/}
36
48
  end
37
49
 
38
50
  Given /^this scenario is tagged with the vcr cassette tag: "([^\"]+)"$/ do |tag|
@@ -47,48 +59,57 @@ Given /^the previous scenario was tagged with the vcr cassette tag: "([^\"]*)"$/
47
59
  VCR::CucumberTags.tags.should include(tag)
48
60
  end
49
61
 
50
- When /^I make an(.*)? HTTP (?:get|post) request to "([^\"]*)"$/ do |request_type, url|
51
- @http_requests ||= Hash.new([])
52
- uri = URI.parse(url)
53
- path = uri.path.to_s == '' ? '/' : uri.path
54
- begin
55
- case request_type
56
- when /asynchronous/
57
- result = Net::HTTP.new(uri.host, uri.port).request_get(path) { |r| r.read_body { } }
58
- result.body.should be_a(Net::ReadAdapter)
59
- when /recursive/
60
- result = Net::HTTP.new(uri.host, uri.port).post(path, nil)
61
- else
62
- result = Net::HTTP.get_response(uri)
63
- end
64
- rescue => e
65
- result = e
62
+ When /^I make (?:an )?HTTP get request to "([^\"]*)"$/ do |url|
63
+ capture_response(url) do |uri, path|
64
+ Net::HTTP.get_response(uri)
65
+ end
66
+ end
67
+
68
+ When /^I make an asynchronous HTTP get request to "([^\"]*)"$/ do |url|
69
+ capture_response(url) do |uri, path|
70
+ result = Net::HTTP.new(uri.host, uri.port).request_get(path) { |r| r.read_body { } }
71
+ result.body.should be_a(Net::ReadAdapter)
72
+ result
73
+ end
74
+ end
75
+
76
+ When /^I make a replayed asynchronous HTTP get request to "([^\"]*)"$/ do |url|
77
+ capture_response(url) do |uri, path|
78
+ result_body = ''
79
+ result = Net::HTTP.new(uri.host, uri.port).request_get(path) { |r| r.read_body { |fragment| result_body << fragment } }
80
+ result.body.should == result_body
81
+ result
82
+ end
83
+ end
84
+
85
+ When /^I make a recursive HTTP post request to "([^\"]*)"$/ do |url|
86
+ capture_response(url) do |uri, path|
87
+ Net::HTTP.new(uri.host, uri.port).post(path, nil)
66
88
  end
67
- @http_requests[url] += [result]
68
89
  end
69
90
 
70
- When /^I make(?: an)?(.*)? HTTP (get|post) requests? to "([^\"]*)"(?: and "([^\"]*)")? within the "([^\"]*)" ?(#{VCR::Cassette::VALID_RECORD_MODES.join('|')})? cassette(?:, allowing requests matching \/([^\/]+)\/)?$/ do |request_type, method, url1, url2, cassette_name, record_mode, allowed|
71
- options = { :record => (record_mode ? record_mode.to_sym : :unregistered) }
91
+ When /^I make (.*HTTP (?:get|post)) requests? to "([^\"]*)"(?: and "([^\"]*)")? within the "([^\"]*)" ?(#{VCR::Cassette::VALID_RECORD_MODES.join('|')})? cassette(?:, allowing requests matching \/([^\/]+)\/)?$/ do |http_request_type, url1, url2, cassette_name, record_mode, allowed|
92
+ options = { :record => (record_mode ? record_mode.to_sym : :new_episodes) }
72
93
  options[:allow_real_http] = lambda { |uri| uri.to_s =~ /#{allowed}/ } if allowed.to_s.size > 0
73
94
  urls = [url1, url2].select { |u| u.to_s.size > 0 }
74
- VCR.with_cassette(cassette_name, options) do
95
+ VCR.use_cassette(cassette_name, options) do
75
96
  urls.each do |url|
76
- When %{I make an#{request_type} HTTP #{method} request to "#{url}"}
97
+ When %{I make #{http_request_type} request to "#{url}"}
77
98
  end
78
99
  end
79
100
  end
80
101
 
81
- Then /^the "([^\"]*)" cache file should have a response for "([^\"]*)" that matches \/(.+)\/$/ do |cassette_name, url, regex_str|
102
+ Then /^the "([^\"]*)" library file should have a response for "([^\"]*)" that matches \/(.+)\/$/ do |cassette_name, url, regex_str|
82
103
  responses = recorded_responses_for(cassette_name)
83
104
  responses.should have_expected_response(url, regex_str)
84
105
  end
85
106
 
86
- Then /^the "([^\"]*)" cache file should have exactly (\d+) response$/ do |cassette_name, response_count|
107
+ Then /^the "([^\"]*)" library file should have exactly (\d+) response$/ do |cassette_name, response_count|
87
108
  responses = recorded_responses_for(cassette_name)
88
109
  responses.should have(response_count.to_i).responses
89
110
  end
90
111
 
91
- Then /^I can test the scenario cassette's recorded responses in the next scenario, after the cassette has been destroyed$/ do
112
+ Then /^I can test the scenario cassette's recorded responses in the next scenario, after the cassette has been ejected$/ do
92
113
  # do nothing...
93
114
  end
94
115
 
@@ -105,7 +126,7 @@ Then /^(?:the )?response(?: (\d+))? for "([^\"]*)" should match \/(.+)\/$/ do |r
105
126
  @http_requests[url][response_num].body.should =~ regex
106
127
  end
107
128
 
108
- Then /^there should not be a "([^\"]*)" cache file$/ do |cassette_name|
109
- yaml_file = File.join(VCR::Config.cache_dir, "#{cassette_name}.yml")
129
+ Then /^there should not be a "([^\"]*)" library file$/ do |cassette_name|
130
+ yaml_file = File.join(VCR::Config.cassette_library_dir, "#{cassette_name}.yml")
110
131
  File.exist?(yaml_file).should be_false
111
132
  end