diff --git a/>= 1.2.5 b/>= 1.2.5 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/>= 1.2.5 diff --git a/README.markdown b/README.markdown index 4886cf0..a538dfc 100644 --- a/README.markdown +++ b/README.markdown @@ -20,7 +20,7 @@ This will create a Rails 2.3.2 app with Heroku-recommended code: * jQuery for Javascript and Ajax * Clearance for authentication * Active Merchant for payment processing -* Cucumber, Shoulda, Factory Girl, & Mocha for testing +* Cucumber, Shoulda, Factory Girl, Mocha, Fakeweb, & Timecop for testing * Inherited Resources for RESTful controllers * Formtastic for form builders * Flutie for CSS framework diff --git a/config/environments/test.rb b/config/environments/test.rb index f38e2f9..58f5af6 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -35,12 +35,19 @@ config.gem 'thoughtbot-shoulda', :lib => 'shoulda', :source => 'http://gems.github.com', :version => '>= 2.10.1' +config.gem 'jtrupiano-timecop', + :lib => 'timecop', + :source => 'http://gems.github.com', + :version => '0.2.1' +config.gem 'fakeweb', + :version => '>= 1.2.5' HOST = 'localhost' begin require 'factory_girl' require 'redgreen' + require 'fakeweb' rescue LoadError end diff --git a/doc/README_FOR_TEMPLATE b/doc/README_FOR_TEMPLATE index 8ee6eb4..f989621 100644 --- a/doc/README_FOR_TEMPLATE +++ b/doc/README_FOR_TEMPLATE @@ -39,6 +39,8 @@ For testing: mocha thoughtbot-factory_girl thoughtbot-shoulda + fakeweb + jtrupiano-timecop For form builders: diff --git a/vendor/gems/fakeweb-1.2.5/.specification b/vendor/gems/fakeweb-1.2.5/.specification new file mode 100644 index 0000000..8d4c75e --- /dev/null +++ b/vendor/gems/fakeweb-1.2.5/.specification @@ -0,0 +1,122 @@ +--- !ruby/object:Gem::Specification +name: fakeweb +version: !ruby/object:Gem::Version + version: 1.2.5 +platform: ruby +authors: +- Chris Kampmeier +- Blaine Cook +autorequire: +bindir: bin +cert_chain: [] + +date: 2009-07-08 00:00:00 -04:00 +default_executable: +dependencies: +- !ruby/object:Gem::Dependency + name: mocha + type: :development + version_requirement: + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - ">=" + - !ruby/object:Gem::Version + version: 0.9.5 + version: +description: FakeWeb is a helper for faking web requests in Ruby. It works at a global level, without modifying code or writing extensive stubs. +email: +- chris@kampers.net +- romeda@gmail.com +executables: [] + +extensions: [] + +extra_rdoc_files: +- CHANGELOG +- LICENSE.txt +- README.rdoc +files: +- CHANGELOG +- LICENSE.txt +- README.rdoc +- Rakefile +- lib/fake_web.rb +- lib/fake_web/ext/net_http.rb +- lib/fake_web/registry.rb +- lib/fake_web/responder.rb +- lib/fake_web/response.rb +- lib/fake_web/stub_socket.rb +- lib/fake_web/utility.rb +- lib/fakeweb.rb +- test/fixtures/google_response_from_curl +- test/fixtures/google_response_with_transfer_encoding +- test/fixtures/google_response_without_transfer_encoding +- test/fixtures/test_example.txt +- test/fixtures/test_txt_file +- test/test_allow_net_connect.rb +- test/test_deprecations.rb +- test/test_fake_authentication.rb +- test/test_fake_web.rb +- test/test_fake_web_open_uri.rb +- test/test_helper.rb +- test/test_missing_open_uri.rb +- test/test_precedence.rb +- test/test_query_string.rb +- test/test_regexes.rb +- test/test_response_headers.rb +- test/test_trailing_slashes.rb +- test/test_utility.rb +has_rdoc: true +homepage: http://github.com/chrisk/fakeweb +licenses: [] + +post_install_message: +rdoc_options: +- --main +- README.rdoc +- --title +- FakeWeb API Documentation +- --charset +- utf-8 +- --line-numbers +- --inline-source +require_paths: +- lib +required_ruby_version: !ruby/object:Gem::Requirement + requirements: + - - ">=" + - !ruby/object:Gem::Version + version: "0" + version: +required_rubygems_version: !ruby/object:Gem::Requirement + requirements: + - - ">=" + - !ruby/object:Gem::Version + version: "0" + version: +requirements: [] + +rubyforge_project: fakeweb +rubygems_version: 1.3.4 +signing_key: +specification_version: 3 +summary: A tool for faking responses to HTTP requests +test_files: +- test/fixtures/google_response_from_curl +- test/fixtures/google_response_with_transfer_encoding +- test/fixtures/google_response_without_transfer_encoding +- test/fixtures/test_example.txt +- test/fixtures/test_txt_file +- test/test_allow_net_connect.rb +- test/test_deprecations.rb +- test/test_fake_authentication.rb +- test/test_fake_web.rb +- test/test_fake_web_open_uri.rb +- test/test_helper.rb +- test/test_missing_open_uri.rb +- test/test_precedence.rb +- test/test_query_string.rb +- test/test_regexes.rb +- test/test_response_headers.rb +- test/test_trailing_slashes.rb +- test/test_utility.rb diff --git a/vendor/gems/fakeweb-1.2.5/CHANGELOG b/vendor/gems/fakeweb-1.2.5/CHANGELOG new file mode 100644 index 0000000..097a9d0 --- /dev/null +++ b/vendor/gems/fakeweb-1.2.5/CHANGELOG @@ -0,0 +1,163 @@ +fakeweb (1.2.5) + +* fix handling of userinfo strings that contain percent-encoded unsafe + characters [Chris Kampmeier, Ken Mayer] + +* fix that exact matches against strings/URIs with the :any method had a lower + precedence than regex matches using a real HTTP method (exact matches now + always take precedence) [Chris Kampmeier] + +* change request handling to raise an exception when more than one registered + regex matches a request URI [Chris Kampmeier] + + +fakeweb (1.2.4) + +* add experimental support for matching URIs via regular expressions + [Jacqui Maher, Tiago Albineli Motta, Peter Wagene] + +* fix an exception when registering with the :response option and a string that + is the same as the name of a directory in the current path [Chris Kampmeier] + +* DEPRECATION: Calling FakeWeb.register_uri with a :string or :file option is + now deprecated. Both options have been replaced with a unified :body option, + since they supply the response body (as opposed to :response, which supplies + the full response including headers) [Chris Kampmeier] + +* add support for specifying HTTP headers as options to FakeWeb.register_uri + when using the :string or :file response types, since those methods only + specify a response body [David Michael, Chris Kampmeier] + +* DEPRECATION: Calling FakeWeb.register_uri and FakeWeb.registered_uri? without + an HTTP method as the first argument is now deprecated. To match against any + HTTP method (the pre-1.2.0 behavior), use :any [Chris Kampmeier] + + +fakeweb (1.2.3) + +* fix the #http_version of :file and :string responses, which was returning the + request URI instead of something sensible like "1.0" [Chris Kampmeier] + +* add method aliases in the Net::HTTP patch to eliminate warnings when running + with -w [Joshua Clingenpeel] + +* fix that removing the redefinition of OpenURI::HTTPError in 1.2.0 caused + :exception responses to raise when OpenURI isn't available [Chris Kampmeier] + +* fix registering an :exception response with classes that require arguments for + instantiation, like Interrupt's subclasses [Chris Kampmeier] + + +fakeweb (1.2.2) + +* fix that HTTP Digest and OAuth requests could raise URI::InvalidURIErrors + [Bill Kocik, Chris Kampmeier] + + +fakeweb (1.2.1) + +* fix that query parameters are handled correctly when registering with a URI + object [Anselmo Alves, Chris Kampmeier] + +* fix an exception when registering with the :response option and a string + containing "\0" [Jonathan Baudanza, Chris Kampmeier] + +* fix that trailing slashes were considered significant for requests to the root + of a domain [Chris Kampmeier] + +* add support for HTTP basic authentication via userinfo strings in URIs + [Michael Bleigh] + + +fakeweb (1.2.0) + +* add lib/fakeweb.rb so you can require "fakeweb" as well [Chris Kampmeier] + +* fix compatibility with Ruby 1.9.1 [Chris Kampmeier] + +* fix that newlines in file-based responses could be doubled in the response + object's body [Mark Menard, Chris Kampmeier] + +* fix unnecessary munging of the transfer-encoding header, which improves + compatibility with mechanize [Mark Menard] + +* fix a test and the RCov dependency to be compatible with JRuby [Mark Menard] + +* remove an unnecessary redefinition of OpenURI::HTTPError [Josh Nichols] + +* rearrange implementation code into separate files, one per class [Josh Nichols] + +* fix a bug where FakeWeb.response_for would raise if the request wasn't + registered [Chris Kampmeier] + +* add HTTP method support, so FakeWeb takes both the URI and method into + account for registration, requests, and responses. Backwards-compatible with + the old method signatures, which didn't have a method param. [Chris Kampmeier] + +* start work on Ruby 1.9 compatibility [Chris Kampmeier] + +* add FakeWeb.allow_net_connect= to enable/disable the pass-through to + Net::HTTP for unregistered URIs [Mislav Marohnić, Chris Kampmeier] + +* remove setup.rb, since most people use RubyGems [Mislav Marohnić] + +* fix that 'http://example.com/?' (empty query) matches a registered + 'http://example.com/', and vice-versa [Mislav Marohnić] + +* improve the test suite to not rely on an internet connection [Chris Kampmeier] + +* use `rake test` instead of `rake tests` [Josh Nichols] + +* fix an incompatibility with Ruby 1.8.6 p36 where you'd get "Errno::EINTR: + Interrupted system call" exceptions in Socket#sysread for any non-faked + request [Chris Kampmeier] + +* response rotation: you can now optionally call FakeWeb.register_uri with an + array of options hashes; these are used, in order, to respond to + repeated requests (to repeat a response more than once before rotating, use + the :times option). Once you run out of responses, further requests always + receive the last response. [Michael Shapiro] + +* add support for Net::HTTP's undocumented full-URI request style (fixes + URI::InvalidURIErrors that you might see in older libraries) [Chris Kampmeier] + +* sort query params before storing internally, so that + http://example.com/?a=1&b=2 and http://example.com/?b=2&a=1 are considered the + same URL (although this is technically incorrect, it's much more + convenient--most web apps work that way, and Net::HTTP's use of a hash to pass + query params means that the order in which FakeWeb stores them can be + unpredictable) [Chris Kampmeier] + +* add support for ports in URLs, so that http://example.com/ and + http://example.com:3000/ are not the same [Chris Kampmeier] + +* fix for non-faked SSL requests failing with "Unable to create local socket" + [Chris Kampmeier] + +* update Rakefile to fix warning about deprecated code [Chris Kampmeier] + + +fakeweb (1.1.2) + +* add required dependencies to GemSpec to ensure that tests pass in firebrigade + (http://firebrigade.seattlerb.org/) [Blaine Cook] + + +fakeweb (1.1.1) + +* fix for non-existence of :string method on File as presented by open-uri + [Blaine Cook] + +* fix for curl example test - google redirects to ccTLDs for those outside US + [Blaine Cook] + + +fakeweb (1.1.0) + +* update code to correspond to ruby 1.8.4 (breaks compatibility with ruby 1.8.2) + [Blaine Cook] + + +fakeweb (1.0.0) + + * initial import [Blaine Cook] diff --git a/vendor/gems/fakeweb-1.2.5/LICENSE.txt b/vendor/gems/fakeweb-1.2.5/LICENSE.txt new file mode 100644 index 0000000..84e4948 --- /dev/null +++ b/vendor/gems/fakeweb-1.2.5/LICENSE.txt @@ -0,0 +1,281 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + diff --git a/vendor/gems/fakeweb-1.2.5/README.rdoc b/vendor/gems/fakeweb-1.2.5/README.rdoc new file mode 100644 index 0000000..eeea95a --- /dev/null +++ b/vendor/gems/fakeweb-1.2.5/README.rdoc @@ -0,0 +1,193 @@ += FakeWeb + +FakeWeb is a helper for faking web requests in Ruby. It works at a global +level, without modifying code or writing extensive stubs. + + +== Installation + +The latest release of FakeWeb is once again available from your friendly +RubyForge mirror. Just install the gem: + + sudo gem install fakeweb + +Note: the gem was previously available as +FakeWeb+ (capital letters), but now +all versions are simply registered as +fakeweb+. If you have any old +FakeWeb+ +gems lying around, remove them: sudo gem uninstall FakeWeb + + +== Help and discussion + +RDocs for the current release are available at http://fakeweb.rubyforge.org. + +There's a mailing list for questions and discussion at +http://groups.google.com/group/fakeweb-users. + +The main source repository is http://github.com/chrisk/fakeweb. + +== Examples + +Start by requiring FakeWeb: + + require 'rubygems' + require 'fakeweb' + +=== Registering basic string responses + + FakeWeb.register_uri(:get, "http://example.com/test1", :body => "Hello World!") + + Net::HTTP.get(URI.parse("http://example.com/test1")) + => "Hello World!" + + Net::HTTP.get(URI.parse("http://example.com/test2")) + => FakeWeb is bypassed and the response from a real request is returned + +You can also call register_uri with a regular expression, to match +more than one URI. + +=== Replaying a recorded response + + page = `curl -is http://www.google.com/` + FakeWeb.register_uri(:get, "http://www.google.com/", :response => page) + + Net::HTTP.get(URI.parse("http://www.google.com/")) + # => Full response, including headers + +=== Adding a custom status to the response + + FakeWeb.register_uri(:get, "http://example.com/", :body => "Nothing to be found 'round here", + :status => ["404", "Not Found"]) + + Net::HTTP.start("example.com") do |req| + response = req.get("/") + response.code # => "404" + response.message # => "Not Found" + response.body # => "Nothing to be found 'round here" + end + +=== Responding to any HTTP method + + FakeWeb.register_uri(:any, "http://example.com", :body => "response for any HTTP method") + +If you use the :any symbol, the URI you specify will be completely +stubbed out (regardless of the HTTP method of the request). This can be useful +for RPC-like services, where the HTTP method isn't significant. (Older +versions of FakeWeb always behaved like this, and didn't accept the first ++method+ argument above; this syntax is now deprecated.) + +=== Rotating responses + +You can optionally call FakeWeb.register_uri with an array of options hashes; +these are used, in order, to respond to repeated requests. Once you run out of +responses, further requests always receive the last response. (You can also send +a response more than once before rotating, by specifying a :times +option for that response.) + + FakeWeb.register_uri(:delete, "http://example.com/posts/1", + [{:body => "Post 1 deleted.", :status => ["200", "OK"]}, + {:body => "Post not found", :status => ["404", "Not Found"]}]) + + Net::HTTP.start("example.com") do |req| + req.delete("/posts/1").body # => "Post 1 deleted" + req.delete("/posts/1").body # => "Post not found" + req.delete("/posts/1").body # => "Post not found" + end + +=== Using HTTP basic authentication + +You can stub requests that use basic authentication with +userinfo+ strings in +the URIs: + + FakeWeb.register_uri(:get, "http://example.com/secret", :body => "Unauthorized", :status => ["401", "Unauthorized"]) + FakeWeb.register_uri(:get, "http://user:pass@example.com/secret", :body => "Authorized") + + Net::HTTP.start("example.com") do |http| + req = Net::HTTP::Get.new("/secret") + http.request(req) # => "Unauthorized" + req.basic_auth("user", "pass") + http.request(req) # => "Authorized" + end + +=== Clearing registered URIs + +The FakeWeb registry is a singleton that lasts for the duration of your +program, maintaining every fake response you register. If needed, you +can clean out the registry and remove all registered URIs: + + FakeWeb.clean_registry + +=== Blocking all real requests + +When you're using FakeWeb to replace _all_ of your requests, it's useful to +catch when requests are made for unregistered URIs (unlike the default +behavior, which is to pass those requests through to Net::HTTP as usual). + + FakeWeb.allow_net_connect = false + Net::HTTP.get(URI.parse("http://example.com/")) + => raises FakeWeb::NetConnectNotAllowedError + + FakeWeb.allow_net_connect = true + Net::HTTP.get(URI.parse("http://example.com/")) + => FakeWeb is bypassed and the response from a real request is returned + +This is handy when you want to make sure your tests are self-contained, or you +want to catch the scenario when a URI is changed in implementation code +without a corresponding test change. + +=== Specifying HTTP response headers + +When you register a response using the :body option, you're only +setting the body of the response. If you want to add headers to these responses, +simply add the header as an option to +register_uri+: + + FakeWeb.register_uri(:get, "http://example.com/hello.txt", :body => "Hello", :content_type => "text/plain") + +This sets the "Content-Type" header in the response. + +== More info + +FakeWeb lets you decouple your test environment from live services without +modifying code or writing extensive stubs. + +In addition to the conceptual advantage of having idempotent request +behaviour, FakeWeb makes tests run faster than if they were made to remote (or +even local) web servers. It also makes it possible to run tests without a +network connection or in situations where the server is behind a firewall or +has host-based access controls. + +FakeWeb works with anything based on Net::HTTP--both higher-level wrappers, +like OpenURI, as well as a ton of libraries for popular web services. + + +== Known Issues + +* Request bodies are ignored, including PUT and POST parameters. If you need + different responses for different request bodies, you need to request + different URLs, and register different responses for each. (Query strings are + fully supported, though.) We're currently considering how the API should + change to add support for request bodies in 1.3.0. Your input would be really + helpful: see http://groups.google.com/group/fakeweb-users/browse_thread/thread/44d190a6b12e4273 + for a discussion of some different options. Thanks! + + +== Copyright + +Copyright 2006-2007 Blaine Cook + +Copyright 2008-2009 various contributors + + FakeWeb is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any later + version. + + FakeWeb is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. + + You should have received a copy of the GNU General Public License along + with FakeWeb; if not, write to the Free Software Foundation, Inc., 51 + Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +See LICENSE.txt for the full terms. diff --git a/vendor/gems/fakeweb-1.2.5/Rakefile b/vendor/gems/fakeweb-1.2.5/Rakefile new file mode 100644 index 0000000..97a32b8 --- /dev/null +++ b/vendor/gems/fakeweb-1.2.5/Rakefile @@ -0,0 +1,76 @@ +puts "Using ruby #{RUBY_VERSION}p#{RUBY_PATCHLEVEL}" + +require 'rubygems' +require 'rake/gempackagetask' +require 'rake/testtask' +begin + require 'rdoc/task' +rescue LoadError + puts "\nIt looks like you're using an old version of RDoc, but FakeWeb requires a newer one." + puts "You can try upgrading with `sudo gem install rdoc`.\n\n" + raise +end + +task :default => :test + +desc "Run All Tests" +Rake::TestTask.new :test do |test| + test.test_files = ["test/**/*.rb"] + test.verbose = false +end + +desc "Generate Documentation" +RDoc::Task.new do |rdoc| + rdoc.main = "README.rdoc" + rdoc.rdoc_dir = "doc" + rdoc.rdoc_files.include("README.rdoc", "CHANGELOG", "LICENSE.txt", "lib/*.rb") + rdoc.title = "FakeWeb API Documentation" + rdoc.options << '--line-numbers' << '--charset' << 'utf-8' +end + +desc %{Update ".manifest" with the latest list of project filenames. Respect\ +.gitignore by excluding everything that git ignores. Update `files` and\ +`test_files` arrays in "*.gemspec" file if it's present.} +task :manifest do + list = Dir['**/*'].sort + spec_file = Dir['*.gemspec'].first + list -= [spec_file] if spec_file + + File.read('.gitignore').each_line do |glob| + glob = glob.chomp.sub(/^\//, '') + list -= Dir[glob] + list -= Dir["#{glob}/**/*"] if File.directory?(glob) and !File.symlink?(glob) + puts "excluding #{glob}" + end + + if spec_file + spec = File.read spec_file + spec.gsub!(/^(\s* s.(test_)?files \s* = \s* )( \[ [^\]]* \] | %w\( [^)]* \) )/mx) do + assignment = $1 + bunch = $2 ? list.grep(/^test\//) : list + '%s%%w(%s)' % [assignment, bunch.join(' ')] + end + + File.open(spec_file, 'w') {|f| f << spec } + end + File.open('.manifest', 'w') {|f| f << list.join("\n") } +end + +if RUBY_PLATFORM =~ /java/ + puts "rcov support disabled (running under JRuby)." +elsif RUBY_VERSION =~ /^1\.9/ + puts "rcov support disabled (running under Ruby 1.9)" +else + require 'rcov/rcovtask' + Rcov::RcovTask.new do |t| + t.test_files = FileList['test/**/test*.rb'] + t.rcov_opts << "--sort coverage" + t.rcov_opts << "--exclude gems" + end +end + +spec = eval(File.read(File.join(File.dirname(__FILE__), "fakeweb.gemspec"))) +Rake::GemPackageTask.new(spec) do |pkg| + pkg.need_tar_gz = true + pkg.need_zip = true +end diff --git a/vendor/gems/fakeweb-1.2.5/lib/fake_web.rb b/vendor/gems/fakeweb-1.2.5/lib/fake_web.rb new file mode 100644 index 0000000..9428eca --- /dev/null +++ b/vendor/gems/fakeweb-1.2.5/lib/fake_web.rb @@ -0,0 +1,172 @@ +require 'singleton' + +require 'fake_web/ext/net_http' +require 'fake_web/registry' +require 'fake_web/response' +require 'fake_web/responder' +require 'fake_web/stub_socket' +require 'fake_web/utility' + +module FakeWeb + + # Resets the FakeWeb Registry. This will force all subsequent web requests to + # behave as real requests. + def self.clean_registry + Registry.instance.clean_registry + end + + # Enables or disables real HTTP connections for requests that don't match + # registered URIs. + # + # If you set FakeWeb.allow_net_connect = false and subsequently try + # to make a request to a URI you haven't registered with #register_uri, a + # NetConnectNotAllowedError will be raised. This is handy when you want to + # make sure your tests are self-contained, or want to catch the scenario + # when a URI is changed in implementation code without a corresponding test + # change. + # + # When FakeWeb.allow_net_connect = true (the default), requests to + # URIs not stubbed with FakeWeb are passed through to Net::HTTP. + def self.allow_net_connect=(allowed) + @allow_net_connect = allowed + end + + # Enable pass-through to Net::HTTP by default. + self.allow_net_connect = true + + # Returns +true+ if requests to URIs not registered with FakeWeb are passed + # through to Net::HTTP for normal processing (the default). Returns +false+ + # if an exception is raised for these requests. + def self.allow_net_connect? + @allow_net_connect + end + + # This exception is raised if you set FakeWeb.allow_net_connect = + # false and subsequently try to make a request to a URI you haven't + # stubbed. + class NetConnectNotAllowedError < StandardError; end; + + # This exception is raised if a Net::HTTP request matches more than one of + # the regular expression-based stubs you've registered. To fix the problem, + # disambiguate the regular expressions by making them more specific. + class MultipleMatchingRegexpsError < StandardError; end; + + # call-seq: + # FakeWeb.register_uri(method, uri, options) + # + # Register requests using the HTTP method specified by the symbol +method+ + # for +uri+ to be handled according to +options+. If you specify the method + # :any, the response will be reigstered for any request for +uri+. + # +uri+ can be a +String+, +URI+, or +Regexp+ object. +options+ must be either + # a +Hash+ or an +Array+ of +Hashes+ (see below), which must contain one of + # these two keys: + # + # :body:: + # A string which is used as the body of the response. If the string refers + # to a valid filesystem path, the contents of that file will be read and used + # as the body of the response instead. (This used to be two options, + # :string and :file, respectively. These are now deprecated.) + # :response:: + # Either an Net::HTTPResponse, an +IO+, or a +String+ which is used + # as the full response for the request. + # + # The easier way by far is to pass the :response option to + # +register_uri+ as a +String+ or an (open for reads) +IO+ object which + # will be used as the complete HTTP response, including headers and body. + # If the string points to a readable file, this file will be used as the + # content for the request. + # + # To obtain a complete response document, you can use the +curl+ command, + # like so: + # + # curl -i http://www.example.com/ > response_for_www.example.com + # + # which can then be used in your test environment like so: + # + # FakeWeb.register_uri(:get, 'http://www.example.com/', :response => 'response_for_www.example.com') + # + # See the Net::HTTPResponse + # documentation[http://ruby-doc.org/stdlib/libdoc/net/http/rdoc/classes/Net/HTTPResponse.html] + # for more information on creating custom response objects. + # + # +options+ may also be an +Array+ containing a list of the above-described + # +Hash+. In this case, FakeWeb will rotate through each provided response, + # you may optionally provide: + # + # :times:: + # The number of times this response will be used. Decremented by one each time it's called. + # FakeWeb will use the final provided request indefinitely, regardless of its :times parameter. + # + # Two optional arguments are also accepted: + # + # :status:: + # Passing :status as a two-value array will set the response code + # and message. The defaults are 200 and OK, respectively. + # Example: + # FakeWeb.register_uri("http://www.example.com/", :body => "Go away!", :status => [404, "Not Found"]) + # :exception:: + # The argument passed via :exception will be raised when the + # specified URL is requested. Any +Exception+ class is valid. Example: + # FakeWeb.register_uri('http://www.example.com/', :exception => Net::HTTPError) + # + # If you're using the :body response type, you can pass additional + # options to specify the HTTP headers to be used in the response. Example: + # + # FakeWeb.register_uri(:get, "http://example.com/index.txt", :body => "Hello", :content_type => "text/plain") + def self.register_uri(*args) + case args.length + when 3 + Registry.instance.register_uri(*args) + when 2 + print_missing_http_method_deprecation_warning(*args) + Registry.instance.register_uri(:any, *args) + else + raise ArgumentError.new("wrong number of arguments (#{args.length} for 3)") + end + end + + # call-seq: + # FakeWeb.response_for(method, uri) + # + # Returns the faked Net::HTTPResponse object associated with +method+ and +uri+. + def self.response_for(*args, &block) #:nodoc: :yields: response + case args.length + when 2 + Registry.instance.response_for(*args, &block) + when 1 + print_missing_http_method_deprecation_warning(*args) + Registry.instance.response_for(:any, *args, &block) + else + raise ArgumentError.new("wrong number of arguments (#{args.length} for 2)") + end + end + + # call-seq: + # FakeWeb.registered_uri?(method, uri) + # + # Returns true if a +method+ request for +uri+ is registered with FakeWeb. + # Specify a method of :any to check for against all HTTP methods. + def self.registered_uri?(*args) + case args.length + when 2 + Registry.instance.registered_uri?(*args) + when 1 + print_missing_http_method_deprecation_warning(*args) + Registry.instance.registered_uri?(:any, *args) + else + raise ArgumentError.new("wrong number of arguments (#{args.length} for 2)") + end + end + + private + + def self.print_missing_http_method_deprecation_warning(*args) + method = caller.first.match(/`(.*?)'/)[1] + new_args = args.map { |a| a.inspect }.unshift(":any") + new_args.last.gsub!(/^\{|\}$/, "").gsub!("=>", " => ") if args.last.is_a?(Hash) + $stderr.puts + $stderr.puts "Deprecation warning: FakeWeb requires an HTTP method argument (or use :any). Try this:" + $stderr.puts " FakeWeb.#{method}(#{new_args.join(', ')})" + $stderr.puts "Called at #{caller[1]}" + end +end diff --git a/vendor/gems/fakeweb-1.2.5/lib/fake_web/ext/net_http.rb b/vendor/gems/fakeweb-1.2.5/lib/fake_web/ext/net_http.rb new file mode 100644 index 0000000..13ea666 --- /dev/null +++ b/vendor/gems/fakeweb-1.2.5/lib/fake_web/ext/net_http.rb @@ -0,0 +1,71 @@ +require 'net/http' +require 'net/https' +require 'stringio' + +module Net #:nodoc: all + + class BufferedIO + alias initialize_without_fakeweb initialize + def initialize(io, debug_output = nil) + @read_timeout = 60 + @rbuf = '' + @debug_output = debug_output + + @io = case io + when Socket, OpenSSL::SSL::SSLSocket, IO + io + when String + if !io.include?("\0") && File.exists?(io) && !File.directory?(io) + File.open(io, "r") + else + StringIO.new(io) + end + end + raise "Unable to create local socket" unless @io + end + end + + class HTTP + class << self + alias socket_type_without_fakeweb socket_type + def socket_type + FakeWeb::StubSocket + end + end + + alias request_without_fakeweb request + def request(request, body = nil, &block) + protocol = use_ssl? ? "https" : "http" + + path = request.path + path = URI.parse(request.path).request_uri if request.path =~ /^http/ + + if request["authorization"] =~ /^Basic / + userinfo = FakeWeb::Utility.decode_userinfo_from_header(request["authorization"]) + userinfo = FakeWeb::Utility.encode_unsafe_chars_in_userinfo(userinfo) + "@" + else + userinfo = "" + end + + uri = "#{protocol}://#{userinfo}#{self.address}:#{self.port}#{path}" + method = request.method.downcase.to_sym + + if FakeWeb.registered_uri?(method, uri) + @socket = Net::HTTP.socket_type.new + FakeWeb.response_for(method, uri, &block) + elsif FakeWeb.allow_net_connect? + connect_without_fakeweb + request_without_fakeweb(request, body, &block) + else + uri = FakeWeb::Utility.strip_default_port_from_uri(uri) + raise FakeWeb::NetConnectNotAllowedError, + "Real HTTP connections are disabled. Unregistered request: #{request.method} #{uri}" + end + end + + alias connect_without_fakeweb connect + def connect + end + end + +end diff --git a/vendor/gems/fakeweb-1.2.5/lib/fake_web/registry.rb b/vendor/gems/fakeweb-1.2.5/lib/fake_web/registry.rb new file mode 100644 index 0000000..ed59524 --- /dev/null +++ b/vendor/gems/fakeweb-1.2.5/lib/fake_web/registry.rb @@ -0,0 +1,103 @@ +module FakeWeb + class Registry #:nodoc: + include Singleton + + attr_accessor :uri_map + + def initialize + clean_registry + end + + def clean_registry + self.uri_map = Hash.new { |hash, key| hash[key] = {} } + end + + def register_uri(method, uri, options) + uri_map[normalize_uri(uri)][method] = [*[options]].flatten.collect do |option| + FakeWeb::Responder.new(method, uri, option, option[:times]) + end + end + + def registered_uri?(method, uri) + normalized_uri = normalize_uri(uri) + !responses_for(method, uri).empty? + end + + def response_for(method, uri, &block) + responses = responses_for(method, uri) + return nil if responses.empty? + + next_response = responses.last + responses.each do |response| + if response.times and response.times > 0 + response.times -= 1 + next_response = response + break + end + end + + next_response.response(&block) + end + + + private + + def responses_for(method, uri) + uri = normalize_uri(uri) + + if uri_map[uri].has_key?(method) + uri_map[uri][method] + elsif uri_map[uri].has_key?(:any) + uri_map[uri][:any] + elsif uri_map_matches?(method, uri) + uri_map_matches(method, uri) + elsif uri_map_matches(:any, uri) + uri_map_matches(:any, uri) + else + [] + end + end + + def uri_map_matches?(method, uri) + !uri_map_matches(method, uri).nil? + end + + def uri_map_matches(method, uri) + uri = normalize_uri(uri.to_s).to_s + uri = Utility.strip_default_port_from_uri(uri) + + matches = uri_map.select { |registered_uri, method_hash| + registered_uri.is_a?(Regexp) && uri.match(registered_uri) && method_hash.has_key?(method) + } + + if matches.size > 1 + raise MultipleMatchingRegexpsError, + "More than one regular expression matched this request: #{method.to_s.upcase} #{uri}" + end + + matches.map { |_, method_hash| method_hash[method] }.first + end + + def normalize_uri(uri) + return uri if uri.is_a?(Regexp) + normalized_uri = + case uri + when URI then uri + when String + uri = 'http://' + uri unless uri.match('^https?://') + URI.parse(uri) + end + normalized_uri.query = sort_query_params(normalized_uri.query) + normalized_uri.normalize + end + + def sort_query_params(query) + if query.nil? || query.empty? + nil + else + query.split('&').sort.join('&') + end + end + + end +end diff --git a/vendor/gems/fakeweb-1.2.5/lib/fake_web/responder.rb b/vendor/gems/fakeweb-1.2.5/lib/fake_web/responder.rb new file mode 100644 index 0000000..e7b0ede --- /dev/null +++ b/vendor/gems/fakeweb-1.2.5/lib/fake_web/responder.rb @@ -0,0 +1,113 @@ +module FakeWeb + class Responder #:nodoc: + + attr_accessor :method, :uri, :options, :times + KNOWN_OPTIONS = [:body, :exception, :response, :status].freeze + + def initialize(method, uri, options, times) + self.method = method + self.uri = uri + self.options = options + self.times = times ? times : 1 + + if options.has_key?(:file) || options.has_key?(:string) + print_file_string_options_deprecation_warning + options[:body] = options.delete(:file) || options.delete(:string) + end + end + + def response(&block) + if has_baked_response? + response = baked_response + else + code, msg = meta_information + response = Net::HTTPResponse.send(:response_class, code.to_s).new("1.0", code.to_s, msg) + response.instance_variable_set(:@body, body) + headers_extracted_from_options.each { |name, value| response[name] = value } + end + + response.instance_variable_set(:@read, true) + response.extend FakeWeb::Response + + optionally_raise(response) + + yield response if block_given? + + response + end + + private + + def headers_extracted_from_options + options.reject {|name, _| KNOWN_OPTIONS.include?(name) }.map { |name, value| + [name.to_s.split("_").map { |segment| segment.capitalize }.join("-"), value] + } + end + + def body + return '' unless options.has_key?(:body) + + if !options[:body].include?("\0") && File.exists?(options[:body]) && !File.directory?(options[:body]) + File.read(options[:body]) + else + options[:body] + end + end + + def baked_response + resp = case options[:response] + when Net::HTTPResponse then options[:response] + when String + socket = Net::BufferedIO.new(options[:response]) + r = Net::HTTPResponse.read_new(socket) + + # Store the oiriginal transfer-encoding + saved_transfer_encoding = r.instance_eval { + @header['transfer-encoding'] if @header.key?('transfer-encoding') + } + + # read the body of response. + r.instance_eval { @header['transfer-encoding'] = nil } + r.reading_body(socket, true) {} + + # Delete the transfer-encoding key from r.@header if there wasn't one, + # else restore the saved_transfer_encoding. + if saved_transfer_encoding.nil? + r.instance_eval { @header.delete('transfer-encoding') } + else + r.instance_eval { @header['transfer-encoding'] = saved_transfer_encoding } + end + r + else raise StandardError, "Handler unimplemented for response #{options[:response]}" + end + end + + def has_baked_response? + options.has_key?(:response) + end + + def optionally_raise(response) + return unless options.has_key?(:exception) + + case options[:exception].to_s + when "Net::HTTPError", "OpenURI::HTTPError" + raise options[:exception].new('Exception from FakeWeb', response) + else + raise options[:exception].new('Exception from FakeWeb') + end + end + + def meta_information + options.has_key?(:status) ? options[:status] : [200, 'OK'] + end + + def print_file_string_options_deprecation_warning + which = options.has_key?(:file) ? :file : :string + $stderr.puts + $stderr.puts "Deprecation warning: FakeWeb's :#{which} option has been renamed to :body." + $stderr.puts "Just replace :#{which} with :body in your FakeWeb.register_uri calls." + $stderr.puts "Called at #{caller[6]}" + end + + end +end \ No newline at end of file diff --git a/vendor/gems/fakeweb-1.2.5/lib/fake_web/response.rb b/vendor/gems/fakeweb-1.2.5/lib/fake_web/response.rb new file mode 100644 index 0000000..41ba255 --- /dev/null +++ b/vendor/gems/fakeweb-1.2.5/lib/fake_web/response.rb @@ -0,0 +1,10 @@ +module FakeWeb + module Response #:nodoc: + + def read_body(*args, &block) + yield @body if block_given? + @body + end + + end +end \ No newline at end of file diff --git a/vendor/gems/fakeweb-1.2.5/lib/fake_web/stub_socket.rb b/vendor/gems/fakeweb-1.2.5/lib/fake_web/stub_socket.rb new file mode 100644 index 0000000..008681c --- /dev/null +++ b/vendor/gems/fakeweb-1.2.5/lib/fake_web/stub_socket.rb @@ -0,0 +1,15 @@ +module FakeWeb + class StubSocket #:nodoc: + + def initialize(*args) + end + + def closed? + @closed ||= true + end + + def readuntil(*args) + end + + end +end \ No newline at end of file diff --git a/vendor/gems/fakeweb-1.2.5/lib/fake_web/utility.rb b/vendor/gems/fakeweb-1.2.5/lib/fake_web/utility.rb new file mode 100644 index 0000000..c3c0d52 --- /dev/null +++ b/vendor/gems/fakeweb-1.2.5/lib/fake_web/utility.rb @@ -0,0 +1,22 @@ +module FakeWeb + module Utility #:nodoc: + + def self.decode_userinfo_from_header(header) + header.sub(/^Basic /, "").unpack("m").first + end + + def self.encode_unsafe_chars_in_userinfo(userinfo) + unsafe_in_userinfo = /[^#{URI::REGEXP::PATTERN::UNRESERVED};&=+$,]|^(#{URI::REGEXP::PATTERN::ESCAPED})/ + userinfo.split(":").map { |part| URI.escape(part, unsafe_in_userinfo) }.join(":") + end + + def self.strip_default_port_from_uri(uri) + case uri + when %r{^http://} then uri.sub(%r{:80(/|$)}, '\1') + when %r{^https://} then uri.sub(%r{:443(/|$)}, '\1') + else uri + end + end + + end +end diff --git a/vendor/gems/fakeweb-1.2.5/lib/fakeweb.rb b/vendor/gems/fakeweb-1.2.5/lib/fakeweb.rb new file mode 100644 index 0000000..6982966 --- /dev/null +++ b/vendor/gems/fakeweb-1.2.5/lib/fakeweb.rb @@ -0,0 +1,2 @@ +# So you can require "fakeweb" instead of "fake_web" +require "fake_web" \ No newline at end of file diff --git a/vendor/gems/fakeweb-1.2.5/test/fixtures/google_response_from_curl b/vendor/gems/fakeweb-1.2.5/test/fixtures/google_response_from_curl new file mode 100644 index 0000000..fe2fe39 --- /dev/null +++ b/vendor/gems/fakeweb-1.2.5/test/fixtures/google_response_from_curl @@ -0,0 +1,12 @@ +HTTP/1.1 200 OK +Cache-Control: private, max-age=0 +Date: Sun, 01 Feb 2009 02:16:24 GMT +Expires: -1 +Content-Type: text/html; charset=ISO-8859-1 +Set-Cookie: PREF=ID=a6d9b5f5a4056dfe:TM=1233454584:LM=1233454584:S=U9pSwSu4eQwOPenX; expires=Tue, 01-Feb-2011 02:16:24 GMT; path=/; domain=.google.com +Server: gws +Transfer-Encoding: chunked + +
©2009 - Privacy
©2009 - Privacy
©2009 - Privacy
+ joe = User.find(1)
+ joe.purchase_home()
+ assert !joe.mortgage_due?
+ # move ahead a month and assert that the mortgage is due
+ Timecop.freeze(Date.today + 30) do
+ assert joe.mortgage_due?
+ end
+
+
+* Set the time for the test environment of a rails app -- this is particularly helpful if your whole application
+ is time-sensitive. It allows you to build your test data at a single point in time, and to move in/out of that
+ time as appropriate (within your tests)
+
+in config/environments/test.rb
+
+
+config.after_initialize do
+ # Set Time.now to September 1, 2008 10:05:00 AM
+ t = Time.local(2008, 9, 1, 10, 5, 0)
+ Timecop.travel(t)
+end
+
+
+h2. REQUIREMENTS
+
+* None
+
+h2. INSTALL
+
+* sudo gem install timecop (latest stable version from rubyforge)
+* sudo gem install jtrupiano-timecop (HEAD of the repo from github)
+
+h2. LICENSE
+
+(The MIT License)
+
+Copyright (c) 2008 FIX
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/gems/jtrupiano-timecop-0.2.1/Rakefile b/vendor/gems/jtrupiano-timecop-0.2.1/Rakefile
new file mode 100644
index 0000000..8c2b381
--- /dev/null
+++ b/vendor/gems/jtrupiano-timecop-0.2.1/Rakefile
@@ -0,0 +1,31 @@
+require 'rake'
+require 'rake/testtask'
+require 'rake/rdoctask'
+
+begin
+ require 'jeweler'
+ Jeweler::Tasks.new do |s|
+ s.name = "timecop"
+ s.rubyforge_project = 'johntrupiano' # if different than lowercase project name
+ 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.)
+ s.summary = s.description # More details later??
+ s.email = "jtrupiano@gmail.com"
+ s.homepage = "http://github.com/jtrupiano/timecop"
+ s.authors = ["John Trupiano"]
+ s.files = FileList["[A-Z]*", "{bin,lib,test}/**/*"]
+ #s.add_dependency 'schacon-git'
+ end
+rescue LoadError
+ puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
+end
+
+# Override the test task and instruct them how to actually run the tests.
+Rake.application.send(:eval, "@tasks.delete('test')")
+desc "Does not execute tests. Manually run shell script ./run_tests.sh to execute tests."
+task :test do
+ puts <<-MSG
+ In order to run the test suite, run: cd test && ./run_tests.sh
+ The tests need to be run with different libraries loaded, which rules out using Rake
+ to automate them.
+ MSG
+end
diff --git a/vendor/gems/jtrupiano-timecop-0.2.1/VERSION.yml b/vendor/gems/jtrupiano-timecop-0.2.1/VERSION.yml
new file mode 100644
index 0000000..a324906
--- /dev/null
+++ b/vendor/gems/jtrupiano-timecop-0.2.1/VERSION.yml
@@ -0,0 +1,4 @@
+---
+:major: 0
+:minor: 2
+:patch: 1
diff --git a/vendor/gems/jtrupiano-timecop-0.2.1/lib/timecop.rb b/vendor/gems/jtrupiano-timecop-0.2.1/lib/timecop.rb
new file mode 100644
index 0000000..5dad1e8
--- /dev/null
+++ b/vendor/gems/jtrupiano-timecop-0.2.1/lib/timecop.rb
@@ -0,0 +1,3 @@
+# place gem dependencies here...
+#require 'timecop/timecop'
+require File.join(File.dirname(__FILE__), 'timecop', 'timecop')
\ No newline at end of file
diff --git a/vendor/gems/jtrupiano-timecop-0.2.1/lib/timecop/stack_item.rb b/vendor/gems/jtrupiano-timecop-0.2.1/lib/timecop/stack_item.rb
new file mode 100644
index 0000000..f6d0a3d
--- /dev/null
+++ b/vendor/gems/jtrupiano-timecop-0.2.1/lib/timecop/stack_item.rb
@@ -0,0 +1,11 @@
+
+# Simply a data class for carrying around "time movement" objects. Makes it easy to keep track of the time
+# movements on a simple stack.
+class StackItem
+
+ attr_reader :mock_type, :year, :month, :day, :hour, :minute, :second
+ def initialize(mock_type, year, month, day, hour, minute, second)
+ @mock_type, @year, @month, @day, @hour, @minute, @second = mock_type, year, month, day, hour, minute, second
+ end
+end
+
diff --git a/vendor/gems/jtrupiano-timecop-0.2.1/lib/timecop/time_extensions.rb b/vendor/gems/jtrupiano-timecop-0.2.1/lib/timecop/time_extensions.rb
new file mode 100644
index 0000000..95698ae
--- /dev/null
+++ b/vendor/gems/jtrupiano-timecop-0.2.1/lib/timecop/time_extensions.rb
@@ -0,0 +1,96 @@
+# 1. Extensions to the Time, Date, and DateTime objects
+# 2. Allows us to "freeze" time in our Ruby applications.
+# 3. This is very useful when your app's functionality is dependent on time (e.g.
+# anything that might expire). This will allow us to alter the return value of
+# Date.today, Time.now, and DateTime.now, such that our application code _never_ has to change.
+
+class Time
+ class << self
+ # Time we might be behaving as
+ #attr_reader :mock_time
+
+ @@mock_offset = nil
+ @@mock_time = nil
+
+ def mock_time
+ if !@@mock_offset.nil?
+ now_without_mock_time - @@mock_offset
+ else
+ @@mock_time
+ end
+ end
+
+ # Set new time to pretend we are.
+ def freeze_time(new_now)
+ @@mock_time = new_now
+ @@mock_offset = nil
+ end
+
+ def move_time(new_now)
+ @@mock_offset = new_now.nil? ? nil : (now_without_mock_time - new_now)
+ @@mock_time = nil
+ end
+
+ # Restores Time to system clock
+ def unmock!
+ move_time(nil)
+ end
+
+ # Alias the original now
+ alias_method :now_without_mock_time, :now
+
+ # Define now_with_mock_time
+ def now_with_mock_time
+ mock_time || now_without_mock_time
+ end
+
+ # Alias now to now_with_mock_time
+ alias_method :now, :now_with_mock_time
+ end
+end
+
+if Object.const_defined?(:Date)
+ class Date
+ class << self
+ def mock_date
+ now = Time.mock_time
+ return nil if now.nil?
+ Date.new(now.year, now.month, now.day)
+ end
+
+ # Alias the original today
+ alias_method :today_without_mock_date, :today
+
+ # Define today_with_mock_date
+ def today_with_mock_date
+ mock_date || today_without_mock_date
+ end
+
+ # Alias today to today_with_mock_date
+ alias_method :today, :today_with_mock_date
+ end
+ end
+end
+
+if Object.const_defined?(:DateTime)
+ class DateTime
+ class << self
+ def mock_time
+ t_now = Time.mock_time
+ return nil if t_now.nil?
+ DateTime.new(t_now.year, t_now.month, t_now.day, t_now.hour, t_now.min, t_now.sec)
+ end
+
+ # Alias the original now
+ alias_method :now_without_mock_time, :now
+
+ # Define now_with_mock_time
+ def now_with_mock_time
+ mock_time || now_without_mock_time
+ end
+
+ # Alias now to now_with_mock_time
+ alias_method :now, :now_with_mock_time
+ end
+ end
+end
\ No newline at end of file
diff --git a/vendor/gems/jtrupiano-timecop-0.2.1/lib/timecop/timecop.rb b/vendor/gems/jtrupiano-timecop-0.2.1/lib/timecop/timecop.rb
new file mode 100644
index 0000000..d47458b
--- /dev/null
+++ b/vendor/gems/jtrupiano-timecop-0.2.1/lib/timecop/timecop.rb
@@ -0,0 +1,198 @@
+require 'singleton'
+require File.join(File.dirname(__FILE__), 'time_extensions')
+require File.join(File.dirname(__FILE__), 'stack_item')
+
+# Timecop
+# * Wrapper class for manipulating the extensions to the Time, Date, and DateTime objects
+# * Allows us to "freeze" time in our Ruby applications.
+# * Optionally allows time travel to simulate a running clock, such time is not technically frozen.
+#
+# This is very useful when your app's functionality is dependent on time (e.g.
+# anything that might expire). This will allow us to alter the return value of
+# Date.today, Time.now, and DateTime.now, such that our application code _never_ has to change.
+class Timecop
+ include Singleton
+
+ # Allows you to run a block of code and "fake" a time throughout the execution of that block.
+ # This is particularly useful for writing test methods where the passage of time is critical to the business
+ # logic being tested. For example:
+ #
+ #
+ # joe = User.find(1)
+ # joe.purchase_home()
+ # assert !joe.mortgage_due?
+ # Timecop.freeze(2008, 10, 5) do
+ # assert joe.mortgage_due?
+ # end
+ #
+ #
+ # freeze and travel will respond to several different arguments:
+ # 1. Timecop.freeze(time_inst)
+ # 2. Timecop.freeze(datetime_inst)
+ # 3. Timecop.freeze(date_inst)
+ # 4. Timecop.freeze(year, month, day, hour=0, minute=0, second=0)
+ #
+ # When a block is also passed, Time.now, DateTime.now and Date.today are all reset to their
+ # previous values. This allows us to nest multiple calls to Timecop.travel and have each block
+ # maintain it's concept of "now."
+ #
+ # * Note: Timecop.freeze will actually freeze time. This can cause unanticipated problems if
+ # benchmark or other timing calls are executed, which implicitly expect Time to actually move
+ # forward.
+ #
+ # * Rails Users: Be especially careful when setting this in your development environment in a
+ # rails project. Generators will load your environment, including the migration generator,
+ # which will lead to files being generated with the timestamp set by the Timecop.freeze call
+ # in your dev environment
+ def self.freeze(*args, &block)
+ instance().send(:travel, :freeze, *args, &block)
+ end
+
+ # Allows you to run a block of code and "fake" a time throughout the execution of that block.
+ # See Timecop#freeze for a sample of how to use (same exact usage syntax)
+ #
+ # * Note: Timecop.travel will not freeze time (as opposed to Timecop.freeze). This is a particularly
+ # good candidate for use in environment files in rails projects.
+ def self.travel(*args, &block)
+ instance().send(:travel, :move, *args, &block)
+ end
+
+ # Reverts back to system's Time.now, Date.today and DateTime.now (if it exists). If freeze_all or rebase_all
+ # was never called in the first place, this method will have no effect.
+ def self.return
+ instance().send(:unmock!)
+ end
+
+ # [Deprecated]: See Timecop#return instead.
+ def self.unset_all
+ $stderr.puts "Timecop#unset_all is deprecated. Please use Timecop#return instead."
+ $stderr.flush
+ self.return
+ end
+
+ protected
+
+ def initialize
+ @_stack = []
+ end
+
+ def travel(mock_type, *args, &block)
+ # parse the arguments, build our base time units
+ year, month, day, hour, minute, second = parse_travel_args(*args)
+
+ # perform our action
+ if mock_type == :freeze
+ freeze_all(year, month, day, hour, minute, second)
+ else
+ move_all(year, month, day, hour, minute, second)
+ end
+ # store this time traveling on our stack...
+ @_stack << StackItem.new(mock_type, year, month, day, hour, minute, second)
+
+ if block_given?
+ begin
+ yield
+ ensure
+ # pull it off the stack...
+ stack_item = @_stack.pop
+ if @_stack.size == 0
+ # completely unmock if there's nothing to revert back to
+ unmock!
+ else
+ # or reinstantiate the new the top of the stack (could be a :freeze or a :move)
+ new_top = @_stack.last
+ if new_top.mock_type == :freeze
+ freeze_all(new_top.year, new_top.month, new_top.day, new_top.hour, new_top.minute, new_top.second)
+ else
+ move_all(new_top.year, new_top.month, new_top.day, new_top.hour, new_top.minute, new_top.second)
+ end
+ end
+ end
+ end
+ end
+
+ def unmock!
+ Time.unmock!
+ end
+
+ private
+
+ # Re-bases Time.now, Date.today and DateTime.now (if it exists) to use the time passed in.
+ # When using this method directly, it is up to the developer to call unset_all to return us
+ # to sanity.
+ #
+ # * If being consumed in a rails app, Time.zone.local will be used to instantiate the time.
+ # Otherwise, Time.local will be used.
+ def freeze_all(year, month, day, hour=0, minute=0, second=0)
+ if Time.respond_to?(:zone) && !Time.zone.nil?
+ # ActiveSupport loaded
+ time = Time.zone.local(year, month, day, hour, minute, second)
+ else
+ # ActiveSupport not loaded
+ time = Time.local(year, month, day, hour, minute, second)
+ end
+
+ Time.freeze_time(time)
+ end
+
+ # Re-bases Time.now, Date.today and DateTime.now to use the time passed in and to continue moving time
+ # forward. When using this method directly, it is up to the developer to call return to return us to
+ # sanity.
+ #
+ # * If being consumed in a rails app, Time.zone.local will be used to instantiate the time.
+ # Otherwise, Time.local will be used.
+ def move_all(year, month, day, hour=0, minute=0, second=0)
+ if Time.respond_to?(:zone) && !Time.zone.nil?
+ # ActiveSupport loaded
+ time = Time.zone.local(year, month, day, hour, minute, second)
+ else
+ # ActiveSupport not loaded
+ time = Time.local(year, month, day, hour, minute, second)
+ end
+
+ Time.move_time(time)
+ end
+
+ def parse_travel_args(*args)
+ arg = args.shift
+ if arg.is_a?(Time) || (Object.const_defined?(:DateTime) && arg.is_a?(DateTime))
+ year, month, day, hour, minute, second = arg.year, arg.month, arg.day, arg.hour, arg.min, arg.sec
+ elsif Object.const_defined?(:Date) && arg.is_a?(Date)
+ year, month, day, hour, minute, second = arg.year, arg.month, arg.day, 0, 0, 0
+ #puts "#{year}-#{month}-#{day} #{hour}:#{minute}:#{second}"
+ elsif args.empty? && arg.kind_of?(Integer)
+ t = Time.now + arg
+ year, month, day, hour, minute, second = t.year, t.month, t.day, t.hour, t.min, t.sec
+ else # we'll just assume it's a list of y/m/h/d/m/s
+ year = arg || 0
+ month = args.shift || 1
+ day = args.shift || 1
+ hour = args.shift || 0
+ minute = args.shift || 0
+ second = args.shift || 0
+ end
+ return year, month, day, hour, minute, second
+ end
+end
+
+#def with_dates(*dates, &block)
+# dates.flatten.each do |date|
+# begin
+# DateTime.forced_now = case date
+# when String: DateTime.parse(date)
+# when Time: DateTime.parse(date.to_s)
+# else
+# date
+# end
+# Date.forced_today = Date.new(DateTime.forced_now.year,
+#DateTime.forced_now.month, DateTime.forced_now.day)
+# yield
+# rescue Exception => e
+# raise e
+# ensure
+# DateTime.forced_now = nil
+# Date.forced_today = nil
+# end
+# end
+#end
+
diff --git a/vendor/gems/jtrupiano-timecop-0.2.1/lib/timecop/version.rb b/vendor/gems/jtrupiano-timecop-0.2.1/lib/timecop/version.rb
new file mode 100644
index 0000000..12fc9da
--- /dev/null
+++ b/vendor/gems/jtrupiano-timecop-0.2.1/lib/timecop/version.rb
@@ -0,0 +1,20 @@
+module Timecop
+ module Version #:nodoc:
+ # A method for comparing versions of required modules. It expects two
+ # arrays of integers as parameters, the first being the minimum version
+ # required, and the second being the actual version available. It returns
+ # true if the actual version is at least equal to the required version.
+ def self.check(required, actual) #:nodoc:
+ required = required.map { |v| "%06d" % v }.join(".")
+ actual = actual.map { |v| "%06d" % v }.join(".")
+ return actual >= required
+ end
+
+ MAJOR = 0
+ MINOR = 2
+ TINY = 0
+
+ STRING = [MAJOR, MINOR, TINY].join(".")
+ end
+end
+
diff --git a/vendor/gems/jtrupiano-timecop-0.2.1/test/run_tests.sh b/vendor/gems/jtrupiano-timecop-0.2.1/test/run_tests.sh
new file mode 100755
index 0000000..f1cd7d5
--- /dev/null
+++ b/vendor/gems/jtrupiano-timecop-0.2.1/test/run_tests.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+echo "\033[1;81m Running test_timecop_internals...\033[0m"
+ruby test_timecop_internals.rb || (echo "FAILED!!!!!!!!!!!!")
+
+echo "\033[1;81m Running test_timecop_without_date...\033[0m"
+ruby test_timecop_without_date.rb || (echo "FAILED!!!!!!!!!!!!")
+
+echo "\033[1;81m Running test_timecop...\033[0m"
+ruby test_timecop.rb || (echo "FAILED!!!!!!!!!!!!")
diff --git a/vendor/gems/jtrupiano-timecop-0.2.1/test/test_timecop.rb b/vendor/gems/jtrupiano-timecop-0.2.1/test/test_timecop.rb
new file mode 100644
index 0000000..83f11df
--- /dev/null
+++ b/vendor/gems/jtrupiano-timecop-0.2.1/test/test_timecop.rb
@@ -0,0 +1,175 @@
+
+require 'date'
+require 'test/unit'
+require File.join(File.dirname(__FILE__), '..', 'lib', 'timecop')
+
+class TestTimecop < Test::Unit::TestCase
+
+ def setup
+
+ end
+
+ # just in case...let's really make sure that Timecop is disabled between tests...
+ def teardown
+ Timecop.return
+ end
+
+ def test_freeze_changes_and_resets_time
+ # depending on how we're invoked (individually or via the rake test suite)
+ assert !Time.respond_to?(:zone) || Time.zone.nil?
+
+ t = Time.local(2008, 10, 10, 10, 10, 10)
+ assert_not_equal t, Time.now
+ Timecop.freeze(2008, 10, 10, 10, 10, 10) do
+ assert_equal t, Time.now
+ end
+ assert_not_equal t, Time.now
+ end
+
+ def test_recursive_freeze
+ t = Time.local(2008, 10, 10, 10, 10, 10)
+ Timecop.freeze(2008, 10, 10, 10, 10, 10) do
+ assert_equal t, Time.now
+ t2 = Time.local(2008, 9, 9, 9, 9, 9)
+ Timecop.freeze(2008, 9, 9, 9, 9, 9) do
+ assert_equal t2, Time.now
+ end
+ assert_equal t, Time.now
+ end
+ assert_not_equal t, Time.now
+ end
+
+ def test_freeze_with_time_instance_works_as_expected
+ t = Time.local(2008, 10, 10, 10, 10, 10)
+ Timecop.freeze(t) do
+ assert_equal t, Time.now
+ assert_equal DateTime.new(2008, 10, 10, 10, 10, 10), DateTime.now
+ assert_equal Date.new(2008, 10, 10), Date.today
+ end
+ assert_not_equal t, Time.now
+ assert_not_equal DateTime.new(2008, 10, 10, 10, 10, 10), DateTime.now
+ assert_not_equal Date.new(2008, 10, 10), Date.today
+ end
+
+ def test_freeze_with_datetime_instance_works_as_expected
+ t = DateTime.new(2008, 10, 10, 10, 10, 10)
+ Timecop.freeze(t) do
+ assert_equal t, DateTime.now
+ assert_equal Time.local(2008, 10, 10, 10, 10, 10), Time.now
+ assert_equal Date.new(2008, 10, 10), Date.today
+ end
+ assert_not_equal t, DateTime.now
+ assert_not_equal Time.local(2008, 10, 10, 10, 10, 10), Time.now
+ assert_not_equal Date.new(2008, 10, 10), Date.today
+ end
+
+ def test_freeze_with_date_instance_works_as_expected
+ d = Date.new(2008, 10, 10)
+ Timecop.freeze(d) do
+ assert_equal d, Date.today
+ assert_equal Time.local(2008, 10, 10, 0, 0, 0), Time.now
+ assert_equal DateTime.new(2008, 10, 10, 0, 0, 0), DateTime.now
+ end
+ assert_not_equal d, Date.today
+ assert_not_equal Time.local(2008, 10, 10, 0, 0, 0), Time.now
+ assert_not_equal DateTime.new(2008, 10, 10, 0, 0, 0), DateTime.now
+ end
+
+ def test_freeze_with_integer_instance_works_as_expected
+ t = Time.local(2008, 10, 10, 10, 10, 10)
+ Timecop.freeze(t) do
+ assert_equal t, Time.now
+ assert_equal DateTime.new(2008, 10, 10, 10, 10, 10), DateTime.now
+ assert_equal Date.new(2008, 10, 10), Date.today
+ Timecop.freeze(10) do
+ assert_equal t + 10, Time.now
+ assert_equal Time.local(2008, 10, 10, 10, 10, 20), Time.now
+ assert_equal Date.new(2008, 10, 10), Date.today
+ end
+ end
+ assert_not_equal t, Time.now
+ assert_not_equal DateTime.new(2008, 10, 10, 10, 10, 10), DateTime.now
+ assert_not_equal Date.new(2008, 10, 10), Date.today
+ end
+
+ def test_exception_thrown_in_freeze_block_properly_resets_time
+ t = Time.local(2008, 10, 10, 10, 10, 10)
+ begin
+ Timecop.freeze(t) do
+ assert_equal t, Time.now
+ raise "blah exception"
+ end
+ rescue
+ assert_not_equal t, Time.now
+ assert_nil Time.send(:mock_time)
+ end
+ end
+
+ def test_freeze_freezes_time
+ t = Time.local(2008, 10, 10, 10, 10, 10)
+ now = Time.now
+ Timecop.freeze(t) do
+ #assert Time.now < now, "If we had failed to freeze, time would have proceeded, which is what appears to have happened."
+ new_t, new_d, new_dt = Time.now, Date.today, DateTime.now
+ assert_equal t, new_t, "Failed to freeze time." # 2 seconds
+ #sleep(10)
+ assert_equal new_t, Time.now
+ assert_equal new_d, Date.today
+ assert_equal new_dt, DateTime.now
+ end
+ end
+
+ def test_travel_keeps_time_moving
+ t = Time.local(2008, 10, 10, 10, 10, 10)
+ now = Time.now
+ Timecop.travel(t) do
+ #assert Time.now < now, "If we had failed to freeze, time would have proceeded, which is what appears to have happened."
+ assert Time.now - t < 2000, "Looks like we failed to actually travel time" # 2 seconds
+ new_t = Time.now
+ #sleep(10)
+ assert_not_equal new_t, Time.now
+ end
+ end
+
+ def test_recursive_rebasing_maintains_each_context
+ t = Time.local(2008, 10, 10, 10, 10, 10)
+ Timecop.travel(2008, 10, 10, 10, 10, 10) do
+ assert((t - Time.now).abs < 50, "Failed to travel time.")
+ t2 = Time.local(2008, 9, 9, 9, 9, 9)
+ Timecop.travel(2008, 9, 9, 9, 9, 9) do
+ assert((t2 - Time.now) < 50, "Failed to travel time.")
+ assert((t - Time.now) > 1000, "Failed to travel time.")
+ end
+ assert((t - Time.now).abs < 2000, "Failed to restore previously-traveled time.")
+ end
+ assert_nil Time.send(:mock_time)
+ end
+
+ def test_recursive_travel_then_freeze
+ t = Time.local(2008, 10, 10, 10, 10, 10)
+ Timecop.travel(2008, 10, 10, 10, 10, 10) do
+ assert((t - Time.now).abs < 50, "Failed to travel time.")
+ t2 = Time.local(2008, 9, 9, 9, 9, 9)
+ Timecop.freeze(2008, 9, 9, 9, 9, 9) do
+ assert_equal t2, Time.now
+ end
+ assert((t - Time.now).abs < 2000, "Failed to restore previously-traveled time.")
+ end
+ assert_nil Time.send(:mock_time)
+ end
+
+ def test_recursive_freeze_then_travel
+ t = Time.local(2008, 10, 10, 10, 10, 10)
+ Timecop.freeze(t) do
+ assert_equal t, Time.now
+ t2 = Time.local(2008, 9, 9, 9, 9, 9)
+ Timecop.travel(t2) do
+ assert((t2 - Time.now) < 50, "Failed to travel time.")
+ assert((t - Time.now) > 1000, "Failed to travel time.")
+ end
+ assert_equal t, Time.now
+ end
+ assert_nil Time.send(:mock_time)
+ end
+
+end
\ No newline at end of file
diff --git a/vendor/gems/jtrupiano-timecop-0.2.1/test/test_timecop_internals.rb b/vendor/gems/jtrupiano-timecop-0.2.1/test/test_timecop_internals.rb
new file mode 100644
index 0000000..949db97
--- /dev/null
+++ b/vendor/gems/jtrupiano-timecop-0.2.1/test/test_timecop_internals.rb
@@ -0,0 +1,69 @@
+
+require 'date'
+require 'test/unit'
+require File.join(File.dirname(__FILE__), '..', 'lib', 'timecop')
+
+class TestTimecopInternals < Test::Unit::TestCase
+
+ def test_parse_travel_args_with_time
+ t = Time.now
+ y, m, d, h, min, s = t.year, t.month, t.day, t.hour, t.min, t.sec
+ ty, tm, td, th, tmin, ts = Timecop.instance().send(:parse_travel_args, t)
+ assert_equal y, ty
+ assert_equal m, tm
+ assert_equal d, td
+ assert_equal h, th
+ assert_equal min, tmin
+ assert_equal s, ts
+ end
+
+ def test_parse_travel_args_with_datetime
+ t = DateTime.now
+ y, m, d, h, min, s = t.year, t.month, t.day, t.hour, t.min, t.sec
+ ty, tm, td, th, tmin, ts = Timecop.instance().send(:parse_travel_args, t)
+ assert_equal y, ty
+ assert_equal m, tm
+ assert_equal d, td
+ assert_equal h, th
+ assert_equal min, tmin
+ assert_equal s, ts
+ end
+
+ def test_parse_travel_args_with_date
+ date = Date.today
+ y, m, d, h, min, s = date.year, date.month, date.day, 0, 0, 0
+ ty, tm, td, th, tmin, ts = Timecop.instance().send(:parse_travel_args, date)
+ assert_equal y, ty
+ assert_equal m, tm
+ assert_equal d, td
+ assert_equal h, th
+ assert_equal min, tmin
+ assert_equal s, ts
+ end
+
+ # Due to the nature of this test (calling Time.now once in this test and
+ # once in #parse_travel_args), this test may fail when two subsequent calls
+ # to Time.now return a different second.
+ def test_parse_travel_args_with_integer
+ t = Time.now
+ y, m, d, h, min, s = t.year, t.month, t.day, t.hour, t.min, t.sec
+ ty, tm, td, th, tmin, ts = Timecop.instance().send(:parse_travel_args, 0)
+ assert_equal y, ty
+ assert_equal m, tm
+ assert_equal d, td
+ assert_equal h, th
+ assert_equal min, tmin
+ assert_equal s, ts
+ end
+
+ def test_parse_travel_args_with_individual_arguments
+ y, m, d, h, min, s = 2008, 10, 10, 10, 10, 10
+ ty, tm, td, th, tmin, ts = Timecop.instance().send(:parse_travel_args, y, m, d, h, min, s)
+ assert_equal y, ty
+ assert_equal m, tm
+ assert_equal d, td
+ assert_equal h, th
+ assert_equal min, tmin
+ assert_equal s, ts
+ end
+end
\ No newline at end of file
diff --git a/vendor/gems/jtrupiano-timecop-0.2.1/test/test_timecop_without_date.rb b/vendor/gems/jtrupiano-timecop-0.2.1/test/test_timecop_without_date.rb
new file mode 100644
index 0000000..20ed8c2
--- /dev/null
+++ b/vendor/gems/jtrupiano-timecop-0.2.1/test/test_timecop_without_date.rb
@@ -0,0 +1,120 @@
+
+require 'test/unit'
+require File.join(File.dirname(__FILE__), '..', 'lib', 'timecop')
+
+class TestTimecopWithouDate < Test::Unit::TestCase
+
+ def setup
+ assert !Object.const_defined?(:Date)
+ assert !Object.const_defined?(:DateTime)
+ end
+
+ # just in case...let's really make sure that Timecop is disabled between tests...
+ def teardown
+ Timecop.return
+ end
+
+ def test_freeze_changes_and_resets_time
+ # depending on how we're invoked (individually or via the rake test suite)
+ assert !Time.respond_to?(:zone) || Time.zone.nil?
+
+ t = Time.local(2008, 10, 10, 10, 10, 10)
+ assert_not_equal t, Time.now
+ Timecop.freeze(2008, 10, 10, 10, 10, 10) do
+ assert_equal t, Time.now
+ end
+ assert_not_equal t, Time.now
+ end
+
+ def test_recursive_freeze
+ t = Time.local(2008, 10, 10, 10, 10, 10)
+ Timecop.freeze(2008, 10, 10, 10, 10, 10) do
+ assert_equal t, Time.now
+ t2 = Time.local(2008, 9, 9, 9, 9, 9)
+ Timecop.freeze(2008, 9, 9, 9, 9, 9) do
+ assert_equal t2, Time.now
+ end
+ assert_equal t, Time.now
+ end
+ assert_nil Time.send(:mock_time)
+ end
+
+ def test_exception_thrown_in_freeze_block_properly_resets_time
+ t = Time.local(2008, 10, 10, 10, 10, 10)
+ begin
+ Timecop.freeze(t) do
+ assert_equal t, Time.now
+ raise "blah exception"
+ end
+ rescue
+ assert_not_equal t, Time.now
+ assert_nil Time.send(:mock_time)
+ end
+ end
+
+ def test_freeze_freezes_time
+ t = Time.local(2008, 10, 10, 10, 10, 10)
+ now = Time.now
+ Timecop.freeze(t) do
+ #assert Time.now < now, "If we had failed to freeze, time would have proceeded, which is what appears to have happened."
+ new_t = Time.now
+ assert_equal t, new_t, "Failed to change move time." # 2 seconds
+ #sleep(10)
+ assert_equal new_t, Time.now
+ end
+ end
+
+ def test_travel_keeps_time_moving
+ t = Time.local(2008, 10, 10, 10, 10, 10)
+ now = Time.now
+ Timecop.travel(t) do
+ #assert Time.now < now, "If we had failed to freeze, time would have proceeded, which is what appears to have happened."
+ assert Time.now - t < 2000, "Looks like we failed to actually travel time" # 2 seconds
+ new_t = Time.now
+ #sleep(10)
+ assert_not_equal new_t, Time.now
+ end
+ end
+
+ def test_recursive_rebasing_maintains_each_context
+ t = Time.local(2008, 10, 10, 10, 10, 10)
+ Timecop.travel(2008, 10, 10, 10, 10, 10) do
+ assert((t - Time.now).abs < 50, "Failed to travel time.")
+ t2 = Time.local(2008, 9, 9, 9, 9, 9)
+ Timecop.travel(2008, 9, 9, 9, 9, 9) do
+ assert((t2 - Time.now) < 50, "Failed to travel time.")
+ assert((t - Time.now) > 1000, "Failed to travel time.")
+ end
+ assert((t - Time.now).abs < 2000, "Failed to restore previously-traveled time.")
+ end
+ assert_nil Time.send(:mock_time)
+ end
+
+ def test_recursive_travel_then_freeze
+ t = Time.local(2008, 10, 10, 10, 10, 10)
+ Timecop.travel(2008, 10, 10, 10, 10, 10) do
+ assert((t - Time.now).abs < 50, "Failed to travel time.")
+ t2 = Time.local(2008, 9, 9, 9, 9, 9)
+ Timecop.freeze(2008, 9, 9, 9, 9, 9) do
+ assert_equal t2, Time.now
+ end
+ assert((t - Time.now).abs < 2000, "Failed to restore previously-traveled time.")
+ end
+ assert_nil Time.send(:mock_time)
+ end
+
+ def test_recursive_freeze_then_travel
+ t = Time.local(2008, 10, 10, 10, 10, 10)
+ Timecop.freeze(t) do
+ assert_equal t, Time.now
+ t2 = Time.local(2008, 9, 9, 9, 9, 9)
+ Timecop.travel(t2) do
+ assert((t2 - Time.now) < 50, "Failed to travel time.")
+ assert((t - Time.now) > 1000, "Failed to travel time.")
+ end
+ assert_equal t, Time.now
+ end
+ assert_nil Time.send(:mock_time)
+ end
+
+end
\ No newline at end of file
--
libgit2 0.21.2