wrest 0.0.8 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +24 -17
- data/Rakefile +5 -4
- data/VERSION.yml +1 -1
- data/examples/delicious.rb +7 -3
- data/examples/redirection.rb +27 -0
- data/examples/twitter.rb +78 -0
- data/{spec/wrest/http/request_spec.rb → examples/twitter_public_timeline.rb} +15 -12
- data/examples/wow_realm_status.rb +7 -3
- data/lib/wrest/components/attributes_container/alias_accessors.rb +66 -0
- data/lib/wrest/components/attributes_container/typecaster.rb +44 -38
- data/lib/wrest/components/attributes_container.rb +23 -5
- data/lib/wrest/components/mutators/base.rb +1 -1
- data/lib/wrest/components/translators.rb +1 -1
- data/lib/wrest/core_ext/string/conversions.rb +1 -1
- data/lib/wrest/exceptions.rb +14 -2
- data/lib/wrest/http/get.rb +2 -0
- data/lib/wrest/http/redirection.rb +35 -0
- data/lib/wrest/http/request.rb +37 -13
- data/lib/wrest/http/response.rb +17 -0
- data/lib/wrest/http.rb +1 -0
- data/lib/wrest/resource/base.rb +1 -2
- data/lib/wrest/uri.rb +2 -0
- data/lib/wrest/version.rb +1 -1
- data/spec/functional/sample_rails_app/README +3 -0
- data/spec/functional/sample_rails_app/Rakefile +10 -0
- data/spec/functional/sample_rails_app/app/controllers/application_controller.rb +10 -0
- data/spec/functional/sample_rails_app/app/controllers/lead_bottles_controller.rb +7 -0
- data/spec/functional/sample_rails_app/app/helpers/application_helper.rb +3 -0
- data/spec/functional/sample_rails_app/app/models/bottle.rb +3 -0
- data/spec/functional/sample_rails_app/app/models/glass_bottle.rb +3 -0
- data/spec/functional/sample_rails_app/app/models/lead_bottle.rb +3 -0
- data/spec/functional/sample_rails_app/config/boot.rb +110 -0
- data/spec/functional/sample_rails_app/config/database.yml +16 -0
- data/spec/functional/sample_rails_app/config/environment.rb +42 -0
- data/spec/functional/sample_rails_app/config/environments/development.rb +17 -0
- data/spec/functional/sample_rails_app/config/environments/production.rb +28 -0
- data/spec/functional/sample_rails_app/config/environments/test.rb +28 -0
- data/spec/functional/sample_rails_app/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/functional/sample_rails_app/config/initializers/inflections.rb +10 -0
- data/spec/functional/sample_rails_app/config/initializers/mime_types.rb +5 -0
- data/spec/functional/sample_rails_app/config/initializers/new_rails_defaults.rb +19 -0
- data/spec/functional/sample_rails_app/config/initializers/session_store.rb +15 -0
- data/spec/functional/sample_rails_app/config/locales/en.yml +5 -0
- data/spec/functional/sample_rails_app/config/routes.rb +3 -0
- data/spec/functional/sample_rails_app/db/development.sqlite3 +0 -0
- data/spec/functional/sample_rails_app/db/migrate/20090319115628_create_bottle.rb +13 -0
- data/spec/functional/sample_rails_app/db/schema.rb +20 -0
- data/spec/functional/sample_rails_app/db/test.sqlite3 +0 -0
- data/spec/functional/sample_rails_app/log/development.log +1 -0
- data/spec/functional/sample_rails_app/public/404.html +30 -0
- data/spec/functional/sample_rails_app/public/422.html +30 -0
- data/spec/functional/sample_rails_app/public/500.html +30 -0
- data/spec/functional/sample_rails_app/public/favicon.ico +0 -0
- data/spec/functional/sample_rails_app/public/images/rails.png +0 -0
- data/spec/functional/sample_rails_app/public/index.html +275 -0
- data/spec/functional/sample_rails_app/public/robots.txt +5 -0
- data/spec/functional/sample_rails_app/script/about +4 -0
- data/spec/functional/sample_rails_app/script/autospec +6 -0
- data/spec/functional/sample_rails_app/script/console +3 -0
- data/spec/functional/sample_rails_app/script/dbconsole +3 -0
- data/spec/functional/sample_rails_app/script/destroy +3 -0
- data/spec/functional/sample_rails_app/script/generate +3 -0
- data/spec/functional/sample_rails_app/script/performance/benchmarker +3 -0
- data/spec/functional/sample_rails_app/script/performance/profiler +3 -0
- data/spec/functional/sample_rails_app/script/plugin +3 -0
- data/spec/functional/sample_rails_app/script/runner +3 -0
- data/spec/functional/sample_rails_app/script/server +3 -0
- data/spec/functional/sample_rails_app/script/spec +10 -0
- data/spec/functional/sample_rails_app/script/spec_server +9 -0
- data/spec/functional/sample_rails_app/test/performance/browsing_test.rb +9 -0
- data/spec/functional/sample_rails_app/test/test_helper.rb +38 -0
- data/spec/functional/sample_rails_app/tmtags +2559 -0
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/MIT-LICENSE +20 -0
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/README.rdoc +100 -0
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/Rakefile +18 -0
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/init.rb +5 -0
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/install.rb +1 -0
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/base.rb +140 -0
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/controllers/resources.rb +16 -0
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/controllers/resources_controller.rb +26 -0
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/controllers/routes_controller.rb +16 -0
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/core_extensions/api.rb +26 -0
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/core_extensions/exception.rb +23 -0
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/core_extensions/from_json.rb +15 -0
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/dispatch.rb +235 -0
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/models/resourced_route.rb +84 -0
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/query.rb +337 -0
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/render/html.rb +50 -0
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/render/json.rb +75 -0
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/render/xml.rb +65 -0
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/render.rb +63 -0
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/retrieve.rb +74 -0
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/version.rb +9 -0
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full.rb +14 -0
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/base_spec.rb +88 -0
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/controllers/resources_spec.rb +29 -0
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/dispatch_spec.rb +262 -0
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/models/resourced_route_spec.rb +62 -0
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/query/parameter_spec.rb +57 -0
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/query_spec.rb +462 -0
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/render/html_spec.rb +4 -0
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/render/json_spec.rb +107 -0
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/render/xml_spec.rb +98 -0
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/render_spec.rb +5 -0
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/retrieve_spec.rb +173 -0
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/spec_helper.rb +98 -0
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/uninstall.rb +1 -0
- data/spec/functional/spec_helper.rb +0 -0
- data/spec/{spec_helper.rb → unit/spec_helper.rb} +2 -2
- data/spec/unit/wrest/components/attributes_container/alias_accessors_spec.rb +49 -0
- data/spec/{wrest → unit/wrest}/components/attributes_container/typecaster_spec.rb +28 -8
- data/spec/{wrest → unit/wrest}/components/attributes_container_spec.rb +42 -15
- data/spec/{wrest → unit/wrest}/components/mutators/base_spec.rb +1 -1
- data/spec/{wrest → unit/wrest}/components/mutators/camel_to_snake_spec.rb +0 -0
- data/spec/{wrest → unit/wrest}/components/mutators/xml_mini_type_caster_spec.rb +0 -0
- data/spec/{wrest → unit/wrest}/components/mutators/xml_simple_type_caster_spec.rb +0 -0
- data/spec/{wrest → unit/wrest}/components/mutators_spec.rb +0 -0
- data/spec/{wrest → unit/wrest}/components/translators/xml_spec.rb +0 -0
- data/spec/{wrest → unit/wrest}/components/translators_spec.rb +1 -1
- data/spec/{wrest → unit/wrest}/core_ext/hash/conversions_spec.rb +0 -0
- data/spec/{wrest → unit/wrest}/core_ext/string/conversions_spec.rb +14 -0
- data/spec/unit/wrest/http/redirection_spec.rb +42 -0
- data/spec/unit/wrest/http/request_spec.rb +70 -0
- data/spec/unit/wrest/http/response_spec.rb +45 -0
- data/spec/{wrest → unit/wrest}/resource/base_spec.rb +5 -4
- data/spec/{wrest → unit/wrest}/uri_spec.rb +68 -67
- data/spec/{wrest → unit/wrest}/uri_template_spec.rb +0 -0
- metadata +187 -38
- data/lib/wrest/exceptions/method_not_overridden_exception.rb +0 -17
- data/lib/wrest/exceptions/unsupported_content_type_exception.rb +0 -17
- data/spec/wrest/http/response_spec.rb +0 -21
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
|
2
|
+
|
|
3
|
+
describe "ResourceFull::Retrieve", :type => :controller do
|
|
4
|
+
controller_name "resource_full_mock_users"
|
|
5
|
+
|
|
6
|
+
before :each do
|
|
7
|
+
ResourceFullMockUser.delete_all
|
|
8
|
+
ResourceFullMockUsersController.resource_identifier = :id
|
|
9
|
+
ResourceFullMockUsersController.queryable_params = []
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "defines custom methods based on the class name" do
|
|
13
|
+
controller.should respond_to(
|
|
14
|
+
:find_resource_full_mock_user,
|
|
15
|
+
:find_all_resource_full_mock_users,
|
|
16
|
+
:update_resource_full_mock_user,
|
|
17
|
+
:destroy_resource_full_mock_user,
|
|
18
|
+
:new_resource_full_mock_user
|
|
19
|
+
)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "changes the custom methods if the model name is changed" do
|
|
23
|
+
controller.class.exposes ResourceFullMock
|
|
24
|
+
controller.should respond_to(:find_resource_full_mock)
|
|
25
|
+
controller.should_not respond_to(:find_resource_full_mock_user)
|
|
26
|
+
controller.class.exposes ResourceFullMockUser # cleanup
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "finds the requested model object" do
|
|
30
|
+
user = ResourceFullMockUser.create!
|
|
31
|
+
get :show, :id => user.id
|
|
32
|
+
assigns(:resource_full_mock_user).should == user
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
describe "resource_identifier and identified_by" do
|
|
36
|
+
controller_name "resource_full_mock_users"
|
|
37
|
+
|
|
38
|
+
before :each do
|
|
39
|
+
ResourceFullMockUser.delete_all
|
|
40
|
+
ResourceFullMockUsersController.resource_identifier = :id
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def get_should_retrieve_by_first_name
|
|
44
|
+
eustace = ResourceFullMockUser.create! :first_name => "eustace"
|
|
45
|
+
eustace_noise = ResourceFullMockUser.create! :first_name => eustace.id
|
|
46
|
+
get :show, :id => "eustace"
|
|
47
|
+
assigns(:resource_full_mock_user).should == eustace
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def get_should_retrieve_by_id
|
|
51
|
+
jimbo = ResourceFullMockUser.create! :first_name => "jimbo"
|
|
52
|
+
jimbo_noise = ResourceFullMockUser.create! :first_name => jimbo.id
|
|
53
|
+
get :show, :id => jimbo.id
|
|
54
|
+
assigns(:resource_full_mock_user).should == jimbo
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it "finds the requested model object using the correct column if the resource_identifier attribute has been overridden" do
|
|
58
|
+
ResourceFullMockUsersController.resource_identifier = :first_name
|
|
59
|
+
get_should_retrieve_by_first_name
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it "doesn't find the requested model object if there are none to find" do
|
|
63
|
+
ResourceFullMockUsersController.resource_identifier = :first_name
|
|
64
|
+
get :show, :id => "eustace"
|
|
65
|
+
assigns(:resource_full_mock_user).should be_nil
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it "finds the requested model object using the correct column if a block is provided to resource_identifier" do
|
|
69
|
+
ResourceFullMockUsersController.resource_identifier = lambda do |id|
|
|
70
|
+
if id =~ /[0-9]+/
|
|
71
|
+
:id
|
|
72
|
+
else :first_name end
|
|
73
|
+
end
|
|
74
|
+
get_should_retrieve_by_first_name
|
|
75
|
+
get_should_retrieve_by_id
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it "finds the requested model object only if the optional block provided to identifed_by is true" do
|
|
79
|
+
ResourceFullMockUsersController.identified_by :first_name, :if => lambda { |id| id =~ /[a-zA-Z]+/ }
|
|
80
|
+
get_should_retrieve_by_first_name
|
|
81
|
+
get_should_retrieve_by_id
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it "finds the requested model object unless the optional block provided to identifed_by is true" do
|
|
85
|
+
ResourceFullMockUsersController.identified_by :first_name, :unless => lambda { |id| id =~ /[0-9]+/ }
|
|
86
|
+
get_should_retrieve_by_first_name
|
|
87
|
+
get_should_retrieve_by_id
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
it "finds the requested model object unless it requests a fallback to a numeric id" do
|
|
91
|
+
ResourceFullMockUsersController.identified_by :first_name, :unless => :id_numeric
|
|
92
|
+
get_should_retrieve_by_first_name
|
|
93
|
+
get_should_retrieve_by_id
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it "updates the requested model object based on the given parameters" do
|
|
98
|
+
user = ResourceFullMockUser.create! :last_name => "threepwood"
|
|
99
|
+
post :update, :id => user.id, :resource_full_mock_user => { :last_name => "guybrush" }
|
|
100
|
+
user.reload.last_name.should == "guybrush"
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it "updates the requested model object using the correct column if the resource_identifier attribute has been overridden" do
|
|
104
|
+
ResourceFullMockUsersController.resource_identifier = :first_name
|
|
105
|
+
user = ResourceFullMockUser.create! :first_name => "guybrush"
|
|
106
|
+
post :update, :id => "guybrush", :resource_full_mock_user => { :last_name => "threepwood" }
|
|
107
|
+
user.reload.last_name.should == "threepwood"
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
it "creates a new model object based on the given parameters" do
|
|
111
|
+
put :create, :resource_full_mock_user => { :first_name => "guybrush", :last_name => "threepwood" }
|
|
112
|
+
ResourceFullMockUser.count.should == 1
|
|
113
|
+
ResourceFullMockUser.find(:first).first_name.should == "guybrush"
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
it "creates a new model object appropriately if a creational parameter is queryable but not placed in the model object params, as with a nested route" do
|
|
117
|
+
ResourceFullMockUsersController.queryable_with :first_name
|
|
118
|
+
put :create, :first_name => "guybrush", :resource_full_mock_user => { :last_name => "threepwood" }
|
|
119
|
+
ResourceFullMockUser.count.should == 1
|
|
120
|
+
user = ResourceFullMockUser.find :first
|
|
121
|
+
user.first_name.should == "guybrush"
|
|
122
|
+
user.last_name.should == "threepwood"
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
it "deletes the requested model object" do
|
|
126
|
+
user = ResourceFullMockUser.create!
|
|
127
|
+
delete :destroy, :id => user.id
|
|
128
|
+
ResourceFullMockUser.exists?(user.id).should be_false
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
it "deletes the requested model object using the correct column if the resource_identifier attribute has been overridden" do
|
|
132
|
+
ResourceFullMockUsersController.resource_identifier = :first_name
|
|
133
|
+
user = ResourceFullMockUser.create! :first_name => "guybrush"
|
|
134
|
+
delete :destroy, :id => "guybrush"
|
|
135
|
+
ResourceFullMockUser.exists?(user.id).should be_false
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
describe "with pagination" do
|
|
139
|
+
controller_name "resource_full_mock_users"
|
|
140
|
+
|
|
141
|
+
before :each do
|
|
142
|
+
ResourceFullMockUser.delete_all
|
|
143
|
+
@users = (1..6).collect { ResourceFullMockUser.create! }
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
after :all do
|
|
147
|
+
ResourceFullMockUser.delete_all
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
it "limits the query to the correct number of records given that parameter" do
|
|
151
|
+
ResourceFullMockUsersController.queryable_with :limit, :scope => lambda {|limit| { :limit => limit }}
|
|
152
|
+
get :index, :limit => 2
|
|
153
|
+
assigns(:resource_full_mock_users).should == @users[0..1]
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
it "offsets the query by the correct number of records" do
|
|
157
|
+
ResourceFullMockUsersController.queryable_with :limit, :scope => lambda {|limit| { :limit => limit }}
|
|
158
|
+
ResourceFullMockUsersController.queryable_with :offset, :scope => lambda {|offset| { :offset => offset }}
|
|
159
|
+
get :index, :offset => 4, :limit => 2
|
|
160
|
+
assigns(:resource_full_mock_users).should == @users[4..5]
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
xit "doesn't attempt to paginate if pagination is disabled" do
|
|
164
|
+
ResourceFullMockUsersController.queryable_with :limit, :scope => lambda {|limit| { :limit => limit }}
|
|
165
|
+
ResourceFullMockUsersController.queryable_with :offset, :scope => lambda {|offset| { :offset => offset }}
|
|
166
|
+
ResourceFullMockUsersController.paginatable = false
|
|
167
|
+
get :index, :offset => 4, :limit => 2
|
|
168
|
+
assigns(:resource_full_mock_users).should == @users
|
|
169
|
+
ResourceFullMockUsersController.paginatable = true # cleanup
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
end
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# This file is copied to ~/spec when you run 'ruby script/generate rspec'
|
|
2
|
+
# from the project root directory.
|
|
3
|
+
ENV["RAILS_ENV"] = "test"
|
|
4
|
+
|
|
5
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../../../config/environment')
|
|
6
|
+
require 'spec'
|
|
7
|
+
require 'spec/rails'
|
|
8
|
+
require 'resource_full/core_extensions/from_json'
|
|
9
|
+
|
|
10
|
+
Spec::Runner.configure do |config|
|
|
11
|
+
# If you're not using ActiveRecord you should remove these
|
|
12
|
+
# lines, delete config/database.yml and disable :active_record
|
|
13
|
+
# in your config/boot.rb
|
|
14
|
+
config.use_transactional_fixtures = true
|
|
15
|
+
config.use_instantiated_fixtures = false
|
|
16
|
+
config.fixture_path = RAILS_ROOT + '/vendor/plugins/resource_full/spec/fixtures/'
|
|
17
|
+
config.mock_with :mocha
|
|
18
|
+
|
|
19
|
+
config.before(:all) do
|
|
20
|
+
ActiveRecord::Base.connection.create_table "resource_full_mock_addresses", :force => true do |t|
|
|
21
|
+
t.string "street"
|
|
22
|
+
t.string "city"
|
|
23
|
+
t.string "state_code"
|
|
24
|
+
t.integer "zip"
|
|
25
|
+
t.integer "resource_full_mock_user_id"
|
|
26
|
+
t.timestamps
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
ActiveRecord::Base.connection.create_table "resource_full_mock_users", :force => true do |t|
|
|
30
|
+
t.string "first_name"
|
|
31
|
+
t.string "last_name"
|
|
32
|
+
t.date "birthdate"
|
|
33
|
+
t.string "email"
|
|
34
|
+
t.string "join_date"
|
|
35
|
+
t.integer "income"
|
|
36
|
+
t.integer "resource_full_mock_employer_id"
|
|
37
|
+
t.timestamps
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
ActiveRecord::Base.connection.create_table "resource_full_mock_employers", :force => true do |t|
|
|
41
|
+
t.string "name"
|
|
42
|
+
t.string "email"
|
|
43
|
+
t.timestamps
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
ActionController::Routing::Routes.draw do |map|
|
|
49
|
+
map.foo '/foo', :controller => 'resource_full_mocks', :action => 'foo'
|
|
50
|
+
map.resources :resource_full_mocks, :resource_full_sub_mocks, :resource_full_mock_addresses
|
|
51
|
+
map.resources :resource_full_mock_users, :collection => {:count => :get} do |users|
|
|
52
|
+
users.resources :resource_full_mock_addresses
|
|
53
|
+
end
|
|
54
|
+
map.resources :resources, :controller => 'resource_full/controllers/resources' do |resource|
|
|
55
|
+
resource.resources :routes, :controller => 'resource_full/controllers/routes'
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
class ResourceFullMock
|
|
60
|
+
def self.table_name; "mock"; end
|
|
61
|
+
end
|
|
62
|
+
class ResourceFullSubMock < ResourceFullMock; end
|
|
63
|
+
|
|
64
|
+
# TODO Remove these or find a better way to handle ActiveRecord dependencies.
|
|
65
|
+
class ResourceFullMockEmployer < ActiveRecord::Base
|
|
66
|
+
has_many :resource_full_mock_users
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
class ResourceFullMockUser < ActiveRecord::Base
|
|
70
|
+
belongs_to :resource_full_mock_employer
|
|
71
|
+
has_many :resource_full_mock_addresses
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
class ResourceFullMockAddress < ActiveRecord::Base
|
|
75
|
+
belongs_to :resource_full_mock_user
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
class ResourceFullMocksController < ResourceFull::Base
|
|
79
|
+
# dispatch_spec custom methods spec, approx. line 98
|
|
80
|
+
def foo
|
|
81
|
+
render :xml => { :foo => "bar" }.to_xml
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
class ResourceFullSubMocksController < ResourceFullMocksController; end
|
|
85
|
+
class ResourceFullMockUsersController < ResourceFull::Base; end
|
|
86
|
+
class ResourceFullMockAddressesController < ResourceFull::Base; end
|
|
87
|
+
|
|
88
|
+
ActionController::Routing.use_controllers! %w{
|
|
89
|
+
resource_full_mock_users
|
|
90
|
+
resource_full_mock_addresses
|
|
91
|
+
resource_full_mocks
|
|
92
|
+
resource_full_sub_mocks
|
|
93
|
+
resource_full/controllers/routes
|
|
94
|
+
resource_full/controllers/resources
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
def putsh(stuff); puts ERB::Util.h(stuff) + "<br/>"; end
|
|
98
|
+
def ph(stuff); puts ERB::Util.h(stuff.inspect) + "<br/>"; end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Uninstall hook code here
|
|
File without changes
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + "
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../../lib/wrest")
|
|
2
2
|
require 'spec'
|
|
3
3
|
|
|
4
|
-
[
|
|
4
|
+
['/../custom_matchers/**/*.rb'].each{|directory|
|
|
5
5
|
Dir["#{File.expand_path(File.dirname(__FILE__) + directory)}"].each { |file|
|
|
6
6
|
require file
|
|
7
7
|
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/../../../spec_helper'
|
|
2
|
+
|
|
3
|
+
module Wrest::Components
|
|
4
|
+
describe AttributesContainer::AliasAccessors do
|
|
5
|
+
before :each do
|
|
6
|
+
@Demon = Class.new
|
|
7
|
+
@Demon.class_eval do
|
|
8
|
+
include Wrest::Components::AttributesContainer
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "should provide a macro to enable aliasing accessors" do
|
|
13
|
+
lambda{ @Demon.class_eval{ alias_accessors :shiriki => :chambala } }.should_not raise_error(NoMethodError)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
describe 'aliasing' do
|
|
17
|
+
before :each do
|
|
18
|
+
@Demon.class_eval{ alias_accessors :sex => :gender, :age => :maturity }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "should provide an accessor methods when we alias to an attribute" do
|
|
22
|
+
demon = @Demon.new
|
|
23
|
+
demon.should respond_to(:gender)
|
|
24
|
+
demon.should respond_to(:gender=)
|
|
25
|
+
demon.should respond_to(:gender?)
|
|
26
|
+
demon.should respond_to(:maturity)
|
|
27
|
+
demon.should respond_to(:maturity=)
|
|
28
|
+
demon.should respond_to(:maturity?)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "should ensure that the aliased getter method delegates to the actual getter" do
|
|
32
|
+
demon = @Demon.new :sex => 'male'
|
|
33
|
+
demon.gender.should == 'male'
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "should ensure that the aliased setter method delegates to the actual getter" do
|
|
37
|
+
demon = @Demon.new
|
|
38
|
+
demon.should_receive(:sex=).with('male')
|
|
39
|
+
demon.gender = 'male'
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "should ensure that the aliased query method delegates to the actual queryier" do
|
|
43
|
+
demon = @Demon.new :age => '1000'
|
|
44
|
+
demon.gender?.should be_false
|
|
45
|
+
demon.maturity?.should be_true
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -5,8 +5,8 @@ module Wrest::Components
|
|
|
5
5
|
before :each do
|
|
6
6
|
@Demon = Class.new
|
|
7
7
|
@Demon.class_eval do
|
|
8
|
-
include AttributesContainer
|
|
9
|
-
include AttributesContainer::Typecaster
|
|
8
|
+
include Wrest::Components::AttributesContainer
|
|
9
|
+
include Wrest::Components::AttributesContainer::Typecaster
|
|
10
10
|
end
|
|
11
11
|
end
|
|
12
12
|
|
|
@@ -16,10 +16,30 @@ module Wrest::Components
|
|
|
16
16
|
kai_wren.age.should == 1
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
describe "where the value is not a typecastable type" do
|
|
20
|
+
it "string should not typecast" do
|
|
21
|
+
@Demon.class_eval{ typecast :age => lambda{|id_string| id_string.to_i} }
|
|
22
|
+
kai_wren = @Demon.new('age' => :ooga)
|
|
23
|
+
kai_wren.age.should == :ooga
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "hash should not typecast" do
|
|
27
|
+
class TestUser
|
|
28
|
+
include Wrest::Components::AttributesContainer
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
@Demon.class_eval{ typecast :user => lambda{|user| TestUser.new(user)}}
|
|
32
|
+
|
|
33
|
+
kai_wren = @Demon.new('user' => {'foo' => 'bar'})
|
|
34
|
+
kai_wren.user.class.should == TestUser
|
|
35
|
+
kai_wren.user.foo.should == 'bar'
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "array should not typecast" do
|
|
39
|
+
@Demon.class_eval{ typecast :addresses => lambda{|addresses| addresses.first} }
|
|
40
|
+
kai_wren = @Demon.new('addresses' => ['foo', 'bar'])
|
|
41
|
+
kai_wren.addresses.should == 'foo'
|
|
42
|
+
end
|
|
23
43
|
end
|
|
24
44
|
|
|
25
45
|
it "should leave nils unchanged" do
|
|
@@ -38,8 +58,8 @@ module Wrest::Components
|
|
|
38
58
|
before :each do
|
|
39
59
|
@Sidhe = Class.new
|
|
40
60
|
@Sidhe.class_eval do
|
|
41
|
-
include AttributesContainer
|
|
42
|
-
include AttributesContainer::Typecaster
|
|
61
|
+
include Wrest::Components::AttributesContainer
|
|
62
|
+
include Wrest::Components::AttributesContainer::Typecaster
|
|
43
63
|
|
|
44
64
|
typecast :age => as_integer
|
|
45
65
|
end
|
|
@@ -12,10 +12,34 @@ require File.dirname(__FILE__) + '/../../spec_helper'
|
|
|
12
12
|
module Wrest::Components
|
|
13
13
|
describe AttributesContainer do
|
|
14
14
|
class HumanBeing
|
|
15
|
-
include AttributesContainer
|
|
15
|
+
include Wrest::Components::AttributesContainer
|
|
16
16
|
always_has :id
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
+
describe "typecasting" do
|
|
20
|
+
before(:each) do
|
|
21
|
+
@Demon = Class.new
|
|
22
|
+
|
|
23
|
+
@Demon.class_eval do
|
|
24
|
+
include Wrest::Components::AttributesContainer
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "should delegate to AttributesContainer::Typecaster#typecast to actually do the typecasting" do
|
|
29
|
+
@Demon.class_eval do
|
|
30
|
+
typecast :foo => lambda{|value| value.to_i}
|
|
31
|
+
end
|
|
32
|
+
@Demon.new(:foo => '1').foo.should == 1
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "should provide helpers for common typecasts" do
|
|
36
|
+
@Demon.class_eval do
|
|
37
|
+
typecast :foo => as_integer
|
|
38
|
+
end
|
|
39
|
+
@Demon.new(:foo => '1').foo.should == 1
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
19
43
|
it "should allow instantiation with no attributes" do
|
|
20
44
|
lambda{ HumanBeing.new }.should_not raise_error
|
|
21
45
|
end
|
|
@@ -26,39 +50,41 @@ module Wrest::Components
|
|
|
26
50
|
@Demon = Class.new
|
|
27
51
|
end
|
|
28
52
|
|
|
53
|
+
# Methods are string in 1.8 and symbols in 1.9. We'll use to_sym to
|
|
54
|
+
# allow us to build on both.
|
|
29
55
|
it "should define attribute getters at the class level" do
|
|
30
56
|
kai_wren = @Demon.new
|
|
31
|
-
kai_wren.methods.should_not include(
|
|
57
|
+
kai_wren.methods.map(&:to_sym).should_not include(:trainer)
|
|
32
58
|
|
|
33
59
|
@Demon.class_eval{
|
|
34
|
-
include AttributesContainer
|
|
60
|
+
include Wrest::Components::AttributesContainer
|
|
35
61
|
always_has :trainer
|
|
36
62
|
}
|
|
37
63
|
|
|
38
|
-
kai_wren.methods.should include(
|
|
64
|
+
kai_wren.methods.map(&:to_sym).should include(:trainer)
|
|
39
65
|
end
|
|
40
66
|
|
|
41
67
|
it "should define attribute setters at the class level" do
|
|
42
68
|
kai_wren = @Demon.new
|
|
43
|
-
kai_wren.methods.should_not include(
|
|
69
|
+
kai_wren.methods.map(&:to_sym).should_not include(:trainer=)
|
|
44
70
|
|
|
45
71
|
@Demon.class_eval{
|
|
46
|
-
include AttributesContainer
|
|
72
|
+
include Wrest::Components::AttributesContainer
|
|
47
73
|
always_has :trainer
|
|
48
74
|
}
|
|
49
75
|
|
|
50
|
-
kai_wren.methods.should include(
|
|
76
|
+
kai_wren.methods.map(&:to_sym).should include(:trainer=)
|
|
51
77
|
end
|
|
52
78
|
|
|
53
79
|
it "should define attribute query methods at the class level" do
|
|
54
80
|
kai_wren = @Demon.new
|
|
55
|
-
kai_wren.methods.should_not include(
|
|
81
|
+
kai_wren.methods.map(&:to_sym).should_not include(:trainer?)
|
|
56
82
|
|
|
57
83
|
@Demon.class_eval{
|
|
58
|
-
include AttributesContainer
|
|
84
|
+
include Wrest::Components::AttributesContainer
|
|
59
85
|
always_has :trainer
|
|
60
86
|
}
|
|
61
|
-
kai_wren.methods.should include(
|
|
87
|
+
kai_wren.methods.map(&:to_sym).should include(:trainer?)
|
|
62
88
|
end
|
|
63
89
|
end
|
|
64
90
|
|
|
@@ -66,7 +92,7 @@ module Wrest::Components
|
|
|
66
92
|
before :each do
|
|
67
93
|
@Demon = Class.new
|
|
68
94
|
@Demon.class_eval{
|
|
69
|
-
include AttributesContainer
|
|
95
|
+
include Wrest::Components::AttributesContainer
|
|
70
96
|
always_has :trainer
|
|
71
97
|
|
|
72
98
|
def method_missing(method_name, *args)
|
|
@@ -155,14 +181,15 @@ module Wrest::Components
|
|
|
155
181
|
@li_piao.should_not respond_to(:god=)
|
|
156
182
|
end
|
|
157
183
|
|
|
158
|
-
it "should
|
|
159
|
-
|
|
184
|
+
it "should return false when query methods for attributes that don't exist are invoked" do
|
|
185
|
+
@li_piao.ooga?.should be_false
|
|
160
186
|
end
|
|
161
187
|
|
|
162
188
|
it "should provide query methods for attributes" do
|
|
163
189
|
li_piao = HumanBeing.new( :profession => 'Natural Magician', :enhanced_by => nil)
|
|
164
190
|
li_piao.profession?.should be_true
|
|
165
191
|
li_piao.enhanced_by?.should be_false
|
|
192
|
+
li_piao.gender?.should be_false
|
|
166
193
|
end
|
|
167
194
|
|
|
168
195
|
it "should respond to query methods for attributes" do
|
|
@@ -179,14 +206,14 @@ module Wrest::Components
|
|
|
179
206
|
@li_piao.id = 6
|
|
180
207
|
@li_piao.id.should == 6
|
|
181
208
|
end
|
|
182
|
-
|
|
209
|
+
|
|
183
210
|
it "should provide getter and query methods to instance which has corresponding attribute" do
|
|
184
211
|
zotoh_zhaan = HumanBeing.new(:species => "Delvian")
|
|
185
212
|
zotoh_zhaan.species.should == "Delvian"
|
|
186
213
|
zotoh_zhaan.species?.should be_true
|
|
187
214
|
zotoh_zhaan.species = "Human"
|
|
188
215
|
lambda{@li_piao.species}.should raise_error(NoMethodError)
|
|
189
|
-
|
|
216
|
+
@li_piao.species?.should be_false
|
|
190
217
|
@li_piao.should_not respond_to(:species=)
|
|
191
218
|
@li_piao.methods.grep(/:species=/).should be_empty
|
|
192
219
|
end
|
|
@@ -12,7 +12,7 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
|
|
|
12
12
|
module Wrest::Components
|
|
13
13
|
describe Mutators::Base do
|
|
14
14
|
it "should raise an exception if mutate is invoked without do_mutate being implemented in a subclass" do
|
|
15
|
-
lambda{ Class.new(Mutators::Base).new.mutate([]) }.should raise_error(Wrest::Exceptions::
|
|
15
|
+
lambda{ Class.new(Mutators::Base).new.mutate([]) }.should raise_error(Wrest::Exceptions::MethodNotOverridden)
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
it "should ensure that the next mutator is invoked for a subclass" do
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -12,7 +12,7 @@ require File.dirname(__FILE__) + '/../../spec_helper'
|
|
|
12
12
|
module Wrest::Components
|
|
13
13
|
describe Translators do
|
|
14
14
|
it "should know how to raise an exception if the mime type doesn't exist" do
|
|
15
|
-
lambda{ Translators.lookup('weird/unknown')}.should raise_error(Wrest::Exceptions::
|
|
15
|
+
lambda{ Translators.lookup('weird/unknown')}.should raise_error(Wrest::Exceptions::UnsupportedContentType)
|
|
16
16
|
end
|
|
17
17
|
end
|
|
18
18
|
end
|
|
File without changes
|
|
@@ -22,4 +22,18 @@ describe String, 'conversions' do
|
|
|
22
22
|
uri.username.should == 'ooga'
|
|
23
23
|
uri.password.should == 'booga'
|
|
24
24
|
end
|
|
25
|
+
|
|
26
|
+
it "should strip leading spaces from a uri before building it" do
|
|
27
|
+
' http://localhost:3000'.to_uri.should == Wrest::Uri.new('http://localhost:3000')
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "should strip trailing spaces from a uri before building it" do
|
|
31
|
+
'http://localhost:3000 '.to_uri.should == Wrest::Uri.new('http://localhost:3000')
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "should levae the original string unchanged after building a uri from it" do
|
|
35
|
+
url = ' http://localhost:3000 '
|
|
36
|
+
url.to_uri.should == Wrest::Uri.new('http://localhost:3000')
|
|
37
|
+
url.should == ' http://localhost:3000 '
|
|
38
|
+
end
|
|
25
39
|
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Wrest::Http::Redirection do
|
|
4
|
+
|
|
5
|
+
it "should make a request to the url in its location header and return the response" do
|
|
6
|
+
mock_net_http_response = mock(Net::HTTPRedirection)
|
|
7
|
+
redirect_url = 'http://redirect.com'
|
|
8
|
+
redirect_uri = redirect_url.to_uri
|
|
9
|
+
mock_net_http_response.should_receive(:[]).with('location').and_return(redirect_url)
|
|
10
|
+
mock_net_http_response.should_receive(:code).and_return('200')
|
|
11
|
+
|
|
12
|
+
Wrest::Uri.should_receive(:new).with(redirect_url, anything).and_return(redirect_uri)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
after_redirect_request = Wrest::Http::Get.new(redirect_uri)
|
|
16
|
+
final_mock_response = mock(Wrest::Http::Response)
|
|
17
|
+
after_redirect_request.should_receive(:invoke).and_return(final_mock_response)
|
|
18
|
+
|
|
19
|
+
Wrest::Http::Get.should_receive(:new).with(redirect_uri, {}, {}, {:username=>nil, :password=>nil}).and_return(after_redirect_request)
|
|
20
|
+
|
|
21
|
+
response = Wrest::Http::Redirection.new(mock_net_http_response)
|
|
22
|
+
response.follow(:follow_redirects_count => 0, :follow_redirects_limit => 5).should == final_mock_response
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "should raise a Wrest::Exceptions::AutoRedirectLimitExceeded if there are more redirections than the limit" do
|
|
26
|
+
request_url = 'http://redirect.com'
|
|
27
|
+
|
|
28
|
+
response = mock(Net::HTTPRedirection)
|
|
29
|
+
response.stub!(:code).and_return('301')
|
|
30
|
+
response.stub!(:message).and_return('')
|
|
31
|
+
response.stub!(:body).and_return('')
|
|
32
|
+
response.should_receive(:[]).with('location').exactly(5).times.and_return(request_url)
|
|
33
|
+
|
|
34
|
+
http_connection = mock(Net::HTTP)
|
|
35
|
+
http_connection.stub!(:read_timeout=)
|
|
36
|
+
http_connection.should_receive(:request).exactly(5).times.and_return(response)
|
|
37
|
+
|
|
38
|
+
Net::HTTP.should_receive(:new).exactly(5).times.and_return(http_connection)
|
|
39
|
+
|
|
40
|
+
lambda{ request_url.to_uri(:follow_redirects_limit => 5).get }.should raise_error(Wrest::Exceptions::AutoRedirectLimitExceeded)
|
|
41
|
+
end
|
|
42
|
+
end
|