resource 0.1.0

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.
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: []