test: add orm association and validation tests
This commit is contained in:
1 parent
42f3294342
commit
7cf239f4e3
2 files changed
+163
No files matched your search
@@ -0,0 +1,94 @@
|
|||||||
|
require 'minitest/autorun'
|
||||||
|
require 'prism'
|
||||||
|
require 'tmpdir'
|
||||||
|
|
||||||
|
class OrmAssociationsTest < Minitest::Test
|
||||||
|
def setup
|
||||||
|
@dir = Dir.mktmpdir('prism-assoc-store')
|
||||||
|
@store = Prism::Orm::Store.new(File.join(@dir, 'test.pstore'))
|
||||||
|
@store.create_table(:authors, %w[id name])
|
||||||
|
@store.create_table(:posts, %w[id title author_id])
|
||||||
|
|
||||||
|
author_class = Class.new(Prism::Orm::Model) do
|
||||||
|
table_name :authors
|
||||||
|
has_many :posts, class_name: 'Post', foreign_key: 'author_id'
|
||||||
|
end
|
||||||
|
post_class = Class.new(Prism::Orm::Model) do
|
||||||
|
table_name :posts
|
||||||
|
belongs_to :author, class_name: 'Author', foreign_key: 'author_id'
|
||||||
|
end
|
||||||
|
author_class.store = @store
|
||||||
|
post_class.store = @store
|
||||||
|
Object.const_set(:Author, author_class)
|
||||||
|
Object.const_set(:Post, post_class)
|
||||||
|
end
|
||||||
|
|
||||||
|
def teardown
|
||||||
|
FileUtils.remove_entry(@dir)
|
||||||
|
%i[Author Post].each { |name| Object.send(:remove_const, name) if Object.const_defined?(name) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_belongs_to_returns_associated_record
|
||||||
|
author = Author.create!(name: 'foksiu')
|
||||||
|
post = Post.create!(title: 'hello', author_id: author.id)
|
||||||
|
assert_equal author, post.author
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_belongs_to_setter_updates_foreign_key
|
||||||
|
author = Author.create!(name: 'foksiu')
|
||||||
|
post = Post.create!(title: 'hello')
|
||||||
|
post.author = author
|
||||||
|
assert_equal author.id, post.author_id
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_belongs_to_returns_nil_when_unset
|
||||||
|
post = Post.create!(title: 'orphan')
|
||||||
|
assert_nil post.author
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_has_many_returns_associated_records
|
||||||
|
author = Author.create!(name: 'foksiu')
|
||||||
|
Post.create!(title: 'first', author_id: author.id)
|
||||||
|
Post.create!(title: 'second', author_id: author.id)
|
||||||
|
Post.create!(title: 'not mine', author_id: nil)
|
||||||
|
|
||||||
|
titles = author.posts.map(&:title).sort
|
||||||
|
assert_equal %w[first second], titles
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_where_with_array_condition
|
||||||
|
a = Author.create!(name: 'a')
|
||||||
|
b = Author.create!(name: 'b')
|
||||||
|
Author.create!(name: 'c')
|
||||||
|
matched = Author.where(id: [a.id, b.id]).map(&:name).sort
|
||||||
|
assert_equal %w[a b], matched
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_order_and_limit
|
||||||
|
Author.create!(name: 'charlie')
|
||||||
|
Author.create!(name: 'alice')
|
||||||
|
Author.create!(name: 'bob')
|
||||||
|
names = Author.order(:name).limit(2).map(&:name)
|
||||||
|
assert_equal %w[alice bob], names
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_order_desc
|
||||||
|
Author.create!(name: 'alice')
|
||||||
|
Author.create!(name: 'bob')
|
||||||
|
names = Author.order(:name, :desc).map(&:name)
|
||||||
|
assert_equal %w[bob alice], names
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_find_by
|
||||||
|
Author.create!(name: 'findme')
|
||||||
|
found = Author.find_by(name: 'findme')
|
||||||
|
refute_nil found
|
||||||
|
assert_nil Author.find_by(name: 'nope')
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_pluck
|
||||||
|
Author.create!(name: 'a')
|
||||||
|
Author.create!(name: 'b')
|
||||||
|
assert_equal %w[a b], Author.all.pluck(:name)
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
require 'minitest/autorun'
|
||||||
|
require 'prism'
|
||||||
|
require 'tmpdir'
|
||||||
|
|
||||||
|
class OrmValidationsTest < Minitest::Test
|
||||||
|
def setup
|
||||||
|
@dir = Dir.mktmpdir('prism-validation-store')
|
||||||
|
@store = Prism::Orm::Store.new(File.join(@dir, 'test.pstore'))
|
||||||
|
@store.create_table(:accounts, %w[id email nickname])
|
||||||
|
account_class = Class.new(Prism::Orm::Model) do
|
||||||
|
table_name :accounts
|
||||||
|
validates :email, presence: true, uniqueness: true, format: { with: /\A[^@\s]+@[^@\s]+\z/ }
|
||||||
|
validates :nickname, length: { minimum: 2, maximum: 10 }
|
||||||
|
end
|
||||||
|
account_class.store = @store
|
||||||
|
Object.const_set(:Account, account_class)
|
||||||
|
end
|
||||||
|
|
||||||
|
def teardown
|
||||||
|
FileUtils.remove_entry(@dir)
|
||||||
|
Object.send(:remove_const, :Account) if Object.const_defined?(:Account)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_presence_validation_blocks_save
|
||||||
|
account = Account.new(email: '')
|
||||||
|
refute account.valid?
|
||||||
|
assert_includes account.errors[:email], 'must be present'
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_format_validation_rejects_bad_email
|
||||||
|
account = Account.new(email: 'not-an-email', nickname: 'foksiu')
|
||||||
|
refute account.valid?
|
||||||
|
assert_includes account.errors[:email], 'is invalid'
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_valid_record_has_no_errors
|
||||||
|
account = Account.new(email: 'foksiu@example.com', nickname: 'foksiu')
|
||||||
|
assert account.valid?
|
||||||
|
assert_empty account.errors
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_uniqueness_rejects_duplicate_email
|
||||||
|
Account.create!(email: 'taken@example.com', nickname: 'first')
|
||||||
|
dupe = Account.new(email: 'taken@example.com', nickname: 'second')
|
||||||
|
refute dupe.valid?
|
||||||
|
assert_includes dupe.errors[:email], 'must be unique'
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_uniqueness_allows_saving_same_record_twice
|
||||||
|
account = Account.create!(email: 'stable@example.com', nickname: 'stable')
|
||||||
|
account.nickname = 'stable2'
|
||||||
|
assert account.save, account.errors.full_messages.join(', ')
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_length_validation
|
||||||
|
account = Account.new(email: 'a@example.com', nickname: 'x')
|
||||||
|
refute account.valid?
|
||||||
|
assert_includes account.errors[:nickname], 'is too short (minimum 2)'
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_custom_message
|
||||||
|
Account.validates(:email, format: { with: /@/, message: 'needs an @ sign' })
|
||||||
|
account = Account.new(email: 'nope', nickname: 'foksiu')
|
||||||
|
refute account.valid?
|
||||||
|
assert_includes account.errors[:email], 'needs an @ sign'
|
||||||
|
ensure
|
||||||
|
Account.validators.pop
|
||||||
|
end
|
||||||
|
end
|
||||||
Reference in new issue
Block a user