From cec2ef0e0b1326f45bf068788b72199e2386d83c Mon Sep 17 00:00:00 2001 From: DualFroz Date: Sun, 13 Sep 2026 11:19:59 +0200 Subject: [PATCH] test: cover OrmPolymorphicTouchTest, teardown --- test/test_orm_polymorphic_touch.rb | 110 ++++++++++++++++++++++++++++ test/test_orm_query_aggregations.rb | 90 +++++++++++++++++++++++ 2 files changed, 200 insertions(+) create mode 100644 test/test_orm_polymorphic_touch.rb create mode 100644 test/test_orm_query_aggregations.rb diff --git a/test/test_orm_polymorphic_touch.rb b/test/test_orm_polymorphic_touch.rb new file mode 100644 index 0000000..99bf6ad --- /dev/null +++ b/test/test_orm_polymorphic_touch.rb @@ -0,0 +1,110 @@ +require 'minitest/autorun' +require 'prism' +require 'tmpdir' + +class OrmPolymorphicTouchTest < Minitest::Test + def setup + @dir = Dir.mktmpdir('prism-polymorphic-touch-store') + @store = Prism::Orm::Store.new(File.join(@dir, 'test.pstore')) + @store.create_table(:posts, %w[id title updated_at]) + @store.create_table(:photos, %w[id caption updated_at reviewed_at]) + @store.create_table(:comments, %w[id body commentable_id commentable_type updated_at]) + + post_class = Class.new(Prism::Orm::Model) do + table_name :posts + has_many :comments, class_name: 'Comment', as: :commentable, dependent: :destroy + end + photo_class = Class.new(Prism::Orm::Model) do + table_name :photos + has_many :comments, class_name: 'Comment', as: :commentable, dependent: :destroy + end + comment_class = Class.new(Prism::Orm::Model) do + table_name :comments + belongs_to :commentable, polymorphic: true, touch: true + end + [post_class, photo_class, comment_class].each { |klass| klass.store = @store } + Object.const_set(:Post, post_class) + Object.const_set(:Photo, photo_class) + Object.const_set(:Comment, comment_class) + end + + def teardown + FileUtils.remove_entry(@dir) + %i[Post Photo Comment].each { |name| Object.send(:remove_const, name) if Object.const_defined?(name) } + end + + def test_creating_a_child_touches_the_polymorphic_owner + post = Post.create!(title: 'hello') + original = post.updated_at + sleep 0.01 + + Comment.create!(body: 'first', commentable_id: post.id, commentable_type: 'Post') + + assert post.reload.updated_at > original + end + + def test_touches_the_correct_owner_type_when_two_types_share_ids + post = Post.create!(title: 'hello') + photo = Photo.create!(caption: 'sunset') + original_post = post.reload.updated_at + original_photo = photo.reload.updated_at + sleep 0.01 + + Comment.create!(body: 'on the photo', commentable_id: photo.id, commentable_type: 'Photo') + + assert_equal original_post, post.reload.updated_at + assert photo.reload.updated_at > original_photo + end + + def test_updating_a_child_touches_the_owner_even_without_changing_the_association + post = Post.create!(title: 'hello') + comment = Comment.create!(body: 'first', commentable_id: post.id, commentable_type: 'Post') + original = post.reload.updated_at + sleep 0.01 + + comment.update!(body: 'first, edited') + + assert post.reload.updated_at > original + end + + def test_destroying_a_child_touches_the_owner + post = Post.create!(title: 'hello') + comment = Comment.create!(body: 'first', commentable_id: post.id, commentable_type: 'Post') + original = post.reload.updated_at + sleep 0.01 + + comment.destroy + + assert post.reload.updated_at > original + end + + def test_reassigning_across_owner_types_touches_both_the_old_and_new_owner + post = Post.create!(title: 'hello') + photo = Photo.create!(caption: 'sunset') + comment = Comment.create!(body: 'wandering', commentable_id: post.id, commentable_type: 'Post') + original_post = post.reload.updated_at + original_photo = photo.reload.updated_at + sleep 0.01 + + comment.commentable = photo + comment.save! + + assert post.reload.updated_at > original_post + assert photo.reload.updated_at > original_photo + end + + def test_destroying_the_owner_via_dependent_destroy_cascade_does_not_re_raise + post = Post.create!(title: 'hello') + Comment.create!(body: 'first', commentable_id: post.id, commentable_type: 'Post') + Comment.create!(body: 'second', commentable_id: post.id, commentable_type: 'Post') + + post.destroy + + assert post.destroyed? + assert_nil Post.find_by(id: post.id) + end + + def test_creating_a_child_without_an_owner_does_not_raise + Comment.create!(body: 'orphan', commentable_id: nil, commentable_type: nil) + end +end diff --git a/test/test_orm_query_aggregations.rb b/test/test_orm_query_aggregations.rb new file mode 100644 index 0000000..2859bd0 --- /dev/null +++ b/test/test_orm_query_aggregations.rb @@ -0,0 +1,90 @@ +require 'minitest/autorun' +require 'prism' +require 'tmpdir' + +class OrmQueryAggregationsTest < Minitest::Test + def setup + @dir = Dir.mktmpdir('prism-query-aggregations') + @store = Prism::Orm::Store.new(File.join(@dir, 'test.pstore')) + @store.create_table(:orders, %w[id customer amount]) + order_class = Class.new(Prism::Orm::Model) do + table_name :orders + end + order_class.store = @store + Object.const_set(:Order, order_class) + + Order.create!(customer: 'alice', amount: 10) + Order.create!(customer: 'alice', amount: 30) + Order.create!(customer: 'bob', amount: 5) + Order.create!(customer: 'bob', amount: 15) + Order.create!(customer: 'carol', amount: nil) + end + + def teardown + FileUtils.remove_entry(@dir) + Object.send(:remove_const, :Order) if Object.const_defined?(:Order) + end + + def test_sum + assert_equal 40, Order.where(customer: 'alice').sum(:amount) + end + + def test_sum_ignores_nil_values + assert_equal 60, Order.sum(:amount) + end + + + def test_average + assert_equal 20.0, Order.where(customer: 'alice').average(:amount) + end + + def test_average_on_empty_relation_is_nil + assert_nil Order.where(customer: 'nobody').average(:amount) + end + + def test_minimum_and_maximum + assert_equal 5, Order.minimum(:amount) + assert_equal 30, Order.maximum(:amount) + end + + def test_group_returns_records_bucketed_by_column + grouped = Order.group(:customer) + assert_equal %w[alice bob carol].sort, grouped.keys.sort + assert_equal 2, grouped['alice'].size + assert_kind_of Order, grouped['alice'].first + end + + def test_group_count + counts = Order.all.group_count(:customer) + assert_equal 2, counts['alice'] + assert_equal 2, counts['bob'] + assert_equal 1, counts['carol'] + end + + def test_pick_single_column + assert_equal 10, Order.where(customer: 'alice').order(:amount).pick(:amount) + end + + def test_pick_multiple_columns + row = Order.where(customer: 'bob').order(:amount).pick(:customer, :amount) + assert_equal ['bob', 5], row + end + + def test_ids_plucks_primary_keys + ids = Order.where(customer: 'alice').ids + assert_equal 2, ids.size + assert(ids.all? { |id| id.is_a?(Integer) }) + end + + def test_distinct_dedupes_plucked_column_values + Order.create!(customer: 'alice', amount: 10) + distinct_amounts = Order.where(customer: 'alice').distinct.pluck(:amount) + assert_equal [10, 30], distinct_amounts.sort + end + + def test_without_distinct_pluck_keeps_duplicates + Order.create!(customer: 'alice', amount: 10) + amounts = Order.where(customer: 'alice').pluck(:amount).sort + assert_equal [10, 10, 30], amounts + end +end