Commit bc7be0ecc5d4f00ab471ba22776b67080daedb59
1 parent
bf22f099
Exists in
master
and in
1 other branch
adding timecop and fakeweb to testing gems
Showing
49 changed files
with
3562 additions
and
1 deletions
Show diff stats
README.markdown
... | ... | @@ -20,7 +20,7 @@ This will create a Rails 2.3.2 app with Heroku-recommended code: |
20 | 20 | * jQuery for Javascript and Ajax |
21 | 21 | * Clearance for authentication |
22 | 22 | * Active Merchant for payment processing |
23 | -* Cucumber, Shoulda, Factory Girl, & Mocha for testing | |
23 | +* Cucumber, Shoulda, Factory Girl, Mocha, Fakeweb, & Timecop for testing | |
24 | 24 | * Inherited Resources for RESTful controllers |
25 | 25 | * Formtastic for form builders |
26 | 26 | * Flutie for CSS framework | ... | ... |
config/environments/test.rb
... | ... | @@ -35,12 +35,19 @@ config.gem 'thoughtbot-shoulda', |
35 | 35 | :lib => 'shoulda', |
36 | 36 | :source => 'http://gems.github.com', |
37 | 37 | :version => '>= 2.10.1' |
38 | +config.gem 'jtrupiano-timecop', | |
39 | + :lib => 'timecop', | |
40 | + :source => 'http://gems.github.com', | |
41 | + :version => '0.2.1' | |
42 | +config.gem 'fakeweb', | |
43 | + :version => '>= 1.2.5' | |
38 | 44 | |
39 | 45 | HOST = 'localhost' |
40 | 46 | |
41 | 47 | begin |
42 | 48 | require 'factory_girl' |
43 | 49 | require 'redgreen' |
50 | + require 'fakeweb' | |
44 | 51 | rescue LoadError |
45 | 52 | end |
46 | 53 | ... | ... |
doc/README_FOR_TEMPLATE
... | ... | @@ -0,0 +1,122 @@ |
1 | +--- !ruby/object:Gem::Specification | |
2 | +name: fakeweb | |
3 | +version: !ruby/object:Gem::Version | |
4 | + version: 1.2.5 | |
5 | +platform: ruby | |
6 | +authors: | |
7 | +- Chris Kampmeier | |
8 | +- Blaine Cook | |
9 | +autorequire: | |
10 | +bindir: bin | |
11 | +cert_chain: [] | |
12 | + | |
13 | +date: 2009-07-08 00:00:00 -04:00 | |
14 | +default_executable: | |
15 | +dependencies: | |
16 | +- !ruby/object:Gem::Dependency | |
17 | + name: mocha | |
18 | + type: :development | |
19 | + version_requirement: | |
20 | + version_requirements: !ruby/object:Gem::Requirement | |
21 | + requirements: | |
22 | + - - ">=" | |
23 | + - !ruby/object:Gem::Version | |
24 | + version: 0.9.5 | |
25 | + version: | |
26 | +description: FakeWeb is a helper for faking web requests in Ruby. It works at a global level, without modifying code or writing extensive stubs. | |
27 | +email: | |
28 | +- chris@kampers.net | |
29 | +- romeda@gmail.com | |
30 | +executables: [] | |
31 | + | |
32 | +extensions: [] | |
33 | + | |
34 | +extra_rdoc_files: | |
35 | +- CHANGELOG | |
36 | +- LICENSE.txt | |
37 | +- README.rdoc | |
38 | +files: | |
39 | +- CHANGELOG | |
40 | +- LICENSE.txt | |
41 | +- README.rdoc | |
42 | +- Rakefile | |
43 | +- lib/fake_web.rb | |
44 | +- lib/fake_web/ext/net_http.rb | |
45 | +- lib/fake_web/registry.rb | |
46 | +- lib/fake_web/responder.rb | |
47 | +- lib/fake_web/response.rb | |
48 | +- lib/fake_web/stub_socket.rb | |
49 | +- lib/fake_web/utility.rb | |
50 | +- lib/fakeweb.rb | |
51 | +- test/fixtures/google_response_from_curl | |
52 | +- test/fixtures/google_response_with_transfer_encoding | |
53 | +- test/fixtures/google_response_without_transfer_encoding | |
54 | +- test/fixtures/test_example.txt | |
55 | +- test/fixtures/test_txt_file | |
56 | +- test/test_allow_net_connect.rb | |
57 | +- test/test_deprecations.rb | |
58 | +- test/test_fake_authentication.rb | |
59 | +- test/test_fake_web.rb | |
60 | +- test/test_fake_web_open_uri.rb | |
61 | +- test/test_helper.rb | |
62 | +- test/test_missing_open_uri.rb | |
63 | +- test/test_precedence.rb | |
64 | +- test/test_query_string.rb | |
65 | +- test/test_regexes.rb | |
66 | +- test/test_response_headers.rb | |
67 | +- test/test_trailing_slashes.rb | |
68 | +- test/test_utility.rb | |
69 | +has_rdoc: true | |
70 | +homepage: http://github.com/chrisk/fakeweb | |
71 | +licenses: [] | |
72 | + | |
73 | +post_install_message: | |
74 | +rdoc_options: | |
75 | +- --main | |
76 | +- README.rdoc | |
77 | +- --title | |
78 | +- FakeWeb API Documentation | |
79 | +- --charset | |
80 | +- utf-8 | |
81 | +- --line-numbers | |
82 | +- --inline-source | |
83 | +require_paths: | |
84 | +- lib | |
85 | +required_ruby_version: !ruby/object:Gem::Requirement | |
86 | + requirements: | |
87 | + - - ">=" | |
88 | + - !ruby/object:Gem::Version | |
89 | + version: "0" | |
90 | + version: | |
91 | +required_rubygems_version: !ruby/object:Gem::Requirement | |
92 | + requirements: | |
93 | + - - ">=" | |
94 | + - !ruby/object:Gem::Version | |
95 | + version: "0" | |
96 | + version: | |
97 | +requirements: [] | |
98 | + | |
99 | +rubyforge_project: fakeweb | |
100 | +rubygems_version: 1.3.4 | |
101 | +signing_key: | |
102 | +specification_version: 3 | |
103 | +summary: A tool for faking responses to HTTP requests | |
104 | +test_files: | |
105 | +- test/fixtures/google_response_from_curl | |
106 | +- test/fixtures/google_response_with_transfer_encoding | |
107 | +- test/fixtures/google_response_without_transfer_encoding | |
108 | +- test/fixtures/test_example.txt | |
109 | +- test/fixtures/test_txt_file | |
110 | +- test/test_allow_net_connect.rb | |
111 | +- test/test_deprecations.rb | |
112 | +- test/test_fake_authentication.rb | |
113 | +- test/test_fake_web.rb | |
114 | +- test/test_fake_web_open_uri.rb | |
115 | +- test/test_helper.rb | |
116 | +- test/test_missing_open_uri.rb | |
117 | +- test/test_precedence.rb | |
118 | +- test/test_query_string.rb | |
119 | +- test/test_regexes.rb | |
120 | +- test/test_response_headers.rb | |
121 | +- test/test_trailing_slashes.rb | |
122 | +- test/test_utility.rb | ... | ... |
... | ... | @@ -0,0 +1,163 @@ |
1 | +fakeweb (1.2.5) | |
2 | + | |
3 | +* fix handling of userinfo strings that contain percent-encoded unsafe | |
4 | + characters [Chris Kampmeier, Ken Mayer] | |
5 | + | |
6 | +* fix that exact matches against strings/URIs with the :any method had a lower | |
7 | + precedence than regex matches using a real HTTP method (exact matches now | |
8 | + always take precedence) [Chris Kampmeier] | |
9 | + | |
10 | +* change request handling to raise an exception when more than one registered | |
11 | + regex matches a request URI [Chris Kampmeier] | |
12 | + | |
13 | + | |
14 | +fakeweb (1.2.4) | |
15 | + | |
16 | +* add experimental support for matching URIs via regular expressions | |
17 | + [Jacqui Maher, Tiago Albineli Motta, Peter Wagene] | |
18 | + | |
19 | +* fix an exception when registering with the :response option and a string that | |
20 | + is the same as the name of a directory in the current path [Chris Kampmeier] | |
21 | + | |
22 | +* DEPRECATION: Calling FakeWeb.register_uri with a :string or :file option is | |
23 | + now deprecated. Both options have been replaced with a unified :body option, | |
24 | + since they supply the response body (as opposed to :response, which supplies | |
25 | + the full response including headers) [Chris Kampmeier] | |
26 | + | |
27 | +* add support for specifying HTTP headers as options to FakeWeb.register_uri | |
28 | + when using the :string or :file response types, since those methods only | |
29 | + specify a response body [David Michael, Chris Kampmeier] | |
30 | + | |
31 | +* DEPRECATION: Calling FakeWeb.register_uri and FakeWeb.registered_uri? without | |
32 | + an HTTP method as the first argument is now deprecated. To match against any | |
33 | + HTTP method (the pre-1.2.0 behavior), use :any [Chris Kampmeier] | |
34 | + | |
35 | + | |
36 | +fakeweb (1.2.3) | |
37 | + | |
38 | +* fix the #http_version of :file and :string responses, which was returning the | |
39 | + request URI instead of something sensible like "1.0" [Chris Kampmeier] | |
40 | + | |
41 | +* add method aliases in the Net::HTTP patch to eliminate warnings when running | |
42 | + with -w [Joshua Clingenpeel] | |
43 | + | |
44 | +* fix that removing the redefinition of OpenURI::HTTPError in 1.2.0 caused | |
45 | + :exception responses to raise when OpenURI isn't available [Chris Kampmeier] | |
46 | + | |
47 | +* fix registering an :exception response with classes that require arguments for | |
48 | + instantiation, like Interrupt's subclasses [Chris Kampmeier] | |
49 | + | |
50 | + | |
51 | +fakeweb (1.2.2) | |
52 | + | |
53 | +* fix that HTTP Digest and OAuth requests could raise URI::InvalidURIErrors | |
54 | + [Bill Kocik, Chris Kampmeier] | |
55 | + | |
56 | + | |
57 | +fakeweb (1.2.1) | |
58 | + | |
59 | +* fix that query parameters are handled correctly when registering with a URI | |
60 | + object [Anselmo Alves, Chris Kampmeier] | |
61 | + | |
62 | +* fix an exception when registering with the :response option and a string | |
63 | + containing "\0" [Jonathan Baudanza, Chris Kampmeier] | |
64 | + | |
65 | +* fix that trailing slashes were considered significant for requests to the root | |
66 | + of a domain [Chris Kampmeier] | |
67 | + | |
68 | +* add support for HTTP basic authentication via userinfo strings in URIs | |
69 | + [Michael Bleigh] | |
70 | + | |
71 | + | |
72 | +fakeweb (1.2.0) | |
73 | + | |
74 | +* add lib/fakeweb.rb so you can require "fakeweb" as well [Chris Kampmeier] | |
75 | + | |
76 | +* fix compatibility with Ruby 1.9.1 [Chris Kampmeier] | |
77 | + | |
78 | +* fix that newlines in file-based responses could be doubled in the response | |
79 | + object's body [Mark Menard, Chris Kampmeier] | |
80 | + | |
81 | +* fix unnecessary munging of the transfer-encoding header, which improves | |
82 | + compatibility with mechanize [Mark Menard] | |
83 | + | |
84 | +* fix a test and the RCov dependency to be compatible with JRuby [Mark Menard] | |
85 | + | |
86 | +* remove an unnecessary redefinition of OpenURI::HTTPError [Josh Nichols] | |
87 | + | |
88 | +* rearrange implementation code into separate files, one per class [Josh Nichols] | |
89 | + | |
90 | +* fix a bug where FakeWeb.response_for would raise if the request wasn't | |
91 | + registered [Chris Kampmeier] | |
92 | + | |
93 | +* add HTTP method support, so FakeWeb takes both the URI and method into | |
94 | + account for registration, requests, and responses. Backwards-compatible with | |
95 | + the old method signatures, which didn't have a method param. [Chris Kampmeier] | |
96 | + | |
97 | +* start work on Ruby 1.9 compatibility [Chris Kampmeier] | |
98 | + | |
99 | +* add FakeWeb.allow_net_connect= to enable/disable the pass-through to | |
100 | + Net::HTTP for unregistered URIs [Mislav Marohnić, Chris Kampmeier] | |
101 | + | |
102 | +* remove setup.rb, since most people use RubyGems [Mislav Marohnić] | |
103 | + | |
104 | +* fix that 'http://example.com/?' (empty query) matches a registered | |
105 | + 'http://example.com/', and vice-versa [Mislav Marohnić] | |
106 | + | |
107 | +* improve the test suite to not rely on an internet connection [Chris Kampmeier] | |
108 | + | |
109 | +* use `rake test` instead of `rake tests` [Josh Nichols] | |
110 | + | |
111 | +* fix an incompatibility with Ruby 1.8.6 p36 where you'd get "Errno::EINTR: | |
112 | + Interrupted system call" exceptions in Socket#sysread for any non-faked | |
113 | + request [Chris Kampmeier] | |
114 | + | |
115 | +* response rotation: you can now optionally call FakeWeb.register_uri with an | |
116 | + array of options hashes; these are used, in order, to respond to | |
117 | + repeated requests (to repeat a response more than once before rotating, use | |
118 | + the :times option). Once you run out of responses, further requests always | |
119 | + receive the last response. [Michael Shapiro] | |
120 | + | |
121 | +* add support for Net::HTTP's undocumented full-URI request style (fixes | |
122 | + URI::InvalidURIErrors that you might see in older libraries) [Chris Kampmeier] | |
123 | + | |
124 | +* sort query params before storing internally, so that | |
125 | + http://example.com/?a=1&b=2 and http://example.com/?b=2&a=1 are considered the | |
126 | + same URL (although this is technically incorrect, it's much more | |
127 | + convenient--most web apps work that way, and Net::HTTP's use of a hash to pass | |
128 | + query params means that the order in which FakeWeb stores them can be | |
129 | + unpredictable) [Chris Kampmeier] | |
130 | + | |
131 | +* add support for ports in URLs, so that http://example.com/ and | |
132 | + http://example.com:3000/ are not the same [Chris Kampmeier] | |
133 | + | |
134 | +* fix for non-faked SSL requests failing with "Unable to create local socket" | |
135 | + [Chris Kampmeier] | |
136 | + | |
137 | +* update Rakefile to fix warning about deprecated code [Chris Kampmeier] | |
138 | + | |
139 | + | |
140 | +fakeweb (1.1.2) | |
141 | + | |
142 | +* add required dependencies to GemSpec to ensure that tests pass in firebrigade | |
143 | + (http://firebrigade.seattlerb.org/) [Blaine Cook] | |
144 | + | |
145 | + | |
146 | +fakeweb (1.1.1) | |
147 | + | |
148 | +* fix for non-existence of :string method on File as presented by open-uri | |
149 | + [Blaine Cook] | |
150 | + | |
151 | +* fix for curl example test - google redirects to ccTLDs for those outside US | |
152 | + [Blaine Cook] | |
153 | + | |
154 | + | |
155 | +fakeweb (1.1.0) | |
156 | + | |
157 | +* update code to correspond to ruby 1.8.4 (breaks compatibility with ruby 1.8.2) | |
158 | + [Blaine Cook] | |
159 | + | |
160 | + | |
161 | +fakeweb (1.0.0) | |
162 | + | |
163 | + * initial import [Blaine Cook] | ... | ... |
... | ... | @@ -0,0 +1,281 @@ |
1 | + GNU GENERAL PUBLIC LICENSE | |
2 | + Version 2, June 1991 | |
3 | + | |
4 | + Copyright (C) 1989, 1991 Free Software Foundation, Inc. | |
5 | + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
6 | + Everyone is permitted to copy and distribute verbatim copies | |
7 | + of this license document, but changing it is not allowed. | |
8 | + | |
9 | + Preamble | |
10 | + | |
11 | + The licenses for most software are designed to take away your | |
12 | +freedom to share and change it. By contrast, the GNU General Public | |
13 | +License is intended to guarantee your freedom to share and change free | |
14 | +software--to make sure the software is free for all its users. This | |
15 | +General Public License applies to most of the Free Software | |
16 | +Foundation's software and to any other program whose authors commit to | |
17 | +using it. (Some other Free Software Foundation software is covered by | |
18 | +the GNU Lesser General Public License instead.) You can apply it to | |
19 | +your programs, too. | |
20 | + | |
21 | + When we speak of free software, we are referring to freedom, not | |
22 | +price. Our General Public Licenses are designed to make sure that you | |
23 | +have the freedom to distribute copies of free software (and charge for | |
24 | +this service if you wish), that you receive source code or can get it | |
25 | +if you want it, that you can change the software or use pieces of it | |
26 | +in new free programs; and that you know you can do these things. | |
27 | + | |
28 | + To protect your rights, we need to make restrictions that forbid | |
29 | +anyone to deny you these rights or to ask you to surrender the rights. | |
30 | +These restrictions translate to certain responsibilities for you if you | |
31 | +distribute copies of the software, or if you modify it. | |
32 | + | |
33 | + For example, if you distribute copies of such a program, whether | |
34 | +gratis or for a fee, you must give the recipients all the rights that | |
35 | +you have. You must make sure that they, too, receive or can get the | |
36 | +source code. And you must show them these terms so they know their | |
37 | +rights. | |
38 | + | |
39 | + We protect your rights with two steps: (1) copyright the software, and | |
40 | +(2) offer you this license which gives you legal permission to copy, | |
41 | +distribute and/or modify the software. | |
42 | + | |
43 | + Also, for each author's protection and ours, we want to make certain | |
44 | +that everyone understands that there is no warranty for this free | |
45 | +software. If the software is modified by someone else and passed on, we | |
46 | +want its recipients to know that what they have is not the original, so | |
47 | +that any problems introduced by others will not reflect on the original | |
48 | +authors' reputations. | |
49 | + | |
50 | + Finally, any free program is threatened constantly by software | |
51 | +patents. We wish to avoid the danger that redistributors of a free | |
52 | +program will individually obtain patent licenses, in effect making the | |
53 | +program proprietary. To prevent this, we have made it clear that any | |
54 | +patent must be licensed for everyone's free use or not licensed at all. | |
55 | + | |
56 | + The precise terms and conditions for copying, distribution and | |
57 | +modification follow. | |
58 | + | |
59 | + GNU GENERAL PUBLIC LICENSE | |
60 | + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | |
61 | + | |
62 | + 0. This License applies to any program or other work which contains | |
63 | +a notice placed by the copyright holder saying it may be distributed | |
64 | +under the terms of this General Public License. The "Program", below, | |
65 | +refers to any such program or work, and a "work based on the Program" | |
66 | +means either the Program or any derivative work under copyright law: | |
67 | +that is to say, a work containing the Program or a portion of it, | |
68 | +either verbatim or with modifications and/or translated into another | |
69 | +language. (Hereinafter, translation is included without limitation in | |
70 | +the term "modification".) Each licensee is addressed as "you". | |
71 | + | |
72 | +Activities other than copying, distribution and modification are not | |
73 | +covered by this License; they are outside its scope. The act of | |
74 | +running the Program is not restricted, and the output from the Program | |
75 | +is covered only if its contents constitute a work based on the | |
76 | +Program (independent of having been made by running the Program). | |
77 | +Whether that is true depends on what the Program does. | |
78 | + | |
79 | + 1. You may copy and distribute verbatim copies of the Program's | |
80 | +source code as you receive it, in any medium, provided that you | |
81 | +conspicuously and appropriately publish on each copy an appropriate | |
82 | +copyright notice and disclaimer of warranty; keep intact all the | |
83 | +notices that refer to this License and to the absence of any warranty; | |
84 | +and give any other recipients of the Program a copy of this License | |
85 | +along with the Program. | |
86 | + | |
87 | +You may charge a fee for the physical act of transferring a copy, and | |
88 | +you may at your option offer warranty protection in exchange for a fee. | |
89 | + | |
90 | + 2. You may modify your copy or copies of the Program or any portion | |
91 | +of it, thus forming a work based on the Program, and copy and | |
92 | +distribute such modifications or work under the terms of Section 1 | |
93 | +above, provided that you also meet all of these conditions: | |
94 | + | |
95 | + a) You must cause the modified files to carry prominent notices | |
96 | + stating that you changed the files and the date of any change. | |
97 | + | |
98 | + b) You must cause any work that you distribute or publish, that in | |
99 | + whole or in part contains or is derived from the Program or any | |
100 | + part thereof, to be licensed as a whole at no charge to all third | |
101 | + parties under the terms of this License. | |
102 | + | |
103 | + c) If the modified program normally reads commands interactively | |
104 | + when run, you must cause it, when started running for such | |
105 | + interactive use in the most ordinary way, to print or display an | |
106 | + announcement including an appropriate copyright notice and a | |
107 | + notice that there is no warranty (or else, saying that you provide | |
108 | + a warranty) and that users may redistribute the program under | |
109 | + these conditions, and telling the user how to view a copy of this | |
110 | + License. (Exception: if the Program itself is interactive but | |
111 | + does not normally print such an announcement, your work based on | |
112 | + the Program is not required to print an announcement.) | |
113 | + | |
114 | +These requirements apply to the modified work as a whole. If | |
115 | +identifiable sections of that work are not derived from the Program, | |
116 | +and can be reasonably considered independent and separate works in | |
117 | +themselves, then this License, and its terms, do not apply to those | |
118 | +sections when you distribute them as separate works. But when you | |
119 | +distribute the same sections as part of a whole which is a work based | |
120 | +on the Program, the distribution of the whole must be on the terms of | |
121 | +this License, whose permissions for other licensees extend to the | |
122 | +entire whole, and thus to each and every part regardless of who wrote it. | |
123 | + | |
124 | +Thus, it is not the intent of this section to claim rights or contest | |
125 | +your rights to work written entirely by you; rather, the intent is to | |
126 | +exercise the right to control the distribution of derivative or | |
127 | +collective works based on the Program. | |
128 | + | |
129 | +In addition, mere aggregation of another work not based on the Program | |
130 | +with the Program (or with a work based on the Program) on a volume of | |
131 | +a storage or distribution medium does not bring the other work under | |
132 | +the scope of this License. | |
133 | + | |
134 | + 3. You may copy and distribute the Program (or a work based on it, | |
135 | +under Section 2) in object code or executable form under the terms of | |
136 | +Sections 1 and 2 above provided that you also do one of the following: | |
137 | + | |
138 | + a) Accompany it with the complete corresponding machine-readable | |
139 | + source code, which must be distributed under the terms of Sections | |
140 | + 1 and 2 above on a medium customarily used for software interchange; or, | |
141 | + | |
142 | + b) Accompany it with a written offer, valid for at least three | |
143 | + years, to give any third party, for a charge no more than your | |
144 | + cost of physically performing source distribution, a complete | |
145 | + machine-readable copy of the corresponding source code, to be | |
146 | + distributed under the terms of Sections 1 and 2 above on a medium | |
147 | + customarily used for software interchange; or, | |
148 | + | |
149 | + c) Accompany it with the information you received as to the offer | |
150 | + to distribute corresponding source code. (This alternative is | |
151 | + allowed only for noncommercial distribution and only if you | |
152 | + received the program in object code or executable form with such | |
153 | + an offer, in accord with Subsection b above.) | |
154 | + | |
155 | +The source code for a work means the preferred form of the work for | |
156 | +making modifications to it. For an executable work, complete source | |
157 | +code means all the source code for all modules it contains, plus any | |
158 | +associated interface definition files, plus the scripts used to | |
159 | +control compilation and installation of the executable. However, as a | |
160 | +special exception, the source code distributed need not include | |
161 | +anything that is normally distributed (in either source or binary | |
162 | +form) with the major components (compiler, kernel, and so on) of the | |
163 | +operating system on which the executable runs, unless that component | |
164 | +itself accompanies the executable. | |
165 | + | |
166 | +If distribution of executable or object code is made by offering | |
167 | +access to copy from a designated place, then offering equivalent | |
168 | +access to copy the source code from the same place counts as | |
169 | +distribution of the source code, even though third parties are not | |
170 | +compelled to copy the source along with the object code. | |
171 | + | |
172 | + 4. You may not copy, modify, sublicense, or distribute the Program | |
173 | +except as expressly provided under this License. Any attempt | |
174 | +otherwise to copy, modify, sublicense or distribute the Program is | |
175 | +void, and will automatically terminate your rights under this License. | |
176 | +However, parties who have received copies, or rights, from you under | |
177 | +this License will not have their licenses terminated so long as such | |
178 | +parties remain in full compliance. | |
179 | + | |
180 | + 5. You are not required to accept this License, since you have not | |
181 | +signed it. However, nothing else grants you permission to modify or | |
182 | +distribute the Program or its derivative works. These actions are | |
183 | +prohibited by law if you do not accept this License. Therefore, by | |
184 | +modifying or distributing the Program (or any work based on the | |
185 | +Program), you indicate your acceptance of this License to do so, and | |
186 | +all its terms and conditions for copying, distributing or modifying | |
187 | +the Program or works based on it. | |
188 | + | |
189 | + 6. Each time you redistribute the Program (or any work based on the | |
190 | +Program), the recipient automatically receives a license from the | |
191 | +original licensor to copy, distribute or modify the Program subject to | |
192 | +these terms and conditions. You may not impose any further | |
193 | +restrictions on the recipients' exercise of the rights granted herein. | |
194 | +You are not responsible for enforcing compliance by third parties to | |
195 | +this License. | |
196 | + | |
197 | + 7. If, as a consequence of a court judgment or allegation of patent | |
198 | +infringement or for any other reason (not limited to patent issues), | |
199 | +conditions are imposed on you (whether by court order, agreement or | |
200 | +otherwise) that contradict the conditions of this License, they do not | |
201 | +excuse you from the conditions of this License. If you cannot | |
202 | +distribute so as to satisfy simultaneously your obligations under this | |
203 | +License and any other pertinent obligations, then as a consequence you | |
204 | +may not distribute the Program at all. For example, if a patent | |
205 | +license would not permit royalty-free redistribution of the Program by | |
206 | +all those who receive copies directly or indirectly through you, then | |
207 | +the only way you could satisfy both it and this License would be to | |
208 | +refrain entirely from distribution of the Program. | |
209 | + | |
210 | +If any portion of this section is held invalid or unenforceable under | |
211 | +any particular circumstance, the balance of the section is intended to | |
212 | +apply and the section as a whole is intended to apply in other | |
213 | +circumstances. | |
214 | + | |
215 | +It is not the purpose of this section to induce you to infringe any | |
216 | +patents or other property right claims or to contest validity of any | |
217 | +such claims; this section has the sole purpose of protecting the | |
218 | +integrity of the free software distribution system, which is | |
219 | +implemented by public license practices. Many people have made | |
220 | +generous contributions to the wide range of software distributed | |
221 | +through that system in reliance on consistent application of that | |
222 | +system; it is up to the author/donor to decide if he or she is willing | |
223 | +to distribute software through any other system and a licensee cannot | |
224 | +impose that choice. | |
225 | + | |
226 | +This section is intended to make thoroughly clear what is believed to | |
227 | +be a consequence of the rest of this License. | |
228 | + | |
229 | + 8. If the distribution and/or use of the Program is restricted in | |
230 | +certain countries either by patents or by copyrighted interfaces, the | |
231 | +original copyright holder who places the Program under this License | |
232 | +may add an explicit geographical distribution limitation excluding | |
233 | +those countries, so that distribution is permitted only in or among | |
234 | +countries not thus excluded. In such case, this License incorporates | |
235 | +the limitation as if written in the body of this License. | |
236 | + | |
237 | + 9. The Free Software Foundation may publish revised and/or new versions | |
238 | +of the General Public License from time to time. Such new versions will | |
239 | +be similar in spirit to the present version, but may differ in detail to | |
240 | +address new problems or concerns. | |
241 | + | |
242 | +Each version is given a distinguishing version number. If the Program | |
243 | +specifies a version number of this License which applies to it and "any | |
244 | +later version", you have the option of following the terms and conditions | |
245 | +either of that version or of any later version published by the Free | |
246 | +Software Foundation. If the Program does not specify a version number of | |
247 | +this License, you may choose any version ever published by the Free Software | |
248 | +Foundation. | |
249 | + | |
250 | + 10. If you wish to incorporate parts of the Program into other free | |
251 | +programs whose distribution conditions are different, write to the author | |
252 | +to ask for permission. For software which is copyrighted by the Free | |
253 | +Software Foundation, write to the Free Software Foundation; we sometimes | |
254 | +make exceptions for this. Our decision will be guided by the two goals | |
255 | +of preserving the free status of all derivatives of our free software and | |
256 | +of promoting the sharing and reuse of software generally. | |
257 | + | |
258 | + NO WARRANTY | |
259 | + | |
260 | + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY | |
261 | +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN | |
262 | +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES | |
263 | +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED | |
264 | +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
265 | +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS | |
266 | +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE | |
267 | +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, | |
268 | +REPAIR OR CORRECTION. | |
269 | + | |
270 | + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING | |
271 | +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR | |
272 | +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, | |
273 | +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING | |
274 | +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED | |
275 | +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY | |
276 | +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER | |
277 | +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE | |
278 | +POSSIBILITY OF SUCH DAMAGES. | |
279 | + | |
280 | + END OF TERMS AND CONDITIONS | |
281 | + | ... | ... |
... | ... | @@ -0,0 +1,193 @@ |
1 | += FakeWeb | |
2 | + | |
3 | +FakeWeb is a helper for faking web requests in Ruby. It works at a global | |
4 | +level, without modifying code or writing extensive stubs. | |
5 | + | |
6 | + | |
7 | +== Installation | |
8 | + | |
9 | +The latest release of FakeWeb is once again available from your friendly | |
10 | +RubyForge mirror. Just install the gem: | |
11 | + | |
12 | + sudo gem install fakeweb | |
13 | + | |
14 | +Note: the gem was previously available as +FakeWeb+ (capital letters), but now | |
15 | +all versions are simply registered as +fakeweb+. If you have any old +FakeWeb+ | |
16 | +gems lying around, remove them: <tt>sudo gem uninstall FakeWeb</tt> | |
17 | + | |
18 | + | |
19 | +== Help and discussion | |
20 | + | |
21 | +RDocs for the current release are available at http://fakeweb.rubyforge.org. | |
22 | + | |
23 | +There's a mailing list for questions and discussion at | |
24 | +http://groups.google.com/group/fakeweb-users. | |
25 | + | |
26 | +The main source repository is http://github.com/chrisk/fakeweb. | |
27 | + | |
28 | +== Examples | |
29 | + | |
30 | +Start by requiring FakeWeb: | |
31 | + | |
32 | + require 'rubygems' | |
33 | + require 'fakeweb' | |
34 | + | |
35 | +=== Registering basic string responses | |
36 | + | |
37 | + FakeWeb.register_uri(:get, "http://example.com/test1", :body => "Hello World!") | |
38 | + | |
39 | + Net::HTTP.get(URI.parse("http://example.com/test1")) | |
40 | + => "Hello World!" | |
41 | + | |
42 | + Net::HTTP.get(URI.parse("http://example.com/test2")) | |
43 | + => FakeWeb is bypassed and the response from a real request is returned | |
44 | + | |
45 | +You can also call <tt>register_uri</tt> with a regular expression, to match | |
46 | +more than one URI. | |
47 | + | |
48 | +=== Replaying a recorded response | |
49 | + | |
50 | + page = `curl -is http://www.google.com/` | |
51 | + FakeWeb.register_uri(:get, "http://www.google.com/", :response => page) | |
52 | + | |
53 | + Net::HTTP.get(URI.parse("http://www.google.com/")) | |
54 | + # => Full response, including headers | |
55 | + | |
56 | +=== Adding a custom status to the response | |
57 | + | |
58 | + FakeWeb.register_uri(:get, "http://example.com/", :body => "Nothing to be found 'round here", | |
59 | + :status => ["404", "Not Found"]) | |
60 | + | |
61 | + Net::HTTP.start("example.com") do |req| | |
62 | + response = req.get("/") | |
63 | + response.code # => "404" | |
64 | + response.message # => "Not Found" | |
65 | + response.body # => "Nothing to be found 'round here" | |
66 | + end | |
67 | + | |
68 | +=== Responding to any HTTP method | |
69 | + | |
70 | + FakeWeb.register_uri(:any, "http://example.com", :body => "response for any HTTP method") | |
71 | + | |
72 | +If you use the <tt>:any</tt> symbol, the URI you specify will be completely | |
73 | +stubbed out (regardless of the HTTP method of the request). This can be useful | |
74 | +for RPC-like services, where the HTTP method isn't significant. (Older | |
75 | +versions of FakeWeb always behaved like this, and didn't accept the first | |
76 | ++method+ argument above; this syntax is now deprecated.) | |
77 | + | |
78 | +=== Rotating responses | |
79 | + | |
80 | +You can optionally call FakeWeb.register_uri with an array of options hashes; | |
81 | +these are used, in order, to respond to repeated requests. Once you run out of | |
82 | +responses, further requests always receive the last response. (You can also send | |
83 | +a response more than once before rotating, by specifying a <tt>:times</tt> | |
84 | +option for that response.) | |
85 | + | |
86 | + FakeWeb.register_uri(:delete, "http://example.com/posts/1", | |
87 | + [{:body => "Post 1 deleted.", :status => ["200", "OK"]}, | |
88 | + {:body => "Post not found", :status => ["404", "Not Found"]}]) | |
89 | + | |
90 | + Net::HTTP.start("example.com") do |req| | |
91 | + req.delete("/posts/1").body # => "Post 1 deleted" | |
92 | + req.delete("/posts/1").body # => "Post not found" | |
93 | + req.delete("/posts/1").body # => "Post not found" | |
94 | + end | |
95 | + | |
96 | +=== Using HTTP basic authentication | |
97 | + | |
98 | +You can stub requests that use basic authentication with +userinfo+ strings in | |
99 | +the URIs: | |
100 | + | |
101 | + FakeWeb.register_uri(:get, "http://example.com/secret", :body => "Unauthorized", :status => ["401", "Unauthorized"]) | |
102 | + FakeWeb.register_uri(:get, "http://user:pass@example.com/secret", :body => "Authorized") | |
103 | + | |
104 | + Net::HTTP.start("example.com") do |http| | |
105 | + req = Net::HTTP::Get.new("/secret") | |
106 | + http.request(req) # => "Unauthorized" | |
107 | + req.basic_auth("user", "pass") | |
108 | + http.request(req) # => "Authorized" | |
109 | + end | |
110 | + | |
111 | +=== Clearing registered URIs | |
112 | + | |
113 | +The FakeWeb registry is a singleton that lasts for the duration of your | |
114 | +program, maintaining every fake response you register. If needed, you | |
115 | +can clean out the registry and remove all registered URIs: | |
116 | + | |
117 | + FakeWeb.clean_registry | |
118 | + | |
119 | +=== Blocking all real requests | |
120 | + | |
121 | +When you're using FakeWeb to replace _all_ of your requests, it's useful to | |
122 | +catch when requests are made for unregistered URIs (unlike the default | |
123 | +behavior, which is to pass those requests through to Net::HTTP as usual). | |
124 | + | |
125 | + FakeWeb.allow_net_connect = false | |
126 | + Net::HTTP.get(URI.parse("http://example.com/")) | |
127 | + => raises FakeWeb::NetConnectNotAllowedError | |
128 | + | |
129 | + FakeWeb.allow_net_connect = true | |
130 | + Net::HTTP.get(URI.parse("http://example.com/")) | |
131 | + => FakeWeb is bypassed and the response from a real request is returned | |
132 | + | |
133 | +This is handy when you want to make sure your tests are self-contained, or you | |
134 | +want to catch the scenario when a URI is changed in implementation code | |
135 | +without a corresponding test change. | |
136 | + | |
137 | +=== Specifying HTTP response headers | |
138 | + | |
139 | +When you register a response using the <tt>:body</tt> option, you're only | |
140 | +setting the body of the response. If you want to add headers to these responses, | |
141 | +simply add the header as an option to +register_uri+: | |
142 | + | |
143 | + FakeWeb.register_uri(:get, "http://example.com/hello.txt", :body => "Hello", :content_type => "text/plain") | |
144 | + | |
145 | +This sets the "Content-Type" header in the response. | |
146 | + | |
147 | +== More info | |
148 | + | |
149 | +FakeWeb lets you decouple your test environment from live services without | |
150 | +modifying code or writing extensive stubs. | |
151 | + | |
152 | +In addition to the conceptual advantage of having idempotent request | |
153 | +behaviour, FakeWeb makes tests run faster than if they were made to remote (or | |
154 | +even local) web servers. It also makes it possible to run tests without a | |
155 | +network connection or in situations where the server is behind a firewall or | |
156 | +has host-based access controls. | |
157 | + | |
158 | +FakeWeb works with anything based on Net::HTTP--both higher-level wrappers, | |
159 | +like OpenURI, as well as a ton of libraries for popular web services. | |
160 | + | |
161 | + | |
162 | +== Known Issues | |
163 | + | |
164 | +* Request bodies are ignored, including PUT and POST parameters. If you need | |
165 | + different responses for different request bodies, you need to request | |
166 | + different URLs, and register different responses for each. (Query strings are | |
167 | + fully supported, though.) We're currently considering how the API should | |
168 | + change to add support for request bodies in 1.3.0. Your input would be really | |
169 | + helpful: see http://groups.google.com/group/fakeweb-users/browse_thread/thread/44d190a6b12e4273 | |
170 | + for a discussion of some different options. Thanks! | |
171 | + | |
172 | + | |
173 | +== Copyright | |
174 | + | |
175 | +Copyright 2006-2007 Blaine Cook | |
176 | + | |
177 | +Copyright 2008-2009 various contributors | |
178 | + | |
179 | + FakeWeb is free software; you can redistribute it and/or modify it under the | |
180 | + terms of the GNU General Public License as published by the Free Software | |
181 | + Foundation; either version 2 of the License, or (at your option) any later | |
182 | + version. | |
183 | + | |
184 | + FakeWeb is distributed in the hope that it will be useful, but WITHOUT ANY | |
185 | + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
186 | + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | |
187 | + details. | |
188 | + | |
189 | + You should have received a copy of the GNU General Public License along | |
190 | + with FakeWeb; if not, write to the Free Software Foundation, Inc., 51 | |
191 | + Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
192 | + | |
193 | +See <tt>LICENSE.txt</tt> for the full terms. | ... | ... |
... | ... | @@ -0,0 +1,76 @@ |
1 | +puts "Using ruby #{RUBY_VERSION}p#{RUBY_PATCHLEVEL}" | |
2 | + | |
3 | +require 'rubygems' | |
4 | +require 'rake/gempackagetask' | |
5 | +require 'rake/testtask' | |
6 | +begin | |
7 | + require 'rdoc/task' | |
8 | +rescue LoadError | |
9 | + puts "\nIt looks like you're using an old version of RDoc, but FakeWeb requires a newer one." | |
10 | + puts "You can try upgrading with `sudo gem install rdoc`.\n\n" | |
11 | + raise | |
12 | +end | |
13 | + | |
14 | +task :default => :test | |
15 | + | |
16 | +desc "Run All Tests" | |
17 | +Rake::TestTask.new :test do |test| | |
18 | + test.test_files = ["test/**/*.rb"] | |
19 | + test.verbose = false | |
20 | +end | |
21 | + | |
22 | +desc "Generate Documentation" | |
23 | +RDoc::Task.new do |rdoc| | |
24 | + rdoc.main = "README.rdoc" | |
25 | + rdoc.rdoc_dir = "doc" | |
26 | + rdoc.rdoc_files.include("README.rdoc", "CHANGELOG", "LICENSE.txt", "lib/*.rb") | |
27 | + rdoc.title = "FakeWeb API Documentation" | |
28 | + rdoc.options << '--line-numbers' << '--charset' << 'utf-8' | |
29 | +end | |
30 | + | |
31 | +desc %{Update ".manifest" with the latest list of project filenames. Respect\ | |
32 | +.gitignore by excluding everything that git ignores. Update `files` and\ | |
33 | +`test_files` arrays in "*.gemspec" file if it's present.} | |
34 | +task :manifest do | |
35 | + list = Dir['**/*'].sort | |
36 | + spec_file = Dir['*.gemspec'].first | |
37 | + list -= [spec_file] if spec_file | |
38 | + | |
39 | + File.read('.gitignore').each_line do |glob| | |
40 | + glob = glob.chomp.sub(/^\//, '') | |
41 | + list -= Dir[glob] | |
42 | + list -= Dir["#{glob}/**/*"] if File.directory?(glob) and !File.symlink?(glob) | |
43 | + puts "excluding #{glob}" | |
44 | + end | |
45 | + | |
46 | + if spec_file | |
47 | + spec = File.read spec_file | |
48 | + spec.gsub!(/^(\s* s.(test_)?files \s* = \s* )( \[ [^\]]* \] | %w\( [^)]* \) )/mx) do | |
49 | + assignment = $1 | |
50 | + bunch = $2 ? list.grep(/^test\//) : list | |
51 | + '%s%%w(%s)' % [assignment, bunch.join(' ')] | |
52 | + end | |
53 | + | |
54 | + File.open(spec_file, 'w') {|f| f << spec } | |
55 | + end | |
56 | + File.open('.manifest', 'w') {|f| f << list.join("\n") } | |
57 | +end | |
58 | + | |
59 | +if RUBY_PLATFORM =~ /java/ | |
60 | + puts "rcov support disabled (running under JRuby)." | |
61 | +elsif RUBY_VERSION =~ /^1\.9/ | |
62 | + puts "rcov support disabled (running under Ruby 1.9)" | |
63 | +else | |
64 | + require 'rcov/rcovtask' | |
65 | + Rcov::RcovTask.new do |t| | |
66 | + t.test_files = FileList['test/**/test*.rb'] | |
67 | + t.rcov_opts << "--sort coverage" | |
68 | + t.rcov_opts << "--exclude gems" | |
69 | + end | |
70 | +end | |
71 | + | |
72 | +spec = eval(File.read(File.join(File.dirname(__FILE__), "fakeweb.gemspec"))) | |
73 | +Rake::GemPackageTask.new(spec) do |pkg| | |
74 | + pkg.need_tar_gz = true | |
75 | + pkg.need_zip = true | |
76 | +end | ... | ... |
... | ... | @@ -0,0 +1,172 @@ |
1 | +require 'singleton' | |
2 | + | |
3 | +require 'fake_web/ext/net_http' | |
4 | +require 'fake_web/registry' | |
5 | +require 'fake_web/response' | |
6 | +require 'fake_web/responder' | |
7 | +require 'fake_web/stub_socket' | |
8 | +require 'fake_web/utility' | |
9 | + | |
10 | +module FakeWeb | |
11 | + | |
12 | + # Resets the FakeWeb Registry. This will force all subsequent web requests to | |
13 | + # behave as real requests. | |
14 | + def self.clean_registry | |
15 | + Registry.instance.clean_registry | |
16 | + end | |
17 | + | |
18 | + # Enables or disables real HTTP connections for requests that don't match | |
19 | + # registered URIs. | |
20 | + # | |
21 | + # If you set <tt>FakeWeb.allow_net_connect = false</tt> and subsequently try | |
22 | + # to make a request to a URI you haven't registered with #register_uri, a | |
23 | + # NetConnectNotAllowedError will be raised. This is handy when you want to | |
24 | + # make sure your tests are self-contained, or want to catch the scenario | |
25 | + # when a URI is changed in implementation code without a corresponding test | |
26 | + # change. | |
27 | + # | |
28 | + # When <tt>FakeWeb.allow_net_connect = true</tt> (the default), requests to | |
29 | + # URIs not stubbed with FakeWeb are passed through to Net::HTTP. | |
30 | + def self.allow_net_connect=(allowed) | |
31 | + @allow_net_connect = allowed | |
32 | + end | |
33 | + | |
34 | + # Enable pass-through to Net::HTTP by default. | |
35 | + self.allow_net_connect = true | |
36 | + | |
37 | + # Returns +true+ if requests to URIs not registered with FakeWeb are passed | |
38 | + # through to Net::HTTP for normal processing (the default). Returns +false+ | |
39 | + # if an exception is raised for these requests. | |
40 | + def self.allow_net_connect? | |
41 | + @allow_net_connect | |
42 | + end | |
43 | + | |
44 | + # This exception is raised if you set <tt>FakeWeb.allow_net_connect = | |
45 | + # false</tt> and subsequently try to make a request to a URI you haven't | |
46 | + # stubbed. | |
47 | + class NetConnectNotAllowedError < StandardError; end; | |
48 | + | |
49 | + # This exception is raised if a Net::HTTP request matches more than one of | |
50 | + # the regular expression-based stubs you've registered. To fix the problem, | |
51 | + # disambiguate the regular expressions by making them more specific. | |
52 | + class MultipleMatchingRegexpsError < StandardError; end; | |
53 | + | |
54 | + # call-seq: | |
55 | + # FakeWeb.register_uri(method, uri, options) | |
56 | + # | |
57 | + # Register requests using the HTTP method specified by the symbol +method+ | |
58 | + # for +uri+ to be handled according to +options+. If you specify the method | |
59 | + # <tt>:any</tt>, the response will be reigstered for any request for +uri+. | |
60 | + # +uri+ can be a +String+, +URI+, or +Regexp+ object. +options+ must be either | |
61 | + # a +Hash+ or an +Array+ of +Hashes+ (see below), which must contain one of | |
62 | + # these two keys: | |
63 | + # | |
64 | + # <tt>:body</tt>:: | |
65 | + # A string which is used as the body of the response. If the string refers | |
66 | + # to a valid filesystem path, the contents of that file will be read and used | |
67 | + # as the body of the response instead. (This used to be two options, | |
68 | + # <tt>:string</tt> and <tt>:file</tt>, respectively. These are now deprecated.) | |
69 | + # <tt>:response</tt>:: | |
70 | + # Either an <tt>Net::HTTPResponse</tt>, an +IO+, or a +String+ which is used | |
71 | + # as the full response for the request. | |
72 | + # | |
73 | + # The easier way by far is to pass the <tt>:response</tt> option to | |
74 | + # +register_uri+ as a +String+ or an (open for reads) +IO+ object which | |
75 | + # will be used as the complete HTTP response, including headers and body. | |
76 | + # If the string points to a readable file, this file will be used as the | |
77 | + # content for the request. | |
78 | + # | |
79 | + # To obtain a complete response document, you can use the +curl+ command, | |
80 | + # like so: | |
81 | + # | |
82 | + # curl -i http://www.example.com/ > response_for_www.example.com | |
83 | + # | |
84 | + # which can then be used in your test environment like so: | |
85 | + # | |
86 | + # FakeWeb.register_uri(:get, 'http://www.example.com/', :response => 'response_for_www.example.com') | |
87 | + # | |
88 | + # See the <tt>Net::HTTPResponse</tt> | |
89 | + # documentation[http://ruby-doc.org/stdlib/libdoc/net/http/rdoc/classes/Net/HTTPResponse.html] | |
90 | + # for more information on creating custom response objects. | |
91 | + # | |
92 | + # +options+ may also be an +Array+ containing a list of the above-described | |
93 | + # +Hash+. In this case, FakeWeb will rotate through each provided response, | |
94 | + # you may optionally provide: | |
95 | + # | |
96 | + # <tt>:times</tt>:: | |
97 | + # The number of times this response will be used. Decremented by one each time it's called. | |
98 | + # FakeWeb will use the final provided request indefinitely, regardless of its :times parameter. | |
99 | + # | |
100 | + # Two optional arguments are also accepted: | |
101 | + # | |
102 | + # <tt>:status</tt>:: | |
103 | + # Passing <tt>:status</tt> as a two-value array will set the response code | |
104 | + # and message. The defaults are <tt>200</tt> and <tt>OK</tt>, respectively. | |
105 | + # Example: | |
106 | + # FakeWeb.register_uri("http://www.example.com/", :body => "Go away!", :status => [404, "Not Found"]) | |
107 | + # <tt>:exception</tt>:: | |
108 | + # The argument passed via <tt>:exception</tt> will be raised when the | |
109 | + # specified URL is requested. Any +Exception+ class is valid. Example: | |
110 | + # FakeWeb.register_uri('http://www.example.com/', :exception => Net::HTTPError) | |
111 | + # | |
112 | + # If you're using the <tt>:body</tt> response type, you can pass additional | |
113 | + # options to specify the HTTP headers to be used in the response. Example: | |
114 | + # | |
115 | + # FakeWeb.register_uri(:get, "http://example.com/index.txt", :body => "Hello", :content_type => "text/plain") | |
116 | + def self.register_uri(*args) | |
117 | + case args.length | |
118 | + when 3 | |
119 | + Registry.instance.register_uri(*args) | |
120 | + when 2 | |
121 | + print_missing_http_method_deprecation_warning(*args) | |
122 | + Registry.instance.register_uri(:any, *args) | |
123 | + else | |
124 | + raise ArgumentError.new("wrong number of arguments (#{args.length} for 3)") | |
125 | + end | |
126 | + end | |
127 | + | |
128 | + # call-seq: | |
129 | + # FakeWeb.response_for(method, uri) | |
130 | + # | |
131 | + # Returns the faked Net::HTTPResponse object associated with +method+ and +uri+. | |
132 | + def self.response_for(*args, &block) #:nodoc: :yields: response | |
133 | + case args.length | |
134 | + when 2 | |
135 | + Registry.instance.response_for(*args, &block) | |
136 | + when 1 | |
137 | + print_missing_http_method_deprecation_warning(*args) | |
138 | + Registry.instance.response_for(:any, *args, &block) | |
139 | + else | |
140 | + raise ArgumentError.new("wrong number of arguments (#{args.length} for 2)") | |
141 | + end | |
142 | + end | |
143 | + | |
144 | + # call-seq: | |
145 | + # FakeWeb.registered_uri?(method, uri) | |
146 | + # | |
147 | + # Returns true if a +method+ request for +uri+ is registered with FakeWeb. | |
148 | + # Specify a method of <tt>:any</tt> to check for against all HTTP methods. | |
149 | + def self.registered_uri?(*args) | |
150 | + case args.length | |
151 | + when 2 | |
152 | + Registry.instance.registered_uri?(*args) | |
153 | + when 1 | |
154 | + print_missing_http_method_deprecation_warning(*args) | |
155 | + Registry.instance.registered_uri?(:any, *args) | |
156 | + else | |
157 | + raise ArgumentError.new("wrong number of arguments (#{args.length} for 2)") | |
158 | + end | |
159 | + end | |
160 | + | |
161 | + private | |
162 | + | |
163 | + def self.print_missing_http_method_deprecation_warning(*args) | |
164 | + method = caller.first.match(/`(.*?)'/)[1] | |
165 | + new_args = args.map { |a| a.inspect }.unshift(":any") | |
166 | + new_args.last.gsub!(/^\{|\}$/, "").gsub!("=>", " => ") if args.last.is_a?(Hash) | |
167 | + $stderr.puts | |
168 | + $stderr.puts "Deprecation warning: FakeWeb requires an HTTP method argument (or use :any). Try this:" | |
169 | + $stderr.puts " FakeWeb.#{method}(#{new_args.join(', ')})" | |
170 | + $stderr.puts "Called at #{caller[1]}" | |
171 | + end | |
172 | +end | ... | ... |
... | ... | @@ -0,0 +1,71 @@ |
1 | +require 'net/http' | |
2 | +require 'net/https' | |
3 | +require 'stringio' | |
4 | + | |
5 | +module Net #:nodoc: all | |
6 | + | |
7 | + class BufferedIO | |
8 | + alias initialize_without_fakeweb initialize | |
9 | + def initialize(io, debug_output = nil) | |
10 | + @read_timeout = 60 | |
11 | + @rbuf = '' | |
12 | + @debug_output = debug_output | |
13 | + | |
14 | + @io = case io | |
15 | + when Socket, OpenSSL::SSL::SSLSocket, IO | |
16 | + io | |
17 | + when String | |
18 | + if !io.include?("\0") && File.exists?(io) && !File.directory?(io) | |
19 | + File.open(io, "r") | |
20 | + else | |
21 | + StringIO.new(io) | |
22 | + end | |
23 | + end | |
24 | + raise "Unable to create local socket" unless @io | |
25 | + end | |
26 | + end | |
27 | + | |
28 | + class HTTP | |
29 | + class << self | |
30 | + alias socket_type_without_fakeweb socket_type | |
31 | + def socket_type | |
32 | + FakeWeb::StubSocket | |
33 | + end | |
34 | + end | |
35 | + | |
36 | + alias request_without_fakeweb request | |
37 | + def request(request, body = nil, &block) | |
38 | + protocol = use_ssl? ? "https" : "http" | |
39 | + | |
40 | + path = request.path | |
41 | + path = URI.parse(request.path).request_uri if request.path =~ /^http/ | |
42 | + | |
43 | + if request["authorization"] =~ /^Basic / | |
44 | + userinfo = FakeWeb::Utility.decode_userinfo_from_header(request["authorization"]) | |
45 | + userinfo = FakeWeb::Utility.encode_unsafe_chars_in_userinfo(userinfo) + "@" | |
46 | + else | |
47 | + userinfo = "" | |
48 | + end | |
49 | + | |
50 | + uri = "#{protocol}://#{userinfo}#{self.address}:#{self.port}#{path}" | |
51 | + method = request.method.downcase.to_sym | |
52 | + | |
53 | + if FakeWeb.registered_uri?(method, uri) | |
54 | + @socket = Net::HTTP.socket_type.new | |
55 | + FakeWeb.response_for(method, uri, &block) | |
56 | + elsif FakeWeb.allow_net_connect? | |
57 | + connect_without_fakeweb | |
58 | + request_without_fakeweb(request, body, &block) | |
59 | + else | |
60 | + uri = FakeWeb::Utility.strip_default_port_from_uri(uri) | |
61 | + raise FakeWeb::NetConnectNotAllowedError, | |
62 | + "Real HTTP connections are disabled. Unregistered request: #{request.method} #{uri}" | |
63 | + end | |
64 | + end | |
65 | + | |
66 | + alias connect_without_fakeweb connect | |
67 | + def connect | |
68 | + end | |
69 | + end | |
70 | + | |
71 | +end | ... | ... |
... | ... | @@ -0,0 +1,103 @@ |
1 | +module FakeWeb | |
2 | + class Registry #:nodoc: | |
3 | + include Singleton | |
4 | + | |
5 | + attr_accessor :uri_map | |
6 | + | |
7 | + def initialize | |
8 | + clean_registry | |
9 | + end | |
10 | + | |
11 | + def clean_registry | |
12 | + self.uri_map = Hash.new { |hash, key| hash[key] = {} } | |
13 | + end | |
14 | + | |
15 | + def register_uri(method, uri, options) | |
16 | + uri_map[normalize_uri(uri)][method] = [*[options]].flatten.collect do |option| | |
17 | + FakeWeb::Responder.new(method, uri, option, option[:times]) | |
18 | + end | |
19 | + end | |
20 | + | |
21 | + def registered_uri?(method, uri) | |
22 | + normalized_uri = normalize_uri(uri) | |
23 | + !responses_for(method, uri).empty? | |
24 | + end | |
25 | + | |
26 | + def response_for(method, uri, &block) | |
27 | + responses = responses_for(method, uri) | |
28 | + return nil if responses.empty? | |
29 | + | |
30 | + next_response = responses.last | |
31 | + responses.each do |response| | |
32 | + if response.times and response.times > 0 | |
33 | + response.times -= 1 | |
34 | + next_response = response | |
35 | + break | |
36 | + end | |
37 | + end | |
38 | + | |
39 | + next_response.response(&block) | |
40 | + end | |
41 | + | |
42 | + | |
43 | + private | |
44 | + | |
45 | + def responses_for(method, uri) | |
46 | + uri = normalize_uri(uri) | |
47 | + | |
48 | + if uri_map[uri].has_key?(method) | |
49 | + uri_map[uri][method] | |
50 | + elsif uri_map[uri].has_key?(:any) | |
51 | + uri_map[uri][:any] | |
52 | + elsif uri_map_matches?(method, uri) | |
53 | + uri_map_matches(method, uri) | |
54 | + elsif uri_map_matches(:any, uri) | |
55 | + uri_map_matches(:any, uri) | |
56 | + else | |
57 | + [] | |
58 | + end | |
59 | + end | |
60 | + | |
61 | + def uri_map_matches?(method, uri) | |
62 | + !uri_map_matches(method, uri).nil? | |
63 | + end | |
64 | + | |
65 | + def uri_map_matches(method, uri) | |
66 | + uri = normalize_uri(uri.to_s).to_s | |
67 | + uri = Utility.strip_default_port_from_uri(uri) | |
68 | + | |
69 | + matches = uri_map.select { |registered_uri, method_hash| | |
70 | + registered_uri.is_a?(Regexp) && uri.match(registered_uri) && method_hash.has_key?(method) | |
71 | + } | |
72 | + | |
73 | + if matches.size > 1 | |
74 | + raise MultipleMatchingRegexpsError, | |
75 | + "More than one regular expression matched this request: #{method.to_s.upcase} #{uri}" | |
76 | + end | |
77 | + | |
78 | + matches.map { |_, method_hash| method_hash[method] }.first | |
79 | + end | |
80 | + | |
81 | + def normalize_uri(uri) | |
82 | + return uri if uri.is_a?(Regexp) | |
83 | + normalized_uri = | |
84 | + case uri | |
85 | + when URI then uri | |
86 | + when String | |
87 | + uri = 'http://' + uri unless uri.match('^https?://') | |
88 | + URI.parse(uri) | |
89 | + end | |
90 | + normalized_uri.query = sort_query_params(normalized_uri.query) | |
91 | + normalized_uri.normalize | |
92 | + end | |
93 | + | |
94 | + def sort_query_params(query) | |
95 | + if query.nil? || query.empty? | |
96 | + nil | |
97 | + else | |
98 | + query.split('&').sort.join('&') | |
99 | + end | |
100 | + end | |
101 | + | |
102 | + end | |
103 | +end | ... | ... |
... | ... | @@ -0,0 +1,113 @@ |
1 | +module FakeWeb | |
2 | + class Responder #:nodoc: | |
3 | + | |
4 | + attr_accessor :method, :uri, :options, :times | |
5 | + KNOWN_OPTIONS = [:body, :exception, :response, :status].freeze | |
6 | + | |
7 | + def initialize(method, uri, options, times) | |
8 | + self.method = method | |
9 | + self.uri = uri | |
10 | + self.options = options | |
11 | + self.times = times ? times : 1 | |
12 | + | |
13 | + if options.has_key?(:file) || options.has_key?(:string) | |
14 | + print_file_string_options_deprecation_warning | |
15 | + options[:body] = options.delete(:file) || options.delete(:string) | |
16 | + end | |
17 | + end | |
18 | + | |
19 | + def response(&block) | |
20 | + if has_baked_response? | |
21 | + response = baked_response | |
22 | + else | |
23 | + code, msg = meta_information | |
24 | + response = Net::HTTPResponse.send(:response_class, code.to_s).new("1.0", code.to_s, msg) | |
25 | + response.instance_variable_set(:@body, body) | |
26 | + headers_extracted_from_options.each { |name, value| response[name] = value } | |
27 | + end | |
28 | + | |
29 | + response.instance_variable_set(:@read, true) | |
30 | + response.extend FakeWeb::Response | |
31 | + | |
32 | + optionally_raise(response) | |
33 | + | |
34 | + yield response if block_given? | |
35 | + | |
36 | + response | |
37 | + end | |
38 | + | |
39 | + private | |
40 | + | |
41 | + def headers_extracted_from_options | |
42 | + options.reject {|name, _| KNOWN_OPTIONS.include?(name) }.map { |name, value| | |
43 | + [name.to_s.split("_").map { |segment| segment.capitalize }.join("-"), value] | |
44 | + } | |
45 | + end | |
46 | + | |
47 | + def body | |
48 | + return '' unless options.has_key?(:body) | |
49 | + | |
50 | + if !options[:body].include?("\0") && File.exists?(options[:body]) && !File.directory?(options[:body]) | |
51 | + File.read(options[:body]) | |
52 | + else | |
53 | + options[:body] | |
54 | + end | |
55 | + end | |
56 | + | |
57 | + def baked_response | |
58 | + resp = case options[:response] | |
59 | + when Net::HTTPResponse then options[:response] | |
60 | + when String | |
61 | + socket = Net::BufferedIO.new(options[:response]) | |
62 | + r = Net::HTTPResponse.read_new(socket) | |
63 | + | |
64 | + # Store the oiriginal transfer-encoding | |
65 | + saved_transfer_encoding = r.instance_eval { | |
66 | + @header['transfer-encoding'] if @header.key?('transfer-encoding') | |
67 | + } | |
68 | + | |
69 | + # read the body of response. | |
70 | + r.instance_eval { @header['transfer-encoding'] = nil } | |
71 | + r.reading_body(socket, true) {} | |
72 | + | |
73 | + # Delete the transfer-encoding key from r.@header if there wasn't one, | |
74 | + # else restore the saved_transfer_encoding. | |
75 | + if saved_transfer_encoding.nil? | |
76 | + r.instance_eval { @header.delete('transfer-encoding') } | |
77 | + else | |
78 | + r.instance_eval { @header['transfer-encoding'] = saved_transfer_encoding } | |
79 | + end | |
80 | + r | |
81 | + else raise StandardError, "Handler unimplemented for response #{options[:response]}" | |
82 | + end | |
83 | + end | |
84 | + | |
85 | + def has_baked_response? | |
86 | + options.has_key?(:response) | |
87 | + end | |
88 | + | |
89 | + def optionally_raise(response) | |
90 | + return unless options.has_key?(:exception) | |
91 | + | |
92 | + case options[:exception].to_s | |
93 | + when "Net::HTTPError", "OpenURI::HTTPError" | |
94 | + raise options[:exception].new('Exception from FakeWeb', response) | |
95 | + else | |
96 | + raise options[:exception].new('Exception from FakeWeb') | |
97 | + end | |
98 | + end | |
99 | + | |
100 | + def meta_information | |
101 | + options.has_key?(:status) ? options[:status] : [200, 'OK'] | |
102 | + end | |
103 | + | |
104 | + def print_file_string_options_deprecation_warning | |
105 | + which = options.has_key?(:file) ? :file : :string | |
106 | + $stderr.puts | |
107 | + $stderr.puts "Deprecation warning: FakeWeb's :#{which} option has been renamed to :body." | |
108 | + $stderr.puts "Just replace :#{which} with :body in your FakeWeb.register_uri calls." | |
109 | + $stderr.puts "Called at #{caller[6]}" | |
110 | + end | |
111 | + | |
112 | + end | |
113 | +end | |
0 | 114 | \ No newline at end of file | ... | ... |
... | ... | @@ -0,0 +1,22 @@ |
1 | +module FakeWeb | |
2 | + module Utility #:nodoc: | |
3 | + | |
4 | + def self.decode_userinfo_from_header(header) | |
5 | + header.sub(/^Basic /, "").unpack("m").first | |
6 | + end | |
7 | + | |
8 | + def self.encode_unsafe_chars_in_userinfo(userinfo) | |
9 | + unsafe_in_userinfo = /[^#{URI::REGEXP::PATTERN::UNRESERVED};&=+$,]|^(#{URI::REGEXP::PATTERN::ESCAPED})/ | |
10 | + userinfo.split(":").map { |part| URI.escape(part, unsafe_in_userinfo) }.join(":") | |
11 | + end | |
12 | + | |
13 | + def self.strip_default_port_from_uri(uri) | |
14 | + case uri | |
15 | + when %r{^http://} then uri.sub(%r{:80(/|$)}, '\1') | |
16 | + when %r{^https://} then uri.sub(%r{:443(/|$)}, '\1') | |
17 | + else uri | |
18 | + end | |
19 | + end | |
20 | + | |
21 | + end | |
22 | +end | ... | ... |
vendor/gems/fakeweb-1.2.5/test/fixtures/google_response_from_curl
0 → 100644
... | ... | @@ -0,0 +1,12 @@ |
1 | +HTTP/1.1 200 OK | |
2 | +Cache-Control: private, max-age=0 | |
3 | +Date: Sun, 01 Feb 2009 02:16:24 GMT | |
4 | +Expires: -1 | |
5 | +Content-Type: text/html; charset=ISO-8859-1 | |
6 | +Set-Cookie: PREF=ID=a6d9b5f5a4056dfe:TM=1233454584:LM=1233454584:S=U9pSwSu4eQwOPenX; expires=Tue, 01-Feb-2011 02:16:24 GMT; path=/; domain=.google.com | |
7 | +Server: gws | |
8 | +Transfer-Encoding: chunked | |
9 | + | |
10 | +<html><head><meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"><title>Google</title><script>var _gjwl=location;function _gjuc(){var a=_gjwl.hash;if(a.indexOf("&q=")>0||a.indexOf("#q=")>=0){a=a.substring(1);if(a.indexOf("#")==-1){for(var c=0;c<a.length;){var d=c;if(a.charAt(d)=="&")++d;var b=a.indexOf("&",d);if(b==-1)b=a.length;var e=a.substring(d,b);if(e.indexOf("fp=")==0){a=a.substring(0,c)+a.substring(b,a.length);b=c}else if(e=="cad=h")return 0;c=b}_gjwl.href="search?"+a+"&cad=h";return 1}}return 0}; | |
11 | +window._gjuc && location.hash && _gjuc();</script><style>body,td,a,p,.h{font-family:arial,sans-serif}.h{color:#36c;font-size:20px}.q{color:#00c}.ts td{padding:0}.ts{border-collapse:collapse}#gbar{height:22px;padding-left:2px}.gbh,.gbd{border-top:1px solid #c9d7f1;font-size:1px}.gbh{height:0;position:absolute;top:24px;width:100%}#gbi,#gbs{background:#fff;left:0;position:absolute;top:24px;visibility:hidden;z-index:1000}#gbi{border:1px solid;border-color:#c9d7f1 #36c #36c #a2bae7;z-index:1001}#guser{padding-bottom:7px !important}#gbar,#guser{font-size:13px;padding-top:1px !important}@media all{.gb1,.gb3{height:22px;margin-right:.73em;vertical-align:top}#gbar{float:left}}.gb2{display:block;padding:.2em .5em}a.gb1,a.gb2,a.gb3{color:#00c !important}.gb2,.gb3{text-decoration:none}a.gb2:hover{background:#36c;color:#fff !important}</style><script>window.google={kEI:"-AWFSZ6qFYuUswO9j5HIDQ",kEXPI:"17259,19547",kHL:"en"}; | |
12 | +google.y={};google.x=function(e,g){google.y[e.id]=[e,g];return false};window.gbar={};(function(){var b=window.gbar,f,h;b.qs=function(a){var c=window.encodeURIComponent&&(document.forms[0].q||"").value;if(c)a.href=a.href.replace(/([?&])q=[^&]*|$/,function(i,g){return(g||"&")+"q="+encodeURIComponent(c)})};function j(a,c){a.visibility=h?"hidden":"visible";a.left=c+"px"}b.tg=function(a){a=a||window.event;var c=0,i,g=window.navExtra,d=document.getElementById("gbi"),e=a.target||a.srcElement;a.cancelBubble=true;if(!f){f=document.createElement(Array.every||window.createPopup?"iframe":"div");f.frameBorder="0";f.src="#";d.parentNode.appendChild(f).id="gbs";if(g)for(i in g)d.insertBefore(g[i],d.firstChild).className="gb2";document.onclick=b.close}if(e.className!="gb3")e=e.parentNode;do c+=e.offsetLeft;while(e=e.offsetParent);j(d.style,c);f.style.width=d.offsetWidth+"px";f.style.height=d.offsetHeight+"px";j(f.style,c);h=!h};b.close=function(a){h&&b.tg(a)}})();</script></head><body bgcolor=#ffffff text=#000000 link=#0000cc vlink=#551a8b alink=#ff0000 onload="document.f.q.focus();if(document.images)new Image().src='/images/nav_logo3.png'" topmargin=3 marginheight=3><div id=gbar><nobr><b class=gb1>Web</b> <a href="http://images.google.com/imghp?hl=en&tab=wi" onclick=gbar.qs(this) class=gb1>Images</a> <a href="http://maps.google.com/maps?hl=en&tab=wl" onclick=gbar.qs(this) class=gb1>Maps</a> <a href="http://news.google.com/nwshp?hl=en&tab=wn" onclick=gbar.qs(this) class=gb1>News</a> <a href="http://www.google.com/prdhp?hl=en&tab=wf" onclick=gbar.qs(this) class=gb1>Shopping</a> <a href="http://mail.google.com/mail/?hl=en&tab=wm" class=gb1>Gmail</a> <a href="http://www.google.com/intl/en/options/" onclick="this.blur();gbar.tg(event);return !1" class=gb3><u>more</u> <small>▼</small></a><div id=gbi> <a href="http://video.google.com/?hl=en&tab=wv" onclick=gbar.qs(this) class=gb2>Video</a> <a href="http://groups.google.com/grphp?hl=en&tab=wg" onclick=gbar.qs(this) class=gb2>Groups</a> <a href="http://books.google.com/bkshp?hl=en&tab=wp" onclick=gbar.qs(this) class=gb2>Books</a> <a href="http://scholar.google.com/schhp?hl=en&tab=ws" onclick=gbar.qs(this) class=gb2>Scholar</a> <a href="http://finance.google.com/finance?hl=en&tab=we" onclick=gbar.qs(this) class=gb2>Finance</a> <a href="http://blogsearch.google.com/?hl=en&tab=wb" onclick=gbar.qs(this) class=gb2>Blogs</a> <div class=gb2><div class=gbd></div></div> <a href="http://www.youtube.com/?hl=en&tab=w1" onclick=gbar.qs(this) class=gb2>YouTube</a> <a href="http://www.google.com/calendar/render?hl=en&tab=wc" class=gb2>Calendar</a> <a href="http://picasaweb.google.com/home?hl=en&tab=wq" onclick=gbar.qs(this) class=gb2>Photos</a> <a href="http://docs.google.com/?hl=en&tab=wo" class=gb2>Documents</a> <a href="http://www.google.com/reader/view/?hl=en&tab=wy" class=gb2>Reader</a> <a href="http://sites.google.com/?hl=en&tab=w3" class=gb2>Sites</a> <div class=gb2><div class=gbd></div></div> <a href="http://www.google.com/intl/en/options/" class=gb2>even more »</a></div> </nobr></div><div class=gbh style=left:0></div><div class=gbh style=right:0></div><div align=right id=guser style="font-size:84%;padding:0 0 4px" width=100%><nobr><a href="/url?sa=p&pref=ig&pval=3&q=http://www.google.com/ig%3Fhl%3Den%26source%3Diglk&usg=AFQjCNFA18XPfgb7dKnXfKz7x7g1GDH1tg">iGoogle</a> | <a href="https://www.google.com/accounts/Login?continue=http://www.google.com/&hl=en">Sign in</a></nobr></div><center><br clear=all id=lgpd><img alt="Google" height=110 src="/intl/en_ALL/images/logo.gif" width=276><br><br><form action="/search" name=f><table cellpadding=0 cellspacing=0><tr valign=top><td width=25%> </td><td align=center nowrap><input name=hl type=hidden value=en><input type=hidden name=ie value="ISO-8859-1"><input autocomplete="off" maxlength=2048 name=q size=55 title="Google Search" value=""><br><input name=btnG type=submit value="Google Search"><input name=btnI type=submit value="I'm Feeling Lucky"></td><td nowrap width=25%><font size=-2> <a href=/advanced_search?hl=en>Advanced Search</a><br> <a href=/preferences?hl=en>Preferences</a><br> <a href=/language_tools?hl=en>Language Tools</a></font></td></tr></table></form><br><font size=-1>Share what you know. <a href="/aclk?sa=L&ai=CYhslHwSFSZH6LIHusAPEsc2eBfv77nqP3YC9CsHZnNkTEAEgwVRQypDftPn_____AWDJBqoECU_QbUVlfOdxZw&num=1&sig=AGiWqtwRgqw8y_kza6RGKxBrCstaXkDJ7A&q=http://knol.google.com">Write a Knol</a>.</font><br><br><br><font size=-1><a href="/intl/en/ads/">Advertising Programs</a> - <a href="/services/">Business Solutions</a> - <a href="/intl/en/about.html">About Google</a></font><p><font size=-2>©2009 - <a href="/intl/en/privacy.html">Privacy</a></font></p></center></body><script>if(google.y)google.y.first=[];window.setTimeout(function(){var xjs=document.createElement('script');xjs.src='/extern_js/f/CgJlbhICdXMgACswCjgVLCswDjgELCswGDgDLA/L3N5xu59nDE.js';document.getElementsByTagName('head')[0].appendChild(xjs)},0);google.y.first.push(function(){google.ac.i(document.f,document.f.q,'','')})</script><script>function _gjp() {!(location.hash && _gjuc()) && setTimeout(_gjp, 500);}window._gjuc && _gjp();</script></html> | |
0 | 13 | \ No newline at end of file | ... | ... |
vendor/gems/fakeweb-1.2.5/test/fixtures/google_response_with_transfer_encoding
0 → 100644
... | ... | @@ -0,0 +1,17 @@ |
1 | +HTTP/1.1 200 OK | |
2 | +Cache-Control: private, max-age=0 | |
3 | +Date: Sun, 01 Feb 2009 01:54:36 GMT | |
4 | +Expires: -1 | |
5 | +Content-Type: text/html; charset=ISO-8859-1 | |
6 | +Set-Cookie: PREF=ID=4320bcaa30d097de:TM=1233453276:LM=1233453276:S=Eio39bg_nIabTxzL; expires=Tue, 01-Feb-2011 01:54:36 GMT; path=/; domain=.google.com | |
7 | +Server: gws | |
8 | +Transfer-Encoding: chunked | |
9 | + | |
10 | +fef | |
11 | +<html><head><meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"><title>Google</title><script>var _gjwl=location;function _gjuc(){var a=_gjwl.hash;if(a.indexOf("&q=")>0||a.indexOf("#q=")>=0){a=a.substring(1);if(a.indexOf("#")==-1){for(var c=0;c<a.length;){var d=c;if(a.charAt(d)=="&")++d;var b=a.indexOf("&",d);if(b==-1)b=a.length;var e=a.substring(d,b);if(e.indexOf("fp=")==0){a=a.substring(0,c)+a.substring(b,a.length);b=c}else if(e=="cad=h")return 0;c=b}_gjwl.href="search?"+a+"&cad=h";return 1}}return 0}; | |
12 | +window._gjuc && location.hash && _gjuc();</script><style>body,td,a,p,.h{font-family:arial,sans-serif}.h{color:#36c;font-size:20px}.q{color:#00c}.ts td{padding:0}.ts{border-collapse:collapse}#gbar{height:22px;padding-left:2px}.gbh,.gbd{border-top:1px solid #c9d7f1;font-size:1px}.gbh{height:0;position:absolute;top:24px;width:100%}#gbi,#gbs{background:#fff;left:0;position:absolute;top:24px;visibility:hidden;z-index:1000}#gbi{border:1px solid;border-color:#c9d7f1 #36c #36c #a2bae7;z-index:1001}#guser{padding-bottom:7px !important}#gbar,#guser{font-size:13px;padding-top:1px !important}@media all{.gb1,.gb3{height:22px;margin-right:.73em;vertical-align:top}#gbar{float:left}}.gb2{display:block;padding:.2em .5em}a.gb1,a.gb2,a.gb3{color:#00c !important}.gb2,.gb3{text-decoration:none}a.gb2:hover{background:#36c;color:#fff !important}</style><script>window.google={kEI:"3ACFSYC6EKTcswOL4_nBDQ",kEXPI:"17259,19463",kHL:"en"}; | |
13 | +google.y={};google.x=function(e,g){google.y[e.id]=[e,g];return false};window.gbar={};(function(){var b=window.gbar,f,h;b.qs=function(a){var c=window.encodeURIComponent&&(document.forms[0].q||"").value;if(c)a.href=a.href.replace(/([?&])q=[^&]*|$/,function(i,g){return(g||"&")+"q="+encodeURIComponent(c)})};function j(a,c){a.visibility=h?"hidden":"visible";a.left=c+"px"}b.tg=function(a){a=a||window.event;var c=0,i,g=window.navExtra,d=document.getElementById("gbi"),e=a.target||a.srcElement;a.cancelBubble=true;if(!f){f=document.createElement(Array.every||window.createPopup?"iframe":"div");f.frameBorder="0";f.src="#";d.parentNode.appendChild(f).id="gbs";if(g)for(i in g)d.insertBefore(g[i],d.firstChild).className="gb2";document.onclick=b.close}if(e.className!="gb3")e=e.parentNode;do c+=e.offsetLeft;while(e=e.offsetParent);j(d.style,c);f.style.width=d.offsetWidth+"px";f.style.height=d.offsetHeight+"px";j(f.style,c);h=!h};b.close=function(a){h&&b.tg(a)}})();</script></head><body bgcolor=#ffffff text=#000000 link=#0000cc vlink=#551a8b alink=#ff0000 onload="document.f.q.focus();if(document.images)new Image().src='/images/nav_logo3.png'" topmargin=3 marginheight=3><div id=gbar><nobr><b class=gb1>Web</b> <a href="http://images.google.com/imghp?hl=en&tab=wi" onclick=gbar.qs(this) class=gb1>Images</a> <a href="http://maps.google.com/maps?hl=en&tab=wl" onclick=gbar.qs(this) class=gb1>Maps</a> <a href="http://news.google.com/nwshp?hl=en&tab=wn" onclick=gbar.qs(this) class=gb1>News</a> <a href="http://www.google.com/prdhp?hl=en&tab=wf" onclick=gbar.qs(this) class=gb1>Shopping</a> <a href="http://mail.google.com/mail/?hl=en&tab=wm" class=gb1>Gmail</a> <a href="http://www.google.com/intl/en/options/" onclick="this.blur();gbar.tg(event);return !1" class=gb3><u>more</u> <small>▼</small></a><div id=gbi> <a href="http://video.google.com/?hl=en&tab=wv" onclick=gbar.qs(this) class=gb2>Video</a> <a href="http://groups.google.com/grphp?hl=en&tab=wg" onclick=gbar.qs(this) class=gb2>Groups</a> <a href="http://books.google.com/bkshp?hl=en&tab=wp" onclick=gbar.qs(this) class=gb2>Books</a> <a href="http://scholar.google.com/schhp?hl=en&tab=ws" onclick=gbar.qs(this) class=gb2>Scholar</a> <a href="http://finance.google.com/finance?hl=en&tab=we" onclick=gbar.qs(this) class=gb2>Finance</a> <a href="http://blogsearch.google.com/?hl=en&tab=wb" onclick=gbar.qs(this) class=gb2>Blogs</a> <div class=gb2><div class=gbd></div></div> <a href="http://www.youtube.com/?hl=en&tab=w1" onclick=gbar.qs(this) class=gb2>YouTube</a> <a href="http://www.google.com/calendar/render?hl=en&tab=wc" class=gb2>Calendar</a> <a href="http | |
14 | +a27 | |
15 | +://picasaweb.google.com/home?hl=en&tab=wq" onclick=gbar.qs(this) class=gb2>Photos</a> <a href="http://docs.google.com/?hl=en&tab=wo" class=gb2>Documents</a> <a href="http://www.google.com/reader/view/?hl=en&tab=wy" class=gb2>Reader</a> <a href="http://sites.google.com/?hl=en&tab=w3" class=gb2>Sites</a> <div class=gb2><div class=gbd></div></div> <a href="http://www.google.com/intl/en/options/" class=gb2>even more »</a></div> </nobr></div><div class=gbh style=left:0></div><div class=gbh style=right:0></div><div align=right id=guser style="font-size:84%;padding:0 0 4px" width=100%><nobr><a href="/url?sa=p&pref=ig&pval=3&q=http://www.google.com/ig%3Fhl%3Den%26source%3Diglk&usg=AFQjCNFA18XPfgb7dKnXfKz7x7g1GDH1tg">iGoogle</a> | <a href="https://www.google.com/accounts/Login?continue=http://www.google.com/&hl=en">Sign in</a></nobr></div><center><br clear=all id=lgpd><img alt="Google" height=110 src="/intl/en_ALL/images/logo.gif" width=276><br><br><form action="/search" name=f><table cellpadding=0 cellspacing=0><tr valign=top><td width=25%> </td><td align=center nowrap><input name=hl type=hidden value=en><input type=hidden name=ie value="ISO-8859-1"><input autocomplete="off" maxlength=2048 name=q size=55 title="Google Search" value=""><br><input name=btnG type=submit value="Google Search"><input name=btnI type=submit value="I'm Feeling Lucky"></td><td nowrap width=25%><font size=-2> <a href=/advanced_search?hl=en>Advanced Search</a><br> <a href=/preferences?hl=en>Preferences</a><br> <a href=/language_tools?hl=en>Language Tools</a></font></td></tr></table></form><br><font size=-1>Share what you know. <a href="/aclk?sa=L&ai=CFL7HzwCFSZCnCJSwsQPm842HB_v77nqP3YC9CsHZnNkTEAEgwVRQypDftPn_____AWDJBqoECU_Q1sTewQNSbw&num=1&sig=AGiWqtyz-UiOD3EpsSp4k3n8A7zooeg48g&q=http://knol.google.com">Write a Knol</a>.</font><br><br><br><font size=-1><a href="/intl/en/ads/">Advertising Programs</a> - <a href="/services/">Business Solutions</a> - <a href="/intl/en/about.html">About Google</a></font><p><font size=-2>©2009 - <a href="/intl/en/privacy.html">Privacy</a></font></p></center></body><script>if(google.y)google.y.first=[];window.setTimeout(function(){var xjs=document.createElement('script');xjs.src='/extern_js/f/CgJlbhICdXMgACswCjgVLCswDjgELCswGDgDLA/L3N5xu59nDE.js';document.getElementsByTagName('head')[0].appendChild(xjs)},0);google.y.first.push(function(){google.ac.i(document.f,document.f.q,'','')})</script><script>function _gjp() {!(location.hash && _gjuc()) && setTimeout(_gjp, 500);}window._gjuc && _gjp();</script></html> | |
16 | +0 | |
17 | + | ... | ... |
vendor/gems/fakeweb-1.2.5/test/fixtures/google_response_without_transfer_encoding
0 → 100644
... | ... | @@ -0,0 +1,11 @@ |
1 | +HTTP/1.0 200 OK | |
2 | +Cache-Control: private, max-age=0 | |
3 | +Date: Sun, 01 Feb 2009 01:55:33 GMT | |
4 | +Expires: -1 | |
5 | +Content-Type: text/html; charset=ISO-8859-1 | |
6 | +Set-Cookie: PREF=ID=3c140c3eb4c4f516:TM=1233453333:LM=1233453333:S=OH7sElk2hOWkb9ot; expires=Tue, 01-Feb-2011 01:55:33 GMT; path=/; domain=.google.com | |
7 | +Server: gws | |
8 | + | |
9 | +<html><head><meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"><title>Google</title><script>var _gjwl=location;function _gjuc(){var a=_gjwl.hash;if(a.indexOf("&q=")>0||a.indexOf("#q=")>=0){a=a.substring(1);if(a.indexOf("#")==-1){for(var c=0;c<a.length;){var d=c;if(a.charAt(d)=="&")++d;var b=a.indexOf("&",d);if(b==-1)b=a.length;var e=a.substring(d,b);if(e.indexOf("fp=")==0){a=a.substring(0,c)+a.substring(b,a.length);b=c}else if(e=="cad=h")return 0;c=b}_gjwl.href="search?"+a+"&cad=h";return 1}}return 0}; | |
10 | +window._gjuc && location.hash && _gjuc();</script><style>body,td,a,p,.h{font-family:arial,sans-serif}.h{color:#36c;font-size:20px}.q{color:#00c}.ts td{padding:0}.ts{border-collapse:collapse}#gbar{height:22px;padding-left:2px}.gbh,.gbd{border-top:1px solid #c9d7f1;font-size:1px}.gbh{height:0;position:absolute;top:24px;width:100%}#gbi,#gbs{background:#fff;left:0;position:absolute;top:24px;visibility:hidden;z-index:1000}#gbi{border:1px solid;border-color:#c9d7f1 #36c #36c #a2bae7;z-index:1001}#guser{padding-bottom:7px !important}#gbar,#guser{font-size:13px;padding-top:1px !important}@media all{.gb1,.gb3{height:22px;margin-right:.73em;vertical-align:top}#gbar{float:left}}.gb2{display:block;padding:.2em .5em}a.gb1,a.gb2,a.gb3{color:#00c !important}.gb2,.gb3{text-decoration:none}a.gb2:hover{background:#36c;color:#fff !important}</style><script>window.google={kEI:"FQGFSY2rG5eSswOKpsHeDQ",kEXPI:"17259",kHL:"en"}; | |
11 | +google.y={};google.x=function(e,g){google.y[e.id]=[e,g];return false};window.gbar={};(function(){var b=window.gbar,f,h;b.qs=function(a){var c=window.encodeURIComponent&&(document.forms[0].q||"").value;if(c)a.href=a.href.replace(/([?&])q=[^&]*|$/,function(i,g){return(g||"&")+"q="+encodeURIComponent(c)})};function j(a,c){a.visibility=h?"hidden":"visible";a.left=c+"px"}b.tg=function(a){a=a||window.event;var c=0,i,g=window.navExtra,d=document.getElementById("gbi"),e=a.target||a.srcElement;a.cancelBubble=true;if(!f){f=document.createElement(Array.every||window.createPopup?"iframe":"div");f.frameBorder="0";f.src="#";d.parentNode.appendChild(f).id="gbs";if(g)for(i in g)d.insertBefore(g[i],d.firstChild).className="gb2";document.onclick=b.close}if(e.className!="gb3")e=e.parentNode;do c+=e.offsetLeft;while(e=e.offsetParent);j(d.style,c);f.style.width=d.offsetWidth+"px";f.style.height=d.offsetHeight+"px";j(f.style,c);h=!h};b.close=function(a){h&&b.tg(a)}})();</script></head><body bgcolor=#ffffff text=#000000 link=#0000cc vlink=#551a8b alink=#ff0000 onload="document.f.q.focus();if(document.images)new Image().src='/images/nav_logo3.png'" topmargin=3 marginheight=3><div id=gbar><nobr><b class=gb1>Web</b> <a href="http://images.google.com/imghp?hl=en&tab=wi" onclick=gbar.qs(this) class=gb1>Images</a> <a href="http://maps.google.com/maps?hl=en&tab=wl" onclick=gbar.qs(this) class=gb1>Maps</a> <a href="http://news.google.com/nwshp?hl=en&tab=wn" onclick=gbar.qs(this) class=gb1>News</a> <a href="http://www.google.com/prdhp?hl=en&tab=wf" onclick=gbar.qs(this) class=gb1>Shopping</a> <a href="http://mail.google.com/mail/?hl=en&tab=wm" class=gb1>Gmail</a> <a href="http://www.google.com/intl/en/options/" onclick="this.blur();gbar.tg(event);return !1" class=gb3><u>more</u> <small>▼</small></a><div id=gbi> <a href="http://video.google.com/?hl=en&tab=wv" onclick=gbar.qs(this) class=gb2>Video</a> <a href="http://groups.google.com/grphp?hl=en&tab=wg" onclick=gbar.qs(this) class=gb2>Groups</a> <a href="http://books.google.com/bkshp?hl=en&tab=wp" onclick=gbar.qs(this) class=gb2>Books</a> <a href="http://scholar.google.com/schhp?hl=en&tab=ws" onclick=gbar.qs(this) class=gb2>Scholar</a> <a href="http://finance.google.com/finance?hl=en&tab=we" onclick=gbar.qs(this) class=gb2>Finance</a> <a href="http://blogsearch.google.com/?hl=en&tab=wb" onclick=gbar.qs(this) class=gb2>Blogs</a> <div class=gb2><div class=gbd></div></div> <a href="http://www.youtube.com/?hl=en&tab=w1" onclick=gbar.qs(this) class=gb2>YouTube</a> <a href="http://www.google.com/calendar/render?hl=en&tab=wc" class=gb2>Calendar</a> <a href="http://picasaweb.google.com/home?hl=en&tab=wq" onclick=gbar.qs(this) class=gb2>Photos</a> <a href="http://docs.google.com/?hl=en&tab=wo" class=gb2>Documents</a> <a href="http://www.google.com/reader/view/?hl=en&tab=wy" class=gb2>Reader</a> <a href="http://sites.google.com/?hl=en&tab=w3" class=gb2>Sites</a> <div class=gb2><div class=gbd></div></div> <a href="http://www.google.com/intl/en/options/" class=gb2>even more »</a></div> </nobr></div><div class=gbh style=left:0></div><div class=gbh style=right:0></div><div align=right id=guser style="font-size:84%;padding:0 0 4px" width=100%><nobr><a href="/url?sa=p&pref=ig&pval=3&q=http://www.google.com/ig%3Fhl%3Den%26source%3Diglk&usg=AFQjCNFA18XPfgb7dKnXfKz7x7g1GDH1tg">iGoogle</a> | <a href="https://www.google.com/accounts/Login?continue=http://www.google.com/&hl=en">Sign in</a></nobr></div><center><br clear=all id=lgpd><img alt="Google" height=110 src="/intl/en_ALL/images/logo.gif" width=276><br><br><form action="/search" name=f><table cellpadding=0 cellspacing=0><tr valign=top><td width=25%> </td><td align=center nowrap><input name=hl type=hidden value=en><input type=hidden name=ie value="ISO-8859-1"><input autocomplete="off" maxlength=2048 name=q size=55 title="Google Search" value=""><br><input name=btnG type=submit value="Google Search"><input name=btnI type=submit value="I'm Feeling Lucky"></td><td nowrap width=25%><font size=-2> <a href=/advanced_search?hl=en>Advanced Search</a><br> <a href=/preferences?hl=en>Preferences</a><br> <a href=/language_tools?hl=en>Language Tools</a></font></td></tr></table></form><br><font size=-1>Share what you know. <a href="/aclk?sa=L&ai=ClyBp_v-EScTWD4W2tQOxoqSkB_v77nqP3YC9CsHZnNkTEAEgwVRQypDftPn_____AWDJBqoECU_QphTjHaZ5QA&num=1&sig=AGiWqtwtBqZ-zra3DJd_1chQKhKGf7lMVg&q=http://knol.google.com">Write a Knol</a>.</font><br><br><br><font size=-1><a href="/intl/en/ads/">Advertising Programs</a> - <a href="/services/">Business Solutions</a> - <a href="/intl/en/about.html">About Google</a></font><p><font size=-2>©2009 - <a href="/intl/en/privacy.html">Privacy</a></font></p></center></body><script>if(google.y)google.y.first=[];window.setTimeout(function(){var xjs=document.createElement('script');xjs.src='/extern_js/f/CgJlbhICdXMgACswCjgNLCswDjgELCswGDgDLA/oTKXc0xdkmY.js';document.getElementsByTagName('head')[0].appendChild(xjs)},0);google.y.first.push(function(){google.ac.i(document.f,document.f.q,'','')})</script><script>function _gjp() {!(location.hash && _gjuc()) && setTimeout(_gjp, 500);}window._gjuc && _gjp();</script></html> | |
0 | 12 | \ No newline at end of file | ... | ... |
vendor/gems/fakeweb-1.2.5/test/fixtures/test_example.txt
0 → 100644
vendor/gems/fakeweb-1.2.5/test/test_allow_net_connect.rb
0 → 100644
... | ... | @@ -0,0 +1,85 @@ |
1 | +require File.join(File.dirname(__FILE__), "test_helper") | |
2 | + | |
3 | +class TestFakeWebAllowNetConnect < Test::Unit::TestCase | |
4 | + | |
5 | + def test_unregistered_requests_are_passed_through_when_allow_net_connect_is_true | |
6 | + FakeWeb.allow_net_connect = true | |
7 | + setup_expectations_for_real_apple_hot_news_request | |
8 | + Net::HTTP.get(URI.parse("http://images.apple.com/main/rss/hotnews/hotnews.rss")) | |
9 | + end | |
10 | + | |
11 | + def test_raises_for_unregistered_requests_when_allow_net_connect_is_false | |
12 | + FakeWeb.allow_net_connect = false | |
13 | + exception = assert_raise FakeWeb::NetConnectNotAllowedError do | |
14 | + Net::HTTP.get(URI.parse("http://example.com/")) | |
15 | + end | |
16 | + end | |
17 | + | |
18 | + def test_exception_message_includes_unregistered_request_method_and_uri_but_no_default_port | |
19 | + FakeWeb.allow_net_connect = false | |
20 | + exception = assert_raise FakeWeb::NetConnectNotAllowedError do | |
21 | + Net::HTTP.get(URI.parse("http://example.com/")) | |
22 | + end | |
23 | + assert exception.message.include?("GET http://example.com/") | |
24 | + | |
25 | + exception = assert_raise FakeWeb::NetConnectNotAllowedError do | |
26 | + http = Net::HTTP.new("example.com", 443) | |
27 | + http.use_ssl = true | |
28 | + http.get("/") | |
29 | + end | |
30 | + assert exception.message.include?("GET https://example.com/") | |
31 | + end | |
32 | + | |
33 | + def test_exception_message_includes_unregistered_request_port_when_not_default | |
34 | + FakeWeb.allow_net_connect = false | |
35 | + exception = assert_raise FakeWeb::NetConnectNotAllowedError do | |
36 | + Net::HTTP.start("example.com", 8000) { |http| http.get("/") } | |
37 | + end | |
38 | + assert exception.message.include?("GET http://example.com:8000/") | |
39 | + | |
40 | + exception = assert_raise FakeWeb::NetConnectNotAllowedError do | |
41 | + http = Net::HTTP.new("example.com", 4433) | |
42 | + http.use_ssl = true | |
43 | + http.get("/") | |
44 | + end | |
45 | + assert exception.message.include?("GET https://example.com:4433/") | |
46 | + end | |
47 | + | |
48 | + def test_exception_message_includes_unregistered_request_port_when_not_default_with_path | |
49 | + FakeWeb.allow_net_connect = false | |
50 | + exception = assert_raise FakeWeb::NetConnectNotAllowedError do | |
51 | + Net::HTTP.start("example.com", 8000) { |http| http.get("/test") } | |
52 | + end | |
53 | + assert exception.message.include?("GET http://example.com:8000/test") | |
54 | + | |
55 | + exception = assert_raise FakeWeb::NetConnectNotAllowedError do | |
56 | + http = Net::HTTP.new("example.com", 4433) | |
57 | + http.use_ssl = true | |
58 | + http.get("/test") | |
59 | + end | |
60 | + assert exception.message.include?("GET https://example.com:4433/test") | |
61 | + end | |
62 | + | |
63 | + def test_question_mark_method_returns_true_after_setting_allow_net_connect_to_true | |
64 | + FakeWeb.allow_net_connect = true | |
65 | + assert FakeWeb.allow_net_connect? | |
66 | + end | |
67 | + | |
68 | + def test_question_mark_method_returns_false_after_setting_allow_net_connect_to_false | |
69 | + FakeWeb.allow_net_connect = false | |
70 | + assert !FakeWeb.allow_net_connect? | |
71 | + end | |
72 | + | |
73 | +end | |
74 | + | |
75 | + | |
76 | +class TestFakeWebAllowNetConnectWithCleanState < Test::Unit::TestCase | |
77 | + # Our test_helper.rb sets allow_net_connect = false in an inherited #setup | |
78 | + # method. Disable that here to test the default setting. | |
79 | + def setup; end | |
80 | + def teardown; end | |
81 | + | |
82 | + def test_allow_net_connect_is_true_by_default | |
83 | + assert FakeWeb.allow_net_connect? | |
84 | + end | |
85 | +end | ... | ... |
... | ... | @@ -0,0 +1,54 @@ |
1 | +require File.join(File.dirname(__FILE__), "test_helper") | |
2 | + | |
3 | +class TestDeprecations < Test::Unit::TestCase | |
4 | + | |
5 | + def test_register_uri_without_method_argument_prints_deprecation_warning | |
6 | + warning = capture_stderr do | |
7 | + FakeWeb.register_uri("http://example.com", :body => "test") | |
8 | + end | |
9 | + assert_match /deprecation warning: fakeweb/i, warning | |
10 | + end | |
11 | + | |
12 | + def test_registered_uri_without_method_argument_prints_deprecation_warning | |
13 | + warning = capture_stderr do | |
14 | + FakeWeb.registered_uri?("http://example.com") | |
15 | + end | |
16 | + assert_match /deprecation warning: fakeweb/i, warning | |
17 | + end | |
18 | + | |
19 | + def test_response_for_without_method_argument_prints_deprecation_warning | |
20 | + warning = capture_stderr do | |
21 | + FakeWeb.response_for("http://example.com") | |
22 | + end | |
23 | + assert_match /deprecation warning: fakeweb/i, warning | |
24 | + end | |
25 | + | |
26 | + def test_register_uri_without_method_argument_prints_deprecation_warning_with_correct_caller | |
27 | + warning = capture_stderr do | |
28 | + FakeWeb.register_uri("http://example.com", :body => "test") | |
29 | + end | |
30 | + assert_match /Called at.*?test_deprecations\.rb/i, warning | |
31 | + end | |
32 | + | |
33 | + def test_register_uri_with_string_option_prints_deprecation_warning | |
34 | + warning = capture_stderr do | |
35 | + FakeWeb.register_uri(:get, "http://example.com", :string => "test") | |
36 | + end | |
37 | + assert_match /deprecation warning: fakeweb's :string option/i, warning | |
38 | + end | |
39 | + | |
40 | + def test_register_uri_with_file_option_prints_deprecation_warning | |
41 | + warning = capture_stderr do | |
42 | + FakeWeb.register_uri(:get, "http://example.com", :file => File.dirname(__FILE__) + '/fixtures/test_example.txt') | |
43 | + end | |
44 | + assert_match /deprecation warning: fakeweb's :file option/i, warning | |
45 | + end | |
46 | + | |
47 | + def test_register_uri_with_string_option_prints_deprecation_warning_with_correct_caller | |
48 | + warning = capture_stderr do | |
49 | + FakeWeb.register_uri(:get, "http://example.com", :string => "test") | |
50 | + end | |
51 | + assert_match /Called at.*?test_deprecations\.rb/i, warning | |
52 | + end | |
53 | + | |
54 | +end | ... | ... |
vendor/gems/fakeweb-1.2.5/test/test_fake_authentication.rb
0 → 100644
... | ... | @@ -0,0 +1,92 @@ |
1 | +require File.join(File.dirname(__FILE__), "test_helper") | |
2 | + | |
3 | +class TestFakeAuthentication < Test::Unit::TestCase | |
4 | + | |
5 | + def test_register_uri_with_authentication | |
6 | + FakeWeb.register_uri(:get, 'http://user:pass@mock/test_example.txt', :body => "example") | |
7 | + assert FakeWeb.registered_uri?(:get, 'http://user:pass@mock/test_example.txt') | |
8 | + end | |
9 | + | |
10 | + def test_register_uri_with_authentication_doesnt_trigger_without | |
11 | + FakeWeb.register_uri(:get, 'http://user:pass@mock/test_example.txt', :body => "example") | |
12 | + assert !FakeWeb.registered_uri?(:get, 'http://mock/test_example.txt') | |
13 | + end | |
14 | + | |
15 | + def test_register_uri_with_authentication_doesnt_trigger_with_incorrect_credentials | |
16 | + FakeWeb.register_uri(:get, 'http://user:pass@mock/test_example.txt', :body => "example") | |
17 | + assert !FakeWeb.registered_uri?(:get, 'http://user:wrong@mock/test_example.txt') | |
18 | + end | |
19 | + | |
20 | + def test_unauthenticated_request | |
21 | + FakeWeb.register_uri(:get, 'http://mock/auth.txt', :body => 'unauthorized') | |
22 | + http = Net::HTTP.new('mock', 80) | |
23 | + req = Net::HTTP::Get.new('/auth.txt') | |
24 | + assert_equal 'unauthorized', http.request(req).body | |
25 | + end | |
26 | + | |
27 | + def test_authenticated_request | |
28 | + FakeWeb.register_uri(:get, 'http://user:pass@mock/auth.txt', :body => 'authorized') | |
29 | + http = Net::HTTP.new('mock',80) | |
30 | + req = Net::HTTP::Get.new('/auth.txt') | |
31 | + req.basic_auth 'user', 'pass' | |
32 | + assert_equal 'authorized', http.request(req).body | |
33 | + end | |
34 | + | |
35 | + def test_authenticated_request_where_only_userinfo_differs | |
36 | + FakeWeb.register_uri(:get, 'http://user:pass@mock/auth.txt', :body => 'first user') | |
37 | + FakeWeb.register_uri(:get, 'http://user2:pass@mock/auth.txt', :body => 'second user') | |
38 | + http = Net::HTTP.new('mock') | |
39 | + req = Net::HTTP::Get.new('/auth.txt') | |
40 | + req.basic_auth 'user2', 'pass' | |
41 | + assert_equal 'second user', http.request(req).body | |
42 | + end | |
43 | + | |
44 | + def test_basic_auth_support_is_transparent_to_oauth | |
45 | + FakeWeb.register_uri(:get, "http://sp.example.com/protected", :body => "secret") | |
46 | + | |
47 | + # from http://oauth.net/core/1.0/#auth_header | |
48 | + auth_header = <<-HEADER | |
49 | + OAuth realm="http://sp.example.com/", | |
50 | + oauth_consumer_key="0685bd9184jfhq22", | |
51 | + oauth_token="ad180jjd733klru7", | |
52 | + oauth_signature_method="HMAC-SHA1", | |
53 | + oauth_signature="wOJIO9A2W5mFwDgiDvZbTSMK%2FPY%3D", | |
54 | + oauth_timestamp="137131200", | |
55 | + oauth_nonce="4572616e48616d6d65724c61686176", | |
56 | + oauth_version="1.0" | |
57 | + HEADER | |
58 | + auth_header.gsub!(/\s+/, " ").strip! | |
59 | + | |
60 | + http = Net::HTTP.new("sp.example.com", 80) | |
61 | + response = nil | |
62 | + http.start do |request| | |
63 | + response = request.get("/protected", {"authorization" => auth_header}) | |
64 | + end | |
65 | + assert_equal "secret", response.body | |
66 | + end | |
67 | + | |
68 | + def test_basic_auth_when_userinfo_contains_allowed_unencoded_characters | |
69 | + FakeWeb.register_uri(:get, "http://roses&hel1o,(+$):so;longs=@example.com", :body => "authorized") | |
70 | + http = Net::HTTP.new("example.com") | |
71 | + request = Net::HTTP::Get.new("/") | |
72 | + request.basic_auth("roses&hel1o,(+$)", "so;longs=") | |
73 | + assert_equal "authorized", http.request(request).body | |
74 | + end | |
75 | + | |
76 | + def test_basic_auth_when_userinfo_contains_encoded_at_sign | |
77 | + FakeWeb.register_uri(:get, "http://user%40example.com:secret@example.com", :body => "authorized") | |
78 | + http = Net::HTTP.new("example.com") | |
79 | + request = Net::HTTP::Get.new("/") | |
80 | + request.basic_auth("user@example.com", "secret") | |
81 | + assert_equal "authorized", http.request(request).body | |
82 | + end | |
83 | + | |
84 | + def test_basic_auth_when_userinfo_contains_allowed_encoded_characters | |
85 | + FakeWeb.register_uri(:get, "http://us%20er:sec%20%2F%2Fret%3F@example.com", :body => "authorized") | |
86 | + http = Net::HTTP.new("example.com") | |
87 | + request = Net::HTTP::Get.new("/") | |
88 | + request.basic_auth("us er", "sec //ret?") | |
89 | + assert_equal "authorized", http.request(request).body | |
90 | + end | |
91 | + | |
92 | +end | ... | ... |
... | ... | @@ -0,0 +1,518 @@ |
1 | +require File.join(File.dirname(__FILE__), "test_helper") | |
2 | + | |
3 | +class TestFakeWeb < Test::Unit::TestCase | |
4 | + | |
5 | + def test_register_uri | |
6 | + FakeWeb.register_uri(:get, 'http://mock/test_example.txt', :body => "example") | |
7 | + assert FakeWeb.registered_uri?(:get, 'http://mock/test_example.txt') | |
8 | + end | |
9 | + | |
10 | + def test_register_uri_with_wrong_number_of_arguments | |
11 | + assert_raises ArgumentError do | |
12 | + FakeWeb.register_uri("http://example.com") | |
13 | + end | |
14 | + assert_raises ArgumentError do | |
15 | + FakeWeb.register_uri(:get, "http://example.com", "/example", :body => "example") | |
16 | + end | |
17 | + end | |
18 | + | |
19 | + def test_registered_uri_with_wrong_number_of_arguments | |
20 | + assert_raises ArgumentError do | |
21 | + FakeWeb.registered_uri? | |
22 | + end | |
23 | + assert_raises ArgumentError do | |
24 | + FakeWeb.registered_uri?(:get, "http://example.com", "/example") | |
25 | + end | |
26 | + end | |
27 | + | |
28 | + def test_response_for_with_wrong_number_of_arguments | |
29 | + assert_raises ArgumentError do | |
30 | + FakeWeb.response_for | |
31 | + end | |
32 | + assert_raises ArgumentError do | |
33 | + FakeWeb.response_for(:get, "http://example.com", "/example") | |
34 | + end | |
35 | + end | |
36 | + | |
37 | + def test_register_uri_without_domain_name | |
38 | + assert_raises URI::InvalidURIError do | |
39 | + FakeWeb.register_uri(:get, 'test_example2.txt', File.dirname(__FILE__) + '/fixtures/test_example.txt') | |
40 | + end | |
41 | + end | |
42 | + | |
43 | + def test_register_uri_with_port_and_check_with_port | |
44 | + FakeWeb.register_uri(:get, 'http://example.com:3000/', :body => 'foo') | |
45 | + assert FakeWeb.registered_uri?(:get, 'http://example.com:3000/') | |
46 | + end | |
47 | + | |
48 | + def test_register_uri_with_port_and_check_without_port | |
49 | + FakeWeb.register_uri(:get, 'http://example.com:3000/', :body => 'foo') | |
50 | + assert !FakeWeb.registered_uri?(:get, 'http://example.com/') | |
51 | + end | |
52 | + | |
53 | + def test_register_uri_with_default_port_for_http_and_check_without_port | |
54 | + FakeWeb.register_uri(:get, 'http://example.com:80/', :body => 'foo') | |
55 | + assert FakeWeb.registered_uri?(:get, 'http://example.com/') | |
56 | + end | |
57 | + | |
58 | + def test_register_uri_with_default_port_for_https_and_check_without_port | |
59 | + FakeWeb.register_uri(:get, 'https://example.com:443/', :body => 'foo') | |
60 | + assert FakeWeb.registered_uri?(:get, 'https://example.com/') | |
61 | + end | |
62 | + | |
63 | + def test_register_uri_with_no_port_for_http_and_check_with_default_port | |
64 | + FakeWeb.register_uri(:get, 'http://example.com/', :body => 'foo') | |
65 | + assert FakeWeb.registered_uri?(:get, 'http://example.com:80/') | |
66 | + end | |
67 | + | |
68 | + def test_register_uri_with_no_port_for_https_and_check_with_default_port | |
69 | + FakeWeb.register_uri(:get, 'https://example.com/', :body => 'foo') | |
70 | + assert FakeWeb.registered_uri?(:get, 'https://example.com:443/') | |
71 | + end | |
72 | + | |
73 | + def test_register_uri_with_no_port_for_https_and_check_with_443_on_http | |
74 | + FakeWeb.register_uri(:get, 'https://example.com/', :body => 'foo') | |
75 | + assert !FakeWeb.registered_uri?(:get, 'http://example.com:443/') | |
76 | + end | |
77 | + | |
78 | + def test_register_uri_with_no_port_for_http_and_check_with_80_on_https | |
79 | + FakeWeb.register_uri(:get, 'http://example.com/', :body => 'foo') | |
80 | + assert !FakeWeb.registered_uri?(:get, 'https://example.com:80/') | |
81 | + end | |
82 | + | |
83 | + def test_register_uri_for_any_method_explicitly | |
84 | + FakeWeb.register_uri(:any, "http://example.com/rpc_endpoint", :body => "OK") | |
85 | + assert FakeWeb.registered_uri?(:get, "http://example.com/rpc_endpoint") | |
86 | + assert FakeWeb.registered_uri?(:post, "http://example.com/rpc_endpoint") | |
87 | + assert FakeWeb.registered_uri?(:put, "http://example.com/rpc_endpoint") | |
88 | + assert FakeWeb.registered_uri?(:delete, "http://example.com/rpc_endpoint") | |
89 | + assert FakeWeb.registered_uri?(:any, "http://example.com/rpc_endpoint") | |
90 | + capture_stderr do # silence deprecation warning | |
91 | + assert FakeWeb.registered_uri?("http://example.com/rpc_endpoint") | |
92 | + end | |
93 | + end | |
94 | + | |
95 | + def test_register_uri_for_get_method_only | |
96 | + FakeWeb.register_uri(:get, "http://example.com/users", :body => "User list") | |
97 | + assert FakeWeb.registered_uri?(:get, "http://example.com/users") | |
98 | + assert !FakeWeb.registered_uri?(:post, "http://example.com/users") | |
99 | + assert !FakeWeb.registered_uri?(:put, "http://example.com/users") | |
100 | + assert !FakeWeb.registered_uri?(:delete, "http://example.com/users") | |
101 | + assert !FakeWeb.registered_uri?(:any, "http://example.com/users") | |
102 | + capture_stderr do # silence deprecation warning | |
103 | + assert !FakeWeb.registered_uri?("http://example.com/users") | |
104 | + end | |
105 | + end | |
106 | + | |
107 | + def test_response_for_with_registered_uri | |
108 | + FakeWeb.register_uri(:get, 'http://mock/test_example.txt', :body => File.dirname(__FILE__) + '/fixtures/test_example.txt') | |
109 | + assert_equal 'test example content', FakeWeb.response_for(:get, 'http://mock/test_example.txt').body | |
110 | + end | |
111 | + | |
112 | + def test_response_for_with_unknown_uri | |
113 | + assert_nil FakeWeb.response_for(:get, 'http://example.com/') | |
114 | + end | |
115 | + | |
116 | + def test_response_for_with_put_method | |
117 | + FakeWeb.register_uri(:put, "http://example.com", :body => "response") | |
118 | + assert_equal 'response', FakeWeb.response_for(:put, "http://example.com").body | |
119 | + end | |
120 | + | |
121 | + def test_response_for_with_any_method_explicitly | |
122 | + FakeWeb.register_uri(:any, "http://example.com", :body => "response") | |
123 | + assert_equal 'response', FakeWeb.response_for(:get, "http://example.com").body | |
124 | + assert_equal 'response', FakeWeb.response_for(:any, "http://example.com").body | |
125 | + end | |
126 | + | |
127 | + def test_content_for_registered_uri_with_port_and_request_with_port | |
128 | + FakeWeb.register_uri(:get, 'http://example.com:3000/', :body => 'test example content') | |
129 | + response = Net::HTTP.start('example.com', 3000) { |http| http.get('/') } | |
130 | + assert_equal 'test example content', response.body | |
131 | + end | |
132 | + | |
133 | + def test_content_for_registered_uri_with_default_port_for_http_and_request_without_port | |
134 | + FakeWeb.register_uri(:get, 'http://example.com:80/', :body => 'test example content') | |
135 | + response = Net::HTTP.start('example.com') { |http| http.get('/') } | |
136 | + assert_equal 'test example content', response.body | |
137 | + end | |
138 | + | |
139 | + def test_content_for_registered_uri_with_no_port_for_http_and_request_with_default_port | |
140 | + FakeWeb.register_uri(:get, 'http://example.com/', :body => 'test example content') | |
141 | + response = Net::HTTP.start('example.com', 80) { |http| http.get('/') } | |
142 | + assert_equal 'test example content', response.body | |
143 | + end | |
144 | + | |
145 | + def test_content_for_registered_uri_with_default_port_for_https_and_request_with_default_port | |
146 | + FakeWeb.register_uri(:get, 'https://example.com:443/', :body => 'test example content') | |
147 | + http = Net::HTTP.new('example.com', 443) | |
148 | + http.use_ssl = true | |
149 | + response = http.get('/') | |
150 | + assert_equal 'test example content', response.body | |
151 | + end | |
152 | + | |
153 | + def test_content_for_registered_uri_with_no_port_for_https_and_request_with_default_port | |
154 | + FakeWeb.register_uri(:get, 'https://example.com/', :body => 'test example content') | |
155 | + http = Net::HTTP.new('example.com', 443) | |
156 | + http.use_ssl = true | |
157 | + response = http.get('/') | |
158 | + assert_equal 'test example content', response.body | |
159 | + end | |
160 | + | |
161 | + def test_content_for_registered_uris_with_ports_on_same_domain_and_request_without_port | |
162 | + FakeWeb.register_uri(:get, 'http://example.com:3000/', :body => 'port 3000') | |
163 | + FakeWeb.register_uri(:get, 'http://example.com/', :body => 'port 80') | |
164 | + response = Net::HTTP.start('example.com') { |http| http.get('/') } | |
165 | + assert_equal 'port 80', response.body | |
166 | + end | |
167 | + | |
168 | + def test_content_for_registered_uris_with_ports_on_same_domain_and_request_with_port | |
169 | + FakeWeb.register_uri(:get, 'http://example.com:3000/', :body => 'port 3000') | |
170 | + FakeWeb.register_uri(:get, 'http://example.com/', :body => 'port 80') | |
171 | + response = Net::HTTP.start('example.com', 3000) { |http| http.get('/') } | |
172 | + assert_equal 'port 3000', response.body | |
173 | + end | |
174 | + | |
175 | + def test_content_for_registered_uri_with_get_method_only | |
176 | + FakeWeb.allow_net_connect = false | |
177 | + FakeWeb.register_uri(:get, "http://example.com/", :body => "test example content") | |
178 | + http = Net::HTTP.new('example.com') | |
179 | + assert_equal 'test example content', http.get('/').body | |
180 | + assert_raises(FakeWeb::NetConnectNotAllowedError) { http.post('/', nil) } | |
181 | + assert_raises(FakeWeb::NetConnectNotAllowedError) { http.put('/', nil) } | |
182 | + assert_raises(FakeWeb::NetConnectNotAllowedError) { http.delete('/') } | |
183 | + end | |
184 | + | |
185 | + def test_content_for_registered_uri_with_any_method_explicitly | |
186 | + FakeWeb.allow_net_connect = false | |
187 | + FakeWeb.register_uri(:any, "http://example.com/", :body => "test example content") | |
188 | + http = Net::HTTP.new('example.com') | |
189 | + assert_equal 'test example content', http.get('/').body | |
190 | + assert_equal 'test example content', http.post('/', nil).body | |
191 | + assert_equal 'test example content', http.put('/', nil).body | |
192 | + assert_equal 'test example content', http.delete('/').body | |
193 | + end | |
194 | + | |
195 | + def test_content_for_registered_uri_with_any_method_implicitly | |
196 | + FakeWeb.allow_net_connect = false | |
197 | + capture_stderr do # silence deprecation warning | |
198 | + FakeWeb.register_uri("http://example.com/", :body => "test example content") | |
199 | + end | |
200 | + | |
201 | + http = Net::HTTP.new('example.com') | |
202 | + assert_equal 'test example content', http.get('/').body | |
203 | + assert_equal 'test example content', http.post('/', nil).body | |
204 | + assert_equal 'test example content', http.put('/', nil).body | |
205 | + assert_equal 'test example content', http.delete('/').body | |
206 | + end | |
207 | + | |
208 | + def test_mock_request_with_block | |
209 | + FakeWeb.register_uri(:get, 'http://mock/test_example.txt', :body => File.dirname(__FILE__) + '/fixtures/test_example.txt') | |
210 | + response = Net::HTTP.start('mock') { |http| http.get('/test_example.txt') } | |
211 | + assert_equal 'test example content', response.body | |
212 | + end | |
213 | + | |
214 | + def test_request_with_registered_body_yields_the_response_body_to_a_request_block | |
215 | + FakeWeb.register_uri(:get, "http://example.com", :body => "content") | |
216 | + body = nil | |
217 | + Net::HTTP.start("example.com") do |http| | |
218 | + http.get("/") do |response_body| | |
219 | + body = response_body | |
220 | + end | |
221 | + end | |
222 | + assert_equal "content", body | |
223 | + end | |
224 | + | |
225 | + def test_request_with_registered_response_yields_the_response_body_to_a_request_block | |
226 | + fake_response = Net::HTTPOK.new('1.1', '200', 'OK') | |
227 | + fake_response.instance_variable_set(:@body, "content") | |
228 | + FakeWeb.register_uri(:get, 'http://example.com', :response => fake_response) | |
229 | + body = nil | |
230 | + Net::HTTP.start("example.com") do |http| | |
231 | + http.get("/") do |response_body| | |
232 | + body = response_body | |
233 | + end | |
234 | + end | |
235 | + assert_equal "content", body | |
236 | + end | |
237 | + | |
238 | + def test_mock_request_with_undocumented_full_uri_argument_style | |
239 | + FakeWeb.register_uri(:get, 'http://mock/test_example.txt', :body => File.dirname(__FILE__) + '/fixtures/test_example.txt') | |
240 | + response = Net::HTTP.start('mock') { |query| query.get('http://mock/test_example.txt') } | |
241 | + assert_equal 'test example content', response.body | |
242 | + end | |
243 | + | |
244 | + def test_mock_request_with_undocumented_full_uri_argument_style_and_query | |
245 | + FakeWeb.register_uri(:get, 'http://mock/test_example.txt?a=b', :body => 'test query content') | |
246 | + response = Net::HTTP.start('mock') { |query| query.get('http://mock/test_example.txt?a=b') } | |
247 | + assert_equal 'test query content', response.body | |
248 | + end | |
249 | + | |
250 | + def test_mock_post | |
251 | + FakeWeb.register_uri(:post, 'http://mock/test_example.txt', :body => File.dirname(__FILE__) + '/fixtures/test_example.txt') | |
252 | + response = Net::HTTP.start('mock') { |query| query.post('/test_example.txt', '') } | |
253 | + assert_equal 'test example content', response.body | |
254 | + end | |
255 | + | |
256 | + def test_mock_post_with_string_as_registered_uri | |
257 | + FakeWeb.register_uri(:post, 'http://mock/test_string.txt', :body => 'foo') | |
258 | + response = Net::HTTP.start('mock') { |query| query.post('/test_string.txt', '') } | |
259 | + assert_equal 'foo', response.body | |
260 | + end | |
261 | + | |
262 | + def test_mock_get_with_request_as_registered_uri | |
263 | + fake_response = Net::HTTPOK.new('1.1', '200', 'OK') | |
264 | + FakeWeb.register_uri(:get, 'http://mock/test_response', :response => fake_response) | |
265 | + response = Net::HTTP.start('mock') { |query| query.get('/test_response') } | |
266 | + assert_equal fake_response, response | |
267 | + end | |
268 | + | |
269 | + def test_mock_get_with_request_from_file_as_registered_uri | |
270 | + FakeWeb.register_uri(:get, 'http://www.google.com/', :response => File.dirname(__FILE__) + '/fixtures/google_response_without_transfer_encoding') | |
271 | + response = Net::HTTP.start('www.google.com') { |query| query.get('/') } | |
272 | + assert_equal '200', response.code | |
273 | + assert response.body.include?('<title>Google</title>') | |
274 | + end | |
275 | + | |
276 | + def test_mock_post_with_request_from_file_as_registered_uri | |
277 | + FakeWeb.register_uri(:post, 'http://www.google.com/', :response => File.dirname(__FILE__) + '/fixtures/google_response_without_transfer_encoding') | |
278 | + response = Net::HTTP.start('www.google.com') { |query| query.post('/', '') } | |
279 | + assert_equal "200", response.code | |
280 | + assert response.body.include?('<title>Google</title>') | |
281 | + end | |
282 | + | |
283 | + def test_proxy_request | |
284 | + FakeWeb.register_uri(:get, 'http://www.example.com/', :body => "hello world") | |
285 | + FakeWeb.register_uri(:get, 'http://your.proxy.host/', :body => "lala") | |
286 | + | |
287 | + response = nil | |
288 | + Net::HTTP::Proxy('your.proxy.host', 8080).start('www.example.com') do |http| | |
289 | + response = http.get('/') | |
290 | + end | |
291 | + assert_equal "hello world", response.body | |
292 | + end | |
293 | + | |
294 | + def test_https_request | |
295 | + FakeWeb.register_uri(:get, 'https://www.example.com/', :body => "Hello World") | |
296 | + http = Net::HTTP.new('www.example.com', 443) | |
297 | + http.use_ssl = true | |
298 | + response = http.get('/') | |
299 | + assert_equal "Hello World", response.body | |
300 | + end | |
301 | + | |
302 | + def test_register_unimplemented_response | |
303 | + FakeWeb.register_uri(:get, 'http://mock/unimplemented', :response => 1) | |
304 | + assert_raises StandardError do | |
305 | + Net::HTTP.start('mock') { |q| q.get('/unimplemented') } | |
306 | + end | |
307 | + end | |
308 | + | |
309 | + def test_real_http_request | |
310 | + FakeWeb.allow_net_connect = true | |
311 | + setup_expectations_for_real_apple_hot_news_request | |
312 | + | |
313 | + resp = nil | |
314 | + Net::HTTP.start('images.apple.com') do |query| | |
315 | + resp = query.get('/main/rss/hotnews/hotnews.rss') | |
316 | + end | |
317 | + assert resp.body.include?('Apple') | |
318 | + assert resp.body.include?('News') | |
319 | + end | |
320 | + | |
321 | + def test_real_http_request_with_undocumented_full_uri_argument_style | |
322 | + FakeWeb.allow_net_connect = true | |
323 | + setup_expectations_for_real_apple_hot_news_request(:path => 'http://images.apple.com/main/rss/hotnews/hotnews.rss') | |
324 | + | |
325 | + resp = nil | |
326 | + Net::HTTP.start('images.apple.com') do |query| | |
327 | + resp = query.get('http://images.apple.com/main/rss/hotnews/hotnews.rss') | |
328 | + end | |
329 | + assert resp.body.include?('Apple') | |
330 | + assert resp.body.include?('News') | |
331 | + end | |
332 | + | |
333 | + def test_real_https_request | |
334 | + FakeWeb.allow_net_connect = true | |
335 | + setup_expectations_for_real_apple_hot_news_request(:port => 443) | |
336 | + | |
337 | + http = Net::HTTP.new('images.apple.com', 443) | |
338 | + http.use_ssl = true | |
339 | + http.verify_mode = OpenSSL::SSL::VERIFY_NONE # silence certificate warning | |
340 | + response = http.get('/main/rss/hotnews/hotnews.rss') | |
341 | + assert response.body.include?('Apple') | |
342 | + assert response.body.include?('News') | |
343 | + end | |
344 | + | |
345 | + def test_real_request_on_same_domain_as_mock | |
346 | + FakeWeb.allow_net_connect = true | |
347 | + setup_expectations_for_real_apple_hot_news_request | |
348 | + | |
349 | + FakeWeb.register_uri(:get, 'http://images.apple.com/test_string.txt', :body => 'foo') | |
350 | + | |
351 | + resp = nil | |
352 | + Net::HTTP.start('images.apple.com') do |query| | |
353 | + resp = query.get('/main/rss/hotnews/hotnews.rss') | |
354 | + end | |
355 | + assert resp.body.include?('Apple') | |
356 | + assert resp.body.include?('News') | |
357 | + end | |
358 | + | |
359 | + def test_mock_request_on_real_domain | |
360 | + FakeWeb.register_uri(:get, 'http://images.apple.com/test_string.txt', :body => 'foo') | |
361 | + resp = nil | |
362 | + Net::HTTP.start('images.apple.com') do |query| | |
363 | + resp = query.get('/test_string.txt') | |
364 | + end | |
365 | + assert_equal 'foo', resp.body | |
366 | + end | |
367 | + | |
368 | + def test_mock_post_that_raises_exception | |
369 | + FakeWeb.register_uri(:post, 'http://mock/raising_exception.txt', :exception => StandardError) | |
370 | + assert_raises(StandardError) do | |
371 | + Net::HTTP.start('mock') do |query| | |
372 | + query.post('/raising_exception.txt', 'some data') | |
373 | + end | |
374 | + end | |
375 | + end | |
376 | + | |
377 | + def test_mock_post_that_raises_an_http_error | |
378 | + FakeWeb.register_uri(:post, 'http://mock/raising_exception.txt', :exception => Net::HTTPError) | |
379 | + assert_raises(Net::HTTPError) do | |
380 | + Net::HTTP.start('mock') do |query| | |
381 | + query.post('/raising_exception.txt', '') | |
382 | + end | |
383 | + end | |
384 | + end | |
385 | + | |
386 | + def test_raising_an_exception_that_requires_an_argument_to_instantiate | |
387 | + FakeWeb.register_uri(:get, "http://example.com/timeout.txt", :exception => Timeout::Error) | |
388 | + assert_raises(Timeout::Error) do | |
389 | + Net::HTTP.get(URI.parse("http://example.com/timeout.txt")) | |
390 | + end | |
391 | + end | |
392 | + | |
393 | + def test_mock_instance_syntax | |
394 | + FakeWeb.register_uri(:get, 'http://mock/test_example.txt', :body => File.dirname(__FILE__) + '/fixtures/test_example.txt') | |
395 | + response = nil | |
396 | + uri = URI.parse('http://mock/test_example.txt') | |
397 | + http = Net::HTTP.new(uri.host, uri.port) | |
398 | + response = http.start do | |
399 | + http.get(uri.path) | |
400 | + end | |
401 | + | |
402 | + assert_equal 'test example content', response.body | |
403 | + end | |
404 | + | |
405 | + def test_mock_via_nil_proxy | |
406 | + response = nil | |
407 | + proxy_address = nil | |
408 | + proxy_port = nil | |
409 | + FakeWeb.register_uri(:get, 'http://mock/test_example.txt', :body => File.dirname(__FILE__) + '/fixtures/test_example.txt') | |
410 | + uri = URI.parse('http://mock/test_example.txt') | |
411 | + http = Net::HTTP::Proxy(proxy_address, proxy_port).new( | |
412 | + uri.host, (uri.port or 80)) | |
413 | + response = http.start do | |
414 | + http.get(uri.path) | |
415 | + end | |
416 | + | |
417 | + assert_equal 'test example content', response.body | |
418 | + end | |
419 | + | |
420 | + def test_response_type | |
421 | + FakeWeb.register_uri(:get, 'http://mock/test_example.txt', :body => "test") | |
422 | + response = Net::HTTP.start('mock') { |http| http.get('/test_example.txt') } | |
423 | + assert_kind_of Net::HTTPSuccess, response | |
424 | + end | |
425 | + | |
426 | + def test_mock_request_that_raises_an_http_error_with_a_specific_status | |
427 | + FakeWeb.register_uri(:get, 'http://mock/raising_exception.txt', :exception => Net::HTTPError, :status => ['404', 'Not Found']) | |
428 | + exception = assert_raises(Net::HTTPError) do | |
429 | + Net::HTTP.start('mock') { |http| http.get('/raising_exception.txt') } | |
430 | + end | |
431 | + assert_equal '404', exception.response.code | |
432 | + assert_equal 'Not Found', exception.response.msg | |
433 | + end | |
434 | + | |
435 | + def test_mock_rotate_responses | |
436 | + FakeWeb.register_uri(:get, 'http://mock/multiple_test_example.txt', | |
437 | + [ {:body => File.dirname(__FILE__) + '/fixtures/test_example.txt', :times => 2}, | |
438 | + {:body => "thrice", :times => 3}, | |
439 | + {:body => "ever_more"} ]) | |
440 | + | |
441 | + uri = URI.parse('http://mock/multiple_test_example.txt') | |
442 | + 2.times { assert_equal 'test example content', Net::HTTP.get(uri) } | |
443 | + 3.times { assert_equal 'thrice', Net::HTTP.get(uri) } | |
444 | + 4.times { assert_equal 'ever_more', Net::HTTP.get(uri) } | |
445 | + end | |
446 | + | |
447 | + def test_mock_request_using_response_with_transfer_encoding_header_has_valid_transfer_encoding_header | |
448 | + FakeWeb.register_uri(:get, 'http://www.google.com/', :response => File.dirname(__FILE__) + '/fixtures/google_response_with_transfer_encoding') | |
449 | + response = Net::HTTP.start('www.google.com') { |query| query.get('/') } | |
450 | + assert_not_nil response['transfer-encoding'] | |
451 | + assert response['transfer-encoding'] == 'chunked' | |
452 | + end | |
453 | + | |
454 | + def test_mock_request_using_response_without_transfer_encoding_header_does_not_have_a_transfer_encoding_header | |
455 | + FakeWeb.register_uri(:get, 'http://www.google.com/', :response => File.dirname(__FILE__) + '/fixtures/google_response_without_transfer_encoding') | |
456 | + response = nil | |
457 | + response = Net::HTTP.start('www.google.com') { |query| query.get('/') } | |
458 | + assert !response.key?('transfer-encoding') | |
459 | + end | |
460 | + | |
461 | + def test_mock_request_using_response_from_curl_has_original_transfer_encoding_header | |
462 | + FakeWeb.register_uri(:get, 'http://www.google.com/', :response => File.dirname(__FILE__) + '/fixtures/google_response_from_curl') | |
463 | + response = Net::HTTP.start('www.google.com') { |query| query.get('/') } | |
464 | + assert_not_nil response['transfer-encoding'] | |
465 | + assert response['transfer-encoding'] == 'chunked' | |
466 | + end | |
467 | + | |
468 | + def test_txt_file_should_have_three_lines | |
469 | + FakeWeb.register_uri(:get, 'http://www.google.com/', :body => File.dirname(__FILE__) + '/fixtures/test_txt_file') | |
470 | + response = Net::HTTP.start('www.google.com') { |query| query.get('/') } | |
471 | + assert response.body.split(/\n/).size == 3, "response has #{response.body.split(/\n/).size} lines should have 3" | |
472 | + end | |
473 | + | |
474 | + def test_requiring_fakeweb_instead_of_fake_web | |
475 | + require "fakeweb" | |
476 | + end | |
477 | + | |
478 | + def test_registering_with_string_containing_null_byte | |
479 | + # Regression test for File.exists? raising an ArgumentError ("string | |
480 | + # contains null byte") since :response first tries to find by filename. | |
481 | + # The string should be treated as a response body, instead, and an | |
482 | + # EOFError is raised when the byte is encountered. | |
483 | + FakeWeb.register_uri(:get, "http://example.com", :response => "test\0test") | |
484 | + assert_raise EOFError do | |
485 | + Net::HTTP.get(URI.parse("http://example.com")) | |
486 | + end | |
487 | + | |
488 | + FakeWeb.register_uri(:get, "http://example.com", :body => "test\0test") | |
489 | + body = Net::HTTP.get(URI.parse("http://example.com")) | |
490 | + assert_equal "test\0test", body | |
491 | + end | |
492 | + | |
493 | + def test_registering_with_string_that_is_a_directory_name | |
494 | + # Similar to above, but for Errno::EISDIR being raised since File.exists? | |
495 | + # returns true for directories | |
496 | + FakeWeb.register_uri(:get, "http://example.com", :response => File.dirname(__FILE__)) | |
497 | + assert_raise EOFError do | |
498 | + body = Net::HTTP.get(URI.parse("http://example.com")) | |
499 | + end | |
500 | + | |
501 | + FakeWeb.register_uri(:get, "http://example.com", :body => File.dirname(__FILE__)) | |
502 | + body = Net::HTTP.get(URI.parse("http://example.com")) | |
503 | + assert_equal File.dirname(__FILE__), body | |
504 | + end | |
505 | + | |
506 | + def test_http_version_from_string_response | |
507 | + FakeWeb.register_uri(:get, "http://example.com", :body => "example") | |
508 | + response = Net::HTTP.start("example.com") { |http| http.get("/") } | |
509 | + assert_equal "1.0", response.http_version | |
510 | + end | |
511 | + | |
512 | + def test_http_version_from_file_response | |
513 | + FakeWeb.register_uri(:get, "http://example.com", :body => File.dirname(__FILE__) + '/fixtures/test_example.txt') | |
514 | + response = Net::HTTP.start("example.com") { |http| http.get("/") } | |
515 | + assert_equal "1.0", response.http_version | |
516 | + end | |
517 | + | |
518 | +end | ... | ... |
vendor/gems/fakeweb-1.2.5/test/test_fake_web_open_uri.rb
0 → 100644
... | ... | @@ -0,0 +1,58 @@ |
1 | +require File.join(File.dirname(__FILE__), "test_helper") | |
2 | + | |
3 | +class TestFakeWebOpenURI < Test::Unit::TestCase | |
4 | + | |
5 | + def test_content_for_registered_uri | |
6 | + FakeWeb.register_uri(:get, 'http://mock/test_example.txt', :body => File.dirname(__FILE__) + '/fixtures/test_example.txt') | |
7 | + assert_equal 'test example content', FakeWeb.response_for(:get, 'http://mock/test_example.txt').body | |
8 | + end | |
9 | + | |
10 | + def test_mock_open | |
11 | + FakeWeb.register_uri(:get, 'http://mock/test_example.txt', :body => File.dirname(__FILE__) + '/fixtures/test_example.txt') | |
12 | + assert_equal 'test example content', open('http://mock/test_example.txt').read | |
13 | + end | |
14 | + | |
15 | + def test_mock_open_with_string_as_registered_uri | |
16 | + FakeWeb.register_uri(:get, 'http://mock/test_string.txt', :body => 'foo') | |
17 | + assert_equal 'foo', open('http://mock/test_string.txt').string | |
18 | + end | |
19 | + | |
20 | + def test_real_open | |
21 | + FakeWeb.allow_net_connect = true | |
22 | + setup_expectations_for_real_apple_hot_news_request | |
23 | + resp = open('http://images.apple.com/main/rss/hotnews/hotnews.rss') | |
24 | + assert_equal "200", resp.status.first | |
25 | + body = resp.read | |
26 | + assert body.include?('Apple') | |
27 | + assert body.include?('News') | |
28 | + end | |
29 | + | |
30 | + def test_mock_open_that_raises_exception | |
31 | + FakeWeb.register_uri(:get, 'http://mock/raising_exception.txt', :exception => StandardError) | |
32 | + assert_raises(StandardError) do | |
33 | + open('http://mock/raising_exception.txt') | |
34 | + end | |
35 | + end | |
36 | + | |
37 | + def test_mock_open_that_raises_an_http_error | |
38 | + FakeWeb.register_uri(:get, 'http://mock/raising_exception.txt', :exception => OpenURI::HTTPError) | |
39 | + assert_raises(OpenURI::HTTPError) do | |
40 | + open('http://mock/raising_exception.txt') | |
41 | + end | |
42 | + end | |
43 | + | |
44 | + def test_mock_open_that_raises_an_http_error_with_a_specific_status | |
45 | + FakeWeb.register_uri(:get, 'http://mock/raising_exception.txt', :exception => OpenURI::HTTPError, :status => ['123', 'jodel']) | |
46 | + exception = assert_raises(OpenURI::HTTPError) do | |
47 | + open('http://mock/raising_exception.txt') | |
48 | + end | |
49 | + assert_equal '123', exception.io.code | |
50 | + assert_equal 'jodel', exception.io.message | |
51 | + end | |
52 | + | |
53 | + def test_mock_open_with_block | |
54 | + FakeWeb.register_uri(:get, 'http://mock/test_example.txt', :body => File.dirname(__FILE__) + '/fixtures/test_example.txt') | |
55 | + body = open('http://mock/test_example.txt') { |f| f.readlines } | |
56 | + assert_equal 'test example content', body.first | |
57 | + end | |
58 | +end | ... | ... |
... | ... | @@ -0,0 +1,74 @@ |
1 | +$:.unshift "#{File.dirname(__FILE__)}/../lib" | |
2 | + | |
3 | +require 'test/unit' | |
4 | +require 'open-uri' | |
5 | +require 'fake_web' | |
6 | +require 'rubygems' | |
7 | +require 'mocha' | |
8 | + | |
9 | + | |
10 | +# Give all tests a common setup and teardown that prevents shared state | |
11 | +class Test::Unit::TestCase | |
12 | + def setup | |
13 | + FakeWeb.clean_registry | |
14 | + @original_allow_net_connect = FakeWeb.allow_net_connect? | |
15 | + FakeWeb.allow_net_connect = false | |
16 | + end | |
17 | + | |
18 | + def teardown | |
19 | + FakeWeb.allow_net_connect = @original_allow_net_connect | |
20 | + end | |
21 | +end | |
22 | + | |
23 | + | |
24 | +module FakeWebTestHelper | |
25 | + | |
26 | + def capture_stderr | |
27 | + $stderr = StringIO.new | |
28 | + yield | |
29 | + $stderr.rewind && $stderr.read | |
30 | + ensure | |
31 | + $stderr = STDERR | |
32 | + end | |
33 | + | |
34 | + # Sets several expectations (using Mocha) that a real HTTP request makes it | |
35 | + # past FakeWeb to the socket layer. You can use this when you need to check | |
36 | + # that a request isn't handled by FakeWeb. | |
37 | + def setup_expectations_for_real_request(options = {}) | |
38 | + # Socket handling | |
39 | + if options[:port] == 443 | |
40 | + socket = mock("SSLSocket") | |
41 | + OpenSSL::SSL::SSLSocket.expects(:===).with(socket).returns(true).at_least_once | |
42 | + OpenSSL::SSL::SSLSocket.expects(:new).with(socket, instance_of(OpenSSL::SSL::SSLContext)).returns(socket).at_least_once | |
43 | + socket.stubs(:sync_close=).returns(true) | |
44 | + socket.expects(:connect).with().at_least_once | |
45 | + else | |
46 | + socket = mock("TCPSocket") | |
47 | + Socket.expects(:===).with(socket).returns(true) | |
48 | + end | |
49 | + | |
50 | + TCPSocket.expects(:open).with(options[:host], options[:port]).returns(socket).at_least_once | |
51 | + socket.stubs(:closed?).returns(false) | |
52 | + socket.stubs(:close).returns(true) | |
53 | + | |
54 | + # Request/response handling | |
55 | + request_parts = ["#{options[:method]} #{options[:path]} HTTP/1.1", "Host: #{options[:host]}"] | |
56 | + socket.expects(:write).with(all_of(includes(request_parts[0]), includes(request_parts[1]))).returns(100) | |
57 | + | |
58 | + socket.expects(:sysread).at_least_once.returns("HTTP/1.1 #{options[:response_code]} #{options[:response_message]}\nContent-Length: #{options[:response_body].length}\n\n#{options[:response_body]}").then.raises(EOFError) | |
59 | + end | |
60 | + | |
61 | + | |
62 | + # A helper that calls #setup_expectations_for_real_request for you, using | |
63 | + # defaults for our commonly used test request to images.apple.com. | |
64 | + def setup_expectations_for_real_apple_hot_news_request(options = {}) | |
65 | + defaults = { :host => "images.apple.com", :port => 80, :method => "GET", | |
66 | + :path => "/main/rss/hotnews/hotnews.rss", | |
67 | + :response_code => 200, :response_message => "OK", | |
68 | + :response_body => "<title>Apple Hot News</title>" } | |
69 | + setup_expectations_for_real_request(defaults.merge(options)) | |
70 | + end | |
71 | + | |
72 | +end | |
73 | + | |
74 | +Test::Unit::TestCase.send(:include, FakeWebTestHelper) | ... | ... |
... | ... | @@ -0,0 +1,25 @@ |
1 | +require File.join(File.dirname(__FILE__), "test_helper") | |
2 | + | |
3 | +class TestMissingOpenURI < Test::Unit::TestCase | |
4 | + | |
5 | + def setup | |
6 | + super | |
7 | + @saved_open_uri = OpenURI | |
8 | + Object.send(:remove_const, :OpenURI) | |
9 | + end | |
10 | + | |
11 | + def teardown | |
12 | + super | |
13 | + Object.const_set(:OpenURI, @saved_open_uri) | |
14 | + end | |
15 | + | |
16 | + | |
17 | + def test_register_using_exception_without_open_uri | |
18 | + # regression test for Responder needing OpenURI::HTTPError to be defined | |
19 | + FakeWeb.register_uri(:get, "http://example.com/", :exception => StandardError) | |
20 | + assert_raises(StandardError) do | |
21 | + Net::HTTP.start("example.com") { |http| http.get("/") } | |
22 | + end | |
23 | + end | |
24 | + | |
25 | +end | ... | ... |
... | ... | @@ -0,0 +1,51 @@ |
1 | +require File.join(File.dirname(__FILE__), "test_helper") | |
2 | + | |
3 | +class TestPrecedence < Test::Unit::TestCase | |
4 | + | |
5 | + def test_matching_get_strings_have_precedence_over_matching_get_regexes | |
6 | + FakeWeb.register_uri(:get, "http://example.com/test", :body => "string") | |
7 | + FakeWeb.register_uri(:get, %r|http://example\.com/test|, :body => "regex") | |
8 | + response = Net::HTTP.start("example.com") { |query| query.get('/test') } | |
9 | + assert_equal "string", response.body | |
10 | + end | |
11 | + | |
12 | + def test_matching_any_strings_have_precedence_over_matching_any_regexes | |
13 | + FakeWeb.register_uri(:any, "http://example.com/test", :body => "string") | |
14 | + FakeWeb.register_uri(:any, %r|http://example\.com/test|, :body => "regex") | |
15 | + response = Net::HTTP.start("example.com") { |query| query.get('/test') } | |
16 | + assert_equal "string", response.body | |
17 | + end | |
18 | + | |
19 | + def test_matching_get_strings_have_precedence_over_matching_any_strings | |
20 | + FakeWeb.register_uri(:get, "http://example.com/test", :body => "get method") | |
21 | + FakeWeb.register_uri(:any, "http://example.com/test", :body => "any method") | |
22 | + response = Net::HTTP.start("example.com") { |query| query.get('/test') } | |
23 | + assert_equal "get method", response.body | |
24 | + | |
25 | + # registration order should not matter | |
26 | + FakeWeb.register_uri(:any, "http://example.com/test2", :body => "any method") | |
27 | + FakeWeb.register_uri(:get, "http://example.com/test2", :body => "get method") | |
28 | + response = Net::HTTP.start("example.com") { |query| query.get('/test2') } | |
29 | + assert_equal "get method", response.body | |
30 | + end | |
31 | + | |
32 | + def test_matching_any_strings_have_precedence_over_matching_get_regexes | |
33 | + FakeWeb.register_uri(:any, "http://example.com/test", :body => "any string") | |
34 | + FakeWeb.register_uri(:get, %r|http://example\.com/test|, :body => "get regex") | |
35 | + response = Net::HTTP.start("example.com") { |query| query.get('/test') } | |
36 | + assert_equal "any string", response.body | |
37 | + end | |
38 | + | |
39 | + def test_registered_strings_and_uris_are_equivalent_so_second_takes_precedence | |
40 | + FakeWeb.register_uri(:get, "http://example.com/test", :body => "string") | |
41 | + FakeWeb.register_uri(:get, URI.parse("http://example.com/test"), :body => "uri") | |
42 | + response = Net::HTTP.start("example.com") { |query| query.get('/test') } | |
43 | + assert_equal "uri", response.body | |
44 | + | |
45 | + FakeWeb.register_uri(:get, URI.parse("http://example.com/test2"), :body => "uri") | |
46 | + FakeWeb.register_uri(:get, "http://example.com/test2", :body => "string") | |
47 | + response = Net::HTTP.start("example.com") { |query| query.get('/test2') } | |
48 | + assert_equal "string", response.body | |
49 | + end | |
50 | + | |
51 | +end | ... | ... |
... | ... | @@ -0,0 +1,45 @@ |
1 | +require File.join(File.dirname(__FILE__), "test_helper") | |
2 | + | |
3 | +class TestFakeWebQueryString < Test::Unit::TestCase | |
4 | + | |
5 | + def test_register_uri_string_with_query_params | |
6 | + FakeWeb.register_uri(:get, 'http://example.com/?a=1&b=1', :body => 'foo') | |
7 | + assert FakeWeb.registered_uri?(:get, 'http://example.com/?a=1&b=1') | |
8 | + | |
9 | + FakeWeb.register_uri(:post, URI.parse("http://example.org/?a=1&b=1"), :body => "foo") | |
10 | + assert FakeWeb.registered_uri?(:post, "http://example.org/?a=1&b=1") | |
11 | + end | |
12 | + | |
13 | + def test_register_uri_with_query_params_and_check_in_different_order | |
14 | + FakeWeb.register_uri(:get, 'http://example.com/?a=1&b=1', :body => 'foo') | |
15 | + assert FakeWeb.registered_uri?(:get, 'http://example.com/?b=1&a=1') | |
16 | + | |
17 | + FakeWeb.register_uri(:post, URI.parse('http://example.org/?a=1&b=1'), :body => 'foo') | |
18 | + assert FakeWeb.registered_uri?(:post, 'http://example.org/?b=1&a=1') | |
19 | + end | |
20 | + | |
21 | + def test_registered_uri_gets_recognized_with_empty_query_params | |
22 | + FakeWeb.register_uri(:get, 'http://example.com/', :body => 'foo') | |
23 | + assert FakeWeb.registered_uri?(:get, 'http://example.com/?') | |
24 | + | |
25 | + FakeWeb.register_uri(:post, URI.parse('http://example.org/'), :body => 'foo') | |
26 | + assert FakeWeb.registered_uri?(:post, 'http://example.org/?') | |
27 | + end | |
28 | + | |
29 | + def test_register_uri_with_empty_query_params_and_check_with_none | |
30 | + FakeWeb.register_uri(:get, 'http://example.com/?', :body => 'foo') | |
31 | + assert FakeWeb.registered_uri?(:get, 'http://example.com/') | |
32 | + | |
33 | + FakeWeb.register_uri(:post, URI.parse('http://example.org/?'), :body => 'foo') | |
34 | + assert FakeWeb.registered_uri?(:post, 'http://example.org/') | |
35 | + end | |
36 | + | |
37 | + def test_registry_sort_query_params | |
38 | + assert_equal "a=1&b=2", FakeWeb::Registry.instance.send(:sort_query_params, "b=2&a=1") | |
39 | + end | |
40 | + | |
41 | + def test_registry_sort_query_params_sorts_by_value_if_keys_collide | |
42 | + assert_equal "a=1&a=2&b=2", FakeWeb::Registry.instance.send(:sort_query_params, "a=2&b=2&a=1") | |
43 | + end | |
44 | + | |
45 | +end | ... | ... |
... | ... | @@ -0,0 +1,103 @@ |
1 | +require File.join(File.dirname(__FILE__), "test_helper") | |
2 | + | |
3 | +class TestRegexes < Test::Unit::TestCase | |
4 | + | |
5 | + def test_registered_uri_with_pattern | |
6 | + FakeWeb.register_uri(:get, %r|http://example.com/test_example/\d+|, :body => "example") | |
7 | + assert FakeWeb.registered_uri?(:get, "http://example.com/test_example/25") | |
8 | + assert !FakeWeb.registered_uri?(:get, "http://example.com/test_example/abc") | |
9 | + end | |
10 | + | |
11 | + def test_response_for_with_matching_registered_uri | |
12 | + FakeWeb.register_uri(:get, %r|http://www.google.com|, :body => "Welcome to Google!") | |
13 | + assert_equal "Welcome to Google!", FakeWeb.response_for(:get, "http://www.google.com").body | |
14 | + end | |
15 | + | |
16 | + def test_response_for_with_matching_registered_uri_and_get_method_matching_to_any_method | |
17 | + FakeWeb.register_uri(:any, %r|http://www.example.com|, :body => "example") | |
18 | + assert_equal "example", FakeWeb.response_for(:get, "http://www.example.com").body | |
19 | + end | |
20 | + | |
21 | + def test_registered_uri_with_authentication_and_pattern | |
22 | + FakeWeb.register_uri(:get, %r|http://user:pass@mock/example\.\w+|i, :body => "example") | |
23 | + assert FakeWeb.registered_uri?(:get, 'http://user:pass@mock/example.txt') | |
24 | + end | |
25 | + | |
26 | + def test_registered_uri_with_authentication_and_pattern_handles_case_insensitivity | |
27 | + FakeWeb.register_uri(:get, %r|http://user:pass@mock/example\.\w+|i, :body => "example") | |
28 | + assert FakeWeb.registered_uri?(:get, 'http://uSeR:PAss@mock/example.txt') | |
29 | + end | |
30 | + | |
31 | + def test_request_with_authentication_and_pattern_handles_case_insensitivity | |
32 | + FakeWeb.register_uri(:get, %r|http://user:pass@mock/example\.\w+|i, :body => "example") | |
33 | + http = Net::HTTP.new('mock', 80) | |
34 | + req = Net::HTTP::Get.new('/example.txt') | |
35 | + req.basic_auth 'uSeR', 'PAss' | |
36 | + assert_equal "example", http.request(req).body | |
37 | + end | |
38 | + | |
39 | + def test_requesting_a_uri_that_matches_two_registered_regexes_raises_an_error | |
40 | + FakeWeb.register_uri(:get, %r|http://example\.com/|, :body => "first") | |
41 | + FakeWeb.register_uri(:get, %r|http://example\.com/a|, :body => "second") | |
42 | + assert_raise FakeWeb::MultipleMatchingRegexpsError do | |
43 | + Net::HTTP.start("example.com") { |query| query.get('/a') } | |
44 | + end | |
45 | + end | |
46 | + | |
47 | + def test_requesting_a_uri_that_matches_two_registered_regexes_raises_an_error_including_request_info | |
48 | + FakeWeb.register_uri(:get, %r|http://example\.com/|, :body => "first") | |
49 | + FakeWeb.register_uri(:get, %r|http://example\.com/a|, :body => "second") | |
50 | + begin | |
51 | + Net::HTTP.start("example.com") { |query| query.get('/a') } | |
52 | + rescue FakeWeb::MultipleMatchingRegexpsError => exception | |
53 | + end | |
54 | + assert exception.message.include?("GET http://example.com/a") | |
55 | + end | |
56 | + | |
57 | + def test_registry_does_not_find_using_mismatched_protocols_or_ports_when_registered_with_both | |
58 | + FakeWeb.register_uri(:get, %r|http://www.example.com:80|, :body => "example") | |
59 | + assert !FakeWeb.registered_uri?(:get, "https://www.example.com:80") | |
60 | + assert !FakeWeb.registered_uri?(:get, "http://www.example.com:443") | |
61 | + end | |
62 | + | |
63 | + def test_registry_only_finds_using_default_port_when_registered_without_if_protocol_matches | |
64 | + FakeWeb.register_uri(:get, %r|http://www.example.com/test|, :body => "example") | |
65 | + assert FakeWeb.registered_uri?(:get, "http://www.example.com:80/test") | |
66 | + assert !FakeWeb.registered_uri?(:get, "http://www.example.com:443/test") | |
67 | + assert !FakeWeb.registered_uri?(:get, "https://www.example.com:443/test") | |
68 | + FakeWeb.register_uri(:get, %r|https://www.example.org/test|, :body => "example") | |
69 | + assert FakeWeb.registered_uri?(:get, "https://www.example.org:443/test") | |
70 | + assert !FakeWeb.registered_uri?(:get, "https://www.example.org:80/test") | |
71 | + assert !FakeWeb.registered_uri?(:get, "http://www.example.org:80/test") | |
72 | + end | |
73 | + | |
74 | + def test_registry_matches_using_mismatched_port_when_registered_without | |
75 | + FakeWeb.register_uri(:get, %r|http://www.example.com|, :body => "example") | |
76 | + assert FakeWeb.registered_uri?(:get, "http://www.example.com:80") | |
77 | + assert FakeWeb.registered_uri?(:get, "http://www.example.com:443") | |
78 | + assert FakeWeb.registered_uri?(:get, "http://www.example.com:12345") | |
79 | + assert !FakeWeb.registered_uri?(:get, "https://www.example.com:443") | |
80 | + assert !FakeWeb.registered_uri?(:get, "https://www.example.com") | |
81 | + end | |
82 | + | |
83 | + def test_registry_matches_using_any_protocol_and_port_when_registered_without_protocol_or_port | |
84 | + FakeWeb.register_uri(:get, %r|www.example.com|, :body => "example") | |
85 | + assert FakeWeb.registered_uri?(:get, "http://www.example.com") | |
86 | + assert FakeWeb.registered_uri?(:get, "http://www.example.com:80") | |
87 | + assert FakeWeb.registered_uri?(:get, "http://www.example.com:443") | |
88 | + assert FakeWeb.registered_uri?(:get, "https://www.example.com") | |
89 | + assert FakeWeb.registered_uri?(:get, "https://www.example.com:80") | |
90 | + assert FakeWeb.registered_uri?(:get, "https://www.example.com:443") | |
91 | + end | |
92 | + | |
93 | + def test_registry_matches_with_query_params | |
94 | + FakeWeb.register_uri(:get, %r[example.com/list\?(.*&|)important=1], :body => "example") | |
95 | + assert FakeWeb.registered_uri?(:get, "http://example.com/list?hash=123&important=1&unimportant=2") | |
96 | + assert FakeWeb.registered_uri?(:get, "http://example.com/list?hash=123&important=12&unimportant=2") | |
97 | + assert FakeWeb.registered_uri?(:get, "http://example.com/list?important=1&unimportant=2") | |
98 | + assert !FakeWeb.registered_uri?(:get, "http://example.com/list?important=2") | |
99 | + assert !FakeWeb.registered_uri?(:get, "http://example.com/list?important=2&unimportant=1") | |
100 | + assert !FakeWeb.registered_uri?(:get, "http://example.com/list?hash=123&important=2&unimportant=1") | |
101 | + assert !FakeWeb.registered_uri?(:get, "http://example.com/list?notimportant=1&unimportant=1") | |
102 | + end | |
103 | +end | ... | ... |
... | ... | @@ -0,0 +1,67 @@ |
1 | +require File.join(File.dirname(__FILE__), "test_helper") | |
2 | + | |
3 | +class TestResponseHeaders < Test::Unit::TestCase | |
4 | + | |
5 | + def test_content_type_when_registering_with_string_and_content_type_header | |
6 | + FakeWeb.register_uri(:get, "http://example.com/users.json", :body => '[{"username": "chrisk"}]', :content_type => "application/json") | |
7 | + response = Net::HTTP.start("example.com") { |query| query.get("/users.json") } | |
8 | + assert_equal '[{"username": "chrisk"}]', response.body | |
9 | + assert_equal "application/json", response['Content-Type'] | |
10 | + end | |
11 | + | |
12 | + def test_content_type_when_registering_with_string_only | |
13 | + FakeWeb.register_uri(:get, "http://example.com/users.json", :body => '[{"username": "chrisk"}]') | |
14 | + response = Net::HTTP.start("example.com") { |query| query.get("/users.json") } | |
15 | + assert_equal '[{"username": "chrisk"}]', response.body | |
16 | + assert_nil response['Content-Type'] | |
17 | + end | |
18 | + | |
19 | + def test_cookies_when_registering_with_file_and_set_cookie_header | |
20 | + FakeWeb.register_uri(:get, "http://example.com/", :body => File.dirname(__FILE__) + '/fixtures/test_example.txt', | |
21 | + :set_cookie => "user_id=1; example=yes") | |
22 | + response = Net::HTTP.start("example.com") { |query| query.get("/") } | |
23 | + assert_equal "test example content", response.body | |
24 | + assert_equal "user_id=1; example=yes", response['Set-Cookie'] | |
25 | + end | |
26 | + | |
27 | + def test_registering_with_baked_response_ignores_header_options | |
28 | + fake_response = Net::HTTPOK.new('1.1', '200', 'OK') | |
29 | + fake_response["Server"] = "Apache/1.3.27 (Unix)" | |
30 | + FakeWeb.register_uri(:get, "http://example.com/", :response => fake_response, | |
31 | + :server => "FakeWeb/1.2.3 (Ruby)") | |
32 | + response = Net::HTTP.start("example.com") { |query| query.get("/") } | |
33 | + assert_equal "200", response.code | |
34 | + assert_equal "OK", response.message | |
35 | + assert_equal "Apache/1.3.27 (Unix)", response["Server"] | |
36 | + end | |
37 | + | |
38 | + def test_headers_are_rotated_when_registering_with_response_rotation | |
39 | + FakeWeb.register_uri(:get, "http://example.com", | |
40 | + [{:body => 'test1', :expires => "Thu, 14 Jun 2009 16:00:00 GMT", | |
41 | + :content_type => "text/plain"}, | |
42 | + {:body => 'test2', :expires => "Thu, 14 Jun 2009 16:00:01 GMT"}]) | |
43 | + | |
44 | + first_response = second_response = nil | |
45 | + Net::HTTP.start("example.com") do |query| | |
46 | + first_response = query.get("/") | |
47 | + second_response = query.get("/") | |
48 | + end | |
49 | + assert_equal 'test1', first_response.body | |
50 | + assert_equal "Thu, 14 Jun 2009 16:00:00 GMT", first_response['Expires'] | |
51 | + assert_equal "text/plain", first_response['Content-Type'] | |
52 | + assert_equal 'test2', second_response.body | |
53 | + assert_equal "Thu, 14 Jun 2009 16:00:01 GMT", second_response['Expires'] | |
54 | + assert_nil second_response['Content-Type'] | |
55 | + end | |
56 | + | |
57 | + def test_registering_with_status_option_and_response_headers | |
58 | + FakeWeb.register_uri(:get, "http://example.com", :status => ["301", "Moved Permanently"], | |
59 | + :location => "http://www.example.com") | |
60 | + | |
61 | + response = Net::HTTP.start("example.com") { |query| query.get("/") } | |
62 | + assert_equal "301", response.code | |
63 | + assert_equal "Moved Permanently", response.message | |
64 | + assert_equal "http://www.example.com", response["Location"] | |
65 | + end | |
66 | + | |
67 | +end | ... | ... |
... | ... | @@ -0,0 +1,53 @@ |
1 | +require File.join(File.dirname(__FILE__), "test_helper") | |
2 | + | |
3 | +class TestFakeWebTrailingSlashes < Test::Unit::TestCase | |
4 | + | |
5 | + def test_registering_root_without_slash_and_ask_predicate_method_with_slash | |
6 | + FakeWeb.register_uri(:get, "http://www.example.com", :body => "root") | |
7 | + assert FakeWeb.registered_uri?(:get, "http://www.example.com/") | |
8 | + end | |
9 | + | |
10 | + def test_registering_root_without_slash_and_request | |
11 | + FakeWeb.register_uri(:get, "http://www.example.com", :body => "root") | |
12 | + response = Net::HTTP.start("www.example.com") { |query| query.get('/') } | |
13 | + assert_equal "root", response.body | |
14 | + end | |
15 | + | |
16 | + def test_registering_root_with_slash_and_ask_predicate_method_without_slash | |
17 | + FakeWeb.register_uri(:get, "http://www.example.com/", :body => "root") | |
18 | + assert FakeWeb.registered_uri?(:get, "http://www.example.com") | |
19 | + end | |
20 | + | |
21 | + def test_registering_root_with_slash_and_request | |
22 | + FakeWeb.register_uri(:get, "http://www.example.com/", :body => "root") | |
23 | + response = Net::HTTP.start("www.example.com") { |query| query.get('/') } | |
24 | + assert_equal "root", response.body | |
25 | + end | |
26 | + | |
27 | + def test_registering_path_without_slash_and_ask_predicate_method_with_slash | |
28 | + FakeWeb.register_uri(:get, "http://www.example.com/users", :body => "User list") | |
29 | + assert !FakeWeb.registered_uri?(:get, "http://www.example.com/users/") | |
30 | + end | |
31 | + | |
32 | + def test_registering_path_without_slash_and_request_with_slash | |
33 | + FakeWeb.allow_net_connect = false | |
34 | + FakeWeb.register_uri(:get, "http://www.example.com/users", :body => "User list") | |
35 | + assert_raise FakeWeb::NetConnectNotAllowedError do | |
36 | + response = Net::HTTP.start("www.example.com") { |query| query.get('/users/') } | |
37 | + end | |
38 | + end | |
39 | + | |
40 | + def test_registering_path_with_slash_and_ask_predicate_method_without_slash | |
41 | + FakeWeb.register_uri(:get, "http://www.example.com/users/", :body => "User list") | |
42 | + assert !FakeWeb.registered_uri?(:get, "http://www.example.com/users") | |
43 | + end | |
44 | + | |
45 | + def test_registering_path_with_slash_and_request_without_slash | |
46 | + FakeWeb.allow_net_connect = false | |
47 | + FakeWeb.register_uri(:get, "http://www.example.com/users/", :body => "User list") | |
48 | + assert_raise FakeWeb::NetConnectNotAllowedError do | |
49 | + response = Net::HTTP.start("www.example.com") { |query| query.get('/users') } | |
50 | + end | |
51 | + end | |
52 | + | |
53 | +end | ... | ... |
... | ... | @@ -0,0 +1,70 @@ |
1 | +require File.join(File.dirname(__FILE__), "test_helper") | |
2 | + | |
3 | +class TestUtility < Test::Unit::TestCase | |
4 | + | |
5 | + def test_decode_userinfo_from_header_handles_basic_auth | |
6 | + authorization_header = "Basic dXNlcm5hbWU6c2VjcmV0" | |
7 | + userinfo = FakeWeb::Utility.decode_userinfo_from_header(authorization_header) | |
8 | + assert_equal "username:secret", userinfo | |
9 | + end | |
10 | + | |
11 | + def test_encode_unsafe_chars_in_userinfo_does_not_encode_userinfo_safe_punctuation | |
12 | + userinfo = "user;&=+$,:secret" | |
13 | + assert_equal userinfo, FakeWeb::Utility.encode_unsafe_chars_in_userinfo(userinfo) | |
14 | + end | |
15 | + | |
16 | + def test_encode_unsafe_chars_in_userinfo_does_not_encode_rfc_3986_unreserved_characters | |
17 | + userinfo = "-_.!~*'()abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789:secret" | |
18 | + assert_equal userinfo, FakeWeb::Utility.encode_unsafe_chars_in_userinfo(userinfo) | |
19 | + end | |
20 | + | |
21 | + def test_encode_unsafe_chars_in_userinfo_does_encode_other_characters | |
22 | + userinfo, safe_userinfo = 'us#rn@me:sec//ret?"', 'us%23rn%40me:sec%2F%2Fret%3F%22' | |
23 | + assert_equal safe_userinfo, FakeWeb::Utility.encode_unsafe_chars_in_userinfo(userinfo) | |
24 | + end | |
25 | + | |
26 | + def test_strip_default_port_from_uri_strips_80_from_http_with_path | |
27 | + uri = "http://example.com:80/foo/bar" | |
28 | + stripped_uri = FakeWeb::Utility.strip_default_port_from_uri(uri) | |
29 | + assert_equal "http://example.com/foo/bar", stripped_uri | |
30 | + end | |
31 | + | |
32 | + def test_strip_default_port_from_uri_strips_80_from_http_without_path | |
33 | + uri = "http://example.com:80" | |
34 | + stripped_uri = FakeWeb::Utility.strip_default_port_from_uri(uri) | |
35 | + assert_equal "http://example.com", stripped_uri | |
36 | + end | |
37 | + | |
38 | + def test_strip_default_port_from_uri_strips_443_from_https_without_path | |
39 | + uri = "https://example.com:443" | |
40 | + stripped_uri = FakeWeb::Utility.strip_default_port_from_uri(uri) | |
41 | + assert_equal "https://example.com", stripped_uri | |
42 | + end | |
43 | + | |
44 | + def test_strip_default_port_from_uri_strips_443_from_https | |
45 | + uri = "https://example.com:443/foo/bar" | |
46 | + stripped_uri = FakeWeb::Utility.strip_default_port_from_uri(uri) | |
47 | + assert_equal "https://example.com/foo/bar", stripped_uri | |
48 | + end | |
49 | + | |
50 | + def test_strip_default_port_from_uri_does_not_strip_8080_from_http | |
51 | + uri = "http://example.com:8080/foo/bar" | |
52 | + assert_equal uri, FakeWeb::Utility.strip_default_port_from_uri(uri) | |
53 | + end | |
54 | + | |
55 | + def test_strip_default_port_from_uri_does_not_strip_443_from_http | |
56 | + uri = "http://example.com:443/foo/bar" | |
57 | + assert_equal uri, FakeWeb::Utility.strip_default_port_from_uri(uri) | |
58 | + end | |
59 | + | |
60 | + def test_strip_default_port_from_uri_does_not_strip_80_from_query_string | |
61 | + uri = "http://example.com/?a=:80&b=c" | |
62 | + assert_equal uri, FakeWeb::Utility.strip_default_port_from_uri(uri) | |
63 | + end | |
64 | + | |
65 | + def test_strip_default_port_from_uri_does_not_modify_strings_that_do_not_start_with_http_or_https | |
66 | + uri = "httpz://example.com:80/" | |
67 | + assert_equal uri, FakeWeb::Utility.strip_default_port_from_uri(uri) | |
68 | + end | |
69 | + | |
70 | +end | ... | ... |
... | ... | @@ -0,0 +1,35 @@ |
1 | +=== 0.2.0 / 2008-12-23 | |
2 | + | |
3 | +* API Changes | |
4 | + | |
5 | + * Timecop#travel no longer freezes time. Rather, it computes the current offset between the new "now" and the real "now", and | |
6 | + returns times as if Time had continued to move forward | |
7 | + | |
8 | + * Timecop#freeze now behaves exactly as the old Timecop#travel behaved. Unless you depended on the actual freezing of time | |
9 | + (which I think would be rare), you should be able to continue to use #travel without worry. | |
10 | + | |
11 | + * Timecop#return is now exposed (previously Timecop#unset_all, but not well advertised). It will completely unmock time, | |
12 | + and will probably be rarely used outside of the actual implementation of this library. | |
13 | + | |
14 | +* More Test Coverage | |
15 | + | |
16 | + * Tests now explicitly cover the cases when the Date and DateTime objects are not loaded, and ensures proper functionality | |
17 | + in their absence and existence. | |
18 | + | |
19 | + * Still haven't done regression testing against anything other than a few version of 1.8.6 (including REE). We should | |
20 | + probably try to get this tested on both 1.8.7 and 1.9.1. | |
21 | + | |
22 | +* Documentation | |
23 | + | |
24 | + * Fixed up a lot of the poorly-formatted rdoc syntax. The public API should now be properly published in the rdoc, | |
25 | + and the internals are omitted. | |
26 | + | |
27 | +=== 0.1.0 / 2008-11-09 | |
28 | + | |
29 | +* Initial Feature Set | |
30 | + | |
31 | + * Temporarily (or permanently if you prefer) change the concept of Time.now, DateTime.now (if defined), and Date.today (if defined) | |
32 | + * Timecop#travel api allows an argument to be passed in as one of: 1) Time instance, 2) DateTime instance, 3) Date instance, | |
33 | + 4) individual arguments (year, month, day, hour, minute, second) | |
34 | + * Nested calls to Timecop#travel are supported -- each block will maintain it's interpretation of now. | |
35 | + | ... | ... |
... | ... | @@ -0,0 +1,14 @@ |
1 | +History.txt | |
2 | +Manifest.txt | |
3 | +README.txt | |
4 | +Rakefile | |
5 | +lib/timecop.rb | |
6 | +lib/timecop/stack_item.rb | |
7 | +lib/timecop/time_extensions.rb | |
8 | +lib/timecop/timecop.rb | |
9 | +lib/timecop/version.rb | |
10 | +test/run_tests.sh | |
11 | +test/test_timecop.rb | |
12 | +test/test_timecop_internals.rb | |
13 | +test/test_timecop_without_date.rb | |
14 | +timecop.gemspec | ... | ... |
... | ... | @@ -0,0 +1,84 @@ |
1 | +h1. timecop | |
2 | + | |
3 | +* http://github.com/jtrupiano/timecop | |
4 | + | |
5 | +h2. DESCRIPTION | |
6 | + | |
7 | +A gem providing simple ways to mock Time.now, Date.today, and DateTime.now. It provides "time travel" and "time freezing" capabilities, making it dead simple to test time-dependent code. | |
8 | + | |
9 | +h2. FEATURES | |
10 | + | |
11 | +* Temporarily (or permanently if you prefer) change the concept of Time.now, DateTime.now, and Date.today | |
12 | +* Timecop api allows arguments to be passed into #freeze and #travel as one of the following: | |
13 | + # Time instance | |
14 | + # DateTime instance | |
15 | + # Date instance | |
16 | + # individual arguments (year, month, day, hour, minute, second) | |
17 | + # a single integer argument that is interpreted as an offset in seconds from Time.now | |
18 | + | |
19 | +* Nested calls to Timecop#travel and Timecop#freeze are supported -- each block will maintain it's interpretation of now. | |
20 | + | |
21 | +h2. SHORTCOMINGS | |
22 | + | |
23 | +* Only fully tested on the 1.8.6 Ruby implementations. 1.8.7 and 1.9.1 should be tested, as well as other flavors (jruby, etc.) | |
24 | + | |
25 | +h2. SYNOPSIS | |
26 | + | |
27 | +* Run a time-sensitive test: | |
28 | +<code> | |
29 | + joe = User.find(1) | |
30 | + joe.purchase_home() | |
31 | + assert !joe.mortgage_due? | |
32 | + # move ahead a month and assert that the mortgage is due | |
33 | + Timecop.freeze(Date.today + 30) do | |
34 | + assert joe.mortgage_due? | |
35 | + end | |
36 | +</code> | |
37 | + | |
38 | +* Set the time for the test environment of a rails app -- this is particularly helpful if your whole application | |
39 | + is time-sensitive. It allows you to build your test data at a single point in time, and to move in/out of that | |
40 | + time as appropriate (within your tests) | |
41 | + | |
42 | +in config/environments/test.rb | |
43 | + | |
44 | +<code> | |
45 | +config.after_initialize do | |
46 | + # Set Time.now to September 1, 2008 10:05:00 AM | |
47 | + t = Time.local(2008, 9, 1, 10, 5, 0) | |
48 | + Timecop.travel(t) | |
49 | +end | |
50 | +</code> | |
51 | + | |
52 | +h2. REQUIREMENTS | |
53 | + | |
54 | +* None | |
55 | + | |
56 | +h2. INSTALL | |
57 | + | |
58 | +* sudo gem install timecop (latest stable version from rubyforge) | |
59 | +* sudo gem install jtrupiano-timecop (HEAD of the repo from github) | |
60 | + | |
61 | +h2. LICENSE | |
62 | + | |
63 | +(The MIT License) | |
64 | + | |
65 | +Copyright (c) 2008 FIX | |
66 | + | |
67 | +Permission is hereby granted, free of charge, to any person obtaining | |
68 | +a copy of this software and associated documentation files (the | |
69 | +'Software'), to deal in the Software without restriction, including | |
70 | +without limitation the rights to use, copy, modify, merge, publish, | |
71 | +distribute, sublicense, and/or sell copies of the Software, and to | |
72 | +permit persons to whom the Software is furnished to do so, subject to | |
73 | +the following conditions: | |
74 | + | |
75 | +The above copyright notice and this permission notice shall be | |
76 | +included in all copies or substantial portions of the Software. | |
77 | + | |
78 | +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, | |
79 | +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
80 | +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |
81 | +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | |
82 | +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | |
83 | +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | |
84 | +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ... | ... |
... | ... | @@ -0,0 +1,31 @@ |
1 | +require 'rake' | |
2 | +require 'rake/testtask' | |
3 | +require 'rake/rdoctask' | |
4 | + | |
5 | +begin | |
6 | + require 'jeweler' | |
7 | + Jeweler::Tasks.new do |s| | |
8 | + s.name = "timecop" | |
9 | + s.rubyforge_project = 'johntrupiano' # if different than lowercase project name | |
10 | + s.description = %q(A gem providing simple ways to temporarily override Time.now, Date.today, and DateTime.now. It provides "time travel" capabilities, making it dead simple to test time-dependent code.) | |
11 | + s.summary = s.description # More details later?? | |
12 | + s.email = "jtrupiano@gmail.com" | |
13 | + s.homepage = "http://github.com/jtrupiano/timecop" | |
14 | + s.authors = ["John Trupiano"] | |
15 | + s.files = FileList["[A-Z]*", "{bin,lib,test}/**/*"] | |
16 | + #s.add_dependency 'schacon-git' | |
17 | + end | |
18 | +rescue LoadError | |
19 | + puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com" | |
20 | +end | |
21 | + | |
22 | +# Override the test task and instruct them how to actually run the tests. | |
23 | +Rake.application.send(:eval, "@tasks.delete('test')") | |
24 | +desc "Does not execute tests. Manually run shell script ./run_tests.sh to execute tests." | |
25 | +task :test do | |
26 | + puts <<-MSG | |
27 | + In order to run the test suite, run: cd test && ./run_tests.sh | |
28 | + The tests need to be run with different libraries loaded, which rules out using Rake | |
29 | + to automate them. | |
30 | + MSG | |
31 | +end | ... | ... |
vendor/gems/jtrupiano-timecop-0.2.1/lib/timecop/stack_item.rb
0 → 100644
... | ... | @@ -0,0 +1,11 @@ |
1 | + | |
2 | +# Simply a data class for carrying around "time movement" objects. Makes it easy to keep track of the time | |
3 | +# movements on a simple stack. | |
4 | +class StackItem | |
5 | + | |
6 | + attr_reader :mock_type, :year, :month, :day, :hour, :minute, :second | |
7 | + def initialize(mock_type, year, month, day, hour, minute, second) | |
8 | + @mock_type, @year, @month, @day, @hour, @minute, @second = mock_type, year, month, day, hour, minute, second | |
9 | + end | |
10 | +end | |
11 | + | ... | ... |
vendor/gems/jtrupiano-timecop-0.2.1/lib/timecop/time_extensions.rb
0 → 100644
... | ... | @@ -0,0 +1,96 @@ |
1 | +# 1. Extensions to the Time, Date, and DateTime objects | |
2 | +# 2. Allows us to "freeze" time in our Ruby applications. | |
3 | +# 3. This is very useful when your app's functionality is dependent on time (e.g. | |
4 | +# anything that might expire). This will allow us to alter the return value of | |
5 | +# Date.today, Time.now, and DateTime.now, such that our application code _never_ has to change. | |
6 | + | |
7 | +class Time | |
8 | + class << self | |
9 | + # Time we might be behaving as | |
10 | + #attr_reader :mock_time | |
11 | + | |
12 | + @@mock_offset = nil | |
13 | + @@mock_time = nil | |
14 | + | |
15 | + def mock_time | |
16 | + if !@@mock_offset.nil? | |
17 | + now_without_mock_time - @@mock_offset | |
18 | + else | |
19 | + @@mock_time | |
20 | + end | |
21 | + end | |
22 | + | |
23 | + # Set new time to pretend we are. | |
24 | + def freeze_time(new_now) | |
25 | + @@mock_time = new_now | |
26 | + @@mock_offset = nil | |
27 | + end | |
28 | + | |
29 | + def move_time(new_now) | |
30 | + @@mock_offset = new_now.nil? ? nil : (now_without_mock_time - new_now) | |
31 | + @@mock_time = nil | |
32 | + end | |
33 | + | |
34 | + # Restores Time to system clock | |
35 | + def unmock! | |
36 | + move_time(nil) | |
37 | + end | |
38 | + | |
39 | + # Alias the original now | |
40 | + alias_method :now_without_mock_time, :now | |
41 | + | |
42 | + # Define now_with_mock_time | |
43 | + def now_with_mock_time | |
44 | + mock_time || now_without_mock_time | |
45 | + end | |
46 | + | |
47 | + # Alias now to now_with_mock_time | |
48 | + alias_method :now, :now_with_mock_time | |
49 | + end | |
50 | +end | |
51 | + | |
52 | +if Object.const_defined?(:Date) | |
53 | + class Date | |
54 | + class << self | |
55 | + def mock_date | |
56 | + now = Time.mock_time | |
57 | + return nil if now.nil? | |
58 | + Date.new(now.year, now.month, now.day) | |
59 | + end | |
60 | + | |
61 | + # Alias the original today | |
62 | + alias_method :today_without_mock_date, :today | |
63 | + | |
64 | + # Define today_with_mock_date | |
65 | + def today_with_mock_date | |
66 | + mock_date || today_without_mock_date | |
67 | + end | |
68 | + | |
69 | + # Alias today to today_with_mock_date | |
70 | + alias_method :today, :today_with_mock_date | |
71 | + end | |
72 | + end | |
73 | +end | |
74 | + | |
75 | +if Object.const_defined?(:DateTime) | |
76 | + class DateTime | |
77 | + class << self | |
78 | + def mock_time | |
79 | + t_now = Time.mock_time | |
80 | + return nil if t_now.nil? | |
81 | + DateTime.new(t_now.year, t_now.month, t_now.day, t_now.hour, t_now.min, t_now.sec) | |
82 | + end | |
83 | + | |
84 | + # Alias the original now | |
85 | + alias_method :now_without_mock_time, :now | |
86 | + | |
87 | + # Define now_with_mock_time | |
88 | + def now_with_mock_time | |
89 | + mock_time || now_without_mock_time | |
90 | + end | |
91 | + | |
92 | + # Alias now to now_with_mock_time | |
93 | + alias_method :now, :now_with_mock_time | |
94 | + end | |
95 | + end | |
96 | +end | |
0 | 97 | \ No newline at end of file | ... | ... |
vendor/gems/jtrupiano-timecop-0.2.1/lib/timecop/timecop.rb
0 → 100644
... | ... | @@ -0,0 +1,198 @@ |
1 | +require 'singleton' | |
2 | +require File.join(File.dirname(__FILE__), 'time_extensions') | |
3 | +require File.join(File.dirname(__FILE__), 'stack_item') | |
4 | + | |
5 | +# Timecop | |
6 | +# * Wrapper class for manipulating the extensions to the Time, Date, and DateTime objects | |
7 | +# * Allows us to "freeze" time in our Ruby applications. | |
8 | +# * Optionally allows time travel to simulate a running clock, such time is not technically frozen. | |
9 | +# | |
10 | +# This is very useful when your app's functionality is dependent on time (e.g. | |
11 | +# anything that might expire). This will allow us to alter the return value of | |
12 | +# Date.today, Time.now, and DateTime.now, such that our application code _never_ has to change. | |
13 | +class Timecop | |
14 | + include Singleton | |
15 | + | |
16 | + # Allows you to run a block of code and "fake" a time throughout the execution of that block. | |
17 | + # This is particularly useful for writing test methods where the passage of time is critical to the business | |
18 | + # logic being tested. For example: | |
19 | + # | |
20 | + # <code> | |
21 | + # joe = User.find(1) | |
22 | + # joe.purchase_home() | |
23 | + # assert !joe.mortgage_due? | |
24 | + # Timecop.freeze(2008, 10, 5) do | |
25 | + # assert joe.mortgage_due? | |
26 | + # end | |
27 | + # </code> | |
28 | + # | |
29 | + # freeze and travel will respond to several different arguments: | |
30 | + # 1. Timecop.freeze(time_inst) | |
31 | + # 2. Timecop.freeze(datetime_inst) | |
32 | + # 3. Timecop.freeze(date_inst) | |
33 | + # 4. Timecop.freeze(year, month, day, hour=0, minute=0, second=0) | |
34 | + # | |
35 | + # When a block is also passed, Time.now, DateTime.now and Date.today are all reset to their | |
36 | + # previous values. This allows us to nest multiple calls to Timecop.travel and have each block | |
37 | + # maintain it's concept of "now." | |
38 | + # | |
39 | + # * Note: Timecop.freeze will actually freeze time. This can cause unanticipated problems if | |
40 | + # benchmark or other timing calls are executed, which implicitly expect Time to actually move | |
41 | + # forward. | |
42 | + # | |
43 | + # * Rails Users: Be especially careful when setting this in your development environment in a | |
44 | + # rails project. Generators will load your environment, including the migration generator, | |
45 | + # which will lead to files being generated with the timestamp set by the Timecop.freeze call | |
46 | + # in your dev environment | |
47 | + def self.freeze(*args, &block) | |
48 | + instance().send(:travel, :freeze, *args, &block) | |
49 | + end | |
50 | + | |
51 | + # Allows you to run a block of code and "fake" a time throughout the execution of that block. | |
52 | + # See Timecop#freeze for a sample of how to use (same exact usage syntax) | |
53 | + # | |
54 | + # * Note: Timecop.travel will not freeze time (as opposed to Timecop.freeze). This is a particularly | |
55 | + # good candidate for use in environment files in rails projects. | |
56 | + def self.travel(*args, &block) | |
57 | + instance().send(:travel, :move, *args, &block) | |
58 | + end | |
59 | + | |
60 | + # Reverts back to system's Time.now, Date.today and DateTime.now (if it exists). If freeze_all or rebase_all | |
61 | + # was never called in the first place, this method will have no effect. | |
62 | + def self.return | |
63 | + instance().send(:unmock!) | |
64 | + end | |
65 | + | |
66 | + # [Deprecated]: See Timecop#return instead. | |
67 | + def self.unset_all | |
68 | + $stderr.puts "Timecop#unset_all is deprecated. Please use Timecop#return instead." | |
69 | + $stderr.flush | |
70 | + self.return | |
71 | + end | |
72 | + | |
73 | + protected | |
74 | + | |
75 | + def initialize | |
76 | + @_stack = [] | |
77 | + end | |
78 | + | |
79 | + def travel(mock_type, *args, &block) | |
80 | + # parse the arguments, build our base time units | |
81 | + year, month, day, hour, minute, second = parse_travel_args(*args) | |
82 | + | |
83 | + # perform our action | |
84 | + if mock_type == :freeze | |
85 | + freeze_all(year, month, day, hour, minute, second) | |
86 | + else | |
87 | + move_all(year, month, day, hour, minute, second) | |
88 | + end | |
89 | + # store this time traveling on our stack... | |
90 | + @_stack << StackItem.new(mock_type, year, month, day, hour, minute, second) | |
91 | + | |
92 | + if block_given? | |
93 | + begin | |
94 | + yield | |
95 | + ensure | |
96 | + # pull it off the stack... | |
97 | + stack_item = @_stack.pop | |
98 | + if @_stack.size == 0 | |
99 | + # completely unmock if there's nothing to revert back to | |
100 | + unmock! | |
101 | + else | |
102 | + # or reinstantiate the new the top of the stack (could be a :freeze or a :move) | |
103 | + new_top = @_stack.last | |
104 | + if new_top.mock_type == :freeze | |
105 | + freeze_all(new_top.year, new_top.month, new_top.day, new_top.hour, new_top.minute, new_top.second) | |
106 | + else | |
107 | + move_all(new_top.year, new_top.month, new_top.day, new_top.hour, new_top.minute, new_top.second) | |
108 | + end | |
109 | + end | |
110 | + end | |
111 | + end | |
112 | + end | |
113 | + | |
114 | + def unmock! | |
115 | + Time.unmock! | |
116 | + end | |
117 | + | |
118 | + private | |
119 | + | |
120 | + # Re-bases Time.now, Date.today and DateTime.now (if it exists) to use the time passed in. | |
121 | + # When using this method directly, it is up to the developer to call unset_all to return us | |
122 | + # to sanity. | |
123 | + # | |
124 | + # * If being consumed in a rails app, Time.zone.local will be used to instantiate the time. | |
125 | + # Otherwise, Time.local will be used. | |
126 | + def freeze_all(year, month, day, hour=0, minute=0, second=0) | |
127 | + if Time.respond_to?(:zone) && !Time.zone.nil? | |
128 | + # ActiveSupport loaded | |
129 | + time = Time.zone.local(year, month, day, hour, minute, second) | |
130 | + else | |
131 | + # ActiveSupport not loaded | |
132 | + time = Time.local(year, month, day, hour, minute, second) | |
133 | + end | |
134 | + | |
135 | + Time.freeze_time(time) | |
136 | + end | |
137 | + | |
138 | + # Re-bases Time.now, Date.today and DateTime.now to use the time passed in and to continue moving time | |
139 | + # forward. When using this method directly, it is up to the developer to call return to return us to | |
140 | + # sanity. | |
141 | + # | |
142 | + # * If being consumed in a rails app, Time.zone.local will be used to instantiate the time. | |
143 | + # Otherwise, Time.local will be used. | |
144 | + def move_all(year, month, day, hour=0, minute=0, second=0) | |
145 | + if Time.respond_to?(:zone) && !Time.zone.nil? | |
146 | + # ActiveSupport loaded | |
147 | + time = Time.zone.local(year, month, day, hour, minute, second) | |
148 | + else | |
149 | + # ActiveSupport not loaded | |
150 | + time = Time.local(year, month, day, hour, minute, second) | |
151 | + end | |
152 | + | |
153 | + Time.move_time(time) | |
154 | + end | |
155 | + | |
156 | + def parse_travel_args(*args) | |
157 | + arg = args.shift | |
158 | + if arg.is_a?(Time) || (Object.const_defined?(:DateTime) && arg.is_a?(DateTime)) | |
159 | + year, month, day, hour, minute, second = arg.year, arg.month, arg.day, arg.hour, arg.min, arg.sec | |
160 | + elsif Object.const_defined?(:Date) && arg.is_a?(Date) | |
161 | + year, month, day, hour, minute, second = arg.year, arg.month, arg.day, 0, 0, 0 | |
162 | + #puts "#{year}-#{month}-#{day} #{hour}:#{minute}:#{second}" | |
163 | + elsif args.empty? && arg.kind_of?(Integer) | |
164 | + t = Time.now + arg | |
165 | + year, month, day, hour, minute, second = t.year, t.month, t.day, t.hour, t.min, t.sec | |
166 | + else # we'll just assume it's a list of y/m/h/d/m/s | |
167 | + year = arg || 0 | |
168 | + month = args.shift || 1 | |
169 | + day = args.shift || 1 | |
170 | + hour = args.shift || 0 | |
171 | + minute = args.shift || 0 | |
172 | + second = args.shift || 0 | |
173 | + end | |
174 | + return year, month, day, hour, minute, second | |
175 | + end | |
176 | +end | |
177 | + | |
178 | +#def with_dates(*dates, &block) | |
179 | +# dates.flatten.each do |date| | |
180 | +# begin | |
181 | +# DateTime.forced_now = case date | |
182 | +# when String: DateTime.parse(date) | |
183 | +# when Time: DateTime.parse(date.to_s) | |
184 | +# else | |
185 | +# date | |
186 | +# end | |
187 | +# Date.forced_today = Date.new(DateTime.forced_now.year, | |
188 | +#DateTime.forced_now.month, DateTime.forced_now.day) | |
189 | +# yield | |
190 | +# rescue Exception => e | |
191 | +# raise e | |
192 | +# ensure | |
193 | +# DateTime.forced_now = nil | |
194 | +# Date.forced_today = nil | |
195 | +# end | |
196 | +# end | |
197 | +#end | |
198 | + | ... | ... |
vendor/gems/jtrupiano-timecop-0.2.1/lib/timecop/version.rb
0 → 100644
... | ... | @@ -0,0 +1,20 @@ |
1 | +module Timecop | |
2 | + module Version #:nodoc: | |
3 | + # A method for comparing versions of required modules. It expects two | |
4 | + # arrays of integers as parameters, the first being the minimum version | |
5 | + # required, and the second being the actual version available. It returns | |
6 | + # true if the actual version is at least equal to the required version. | |
7 | + def self.check(required, actual) #:nodoc: | |
8 | + required = required.map { |v| "%06d" % v }.join(".") | |
9 | + actual = actual.map { |v| "%06d" % v }.join(".") | |
10 | + return actual >= required | |
11 | + end | |
12 | + | |
13 | + MAJOR = 0 | |
14 | + MINOR = 2 | |
15 | + TINY = 0 | |
16 | + | |
17 | + STRING = [MAJOR, MINOR, TINY].join(".") | |
18 | + end | |
19 | +end | |
20 | + | ... | ... |
... | ... | @@ -0,0 +1,10 @@ |
1 | +#!/bin/sh | |
2 | + | |
3 | +echo "\033[1;81m Running test_timecop_internals...\033[0m" | |
4 | +ruby test_timecop_internals.rb || (echo "FAILED!!!!!!!!!!!!") | |
5 | + | |
6 | +echo "\033[1;81m Running test_timecop_without_date...\033[0m" | |
7 | +ruby test_timecop_without_date.rb || (echo "FAILED!!!!!!!!!!!!") | |
8 | + | |
9 | +echo "\033[1;81m Running test_timecop...\033[0m" | |
10 | +ruby test_timecop.rb || (echo "FAILED!!!!!!!!!!!!") | ... | ... |
vendor/gems/jtrupiano-timecop-0.2.1/test/test_timecop.rb
0 → 100644
... | ... | @@ -0,0 +1,175 @@ |
1 | + | |
2 | +require 'date' | |
3 | +require 'test/unit' | |
4 | +require File.join(File.dirname(__FILE__), '..', 'lib', 'timecop') | |
5 | + | |
6 | +class TestTimecop < Test::Unit::TestCase | |
7 | + | |
8 | + def setup | |
9 | + | |
10 | + end | |
11 | + | |
12 | + # just in case...let's really make sure that Timecop is disabled between tests... | |
13 | + def teardown | |
14 | + Timecop.return | |
15 | + end | |
16 | + | |
17 | + def test_freeze_changes_and_resets_time | |
18 | + # depending on how we're invoked (individually or via the rake test suite) | |
19 | + assert !Time.respond_to?(:zone) || Time.zone.nil? | |
20 | + | |
21 | + t = Time.local(2008, 10, 10, 10, 10, 10) | |
22 | + assert_not_equal t, Time.now | |
23 | + Timecop.freeze(2008, 10, 10, 10, 10, 10) do | |
24 | + assert_equal t, Time.now | |
25 | + end | |
26 | + assert_not_equal t, Time.now | |
27 | + end | |
28 | + | |
29 | + def test_recursive_freeze | |
30 | + t = Time.local(2008, 10, 10, 10, 10, 10) | |
31 | + Timecop.freeze(2008, 10, 10, 10, 10, 10) do | |
32 | + assert_equal t, Time.now | |
33 | + t2 = Time.local(2008, 9, 9, 9, 9, 9) | |
34 | + Timecop.freeze(2008, 9, 9, 9, 9, 9) do | |
35 | + assert_equal t2, Time.now | |
36 | + end | |
37 | + assert_equal t, Time.now | |
38 | + end | |
39 | + assert_not_equal t, Time.now | |
40 | + end | |
41 | + | |
42 | + def test_freeze_with_time_instance_works_as_expected | |
43 | + t = Time.local(2008, 10, 10, 10, 10, 10) | |
44 | + Timecop.freeze(t) do | |
45 | + assert_equal t, Time.now | |
46 | + assert_equal DateTime.new(2008, 10, 10, 10, 10, 10), DateTime.now | |
47 | + assert_equal Date.new(2008, 10, 10), Date.today | |
48 | + end | |
49 | + assert_not_equal t, Time.now | |
50 | + assert_not_equal DateTime.new(2008, 10, 10, 10, 10, 10), DateTime.now | |
51 | + assert_not_equal Date.new(2008, 10, 10), Date.today | |
52 | + end | |
53 | + | |
54 | + def test_freeze_with_datetime_instance_works_as_expected | |
55 | + t = DateTime.new(2008, 10, 10, 10, 10, 10) | |
56 | + Timecop.freeze(t) do | |
57 | + assert_equal t, DateTime.now | |
58 | + assert_equal Time.local(2008, 10, 10, 10, 10, 10), Time.now | |
59 | + assert_equal Date.new(2008, 10, 10), Date.today | |
60 | + end | |
61 | + assert_not_equal t, DateTime.now | |
62 | + assert_not_equal Time.local(2008, 10, 10, 10, 10, 10), Time.now | |
63 | + assert_not_equal Date.new(2008, 10, 10), Date.today | |
64 | + end | |
65 | + | |
66 | + def test_freeze_with_date_instance_works_as_expected | |
67 | + d = Date.new(2008, 10, 10) | |
68 | + Timecop.freeze(d) do | |
69 | + assert_equal d, Date.today | |
70 | + assert_equal Time.local(2008, 10, 10, 0, 0, 0), Time.now | |
71 | + assert_equal DateTime.new(2008, 10, 10, 0, 0, 0), DateTime.now | |
72 | + end | |
73 | + assert_not_equal d, Date.today | |
74 | + assert_not_equal Time.local(2008, 10, 10, 0, 0, 0), Time.now | |
75 | + assert_not_equal DateTime.new(2008, 10, 10, 0, 0, 0), DateTime.now | |
76 | + end | |
77 | + | |
78 | + def test_freeze_with_integer_instance_works_as_expected | |
79 | + t = Time.local(2008, 10, 10, 10, 10, 10) | |
80 | + Timecop.freeze(t) do | |
81 | + assert_equal t, Time.now | |
82 | + assert_equal DateTime.new(2008, 10, 10, 10, 10, 10), DateTime.now | |
83 | + assert_equal Date.new(2008, 10, 10), Date.today | |
84 | + Timecop.freeze(10) do | |
85 | + assert_equal t + 10, Time.now | |
86 | + assert_equal Time.local(2008, 10, 10, 10, 10, 20), Time.now | |
87 | + assert_equal Date.new(2008, 10, 10), Date.today | |
88 | + end | |
89 | + end | |
90 | + assert_not_equal t, Time.now | |
91 | + assert_not_equal DateTime.new(2008, 10, 10, 10, 10, 10), DateTime.now | |
92 | + assert_not_equal Date.new(2008, 10, 10), Date.today | |
93 | + end | |
94 | + | |
95 | + def test_exception_thrown_in_freeze_block_properly_resets_time | |
96 | + t = Time.local(2008, 10, 10, 10, 10, 10) | |
97 | + begin | |
98 | + Timecop.freeze(t) do | |
99 | + assert_equal t, Time.now | |
100 | + raise "blah exception" | |
101 | + end | |
102 | + rescue | |
103 | + assert_not_equal t, Time.now | |
104 | + assert_nil Time.send(:mock_time) | |
105 | + end | |
106 | + end | |
107 | + | |
108 | + def test_freeze_freezes_time | |
109 | + t = Time.local(2008, 10, 10, 10, 10, 10) | |
110 | + now = Time.now | |
111 | + Timecop.freeze(t) do | |
112 | + #assert Time.now < now, "If we had failed to freeze, time would have proceeded, which is what appears to have happened." | |
113 | + new_t, new_d, new_dt = Time.now, Date.today, DateTime.now | |
114 | + assert_equal t, new_t, "Failed to freeze time." # 2 seconds | |
115 | + #sleep(10) | |
116 | + assert_equal new_t, Time.now | |
117 | + assert_equal new_d, Date.today | |
118 | + assert_equal new_dt, DateTime.now | |
119 | + end | |
120 | + end | |
121 | + | |
122 | + def test_travel_keeps_time_moving | |
123 | + t = Time.local(2008, 10, 10, 10, 10, 10) | |
124 | + now = Time.now | |
125 | + Timecop.travel(t) do | |
126 | + #assert Time.now < now, "If we had failed to freeze, time would have proceeded, which is what appears to have happened." | |
127 | + assert Time.now - t < 2000, "Looks like we failed to actually travel time" # 2 seconds | |
128 | + new_t = Time.now | |
129 | + #sleep(10) | |
130 | + assert_not_equal new_t, Time.now | |
131 | + end | |
132 | + end | |
133 | + | |
134 | + def test_recursive_rebasing_maintains_each_context | |
135 | + t = Time.local(2008, 10, 10, 10, 10, 10) | |
136 | + Timecop.travel(2008, 10, 10, 10, 10, 10) do | |
137 | + assert((t - Time.now).abs < 50, "Failed to travel time.") | |
138 | + t2 = Time.local(2008, 9, 9, 9, 9, 9) | |
139 | + Timecop.travel(2008, 9, 9, 9, 9, 9) do | |
140 | + assert((t2 - Time.now) < 50, "Failed to travel time.") | |
141 | + assert((t - Time.now) > 1000, "Failed to travel time.") | |
142 | + end | |
143 | + assert((t - Time.now).abs < 2000, "Failed to restore previously-traveled time.") | |
144 | + end | |
145 | + assert_nil Time.send(:mock_time) | |
146 | + end | |
147 | + | |
148 | + def test_recursive_travel_then_freeze | |
149 | + t = Time.local(2008, 10, 10, 10, 10, 10) | |
150 | + Timecop.travel(2008, 10, 10, 10, 10, 10) do | |
151 | + assert((t - Time.now).abs < 50, "Failed to travel time.") | |
152 | + t2 = Time.local(2008, 9, 9, 9, 9, 9) | |
153 | + Timecop.freeze(2008, 9, 9, 9, 9, 9) do | |
154 | + assert_equal t2, Time.now | |
155 | + end | |
156 | + assert((t - Time.now).abs < 2000, "Failed to restore previously-traveled time.") | |
157 | + end | |
158 | + assert_nil Time.send(:mock_time) | |
159 | + end | |
160 | + | |
161 | + def test_recursive_freeze_then_travel | |
162 | + t = Time.local(2008, 10, 10, 10, 10, 10) | |
163 | + Timecop.freeze(t) do | |
164 | + assert_equal t, Time.now | |
165 | + t2 = Time.local(2008, 9, 9, 9, 9, 9) | |
166 | + Timecop.travel(t2) do | |
167 | + assert((t2 - Time.now) < 50, "Failed to travel time.") | |
168 | + assert((t - Time.now) > 1000, "Failed to travel time.") | |
169 | + end | |
170 | + assert_equal t, Time.now | |
171 | + end | |
172 | + assert_nil Time.send(:mock_time) | |
173 | + end | |
174 | + | |
175 | +end | |
0 | 176 | \ No newline at end of file | ... | ... |
vendor/gems/jtrupiano-timecop-0.2.1/test/test_timecop_internals.rb
0 → 100644
... | ... | @@ -0,0 +1,69 @@ |
1 | + | |
2 | +require 'date' | |
3 | +require 'test/unit' | |
4 | +require File.join(File.dirname(__FILE__), '..', 'lib', 'timecop') | |
5 | + | |
6 | +class TestTimecopInternals < Test::Unit::TestCase | |
7 | + | |
8 | + def test_parse_travel_args_with_time | |
9 | + t = Time.now | |
10 | + y, m, d, h, min, s = t.year, t.month, t.day, t.hour, t.min, t.sec | |
11 | + ty, tm, td, th, tmin, ts = Timecop.instance().send(:parse_travel_args, t) | |
12 | + assert_equal y, ty | |
13 | + assert_equal m, tm | |
14 | + assert_equal d, td | |
15 | + assert_equal h, th | |
16 | + assert_equal min, tmin | |
17 | + assert_equal s, ts | |
18 | + end | |
19 | + | |
20 | + def test_parse_travel_args_with_datetime | |
21 | + t = DateTime.now | |
22 | + y, m, d, h, min, s = t.year, t.month, t.day, t.hour, t.min, t.sec | |
23 | + ty, tm, td, th, tmin, ts = Timecop.instance().send(:parse_travel_args, t) | |
24 | + assert_equal y, ty | |
25 | + assert_equal m, tm | |
26 | + assert_equal d, td | |
27 | + assert_equal h, th | |
28 | + assert_equal min, tmin | |
29 | + assert_equal s, ts | |
30 | + end | |
31 | + | |
32 | + def test_parse_travel_args_with_date | |
33 | + date = Date.today | |
34 | + y, m, d, h, min, s = date.year, date.month, date.day, 0, 0, 0 | |
35 | + ty, tm, td, th, tmin, ts = Timecop.instance().send(:parse_travel_args, date) | |
36 | + assert_equal y, ty | |
37 | + assert_equal m, tm | |
38 | + assert_equal d, td | |
39 | + assert_equal h, th | |
40 | + assert_equal min, tmin | |
41 | + assert_equal s, ts | |
42 | + end | |
43 | + | |
44 | + # Due to the nature of this test (calling Time.now once in this test and | |
45 | + # once in #parse_travel_args), this test may fail when two subsequent calls | |
46 | + # to Time.now return a different second. | |
47 | + def test_parse_travel_args_with_integer | |
48 | + t = Time.now | |
49 | + y, m, d, h, min, s = t.year, t.month, t.day, t.hour, t.min, t.sec | |
50 | + ty, tm, td, th, tmin, ts = Timecop.instance().send(:parse_travel_args, 0) | |
51 | + assert_equal y, ty | |
52 | + assert_equal m, tm | |
53 | + assert_equal d, td | |
54 | + assert_equal h, th | |
55 | + assert_equal min, tmin | |
56 | + assert_equal s, ts | |
57 | + end | |
58 | + | |
59 | + def test_parse_travel_args_with_individual_arguments | |
60 | + y, m, d, h, min, s = 2008, 10, 10, 10, 10, 10 | |
61 | + ty, tm, td, th, tmin, ts = Timecop.instance().send(:parse_travel_args, y, m, d, h, min, s) | |
62 | + assert_equal y, ty | |
63 | + assert_equal m, tm | |
64 | + assert_equal d, td | |
65 | + assert_equal h, th | |
66 | + assert_equal min, tmin | |
67 | + assert_equal s, ts | |
68 | + end | |
69 | +end | |
0 | 70 | \ No newline at end of file | ... | ... |
vendor/gems/jtrupiano-timecop-0.2.1/test/test_timecop_without_date.rb
0 → 100644
... | ... | @@ -0,0 +1,120 @@ |
1 | + | |
2 | +require 'test/unit' | |
3 | +require File.join(File.dirname(__FILE__), '..', 'lib', 'timecop') | |
4 | + | |
5 | +class TestTimecopWithouDate < Test::Unit::TestCase | |
6 | + | |
7 | + def setup | |
8 | + assert !Object.const_defined?(:Date) | |
9 | + assert !Object.const_defined?(:DateTime) | |
10 | + end | |
11 | + | |
12 | + # just in case...let's really make sure that Timecop is disabled between tests... | |
13 | + def teardown | |
14 | + Timecop.return | |
15 | + end | |
16 | + | |
17 | + def test_freeze_changes_and_resets_time | |
18 | + # depending on how we're invoked (individually or via the rake test suite) | |
19 | + assert !Time.respond_to?(:zone) || Time.zone.nil? | |
20 | + | |
21 | + t = Time.local(2008, 10, 10, 10, 10, 10) | |
22 | + assert_not_equal t, Time.now | |
23 | + Timecop.freeze(2008, 10, 10, 10, 10, 10) do | |
24 | + assert_equal t, Time.now | |
25 | + end | |
26 | + assert_not_equal t, Time.now | |
27 | + end | |
28 | + | |
29 | + def test_recursive_freeze | |
30 | + t = Time.local(2008, 10, 10, 10, 10, 10) | |
31 | + Timecop.freeze(2008, 10, 10, 10, 10, 10) do | |
32 | + assert_equal t, Time.now | |
33 | + t2 = Time.local(2008, 9, 9, 9, 9, 9) | |
34 | + Timecop.freeze(2008, 9, 9, 9, 9, 9) do | |
35 | + assert_equal t2, Time.now | |
36 | + end | |
37 | + assert_equal t, Time.now | |
38 | + end | |
39 | + assert_nil Time.send(:mock_time) | |
40 | + end | |
41 | + | |
42 | + def test_exception_thrown_in_freeze_block_properly_resets_time | |
43 | + t = Time.local(2008, 10, 10, 10, 10, 10) | |
44 | + begin | |
45 | + Timecop.freeze(t) do | |
46 | + assert_equal t, Time.now | |
47 | + raise "blah exception" | |
48 | + end | |
49 | + rescue | |
50 | + assert_not_equal t, Time.now | |
51 | + assert_nil Time.send(:mock_time) | |
52 | + end | |
53 | + end | |
54 | + | |
55 | + def test_freeze_freezes_time | |
56 | + t = Time.local(2008, 10, 10, 10, 10, 10) | |
57 | + now = Time.now | |
58 | + Timecop.freeze(t) do | |
59 | + #assert Time.now < now, "If we had failed to freeze, time would have proceeded, which is what appears to have happened." | |
60 | + new_t = Time.now | |
61 | + assert_equal t, new_t, "Failed to change move time." # 2 seconds | |
62 | + #sleep(10) | |
63 | + assert_equal new_t, Time.now | |
64 | + end | |
65 | + end | |
66 | + | |
67 | + def test_travel_keeps_time_moving | |
68 | + t = Time.local(2008, 10, 10, 10, 10, 10) | |
69 | + now = Time.now | |
70 | + Timecop.travel(t) do | |
71 | + #assert Time.now < now, "If we had failed to freeze, time would have proceeded, which is what appears to have happened." | |
72 | + assert Time.now - t < 2000, "Looks like we failed to actually travel time" # 2 seconds | |
73 | + new_t = Time.now | |
74 | + #sleep(10) | |
75 | + assert_not_equal new_t, Time.now | |
76 | + end | |
77 | + end | |
78 | + | |
79 | + def test_recursive_rebasing_maintains_each_context | |
80 | + t = Time.local(2008, 10, 10, 10, 10, 10) | |
81 | + Timecop.travel(2008, 10, 10, 10, 10, 10) do | |
82 | + assert((t - Time.now).abs < 50, "Failed to travel time.") | |
83 | + t2 = Time.local(2008, 9, 9, 9, 9, 9) | |
84 | + Timecop.travel(2008, 9, 9, 9, 9, 9) do | |
85 | + assert((t2 - Time.now) < 50, "Failed to travel time.") | |
86 | + assert((t - Time.now) > 1000, "Failed to travel time.") | |
87 | + end | |
88 | + assert((t - Time.now).abs < 2000, "Failed to restore previously-traveled time.") | |
89 | + end | |
90 | + assert_nil Time.send(:mock_time) | |
91 | + end | |
92 | + | |
93 | + def test_recursive_travel_then_freeze | |
94 | + t = Time.local(2008, 10, 10, 10, 10, 10) | |
95 | + Timecop.travel(2008, 10, 10, 10, 10, 10) do | |
96 | + assert((t - Time.now).abs < 50, "Failed to travel time.") | |
97 | + t2 = Time.local(2008, 9, 9, 9, 9, 9) | |
98 | + Timecop.freeze(2008, 9, 9, 9, 9, 9) do | |
99 | + assert_equal t2, Time.now | |
100 | + end | |
101 | + assert((t - Time.now).abs < 2000, "Failed to restore previously-traveled time.") | |
102 | + end | |
103 | + assert_nil Time.send(:mock_time) | |
104 | + end | |
105 | + | |
106 | + def test_recursive_freeze_then_travel | |
107 | + t = Time.local(2008, 10, 10, 10, 10, 10) | |
108 | + Timecop.freeze(t) do | |
109 | + assert_equal t, Time.now | |
110 | + t2 = Time.local(2008, 9, 9, 9, 9, 9) | |
111 | + Timecop.travel(t2) do | |
112 | + assert((t2 - Time.now) < 50, "Failed to travel time.") | |
113 | + assert((t - Time.now) > 1000, "Failed to travel time.") | |
114 | + end | |
115 | + assert_equal t, Time.now | |
116 | + end | |
117 | + assert_nil Time.send(:mock_time) | |
118 | + end | |
119 | + | |
120 | +end | |
0 | 121 | \ No newline at end of file | ... | ... |