Skip to content

Commit

Permalink
chore: move test to minitest (#434)
Browse files Browse the repository at this point in the history
feat: bump with_advisory_lock to 5.0.0
  • Loading branch information
seuros authored Jan 19, 2024
1 parent 7ba50f7 commit 7aed799
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 39 deletions.
2 changes: 1 addition & 1 deletion closure_tree.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Gem::Specification.new do |gem|
gem.required_ruby_version = '>= 3.0.0'

gem.add_runtime_dependency 'activerecord', '>= 6.1.0'
gem.add_runtime_dependency 'with_advisory_lock', '>= 4.0.0'
gem.add_runtime_dependency 'with_advisory_lock', '>= 5.0.0'

gem.add_development_dependency 'appraisal'
gem.add_development_dependency 'database_cleaner'
Expand Down
38 changes: 0 additions & 38 deletions spec/closure_tree/cache_invalidation_spec.rb

This file was deleted.

36 changes: 36 additions & 0 deletions test/closure_tree/cache_invalidation_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
require 'test_helper'

class CacheInvalidationTest < ActiveSupport::TestCase
def setup
Timecop.travel(10.seconds.ago) do
#create a long tree with 2 branch
@root = MenuItem.create(
name: SecureRandom.hex(10)
)
2.times do
parent = @root
10.times do
parent = parent.children.create(
name: SecureRandom.hex(10)
)
end
end
@first_leaf = MenuItem.leaves.first
@second_leaf = MenuItem.leaves.last
end
end

test "touch option should invalidate cache for all it ancestors" do
old_time_stamp = @first_leaf.ancestors.pluck(:updated_at)
@first_leaf.touch
new_time_stamp = @first_leaf.ancestors.pluck(:updated_at)
assert_not_equal old_time_stamp, new_time_stamp, 'Cache not invalidated for all ancestors'
end

test "touch option should not invalidate cache for another branch" do
old_time_stamp = @second_leaf.updated_at
@first_leaf.touch
new_time_stamp = @second_leaf.updated_at
assert_equal old_time_stamp, new_time_stamp, 'Cache incorrectly invalidated for another branch'
end
end
80 changes: 80 additions & 0 deletions test/closure_tree/has_closure_tree_root_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
require "test_helper"

class HasClosureTreeRootTest < ActiveSupport::TestCase
setup do
ENV['FLOCK_DIR'] = Dir.mktmpdir
end

teardown do
FileUtils.remove_entry_secure ENV['FLOCK_DIR']
end
def create_tree(group)
@ct1 = ContractType.create!(name: "Type1")
@ct2 = ContractType.create!(name: "Type2")
@user1 = User.create!(email: "1@example.com", group_id: group.id)
@user2 = User.create!(email: "2@example.com", group_id: group.id)
@user3 = User.create!(email: "3@example.com", group_id: group.id)
@user4 = User.create!(email: "4@example.com", group_id: group.id)
@user5 = User.create!(email: "5@example.com", group_id: group.id)
@user6 = User.create!(email: "6@example.com", group_id: group.id)

# The tree (contract types in parens)
#
# U1(1)
# / \
# U2(1) U3(1&2)
# / / \
# U4(2) U5(1) U6(2)

@user1.children << @user2
@user1.children << @user3
@user2.children << @user4
@user3.children << @user5
@user3.children << @user6

@user1.contracts.create!(title: "Contract 1", contract_type: @ct1)
@user2.contracts.create!(title: "Contract 2", contract_type: @ct1)
@user3.contracts.create!(title: "Contract 3", contract_type: @ct1)
@user3.contracts.create!(title: "Contract 4", contract_type: @ct2)
@user4.contracts.create!(title: "Contract 5", contract_type: @ct2)
@user5.contracts.create!(title: "Contract 6", contract_type: @ct1)
@user6.contracts.create!(title: "Contract 7", contract_type: @ct2)
end

test "loads all nodes in a constant number of queries" do
group = Group.create!(name: "TheGrouping")
create_tree(group)
reloaded_group = group.reload
exceed_query_limit(2) do
root = reloaded_group.root_user_including_tree
assert_equal "2@example.com", root.children[0].email
assert_equal "3@example.com", root.children[0].parent.children[1].email
end
end

test "loads all nodes plus single association in a constant number of queries" do
group = Group.create!(name: "TheGrouping")
create_tree(group)
reloaded_group = group.reload
exceed_query_limit(3) do
root = reloaded_group.root_user_including_tree(:contracts)
assert_equal "2@example.com", root.children[0].email
assert_equal "3@example.com", root.children[0].parent.children[1].email
assert_equal "Contract 7", root.children[0].children[0].contracts[0].user.parent.parent.children[1].children[1].contracts[0].title
end
end

test "loads all nodes and associations in a constant number of queries" do
group = Group.create!(name: "TheGrouping")
create_tree(group)
reloaded_group = group.reload
exceed_query_limit(4) do
root = reloaded_group.root_user_including_tree(contracts: :contract_type)
assert_equal "2@example.com", root.children[0].email
assert_equal "3@example.com", root.children[0].parent.children[1].email
assert_equal %w[Type1 Type2], root.children[1].contracts.map(&:contract_type).map(&:name)
assert_equal "Type1", root.children[1].children[0].contracts[0].contract_type.name
assert_equal "Type2", root.children[0].children[0].contracts[0].user.parent.parent.children[1].children[1].contracts[0].contract_type.name
end
end
end
29 changes: 29 additions & 0 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
require 'database_cleaner'
require 'support/query_counter'
require 'parallel'
require 'timecop'

ActiveRecord::Base.configurations = {
default_env: {
Expand Down Expand Up @@ -61,9 +62,37 @@ class Spec
end
end

class ActiveSupport::TestCase
def exceed_query_limit(num, &block)
counter = QueryCounter.new
ActiveSupport::Notifications.subscribed(counter.to_proc, 'sql.active_record', &block)
assert counter.query_count <= num, "Expected to run maximum #{num} queries, but ran #{counter.query_count}"
end

class QueryCounter
attr_reader :query_count

def initialize
@query_count = 0
end

def to_proc
lambda(&method(:callback))
end

def callback(name, start, finish, message_id, values)
@query_count += 1 unless %w(CACHE SCHEMA).include?(values[:name])
end
end
end

# Configure parallel tests
Thread.abort_on_exception = true

# Configure advisory_lock
# See: https://github.com/ClosureTree/with_advisory_lock
ENV['WITH_ADVISORY_LOCK_PREFIX'] ||= SecureRandom.hex

require 'closure_tree'
require_relative '../spec/support/schema'
require_relative '../spec/support/models'

0 comments on commit 7aed799

Please sign in to comment.