Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 22 additions & 20 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,43 @@ PATH
remote: .
specs:
activerecord-delay_touching (1.1.2)
activerecord (>= 4.2, < 7.2)
activerecord (>= 4.2, < 7.3)

GEM
remote: https://rubygems.org/
specs:
activemodel (7.1.3)
activesupport (= 7.1.3)
activerecord (7.1.3)
activemodel (= 7.1.3)
activesupport (= 7.1.3)
activemodel (7.2.2.1)
activesupport (= 7.2.2.1)
activerecord (7.2.2.1)
activemodel (= 7.2.2.1)
activesupport (= 7.2.2.1)
timeout (>= 0.4.0)
activesupport (7.1.3)
activesupport (7.2.2.1)
base64
benchmark (>= 0.3)
bigdecimal
concurrent-ruby (~> 1.0, >= 1.0.2)
concurrent-ruby (~> 1.0, >= 1.3.1)
connection_pool (>= 2.2.5)
drb
i18n (>= 1.6, < 2)
logger (>= 1.4.2)
minitest (>= 5.1)
mutex_m
tzinfo (~> 2.0)
securerandom (>= 0.3)
tzinfo (~> 2.0, >= 2.0.5)
base64 (0.2.0)
bigdecimal (3.1.5)
benchmark (0.4.0)
bigdecimal (3.1.9)
builder (3.2.4)
concurrent-ruby (1.2.2)
connection_pool (2.4.1)
concurrent-ruby (1.3.5)
connection_pool (2.5.3)
diff-lcs (1.5.0)
docile (1.4.0)
drb (2.2.0)
ruby2_keywords
i18n (1.12.0)
drb (2.2.1)
i18n (1.14.7)
concurrent-ruby (~> 1.0)
logger (1.7.0)
mini_portile2 (2.8.1)
minitest (5.18.0)
mutex_m (0.2.0)
minitest (5.25.5)
rack (2.2.6.3)
rake (13.0.6)
rspec (3.12.0)
Expand All @@ -55,7 +57,7 @@ GEM
rack (>= 1.0.0)
rspec (>= 1.3.0)
rspec-support (3.12.0)
ruby2_keywords (0.0.5)
securerandom (0.4.1)
simplecov (0.22.0)
docile (~> 1.1)
simplecov-html (~> 0.11)
Expand All @@ -67,7 +69,7 @@ GEM
sqlite3 (1.6.1)
mini_portile2 (~> 2.8.0)
timecop (0.9.6)
timeout (0.4.1)
timeout (0.4.3)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
yarjuf (2.0.0)
Expand Down
2 changes: 1 addition & 1 deletion activerecord-delay_touching.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ Gem::Specification.new do |spec|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = ["lib"]

spec.add_dependency "activerecord", ">= 4.2", "< 7.2"
spec.add_dependency "activerecord", ">= 4.2", "< 7.3"
end
42 changes: 30 additions & 12 deletions spec/activerecord/delay_touching_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@
let(:pet1) { Pet.create(name: "Bones") }
let(:pet2) { Pet.create(name: "Ema") }


# Rails 7.2 deprecated ActiveRecord::Base.connection in favor of .lease_connection and .with_connection. By default,
# rspec should already have established an active connection around each test which gets reused by each downstream
# call to .lease_connection & .with_connection within ActiveRecord. However, Base.lease_connection doesn't make it
# clear that the same connection is reused, so we codify this expectation a little more explicitly by using this
# `let!`, which is eagerly evaluated for each test and gives us a value to use for assertions.
let!(:connection) do
expect(ActiveRecord::Base.connection_pool.active_connection?).to be_truthy, "rspec isn't connected to the db"
ActiveRecord::Base.connection_pool.active_connection
end

it 'has a version number' do
expect(Activerecord::DelayTouching::VERSION).not_to be nil
end
Expand Down Expand Up @@ -126,24 +137,31 @@
end

it 'will not connect to the database if there are no touches' do
expect(ActiveRecord::Base).not_to receive(:connection)
ActiveRecord::Base.delay_touching do
# no touches, so no reason to fetch a connection
expect(ActiveRecord::Base).not_to receive(:lease_connection)
expect(ActiveRecord::Base).not_to receive(:with_connection)
expect_updates [] do
ActiveRecord::Base.delay_touching do
# no touches, so no reason to fetch a connection
end
end
end

it 'will not connect to the database if none of the touches are persisted' do
expect(ActiveRecord::Base).not_to receive(:connection)
ActiveRecord::Base.delay_touching do
Pet.new.touch # not persisted, so won't cause updates
expect(ActiveRecord::Base).not_to receive(:lease_connection)
expect(ActiveRecord::Base).not_to receive(:with_connection)
expect_updates [] do
ActiveRecord::Base.delay_touching do
Pet.new.touch # not persisted, so won't cause updates
end
end
end

it 'still connects to the database for other queries, even if there are no touches' do
expect(ActiveRecord::Base.connection).not_to receive(:update) # no touches
expect(ActiveRecord::Base).to receive(:connection).at_least(:once).and_call_original
ActiveRecord::Base.delay_touching do
expect(Pet.count).to be >= 0 # query should still work
expect(ActiveRecord::Base).to receive(:with_connection).at_least(:once).and_call_original
expect_updates [] do
ActiveRecord::Base.delay_touching do
expect(Pet.count).to be >= 0 # query should still work
end
end
end

Expand Down Expand Up @@ -199,7 +217,7 @@

it 'does not infinitely loop' do
updates = 0
allow(ActiveRecord::Base.connection).to receive(:update).and_wrap_original do |m, *args|
allow(connection).to receive(:update).and_wrap_original do |m, *args|
updates = updates + 1
raise StandardError, 'Too many updates - likely infinite loop detected' if updates > 1

Expand Down Expand Up @@ -229,7 +247,7 @@ def expect_updates(tables)
Regexp.new(%Q{UPDATE "#{entry}" SET "updated_at" = })
end
end.flatten
expect(ActiveRecord::Base.connection).to receive(:update).exactly(expected_sql.length).times do |stmt, _, _|
expect(connection).to receive(:update).exactly(expected_sql.length).times do |stmt, _, _|
index = expected_sql.index { |sql| stmt.to_sql =~ sql}
expect(index).to be, "An unexpected touch occurred: #{stmt.to_sql}"
expected_sql.delete_at(index)
Expand Down