remotable 0.2.3 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -1,6 +1,5 @@
1
1
  *.gem
2
2
  .bundle
3
- Gemfile.lock
4
3
  pkg/*
5
4
  coverage
6
5
 
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
- private
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 default_remote_attributes
268
- column_names - %w{id created_at updated_at expires_at}
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
- def assert_that_remote_resource_responds_to_remote_attributes!(model)
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
@@ -1,3 +1,3 @@
1
1
  module Remotable
2
- VERSION = "0.2.3"
2
+ VERSION = "0.2.4"
3
3
  end
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
- # * +new_resource+
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+ (returning a hash of error messages by attribute)
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
@@ -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
@@ -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; set_table_name "tenants"; end
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; set_table_name "tenants"; end
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; set_table_name "tenants"; end
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; set_table_name "tenants"; end
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
- set_table_name "tenants"
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
- set_table_name "tenants"
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
- set_table_name "tenants"
39
+ self.table_name = "tenants"
40
40
 
41
41
  remote_model RemoteTenant
42
42
  attr_remote :group_id, :slug
@@ -48,7 +48,7 @@ class BespokeResource
48
48
  end
49
49
 
50
50
  class BespokeTenant < ActiveRecord::Base
51
- set_table_name "tenants"
51
+ self.table_name = "tenants"
52
52
 
53
53
  remote_model BespokeModel.new
54
54
  attr_remote :slug, :name
@@ -0,0 +1,10 @@
1
+ require "active_record"
2
+
3
+
4
+ class NullTestTenant < ActiveRecord::Base
5
+ self.table_name = "tenants"
6
+
7
+ remote_model Remotable::NullRemote
8
+ attr_remote :slug, :name
9
+ remote_key :slug
10
+ end
data/test/test_helper.rb CHANGED
@@ -5,6 +5,7 @@ require 'rails/test_help'
5
5
  require 'active_support/core_ext'
6
6
  require 'factory_girl'
7
7
  require 'turn'
8
+ require 'pry'
8
9
  require 'database_cleaner'
9
10
 
10
11
 
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.3
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: 2012-10-08 00:00:00.000000000 Z
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: 1.8.23
255
+ rubygems_version: 2.0.0
270
256
  signing_key:
271
- specification_version: 3
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