hopsoft / tag_columns

Fast & simple Rails ActiveRecord model tagging using PostgreSQL's Array datatype
MIT License
52 stars 3 forks source link

Tests #7

Open fractaledmind opened 1 year ago

fractaledmind commented 1 year ago

As a follow up to #6:

I also wrote a small collection of MiniTest tests to help me ensure my queries were doing what I wanted. Again, I'm not certain how you would prefer to add tests that actually query a database, so I thought I'd just start by sharing my code in case it proves helpful to you.

In either issue, I'm happy to turn these into proper PRs myself if you want to offer some guidance on how you want things done. Or, you can simply copy and paste this code and mutate it however you see fit. Either way, I've enjoyed this afternoon.

ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Base.logger = Logger.new(STDOUT)

ActiveRecord::Schema.define do
  create_table :posts, force: true do |t|
    t.json :tags, null: false, default: []
    t.check_constraint "JSON_TYPE(tags) = 'array'", name: 'post_tags_is_array'
  end
end

class Post < ActiveRecord::Base
  include TagColumns

  tag_columns :tags
end

# -----------------------------------------------------------------------------

POST_1 = Post.create!(tags: %w[a b c d])
POST_2 = Post.create!(tags: %w[c d e f])
POST_3 = Post.create!

class TagColumnsTest < Minitest::Test
  def test_unique_tags
    assert_equal %w[a b c d e f], Post.unique_tags
  end

  def test_tags_cloud
    assert_equal({ 'a' => 1, 'b' => 1, 'c' => 2, 'd' => 2, 'e' => 1, 'f' => 1 }, Post.tags_cloud)
  end

  def test_with_tags
    collection = Post.with_tags
    assert collection.include?(POST_1)
    assert collection.include?(POST_2)
    assert !collection.include?(POST_3)
  end

  def test_without_tags
    collection = Post.without_tags
    assert !collection.include?(POST_1)
    assert !collection.include?(POST_2)
    assert collection.include?(POST_3)
  end

  def test_with_any_tags_receiving_unique_argument
    collection = Post.with_any_tags 'a'
    assert collection.include?(POST_1)
    assert !collection.include?(POST_2)
    assert !collection.include?(POST_3)
  end

  def test_with_any_tags_receiving_shared_argument
    collection = Post.with_any_tags 'c'
    assert collection.include?(POST_1)
    assert collection.include?(POST_2)
    assert !collection.include?(POST_3)
  end

  def test_with_any_tags_receiving_nonexistent_argument
    collection = Post.with_any_tags 'z'
    assert !collection.include?(POST_1)
    assert !collection.include?(POST_2)
    assert !collection.include?(POST_3)
  end

  def test_with_any_tags_receiving_unique_arguments
    collection = Post.with_any_tags 'a', 'b'
    assert collection.include?(POST_1)
    assert !collection.include?(POST_2)
    assert !collection.include?(POST_3)
  end

  def test_with_any_tags_receiving_shared_arguments
    collection = Post.with_any_tags 'c', 'd'
    assert collection.include?(POST_1)
    assert collection.include?(POST_2)
    assert !collection.include?(POST_3)
  end

  def test_with_any_tags_receiving_nonexistent_arguments
    collection = Post.with_any_tags 'y', 'z'
    assert !collection.include?(POST_1)
    assert !collection.include?(POST_2)
    assert !collection.include?(POST_3)
  end

  def test_with_any_tags_receiving_split_arguments
    collection = Post.with_any_tags 'a', 'f'
    assert collection.include?(POST_1)
    assert collection.include?(POST_2)
    assert !collection.include?(POST_3)
  end

  def test_with_all_tags_receiving_unique_argument
    collection = Post.with_all_tags 'a'
    assert collection.include?(POST_1)
    assert !collection.include?(POST_2)
    assert !collection.include?(POST_3)
  end

  def test_with_all_tags_receiving_shared_argument
    collection = Post.with_all_tags 'c'
    assert collection.include?(POST_1)
    assert collection.include?(POST_2)
    assert !collection.include?(POST_3)
  end

  def test_with_all_tags_receiving_nonexistent_argument
    collection = Post.with_all_tags 'z'
    assert !collection.include?(POST_1)
    assert !collection.include?(POST_2)
    assert !collection.include?(POST_3)
  end

  def test_with_all_tags_receiving_unique_arguments
    collection = Post.with_all_tags 'a', 'b'
    assert collection.include?(POST_1)
    assert !collection.include?(POST_2)
    assert !collection.include?(POST_3)
  end

  def test_with_all_tags_receiving_shared_arguments
    collection = Post.with_all_tags 'c', 'd'
    assert collection.include?(POST_1)
    assert collection.include?(POST_2)
    assert !collection.include?(POST_3)
  end

  def test_with_all_tags_receiving_nonexistent_arguments
    collection = Post.with_all_tags 'y', 'z'
    assert !collection.include?(POST_1)
    assert !collection.include?(POST_2)
    assert !collection.include?(POST_3)
  end

  def test_with_all_tags_receiving_split_arguments
    collection = Post.with_all_tags 'a', 'f'
    assert !collection.include?(POST_1)
    assert !collection.include?(POST_2)
    assert !collection.include?(POST_3)
  end

  def test_without_any_tags_receiving_unique_argument
    collection = Post.without_any_tags 'a'
    assert !collection.include?(POST_1)
    assert collection.include?(POST_2)
    assert collection.include?(POST_3)
  end

  def test_without_any_tags_receiving_shared_argument
    collection = Post.without_any_tags 'c'
    assert !collection.include?(POST_1)
    assert !collection.include?(POST_2)
    assert collection.include?(POST_3)
  end

  def test_without_any_tags_receiving_nonexistent_argument
    collection = Post.without_any_tags 'z'
    assert collection.include?(POST_1)
    assert collection.include?(POST_2)
    assert collection.include?(POST_3)
  end

  def test_without_any_tags_receiving_unique_arguments
    collection = Post.without_any_tags 'a', 'b'
    assert !collection.include?(POST_1)
    assert collection.include?(POST_2)
    assert collection.include?(POST_3)
  end

  def test_without_any_tags_receiving_shared_arguments
    collection = Post.without_any_tags 'c', 'd'
    assert !collection.include?(POST_1)
    assert !collection.include?(POST_2)
    assert collection.include?(POST_3)
  end

  def test_without_any_tags_receiving_nonexistent_arguments
    collection = Post.without_any_tags 'y', 'z'
    assert collection.include?(POST_1)
    assert collection.include?(POST_2)
    assert collection.include?(POST_3)
  end

  def test_without_any_tags_receiving_split_arguments
    collection = Post.without_any_tags 'a', 'f'
    assert !collection.include?(POST_1)
    assert !collection.include?(POST_2)
    assert collection.include?(POST_3)
  end

  def test_without_all_tags_receiving_unique_argument
    collection = Post.without_all_tags 'a'
    assert !collection.include?(POST_1)
    assert collection.include?(POST_2)
    assert collection.include?(POST_3)
  end

  def test_without_all_tags_receiving_shared_argument
    collection = Post.without_all_tags 'c'
    assert !collection.include?(POST_1)
    assert !collection.include?(POST_2)
    assert collection.include?(POST_3)
  end

  def test_without_all_tags_receiving_nonexistent_argument
    collection = Post.without_all_tags 'z'
    assert collection.include?(POST_1)
    assert collection.include?(POST_2)
    assert collection.include?(POST_3)
  end

  def test_without_all_tags_receiving_unique_arguments
    collection = Post.without_all_tags 'a', 'b'
    assert !collection.include?(POST_1)
    assert collection.include?(POST_2)
    assert collection.include?(POST_3)
  end

  def test_without_all_tags_receiving_shared_arguments
    collection = Post.without_all_tags 'c', 'd'
    assert !collection.include?(POST_1)
    assert !collection.include?(POST_2)
    assert collection.include?(POST_3)
  end

  def test_without_all_tags_receiving_nonexistent_arguments
    collection = Post.without_all_tags 'y', 'z'
    assert collection.include?(POST_1)
    assert collection.include?(POST_2)
    assert collection.include?(POST_3)
  end

  def test_without_all_tags_receiving_split_arguments
    collection = Post.without_all_tags 'a', 'f'
    assert collection.include?(POST_1)
    assert collection.include?(POST_2)
    assert collection.include?(POST_3)
  end

  def test_has_any_tags_receiving_unique_argument
    assert POST_1.has_any_tags?('a')
    assert !POST_2.has_any_tags?('a')
    assert !POST_3.has_any_tags?('a')
  end

  def test_has_any_tags_receiving_shared_argument
    assert POST_1.has_any_tags?('c')
    assert POST_2.has_any_tags?('c')
    assert !POST_3.has_any_tags?('c')
  end

  def test_has_any_tags_receiving_nonexistent_argument
    assert !POST_1.has_any_tags?('z')
    assert !POST_2.has_any_tags?('z')
    assert !POST_3.has_any_tags?('z')
  end

  def test_has_any_tags_receiving_unique_arguments
    assert POST_1.has_any_tags?('a', 'b')
    assert !POST_2.has_any_tags?('a', 'b')
    assert !POST_3.has_any_tags?('a', 'b')
  end

  def test_has_any_tags_receiving_shared_arguments
    assert POST_1.has_any_tags?('c', 'd')
    assert POST_2.has_any_tags?('c', 'd')
    assert !POST_3.has_any_tags?('c', 'd')
  end

  def test_has_any_tags_receiving_nonexistent_arguments
    assert !POST_1.has_any_tags?('y', 'z')
    assert !POST_2.has_any_tags?('y', 'z')
    assert !POST_3.has_any_tags?('y', 'z')
  end

  def test_has_any_tags_receiving_split_arguments
    assert POST_1.has_any_tags?('a', 'f')
    assert POST_2.has_any_tags?('a', 'f')
    assert !POST_3.has_any_tags?('a', 'f')
  end

  def test_has_all_tags_receiving_unique_argument
    assert POST_1.has_all_tags?('a')
    assert !POST_2.has_all_tags?('a')
    assert !POST_3.has_all_tags?('a')
  end

  def test_has_all_tags_receiving_shared_argument
    assert POST_1.has_all_tags?('c')
    assert POST_2.has_all_tags?('c')
    assert !POST_3.has_all_tags?('c')
  end

  def test_has_all_tags_receiving_nonexistent_argument
    assert !POST_1.has_all_tags?('z')
    assert !POST_2.has_all_tags?('z')
    assert !POST_3.has_all_tags?('z')
  end

  def test_has_all_tags_receiving_unique_arguments
    assert POST_1.has_all_tags?('a', 'b')
    assert !POST_2.has_all_tags?('a', 'b')
    assert !POST_3.has_all_tags?('a', 'b')
  end

  def test_has_all_tags_receiving_shared_arguments
    assert POST_1.has_all_tags?('c', 'd')
    assert POST_2.has_all_tags?('c', 'd')
    assert !POST_3.has_all_tags?('c', 'd')
  end

  def test_has_all_tags_receiving_nonexistent_arguments
    assert !POST_1.has_all_tags?('y', 'z')
    assert !POST_2.has_all_tags?('y', 'z')
    assert !POST_3.has_all_tags?('y', 'z')
  end

  def test_has_all_tags_receiving_split_arguments
    assert !POST_1.has_all_tags?('a', 'f')
    assert !POST_2.has_all_tags?('a', 'f')
    assert !POST_3.has_all_tags?('a', 'f')
  end
end
hopsoft commented 1 year ago

I have some ideas around getting tests stood up, but it would require me to turn this gem into a full blown Rails engine. Starting think on this again though. Thanks for the push.

fractaledmind commented 1 year ago

We could also just add an executable test script, like the bug report templates from the Rails guides. Then, just have CI execute those scripts.