![Create React App Officially Deprecated Amid React 19 Compatibility Issues](https://cdn.sanity.io/images/cgdhsj6q/production/04fa08cf844d798abc0e1a6391c129363cc7e2ab-1024x1024.webp?w=400&fit=max&auto=format)
Security News
Create React App Officially Deprecated Amid React 19 Compatibility Issues
Create React App is officially deprecated due to React 19 issues and lack of maintenance—developers should switch to Vite or other modern alternatives.
Coverage: Currently at 99.1%
Minitest assertions to speed-up development and testing of Sequel database setups.
The general hope is that this gem will contain a variety of useful assertions in all areas of testing Sequel database code within your apps, gems, etc.
Please help out with missing features / functionality.
#assert_have_column (:model, :attribute, :opts, :msg)
spec: _(model).must_have_column(:attribute, :opts, :msg)
Conveniently test your Model definitions as follows:
let(:m) { Post.first }
it { assert_have_column(m, :title, type: :string, db_type: 'varchar(250)', allow_null: :false) }
it { _(m).must_have_column(:title, type: :string, allow_null: :false) }
it { _(m).must_have_column(:title, { type: :string, allow_null: :false }, "Custom messsage") }
# definition of args
# assert_have_column(
# <instance>,
# <column_name>,
# <options>,
# <custom_error_message>
# )
The #assert_have_column()
method first tests if the column name is defined in the Model and then
checks all passed options.
The following options are valid and checked:
:type
:db_type
:allow_null
:max_length
:default
:primary_key
:auto_increment
In the event the specs differ from the actual database implementation an extensive error message with the differing option(s) is provided to help speed up debugging the issue:
Expected Post model to have column: :title with: \
{
type: 'string',
db_type: 'varchar(250)',
allow_null: 'false'
}
but found: { db_type: 'varchar(255)' }
[!NOTE] To test options with a value that is either
nil
,true
orfalse
, please use:nil
,:false
or:true
and provide numbers as 'strings' instead, ie:'1'
instead of1
.
Conveniently test model associations quickly and easily with these Minitest assertions:
#assert_association_one_to_one
#assert_association_one_to_many
#assert_association_many_to_one
#assert_association_many_to_many
#assert_association
:one_to_one
associationA model defined with an association like this:
class Post < Sequel::Model
one_to_one :first_comment, class: :Comment, order: :id
end
Can be easily and quickly tested with #assert_association_one_to_one()
like this:
let(:m) { Post.first }
it { assert_association_one_to_one(m, :first_comment)
# or
it { _(m).must_have_one_to_one_association(:first_comment) }
# definition of args
assert_association_one_to_one(
<model_instance>,
<association_name>, # ie: :first_comment
<options>,
<custom_error_message>
)
In the event of errors an extensive error message is provided:
# example error message
Expected Author to have a :one_to_one association :key_posts but no association ':key_posts' \
was found - available associations are: [ \
{
:attribute=>:posts,
:type=>:one_to_many,
:class=>:Post,
:keys=>[:author_id]},
{
:attribute=>:key_post,
:type=>:one_to_one,
:class=>:Post,
:keys=>[:author_id]
}
]
:one_to_many
associationA model defined with an association like this:
class Post < Sequel::Model
one_to_many :comments
end
Can be easily and quickly tested with #assert_association_one_to_many()
like this:
let(:m) { Post.first }
it { assert_association_one_to_many(m, :comments) }
# or
it { _(m).must_have_one_to_many_association(:comments) }
As above the assertion provides an extensive error message if something is wrong.
:many_to_one
associationA model defined with an association like this:
class Post < Sequel::Model
many_to_one :author
end
Can be easily and quickly tested with #assert_association_many_to_one()
like this:
let(:m) { Post.first }
it { assert_association_many_to_one(m, :author) }
# or
it { _(m).must_have_many_to_one_association(:author) }
As above the assertion provides an extensive error message if something is wrong.
:many_to_many
associationA model defined with an association like this:
class Post < Sequel::Model
many_to_many :categories
end
Can be easily and quickly tested with #assert_association_many_to_many()
like this:
let(:m) { Post.first }
it { assert_association_many_to_many(m, :categories) }
# or
it { _(m).must_have_many_to_many_association(:categories) }
If something is wrong an extensive error message is provided:
Expected Category to have a :many_to_many association :posts with given options: \
{:class_name=>'Posts'} but should be {:class_name=>'Post' }
or
Expected Category to have a :many_to_many association :post but no association ':post' was found \
- available associations are: [ \
{
:attribute=>:posts,
:type=>:many_to_many,
:class=>:Post,
:join_table=>:categories_posts,
:left_keys=>[:category_id],
:right_keys=>[:post_id]
}
]
#assert_association(:model, :type, :attribute, :options, :msg)
spec: _(model).must_have_association(:type, :attribute, :options, :msg)
if the above assertion methods are insufficient, you can use the base
assert_association
method instead.
it "should have a :one_through_one association" do
assert_association(Post, :one_through_one, :author)
# or
_(Post).must_have_association(:one_through_one, :author)
end
# definition of args
assert_association(
<model_class>,
<association_type>,
<association_name>,
<options>,
<custom_error_message>
)
If you are using the recommended :validation_class_methods
plugin in your app, the following
instance validation methods are supported:
#assert_validates_presence()
#assert_validates_exact_length()
#assert_validates_length_range()
#assert_validates_max_length()
#assert_validates_min_length()
#assert_validates_format()
#assert_validates_inclusion()
#assert_validates_integer()
#assert_validates_numericality()
#assert_validates_uniqueness()
#assert_validates_acceptance()
#assert_validates_confirmation()
With all valid options checked
#assert_validates_presence(:model, :attribute, :opts, :msg)
alias: #assert_validates_presence_of(:attribute, :opts, :msg)
Test for validating presence of a model attribute
let(:m) { Post.first }
it { assert_validates_presence(m, :title) }
# or
it { _(m).must_validate_presence_of(:title, { message: '...' }) }
#assert_validates_length(:model, :attribute, :opts, :msg)
alias #assert_validates_length_of
Test for validating the length of a model's attribute.
Available options:
:message - The message to use (no default, overrides :nil_message, :too_long, :too_short, and :wrong_length options if present)
:nil_message - The message to use use if :maximum option is used and the value is nil (default: 'is not present')
:too_long - The message to use use if it the value is too long (default: 'is too long')
:too_short - The message to use use if it the value is too short (default: 'is too short')
:wrong_length - The message to use use if it the value is not valid (default: 'is the wrong length')
Size related options:
:is - The exact size required for the value to be valid (no default)
:minimum - The minimum size allowed for the value (no default)
:maximum - The maximum size allowed for the value (no default)
:within - The array/range that must include the size of the value for it to be valid (no default)
let(:m) { Post.first }
it { assert_validates_length(m, :title, { maximum: 12 }) }
# or
it { _(m).must_validate_length_of(:title, { within: 4..12 }) }
#assert_validates_exact_length(:model, :attribute, :exact_length, :opts, :msg)
alias: #assert_validates_exact_length_of
Test for validating the exact length of a model's attribute.
let(:m) { Post.first }
it { assert_validates_exact_length(m, :title, 12, { message: '...' }) }
# or
it { _(m).must_validate_exact_length_of(:title, 12, { message: '...' }) }
#assert_validates_length_range(:model, :attribute, :range, :opts, :msg)
alias: #assert_validates_length_range_of
Test for validating the exact length of a model's attribute.
let(:m) { Post.first }
it { assert_validates_length_range(m, :title, 4..12, { message: '...' }) }
# or
it { _(m).must_validate_length_range_of(:title, 4..12, { message: '...' }) }
#assert_validates_max_length(:model, :attribute, :max_length, :opts, :msg)
alias: #assert_validates_max_length_of
Test for validating the maximum length of a model's attribute.
let(:m) { Post.first }
it { assert_validates_max_length(m, :title, 12, { message: '...' }) }
# or
it { _(m).must_validate_max_length_of(:title, 12, { message: '...' }) }
#assert_validates_min_length(:model, :attribute, :min_length, :opts, :msg)
alias: #assert_validates_min_length_of
Test for validating the minimum length of a model's attribute.
let(:m) { Post.first }
it { assert_validates_min_length(m, :title, 12, { message: '...' }) }
# or
it { _(m).must_validate_min_length_of(:title, 12, { message: '...' }) }
#assert_validates_format(:model, :attribute, :opts, :msg)
alias: #assert_validates_format_of
Test for validating the format of a model's attribute with a regexp.
let(:m) { Post.first }
it { assert_validates_format(m, :title, { with: /[a-z+]/ }) }
# or
it { _(m).must_validate_format_of(:title, { with: /[a-z]+/ }) }
#assert_validates_inclusion(:model, :attribute, :opts, :msg)
alias: #assert_validates_inclusion_of
Test for validating that a model's attribute is within a specified range or set of values.
let(:m) { Post.first }
it { assert_validates_inclusion(m, :status, { in: [:a, :b, :c] }) }
# or
it { _(m).must_validate_inclusion_of(:status, { in: [:a, :b, :c] }) }
#assert_validates_integer(:model, :attribute, :opts, :msg)
alias: none
Test for validating that a a model's attribute is an integer.
let(:m) { Post.first }
it { assert_validates_integer(m, :author_id, { message: '...' }) }
# or
it { _(m).must_validate_integer_of(:author_id, { message: '...' }) }
#assert_validates_numericality(:model, :attribute, :opts, :msg)
alias: #assert_validates_numericality_of
Test for validating that a model's attribute is numeric (number).
let(:m) { Post.first }
it { assert_validates_numericality(m, :author_id, { message: '...' }) }
# or
it { _(m).must_validate_numericality_of(:author_id, { message: '...' }) }
#assert_validates_uniqueness(:model, :attribute, :opts, :msg)
alias: #assert_validates_uniqueness_of
Test for validating that a model's attribute is unique.
let(:m) { Post.first }
it { assert_validates_uniqueness(m, :urlslug, { message: '...' }) }
# or
it { _(m).must_validate_uniqueness_of(:urlslug, { message: '...' }) }
#assert_validates_acceptance(:model, :attribute, :opts, :msg)
alias: #assert_validates_acceptance_of
Test for validating the acceptance of a model's attribute.
let(:m) { Order.new }
it { assert_validates_acceptance(m, :toc, { message: '...' }) }
# or
it { _(m).must_validate_acceptance_of(:toc, { message: '...' }) }
#assert_validates_confirmation(:model, :attribute, :opts, :msg)
alias: #assert_validates_confirmation_of
Test for validating the confirmation of a model's attribute.
let(:m) { User.new }
it { assert_validates_confirmation(m, :password, { message: '...' }) }
# or
it { _(m).must_validate_confirmation_of(:password, { message: '...' }) }
Each validation assertion have a responding negative test, ie: refute_validate_presence()
A model defined with validations like this:
class Post < Sequel::Model
plugin :validation_helpers
def validate
super
validates_presence(:title)
validates_format(/\w+/, :title)
end
end
Can be quickly tested like this:
# <snip...>
let(:m) { Post.first }
it "should validate presence of :title column" do
assert_validates_presence(m, :title)
# or
_(m).must_validate_presence_of(:title)
end
it "should validate format of :title column with regexp" do
assert_validates_format(m, :title, /\w+/)
# or
_(m).must_validate_format_of(:title, /\w+/)
end
This gem also contains a collection of "helpers" that aid working with Sequel models:
#assert_timestamped_model(:model, :opts, :msg)
Quickly test if a model class is timestamped with .plugin(:timestamps)
with
Sequel-Timestamps
[!NOTE] The test examples below uses the minitest-assert_errors package.
# Declared locally in the Model
class Comment < Sequel::Model
plugin(:timestamps)
end
assert_no_error { assert_timestamped_model(Comment) }
# on a non-timestamped model
class Post < Sequel::Model; end
msg = /Not a \.plugin\(:timestamps\) model, available plugins are/
assert_error_raised(msg) { assert_timestamped_model(Post) }
[!TIP] You can also pass attributes to the created model in the tests via the
opts
hash like this:
assert_no_error do
assert_timestamped_model(Comment, {body: "I think...", email: "e@email.com"})
end
Timestamps can be declared globally for all models via Sequel::Model.plugin(:timestamps)
before
the models are migrated.
#assert_timestamped_model_instance(:model, :opts, :msg)
Test if a model instance is timestamped with the .plugin(:timestamps) via Sequel-Timestamps
let(:m) { Post.create(title: "Dummy") }
assert_no_error { assert_timestamped_model_instance(m) }
You can also test if an updated record is correctly timestamped
m.title = "Updated"
m.save
assert_no_error do
assert_timestamped_model_instance(m, updated_record: true)
end
Or alternatively test if an updated record is wrongly timestamped
let(:m) { Post.create(title: "Dummy", updated_at: Time.now) }
msg = /expected #.updated_at to be NIL on new record/
assert_error_raised(msg) do
assert_timestamped_model_instance(m, updated_record: false)
end
#assert_paranoid_model(:model, :opts, :msg)
Test if a model class is paranoid with .plugin(:paranoid) via Sequel-Paranoid
# Declared locally in the Model
class Comment < Sequel::Model
plugin(:paranoid)
end
assert_no_error { assert_paranoid_model(Comment) }
# on a non-paranoid model
class Post < Sequel::Model; end
msg = /Not a plugin\(:paranoid\) model, available plugins are/
assert_error_raised(msg) { assert_paranoid_model(Post) }
[!TIP] You can also pass attributes to the created model in the tests via the
opts
hash like this:
assert_no_error do
assert_timestamped_model(Comment, { body: "I think...", email: "e@email.com" })
end
#refute_timestamped_model(:model, :msg)
Test to ensure a model is NOT declared with .plugin(:timestamps) using Sequel-Timestamps
Test if a model class is paranoid with .plugin(:paranoid) via Sequel-Paranoid
class Comment < Sequel::Model
plugin(:timestamps)
end
msg = /expected Comment to NOT be a :timestamped model, but it was/
assert_error_raised(msg) do
refute_timestamped_model(Comment)
end
# on a non-timestamped model
class Post < Sequel::Model; end
it { refute_timestamped_model(Post) }
#refute_paranoid_model(:model, :msg)
Test to ensure a model is NOT declared with .plugin(:paranoid) using Sequel-Paranoid
class Comment < Sequel::Model
plugin(:paranoid)
end
msg = /expected Comment to NOT be a :paranoid model, but it was/
assert_error_raised(msg) { refute_paranoid_model(Comment) }
# on a non-paranoid model
class Post < Sequel::Model; end
it { refute_paranoid_model(Post) }
This gem also contains a collection of "helpers" that aid working with Sequel models:
#ensure_working_CRUD(:model, :attribute)
Enables quick tests to ensure that the basic CRUD functionality is working correctly for a Model
ensure_working_CRUD(User, :name)
[!NOTE]
- the passed
:model
argument must be the actual Model class and NOT a string or symbol- the passed attribute
:attribute
must be a String attribute or the tests will fail
This test depends upon being able to create a new model instance for each test via using
Sequel Factory's #make()
method
Add this line to your application's Gemfile:
gem 'minitest-sequel'
And then execute:
bundle
Or install it yourself as:
gem install minitest-sequel
In your project's spec/spec_helper.rb
or test/test_helper.rb
file ensure
the following code is present:
gem 'minitest'
require 'minitest/autorun'
require 'minitest/sequel' # NB!! must be loaded after minitest/autorun
require 'sqlite3' # using sqlite for tests
# The preferred default validations plugin, which uses class-level methods.
Sequel::Model.plugin(:validation_class_methods)
# connect to database
DB = Sequel.sqlite # :memory
## add migrations and seeds below
DB.create_table(:posts) do
primary_key :id
# <snip...>
end
# <snip...>
Then in your tests you should be good to go when using the sequel assertions.
After checking out the repo, run bundle install
to install all dependencies.
Then, run rake spec
to run the tests.
To install this gem onto your local machine, run bundle exec rake install
.
To release a new version, update the version number in version.rb
, and then run
bundle exec rake release
, which will create a git tag for the version, push git commits and
tags, and push the .gem
file to rubygems.org.
Bug reports and pull requests are welcome on GitHub at Issues.
This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.
The gem is available as open source under the terms of the MIT License.
FAQs
Unknown package
We found that minitest-sequel demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Create React App is officially deprecated due to React 19 issues and lack of maintenance—developers should switch to Vite or other modern alternatives.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Security News
The Linux Foundation is warning open source developers that compliance with global sanctions is mandatory, highlighting legal risks and restrictions on contributions.