remotable 0.2.3 → 0.2.4
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.
- checksums.yaml +7 -0
- data/.gitignore +0 -1
- data/Gemfile.lock +125 -0
- data/lib/remotable/active_record_extender.rb +57 -24
- data/lib/remotable/null_remote.rb +51 -0
- data/lib/remotable/version.rb +1 -1
- data/lib/remotable.rb +4 -2
- data/remotable.gemspec +1 -0
- data/test/active_resource_test.rb +32 -0
- data/test/factories/tenants.rb +8 -0
- data/test/nosync_test.rb +15 -0
- data/test/null_remote_test.rb +73 -0
- data/test/remotable_test.rb +4 -5
- data/test/support/active_resource.rb +3 -3
- data/test/support/bespoke.rb +1 -1
- data/test/support/null.rb +10 -0
- data/test/test_helper.rb +1 -0
- metadata +51 -63
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e84548b3d422a45df52d3a730cbe4d41d78c954e
|
4
|
+
data.tar.gz: 4734d71d361ec0ca5f9634a660f53a1375ad5670
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1d89d1ffb5585fc6f9219460f901c61e9c3512260272daa87fa15d3c68a0c3bf914bbf921a23d6f62def17d04ff0186583bebff9a6d20cda3cc3bc0cc5a1d451
|
7
|
+
data.tar.gz: c4da1216f5058cc9d7b4a1b265601edc41f44769efdf05950fa2c8cc0f40020d2c1895aa7b306e6176095fa7679bff799c3e8b35060033cde1a3460f013d8ae5
|
data/.gitignore
CHANGED
data/Gemfile.lock
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
remotable (0.2.4)
|
5
|
+
activerecord
|
6
|
+
activeresource
|
7
|
+
activesupport
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: http://rubygems.org/
|
11
|
+
specs:
|
12
|
+
actionmailer (3.2.13)
|
13
|
+
actionpack (= 3.2.13)
|
14
|
+
mail (~> 2.5.3)
|
15
|
+
actionpack (3.2.13)
|
16
|
+
activemodel (= 3.2.13)
|
17
|
+
activesupport (= 3.2.13)
|
18
|
+
builder (~> 3.0.0)
|
19
|
+
erubis (~> 2.7.0)
|
20
|
+
journey (~> 1.0.4)
|
21
|
+
rack (~> 1.4.5)
|
22
|
+
rack-cache (~> 1.2)
|
23
|
+
rack-test (~> 0.6.1)
|
24
|
+
sprockets (~> 2.2.1)
|
25
|
+
active_resource_simulator (0.0.1)
|
26
|
+
activeresource
|
27
|
+
activemodel (3.2.13)
|
28
|
+
activesupport (= 3.2.13)
|
29
|
+
builder (~> 3.0.0)
|
30
|
+
activerecord (3.2.13)
|
31
|
+
activemodel (= 3.2.13)
|
32
|
+
activesupport (= 3.2.13)
|
33
|
+
arel (~> 3.0.2)
|
34
|
+
tzinfo (~> 0.3.29)
|
35
|
+
activeresource (3.2.13)
|
36
|
+
activemodel (= 3.2.13)
|
37
|
+
activesupport (= 3.2.13)
|
38
|
+
activesupport (3.2.13)
|
39
|
+
i18n (= 0.6.1)
|
40
|
+
multi_json (~> 1.0)
|
41
|
+
ansi (1.4.3)
|
42
|
+
arel (3.0.2)
|
43
|
+
builder (3.0.4)
|
44
|
+
coderay (1.0.8)
|
45
|
+
database_cleaner (0.6.7)
|
46
|
+
erubis (2.7.0)
|
47
|
+
factory_girl (2.0.4)
|
48
|
+
hike (1.2.1)
|
49
|
+
i18n (0.6.1)
|
50
|
+
journey (1.0.4)
|
51
|
+
json (1.7.7)
|
52
|
+
mail (2.5.3)
|
53
|
+
i18n (>= 0.4.0)
|
54
|
+
mime-types (~> 1.16)
|
55
|
+
treetop (~> 1.4.8)
|
56
|
+
method_source (0.8.1)
|
57
|
+
mime-types (1.21)
|
58
|
+
minitest (2.10.0)
|
59
|
+
multi_json (1.0.3)
|
60
|
+
polyglot (0.3.3)
|
61
|
+
pry (0.9.10)
|
62
|
+
coderay (~> 1.0.5)
|
63
|
+
method_source (~> 0.8)
|
64
|
+
slop (~> 3.3.1)
|
65
|
+
rack (1.4.5)
|
66
|
+
rack-cache (1.2)
|
67
|
+
rack (>= 0.4)
|
68
|
+
rack-ssl (1.3.3)
|
69
|
+
rack
|
70
|
+
rack-test (0.6.2)
|
71
|
+
rack (>= 1.0)
|
72
|
+
rails (3.2.13)
|
73
|
+
actionmailer (= 3.2.13)
|
74
|
+
actionpack (= 3.2.13)
|
75
|
+
activerecord (= 3.2.13)
|
76
|
+
activeresource (= 3.2.13)
|
77
|
+
activesupport (= 3.2.13)
|
78
|
+
bundler (~> 1.0)
|
79
|
+
railties (= 3.2.13)
|
80
|
+
railties (3.2.13)
|
81
|
+
actionpack (= 3.2.13)
|
82
|
+
activesupport (= 3.2.13)
|
83
|
+
rack-ssl (~> 1.3.2)
|
84
|
+
rake (>= 0.8.7)
|
85
|
+
rdoc (~> 3.4)
|
86
|
+
thor (>= 0.14.6, < 2.0)
|
87
|
+
rake (10.0.3)
|
88
|
+
rdoc (3.12.2)
|
89
|
+
json (~> 1.4)
|
90
|
+
rr (1.0.4)
|
91
|
+
simplecov (0.5.3)
|
92
|
+
multi_json (~> 1.0.3)
|
93
|
+
simplecov-html (~> 0.5.3)
|
94
|
+
simplecov-html (0.5.3)
|
95
|
+
slop (3.3.3)
|
96
|
+
sprockets (2.2.2)
|
97
|
+
hike (~> 1.2)
|
98
|
+
multi_json (~> 1.0)
|
99
|
+
rack (~> 1.0)
|
100
|
+
tilt (~> 1.1, != 1.3.0)
|
101
|
+
sqlite3 (1.3.7)
|
102
|
+
thor (0.17.0)
|
103
|
+
tilt (1.3.6)
|
104
|
+
treetop (1.4.12)
|
105
|
+
polyglot
|
106
|
+
polyglot (>= 0.3.1)
|
107
|
+
turn (0.9.6)
|
108
|
+
ansi
|
109
|
+
tzinfo (0.3.37)
|
110
|
+
|
111
|
+
PLATFORMS
|
112
|
+
ruby
|
113
|
+
|
114
|
+
DEPENDENCIES
|
115
|
+
active_resource_simulator
|
116
|
+
database_cleaner
|
117
|
+
factory_girl
|
118
|
+
minitest
|
119
|
+
pry
|
120
|
+
rails
|
121
|
+
remotable!
|
122
|
+
rr
|
123
|
+
simplecov
|
124
|
+
sqlite3
|
125
|
+
turn
|
@@ -81,11 +81,7 @@ module Remotable
|
|
81
81
|
map = attrs.extract_options!
|
82
82
|
map = attrs.map_to_self.merge(map)
|
83
83
|
@remote_attribute_map = map
|
84
|
-
|
85
|
-
assert_that_remote_resource_responds_to_remote_attributes!(remote_model) if Remotable.validate_models?
|
86
|
-
|
87
|
-
# Reset routes
|
88
|
-
@local_attribute_routes = {}
|
84
|
+
@local_attribute_routes = {} # reset routes
|
89
85
|
end
|
90
86
|
|
91
87
|
def fetch_with(local_key, options={})
|
@@ -129,7 +125,6 @@ module Remotable
|
|
129
125
|
end
|
130
126
|
|
131
127
|
def default_route_for(local_key, remote_key=nil)
|
132
|
-
puts "local_key: #{local_key}; remote_key: #{remote_key}"
|
133
128
|
remote_key ||= remote_attribute_name(local_key)
|
134
129
|
if remote_key.to_s == primary_key
|
135
130
|
":#{local_key}"
|
@@ -260,30 +255,62 @@ module Remotable
|
|
260
255
|
|
261
256
|
|
262
257
|
|
263
|
-
|
258
|
+
def all_by_remote
|
259
|
+
find_by_remote_query(:all)
|
260
|
+
end
|
264
261
|
|
262
|
+
def find_by_remote_query(remote_method_name, *args)
|
263
|
+
remote_resources = remote_model.send(remote_method_name, *args)
|
264
|
+
map_remote_resources_to_local(remote_resources)
|
265
|
+
end
|
265
266
|
|
267
|
+
def map_remote_resources_to_local(remote_resources)
|
268
|
+
return [] if remote_resources.empty?
|
269
|
+
|
270
|
+
local_resources = nosync { fetch_corresponding_local_resources(remote_resources).to_a }
|
271
|
+
|
272
|
+
# Ensure a corresponding local resource for
|
273
|
+
# each remote resource; return the set of
|
274
|
+
# local resources.
|
275
|
+
remote_resources.map do |remote_resource|
|
276
|
+
|
277
|
+
# Get the specific local resource that
|
278
|
+
# corresponds to this remote one.
|
279
|
+
local_resource = local_resources.detect { |local_resource|
|
280
|
+
Array.wrap(remote_key).all? { |remote_attr|
|
281
|
+
local_attr = local_attribute_name(remote_attr)
|
282
|
+
local_resource.send(local_attr) == remote_resource.send(remote_attr)
|
283
|
+
}
|
284
|
+
}
|
285
|
+
|
286
|
+
# If a local counterpart to this remote value
|
287
|
+
# exists, update the local resource and return it.
|
288
|
+
# If not, create a local counterpart and return it.
|
289
|
+
if local_resource
|
290
|
+
local_resource.instance_variable_set :@remote_resource, remote_resource
|
291
|
+
local_resource.pull_remote_data!
|
292
|
+
else
|
293
|
+
new_from_remote(remote_resource)
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|
266
297
|
|
267
|
-
def
|
268
|
-
|
298
|
+
def fetch_corresponding_local_resources(remote_resources)
|
299
|
+
conditions = Array.wrap(remote_key).each_with_object({}) do |remote_attr, query|
|
300
|
+
local_attr = local_attribute_name(remote_attr)
|
301
|
+
query[local_attr] = remote_resources.map(&remote_attr)
|
302
|
+
end
|
303
|
+
|
304
|
+
where(conditions)
|
269
305
|
end
|
270
306
|
|
271
307
|
|
272
308
|
|
273
|
-
|
274
|
-
# Skip this for ActiveResource because it won't define a method until it has
|
275
|
-
# loaded an JSON for that method
|
276
|
-
return if model.is_a?(Class) and (model < ActiveResource::Base)
|
277
|
-
|
278
|
-
instance = model.new_resource
|
279
|
-
attr_getters_and_setters = remote_attribute_names + remote_attribute_names.map {|attr| :"#{attr}="}
|
280
|
-
unless instance.respond_to_all?(attr_getters_and_setters)
|
281
|
-
raise InvalidRemoteModel,
|
282
|
-
"#{instance.class} does not respond to getters and setters " <<
|
283
|
-
"for each remote attribute (not implemented: #{instance.does_not_respond_to(attr_getters_and_setters).sort.join(", ")}).\n"
|
284
|
-
end
|
285
|
-
end
|
309
|
+
private
|
286
310
|
|
311
|
+
def default_remote_attributes
|
312
|
+
column_names - %w{id created_at updated_at expires_at}
|
313
|
+
end
|
287
314
|
|
288
315
|
|
289
316
|
def generate_default_remote_key
|
@@ -293,7 +320,6 @@ module Remotable
|
|
293
320
|
end
|
294
321
|
|
295
322
|
|
296
|
-
|
297
323
|
def new_from_remote(remote_resource)
|
298
324
|
record = self.new
|
299
325
|
record.instance_variable_set(:@remote_resource, remote_resource)
|
@@ -313,7 +339,6 @@ module Remotable
|
|
313
339
|
:local_attribute_names,
|
314
340
|
:local_attribute_name,
|
315
341
|
:expires_after,
|
316
|
-
:find_remote_resource_by,
|
317
342
|
:to => "self.class"
|
318
343
|
|
319
344
|
def expired?
|
@@ -360,6 +385,14 @@ module Remotable
|
|
360
385
|
fetch_value && find_remote_resource_by(remote_key, fetch_value)
|
361
386
|
end
|
362
387
|
|
388
|
+
def find_remote_resource_by(remote_key, fetch_value)
|
389
|
+
if remote_model.respond_to?(:find_by_for_local)
|
390
|
+
remote_model.find_by_for_local(self, remote_key, fetch_value)
|
391
|
+
else
|
392
|
+
self.class.find_remote_resource_by(remote_key, fetch_value)
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
363
396
|
def merge_remote_data!(remote_resource)
|
364
397
|
merge_remote_data(remote_resource)
|
365
398
|
reset_expiration_date
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Remotable
|
2
|
+
class NullRemote
|
3
|
+
|
4
|
+
class << self
|
5
|
+
|
6
|
+
# This is always invoked by instance#fetch_remote_resource.
|
7
|
+
# It expects to find a remote counterpart for a local resource.
|
8
|
+
# It should always return a NullRemote object that doesn't
|
9
|
+
# alter the behavior of a normal model at all.
|
10
|
+
def find_by_for_local(local_record, remote_key, fetch_value)
|
11
|
+
new
|
12
|
+
end
|
13
|
+
|
14
|
+
# This is always invoked via class#find_remote_resource_by
|
15
|
+
# by class#fetch_by. It gives the remote model an opportunity
|
16
|
+
# to discover a remote object that doesn't have a local
|
17
|
+
# counterpart. NullRemote should never discover something
|
18
|
+
# that doesn't exist locally.
|
19
|
+
def find_by(remote_attr, value)
|
20
|
+
nil
|
21
|
+
end
|
22
|
+
|
23
|
+
def new_resource
|
24
|
+
new
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
# NullRemote needs to receive setter messages and
|
31
|
+
# swallow them. It doesn't need to respond to getter
|
32
|
+
# messages since it has nothing to say.
|
33
|
+
def method_missing(method_name, *args)
|
34
|
+
super unless method_name.to_s =~ /=$/
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
def save
|
39
|
+
true
|
40
|
+
end
|
41
|
+
|
42
|
+
def errors
|
43
|
+
{}
|
44
|
+
end
|
45
|
+
|
46
|
+
def destroy
|
47
|
+
true
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
data/lib/remotable/version.rb
CHANGED
data/lib/remotable.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "remotable/version"
|
2
2
|
require "remotable/nosync"
|
3
|
+
require "remotable/null_remote"
|
3
4
|
require "remotable/validate_models"
|
4
5
|
require "remotable/with_remote_model_proxy"
|
5
6
|
|
@@ -59,17 +60,18 @@ module Remotable
|
|
59
60
|
# <tt>model</tt> can be any object that responds
|
60
61
|
# to these two methods for getting a resource:
|
61
62
|
#
|
63
|
+
# * +new_resource+
|
62
64
|
# * +find_by(path)+ or +find_by(remote_attr, value)+
|
63
65
|
# +find_by+ can be defined to take either one argument or two.
|
64
66
|
# If it takes one argument, it will be passed path.
|
65
67
|
# If it takes two, it will be passed remote_attr and value.
|
66
|
-
# * +
|
68
|
+
# * (Optional) +find_by_for_local(local_record, remote_key, fetch_value)+
|
67
69
|
#
|
68
70
|
# Resources must respond to:
|
69
71
|
#
|
70
72
|
# * +save+ (return true on success and false on failure)
|
71
73
|
# * +destroy+
|
72
|
-
# * +errors+ (
|
74
|
+
# * +errors+ (returns a hash of error messages by attribute)
|
73
75
|
# * getters and setters for each attribute
|
74
76
|
#
|
75
77
|
def remote_model(*args)
|
data/remotable.gemspec
CHANGED
@@ -20,6 +20,7 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.add_development_dependency "rails"
|
21
21
|
s.add_development_dependency "minitest"
|
22
22
|
s.add_development_dependency "turn"
|
23
|
+
s.add_development_dependency "pry"
|
23
24
|
s.add_development_dependency "factory_girl"
|
24
25
|
s.add_development_dependency "sqlite3"
|
25
26
|
s.add_development_dependency "active_resource_simulator"
|
@@ -333,4 +333,36 @@ class ActiveResourceTest < ActiveSupport::TestCase
|
|
333
333
|
|
334
334
|
|
335
335
|
|
336
|
+
# ========================================================================= #
|
337
|
+
# Listing #
|
338
|
+
# ========================================================================= #
|
339
|
+
|
340
|
+
test "should be able to find all remote resources and sync them with local resources" do
|
341
|
+
tenant = Factory(:tenant, :expires_at => 1.year.ago)
|
342
|
+
|
343
|
+
assert_equal 1, Tenant.count, "There's supposed to be 1 tenant"
|
344
|
+
|
345
|
+
# Creates 1 missing resources, updates 1
|
346
|
+
assert_difference "Tenant.count", +1 do
|
347
|
+
RemoteTenant.run_simulation do |s|
|
348
|
+
s.show(nil, [
|
349
|
+
{ :id => tenant.id,
|
350
|
+
:slug => "a-different-slug",
|
351
|
+
:church_name => "A Different Name" },
|
352
|
+
{ :id => tenant.id + 1,
|
353
|
+
:slug => "generic-slug",
|
354
|
+
:church_name => "Generic Name" }],
|
355
|
+
:path => "/api/accounts.json")
|
356
|
+
|
357
|
+
tenants = Tenant.all_by_remote
|
358
|
+
assert_equal 2, tenants.length
|
359
|
+
|
360
|
+
assert_equal "a-different-slug", tenant.reload.slug
|
361
|
+
end
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
|
366
|
+
|
367
|
+
|
336
368
|
end
|
data/test/factories/tenants.rb
CHANGED
@@ -13,3 +13,11 @@ Factory.define :bespoke_tenant do |f|
|
|
13
13
|
f.expires_at 100.years.from_now
|
14
14
|
f.nosync true
|
15
15
|
end
|
16
|
+
|
17
|
+
Factory.define :null_test_tenant do |f|
|
18
|
+
f.sequence(:slug) { |n| "test#{n}" }
|
19
|
+
f.name "Test"
|
20
|
+
f.sequence(:remote_id)
|
21
|
+
f.expires_at 100.years.from_now
|
22
|
+
f.nosync true
|
23
|
+
end
|
data/test/nosync_test.rb
CHANGED
@@ -27,4 +27,19 @@ class NoSyncTest < ActiveSupport::TestCase
|
|
27
27
|
|
28
28
|
|
29
29
|
|
30
|
+
# ========================================================================= #
|
31
|
+
# Finding #
|
32
|
+
# ========================================================================= #
|
33
|
+
|
34
|
+
test "should do nothing if a tenant is expired" do
|
35
|
+
tenant = Factory(:tenant, :expires_at => 1.year.ago)
|
36
|
+
|
37
|
+
Remotable.nosync do
|
38
|
+
result = Tenant.find_by_remote_id(tenant.remote_id)
|
39
|
+
assert_equal tenant, result
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
|
30
45
|
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
require "remotable"
|
3
|
+
require "support/null"
|
4
|
+
|
5
|
+
|
6
|
+
class NullRemoteTest < ActiveSupport::TestCase
|
7
|
+
include RR::Adapters::TestUnit
|
8
|
+
|
9
|
+
|
10
|
+
|
11
|
+
# ========================================================================= #
|
12
|
+
# Finding #
|
13
|
+
# ========================================================================= #
|
14
|
+
|
15
|
+
test "should do nothing if a tenant is expired" do
|
16
|
+
tenant = Factory(:null_test_tenant, expires_at: 2.days.ago)
|
17
|
+
result = NullTestTenant.find_by_slug(tenant.slug)
|
18
|
+
assert_equal tenant, result
|
19
|
+
end
|
20
|
+
|
21
|
+
test "should raise an exception with the bang method if resource isn't found locally" do
|
22
|
+
new_tenant_slug = "not_found3"
|
23
|
+
assert_equal 0, NullTestTenant.where(:slug => new_tenant_slug).count,
|
24
|
+
"There's not supposed to be a NullTestTenant with the slug #{new_tenant_slug}."
|
25
|
+
|
26
|
+
assert_raises ActiveRecord::RecordNotFound do
|
27
|
+
NullTestTenant.find_by_slug!(new_tenant_slug)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
|
33
|
+
# ========================================================================= #
|
34
|
+
# Updating #
|
35
|
+
# ========================================================================= #
|
36
|
+
|
37
|
+
test "should update a record locally without any interference" do
|
38
|
+
tenant = Factory(:null_test_tenant)
|
39
|
+
new_name = "Totally Wonky"
|
40
|
+
|
41
|
+
tenant.name = new_name
|
42
|
+
tenant.save!
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
|
47
|
+
# ========================================================================= #
|
48
|
+
# Creating #
|
49
|
+
# ========================================================================= #
|
50
|
+
|
51
|
+
test "should create a record locally without any interference" do
|
52
|
+
tenant = NullTestTenant.create!({
|
53
|
+
:slug => "brand_new",
|
54
|
+
:name => "Brand New"
|
55
|
+
})
|
56
|
+
assert_not_nil tenant.remote_resource
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
|
61
|
+
# ========================================================================= #
|
62
|
+
# Destroying #
|
63
|
+
# ========================================================================= #
|
64
|
+
|
65
|
+
test "should destroy a record locally without any interference" do
|
66
|
+
tenant = Factory(:null_test_tenant)
|
67
|
+
tenant.nosync = false
|
68
|
+
tenant.destroy
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
|
73
|
+
end
|
data/test/remotable_test.rb
CHANGED
@@ -79,7 +79,6 @@ class RemotableTest < ActiveSupport::TestCase
|
|
79
79
|
|
80
80
|
# Fetching this tenant, Remotable will want to
|
81
81
|
# refresh it, but it shouldn't because it can't.
|
82
|
-
puts "->"
|
83
82
|
assert_not_nil Tenant.where(:slug => "test-1").first, "A tenant with the slug \"test-1\" was not found"
|
84
83
|
end
|
85
84
|
|
@@ -127,27 +126,27 @@ class RemotableTest < ActiveSupport::TestCase
|
|
127
126
|
# ========================================================================= #
|
128
127
|
|
129
128
|
test "should raise an exception if a remote model does not respond to all class methods" do
|
130
|
-
class Example1 < ActiveRecord::Base;
|
129
|
+
class Example1 < ActiveRecord::Base; self.table_name = "tenants"; end
|
131
130
|
class RemoteModel1; def self.find_by(*args); end; end
|
132
131
|
assert_raise(Remotable::InvalidRemoteModel) { Example1.remote_model RemoteModel1 }
|
133
132
|
end
|
134
133
|
|
135
134
|
test "should raise an exception if a remote resource does not respond to all instance methods" do
|
136
|
-
class Example2 < ActiveRecord::Base;
|
135
|
+
class Example2 < ActiveRecord::Base; self.table_name = "tenants"; end
|
137
136
|
class RemoteModel2; def self.new_resource; Object.new; end; end
|
138
137
|
assert_raise(Remotable::InvalidRemoteModel) { Example2.remote_model RemoteModel2 }
|
139
138
|
end
|
140
139
|
|
141
140
|
test "should not raise an exception if remote models are not being validated" do
|
142
141
|
Remotable.without_validation do
|
143
|
-
class Example4 < ActiveRecord::Base;
|
142
|
+
class Example4 < ActiveRecord::Base; self.table_name = "tenants"; end
|
144
143
|
class RemoteModel4; def self.find_by(*args); end; end
|
145
144
|
assert_nothing_raised { Example4.remote_model RemoteModel4 }
|
146
145
|
end
|
147
146
|
end
|
148
147
|
|
149
148
|
test "should not raise an exception if a remote model responds to all required methods" do
|
150
|
-
class Example3 < ActiveRecord::Base;
|
149
|
+
class Example3 < ActiveRecord::Base; self.table_name = "tenants"; end
|
151
150
|
assert_nothing_raised { Example3.remote_model BespokeModel.new }
|
152
151
|
end
|
153
152
|
|
@@ -21,14 +21,14 @@ class Tenant < ActiveRecord::Base
|
|
21
21
|
end
|
22
22
|
|
23
23
|
class RemoteWithoutKey < ActiveRecord::Base
|
24
|
-
|
24
|
+
self.table_name = "tenants"
|
25
25
|
|
26
26
|
remote_model RemoteTenant
|
27
27
|
attr_remote :id => :remote_id
|
28
28
|
end
|
29
29
|
|
30
30
|
class RemoteWithKey < ActiveRecord::Base
|
31
|
-
|
31
|
+
self.table_name = "tenants"
|
32
32
|
|
33
33
|
remote_model RemoteTenant
|
34
34
|
attr_remote :slug
|
@@ -36,7 +36,7 @@ class RemoteWithKey < ActiveRecord::Base
|
|
36
36
|
end
|
37
37
|
|
38
38
|
class RemoteWithCompositeKey < ActiveRecord::Base
|
39
|
-
|
39
|
+
self.table_name = "tenants"
|
40
40
|
|
41
41
|
remote_model RemoteTenant
|
42
42
|
attr_remote :group_id, :slug
|
data/test/support/bespoke.rb
CHANGED
data/test/test_helper.rb
CHANGED
metadata
CHANGED
@@ -1,206 +1,195 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: remotable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
5
|
-
prerelease:
|
4
|
+
version: 0.2.4
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Robert Lail
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2013-03-18 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: activeresource
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - '>='
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - '>='
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '0'
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: activerecord
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - '>='
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: '0'
|
38
34
|
type: :runtime
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - '>='
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: '0'
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: activesupport
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- -
|
45
|
+
- - '>='
|
52
46
|
- !ruby/object:Gem::Version
|
53
47
|
version: '0'
|
54
48
|
type: :runtime
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- -
|
52
|
+
- - '>='
|
60
53
|
- !ruby/object:Gem::Version
|
61
54
|
version: '0'
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
56
|
name: rails
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
|
-
- -
|
59
|
+
- - '>='
|
68
60
|
- !ruby/object:Gem::Version
|
69
61
|
version: '0'
|
70
62
|
type: :development
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
|
-
- -
|
66
|
+
- - '>='
|
76
67
|
- !ruby/object:Gem::Version
|
77
68
|
version: '0'
|
78
69
|
- !ruby/object:Gem::Dependency
|
79
70
|
name: minitest
|
80
71
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
72
|
requirements:
|
83
|
-
- -
|
73
|
+
- - '>='
|
84
74
|
- !ruby/object:Gem::Version
|
85
75
|
version: '0'
|
86
76
|
type: :development
|
87
77
|
prerelease: false
|
88
78
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
79
|
requirements:
|
91
|
-
- -
|
80
|
+
- - '>='
|
92
81
|
- !ruby/object:Gem::Version
|
93
82
|
version: '0'
|
94
83
|
- !ruby/object:Gem::Dependency
|
95
84
|
name: turn
|
96
85
|
requirement: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
86
|
requirements:
|
99
|
-
- -
|
87
|
+
- - '>='
|
100
88
|
- !ruby/object:Gem::Version
|
101
89
|
version: '0'
|
102
90
|
type: :development
|
103
91
|
prerelease: false
|
104
92
|
version_requirements: !ruby/object:Gem::Requirement
|
105
|
-
none: false
|
106
93
|
requirements:
|
107
|
-
- -
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: pry
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '>='
|
108
109
|
- !ruby/object:Gem::Version
|
109
110
|
version: '0'
|
110
111
|
- !ruby/object:Gem::Dependency
|
111
112
|
name: factory_girl
|
112
113
|
requirement: !ruby/object:Gem::Requirement
|
113
|
-
none: false
|
114
114
|
requirements:
|
115
|
-
- -
|
115
|
+
- - '>='
|
116
116
|
- !ruby/object:Gem::Version
|
117
117
|
version: '0'
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
none: false
|
122
121
|
requirements:
|
123
|
-
- -
|
122
|
+
- - '>='
|
124
123
|
- !ruby/object:Gem::Version
|
125
124
|
version: '0'
|
126
125
|
- !ruby/object:Gem::Dependency
|
127
126
|
name: sqlite3
|
128
127
|
requirement: !ruby/object:Gem::Requirement
|
129
|
-
none: false
|
130
128
|
requirements:
|
131
|
-
- -
|
129
|
+
- - '>='
|
132
130
|
- !ruby/object:Gem::Version
|
133
131
|
version: '0'
|
134
132
|
type: :development
|
135
133
|
prerelease: false
|
136
134
|
version_requirements: !ruby/object:Gem::Requirement
|
137
|
-
none: false
|
138
135
|
requirements:
|
139
|
-
- -
|
136
|
+
- - '>='
|
140
137
|
- !ruby/object:Gem::Version
|
141
138
|
version: '0'
|
142
139
|
- !ruby/object:Gem::Dependency
|
143
140
|
name: active_resource_simulator
|
144
141
|
requirement: !ruby/object:Gem::Requirement
|
145
|
-
none: false
|
146
142
|
requirements:
|
147
|
-
- -
|
143
|
+
- - '>='
|
148
144
|
- !ruby/object:Gem::Version
|
149
145
|
version: '0'
|
150
146
|
type: :development
|
151
147
|
prerelease: false
|
152
148
|
version_requirements: !ruby/object:Gem::Requirement
|
153
|
-
none: false
|
154
149
|
requirements:
|
155
|
-
- -
|
150
|
+
- - '>='
|
156
151
|
- !ruby/object:Gem::Version
|
157
152
|
version: '0'
|
158
153
|
- !ruby/object:Gem::Dependency
|
159
154
|
name: simplecov
|
160
155
|
requirement: !ruby/object:Gem::Requirement
|
161
|
-
none: false
|
162
156
|
requirements:
|
163
|
-
- -
|
157
|
+
- - '>='
|
164
158
|
- !ruby/object:Gem::Version
|
165
159
|
version: '0'
|
166
160
|
type: :development
|
167
161
|
prerelease: false
|
168
162
|
version_requirements: !ruby/object:Gem::Requirement
|
169
|
-
none: false
|
170
163
|
requirements:
|
171
|
-
- -
|
164
|
+
- - '>='
|
172
165
|
- !ruby/object:Gem::Version
|
173
166
|
version: '0'
|
174
167
|
- !ruby/object:Gem::Dependency
|
175
168
|
name: rr
|
176
169
|
requirement: !ruby/object:Gem::Requirement
|
177
|
-
none: false
|
178
170
|
requirements:
|
179
|
-
- -
|
171
|
+
- - '>='
|
180
172
|
- !ruby/object:Gem::Version
|
181
173
|
version: '0'
|
182
174
|
type: :development
|
183
175
|
prerelease: false
|
184
176
|
version_requirements: !ruby/object:Gem::Requirement
|
185
|
-
none: false
|
186
177
|
requirements:
|
187
|
-
- -
|
178
|
+
- - '>='
|
188
179
|
- !ruby/object:Gem::Version
|
189
180
|
version: '0'
|
190
181
|
- !ruby/object:Gem::Dependency
|
191
182
|
name: database_cleaner
|
192
183
|
requirement: !ruby/object:Gem::Requirement
|
193
|
-
none: false
|
194
184
|
requirements:
|
195
|
-
- -
|
185
|
+
- - '>='
|
196
186
|
- !ruby/object:Gem::Version
|
197
187
|
version: '0'
|
198
188
|
type: :development
|
199
189
|
prerelease: false
|
200
190
|
version_requirements: !ruby/object:Gem::Requirement
|
201
|
-
none: false
|
202
191
|
requirements:
|
203
|
-
- -
|
192
|
+
- - '>='
|
204
193
|
- !ruby/object:Gem::Version
|
205
194
|
version: '0'
|
206
195
|
description: Remotable keeps a locally-stored ActiveRecord synchronized with a remote
|
@@ -214,6 +203,7 @@ files:
|
|
214
203
|
- .gitignore
|
215
204
|
- .simplecov
|
216
205
|
- Gemfile
|
206
|
+
- Gemfile.lock
|
217
207
|
- MIT-LICENSE
|
218
208
|
- README.mdown
|
219
209
|
- Rakefile
|
@@ -226,6 +216,7 @@ files:
|
|
226
216
|
- lib/remotable/core_ext/object.rb
|
227
217
|
- lib/remotable/core_ext/uri.rb
|
228
218
|
- lib/remotable/nosync.rb
|
219
|
+
- lib/remotable/null_remote.rb
|
229
220
|
- lib/remotable/validate_models.rb
|
230
221
|
- lib/remotable/version.rb
|
231
222
|
- lib/remotable/with_remote_model_proxy.rb
|
@@ -234,50 +225,47 @@ files:
|
|
234
225
|
- test/bespoke_test.rb
|
235
226
|
- test/factories/tenants.rb
|
236
227
|
- test/nosync_test.rb
|
228
|
+
- test/null_remote_test.rb
|
237
229
|
- test/remotable_test.rb
|
238
230
|
- test/support/active_resource.rb
|
239
231
|
- test/support/bespoke.rb
|
232
|
+
- test/support/null.rb
|
240
233
|
- test/support/schema.rb
|
241
234
|
- test/test_helper.rb
|
242
235
|
- test/understanding_test.rb
|
243
236
|
homepage: ''
|
244
237
|
licenses: []
|
238
|
+
metadata: {}
|
245
239
|
post_install_message:
|
246
240
|
rdoc_options: []
|
247
241
|
require_paths:
|
248
242
|
- lib
|
249
243
|
required_ruby_version: !ruby/object:Gem::Requirement
|
250
|
-
none: false
|
251
244
|
requirements:
|
252
|
-
- -
|
245
|
+
- - '>='
|
253
246
|
- !ruby/object:Gem::Version
|
254
247
|
version: '0'
|
255
|
-
segments:
|
256
|
-
- 0
|
257
|
-
hash: 3994390182043534799
|
258
248
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
259
|
-
none: false
|
260
249
|
requirements:
|
261
|
-
- -
|
250
|
+
- - '>='
|
262
251
|
- !ruby/object:Gem::Version
|
263
252
|
version: '0'
|
264
|
-
segments:
|
265
|
-
- 0
|
266
|
-
hash: 3994390182043534799
|
267
253
|
requirements: []
|
268
254
|
rubyforge_project: remotable
|
269
|
-
rubygems_version:
|
255
|
+
rubygems_version: 2.0.0
|
270
256
|
signing_key:
|
271
|
-
specification_version:
|
257
|
+
specification_version: 4
|
272
258
|
summary: Binds an ActiveRecord model to a remote resource and keeps the two synchronized
|
273
259
|
test_files:
|
274
260
|
- test/active_resource_test.rb
|
275
261
|
- test/bespoke_test.rb
|
276
262
|
- test/factories/tenants.rb
|
277
263
|
- test/nosync_test.rb
|
264
|
+
- test/null_remote_test.rb
|
278
265
|
- test/remotable_test.rb
|
279
266
|
- test/support/active_resource.rb
|
280
267
|
- test/support/bespoke.rb
|
268
|
+
- test/support/null.rb
|
281
269
|
- test/support/schema.rb
|
282
270
|
- test/test_helper.rb
|
283
271
|
- test/understanding_test.rb
|