wrest 0.0.9 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (154) hide show
  1. data/CHANGELOG +34 -0
  2. data/README.rdoc +16 -10
  3. data/Rakefile +361 -123
  4. data/VERSION.yml +2 -2
  5. data/examples/delicious.rb +17 -7
  6. data/examples/facebook.rb +101 -0
  7. data/examples/keep_alive.rb +37 -0
  8. data/examples/twitter.rb +3 -3
  9. data/examples/twitter_public_timeline.rb +11 -4
  10. data/examples/wow_realm_status.rb +8 -2
  11. data/{spec/functional/sample_rails_app/public/favicon.ico → init.rb} +0 -0
  12. data/lib/wrest/components/{attributes_container → container}/alias_accessors.rb +4 -4
  13. data/lib/wrest/components/{attributes_container → container}/typecaster.rb +1 -1
  14. data/lib/wrest/components/{attributes_container.rb → container.rb} +46 -16
  15. data/lib/wrest/components/mutators.rb +4 -4
  16. data/lib/wrest/components/translators/json.rb +2 -2
  17. data/lib/wrest/components/translators/xml.rb +3 -2
  18. data/lib/wrest/components/translators.rb +3 -3
  19. data/lib/wrest/components.rb +3 -3
  20. data/lib/wrest/core_ext/hash.rb +1 -1
  21. data/lib/wrest/core_ext/string.rb +1 -1
  22. data/lib/wrest/curl/delete.rb +23 -0
  23. data/lib/wrest/curl/get.rb +23 -0
  24. data/lib/wrest/curl/options.rb +16 -0
  25. data/lib/wrest/curl/post.rb +23 -0
  26. data/lib/wrest/curl/put.rb +23 -0
  27. data/lib/wrest/curl/request.rb +95 -0
  28. data/lib/wrest/curl/response.rb +63 -0
  29. data/lib/wrest/curl/session.rb +57 -0
  30. data/lib/wrest/curl.rb +49 -0
  31. data/lib/wrest/exceptions.rb +16 -1
  32. data/lib/wrest/http_shared/headers.rb +350 -0
  33. data/lib/wrest/http_shared/standard_headers.rb +21 -0
  34. data/lib/wrest/http_shared/standard_tokens.rb +18 -0
  35. data/lib/wrest/http_shared.rb +24 -0
  36. data/lib/wrest/native/connection_factory.rb +23 -0
  37. data/lib/wrest/{http → native}/delete.rb +1 -1
  38. data/lib/wrest/{http → native}/get.rb +1 -1
  39. data/lib/wrest/{http → native}/options.rb +1 -1
  40. data/lib/wrest/{http → native}/post.rb +1 -1
  41. data/lib/wrest/{http → native}/put.rb +1 -1
  42. data/lib/wrest/{http → native}/redirection.rb +4 -1
  43. data/lib/wrest/{http → native}/request.rb +32 -20
  44. data/lib/wrest/{http → native}/response.rb +12 -4
  45. data/lib/wrest/native/session.rb +57 -0
  46. data/lib/wrest/native.rb +32 -0
  47. data/lib/wrest/resource/base.rb +1 -1
  48. data/lib/wrest/resource.rb +1 -1
  49. data/lib/wrest/test/request_patches.rb +5 -0
  50. data/lib/wrest/test.rb +1 -0
  51. data/lib/wrest/uri.rb +31 -3
  52. data/lib/wrest/version.rb +2 -2
  53. data/lib/wrest.rb +52 -16
  54. data/spec/unit/spec_helper.rb +12 -3
  55. data/spec/unit/wrest/components/attributes_container/alias_accessors_spec.rb +2 -2
  56. data/spec/unit/wrest/components/attributes_container/typecaster_spec.rb +6 -6
  57. data/spec/unit/wrest/components/attributes_container_spec.rb +44 -12
  58. data/spec/unit/wrest/components/translators/xml_spec.rb +7 -3
  59. data/spec/unit/wrest/curl/request_spec.rb +19 -0
  60. data/spec/unit/wrest/curl/response_spec.rb +16 -0
  61. data/spec/unit/wrest/http/response_spec.rb +17 -38
  62. data/spec/unit/wrest/{http → native}/redirection_spec.rb +5 -5
  63. data/spec/unit/wrest/{http → native}/request_spec.rb +15 -14
  64. data/spec/unit/wrest/native/response_spec.rb +72 -0
  65. data/spec/unit/wrest/native/session_spec.rb +74 -0
  66. data/spec/unit/wrest/resource/base_spec.rb +2 -2
  67. data/spec/unit/wrest/uri_spec.rb +51 -11
  68. data/wrest.gemspec +164 -0
  69. metadata +51 -165
  70. data/lib/wrest/http.rb +0 -25
  71. data/spec/functional/sample_rails_app/README +0 -3
  72. data/spec/functional/sample_rails_app/Rakefile +0 -10
  73. data/spec/functional/sample_rails_app/app/controllers/application_controller.rb +0 -10
  74. data/spec/functional/sample_rails_app/app/controllers/lead_bottles_controller.rb +0 -7
  75. data/spec/functional/sample_rails_app/app/helpers/application_helper.rb +0 -3
  76. data/spec/functional/sample_rails_app/app/models/bottle.rb +0 -3
  77. data/spec/functional/sample_rails_app/app/models/glass_bottle.rb +0 -3
  78. data/spec/functional/sample_rails_app/app/models/lead_bottle.rb +0 -3
  79. data/spec/functional/sample_rails_app/config/boot.rb +0 -110
  80. data/spec/functional/sample_rails_app/config/database.yml +0 -16
  81. data/spec/functional/sample_rails_app/config/environment.rb +0 -42
  82. data/spec/functional/sample_rails_app/config/environments/development.rb +0 -17
  83. data/spec/functional/sample_rails_app/config/environments/production.rb +0 -28
  84. data/spec/functional/sample_rails_app/config/environments/test.rb +0 -28
  85. data/spec/functional/sample_rails_app/config/initializers/backtrace_silencers.rb +0 -7
  86. data/spec/functional/sample_rails_app/config/initializers/inflections.rb +0 -10
  87. data/spec/functional/sample_rails_app/config/initializers/mime_types.rb +0 -5
  88. data/spec/functional/sample_rails_app/config/initializers/new_rails_defaults.rb +0 -19
  89. data/spec/functional/sample_rails_app/config/initializers/session_store.rb +0 -15
  90. data/spec/functional/sample_rails_app/config/locales/en.yml +0 -5
  91. data/spec/functional/sample_rails_app/config/routes.rb +0 -3
  92. data/spec/functional/sample_rails_app/db/development.sqlite3 +0 -0
  93. data/spec/functional/sample_rails_app/db/migrate/20090319115628_create_bottle.rb +0 -13
  94. data/spec/functional/sample_rails_app/db/schema.rb +0 -20
  95. data/spec/functional/sample_rails_app/db/test.sqlite3 +0 -0
  96. data/spec/functional/sample_rails_app/log/development.log +0 -1
  97. data/spec/functional/sample_rails_app/public/404.html +0 -30
  98. data/spec/functional/sample_rails_app/public/422.html +0 -30
  99. data/spec/functional/sample_rails_app/public/500.html +0 -30
  100. data/spec/functional/sample_rails_app/public/images/rails.png +0 -0
  101. data/spec/functional/sample_rails_app/public/index.html +0 -275
  102. data/spec/functional/sample_rails_app/public/robots.txt +0 -5
  103. data/spec/functional/sample_rails_app/script/about +0 -4
  104. data/spec/functional/sample_rails_app/script/autospec +0 -6
  105. data/spec/functional/sample_rails_app/script/console +0 -3
  106. data/spec/functional/sample_rails_app/script/dbconsole +0 -3
  107. data/spec/functional/sample_rails_app/script/destroy +0 -3
  108. data/spec/functional/sample_rails_app/script/generate +0 -3
  109. data/spec/functional/sample_rails_app/script/performance/benchmarker +0 -3
  110. data/spec/functional/sample_rails_app/script/performance/profiler +0 -3
  111. data/spec/functional/sample_rails_app/script/plugin +0 -3
  112. data/spec/functional/sample_rails_app/script/runner +0 -3
  113. data/spec/functional/sample_rails_app/script/server +0 -3
  114. data/spec/functional/sample_rails_app/script/spec +0 -10
  115. data/spec/functional/sample_rails_app/script/spec_server +0 -9
  116. data/spec/functional/sample_rails_app/test/performance/browsing_test.rb +0 -9
  117. data/spec/functional/sample_rails_app/test/test_helper.rb +0 -38
  118. data/spec/functional/sample_rails_app/tmtags +0 -2559
  119. data/spec/functional/sample_rails_app/vendor/plugins/resource_full/MIT-LICENSE +0 -20
  120. data/spec/functional/sample_rails_app/vendor/plugins/resource_full/README.rdoc +0 -100
  121. data/spec/functional/sample_rails_app/vendor/plugins/resource_full/Rakefile +0 -18
  122. data/spec/functional/sample_rails_app/vendor/plugins/resource_full/init.rb +0 -5
  123. data/spec/functional/sample_rails_app/vendor/plugins/resource_full/install.rb +0 -1
  124. data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/base.rb +0 -140
  125. data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/controllers/resources.rb +0 -16
  126. data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/controllers/resources_controller.rb +0 -26
  127. data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/controllers/routes_controller.rb +0 -16
  128. data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/core_extensions/api.rb +0 -26
  129. data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/core_extensions/exception.rb +0 -23
  130. data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/core_extensions/from_json.rb +0 -15
  131. data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/dispatch.rb +0 -235
  132. data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/models/resourced_route.rb +0 -84
  133. data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/query.rb +0 -337
  134. data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/render/html.rb +0 -50
  135. data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/render/json.rb +0 -75
  136. data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/render/xml.rb +0 -65
  137. data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/render.rb +0 -63
  138. data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/retrieve.rb +0 -74
  139. data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/version.rb +0 -9
  140. data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full.rb +0 -14
  141. data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/base_spec.rb +0 -88
  142. data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/controllers/resources_spec.rb +0 -29
  143. data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/dispatch_spec.rb +0 -262
  144. data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/models/resourced_route_spec.rb +0 -62
  145. data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/query/parameter_spec.rb +0 -57
  146. data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/query_spec.rb +0 -462
  147. data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/render/html_spec.rb +0 -4
  148. data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/render/json_spec.rb +0 -107
  149. data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/render/xml_spec.rb +0 -98
  150. data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/render_spec.rb +0 -5
  151. data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/retrieve_spec.rb +0 -173
  152. data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/spec_helper.rb +0 -98
  153. data/spec/functional/sample_rails_app/vendor/plugins/resource_full/uninstall.rb +0 -1
  154. data/spec/functional/spec_helper.rb +0 -0
@@ -10,18 +10,54 @@
10
10
  require File.dirname(__FILE__) + '/../../spec_helper'
11
11
 
12
12
  module Wrest::Components
13
- describe AttributesContainer do
13
+ describe Container do
14
14
  class HumanBeing
15
- include Wrest::Components::AttributesContainer
15
+ include Wrest::Components::Container
16
16
  always_has :id
17
17
  end
18
18
 
19
+ class WaterMagician < HumanBeing
20
+ end
21
+
22
+ it "should allow instantiation with no attributes" do
23
+ lambda{ HumanBeing.new }.should_not raise_error
24
+ end
25
+
26
+ describe 'serialisation' do
27
+ it "should know its xml element name" do
28
+ HumanBeing.element_name.should == 'human_being'
29
+ end
30
+
31
+ it "should know how to serialise itself given any of the Wrest::Components::Translators" do
32
+ result = HumanBeing.new(:age => "70", :name => 'Li Piao').serialise_using(Wrest::Components::Translators::Json)
33
+ expectedPermutationOne = "{\"age\":\"70\",\"name\":\"Li Piao\"}"
34
+ expectedPermutationTwo = "{\"name\":\"Li Piao\",\"age\":\"70\"}"
35
+
36
+ (result == expectedPermutationOne || result == expectedPermutationTwo).should be_true
37
+ end
38
+
39
+ it "should have a to_xml helper that ensures that the name of the class is the root of the serilised form" do
40
+ result = HumanBeing.new(:age => "70", :name => 'Li Piao').to_xml
41
+ expectedPermutationOne = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<human-being>\n <age>70</age>\n <name>Li Piao</name>\n</human-being>\n"
42
+ expectedPermutationTwo = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<human-being>\n <name>Li Piao</name>\n <age>70</age>\n</human-being>\n"
43
+
44
+ (result == expectedPermutationOne || result == expectedPermutationTwo).should be_true
45
+ end
46
+
47
+ describe 'subclasses' do
48
+ it "should not allow cached element name to clash" do
49
+ WaterMagician.element_name.should == 'water_magician'
50
+ HumanBeing.element_name.should == 'human_being'
51
+ end
52
+ end
53
+ end
54
+
19
55
  describe "typecasting" do
20
56
  before(:each) do
21
57
  @Demon = Class.new
22
58
 
23
59
  @Demon.class_eval do
24
- include Wrest::Components::AttributesContainer
60
+ include Wrest::Components::Container
25
61
  end
26
62
  end
27
63
 
@@ -31,7 +67,7 @@ module Wrest::Components
31
67
  end
32
68
  @Demon.new(:foo => '1').foo.should == 1
33
69
  end
34
-
70
+
35
71
  it "should provide helpers for common typecasts" do
36
72
  @Demon.class_eval do
37
73
  typecast :foo => as_integer
@@ -40,10 +76,6 @@ module Wrest::Components
40
76
  end
41
77
  end
42
78
 
43
- it "should allow instantiation with no attributes" do
44
- lambda{ HumanBeing.new }.should_not raise_error
45
- end
46
-
47
79
  describe 'always_has' do
48
80
  describe 'method creation' do
49
81
  before :each do
@@ -57,7 +89,7 @@ module Wrest::Components
57
89
  kai_wren.methods.map(&:to_sym).should_not include(:trainer)
58
90
 
59
91
  @Demon.class_eval{
60
- include Wrest::Components::AttributesContainer
92
+ include Wrest::Components::Container
61
93
  always_has :trainer
62
94
  }
63
95
 
@@ -69,7 +101,7 @@ module Wrest::Components
69
101
  kai_wren.methods.map(&:to_sym).should_not include(:trainer=)
70
102
 
71
103
  @Demon.class_eval{
72
- include Wrest::Components::AttributesContainer
104
+ include Wrest::Components::Container
73
105
  always_has :trainer
74
106
  }
75
107
 
@@ -81,7 +113,7 @@ module Wrest::Components
81
113
  kai_wren.methods.map(&:to_sym).should_not include(:trainer?)
82
114
 
83
115
  @Demon.class_eval{
84
- include Wrest::Components::AttributesContainer
116
+ include Wrest::Components::Container
85
117
  always_has :trainer
86
118
  }
87
119
  kai_wren.methods.map(&:to_sym).should include(:trainer?)
@@ -92,7 +124,7 @@ module Wrest::Components
92
124
  before :each do
93
125
  @Demon = Class.new
94
126
  @Demon.class_eval{
95
- include Wrest::Components::AttributesContainer
127
+ include Wrest::Components::Container
96
128
  always_has :trainer
97
129
 
98
130
  def method_missing(method_name, *args)
@@ -1,12 +1,16 @@
1
1
  require File.dirname(__FILE__) + '/../../../spec_helper'
2
2
 
3
3
  module Wrest::Components::Translators
4
- describe Xml do
4
+ describe Xml do
5
5
  it "should know how to convert xml to a hashmap" do
6
6
  http_response = mock('Http Reponse')
7
7
  http_response.should_receive(:body).and_return("<ooga><age>12</age></ooga>")
8
8
 
9
- Xml.deserialise(http_response).should == {"ooga"=>{"age"=>{"__content__" => "12"}}}
9
+ Xml.deserialise(http_response).should == {"ooga"=>{"age"=> "12"}}
10
+ end
11
+
12
+ it "should know how to convert a hashmap to xml" do
13
+ Xml.serialise({"ooga"=>{"age" => "12"}}).should == "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<hash>\n <ooga>\n <age>12</age>\n </ooga>\n</hash>\n"
10
14
  end
11
15
  end
12
- end
16
+ end
@@ -0,0 +1,19 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ unless RUBY_PLATFORM =~ /java/
4
+ module Wrest
5
+ describe Curl::Request do
6
+ before :all do
7
+ Wrest.use_curl
8
+ end
9
+
10
+ it "should raise an exception if an options is invoked" do
11
+ lambda{ 'http://localhost:3000/bottles'.to_uri.options }.should raise_error(Wrest::Exceptions::UnsupportedHttpVerb)
12
+ end
13
+
14
+ after :all do
15
+ Wrest.use_native
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,16 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ unless RUBY_PLATFORM =~ /java/
4
+ module Wrest
5
+ describe Curl::Response do
6
+ describe 'Headers' do
7
+ it "should know how to retrieve content type irrespective of the casing" do
8
+ http_response = mock('Patron::Response')
9
+ http_response.stub!(:headers).and_return({'Content-type' => 'text/xml;charset=utf-8'})
10
+ response = Wrest::Curl::Response.new(http_response)
11
+ response.content_type.should == 'text/xml'
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -1,45 +1,24 @@
1
1
  require File.dirname(__FILE__) + '/../../spec_helper'
2
2
 
3
3
  module Wrest
4
- describe Http::Response do
5
- it "should build a Redirection instead of a normal response if the code is 3xx" do
6
- http_response = mock(Net::HTTPRedirection)
7
- http_response.stub!(:code).and_return('301')
8
-
9
- Http::Response.new(http_response).class.should == Wrest::Http::Redirection
10
- end
11
-
12
- it "should build a normal Response for non 3xx codes" do
13
- http_response = mock(Net::HTTPResponse)
14
- http_response.stub!(:code).and_return('200')
15
-
16
- Http::Response.new(http_response).class.should == Wrest::Http::Response
17
- end
18
-
19
- it "should know how to delegate to a translator" do
20
- http_response = mock('response')
21
- http_response.stub!(:code).and_return('200')
22
- Components::Translators::Xml.should_receive(:deserialise).with(http_response)
23
- Http::Response.new(http_response).deserialise_using(Components::Translators::Xml)
24
- end
25
-
26
- it "should know how to load a translator based on content type" do
27
- http_response = mock('response')
28
- http_response.stub!(:code).and_return('422')
29
- http_response.should_receive(:content_type).and_return('application/xml')
30
-
31
- response = Http::Response.new(http_response)
32
- response.should_receive(:deserialise_using).with(Components::Translators::Xml)
33
-
34
- response.deserialise
35
- end
4
+ libraries = [Wrest::Native]
5
+ libraries << Wrest::Curl unless RUBY_PLATFORM =~ /java/
36
6
 
37
- it "should simply return itself when asked to follow (null object behaviour - see MovedPermanently for more context)" do
38
- http_response = mock('response')
39
- http_response.stub!(:code).and_return('422')
40
-
41
- response = Http::Response.new(http_response)
42
- response.follow.equal?(response).should be_true
7
+ libraries.each do |library|
8
+ describe "For #{library}" do
9
+ describe 'Response' do
10
+ describe 'Headers' do
11
+ it "should know how to retrieve content type irrespective of the casing" do
12
+ http_response = mock('Response')
13
+ http_response.stub!(:headers).and_return({'Content-type' => 'application/xml'})
14
+ http_response.stub!(:code).and_return('200')
15
+ http_response.stub!(:content_type).and_return('application/xml')
16
+
17
+ response = library::Response.new(http_response)
18
+ response.content_type.should == 'application/xml'
19
+ end
20
+ end
21
+ end
43
22
  end
44
23
  end
45
24
  end
@@ -1,6 +1,6 @@
1
1
  require File.dirname(__FILE__) + '/../../spec_helper'
2
2
 
3
- describe Wrest::Http::Redirection do
3
+ describe Wrest::Native::Redirection do
4
4
 
5
5
  it "should make a request to the url in its location header and return the response" do
6
6
  mock_net_http_response = mock(Net::HTTPRedirection)
@@ -12,13 +12,13 @@ describe Wrest::Http::Redirection do
12
12
  Wrest::Uri.should_receive(:new).with(redirect_url, anything).and_return(redirect_uri)
13
13
 
14
14
 
15
- after_redirect_request = Wrest::Http::Get.new(redirect_uri)
16
- final_mock_response = mock(Wrest::Http::Response)
15
+ after_redirect_request = Wrest::Native::Get.new(redirect_uri)
16
+ final_mock_response = mock(Wrest::Native::Response)
17
17
  after_redirect_request.should_receive(:invoke).and_return(final_mock_response)
18
18
 
19
- Wrest::Http::Get.should_receive(:new).with(redirect_uri, {}, {}, {:username=>nil, :password=>nil}).and_return(after_redirect_request)
19
+ Wrest::Native::Get.should_receive(:new).with(redirect_uri, {}, {}, {:username=>nil, :password=>nil}).and_return(after_redirect_request)
20
20
 
21
- response = Wrest::Http::Redirection.new(mock_net_http_response)
21
+ response = Wrest::Native::Redirection.new(mock_net_http_response)
22
22
  response.follow(:follow_redirects_count => 0, :follow_redirects_limit => 5).should == final_mock_response
23
23
  end
24
24
 
@@ -9,9 +9,9 @@
9
9
 
10
10
  require File.dirname(__FILE__) + '/../../spec_helper'
11
11
 
12
- describe Wrest::Http::Request do
12
+ describe Wrest::Native::Request do
13
13
  it "should convert all symbols in header keys to strings" do
14
- Wrest::Http::Request.new(
14
+ Wrest::Native::Request.new(
15
15
  'http://localhost/foo'.to_uri, Net::HTTP::Get, {},
16
16
  nil, 'Content-Type' => 'application/xml', :per_page => '10'
17
17
  ).headers.should == {
@@ -21,28 +21,29 @@ describe Wrest::Http::Request do
21
21
  end
22
22
 
23
23
  it "should default the 'follow_redirects' option to true for a Get" do
24
- Wrest::Http::Get.new('http://localhost/foo'.to_uri).follow_redirects.should be_true
24
+ Wrest::Native::Get.new('http://localhost/foo'.to_uri).follow_redirects.should be_true
25
25
  end
26
26
 
27
27
  it "should default the 'follow_redirects_count' option to 0" do
28
- Wrest::Http::Get.new('http://localhost/foo'.to_uri).follow_redirects_count.should == 0
28
+ Wrest::Native::Get.new('http://localhost/foo'.to_uri).follow_redirects_count.should == 0
29
29
  end
30
30
 
31
31
  it "should default the 'follow_redirects_limit' option to 5" do
32
- Wrest::Http::Get.new('http://localhost/foo'.to_uri).follow_redirects_limit.should == 5
32
+ Wrest::Native::Get.new('http://localhost/foo'.to_uri).follow_redirects_limit.should == 5
33
33
  end
34
34
 
35
35
  it "should allow Gets to disable redirect follows" do
36
- Wrest::Http::Get.new('http://localhost/foo'.to_uri, {}, {}, {:follow_redirects => false}).follow_redirects.should be_false
36
+ Wrest::Native::Get.new('http://localhost/foo'.to_uri, {}, {}, {:follow_redirects => false}).follow_redirects.should be_false
37
37
  end
38
38
 
39
39
  it "should increment the follow_redirects_count for every redirect leving the count unaffected in previous requests" do
40
- request = Wrest::Http::Get.new('http://localhost/foo'.to_uri)
40
+ uri = 'http://localhost/foo'.to_uri
41
+ request = Wrest::Native::Get.new(uri)
41
42
  redirect_location = 'http://coathangers.com'
42
43
  redirected_request = mock('Request to http://coathangers.com')
43
44
 
44
45
  mock_connection = mock('Http Connection')
45
- request.stub!(:create_connection).and_return(mock_connection)
46
+ uri.stub!(:create_connection).and_return(mock_connection)
46
47
 
47
48
  raw_response = mock(Net::HTTPRedirection)
48
49
  raw_response.stub!(:code).and_return('301')
@@ -50,11 +51,11 @@ describe Wrest::Http::Request do
50
51
  raw_response.stub!(:body).and_return('')
51
52
  raw_response.stub!(:[]).with('location').and_return(redirect_location)
52
53
 
53
- response = Wrest::Http::Redirection.new(raw_response)
54
+ response = Wrest::Native::Redirection.new(raw_response)
54
55
 
55
56
  mock_connection.should_receive(:request).and_return(raw_response)
56
57
 
57
- Wrest::Http::Response.should_receive(:new).and_return(response)
58
+ Wrest::Native::Response.should_receive(:new).and_return(response)
58
59
  redirected_request.stub!(:get)
59
60
  redirect_location.should_receive(:to_uri).with(hash_including(:follow_redirects_count=>1)).and_return(redirected_request)
60
61
 
@@ -63,8 +64,8 @@ describe Wrest::Http::Request do
63
64
  end
64
65
 
65
66
  it "should default the 'follow_redirects' option to false for a Post, Put or Delete" do
66
- Wrest::Http::Post.new('http://localhost/foo'.to_uri).follow_redirects.should_not be_true
67
- Wrest::Http::Put.new('http://localhost/foo'.to_uri).follow_redirects.should_not be_true
68
- Wrest::Http::Delete.new('http://localhost/foo'.to_uri).follow_redirects.should_not be_true
69
- end
67
+ Wrest::Native::Post.new('http://localhost/foo'.to_uri).follow_redirects.should_not be_true
68
+ Wrest::Native::Put.new('http://localhost/foo'.to_uri).follow_redirects.should_not be_true
69
+ Wrest::Native::Delete.new('http://localhost/foo'.to_uri).follow_redirects.should_not be_true
70
+ end
70
71
  end
@@ -0,0 +1,72 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ module Wrest
4
+ describe Native::Response do
5
+ it "should build a Redirection instead of a normal response if the code is 301..303 or 305..3xx" do
6
+ http_response = mock(Net::HTTPRedirection)
7
+ http_response.stub!(:code).and_return('301')
8
+
9
+ Native::Response.new(http_response).class.should == Wrest::Native::Redirection
10
+ end
11
+
12
+ it "should build a normal response if the code is 304" do
13
+ http_response = mock(Net::HTTPRedirection)
14
+ http_response.stub!(:code).and_return('304')
15
+
16
+ Native::Response.new(http_response).class.should == Wrest::Native::Response
17
+ end
18
+
19
+ it "should build a normal Response for non 3xx codes" do
20
+ http_response = mock(Net::HTTPResponse)
21
+ http_response.stub!(:code).and_return('200')
22
+
23
+ Native::Response.new(http_response).class.should == Wrest::Native::Response
24
+ end
25
+
26
+ it "should know how to delegate to a translator" do
27
+ http_response = mock('response')
28
+ http_response.stub!(:code).and_return('200')
29
+ Components::Translators::Xml.should_receive(:deserialise).with(http_response)
30
+ Native::Response.new(http_response).deserialise_using(Components::Translators::Xml)
31
+ end
32
+
33
+ it "should know how to load a translator based on content type" do
34
+ http_response = mock('response')
35
+ http_response.stub!(:code).and_return('422')
36
+ http_response.should_receive(:content_type).and_return('application/xml')
37
+
38
+ response = Native::Response.new(http_response)
39
+ response.should_receive(:deserialise_using).with(Components::Translators::Xml)
40
+
41
+ response.deserialise
42
+ end
43
+
44
+ it "should simply return itself when asked to follow (null object behaviour - see MovedPermanently for more context)" do
45
+ http_response = mock('response')
46
+ http_response.stub!(:code).and_return('422')
47
+
48
+ response = Native::Response.new(http_response)
49
+ response.follow.equal?(response).should be_true
50
+ end
51
+
52
+ describe 'Keep-Alive' do
53
+ it "should know when a connection has been closed" do
54
+ http_response = mock('response')
55
+ http_response.stub!(:code).and_return('200')
56
+ http_response.should_receive(:[]).with(Wrest::H::Connection).and_return('Close')
57
+
58
+ response = Native::Response.new(http_response)
59
+ response.should be_connection_closed
60
+ end
61
+
62
+ it "should know when a keep-alive connection has been estalished" do
63
+ http_response = mock('response')
64
+ http_response.stub!(:code).and_return('200')
65
+ http_response.should_receive(:[]).with(Wrest::H::Connection).and_return('')
66
+
67
+ response = Native::Response.new(http_response)
68
+ response.should_not be_connection_closed
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,74 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ module Wrest
4
+ describe Native::Session do
5
+ describe 'Construction' do
6
+ it "should accept a string uri and convert it to a Wrest::Uri" do
7
+ uri = "http://localhost:3000"
8
+ Native::Session.new(uri).uri.should == uri.to_uri
9
+ end
10
+
11
+ it "should accept a Wrest::Uri" do
12
+ uri = "http://localhost:3000"
13
+ Native::Session.new(uri.to_uri).uri.should == uri.to_uri
14
+ end
15
+ end
16
+
17
+ it "should know how to use the connection provided to make requests" do
18
+ uri = "http://localhost:3000".to_uri
19
+ uri.should_not be_https
20
+
21
+ http = mock(Net::HTTP)
22
+ Net::HTTP.should_receive(:new).with('localhost', 3000).and_return(http)
23
+ http.should_receive(:read_timeout=).with(60)
24
+
25
+ request_one = Net::HTTP::Get.new('/glassware?owner=Kai&type=bottle', {H::Connection=>T::KeepAlive})
26
+ request_two = Net::HTTP::Get.new('/bottles.xml', {H::Connection=>T::KeepAlive})
27
+
28
+ Net::HTTP::Get.should_receive(:new).with('/glassware?owner=Kai&type=bottle', {H::Connection=>T::KeepAlive}).and_return(request_one)
29
+ Net::HTTP::Get.should_receive(:new).with('/bottles.xml', {H::Connection=>T::KeepAlive}).and_return(request_two)
30
+
31
+ ok_response = build_ok_response
32
+ ok_response.should_receive(:[]).with(Native::StandardHeaders::Connection).twice.and_return(Native::StandardTokens::KeepAlive)
33
+
34
+ http.should_receive(:request).with(request_one, nil).and_return(ok_response)
35
+ http.should_receive(:request).with(request_two, nil).and_return(ok_response)
36
+
37
+ Native::Session.new(uri) do |session|
38
+ session.get('/glassware', :owner => 'Kai', :type => 'bottle')
39
+ session.get '/bottles.xml'
40
+ end
41
+ end
42
+
43
+ it "should destroy the current connection if a response is returned with a Connection: Close" do
44
+ uri = "http://localhost:3000".to_uri
45
+ uri.should_not be_https
46
+
47
+ http = mock(Net::HTTP)
48
+ Net::HTTP.should_receive(:new).with('localhost', 3000).and_return(http)
49
+ http.should_receive(:read_timeout=).with(60)
50
+
51
+ request_one = Net::HTTP::Get.new('/glassware?owner=Kai&type=bottle', {H::Connection=>T::KeepAlive})
52
+ request_two = Net::HTTP::Get.new('/bottles.xml', {H::Connection=>T::KeepAlive})
53
+
54
+ Net::HTTP::Get.should_receive(:new).with('/glassware?owner=Kai&type=bottle', {H::Connection=>T::KeepAlive}).and_return(request_one)
55
+ Net::HTTP::Get.should_receive(:new).with('/bottles.xml', {H::Connection=>T::KeepAlive}).and_return(request_two)
56
+
57
+ ok_response = build_ok_response
58
+ ok_response.should_receive(:[]).with(Native::StandardHeaders::Connection).once.and_return(Native::StandardTokens::KeepAlive)
59
+
60
+ ok_response_with_connection_close = build_ok_response
61
+ ok_response_with_connection_close.should_receive(:[]).with(Native::StandardHeaders::Connection).once.and_return(Native::StandardTokens::Close)
62
+
63
+ http.should_receive(:request).with(request_one, nil).and_return(ok_response)
64
+ http.should_receive(:request).with(request_two, nil).and_return(ok_response_with_connection_close)
65
+
66
+ Native::Session.new(uri) do |session|
67
+ session.get('/glassware', :owner => 'Kai', :type => 'bottle')
68
+ session.instance_variable_get('@connection').should == http
69
+ session.get '/bottles.xml'
70
+ session.instance_variable_get('@connection').should be_nil
71
+ end
72
+ end
73
+ end
74
+ end
@@ -165,7 +165,7 @@ module Wrest
165
165
  it "should know how to find a resource by id" do
166
166
  uri = 'http://localhost:3001/bottled_universe/1.xml'.to_uri
167
167
  Wrest::Uri.should_receive(:new).with('http://localhost:3001/bottled_universes/1.xml', {}).and_return(uri)
168
- response = mock(Wrest::Http::Response)
168
+ response = mock(Wrest::Native::Response)
169
169
  uri.should_receive(:get).with(no_args).and_return(response)
170
170
  response.should_receive(:deserialise).and_return({"bottled-universe"=>{"name"=>{"__content__"=>"Wooz"}, "universe-id"=>{"type"=>"integer", "nil"=>"true"}, "id"=>{"__content__"=>"1", "type"=>"integer"}}})
171
171
 
@@ -196,7 +196,7 @@ module Wrest
196
196
  uri.should_receive(:post).with(
197
197
  "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<bottled-universe>\n <name>Woot</name>\n</bottled-universe>\n",
198
198
  'Content-Type' => 'application/xml'
199
- ).and_return(Wrest::Http::Response.new(mock_http_response))
199
+ ).and_return(Wrest::Native::Response.new(mock_http_response))
200
200
  ware = BottledUniverse.create(:name => 'Woot')
201
201
  end
202
202
  end
@@ -11,14 +11,6 @@ require File.dirname(__FILE__) + '/../spec_helper'
11
11
 
12
12
  module Wrest
13
13
  describe Wrest::Uri do
14
- def build_ok_response(body = '')
15
- returning mock(Net::HTTPOK) do |response|
16
- response.stub!(:code).and_return('200')
17
- response.stub!(:message).and_return('OK')
18
- response.stub!(:body).and_return(body)
19
- end
20
- end
21
-
22
14
  it "should respond to the four http actions" do
23
15
  uri = Uri.new('http://localhost')
24
16
  uri.should respond_to(:get)
@@ -38,7 +30,7 @@ module Wrest
38
30
  it "should know how to build a new uri from an existing one by appending a path" do
39
31
  Uri.new('http://localhost:3000')['/ooga/booga'].should == Uri.new('http://localhost:3000/ooga/booga')
40
32
  end
41
-
33
+
42
34
  it "should know its full path" do
43
35
  Uri.new('http://localhost:3000/ooga').full_path.should == '/ooga'
44
36
  Uri.new('http://localhost:3000/ooga?foo=meh&bar=1').full_path.should == '/ooga?foo=meh&bar=1'
@@ -47,12 +39,12 @@ module Wrest
47
39
  it "should know its host" do
48
40
  Uri.new('http://localhost:3000/ooga').host.should == 'localhost'
49
41
  end
50
-
42
+
51
43
  it "should know its port" do
52
44
  Uri.new('http://localhost:3000/ooga').port.should == 3000
53
45
  Uri.new('http://localhost/ooga').port.should == 80
54
46
  end
55
-
47
+
56
48
  it "should include the username and password while building a new uri if no options are provided" do
57
49
  Uri.new(
58
50
  'http://localhost:3000',
@@ -73,6 +65,13 @@ module Wrest
73
65
  extended_uri.password.should == 'baz'
74
66
  end
75
67
 
68
+ it "should know how to produce its uri as a string" do
69
+ Uri.new('http://localhost:3000').uri_string.should == 'http://localhost:3000'
70
+ Uri.new('http://localhost:3000').to_s.should == 'http://localhost:3000'
71
+ Uri.new('http://localhost:3000', :username => 'foo', :password => 'bar').to_s.should == 'http://localhost:3000'
72
+ Uri.new('http://foo:bar@localhost:3000').to_s.should == 'http://foo:bar@localhost:3000'
73
+ end
74
+
76
75
  describe 'Equals' do
77
76
  it "should understand equality" do
78
77
  Uri.new('https://localhost:3000/ooga').should_not == nil
@@ -105,6 +104,29 @@ module Wrest
105
104
  end
106
105
  end
107
106
 
107
+ describe 'Cloning' do
108
+ before :each do
109
+ @original = Uri.new('http://localhost:3000/ooga')
110
+ @clone = @original.clone
111
+ end
112
+
113
+ it "should be equal to its clone" do
114
+ @original.should == @clone
115
+ end
116
+
117
+ it "should not be the same object as the clone" do
118
+ @original.should_not be_equal(@clone)
119
+ end
120
+
121
+ it "should allow options to be changed when building the clone" do
122
+ clone = @original.clone(:username => 'kaiwren', :password => 'bottle')
123
+ @original.should_not == clone
124
+ clone.username.should == 'kaiwren'
125
+ clone.password.should == 'bottle'
126
+ @original.username.should be_nil
127
+ end
128
+ end
129
+
108
130
  describe 'HTTP actions' do
109
131
  def setup_http
110
132
  returning mock(Net::HTTP) do |http|
@@ -168,6 +190,24 @@ module Wrest
168
190
 
169
191
  uri.post '<ooga>Booga</ooga>', :page => '2', :per_page => '5'
170
192
  end
193
+
194
+ it "should know how to post form-encoded parameters using Uri#post_form" do
195
+ uri = "http://localhost:3000/glassware".to_uri
196
+ uri.should_not be_https
197
+
198
+ http = setup_http
199
+
200
+ request = Net::HTTP::Post.new('/glassware', {'page' => '2', 'per_page' => '5'})
201
+ Net::HTTP::Post.should_receive(:new).with('/glassware',
202
+ 'page' => '2', 'per_page' => '5', H::ContentType=>T::FormEncoded
203
+ ).and_return(request)
204
+
205
+ http.should_receive(:request).with(request, "foo=bar&ooga=booga").and_return(build_ok_response)
206
+ params = ActiveSupport::OrderedHash.new
207
+ params[:ooga] = 'booga'
208
+ params[:foo] = 'bar'
209
+ uri.post_form(params, :page => '2', :per_page => '5')
210
+ end
171
211
 
172
212
  it "should know how to put" do
173
213
  uri = "http://localhost:3000/glassware".to_uri