vcr 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/.document +5 -0
  2. data/.gitignore +22 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +156 -0
  5. data/Rakefile +60 -0
  6. data/VERSION +1 -0
  7. data/features/fixtures/vcr_cassettes/1.8.6/cucumber_tags/replay_cassette1.yml +43 -0
  8. data/features/fixtures/vcr_cassettes/1.8.6/cucumber_tags/replay_cassette2.yml +45 -0
  9. data/features/fixtures/vcr_cassettes/1.8.6/nested_replay_cassette.yml +23 -0
  10. data/features/fixtures/vcr_cassettes/1.8.6/not_the_real_response.yml +43 -0
  11. data/features/fixtures/vcr_cassettes/1.8.7/cucumber_tags/replay_cassette1.yml +43 -0
  12. data/features/fixtures/vcr_cassettes/1.8.7/cucumber_tags/replay_cassette2.yml +45 -0
  13. data/features/fixtures/vcr_cassettes/1.8.7/nested_replay_cassette.yml +23 -0
  14. data/features/fixtures/vcr_cassettes/1.8.7/not_the_real_response.yml +43 -0
  15. data/features/fixtures/vcr_cassettes/1.9.1/cucumber_tags/replay_cassette1.yml +43 -0
  16. data/features/fixtures/vcr_cassettes/1.9.1/cucumber_tags/replay_cassette2.yml +61 -0
  17. data/features/fixtures/vcr_cassettes/1.9.1/nested_replay_cassette.yml +31 -0
  18. data/features/fixtures/vcr_cassettes/1.9.1/not_the_real_response.yml +43 -0
  19. data/features/record_response.feature +55 -0
  20. data/features/replay_recorded_response.feature +53 -0
  21. data/features/step_definitions/vcr_steps.rb +88 -0
  22. data/features/support/env.rb +55 -0
  23. data/lib/vcr.rb +48 -0
  24. data/lib/vcr/cassette.rb +89 -0
  25. data/lib/vcr/config.rb +19 -0
  26. data/lib/vcr/cucumber_tags.rb +38 -0
  27. data/lib/vcr/fake_web_extensions.rb +18 -0
  28. data/lib/vcr/net_http_extensions.rb +39 -0
  29. data/lib/vcr/recorded_response.rb +4 -0
  30. data/spec/cassette_spec.rb +185 -0
  31. data/spec/config_spec.rb +27 -0
  32. data/spec/cucumber_tags_spec.rb +71 -0
  33. data/spec/fake_web_extensions_spec.rb +26 -0
  34. data/spec/fixtures/1.8.6/cassette_spec/example.yml +78 -0
  35. data/spec/fixtures/1.8.7/cassette_spec/example.yml +78 -0
  36. data/spec/fixtures/1.9.1/cassette_spec/example.yml +77 -0
  37. data/spec/net_http_extensions_spec.rb +40 -0
  38. data/spec/recorded_response_spec.rb +25 -0
  39. data/spec/spec.opts +2 -0
  40. data/spec/spec_helper.rb +22 -0
  41. data/spec/support/temp_cache_dir.rb +16 -0
  42. data/spec/vcr_spec.rb +95 -0
  43. metadata +154 -0
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,22 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
22
+ features/fixtures/vcr_cassettes/**/temp/
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Myron Marston
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,156 @@
1
+ = VCR
2
+
3
+ VCR provides helpers to record HTTP requests for URIs that are not registered with fakeweb, and replay them later.
4
+ It provides built-in support for cucumber, but works with any ruby testing framework.
5
+
6
+ == Installation
7
+
8
+ gem install vcr
9
+
10
+ == Background
11
+
12
+ This README assumes you are familiar with FakeWeb; if not, please checkout the {README}[http://github.com/chrisk/fakeweb/blob/master/README.rdoc].
13
+
14
+ VCR was inspired by {NetRecorder}[http://github.com/chrisyoung/netrecorder], but was designed from the ground up to support
15
+ localized recording and replaying, rather than the global recording and replaying of NetRecorder.
16
+
17
+ == Cassettes
18
+
19
+ Cassettes are central to the way VCR works. They are a similar to VHS cassettes--your library of cassettes
20
+ is your library of previously recorded responses that can be replayed. When you create a cassette, it does
21
+ the following:
22
+
23
+ * It loads the previously recorded responses from the cache file corresponding to the cassette name.
24
+ * It register these responses with fakeweb (depending on the cassette's :record option--see below)
25
+ * It sets the <tt>FakeWeb.allow_net_connect</tt> setting based on the cassette's :record option.
26
+
27
+ While a cassette is active, any HTTP requests to a URL of a previously recorded responses will use get
28
+ the recorded response. New HTTP requests (i.e. HTTP requests that have not been previously recorded)
29
+ will be recorded to the same cache file, depending on your :record option. When you destroy a cassette,
30
+ it does the following:
31
+
32
+ * It saves all of the recorded responses (both old and new) to a cached yml file corresponding to the cassette name.
33
+ * It removes the registrations it made with fakeweb, to prevent "leakage" into other tests.
34
+ * It reverts the <tt>FakeWeb.allow_net_connect</tt> back to whatever it was before the cassette was created.
35
+
36
+ == Record modes
37
+
38
+ VCR supports 3 record modes, which configures when it records new responses. You can set a default
39
+ record mode in your configuration (see below) and a per-cassette record mode when creating a cassette. The record
40
+ modes are:
41
+
42
+ * :all - This will cause VCR to re-record all HTTP requests that occur while the cassette is the current one.
43
+ When the cassette is created, it will not register any of the cached responses with fakeweb.
44
+ <tt>FakeWeb.allow_net_connect</tt> will be set to true, so it can record the requests.
45
+ * :none - This will prevent VCR from recording, or even allowing, any new HTTP requests while the cassette is the current one.
46
+ The previously recorded responses will be registered with fakeweb. <tt>FakeWeb.allow_net_connect</tt> will be set to
47
+ false, so that no new HTTP connections are allowed.
48
+ * :unregistered - This will use the previously recorded responses, and record any new requests that are not registered with
49
+ fakeweb. The previously recorded responses will be registered with fakeweb. <tt>FakeWeb.allow_net_connect</tt> will be
50
+ set to true, so that VCR will record any new HTTP requests within the cassette.
51
+
52
+ Note that :none and :unregistered will usually at the same. The difference is when your code changes and
53
+ it makes a new HTTP request that wasn't made when the cassette was first recorded. With :none, you would
54
+ get an error from FakeWeb (since allow_net_connect is set to false). With :unregistered, the new response
55
+ would get saved in the cassette's yaml file, and automatically get used in the future.
56
+
57
+ == Configuration
58
+
59
+ # Set the default allow_net_connect option--usually you'll want this off.
60
+ # You don't usually want your test suite to make HTTP connections, do you?
61
+ FakeWeb.allow_net_connect = false
62
+
63
+ VCR.config do |c|
64
+ # the cache_dir is where the cassette yml files will be saved.
65
+ c.cache_dir = File.join(Rails.root, 'features', 'fixtures', 'vcr_cassettes')
66
+
67
+ # this record mode will be used for any cassette you create without specifying a record mode.
68
+ c.default_cassette_record_mode = :none
69
+ end
70
+
71
+ This can go pretty much wherever, as long as this code is run before your tests, specs or scenarios.
72
+
73
+ == Usage with your favorite test/spec framework
74
+
75
+ VCR can easily be used with any ruby test/spec framework. Usually, you'll want to use <tt>VCR.with_cassette</tt>:
76
+
77
+ VCR.with_cassette('geocoding/Seattle, WA', :record => :unregistered) do
78
+ # do something that causes an HTTP request.
79
+ end
80
+
81
+ Alternately, you can create and destroy the cassette with individual method calls from setup/before and teardown/after:
82
+
83
+ describe "Something that makes an HTTP request" do
84
+ before(:each) do
85
+ VCR.create_cassette!('geocoding/Seattle, WA', :record => :unregistered)
86
+ end
87
+
88
+ it "should do something that makes an HTTP request"
89
+
90
+ after(:each) do
91
+ VCR.destroy_cassette!
92
+ end
93
+ end
94
+
95
+ In both of these cases, VCR would use the file geocoding/Seattle_WA.yml within the configured
96
+ cache dir. The :record setting is optional--if you leave it blank, your configured default will be used.
97
+
98
+ == Usage with Cucumber
99
+
100
+ VCR provides special support for cucumber. You can of course use <tt>VCR.with_cassette</tt> within a step definition,
101
+ and that's the recommended way for any of your step definitions. But many times I find myself using generic step definitions
102
+ provided by another library (such as the webrat/capybara web steps generated by cucumber-rails), and I don't want to modify
103
+ these. VCR provides cucumber tagging support to help in these cases:
104
+
105
+ # in a cucumber feature file...
106
+ @facebook_http_request
107
+ Scenario: Sign up with facebook connect
108
+
109
+ # in features/support/vcr.rb (or some similar support file)
110
+ VCR.cucumber_tags do |t|
111
+ t.tags '@facebook_http_request', '@twitter_status_update', :record => :none
112
+ t.tags '@another_scenario_tag' # the default record mode will be used for this tag.
113
+ end
114
+
115
+ # Note: you'd probably also want to put your VCR config in this file (see above).
116
+
117
+ For each of the tags you specify in your cucumber_tags block, VCR will set up the appropriate
118
+ {Before and After hooks}[http://wiki.github.com/aslakhellesoy/cucumber/hooks] to use a cassette
119
+ for the entire scenario. The tag (minus the '@') will be used as the cassette name, and it'll
120
+ go in the cucumber_tags subdirectory of the configured cache dir.
121
+
122
+ == Ruby Version Compatibility
123
+
124
+ specs.should pass if RUBY_VERSION =~ /^1.(8.6|8.7|9.1)$/
125
+
126
+ == Notes, etc.
127
+
128
+ * The cassette name determines the name of the cache file for the given cassette. Strings or symbols are fine,
129
+ and you can include any characters, but spaces and invalid file name characters will be removed
130
+ before the cassette reads or writes to the file.
131
+ * You can use a directory separator (i.e. '/') in your cassette names to cause it to use a subdirectory
132
+ of the cache_dir. The cucumber tagging support uses this.
133
+ * VCR maintains a simple stack of cassette. This allows you to nest them as deeply as you want.
134
+ This is particularly useful when you have a cucumber step definition that uses a cassette, and
135
+ you also want to use a cassette for the entire scenario using the tagging support.
136
+
137
+ == Note on Patches/Pull Requests
138
+
139
+ * Fork the project.
140
+ * Make your feature addition or bug fix.
141
+ * Add tests for it. This is important so I don't break it in a
142
+ future version unintentionally.
143
+ * Commit, do not mess with rakefile, version, or history.
144
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
145
+ * Send me a pull request. Bonus points for topic branches.
146
+
147
+ == Thanks
148
+
149
+ * {Aslak Hellesøy}[http://github.com/aslakhellesoy] for {Cucumber}[http://github.com/aslakhellesoy/cucumber].
150
+ * {Chris Kampmeier}[http://github.com/chrisk] for {FakeWeb}[http://github.com/chrisk/fakeweb].
151
+ * {Chris Young}[http://github.com/chrisyoung] for {NetRecorder}[http://github.com/chrisyoung/netrecorder], the inspiration
152
+ for VCR.
153
+
154
+ == Copyright
155
+
156
+ Copyright (c) 2010 Myron Marston. See LICENSE for details.
@@ -0,0 +1,60 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "vcr"
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.}
10
+ gem.email = "myron.marston@gmail.com"
11
+ gem.homepage = "http://github.com/myronmarston/vcr"
12
+ gem.authors = ["Myron Marston"]
13
+
14
+ gem.add_dependency 'fakeweb', '>= 1.2.8'
15
+
16
+ gem.add_development_dependency "rspec", ">= 1.2.9"
17
+ gem.add_development_dependency "cucumber", ">= 0.6.1"
18
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
19
+ end
20
+ Jeweler::GemcutterTasks.new
21
+ rescue LoadError
22
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
23
+ end
24
+
25
+ require 'spec/rake/spectask'
26
+ Spec::Rake::SpecTask.new(:spec) do |spec|
27
+ spec.libs << 'lib' << 'spec'
28
+ spec.spec_files = FileList['spec/**/*_spec.rb']
29
+ end
30
+
31
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
32
+ spec.libs << 'lib' << 'spec'
33
+ spec.pattern = 'spec/**/*_spec.rb'
34
+ spec.rcov = true
35
+ end
36
+
37
+ task :spec => :check_dependencies if defined?(Jeweler)
38
+
39
+ begin
40
+ require 'cucumber/rake/task'
41
+ Cucumber::Rake::Task.new(:features)
42
+
43
+ task :features => :check_dependencies
44
+ rescue LoadError
45
+ task :features do
46
+ abort "Cucumber is not available. In order to run features, you must: sudo gem install cucumber"
47
+ end
48
+ end
49
+
50
+ task :default => [:spec, :features]
51
+
52
+ require 'rake/rdoctask'
53
+ Rake::RDocTask.new do |rdoc|
54
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
55
+
56
+ rdoc.rdoc_dir = 'rdoc'
57
+ rdoc.title = "vcr #{version}"
58
+ rdoc.rdoc_files.include('README*')
59
+ rdoc.rdoc_files.include('lib/**/*.rb')
60
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,43 @@
1
+ ---
2
+ - !ruby/struct:VCR::RecordedResponse
3
+ method: :get
4
+ uri: http://example.com:80/
5
+ response: !ruby/object:Net::HTTPOK
6
+ body: |
7
+ <HTML>
8
+ <HEAD>
9
+ <TITLE>Example Web Page</TITLE>
10
+ </HEAD>
11
+ <body>
12
+ <p>
13
+ This is not the real response from example.com
14
+ </p>
15
+ </BODY>
16
+ </HTML>
17
+
18
+
19
+ body_exist: true
20
+ code: "200"
21
+ header:
22
+ etag:
23
+ - "\"24ec5-1b6-4059a80bfd280\""
24
+ last-modified:
25
+ - Tue, 15 Nov 2005 13:24:10 GMT
26
+ connection:
27
+ - Keep-Alive
28
+ content-type:
29
+ - text/html; charset=UTF-8
30
+ date:
31
+ - Thu, 25 Feb 2010 15:22:32 GMT
32
+ server:
33
+ - Apache/2.2.3 (CentOS)
34
+ content-length:
35
+ - "438"
36
+ age:
37
+ - "2643"
38
+ accept-ranges:
39
+ - bytes
40
+ http_version: "1.1"
41
+ message: OK
42
+ read: true
43
+ socket:
@@ -0,0 +1,45 @@
1
+ ---
2
+ - !ruby/struct:VCR::RecordedResponse
3
+ method: :get
4
+ uri: http://example.com:80/before_nested
5
+ response: !ruby/object:Net::HTTPNotFound
6
+ body: The before_nested response
7
+ body_exist: true
8
+ code: "404"
9
+ header:
10
+ content-type:
11
+ - text/html; charset=iso-8859-1
12
+ connection:
13
+ - close
14
+ server:
15
+ - Apache/2.2.3 (CentOS)
16
+ date:
17
+ - Thu, 25 Feb 2010 15:23:39 GMT
18
+ content-length:
19
+ - "287"
20
+ http_version: "1.1"
21
+ message: Not Found
22
+ read: true
23
+ socket:
24
+ - !ruby/struct:VCR::RecordedResponse
25
+ method: :get
26
+ uri: http://example.com:80/after_nested
27
+ response: !ruby/object:Net::HTTPNotFound
28
+ body: The after_nested response
29
+ body_exist: true
30
+ code: "404"
31
+ header:
32
+ content-type:
33
+ - text/html; charset=iso-8859-1
34
+ connection:
35
+ - close
36
+ server:
37
+ - Apache/2.2.3 (CentOS)
38
+ date:
39
+ - Thu, 25 Feb 2010 15:23:39 GMT
40
+ content-length:
41
+ - "286"
42
+ http_version: "1.1"
43
+ message: Not Found
44
+ read: true
45
+ socket:
@@ -0,0 +1,23 @@
1
+ ---
2
+ - !ruby/struct:VCR::RecordedResponse
3
+ method: :get
4
+ uri: http://example.com:80/nested
5
+ response: !ruby/object:Net::HTTPNotFound
6
+ body: The nested response
7
+ body_exist: true
8
+ code: "404"
9
+ header:
10
+ content-type:
11
+ - text/html; charset=iso-8859-1
12
+ connection:
13
+ - close
14
+ server:
15
+ - Apache/2.2.3 (CentOS)
16
+ date:
17
+ - Thu, 25 Feb 2010 15:19:40 GMT
18
+ content-length:
19
+ - "280"
20
+ http_version: "1.1"
21
+ message: Not Found
22
+ read: true
23
+ socket:
@@ -0,0 +1,43 @@
1
+ ---
2
+ - !ruby/struct:VCR::RecordedResponse
3
+ method: :get
4
+ uri: http://example.com:80/
5
+ response: !ruby/object:Net::HTTPOK
6
+ body: |
7
+ <HTML>
8
+ <HEAD>
9
+ <TITLE>Example Web Page</TITLE>
10
+ </HEAD>
11
+ <body>
12
+ <p>
13
+ This is not the real response from example.com
14
+ </p>
15
+ </BODY>
16
+ </HTML>
17
+
18
+
19
+ body_exist: true
20
+ code: "200"
21
+ header:
22
+ etag:
23
+ - "\"24ec5-1b6-4059a80bfd280\""
24
+ last-modified:
25
+ - Tue, 15 Nov 2005 13:24:10 GMT
26
+ connection:
27
+ - Keep-Alive
28
+ content-type:
29
+ - text/html; charset=UTF-8
30
+ date:
31
+ - Thu, 25 Feb 2010 15:20:47 GMT
32
+ server:
33
+ - Apache/2.2.3 (CentOS)
34
+ content-length:
35
+ - "438"
36
+ age:
37
+ - "2546"
38
+ accept-ranges:
39
+ - bytes
40
+ http_version: "1.1"
41
+ message: OK
42
+ read: true
43
+ socket:
@@ -0,0 +1,43 @@
1
+ ---
2
+ - !ruby/struct:VCR::RecordedResponse
3
+ method: :get
4
+ uri: http://example.com:80/
5
+ response: !ruby/object:Net::HTTPOK
6
+ body: |
7
+ <HTML>
8
+ <HEAD>
9
+ <TITLE>Example Web Page</TITLE>
10
+ </HEAD>
11
+ <body>
12
+ <p>
13
+ This is not the real response from example.com
14
+ </p>
15
+ </BODY>
16
+ </HTML>
17
+
18
+
19
+ body_exist: true
20
+ code: "200"
21
+ header:
22
+ etag:
23
+ - "\"24ec5-1b6-4059a80bfd280\""
24
+ last-modified:
25
+ - Tue, 15 Nov 2005 13:24:10 GMT
26
+ connection:
27
+ - Keep-Alive
28
+ content-type:
29
+ - text/html; charset=UTF-8
30
+ date:
31
+ - Thu, 25 Feb 2010 15:22:32 GMT
32
+ server:
33
+ - Apache/2.2.3 (CentOS)
34
+ content-length:
35
+ - "438"
36
+ age:
37
+ - "2643"
38
+ accept-ranges:
39
+ - bytes
40
+ http_version: "1.1"
41
+ message: OK
42
+ read: true
43
+ socket: