remotable 0.6.3 → 0.9.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.
- checksums.yaml +4 -4
- data/.github/workflows/tests.yml +39 -0
- data/Appraisals +5 -15
- data/CHANGELOG.md +8 -0
- data/gemfiles/{rails_5.0.gemfile → rails_6.1.gemfile} +2 -2
- data/gemfiles/rails_edge.gemfile +0 -1
- data/lib/remotable/active_record_extender.rb +11 -7
- data/lib/remotable/nosync.rb +7 -1
- data/lib/remotable/version.rb +1 -1
- data/remotable.gemspec +2 -2
- data/test/bespoke_test.rb +1 -1
- data/test/nosync_test.rb +11 -3
- data/test/remotable_test.rb +24 -4
- metadata +8 -10
- data/.travis.yml +0 -31
- data/gemfiles/rails_5.1.gemfile +0 -8
- data/gemfiles/rails_5.2.gemfile +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 63584474c5b00a857f670dee818ce28a13afc86ab2cb5aaf6a57bac41bc307d9
|
4
|
+
data.tar.gz: f8737d89d220a3055f48e46b664da8faba882fee0e24532cc2895bf44f3ab32f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ff131813baeba52877f45c3ce493ec219d0e31583eb0571622f96e6a4c29f350cf4a582c8b6cb06848e9e463e49731fdb27cacbdd6df1dd2a1d49396be1e8e1b
|
7
|
+
data.tar.gz: 38f6a48221d360eb17026c128ce70f1e6db301c73540055b9a50c28b4049bd5c3e6ca6c8e9efed9c87103e055243a75e8d80d041607e31706d61125632191c2d
|
@@ -0,0 +1,39 @@
|
|
1
|
+
name: Tests
|
2
|
+
on: [push]
|
3
|
+
jobs:
|
4
|
+
rails:
|
5
|
+
name: Rails Tests
|
6
|
+
runs-on: ubuntu-latest
|
7
|
+
strategy:
|
8
|
+
matrix:
|
9
|
+
ruby: [2.6, 2.7, "3.0"]
|
10
|
+
gemfile: ["gemfiles/rails_6.0.gemfile", "gemfiles/rails_6.1.gemfile"]
|
11
|
+
fail-fast: false
|
12
|
+
env:
|
13
|
+
GEM_HOME: $HOME/.gem
|
14
|
+
steps:
|
15
|
+
- name: Checkout
|
16
|
+
uses: actions/checkout@v2
|
17
|
+
|
18
|
+
- name: Setup Ruby
|
19
|
+
uses: ruby/setup-ruby@v1
|
20
|
+
with:
|
21
|
+
ruby-version: ${{ matrix.ruby }}
|
22
|
+
bundler: 2.2.14
|
23
|
+
bundler-cache: true
|
24
|
+
|
25
|
+
- name: Clean appraisals
|
26
|
+
run: bundle exec appraisal clean
|
27
|
+
|
28
|
+
# We'll let appraisal generate our gemfiles
|
29
|
+
- name: Generate gemfiles
|
30
|
+
run: bundle exec appraisal generate
|
31
|
+
|
32
|
+
# We'll only install the gems for our non-rails-edge tests, those can be run locally
|
33
|
+
# This will overwrite the Gemfile.lock in the root app directory, with the gem versions we need for the test
|
34
|
+
- name: Install gemfile dependencies
|
35
|
+
run: BUNDLE_GEMFILE=${{ matrix.gemfile }} bundle install
|
36
|
+
|
37
|
+
- name: Run the tests
|
38
|
+
id: tests
|
39
|
+
run: bundle exec rake test
|
data/Appraisals
CHANGED
@@ -1,23 +1,13 @@
|
|
1
|
-
appraise "rails-5.0" do
|
2
|
-
gem "activerecord", "~> 5.0.0"
|
3
|
-
gem "sqlite3", "~> 1.3.6"
|
4
|
-
end
|
5
|
-
|
6
|
-
appraise "rails-5.1" do
|
7
|
-
gem "activerecord", "~> 5.1.0"
|
8
|
-
gem "sqlite3", "~> 1.3.6"
|
9
|
-
end
|
10
|
-
|
11
|
-
appraise "rails-5.2" do
|
12
|
-
gem "activerecord", "~> 5.2.0"
|
13
|
-
gem "sqlite3", "~> 1.3.6"
|
14
|
-
end
|
15
|
-
|
16
1
|
appraise "rails-6.0" do
|
17
2
|
gem "activerecord", "~> 6.0.0"
|
18
3
|
gem "sqlite3", "~> 1.4.0"
|
19
4
|
end
|
20
5
|
|
6
|
+
appraise "rails-6.1" do
|
7
|
+
gem "activerecord", "~> 6.1"
|
8
|
+
gem "sqlite3", "~> 1.4.0"
|
9
|
+
end
|
10
|
+
|
21
11
|
appraise "rails-edge" do
|
22
12
|
gem "rails", git: "https://github.com/rails/rails.git", branch: "master", require: "activerecord"
|
23
13
|
gem "sqlite3", "~> 1.4.0"
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
### 0.7.0
|
4
|
+
* **Bugfix** Ensured ActiveRecord models were using Nosync's `ClassMethods` instead of the non-threadsafe `InstanceMethods`
|
5
|
+
|
6
|
+
### 0.6.4
|
7
|
+
* **Feature** Added `Remotable.unsafe_nosync!` method to set `nosync` globally using a class variable. As the method name indicates, this is not threadsafe and should only be used for testing or other situations where thread safety is not an issue.
|
8
|
+
* **Bugfix** Stopped deferring to `Thread.main` if `nosync` was unset on the current thread; while convenient for tests (see above), it ended up allowing requests to leak state if they were handled on the main thread.
|
9
|
+
|
10
|
+
|
3
11
|
### 0.6.3
|
4
12
|
* **Fix** Replaced deprecated calls to URI.escape
|
5
13
|
|
data/gemfiles/rails_edge.gemfile
CHANGED
@@ -17,6 +17,16 @@ module Remotable
|
|
17
17
|
|
18
18
|
|
19
19
|
included do
|
20
|
+
extend Nosync
|
21
|
+
|
22
|
+
# Has to be re-defined _after_ Nosync is extended, which cannot
|
23
|
+
# be done as part of the ClassMethods module
|
24
|
+
def self.nosync?
|
25
|
+
return true if remote_model.nil?
|
26
|
+
return super if nosync_value?
|
27
|
+
Remotable.nosync?
|
28
|
+
end
|
29
|
+
|
20
30
|
before_update :update_remote_resource, :unless => :nosync?
|
21
31
|
before_create :create_remote_resource, :unless => :nosync?
|
22
32
|
before_destroy :destroy_remote_resource, :unless => :nosync?
|
@@ -41,16 +51,10 @@ module Remotable
|
|
41
51
|
|
42
52
|
|
43
53
|
module ClassMethods
|
44
|
-
include Nosync
|
45
54
|
|
46
55
|
attr_accessor :_remote_attribute_map, :_local_attribute_routes, :_expires_after,
|
47
56
|
:_remote_timeout, :remotable_skip_validation_on_sync
|
48
57
|
|
49
|
-
def nosync?
|
50
|
-
return true if remote_model.nil?
|
51
|
-
return super if nosync_value?
|
52
|
-
Remotable.nosync?
|
53
|
-
end
|
54
58
|
|
55
59
|
# Sets the key with which a resource is identified remotely.
|
56
60
|
# If no remote key is set, the remote key is assumed to be :id.
|
@@ -606,7 +610,7 @@ module Remotable
|
|
606
610
|
|
607
611
|
def merge_remote_errors(errors)
|
608
612
|
Remotable.logger.debug "[remotable:#{self.class.name.underscore}:merge_remote_errors](#{fetch_value.inspect}) #{errors.inspect}"
|
609
|
-
errors.each do |attribute, messages|
|
613
|
+
errors.to_h.each do |attribute, messages|
|
610
614
|
Array.wrap(messages).each do |message|
|
611
615
|
self.errors.add(local_attribute_name(attribute), message)
|
612
616
|
end
|
data/lib/remotable/nosync.rb
CHANGED
@@ -50,8 +50,14 @@ module Remotable
|
|
50
50
|
module ClassMethods
|
51
51
|
include InstanceMethods
|
52
52
|
|
53
|
+
def unsafe_nosync!
|
54
|
+
nosync!
|
55
|
+
@_unsafe_nosync = true
|
56
|
+
end
|
57
|
+
|
53
58
|
def reset_nosync!
|
54
59
|
self.nosync = nil
|
60
|
+
remove_instance_variable :@_unsafe_nosync if instance_variable_defined? :@_unsafe_nosync
|
55
61
|
end
|
56
62
|
|
57
63
|
def nosync=(val)
|
@@ -62,7 +68,7 @@ module Remotable
|
|
62
68
|
|
63
69
|
def _nosync
|
64
70
|
return Thread.current.thread_variable_get "remotable.nosync.#{self.object_id}" if nosync_defined_on?(Thread.current)
|
65
|
-
|
71
|
+
@_unsafe_nosync if instance_variable_defined?(:@_unsafe_nosync)
|
66
72
|
end
|
67
73
|
|
68
74
|
def _nosync=(value)
|
data/lib/remotable/version.rb
CHANGED
data/remotable.gemspec
CHANGED
@@ -11,13 +11,13 @@ Gem::Specification.new do |s|
|
|
11
11
|
s.summary = %q{Binds an ActiveRecord model to a remote resource and keeps the two synchronized}
|
12
12
|
s.description = %q{Remotable keeps a locally-stored ActiveRecord synchronized with a remote resource.}
|
13
13
|
|
14
|
-
s.add_dependency "activeresource", ">=
|
14
|
+
s.add_dependency "activeresource", ">= 5.1.1"
|
15
15
|
s.add_dependency "activerecord"
|
16
16
|
s.add_dependency "activesupport"
|
17
17
|
|
18
18
|
s.add_development_dependency "appraisal"
|
19
19
|
s.add_development_dependency "rake"
|
20
|
-
s.add_development_dependency "minitest", "~> 5.
|
20
|
+
s.add_development_dependency "minitest", "~> 5.14.4"
|
21
21
|
s.add_development_dependency "minitest-reporters"
|
22
22
|
s.add_development_dependency "minitest-reporters-turn_reporter"
|
23
23
|
s.add_development_dependency "pry"
|
data/test/bespoke_test.rb
CHANGED
data/test/nosync_test.rb
CHANGED
@@ -48,11 +48,9 @@ class NoSyncTest < ActiveSupport::TestCase
|
|
48
48
|
assert_equal true, Tenant.nosync?
|
49
49
|
end
|
50
50
|
|
51
|
-
test "nosync? should defer to the main thread's value if set there but not on the current thread" do
|
51
|
+
test "nosync? should not defer to the main thread's value if set there but not on the current thread" do
|
52
52
|
Remotable.nosync!
|
53
53
|
subthread = Thread.new do
|
54
|
-
assert Remotable.nosync?
|
55
|
-
Remotable.reset_nosync!
|
56
54
|
refute Remotable.nosync?
|
57
55
|
Thread.stop
|
58
56
|
end
|
@@ -60,6 +58,16 @@ class NoSyncTest < ActiveSupport::TestCase
|
|
60
58
|
assert Remotable.nosync?
|
61
59
|
end
|
62
60
|
|
61
|
+
test "unsafe_nosync! should coerce nosync? to true across threads" do
|
62
|
+
Remotable.unsafe_nosync!
|
63
|
+
subthread = Thread.new do
|
64
|
+
assert Remotable.nosync?
|
65
|
+
Thread.stop
|
66
|
+
end
|
67
|
+
sleep 0.1 while subthread.status != "sleep"
|
68
|
+
assert Remotable.nosync?
|
69
|
+
end
|
70
|
+
|
63
71
|
|
64
72
|
|
65
73
|
# ========================================================================= #
|
data/test/remotable_test.rb
CHANGED
@@ -52,7 +52,7 @@ class RemotableTest < ActiveSupport::TestCase
|
|
52
52
|
test "should support setting remote_model to nil" do
|
53
53
|
Tenant.with_remote_model(nil) do
|
54
54
|
Tenant.remote_model
|
55
|
-
|
55
|
+
assert_nil Tenant.remote_model, "remote_model didn't get set to nil"
|
56
56
|
Tenant.create!(:name => "Test 1", :slug => "test-1")
|
57
57
|
assert_not_nil Tenant.find_by_name("Test 1"), "new tenant was not found"
|
58
58
|
end
|
@@ -68,6 +68,13 @@ class RemotableTest < ActiveSupport::TestCase
|
|
68
68
|
|
69
69
|
concurrently do
|
70
70
|
assert_nil BespokeTenant.find_by_slug(first_slug), "Expected not to find the first model initially"
|
71
|
+
# If the second thread attempts the above lookup after the first thread
|
72
|
+
# has already run the lookup below, the lookup above will find the
|
73
|
+
# _local_ record in the database, which is not what this test is trying
|
74
|
+
# to test -- whether we successfully switch models temporarily in a
|
75
|
+
# mult-threaded situation. The extra sleep call ensures that the first
|
76
|
+
# call completes on both before moving on to the rest of the lookups.
|
77
|
+
sleep rand
|
71
78
|
assert_not_nil BespokeTenant.with_remote_model(BespokeModel2.new) {
|
72
79
|
BespokeTenant.find_by_slug(first_slug)
|
73
80
|
sleep rand
|
@@ -94,7 +101,7 @@ class RemotableTest < ActiveSupport::TestCase
|
|
94
101
|
:slug => "test-1",
|
95
102
|
:remote_id => nil,
|
96
103
|
:expires_at => 1.day.ago ) }
|
97
|
-
|
104
|
+
assert_nil tenant.remote_id
|
98
105
|
|
99
106
|
# Fetching this tenant, Remotable will want to
|
100
107
|
# refresh it, but it shouldn't because it can't.
|
@@ -106,11 +113,11 @@ class RemotableTest < ActiveSupport::TestCase
|
|
106
113
|
:name => "Test 1",
|
107
114
|
:slug => "test-1",
|
108
115
|
:remote_id => nil ) }
|
109
|
-
|
116
|
+
assert_nil tenant.remote_id
|
110
117
|
|
111
118
|
# Updating this tenatn, Remotable will want to
|
112
119
|
# sync it, but it shouldn't because it can't.
|
113
|
-
assert_equal true, tenant.
|
120
|
+
assert_equal true, tenant.update(name: "Test 2"), "The tenant was not updated (errors: #{tenant.errors.full_messages.join(", ")})"
|
114
121
|
end
|
115
122
|
|
116
123
|
|
@@ -170,4 +177,17 @@ class RemotableTest < ActiveSupport::TestCase
|
|
170
177
|
end
|
171
178
|
|
172
179
|
|
180
|
+
|
181
|
+
# ========================================================================= #
|
182
|
+
# ActiveRecordExtender #
|
183
|
+
# ========================================================================= #
|
184
|
+
|
185
|
+
test "should extend an ActiveRecord subclass with Nosync class methods" do
|
186
|
+
class Example5 < ActiveRecord::Base; self.table_name = "tenants"; end
|
187
|
+
Example5.remote_model BespokeModel.new
|
188
|
+
# Method is _only_ on the class version
|
189
|
+
assert Example5.respond_to?(:unsafe_nosync!)
|
190
|
+
end
|
191
|
+
|
192
|
+
|
173
193
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: remotable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Lail
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-11-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activeresource
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 5.1.1
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 5.1.1
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: activerecord
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,14 +86,14 @@ dependencies:
|
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: 5.
|
89
|
+
version: 5.14.4
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: 5.
|
96
|
+
version: 5.14.4
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: minitest-reporters
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -228,19 +228,17 @@ executables: []
|
|
228
228
|
extensions: []
|
229
229
|
extra_rdoc_files: []
|
230
230
|
files:
|
231
|
+
- ".github/workflows/tests.yml"
|
231
232
|
- ".gitignore"
|
232
233
|
- ".simplecov"
|
233
|
-
- ".travis.yml"
|
234
234
|
- Appraisals
|
235
235
|
- CHANGELOG.md
|
236
236
|
- Gemfile
|
237
237
|
- MIT-LICENSE
|
238
238
|
- README.mdown
|
239
239
|
- Rakefile
|
240
|
-
- gemfiles/rails_5.0.gemfile
|
241
|
-
- gemfiles/rails_5.1.gemfile
|
242
|
-
- gemfiles/rails_5.2.gemfile
|
243
240
|
- gemfiles/rails_6.0.gemfile
|
241
|
+
- gemfiles/rails_6.1.gemfile
|
244
242
|
- gemfiles/rails_edge.gemfile
|
245
243
|
- lib/remotable.rb
|
246
244
|
- lib/remotable/active_record_extender.rb
|
data/.travis.yml
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
language: ruby
|
2
|
-
rvm:
|
3
|
-
- 2.3
|
4
|
-
- 2.5
|
5
|
-
- 2.6
|
6
|
-
|
7
|
-
gemfile:
|
8
|
-
- gemfiles/rails_5.0.gemfile
|
9
|
-
- gemfiles/rails_5.1.gemfile
|
10
|
-
- gemfiles/rails_5.2.gemfile
|
11
|
-
- gemfiles/rails_6.0.gemfile
|
12
|
-
- gemfiles/rails_edge.gemfile
|
13
|
-
|
14
|
-
jobs:
|
15
|
-
exclude:
|
16
|
-
- rvm: 2.3
|
17
|
-
gemfile: gemfiles/rails_6.0.gemfile
|
18
|
-
- rvm: 2.3
|
19
|
-
gemfile: gemfiles/rails_edge.gemfile
|
20
|
-
- rvm: 2.4
|
21
|
-
gemfile: gemfiles/rails_6.0.gemfile
|
22
|
-
- rvm: 2.4
|
23
|
-
gemfile: gemfiles/rails_edge.gemfile
|
24
|
-
allow_failures:
|
25
|
-
- gemfile: gemfiles/rails_edge.gemfile
|
26
|
-
|
27
|
-
script: bundle exec rake test
|
28
|
-
|
29
|
-
# To stop Travis from running tests for a new commit,
|
30
|
-
# add the following to your commit message: [ci skip]
|
31
|
-
# You should add this when you edit documentation or comments, etc.
|
data/gemfiles/rails_5.1.gemfile
DELETED