vcr 1.3.1 → 1.3.2

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 (72) hide show
  1. data/CHANGELOG.md +14 -2
  2. data/Gemfile +3 -0
  3. data/Gemfile.lock +20 -2
  4. data/README.md +6 -1
  5. data/Rakefile +6 -44
  6. data/benchmarks/http_stubbing_libraries.rb +4 -4
  7. data/cucumber.yml +14 -0
  8. data/features/README.md +21 -0
  9. data/features/cassettes/automatic_re_recording.feature +68 -0
  10. data/features/cassettes/dynamic_erb.feature +90 -0
  11. data/features/cassettes/format.feature +81 -0
  12. data/features/cassettes/no_cassette.feature +38 -0
  13. data/features/cassettes/record_modes/all.feature +78 -0
  14. data/features/cassettes/record_modes/new_episodes.feature +71 -0
  15. data/features/cassettes/record_modes/none.feature +65 -0
  16. data/features/cassettes/request_matching.feature +379 -0
  17. data/features/configuration/cassette_library_dir.feature +28 -0
  18. data/features/configuration/default_cassette_options.feature +80 -0
  19. data/features/configuration/ignore_localhost.feature +103 -0
  20. data/features/configuration/stub_with.feature +164 -0
  21. data/features/http_libraries/net_http.feature +137 -0
  22. data/features/step_definitions/cli_steps.rb +82 -0
  23. data/features/support/aruba_workaround/aruba_patches.rb +36 -0
  24. data/features/support/aruba_workaround/background_process.rb +4 -0
  25. data/features/support/env.rb +16 -102
  26. data/features/support/http_lib_filters.rb +37 -0
  27. data/features/support/vcr_cucumber_helpers.rb +34 -0
  28. data/features/test_frameworks/cucumber.feature +109 -0
  29. data/features/test_frameworks/rspec.feature +110 -0
  30. data/features/test_frameworks/shoulda.feature +64 -0
  31. data/features/test_frameworks/test_unit.feature +46 -0
  32. data/lib/vcr/cassette.rb +1 -1
  33. data/lib/vcr/structs.rb +64 -13
  34. data/lib/vcr/version.rb +1 -1
  35. data/{FullBuildRakeFile → script/FullBuildRakeFile} +0 -0
  36. data/script/full_build +1 -0
  37. data/spec/extensions/net_http_spec.rb +1 -1
  38. data/spec/spec_helper.rb +1 -1
  39. data/spec/structs_spec.rb +47 -16
  40. data/spec/support/vcr_localhost_server.rb +11 -5
  41. data/vcr.gemspec +2 -1
  42. metadata +82 -77
  43. data/features/fixtures/vcr_cassettes/1.9.1/cucumber_tags/regex_cassette.yml +0 -43
  44. data/features/fixtures/vcr_cassettes/1.9.1/cucumber_tags/replay_cassette1.yml +0 -43
  45. data/features/fixtures/vcr_cassettes/1.9.1/cucumber_tags/replay_cassette2.yml +0 -63
  46. data/features/fixtures/vcr_cassettes/1.9.1/cucumber_tags/replay_cassette3.yml +0 -85
  47. data/features/fixtures/vcr_cassettes/1.9.1/erb_cassette.yml +0 -36
  48. data/features/fixtures/vcr_cassettes/1.9.1/match_requests_on.yml +0 -35
  49. data/features/fixtures/vcr_cassettes/1.9.1/nested_replay_cassette.yml +0 -32
  50. data/features/fixtures/vcr_cassettes/1.9.1/not_the_real_response.yml +0 -43
  51. data/features/fixtures/vcr_cassettes/1.9.1/record_all.yml +0 -62
  52. data/features/fixtures/vcr_cassettes/1.9.1/replay_localhost_cassette.yml +0 -32
  53. data/features/fixtures/vcr_cassettes/not_1.9.1/cucumber_tags/regex_cassette.yml +0 -43
  54. data/features/fixtures/vcr_cassettes/not_1.9.1/cucumber_tags/replay_cassette1.yml +0 -43
  55. data/features/fixtures/vcr_cassettes/not_1.9.1/cucumber_tags/replay_cassette2.yml +0 -47
  56. data/features/fixtures/vcr_cassettes/not_1.9.1/cucumber_tags/replay_cassette3.yml +0 -85
  57. data/features/fixtures/vcr_cassettes/not_1.9.1/erb_cassette.yml +0 -36
  58. data/features/fixtures/vcr_cassettes/not_1.9.1/match_requests_on.yml +0 -35
  59. data/features/fixtures/vcr_cassettes/not_1.9.1/nested_replay_cassette.yml +0 -24
  60. data/features/fixtures/vcr_cassettes/not_1.9.1/not_the_real_response.yml +0 -43
  61. data/features/fixtures/vcr_cassettes/not_1.9.1/record_all.yml +0 -61
  62. data/features/fixtures/vcr_cassettes/not_1.9.1/replay_localhost_cassette.yml +0 -32
  63. data/features/http_client.feature +0 -16
  64. data/features/net_http.feature +0 -38
  65. data/features/record_response.feature +0 -95
  66. data/features/replay_recorded_response.feature +0 -96
  67. data/features/rspec.feature +0 -100
  68. data/features/step_definitions/http_client_steps.rb +0 -7
  69. data/features/step_definitions/net_http_steps.rb +0 -49
  70. data/features/step_definitions/vcr_steps.rb +0 -252
  71. data/features/webmock.feature +0 -26
  72. data/full_build +0 -1
@@ -1,32 +0,0 @@
1
- ---
2
- - !ruby/struct:VCR::HTTPInteraction
3
- request: !ruby/struct:VCR::Request
4
- method: :get
5
- uri: http://localhost/
6
- body:
7
- headers:
8
- response: !ruby/struct:VCR::Response
9
- status: !ruby/struct:VCR::ResponseStatus
10
- code: 200
11
- message: OK
12
- headers:
13
- etag:
14
- - "\"24ec5-1b6-4059a80bfd280\""
15
- last-modified:
16
- - Tue, 15 Nov 2005 13:24:10 GMT
17
- connection:
18
- - Keep-Alive
19
- content-type:
20
- - text/html; charset=UTF-8
21
- date:
22
- - Thu, 25 Feb 2010 15:22:32 GMT
23
- server:
24
- - Apache/2.2.3 (CentOS)
25
- content-length:
26
- - "438"
27
- age:
28
- - "2643"
29
- accept-ranges:
30
- - bytes
31
- body: This is a fake response.
32
- http_version: "1.1"
@@ -1,16 +0,0 @@
1
- @httpclient
2
- Feature: HTTPClient
3
- In order to have deterministic, fast tests that do not depend on an internet connection
4
- As a TDD/BDD developer
5
- I want VCR to work with asynchronous HTTPClient requests
6
-
7
- Scenario: Record an asynchronous request
8
- Given we do not have a "temp/asynchronous" cassette
9
- When I make an asynchronous HTTPClient get request to "http://example.com" while using the "temp/asynchronous" cassette
10
- 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/
11
-
12
- @copy_not_the_real_response_to_temp
13
- Scenario: Replay a response for an asynchronous request
14
- 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/
15
- When I make an asynchronous HTTPClient get request to "http://example.com" while using the "temp/not_the_real_response" cassette
16
- Then the response for "http://example.com" should match /This is not the real response from example\.com/
@@ -1,38 +0,0 @@
1
- @net_http
2
- Feature: Net::HTTP
3
- In order to have deterministic, fast tests that do not depend on an internet connection
4
- As a TDD/BDD developer
5
- I want to use VCR with Net::HTTP
6
-
7
- Scenario: Record an asynchronous request (such as for mechanize)
8
- Given we do not have a "temp/asynchronous" cassette
9
- When I make an asynchronous Net::HTTP get request to "http://example.com" while using the "temp/asynchronous" cassette
10
- 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/
11
-
12
- @copy_not_the_real_response_to_temp
13
- Scenario: Replay a response for an asynchronous request (such as for mechanize)
14
- 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/
15
- When I make a replayed asynchronous Net::HTTP get request to "http://example.com" while using the "temp/not_the_real_response" cassette
16
- Then the response for "http://example.com" should match /This is not the real response from example\.com/
17
-
18
- Scenario: Record a recursive post request
19
- Given we do not have a "temp/recursive_post" cassette
20
- When I make a recursive Net::HTTP post request to "http://example.com" while using the "temp/recursive_post" cassette
21
- 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/
22
- And the "temp/recursive_post" library file should have exactly 1 response
23
-
24
- Scenario: Record a request with a block with a return statement
25
- Given we do not have a "temp/block_with_a_return" cassette
26
- When I make a returning block Net::HTTP get request to "http://example.com" while using the "temp/block_with_a_return" cassette
27
- 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/
28
-
29
- Scenario: Record a request made with open uri
30
- Given we do not have a "temp/open_uri" cassette
31
- When I make an open uri Net::HTTP get request to "http://example.com" while using the "temp/open_uri" cassette
32
- Then the "temp/open_uri" library file should have a response for "http://example.com" that matches /You have reached this web page by typing.*example\.com/
33
-
34
- @copy_not_the_real_response_to_temp
35
- Scenario: Replay a response for an open uri request
36
- 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/
37
- When I make an open uri Net::HTTP get request to "http://example.com" while using the "temp/not_the_real_response" cassette
38
- Then the response for "http://example.com" should match /This is not the real response from example\.com/
@@ -1,95 +0,0 @@
1
- @all_http_libs
2
- Feature: Record response
3
- In order to have deterministic, fast tests that do not depend on an internet connection
4
- As a TDD/BDD developer
5
- I want to record responses for new requests so I can replay them in future test runs
6
-
7
- Scenario: Record a response using VCR.use_cassette
8
- Given we do not have a "temp/cassette" cassette
9
- When I make an HTTP get request to "http://example.com/" while using the "temp/cassette" cassette
10
- 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/
11
- And the "temp/cassette" library file should have normalized headers for all recorded interactions
12
-
13
- @record_cassette1
14
- Scenario: Record a response using a tagged scenario
15
- Given we do not have a "cucumber_tags/record_cassette1" cassette
16
- And this scenario is tagged with the vcr cassette tag: "@record_cassette1"
17
- When I make an HTTP get request to "http://example.com/"
18
- Then I can test the scenario cassette's recorded responses in the next scenario, after the cassette has been ejected
19
-
20
- Scenario: Check the recorded response for the previous scenario
21
- Given the previous scenario was tagged with the vcr cassette tag: "@record_cassette1"
22
- 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/
23
-
24
- @record_cassette2
25
- Scenario: Use both a tagged scenario cassette and a nested cassette within a single step definition
26
- Given we do not have a "cucumber_tags/record_cassette2" cassette
27
- And we do not have a "temp/nested" cassette
28
- And this scenario is tagged with the vcr cassette tag: "@record_cassette2"
29
- When I make an HTTP get request to "http://example.com/before_nested"
30
- And I make an HTTP get request to "http://example.com/nested" while using the "temp/nested" cassette
31
- And I make an HTTP get request to "http://example.com/after_nested"
32
- Then I can test the scenario cassette's recorded responses in the next scenario, after the cassette has been ejected
33
- And the "temp/nested" library file should have a response for "http://example.com/nested" that matches /The requested URL \/nested was not found/
34
-
35
- Scenario: Check the recorded response for the previous scenario
36
- Given the previous scenario was tagged with the vcr cassette tag: "@record_cassette2"
37
- 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/
38
- 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/
39
-
40
- Scenario: Make an HTTP request in a cassette with record mode set to :all when the cassette does not already exist
41
- Given we do not have a "temp/record_all_cassette" cassette
42
- When I make an HTTP get request to "http://example.com/" while using the "temp/record_all_cassette" cassette using cassette options: { :record => :all }
43
- 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/
44
-
45
- @copy_record_all_to_temp
46
- Scenario: Make an HTTP request in a cassette with record mode set to :all when the cassette already exists
47
- Given the "temp/record_all" library file has a response for "http://example.com/a" that matches /a response 1/
48
- And the "temp/record_all" library file has a response for "http://example.com/a" that matches /a response 2/
49
- And the "temp/record_all" library file has a response for "http://example.com/b" that matches /b response 1/
50
- And the "temp/record_all" library file has a response for "http://example.com/b" that matches /b response 2/
51
- When I make an HTTP get request to "http://example.com/a" while using the "temp/record_all" cassette using cassette options: { :record => :all }
52
- Then the "temp/record_all" library file should have a response for "http://example.com/a" that matches /The requested URL \/a was not found/
53
- And the "temp/record_all" library file should not have a response for "http://example.com/a" that matches /a response 1/
54
- And the "temp/record_all" library file should not have a response for "http://example.com/a" that matches /a response 2/
55
- And the "temp/record_all" library file should have a response for "http://example.com/b" that matches /b response 1/
56
- And the "temp/record_all" library file should have a response for "http://example.com/b" that matches /b response 2/
57
-
58
- Scenario: Make an HTTP request in a cassette with record mode set to :none
59
- Given we do not have a "temp/record_none_cassette" cassette
60
- When I make an HTTP get request to "http://example.com/" while using the "temp/record_none_cassette" cassette using cassette options: { :record => :none }
61
- Then the HTTP get request to "http://example.com/" should result in an error that mentions VCR
62
- And there should not be a "temp/record_none_cassette" library file
63
-
64
- @copy_not_the_real_response_to_temp
65
- Scenario: Make an HTTP request in a cassette with record mode set to :new_episodes
66
- Given we have a "temp/not_the_real_response" library file with a previously recorded response for "http://example.com/"
67
- And we have a "temp/not_the_real_response" library file with no previously recorded response for "http://example.com/foo"
68
- When I make HTTP get requests to "http://example.com/" and "http://example.com/foo" while using the "temp/not_the_real_response" cassette
69
- 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/
70
- 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/
71
-
72
- @spawns_localhost_server
73
- Scenario: Ignore localhost setting allows localhost requests and does not record them
74
- Given we do not have a "temp/localhost" cassette
75
- And the ignore_localhost config setting is set to true
76
- And a rack app is running on localhost that returns "hello world" for all requests
77
- When I make an HTTP get request to the localhost rack app while using the "temp/localhost" cassette
78
- Then the response for the localhost rack app should match /hello world/
79
- And there should not be a "temp/localhost" library file
80
-
81
- @copy_not_the_real_response_to_temp
82
- Scenario: The response is not automatically recorded when not enough time has passed
83
- 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/
84
- And 6 days have passed since the "temp/not_the_real_response" library file last changed
85
- When I make an HTTP get request to "http://example.com/" while using the "temp/not_the_real_response" cassette using cassette options: { :record => :none, :re_record_interval => 7.days }
86
- Then the response for "http://example.com/" should match /This is not the real response from example.com/
87
- And 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/
88
-
89
- @copy_not_the_real_response_to_temp
90
- Scenario: The response is automatically recorded when enough time has passed
91
- 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/
92
- And 8 days have passed since the "temp/not_the_real_response" library file last changed
93
- When I make an HTTP get request to "http://example.com/" while using the "temp/not_the_real_response" cassette using cassette options: { :record => :none, :re_record_interval => 7.days }
94
- Then the response for "http://example.com/" should match /You have reached this web page by typing.*example\.com/
95
- And the "temp/not_the_real_response" library file should have a response for "http://example.com/" that matches /You have reached this web page by typing.*example\.com/
@@ -1,96 +0,0 @@
1
- @all_http_libs
2
- Feature: Replay recorded response
3
- In order to have deterministic, fast tests that do not depend on an internet connection
4
- As a TDD/BDD developer
5
- I want to replay responses for requests I have previously recorded
6
-
7
- Scenario: Replay recorded response for a request in a VCR.use_cassette block
8
- 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/
9
- When I make an HTTP get request to "http://example.com/" while using the "not_the_real_response" cassette
10
- Then the response for "http://example.com/" should match /This is not the real response from example\.com/
11
-
12
- @replay_cassette1
13
- Scenario: Replay recorded response for a request within a tagged scenario
14
- Given this scenario is tagged with the vcr cassette tag: "@replay_cassette1"
15
- 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/
16
- When I make an HTTP get request to "http://example.com/"
17
- Then the response for "http://example.com/" should match /This is not the real response from example\.com/
18
-
19
- @replay_cassette2
20
- Scenario: Use both a tagged scenario cassette and a nested cassette within a single step definition
21
- Given this scenario is tagged with the vcr cassette tag: "@replay_cassette2"
22
- And the "cucumber_tags/replay_cassette2" library file has a response for "http://example.com/before_nested" that matches /The before_nested response/
23
- And the "nested_replay_cassette" library file has a response for "http://example.com/nested" that matches /The nested response/
24
- And the "cucumber_tags/replay_cassette2" library file has a response for "http://example.com/after_nested" that matches /The after_nested response/
25
- When I make an HTTP get request to "http://example.com/before_nested"
26
- And I make an HTTP get request to "http://example.com/nested" while using the "nested_replay_cassette" cassette
27
- And I make an HTTP get request to "http://example.com/after_nested"
28
- Then the response for "http://example.com/before_nested" should match /The before_nested response/
29
- And the response for "http://example.com/nested" should match /The nested response/
30
- And the response for "http://example.com/after_nested" should match /The after_nested response/
31
-
32
- @copy_not_the_real_response_to_temp
33
- Scenario: Make an HTTP request in a cassette with record mode set to :all
34
- Given we have a "temp/not_the_real_response" library file with a previously recorded response for "http://example.com/"
35
- And we have a "temp/not_the_real_response" library file with no previously recorded response for "http://example.com/foo"
36
- When I make HTTP get requests to "http://example.com/" and "http://example.com/foo" while using the "temp/not_the_real_response" cassette using cassette options: { :record => :all }
37
- Then the response for "http://example.com/" should match /You have reached this web page by typing.*example\.com/
38
- And the response for "http://example.com/foo" should match /The requested URL \/foo was not found/
39
-
40
- @copy_not_the_real_response_to_temp
41
- Scenario: Make an HTTP request in a cassette with record mode set to :none
42
- Given we have a "temp/not_the_real_response" library file with a previously recorded response for "http://example.com/"
43
- And we have a "temp/not_the_real_response" library file with no previously recorded response for "http://example.com/foo"
44
- When I make HTTP get requests to "http://example.com/" and "http://example.com/foo" while using the "temp/not_the_real_response" cassette using cassette options: { :record => :none }
45
- Then the response for "http://example.com/" should match /This is not the real response from example\.com/
46
- And the HTTP get request to "http://example.com/foo" should result in an error that mentions VCR
47
-
48
- @copy_not_the_real_response_to_temp
49
- Scenario: Make an HTTP request in a cassette with record mode set to :new_episodes
50
- Given we have a "temp/not_the_real_response" library file with a previously recorded response for "http://example.com/"
51
- And we have a "temp/not_the_real_response" library file with no previously recorded response for "http://example.com/foo"
52
- When I make HTTP get requests to "http://example.com/" and "http://example.com/foo" while using the "temp/not_the_real_response" cassette
53
- Then the response for "http://example.com/" should match /This is not the real response from example\.com/
54
- And the response for "http://example.com/foo" should match /The requested URL \/foo was not found/
55
-
56
- @replay_cassette3
57
- Scenario: Replay multiple different recorded responses for requests to the same URL
58
- Given this scenario is tagged with the vcr cassette tag: "@replay_cassette3"
59
- 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/
60
- 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/
61
- When I make an HTTP get request to "http://example.com/"
62
- And I make an HTTP get request to "http://example.com/"
63
- Then response 1 for "http://example.com/" should match /This is not the real response from example\.com/
64
- And response 2 for "http://example.com/" should match /This is another fake response from example\.com/
65
-
66
- @regex_cassette
67
- Scenario: Replay a cassette with a regex URI
68
- Given this scenario is tagged with the vcr cassette tag: "@regex_cassette"
69
- And the "cucumber_tags/regex_cassette" library file has a response for /example\.com\/reg/ that matches /This is the response from the regex cassette/
70
- When I make an HTTP get request to "http://example.com/regex1"
71
- And I make an HTTP get request to "http://example.com/regex2"
72
- And I make an HTTP get request to "http://example.com/something_else"
73
- Then the response for "http://example.com/regex1" should match /This is the response from the regex cassette/
74
- And the response for "http://example.com/regex2" should match /This is the response from the regex cassette/
75
- And the HTTP get request to "http://example.com/something_else" should result in an error that mentions VCR
76
-
77
- Scenario: Replay recorded erb response
78
- Given the "erb_cassette" library file has a response for "http://example.com/embedded_ruby_code" that matches /Some embedded ruby code[\S\s]*The value of some_variable is/
79
- When I make an HTTP get request to "http://example.com/embedded_ruby_code" while using the "erb_cassette" cassette using cassette options: { :record => :none, :erb => { :some_variable => 'foo-bar' } }
80
- Then the response for "http://example.com/embedded_ruby_code" should match /Some embedded ruby code: 7[\S\s]*The value of some_variable is: foo-bar/
81
-
82
- @create_replay_localhost_cassette @spawns_localhost_server
83
- Scenario: Replay recorded localhost response with ignore_localhost = false
84
- Given the ignore_localhost config setting is set to false
85
- And the "temp/replay_localhost_cassette" library file has a response for localhost that matches /This is a fake response/
86
- And a rack app is running on localhost that returns "localhost response" for all requests
87
- When I make an HTTP get request to the localhost rack app while using the "temp/replay_localhost_cassette" cassette
88
- Then the response for the localhost rack app should match /This is a fake response/
89
-
90
- @create_replay_localhost_cassette @spawns_localhost_server
91
- Scenario: Replay recorded localhost response with ignore_localhost = true
92
- Given the ignore_localhost config setting is set to true
93
- And the "temp/replay_localhost_cassette" library file has a response for localhost that matches /This is a fake response/
94
- And a rack app is running on localhost that returns "localhost response" for all requests
95
- When I make an HTTP get request to the localhost rack app while using the "temp/replay_localhost_cassette" cassette
96
- Then the response for the localhost rack app should match /localhost response/
@@ -1,100 +0,0 @@
1
- @fakeweb
2
- Feature: RSpec integration
3
- In order to easily use VCR with RSpec
4
- As a user of both VCR and RSpec
5
- I want a simple macro that uses a cassette for an example group
6
-
7
- Scenario: `use_vcr_cassette` macro for RSpec 2
8
- Given the following files do not exist:
9
- | cassettes/VCR-RSpec_integration/without_an_explicit_cassette_name.yml |
10
- | cassettes/net_http_example.yml |
11
- And a file named "use_vcr_cassette_for_rspec_2_spec.rb" with:
12
- """
13
- require 'vcr'
14
-
15
- VCR.config do |c|
16
- c.cassette_library_dir = 'cassettes'
17
- c.http_stubbing_library = :fakeweb
18
- c.default_cassette_options = { :record => :new_episodes }
19
- end
20
-
21
- RSpec.configure do |c|
22
- c.extend VCR::RSpec::Macros
23
- end
24
-
25
- describe "VCR-RSpec integration" do
26
- def make_http_request
27
- Net::HTTP.get_response('example.com', '/').body
28
- end
29
-
30
- context "without an explicit cassette name" do
31
- use_vcr_cassette
32
-
33
- it 'records an http request' do
34
- make_http_request.should =~ /You have reached this web page by typing.*example\.com/
35
- end
36
- end
37
-
38
- context "with an explicit cassette name" do
39
- use_vcr_cassette "net_http_example"
40
-
41
- it 'records an http request' do
42
- make_http_request.should =~ /You have reached this web page by typing.*example\.com/
43
- end
44
- end
45
- end
46
- """
47
- When I run "rspec ./use_vcr_cassette_for_rspec_2_spec.rb"
48
- Then the output should contain "2 examples, 0 failures"
49
- And the file "cassettes/VCR-RSpec_integration/without_an_explicit_cassette_name.yml" should contain "You have reached this web page by typing"
50
- And the file "cassettes/net_http_example.yml" should contain "You have reached this web page by typing"
51
-
52
- Scenario: `use_vcr_cassette` macro for RSpec 1
53
- Given the following files do not exist:
54
- | cassettes/VCR-RSpec_integration/without_an_explicit_cassette_name.yml |
55
- | cassettes/net_http_example.yml |
56
- And a file named "use_vcr_cassette_for_rspec_1_spec.rb" with:
57
- """
58
- $LOAD_PATH.unshift(File.join(%w[ .. .. vendor rspec-1 lib ]))
59
-
60
- require 'spec'
61
- require 'spec/autorun'
62
-
63
- require 'vcr'
64
-
65
- VCR.config do |c|
66
- c.cassette_library_dir = 'cassettes'
67
- c.http_stubbing_library = :fakeweb
68
- c.default_cassette_options = { :record => :new_episodes }
69
- end
70
-
71
- Spec::Runner.configure do |c|
72
- c.extend VCR::RSpec::Macros
73
- end
74
-
75
- describe "VCR-RSpec integration" do
76
- def make_http_request
77
- Net::HTTP.get_response('example.com', '/').body
78
- end
79
-
80
- context "without an explicit cassette name" do
81
- use_vcr_cassette
82
-
83
- it 'records an http request' do
84
- make_http_request.should =~ /You have reached this web page by typing.*example\.com/
85
- end
86
- end
87
-
88
- context "with an explicit cassette name" do
89
- use_vcr_cassette "net_http_example"
90
-
91
- it 'records an http request' do
92
- make_http_request.should =~ /You have reached this web page by typing.*example\.com/
93
- end
94
- end
95
- end
96
- """
97
- When I run "ruby -I'../../lib' ./use_vcr_cassette_for_rspec_1_spec.rb"
98
- Then the output should contain "2 examples, 0 failures"
99
- And the file "cassettes/VCR-RSpec_integration/without_an_explicit_cassette_name.yml" should contain "You have reached this web page by typing"
100
- And the file "cassettes/net_http_example.yml" should contain "You have reached this web page by typing"
@@ -1,7 +0,0 @@
1
- When /^I make an asynchronous HTTPClient get request to "([^\"]*)"$/ do |url|
2
- capture_response(url) do |uri, path|
3
- connection = HTTPClient.new.get_async(uri)
4
- connection.join
5
- connection.pop
6
- end
7
- end
@@ -1,49 +0,0 @@
1
- require 'open-uri'
2
-
3
- module NetHTTPHelpers
4
- def perform_net_http_get_with_returning_block(uri, path)
5
- Net::HTTP.new(uri.host, uri.port).request(Net::HTTP::Get.new(path, {})) do |response|
6
- return response
7
- end
8
- end
9
- end
10
- World(NetHTTPHelpers)
11
-
12
- When /^I make an asynchronous Net::HTTP get request to "([^\"]*)"$/ do |url|
13
- capture_response(url) do |uri, path|
14
- result = Net::HTTP.new(uri.host, uri.port).request_get(path) { |r| r.read_body { } }
15
- result.body.should be_a(Net::ReadAdapter)
16
- result
17
- end
18
- end
19
-
20
- When /^I make a replayed asynchronous Net::HTTP get request to "([^\"]*)"$/ do |url|
21
- capture_response(url) do |uri, path|
22
- result_body = ''
23
- result = Net::HTTP.new(uri.host, uri.port).request_get(path) { |r| r.read_body { |fragment| result_body << fragment } }
24
- def result_body.body; self; end # make the string a fake response (so response.body can be called on it)
25
- result_body
26
- end
27
- end
28
-
29
- When /^I make a recursive Net::HTTP post request to "([^\"]*)"$/ do |url|
30
- capture_response(url) do |uri, path|
31
- Net::HTTP.new(uri.host, uri.port).post(path, nil)
32
- end
33
- end
34
-
35
- When /^I make a returning block Net::HTTP get request to "([^\"]*)"$/ do |url|
36
- capture_response(url) do |uri, path|
37
- perform_net_http_get_with_returning_block(uri, path)
38
- end
39
- end
40
-
41
- When /^I make an open uri Net::HTTP get request to "([^"]*)"$/ do |url|
42
- capture_response(url) do |uri, path|
43
- result = open(url)
44
- # #open returns a StringIO rather than a Net::HTTPResponse, so we add #body to make it conform to the same interface
45
- def result.body; read; end
46
- result
47
- end
48
- end
49
-
@@ -1,252 +0,0 @@
1
- require 'tmpdir'
2
-
3
- RSpec::Matchers.define :have_expected_response do |regex_str, request_attributes|
4
- def matched_responses(responses, request_attributes)
5
- url, request_body, request_headers = request_attributes[:url], request_attributes[:request_body], request_attributes[:request_headers]
6
-
7
- selector = case url
8
- when String then lambda { |r| URI.parse(r.uri) == URI.parse(url) }
9
- when Regexp then lambda { |r| r.uri == url }
10
- else raise ArgumentError.new("Unexpected url: #{url.class.to_s}: #{url.inspect}")
11
- end
12
-
13
- matched = responses.select(&selector)
14
-
15
- if request_body
16
- matched = matched.select { |r| r.request.body == request_body }
17
- end
18
-
19
- (request_headers || {}).each do |r_key, r_val|
20
- matched = matched.select do |r|
21
- r.request.headers.any? { |k, v| k.downcase == r_key.downcase && v == [r_val] }
22
- end
23
- end
24
-
25
- matched
26
- end
27
-
28
- match do |responses|
29
- regex = /#{regex_str}/i
30
- matched_responses(responses, request_attributes).detect { |r| r.response.body =~ regex }
31
- end
32
-
33
- failure_message_for_should do |responses|
34
- url = request_attributes[:url]
35
- responses = matched_responses(responses, request_attributes)
36
- response_bodies = responses.map { |r| r.response.body }
37
- "expected a response for #{url.inspect} to match /#{regex_str}/. Responses for #{url.inspect}:\n\n #{response_bodies.join("\n\n")}"
38
- end
39
- end
40
-
41
- RSpec::Matchers.define :be_tagged_with do |tag|
42
- match do |scenario|
43
- scenario.source_tag_names.include?(tag)
44
- end
45
-
46
- failure_message_for_should do |scenario|
47
- "expected scenario to be tagged with #{tag}. Tags: #{scenario.source_tag_names.inspect}"
48
- end
49
- end
50
-
51
- RSpec::Matchers.define :have_normalized_headers do
52
- match do |object|
53
- headers = object.headers
54
- headers.is_a?(Hash) &&
55
- headers.keys.map { |k| k.downcase } == headers.keys &&
56
- headers.values.all? { |val| val.is_a?(Array) }
57
- end
58
-
59
- failure_message_for_should do |object|
60
- "expected headers to be normalized to have lower cased keys and arrays as values. Actual headers: #{object.headers.inspect}"
61
- end
62
- end
63
-
64
- module VCRHelpers
65
- def static_rack_server(response_string)
66
- orig_ignore_localhost = VCR.http_stubbing_adapter.ignore_localhost?
67
- VCR.http_stubbing_adapter.ignore_localhost = true
68
-
69
- begin
70
- VCR::LocalhostServer::STATIC_SERVERS[response_string]
71
- ensure
72
- VCR.http_stubbing_adapter.ignore_localhost = orig_ignore_localhost
73
- end
74
- end
75
-
76
- def recorded_interactions_for(cassette_name)
77
- interactions = YAML.load(File.read(file_name(cassette_name)))
78
- end
79
-
80
- def file_name(cassette_name)
81
- File.join(VCR::Config.cassette_library_dir, "#{cassette_name}.yml")
82
- end
83
-
84
- def capture_response(url)
85
- @http_requests ||= Hash.new([])
86
- uri = URI.parse(url)
87
- path = uri.path.to_s == '' ? '/' : uri.path
88
- begin
89
- result = yield uri, path
90
- rescue => e
91
- result = e
92
- end
93
- @http_requests[url] += [result]
94
- end
95
-
96
- end
97
- World(VCRHelpers)
98
-
99
- Given /^we do not have a "([^\"]*)" cassette$/ do |cassette_name|
100
- File.exist?(file_name(cassette_name)).should be_false
101
- end
102
-
103
- Given /^we have a "([^\"]*)" library file with (a|no) previously recorded response for "([^\"]*)"$/ do |cassette_name, a_or_no, url|
104
- fixture_file = file_name(cassette_name)
105
- File.exist?(fixture_file).should be_true
106
- responses = File.open(fixture_file, 'r') { |f| YAML.load(f.read) }
107
- should_method = a_or_no == 'a' ? :should : :should_not
108
- responses.map{ |r| URI.parse(r.uri) }.send(should_method, include(URI.parse(url)))
109
- end
110
-
111
- Given /^the "([^\"]*)" library file has a response for "([^\"]*)" that matches \/(.+)\/$/ do |cassette_name, url, regex_str|
112
- Given %{we have a "#{cassette_name}" library file with a previously recorded response for "#{url}"}
113
- Then %{the "#{cassette_name}" library file should have a response for "#{url}" that matches /#{regex_str}/}
114
- end
115
-
116
- Given /^the "([^\"]*)" library file has a response for \/(\S+)\/ that matches \/(.+)\/$/ do |cassette_name, url_regex, body_regex|
117
- recorded_interactions_for(cassette_name).should have_expected_response(body_regex, :url => /#{url_regex}/)
118
- end
119
-
120
- Given /^the "([^"]*)" library file has a response for "([^"]*)" with the request body "([^"]*)" that matches \/(.+)\/$/ do |cassette_name, url, request_body, response_regex|
121
- recorded_interactions_for(cassette_name).should have_expected_response(response_regex, :url => url, :request_body => request_body)
122
- end
123
-
124
- Given /^the "([^"]*)" library file has a response for "([^"]*)" with the request header "([^"]*)=([^"]*)" that matches \/(.+)\/$/ do |cassette_name, url, header_key, header_value, response_regex|
125
- recorded_interactions_for(cassette_name).should have_expected_response(response_regex, :url => url, :request_headers => { header_key => header_value })
126
- end
127
-
128
- Given /^this scenario is tagged with the vcr cassette tag: "([^\"]+)"$/ do |tag|
129
- VCR.current_cucumber_scenario.should be_tagged_with(tag)
130
- VCR::CucumberTags.tags.should include(tag)
131
- end
132
-
133
- Given /^the previous scenario was tagged with the vcr cassette tag: "([^\"]*)"$/ do |tag|
134
- last_scenario = VCR.completed_cucumber_scenarios.last
135
- last_scenario.should_not be_nil
136
- last_scenario.should be_tagged_with(tag)
137
- VCR::CucumberTags.tags.should include(tag)
138
- end
139
-
140
- When /^I make (?:an )?HTTP get request to "([^\"]*)"$/ do |url|
141
- capture_response(url) do |uri, path|
142
- make_http_request(:get, url)
143
- end
144
- end
145
-
146
- When /^I make an HTTP post request to "([^"]*)" with request body "([^"]*)"$/ do |url, request_body|
147
- capture_response(url) do |uri, path|
148
- make_http_request(:post, url, request_body)
149
- end
150
- end
151
-
152
- When /^I make an HTTP post request to "([^"]*)" with request header "([^"]*)=([^"]*)"$/ do |url, header_key, header_val|
153
- capture_response(url) do |uri, path|
154
- make_http_request(:post, url, '', { header_key => header_val })
155
- end
156
- end
157
-
158
- When /^I make (.*) requests? to "([^\"]*)"(?: and "([^\"]*)")? while using the "([^\"]*)" cassette(?: using cassette options: (.*))?$/ do |http_request_type, url1, url2, cassette_name, options|
159
- options = options.to_s == '' ? { :record => :new_episodes } : eval(options)
160
- urls = [url1, url2].select { |u| u.to_s.size > 0 }
161
- VCR.use_cassette(cassette_name, options) do
162
- urls.each do |url|
163
- When %{I make #{http_request_type} request to "#{url}"}
164
- end
165
- end
166
- end
167
-
168
- When /^I make an HTTP post request to "([^"]*)" with request body "([^"]*)" while using the "([^"]*)" cassette(?: using cassette options: (.*))?$/ do |url, request_body, cassette_name, options|
169
- options = options.to_s == '' ? { :record => :new_episodes } : eval(options)
170
- VCR.use_cassette(cassette_name, options) do
171
- When %{I make an HTTP post request to "#{url}" with request body "#{request_body}"}
172
- end
173
- end
174
-
175
- When /^I make an HTTP post request to "([^"]*)" with request header "([^"]*)=([^"]*)" while using the "([^"]*)" cassette(?: using cassette options: (.*))?$/ do |url, header_key, header_value, cassette_name, options|
176
- options = options.to_s == '' ? { :record => :new_episodes } : eval(options)
177
- VCR.use_cassette(cassette_name, options) do
178
- When %{I make an HTTP post request to "#{url}" with request header "#{header_key}=#{header_value}"}
179
- end
180
- end
181
-
182
- Then /^the "([^\"]*)" library file (should(?: not)?) have a response for "([^\"]*)" that matches \/(.+)\/$/ do |cassette_name, expectation, url, regex_str|
183
- expectation = expectation.gsub(' ', '_')
184
- interactions = recorded_interactions_for(cassette_name)
185
- interactions.send(expectation, have_expected_response(regex_str, :url => url))
186
- end
187
-
188
- Then /^the "([^\"]*)" library file should have exactly (\d+) response$/ do |cassette_name, response_count|
189
- interactions = recorded_interactions_for(cassette_name)
190
- interactions.should have(response_count.to_i).responses
191
- end
192
-
193
- Then /^the "([^"]*)" library file should have normalized headers for all recorded interactions$/ do |cassette_name|
194
- interactions = recorded_interactions_for(cassette_name)
195
- interactions.each do |i|
196
- i.request.should have_normalized_headers
197
- i.response.should have_normalized_headers
198
- end
199
- end
200
-
201
- Then /^I can test the scenario cassette's recorded responses in the next scenario, after the cassette has been ejected$/ do
202
- # do nothing...
203
- end
204
-
205
- Then /^the HTTP get request to "([^\"]*)" should result in an error that mentions VCR$/ do |url|
206
- result = @http_requests[url][0]
207
- result.should be_a(StandardError)
208
- result.message.should =~ /VCR/
209
- end
210
-
211
- Then /^(?:the )?response(?: (\d+))? for "([^\"]*)" should match \/(.+)\/$/ do |response_num, url, regex_str|
212
- response_num = response_num.to_i || 0
213
- response_num -= 1 if response_num > 0 # translate to 0-based array index.
214
- regex = /#{regex_str}/i
215
- response = @http_requests[url][response_num]
216
- raise response if response.is_a?(Exception)
217
- get_body_string(response).should =~ regex
218
- end
219
-
220
- Then /^there should not be a "([^\"]*)" library file$/ do |cassette_name|
221
- File.exist?(file_name(cassette_name)).should be_false
222
- end
223
-
224
- Given /^the ignore_localhost config setting is set to (true|false)$/ do |value|
225
- VCR::Config.ignore_localhost = eval(value)
226
- end
227
-
228
- Given /^a rack app is running on localhost that returns "([^"]+)" for all requests$/ do |response_string|
229
- @rack_server = static_rack_server(response_string)
230
- end
231
-
232
- When /^I make an HTTP get request to the localhost rack app while using the "([^\"]*)" cassette$/ do |cassette|
233
- When %{I make an HTTP get request to "http://localhost:#{@rack_server.port}/" while using the "#{cassette}" cassette}
234
- end
235
-
236
- Then /^the response for the localhost rack app should match \/(.*)\/$/ do |regex|
237
- Then %{the response for "http://localhost:#{@rack_server.port}/" should match /#{regex}/}
238
- end
239
-
240
- Given /^the "([^\"]*)" library file has a response for localhost that matches \/(.*)\/$/ do |cassette, regex|
241
- port = static_rack_server('localhost response').port
242
- Given %{the "#{cassette}" library file has a response for "http://localhost:#{port}/" that matches /#{regex}/}
243
- end
244
-
245
- Given /^(\d+) days have passed since the "([^"]*)" library file last changed$/ do |day_count, file|
246
- last_changed_at = File.new(file_name(file)).mtime
247
- Timecop.travel(last_changed_at + day_count.to_i.days)
248
- end
249
-
250
- Given /the following files do not exist:/ do |files|
251
- check_file_presence(files.raw.map{|file_row| file_row[0]}, false)
252
- end