vcr 0.4.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. data/CHANGELOG.md +34 -0
  2. data/README.md +89 -21
  3. data/lib/vcr.rb +12 -1
  4. data/lib/vcr/cassette.rb +50 -27
  5. data/lib/vcr/config.rb +9 -0
  6. data/lib/vcr/deprecations.rb +15 -42
  7. data/lib/vcr/extensions/net_http.rb +13 -20
  8. data/lib/vcr/extensions/net_http_response.rb +6 -13
  9. data/lib/vcr/http_stubbing_adapters/fakeweb.rb +21 -3
  10. data/lib/vcr/http_stubbing_adapters/webmock.rb +34 -4
  11. data/lib/vcr/version.rb +16 -0
  12. metadata +90 -108
  13. data/.document +0 -5
  14. data/.gitignore +0 -22
  15. data/Rakefile +0 -67
  16. data/VERSION +0 -1
  17. data/benchmarks/http_stubbing_libraries.rb +0 -59
  18. data/features/fixtures/vcr_cassettes/1.8.6/cucumber_tags/replay_cassette1.yml +0 -43
  19. data/features/fixtures/vcr_cassettes/1.8.6/cucumber_tags/replay_cassette2.yml +0 -47
  20. data/features/fixtures/vcr_cassettes/1.8.6/cucumber_tags/replay_cassette3.yml +0 -85
  21. data/features/fixtures/vcr_cassettes/1.8.6/nested_replay_cassette.yml +0 -24
  22. data/features/fixtures/vcr_cassettes/1.8.6/not_the_real_response.yml +0 -43
  23. data/features/fixtures/vcr_cassettes/1.8.7/cucumber_tags/replay_cassette1.yml +0 -43
  24. data/features/fixtures/vcr_cassettes/1.8.7/cucumber_tags/replay_cassette2.yml +0 -47
  25. data/features/fixtures/vcr_cassettes/1.8.7/cucumber_tags/replay_cassette3.yml +0 -85
  26. data/features/fixtures/vcr_cassettes/1.8.7/nested_replay_cassette.yml +0 -24
  27. data/features/fixtures/vcr_cassettes/1.8.7/not_the_real_response.yml +0 -43
  28. data/features/fixtures/vcr_cassettes/1.9.1/cucumber_tags/replay_cassette1.yml +0 -43
  29. data/features/fixtures/vcr_cassettes/1.9.1/cucumber_tags/replay_cassette2.yml +0 -63
  30. data/features/fixtures/vcr_cassettes/1.9.1/cucumber_tags/replay_cassette3.yml +0 -85
  31. data/features/fixtures/vcr_cassettes/1.9.1/nested_replay_cassette.yml +0 -32
  32. data/features/fixtures/vcr_cassettes/1.9.1/not_the_real_response.yml +0 -43
  33. data/features/record_response.feature +0 -77
  34. data/features/replay_recorded_response.feature +0 -69
  35. data/features/step_definitions/vcr_steps.rb +0 -144
  36. data/features/support/env.rb +0 -64
  37. data/lib/vcr/extensions/fake_web.rb +0 -20
  38. data/lib/vcr/extensions/net_read_adapter.rb +0 -22
  39. data/spec/cassette_spec.rb +0 -213
  40. data/spec/config_spec.rb +0 -49
  41. data/spec/cucumber_tags_spec.rb +0 -71
  42. data/spec/deprecations_spec.rb +0 -67
  43. data/spec/extensions/net_http_response_spec.rb +0 -86
  44. data/spec/extensions/net_http_spec.rb +0 -72
  45. data/spec/extensions/net_read_adapter_spec.rb +0 -10
  46. data/spec/fixtures/1.8.6/0_3_1_cassette.yml +0 -29
  47. data/spec/fixtures/1.8.6/cassette_spec/example.yml +0 -110
  48. data/spec/fixtures/1.8.6/example_net_http.yml +0 -14
  49. data/spec/fixtures/1.8.6/example_net_http_request.yml +0 -12
  50. data/spec/fixtures/1.8.6/example_net_http_response.yml +0 -25
  51. data/spec/fixtures/1.8.6/fake_example.com_responses.yml +0 -90
  52. data/spec/fixtures/1.8.7/0_3_1_cassette.yml +0 -29
  53. data/spec/fixtures/1.8.7/cassette_spec/example.yml +0 -110
  54. data/spec/fixtures/1.8.7/example_net_http.yml +0 -14
  55. data/spec/fixtures/1.8.7/example_net_http_request.yml +0 -12
  56. data/spec/fixtures/1.8.7/example_net_http_response.yml +0 -25
  57. data/spec/fixtures/1.8.7/fake_example.com_responses.yml +0 -90
  58. data/spec/fixtures/1.9.1/0_3_1_cassette.yml +0 -29
  59. data/spec/fixtures/1.9.1/cassette_spec/example.yml +0 -110
  60. data/spec/fixtures/1.9.1/example_net_http.yml +0 -14
  61. data/spec/fixtures/1.9.1/example_net_http_request.yml +0 -12
  62. data/spec/fixtures/1.9.1/example_net_http_response.yml +0 -25
  63. data/spec/fixtures/1.9.1/fake_example.com_responses.yml +0 -90
  64. data/spec/http_stubbing_adapters/fakeweb_spec.rb +0 -24
  65. data/spec/http_stubbing_adapters/webmock_spec.rb +0 -23
  66. data/spec/spec.opts +0 -2
  67. data/spec/spec_helper.rb +0 -35
  68. data/spec/structs_spec.rb +0 -95
  69. data/spec/support/deprecated.rb +0 -18
  70. data/spec/support/disable_warnings.rb +0 -12
  71. data/spec/support/http_stubbing_adapter.rb +0 -113
  72. data/spec/support/temp_cassette_library_dir.rb +0 -16
  73. data/spec/task_runner_spec.rb +0 -59
  74. data/spec/vcr_spec.rb +0 -119
  75. data/vcr.gemspec +0 -147
@@ -1,77 +0,0 @@
1
- Feature: Record response
2
- In order to have deterministic, fast tests that do not depend on an internet connection
3
- As a TDD/BDD developer
4
- I want to record responses for new requests so I can replay them in future test runs
5
-
6
- Scenario: Record a response using VCR.use_cassette
7
- Given we do not have a "temp/cassette" cassette
8
- When I make an HTTP get request to "http://example.com" within the "temp/cassette" cassette
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
-
11
- @record_cassette1
12
- Scenario: Record a response using a tagged scenario
13
- Given we do not have a "cucumber_tags/record_cassette1" cassette
14
- And this scenario is tagged with the vcr cassette tag: "@record_cassette1"
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 ejected
17
-
18
- Scenario: Check the recorded response for the previous scenario
19
- Given the previous scenario was tagged with the vcr cassette tag: "@record_cassette1"
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
-
22
- @record_cassette2
23
- Scenario: Use both a tagged scenario cassette and a nested cassette within a single step definition
24
- Given we do not have a "cucumber_tags/record_cassette2" cassette
25
- And we do not have a "temp/nested" cassette
26
- And this scenario is tagged with the vcr cassette tag: "@record_cassette2"
27
- When I make an HTTP get request to "http://example.com/before_nested"
28
- And I make an HTTP get request to "http://example.com/nested" within the "temp/nested" cassette
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 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
-
33
- Scenario: Check the recorded response for the previous scenario
34
- Given the previous scenario was tagged with the vcr cassette tag: "@record_cassette2"
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
-
38
- Scenario: Make an HTTP request in a cassette with record mode set to :all
39
- Given we do not have a "temp/record_all_cassette" cassette
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" library file should have a response for "http://example.com" that matches /You have reached this web page by typing.*example\.com/
42
-
43
- Scenario: Make an HTTP request in a cassette with record mode set to :none
44
- Given we do not have a "temp/record_none_cassette" cassette
45
- When I make an HTTP get request to "http://example.com" within the "temp/record_none_cassette" none cassette
46
- Then the HTTP get request to "http://example.com" should result in an error that mentions VCR
47
- And there should not be a "temp/record_none_cassette" library file
48
-
49
- @copy_not_the_real_response_to_temp
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
-
57
- Scenario: Record an asynchronous request (such as for mechanize)
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" 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
-
62
- Scenario: Record a recursive post request
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" 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
-
68
- Scenario: Make an allowed HTTP request in a cassette with record mode set to :none
69
- Given we do not have a "temp/record_none_cassette" cassette
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
- 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" library file
73
-
74
- Scenario: Record a request with a block with a return statement
75
- Given we do not have a "temp/block_with_a_return" cassette
76
- When I make a returning block HTTP get request to "http://example.com" within the "temp/block_with_a_return" new_episodes cassette
77
- Then the "temp/block_with_a_return" library file should have a response for "http://example.com" that matches /You have reached this web page by typing.*example\.com/
@@ -1,69 +0,0 @@
1
- Feature: Replay recorded response
2
- In order to have deterministic, fast tests that do not depend on an internet connection
3
- As a TDD/BDD developer
4
- I want to replay responses for requests I have previously recorded
5
-
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
- When I make an HTTP get request to "http://example.com" within the "not_the_real_response" cassette
9
- Then the response for "http://example.com" should match /This is not the real response from example\.com/
10
-
11
- @replay_cassette1
12
- Scenario: Replay recorded response for a request within a tagged scenario
13
- Given this scenario is tagged with the vcr cassette tag: "@replay_cassette1"
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
- When I make an HTTP get request to "http://example.com"
16
- Then the response for "http://example.com" should match /This is not the real response from example\.com/
17
-
18
- @replay_cassette2
19
- Scenario: Use both a tagged scenario cassette and a nested cassette within a single step definition
20
- Given this scenario is tagged with the vcr cassette tag: "@replay_cassette2"
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
- When I make an HTTP get request to "http://example.com/before_nested"
25
- And I make an HTTP get request to "http://example.com/nested" within the "nested_replay_cassette" cassette
26
- And I make an HTTP get request to "http://example.com/after_nested"
27
- Then the response for "http://example.com/before_nested" should match /The before_nested response/
28
- And the response for "http://example.com/nested" should match /The nested response/
29
- And the response for "http://example.com/after_nested" should match /The after_nested response/
30
-
31
- @copy_not_the_real_response_to_temp
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" 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
- 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
- Then the response for "http://example.com" should match /You have reached this web page by typing.*example\.com/
37
- And the response for "http://example.com/foo" should match /The requested URL \/foo was not found/
38
-
39
- @copy_not_the_real_response_to_temp
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" 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
- 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
- Then the response for "http://example.com" should match /This is not the real response from example\.com/
45
- And the HTTP get request to "http://example.com/foo" should result in an error that mentions VCR
46
-
47
- @copy_not_the_real_response_to_temp
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
- Then the response for "http://example.com" should match /This is not the real response from example\.com/
53
- And the response for "http://example.com/foo" should match /The requested URL \/foo was not found/
54
-
55
- @replay_cassette3
56
- Scenario: Replay multiple different recorded responses for requests to the same URL
57
- Given this scenario is tagged with the vcr cassette tag: "@replay_cassette3"
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
- When I make an HTTP get request to "http://example.com"
61
- And I make an HTTP get request to "http://example.com"
62
- Then response 1 for "http://example.com" should match /This is not the real response from example\.com/
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/
@@ -1,144 +0,0 @@
1
- require 'tmpdir'
2
-
3
- module VCRHelpers
4
- def have_expected_response(url, regex_str)
5
- simple_matcher("a response from #{url} that matches /#{regex_str}/") do |responses|
6
- regex = /#{regex_str}/i
7
- responses = responses.select { |r| URI.parse(r.uri) == URI.parse(url) }
8
- responses.detect { |r| r.response.body =~ regex }
9
- end
10
- end
11
-
12
- def recorded_interactions_for(cassette_name)
13
- yaml_file = File.join(VCR::Config.cassette_library_dir, "#{cassette_name}.yml")
14
- yaml = File.open(yaml_file, 'r') { |f| f.read }
15
- interactions = YAML.load(yaml)
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
29
-
30
- def perform_get_with_returning_block(uri, path)
31
- Net::HTTP.new(uri.host, uri.port).request(Net::HTTP::Get.new(path, {})) do |response|
32
- return response
33
- end
34
- end
35
- end
36
- World(VCRHelpers)
37
-
38
- Given /^we do not have a "([^\"]*)" cassette$/ do |cassette_name|
39
- fixture_file = File.join(VCR::Config.cassette_library_dir, "#{cassette_name}.yml")
40
- File.exist?(fixture_file).should be_false
41
- end
42
-
43
- Given /^we have a "([^\"]*)" library file with (a|no) previously recorded response for "([^\"]*)"$/ do |file_name, a_or_no, url|
44
- fixture_file = File.join(VCR::Config.cassette_library_dir, "#{file_name}.yml")
45
- File.exist?(fixture_file).should be_true
46
- responses = File.open(fixture_file, 'r') { |f| YAML.load(f.read) }
47
- should_method = a_or_no == 'a' ? :should : :should_not
48
- responses.map{ |r| URI.parse(r.uri) }.send(should_method, include(URI.parse(url)))
49
- end
50
-
51
- Given /^the "([^\"]*)" library file has a response for "([^\"]*)" that matches \/(.+)\/$/ do |cassette_name, url, regex_str|
52
- Given %{we have a "#{cassette_name}" library file with a previously recorded response for "#{url}"}
53
- Then %{the "#{cassette_name}" library file should have a response for "#{url}" that matches /#{regex_str}/}
54
- end
55
-
56
- Given /^this scenario is tagged with the vcr cassette tag: "([^\"]+)"$/ do |tag|
57
- VCR.current_cucumber_scenario.should be_tagged_with(tag)
58
- VCR::CucumberTags.tags.should include(tag)
59
- end
60
-
61
- Given /^the previous scenario was tagged with the vcr cassette tag: "([^\"]*)"$/ do |tag|
62
- last_scenario = VCR.completed_cucumber_scenarios.last
63
- last_scenario.should_not be_nil
64
- last_scenario.should be_tagged_with(tag)
65
- VCR::CucumberTags.tags.should include(tag)
66
- end
67
-
68
- When /^I make (?:an )?HTTP get request to "([^\"]*)"$/ do |url|
69
- capture_response(url) do |uri, path|
70
- Net::HTTP.get_response(uri)
71
- end
72
- end
73
-
74
- When /^I make an asynchronous HTTP get request to "([^\"]*)"$/ do |url|
75
- capture_response(url) do |uri, path|
76
- result = Net::HTTP.new(uri.host, uri.port).request_get(path) { |r| r.read_body { } }
77
- result.body.should be_a(Net::ReadAdapter)
78
- result
79
- end
80
- end
81
-
82
- When /^I make a replayed asynchronous HTTP get request to "([^\"]*)"$/ do |url|
83
- capture_response(url) do |uri, path|
84
- result_body = ''
85
- result = Net::HTTP.new(uri.host, uri.port).request_get(path) { |r| r.read_body { |fragment| result_body << fragment } }
86
- result.body.should == result_body
87
- result
88
- end
89
- end
90
-
91
- When /^I make a recursive HTTP post request to "([^\"]*)"$/ do |url|
92
- capture_response(url) do |uri, path|
93
- Net::HTTP.new(uri.host, uri.port).post(path, nil)
94
- end
95
- end
96
-
97
- When /^I make a returning block HTTP get request to "([^\"]*)"$/ do |url|
98
- capture_response(url) do |uri, path|
99
- perform_get_with_returning_block(uri, path)
100
- end
101
- end
102
-
103
- 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|
104
- options = { :record => (record_mode ? record_mode.to_sym : :new_episodes) }
105
- options[:allow_real_http] = lambda { |uri| uri.to_s =~ /#{allowed}/ } if allowed.to_s.size > 0
106
- urls = [url1, url2].select { |u| u.to_s.size > 0 }
107
- VCR.use_cassette(cassette_name, options) do
108
- urls.each do |url|
109
- When %{I make #{http_request_type} request to "#{url}"}
110
- end
111
- end
112
- end
113
-
114
- Then /^the "([^\"]*)" library file should have a response for "([^\"]*)" that matches \/(.+)\/$/ do |cassette_name, url, regex_str|
115
- interactions = recorded_interactions_for(cassette_name)
116
- interactions.should have_expected_response(url, regex_str)
117
- end
118
-
119
- Then /^the "([^\"]*)" library file should have exactly (\d+) response$/ do |cassette_name, response_count|
120
- interactions = recorded_interactions_for(cassette_name)
121
- interactions.should have(response_count.to_i).responses
122
- end
123
-
124
- Then /^I can test the scenario cassette's recorded responses in the next scenario, after the cassette has been ejected$/ do
125
- # do nothing...
126
- end
127
-
128
- Then /^the HTTP get request to "([^\"]*)" should result in an error that mentions VCR$/ do |url|
129
- result = @http_requests[url][0]
130
- result.should be_a(StandardError)
131
- result.message.should =~ /VCR/
132
- end
133
-
134
- Then /^(?:the )?response(?: (\d+))? for "([^\"]*)" should match \/(.+)\/$/ do |response_num, url, regex_str|
135
- response_num = response_num.to_i || 0
136
- response_num -= 1 if response_num > 0 # translate to 0-based array index.
137
- regex = /#{regex_str}/i
138
- @http_requests[url][response_num].body.should =~ regex
139
- end
140
-
141
- Then /^there should not be a "([^\"]*)" library file$/ do |cassette_name|
142
- yaml_file = File.join(VCR::Config.cassette_library_dir, "#{cassette_name}.yml")
143
- File.exist?(yaml_file).should be_false
144
- end
@@ -1,64 +0,0 @@
1
- $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../lib')
2
- require 'vcr'
3
-
4
- begin
5
- require 'ruby-debug'
6
- Debugger.start
7
- Debugger.settings[:autoeval] = true if Debugger.respond_to?(:settings)
8
- rescue LoadError
9
- # ruby-debug wasn't available so neither can the debugging be
10
- end
11
-
12
- require 'spec/expectations'
13
-
14
- VCR.config do |c|
15
- c.cassette_library_dir = File.join(File.dirname(__FILE__), '..', 'fixtures', 'vcr_cassettes', RUBY_VERSION)
16
- c.http_stubbing_library = if ENV['HTTP_STUBBING_ADAPTER'].to_s == ''
17
- warn "Using fakeweb for VCR's cucumber features since the adapter was not specified. Set HTTP_STUBBING_ADAPTER to specify."
18
- :fakeweb
19
- else
20
- ENV['HTTP_STUBBING_ADAPTER'].to_sym
21
- end
22
- end
23
-
24
- VCR.module_eval do
25
- def self.completed_cucumber_scenarios
26
- @completed_cucumber_scenarios ||= []
27
- end
28
-
29
- class << self
30
- attr_accessor :current_cucumber_scenario
31
- end
32
- end
33
-
34
- After do |scenario|
35
- if raised_error = (@http_requests || {}).values.flatten.detect { |result| result.is_a?(Exception) && result.message !~ /VCR/ }
36
- raise raised_error
37
- end
38
- VCR.completed_cucumber_scenarios << scenario
39
- end
40
-
41
- Before do |scenario|
42
- VCR.current_cucumber_scenario = scenario
43
- temp_dir = File.join(VCR::Config.cassette_library_dir, 'temp')
44
- FileUtils.rm_rf(temp_dir) if File.exist?(temp_dir)
45
- end
46
-
47
- Before('@copy_not_the_real_response_to_temp') do
48
- orig_file = File.join(VCR::Config.cassette_library_dir, 'not_the_real_response.yml')
49
- temp_file = File.join(VCR::Config.cassette_library_dir, 'temp', 'not_the_real_response.yml')
50
- FileUtils.mkdir_p(File.join(VCR::Config.cassette_library_dir, 'temp'))
51
- FileUtils.cp orig_file, temp_file
52
- end
53
-
54
- at_exit do
55
- %w(record_cassette1 record_cassette2).each do |tag|
56
- file = File.join(VCR::Config.cassette_library_dir, 'cucumber_tags', "#{tag}.yml")
57
- FileUtils.rm_rf(file) if File.exist?(file)
58
- end
59
- end
60
-
61
- VCR.cucumber_tags do |t|
62
- t.tags '@record_cassette1', '@record_cassette2', :record => :new_episodes
63
- t.tags '@replay_cassette1', '@replay_cassette2', '@replay_cassette3', :record => :none
64
- end
@@ -1,20 +0,0 @@
1
- require 'fakeweb'
2
-
3
- module FakeWeb
4
- def self.request_uri(net_http, request)
5
- # Copied from: http://github.com/chrisk/fakeweb/blob/fakeweb-1.2.8/lib/fake_web/ext/net_http.rb#L39-52
6
- protocol = net_http.use_ssl? ? "https" : "http"
7
-
8
- path = request.path
9
- path = URI.parse(request.path).request_uri if request.path =~ /^http/
10
-
11
- if request["authorization"] =~ /^Basic /
12
- userinfo = FakeWeb::Utility.decode_userinfo_from_header(request["authorization"])
13
- userinfo = FakeWeb::Utility.encode_unsafe_chars_in_userinfo(userinfo) + "@"
14
- else
15
- userinfo = ""
16
- end
17
-
18
- "#{protocol}://#{userinfo}#{net_http.address}:#{net_http.port}#{path}"
19
- end
20
- end
@@ -1,22 +0,0 @@
1
- require 'net/http'
2
-
3
- module VCR
4
- module NetReadAdapter
5
- def new(*args, &block)
6
- super.extend Extension
7
- end
8
-
9
- module Extension
10
- def <<(str)
11
- (@__body_for_vcr__ ||= '') << str
12
- super
13
- end
14
-
15
- def to_yaml(*args)
16
- @__body_for_vcr__.to_yaml(*args)
17
- end
18
- end
19
- end
20
- end
21
-
22
- Net::ReadAdapter.extend VCR::NetReadAdapter
@@ -1,213 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
-
3
- describe VCR::Cassette do
4
- describe '#file' do
5
- temp_dir File.expand_path(File.dirname(__FILE__) + '/fixtures/file'), :assign_to_cassette_library_dir => true
6
-
7
- it 'combines the cassette_library_dir with the cassette name' do
8
- cassette = VCR::Cassette.new('the_file')
9
- cassette.file.should == File.join(VCR::Config.cassette_library_dir, 'the_file.yml')
10
- end
11
-
12
- it 'strips out disallowed characters so that it is a valid file name with no spaces' do
13
- cassette = VCR::Cassette.new("\nthis \t! is-the_13212_file name")
14
- cassette.file.should =~ /#{Regexp.escape('_this_is-the_13212_file_name.yml')}$/
15
- end
16
-
17
- it 'keeps any path separators' do
18
- cassette = VCR::Cassette.new("dir/file_name")
19
- cassette.file.should =~ /#{Regexp.escape('dir/file_name.yml')}$/
20
- end
21
-
22
- it 'returns nil if the cassette_library_dir is not set' do
23
- VCR::Config.cassette_library_dir = nil
24
- cassette = VCR::Cassette.new('the_file')
25
- cassette.file.should be_nil
26
- end
27
- end
28
-
29
- describe '#record_http_interaction' do
30
- it 'adds the interaction to #recorded_interactions' do
31
- cassette = VCR::Cassette.new(:test_cassette)
32
- cassette.recorded_interactions.should == []
33
- cassette.record_http_interaction(:the_interaction)
34
- cassette.recorded_interactions.should == [:the_interaction]
35
- end
36
- end
37
-
38
- describe 'on creation' do
39
- it 'raises an error with a helpful message when loading an old unsupported cassette' do
40
- VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{RUBY_VERSION}")
41
- lambda { VCR::Cassette.new('0_3_1_cassette') }.should raise_error(/The VCR cassette 0_3_1_cassette uses an old format that is now deprecated/)
42
- end
43
-
44
- it "raises an error if given an invalid record mode" do
45
- lambda { VCR::Cassette.new(:test, :record => :not_a_record_mode) }.should raise_error(ArgumentError)
46
- end
47
-
48
- it 'creates a stubs checkpoint on the http_stubbing_adapter' do
49
- VCR.http_stubbing_adapter.should_receive(:create_stubs_checkpoint).with('example').once
50
- VCR::Cassette.new('example')
51
- end
52
-
53
- VCR::Cassette::VALID_RECORD_MODES.each do |mode|
54
- it "defaults the record mode to #{mode} when VCR::Config.default_cassette_options[:record] is #{mode}" do
55
- VCR::Config.default_cassette_options = { :record => mode }
56
- cassette = VCR::Cassette.new(:test)
57
- cassette.record_mode.should == mode
58
- end
59
- end
60
-
61
- { :new_episodes => true, :all => true, :none => false }.each do |record_mode, http_connections_allowed|
62
- it "sets http_connections_allowed to #{http_connections_allowed} on the http stubbing adapter when the record mode is #{record_mode}" do
63
- VCR.http_stubbing_adapter.should_receive(:http_connections_allowed=).with(http_connections_allowed)
64
- VCR::Cassette.new(:name, :record => record_mode)
65
- end
66
- end
67
-
68
- { :new_episodes => true, :all => false, :none => true }.each do |record_mode, load_interactions|
69
- it "#{load_interactions ? 'loads' : 'does not load'} the recorded interactions from the library yml file when the record mode is #{record_mode}" do
70
- VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{RUBY_VERSION}/cassette_spec")
71
- cassette = VCR::Cassette.new('example', :record => record_mode)
72
-
73
- if load_interactions
74
- cassette.should have(3).recorded_interactions
75
-
76
- i1, i2, i3 = *cassette.recorded_interactions
77
-
78
- i1.request.method.should == :get
79
- i1.request.uri.should == 'http://example.com:80/'
80
- i1.response.body.should =~ /You have reached this web page by typing.+example\.com/
81
-
82
- i2.request.method.should == :get
83
- i2.request.uri.should == 'http://example.com:80/foo'
84
- i2.response.body.should =~ /foo was not found on this server/
85
-
86
- i3.request.method.should == :get
87
- i3.request.uri.should == 'http://example.com:80/'
88
- i3.response.body.should =~ /Another example\.com response/
89
- else
90
- cassette.should have(0).recorded_interactions
91
- end
92
- end
93
-
94
- it "#{load_interactions ? 'stubs' : 'does not stub'} the recorded requests with the http stubbing adapter when the record mode is #{record_mode}" do
95
- VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{RUBY_VERSION}/cassette_spec")
96
-
97
- if load_interactions
98
- VCR.http_stubbing_adapter.should_receive(:stub_requests).with([an_instance_of(VCR::HTTPInteraction)]*3)
99
- else
100
- VCR.http_stubbing_adapter.should_receive(:stub_requests).never
101
- end
102
-
103
- cassette = VCR::Cassette.new('example', :record => record_mode)
104
- end
105
- end
106
- end
107
-
108
- describe '#allow_real_http_requests_to?' do
109
- it 'delegates to the :allow_real_http lambda' do
110
- [true, false].each do |value|
111
- yielded_uri = nil
112
- c = VCR::Cassette.new('example', :allow_real_http => lambda { |uri| yielded_uri = uri; value })
113
- c.allow_real_http_requests_to?(:the_uri).should == value
114
- yielded_uri.should == :the_uri
115
- end
116
- end
117
-
118
- it 'returns true for localhost requests when the :allow_real_http option is set to :localhost' do
119
- c = VCR::Cassette.new('example', :allow_real_http => :localhost)
120
- c.allow_real_http_requests_to?(URI('http://localhost')).should be_true
121
- c.allow_real_http_requests_to?(URI('http://example.com')).should be_false
122
- end
123
-
124
- it 'returns false when no option is set' do
125
- c = VCR::Cassette.new('example')
126
- c.allow_real_http_requests_to?(URI('http://localhost')).should be_false
127
- c.allow_real_http_requests_to?(URI('http://example.com')).should be_false
128
- end
129
-
130
- it 'delegates to the default :allow_real_http lambda' do
131
- [true, false].each do |value|
132
- yielded_uri = nil
133
- VCR::Config.default_cassette_options.merge!(:allow_real_http => lambda { |uri| yielded_uri = uri; value })
134
- c = VCR::Cassette.new('example')
135
- c.allow_real_http_requests_to?(:the_uri).should == value
136
- yielded_uri.should == :the_uri
137
- end
138
-
139
- VCR::Config.default_cassette_options.merge!(:allow_real_http => :localhost)
140
- c = VCR::Cassette.new('example')
141
- c.allow_real_http_requests_to?(URI('http://localhost')).should be_true
142
- c.allow_real_http_requests_to?(URI('http://example.com')).should be_false
143
- end
144
- end
145
-
146
- describe '#eject' do
147
- temp_dir File.expand_path(File.dirname(__FILE__) + '/fixtures/cassette_spec_eject'), :assign_to_cassette_library_dir => true
148
-
149
- [true, false].each do |orig_http_connections_allowed|
150
- it "resets #{orig_http_connections_allowed} on the http stubbing adapter if it was originally #{orig_http_connections_allowed}" do
151
- VCR.http_stubbing_adapter.should_receive(:http_connections_allowed?).and_return(orig_http_connections_allowed)
152
- cassette = VCR::Cassette.new(:name)
153
- VCR.http_stubbing_adapter.should_receive(:http_connections_allowed=).with(orig_http_connections_allowed)
154
- cassette.eject
155
- end
156
- end
157
-
158
- it "writes the recorded interactions to disk as yaml" do
159
- recorded_interactions = [
160
- VCR::HTTPInteraction.new(:req_sig_1, :response_1),
161
- VCR::HTTPInteraction.new(:req_sig_2, :response_2),
162
- VCR::HTTPInteraction.new(:req_sig_3, :response_3)
163
- ]
164
-
165
- cassette = VCR::Cassette.new(:eject_test)
166
- cassette.stub!(:recorded_interactions).and_return(recorded_interactions)
167
-
168
- lambda { cassette.eject }.should change { File.exist?(cassette.file) }.from(false).to(true)
169
- saved_recorded_interactions = File.open(cassette.file, "r") { |f| YAML.load(f.read) }
170
- saved_recorded_interactions.should == recorded_interactions
171
- end
172
-
173
- it "writes the recorded interactions to a subdirectory if the cassette name includes a directory" do
174
- recorded_interactions = [VCR::HTTPInteraction.new(:the_request, :the_response)]
175
- cassette = VCR::Cassette.new('subdirectory/test_cassette')
176
- cassette.stub!(:recorded_interactions).and_return(recorded_interactions)
177
-
178
- lambda { cassette.eject }.should change { File.exist?(cassette.file) }.from(false).to(true)
179
- saved_recorded_interactions = File.open(cassette.file, "r") { |f| YAML.load(f.read) }
180
- saved_recorded_interactions.should == recorded_interactions
181
- end
182
-
183
- it "writes both old and new recorded interactions to disk" do
184
- file = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{RUBY_VERSION}/cassette_spec/example.yml")
185
- FileUtils.cp file, File.join(@temp_dir, 'previously_recorded_interactions.yml')
186
- cassette = VCR::Cassette.new('previously_recorded_interactions')
187
- cassette.should have(3).recorded_interactions
188
- new_recorded_interaction = VCR::HTTPInteraction.new(:the_request, :the_response)
189
- cassette.record_http_interaction(new_recorded_interaction)
190
- cassette.eject
191
- saved_recorded_interactions = File.open(cassette.file, "r") { |f| YAML.load(f.read) }
192
- saved_recorded_interactions.should have(4).recorded_interactions
193
- saved_recorded_interactions.last.should == new_recorded_interaction
194
- end
195
- end
196
-
197
- describe '#eject for a cassette with previously recorded interactions' do
198
- it "restore the stubs checkpoint on the http stubbing adapter" do
199
- VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{RUBY_VERSION}/cassette_spec")
200
- cassette = VCR::Cassette.new('example', :record => :none)
201
- VCR.http_stubbing_adapter.should_receive(:restore_stubs_checkpoint).with('example')
202
- cassette.eject
203
- end
204
-
205
- it "does not re-write to disk the previously recorded interactions if there are no new ones" do
206
- VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{RUBY_VERSION}/cassette_spec")
207
- yaml_file = File.join(VCR::Config.cassette_library_dir, 'example.yml')
208
- cassette = VCR::Cassette.new('example', :record => :none)
209
- File.should_not_receive(:open).with(cassette.file, 'w')
210
- lambda { cassette.eject }.should_not change { File.mtime(yaml_file) }
211
- end
212
- end
213
- end