resource 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/.document +5 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +26 -0
  4. data/Guardfile +22 -0
  5. data/LICENSE.txt +20 -0
  6. data/README.rdoc +19 -0
  7. data/Rakefile +49 -0
  8. data/VERSION +1 -0
  9. data/lib/api_resource.rb +51 -0
  10. data/lib/api_resource/associations.rb +472 -0
  11. data/lib/api_resource/attributes.rb +154 -0
  12. data/lib/api_resource/base.rb +517 -0
  13. data/lib/api_resource/callbacks.rb +49 -0
  14. data/lib/api_resource/connection.rb +162 -0
  15. data/lib/api_resource/core_extensions.rb +7 -0
  16. data/lib/api_resource/custom_methods.rb +119 -0
  17. data/lib/api_resource/exceptions.rb +74 -0
  18. data/lib/api_resource/formats.rb +14 -0
  19. data/lib/api_resource/formats/json_format.rb +25 -0
  20. data/lib/api_resource/formats/xml_format.rb +36 -0
  21. data/lib/api_resource/log_subscriber.rb +15 -0
  22. data/lib/api_resource/mocks.rb +249 -0
  23. data/lib/api_resource/model_errors.rb +86 -0
  24. data/lib/api_resource/observing.rb +29 -0
  25. data/resource.gemspec +125 -0
  26. data/spec/lib/associations_spec.rb +412 -0
  27. data/spec/lib/attributes_spec.rb +109 -0
  28. data/spec/lib/base_spec.rb +454 -0
  29. data/spec/lib/callbacks_spec.rb +68 -0
  30. data/spec/lib/model_errors_spec.rb +29 -0
  31. data/spec/spec_helper.rb +32 -0
  32. data/spec/support/mocks/association_mocks.rb +18 -0
  33. data/spec/support/mocks/error_resource_mocks.rb +21 -0
  34. data/spec/support/mocks/test_resource_mocks.rb +23 -0
  35. data/spec/support/requests/association_requests.rb +14 -0
  36. data/spec/support/requests/error_resource_requests.rb +25 -0
  37. data/spec/support/requests/test_resource_requests.rb +31 -0
  38. data/spec/support/test_resource.rb +19 -0
  39. metadata +277 -0
@@ -0,0 +1,68 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ include ApiResource
4
+
5
+ describe "Should put callbacks around save, create, update, and destroy by default" do
6
+
7
+ before(:all) do
8
+ # This defines all the callbacks to check and see if they are fired
9
+ TestResource.class_eval <<-EOE, __FILE__, __LINE__ + 1
10
+ attr_accessor :s_val, :c_val, :u_val, :d_val
11
+ before_save :bs_cb; after_save :as_cb
12
+ before_create :bc_cb; after_create :ac_cb
13
+ before_update :bu_cb; after_update :au_cb
14
+ before_destroy :bd_cb; after_destroy :ad_cb
15
+
16
+ def bs_cb
17
+ @s_val = 1
18
+ end
19
+ def as_cb
20
+ @s_val += 1
21
+ end
22
+ def bc_cb
23
+ @c_val = 1
24
+ end
25
+ def ac_cb
26
+ @c_val += 1
27
+ end
28
+ def bu_cb
29
+ @u_val = 1
30
+ end
31
+ def au_cb
32
+ @u_val += 1
33
+ end
34
+ def bd_cb
35
+ @d_val = 1
36
+ end
37
+ def ad_cb
38
+ @d_val += 1
39
+ end
40
+ EOE
41
+ end
42
+
43
+ it "should fire save and create callbacks when saving a new record" do
44
+ tr = TestResource.new(:name => "Ethan", :age => 20)
45
+ tr.save.should be_true
46
+ tr.s_val.should eql(2)
47
+ tr.c_val.should eql(2)
48
+ tr.u_val.should be_nil
49
+ end
50
+
51
+ it "should fire save and update callbacks when updating a record" do
52
+ tr = TestResource.new(:id => 1, :name => "Ethan", :age => 20)
53
+ tr.name = "Test"
54
+ tr.age = 21
55
+ tr.save.should be_true
56
+ tr.s_val.should eql(2)
57
+ tr.c_val.should be_nil
58
+ tr.u_val.should eql(2)
59
+ end
60
+
61
+ it "should only fire destroy callbacks when destroying a record" do
62
+ tr = TestResource.new(:id => 1, :name => "Ethan", :age => 20)
63
+ tr.destroy.should be_true
64
+ tr.d_val.should eql(2)
65
+ tr.s_val.should be_nil
66
+ end
67
+
68
+ end
@@ -0,0 +1,29 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ include ApiResource
4
+
5
+ describe "Saving Resources with errors" do
6
+
7
+ before(:all) do
8
+ ErrorResource.include_root_in_json = true
9
+ end
10
+
11
+ context "Remote Errors" do
12
+
13
+ it "should be able to handle errors as a hash" do
14
+ t = ErrorResource.new(:name => "Ethan", :age => 12)
15
+ t.save.should be_false
16
+ t.errors.should_not be_nil
17
+ t.errors['name'].should_not be_nil
18
+ end
19
+
20
+ it "should be able to handle errors as full messages" do
21
+ t = ErrorFullMessageResource.new(:name => "Ethan", :age => 12)
22
+ t.save.should be_false
23
+ t.errors.should_not be_nil
24
+ t.errors['name'].should_not be_nil
25
+ end
26
+
27
+ end
28
+
29
+ end
@@ -0,0 +1,32 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+
4
+ require 'bundler'
5
+ require 'api_resource'
6
+ require 'simplecov'
7
+
8
+ # Requires supporting files with custom matchers and macros, etc,
9
+ # in ./support/ and its subdirectories.
10
+ Bundler.require(:default, :development)
11
+ Debugger.start
12
+
13
+ SimpleCov.start
14
+
15
+ SimpleCov.at_exit do
16
+ SimpleCov.result.format!
17
+ end
18
+
19
+ # Requires supporting files with custom matchers and macros, etc,
20
+ # in ./support/ and its subdirectories.
21
+ #ApiResource.load_mocks_and_factories
22
+ ApiResource.site = 'http://localhost:3000'
23
+ ApiResource.format = :json
24
+ ApiResource.load_mocks_and_factories
25
+
26
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
27
+
28
+
29
+
30
+ RSpec.configure do |config|
31
+
32
+ end
@@ -0,0 +1,18 @@
1
+ include ApiResource
2
+
3
+ Mocks.define do
4
+
5
+ endpoint('/single_object_association') do
6
+ get(HashDealer.roll(:test_association_resource), :params => {})
7
+ get(HashDealer.roll(:active_test_association_resource), :params => {:active => true})
8
+ get(HashDealer.roll(:active_birthday_test_association_resource), :params => {:active => true, :birthday => true})
9
+ end
10
+
11
+ endpoint('/multi_object_association') do
12
+ get((0..4).to_a.collect{HashDealer.roll(:test_association_resource)}, :params => {})
13
+ get((0..4).to_a.collect{HashDealer.roll(:active_test_association_resource)}, :params => {:active => true})
14
+ get((0..4).to_a.collect{HashDealer.roll(:active_test_association_resource)}, :params => {:active => false})
15
+ get((0..4).to_a.collect{HashDealer.roll(:active_birthday_test_association_resource)}, :params => {:active => true, :birthday => true})
16
+ end
17
+
18
+ end
@@ -0,0 +1,21 @@
1
+ include ApiResource
2
+
3
+ Mocks.define do
4
+
5
+ endpoint("/error_resources/new") do
6
+ get(HashDealer.roll(:new_error_resource))
7
+ end
8
+
9
+ endpoint("/error_resources") do
10
+ post(HashDealer.roll(:error_resource_errors), :params => {:error_resource => HashDealer.roll(:error_resource).matcher}, :status_code => 422)
11
+ end
12
+
13
+ endpoint("/error_full_message_resources/new") do
14
+ get(HashDealer.roll(:new_error_resource))
15
+ end
16
+
17
+ endpoint("/error_full_message_resources") do
18
+ post(HashDealer.roll(:error_resource_full_message_errors), :params => {:error_full_message_resource => HashDealer.roll(:error_resource).matcher}, :status_code => 422)
19
+ end
20
+
21
+ end
@@ -0,0 +1,23 @@
1
+ include ApiResource
2
+
3
+ Mocks.define do
4
+
5
+ endpoint("/test_resources/new") do
6
+ get(HashDealer.roll(:new_test_object))
7
+ end
8
+
9
+ endpoint("/test_resources") do
10
+ post(HashDealer.roll(:test_resource).merge(:id => 1), :params => {:test_resource => HashDealer.roll(:test_resource).matcher})
11
+ get((0..4).to_a.collect{HashDealer.roll(:test_resource)})
12
+ get((0..4).to_a.collect{HashDealer.roll(:test_resource)}, :params => {:active => true})
13
+ end
14
+
15
+ endpoint("/test_resources/:id") do
16
+ get(HashDealer.roll(:test_resource)) do |params|
17
+ self.merge(params)
18
+ end
19
+ delete({})
20
+ put({}, :params => {:test_resource => HashDealer.roll(:test_resource).matcher})
21
+ end
22
+
23
+ end
@@ -0,0 +1,14 @@
1
+ HashDealer.define(:test_association_resource) do
2
+ id{Kernel.rand(99999)}
3
+ name{Faker::Name.first_name}
4
+ age{Kernel.rand(99999)}
5
+ active(false)
6
+ end
7
+
8
+ HashDealer.define(:active_test_association_resource, :parent => :test_association_resource) do
9
+ active(true)
10
+ end
11
+
12
+ HashDealer.define(:active_birthday_test_association_resource, :parent => :active_test_association_resource) do
13
+ birthday{Date.today}
14
+ end
@@ -0,0 +1,25 @@
1
+ HashDealer.define(:new_error_resource) do
2
+ attributes({
3
+ :protected => [:id],
4
+ :public => [:name, :age],
5
+ })
6
+ end
7
+
8
+ HashDealer.define(:error_resource) do
9
+ name("Name")
10
+ age("age")
11
+ end
12
+
13
+ HashDealer.define(:error_resource_errors) do
14
+ errors({
15
+ :name => ["must not be empty"],
16
+ :age => ["must be a valid integer"]
17
+ })
18
+ end
19
+
20
+ HashDealer.define(:error_resource_full_message_errors) do
21
+ errors([
22
+ "Name cannot be empty",
23
+ "Age must be a valid integer"
24
+ ])
25
+ end
@@ -0,0 +1,31 @@
1
+ HashDealer.define(:new_test_object) do
2
+ attributes({
3
+ :protected => [:id],
4
+ :public => [:name, :age],
5
+ })
6
+ scopes([
7
+ {:active => {:active => true}},
8
+ {:paginate => {:paginate => true, :per_page => :per_page, :current_page => :current_page}}
9
+ ])
10
+ associations({
11
+ :has_many => {:has_many_objects => {}},
12
+ :belongs_to => {:belongs_to_object => {}},
13
+ :has_one => {:has_one_object => {}}
14
+ })
15
+ # Think of a use case for this
16
+ options({
17
+
18
+ })
19
+ end
20
+
21
+ HashDealer.define(:test_resource) do
22
+ name("name")
23
+ age("age")
24
+ end
25
+
26
+ HashDealer.define(:test_resource_errors) do
27
+ errors({
28
+ :name => ["can't be blank"],
29
+ :age => ["must be a valid number"]
30
+ })
31
+ end
@@ -0,0 +1,19 @@
1
+ class TestResource < ApiResource::Base
2
+ end
3
+
4
+ class HasManyObject < ApiResource::Base
5
+ end
6
+
7
+ class BelongsToObject < ApiResource::Base
8
+ end
9
+
10
+ class HasOneObject < ApiResource::Base
11
+ end
12
+
13
+ class ErrorResource < ApiResource::Base
14
+
15
+ end
16
+
17
+ class ErrorFullMessageResource < ApiResource::Base
18
+
19
+ end
metadata ADDED
@@ -0,0 +1,277 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: resource
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Ethan Langevin
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-08-26 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rails
16
+ requirement: &2154504280 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - =
20
+ - !ruby/object:Gem::Version
21
+ version: 3.0.9
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *2154504280
25
+ - !ruby/object:Gem::Dependency
26
+ name: activeresource
27
+ requirement: &2154503660 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - =
31
+ - !ruby/object:Gem::Version
32
+ version: 3.0.9
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *2154503660
36
+ - !ruby/object:Gem::Dependency
37
+ name: hash_dealer
38
+ requirement: &2154502920 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *2154502920
47
+ - !ruby/object:Gem::Dependency
48
+ name: rest-client
49
+ requirement: &2154502080 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: *2154502080
58
+ - !ruby/object:Gem::Dependency
59
+ name: rspec
60
+ requirement: &2154501500 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *2154501500
69
+ - !ruby/object:Gem::Dependency
70
+ name: ruby-debug19
71
+ requirement: &2154500740 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *2154500740
80
+ - !ruby/object:Gem::Dependency
81
+ name: growl
82
+ requirement: &2154500000 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *2154500000
91
+ - !ruby/object:Gem::Dependency
92
+ name: rspec-rails
93
+ requirement: &2154499340 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ type: :development
100
+ prerelease: false
101
+ version_requirements: *2154499340
102
+ - !ruby/object:Gem::Dependency
103
+ name: factory_girl
104
+ requirement: &2154498640 !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: *2154498640
113
+ - !ruby/object:Gem::Dependency
114
+ name: simplecov
115
+ requirement: &2154478560 !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ! '>='
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ type: :development
122
+ prerelease: false
123
+ version_requirements: *2154478560
124
+ - !ruby/object:Gem::Dependency
125
+ name: faker
126
+ requirement: &2154476640 !ruby/object:Gem::Requirement
127
+ none: false
128
+ requirements:
129
+ - - ! '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: *2154476640
135
+ - !ruby/object:Gem::Dependency
136
+ name: guard
137
+ requirement: &2154475840 !ruby/object:Gem::Requirement
138
+ none: false
139
+ requirements:
140
+ - - ! '>='
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ type: :development
144
+ prerelease: false
145
+ version_requirements: *2154475840
146
+ - !ruby/object:Gem::Dependency
147
+ name: guard-rspec
148
+ requirement: &2154475120 !ruby/object:Gem::Requirement
149
+ none: false
150
+ requirements:
151
+ - - ! '>='
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ type: :development
155
+ prerelease: false
156
+ version_requirements: *2154475120
157
+ - !ruby/object:Gem::Dependency
158
+ name: mocha
159
+ requirement: &2154474140 !ruby/object:Gem::Requirement
160
+ none: false
161
+ requirements:
162
+ - - ! '>='
163
+ - !ruby/object:Gem::Version
164
+ version: '0'
165
+ type: :development
166
+ prerelease: false
167
+ version_requirements: *2154474140
168
+ - !ruby/object:Gem::Dependency
169
+ name: bundler
170
+ requirement: &2154473300 !ruby/object:Gem::Requirement
171
+ none: false
172
+ requirements:
173
+ - - ~>
174
+ - !ruby/object:Gem::Version
175
+ version: 1.0.0
176
+ type: :development
177
+ prerelease: false
178
+ version_requirements: *2154473300
179
+ - !ruby/object:Gem::Dependency
180
+ name: jeweler
181
+ requirement: &2154472400 !ruby/object:Gem::Requirement
182
+ none: false
183
+ requirements:
184
+ - - ~>
185
+ - !ruby/object:Gem::Version
186
+ version: 1.6.4
187
+ type: :development
188
+ prerelease: false
189
+ version_requirements: *2154472400
190
+ - !ruby/object:Gem::Dependency
191
+ name: rcov
192
+ requirement: &2154471700 !ruby/object:Gem::Requirement
193
+ none: false
194
+ requirements:
195
+ - - ! '>='
196
+ - !ruby/object:Gem::Version
197
+ version: '0'
198
+ type: :development
199
+ prerelease: false
200
+ version_requirements: *2154471700
201
+ description: A replacement for ActiveResource for RESTful APIs that handles associated
202
+ object and multiple data sources
203
+ email: ejl6266@gmail.com
204
+ executables: []
205
+ extensions: []
206
+ extra_rdoc_files:
207
+ - LICENSE.txt
208
+ - README.rdoc
209
+ files:
210
+ - .document
211
+ - .rspec
212
+ - Gemfile
213
+ - Guardfile
214
+ - LICENSE.txt
215
+ - README.rdoc
216
+ - Rakefile
217
+ - VERSION
218
+ - lib/api_resource.rb
219
+ - lib/api_resource/associations.rb
220
+ - lib/api_resource/attributes.rb
221
+ - lib/api_resource/base.rb
222
+ - lib/api_resource/callbacks.rb
223
+ - lib/api_resource/connection.rb
224
+ - lib/api_resource/core_extensions.rb
225
+ - lib/api_resource/custom_methods.rb
226
+ - lib/api_resource/exceptions.rb
227
+ - lib/api_resource/formats.rb
228
+ - lib/api_resource/formats/json_format.rb
229
+ - lib/api_resource/formats/xml_format.rb
230
+ - lib/api_resource/log_subscriber.rb
231
+ - lib/api_resource/mocks.rb
232
+ - lib/api_resource/model_errors.rb
233
+ - lib/api_resource/observing.rb
234
+ - resource.gemspec
235
+ - spec/lib/associations_spec.rb
236
+ - spec/lib/attributes_spec.rb
237
+ - spec/lib/base_spec.rb
238
+ - spec/lib/callbacks_spec.rb
239
+ - spec/lib/model_errors_spec.rb
240
+ - spec/spec_helper.rb
241
+ - spec/support/mocks/association_mocks.rb
242
+ - spec/support/mocks/error_resource_mocks.rb
243
+ - spec/support/mocks/test_resource_mocks.rb
244
+ - spec/support/requests/association_requests.rb
245
+ - spec/support/requests/error_resource_requests.rb
246
+ - spec/support/requests/test_resource_requests.rb
247
+ - spec/support/test_resource.rb
248
+ homepage: http://github.com/ejlangev/resource
249
+ licenses:
250
+ - MIT
251
+ post_install_message:
252
+ rdoc_options: []
253
+ require_paths:
254
+ - lib
255
+ required_ruby_version: !ruby/object:Gem::Requirement
256
+ none: false
257
+ requirements:
258
+ - - ! '>='
259
+ - !ruby/object:Gem::Version
260
+ version: '0'
261
+ segments:
262
+ - 0
263
+ hash: -2418567610397208476
264
+ required_rubygems_version: !ruby/object:Gem::Requirement
265
+ none: false
266
+ requirements:
267
+ - - ! '>='
268
+ - !ruby/object:Gem::Version
269
+ version: '0'
270
+ requirements: []
271
+ rubyforge_project:
272
+ rubygems_version: 1.8.8
273
+ signing_key:
274
+ specification_version: 3
275
+ summary: A replacement for ActiveResource for RESTful APIs that handles associated
276
+ object and multiple data sources
277
+ test_files: []