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 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