Module: Minitest::Assertions

Defined in:
lib/minitest/sequel.rb,
lib/minitest/sequel/columns.rb,
lib/minitest/sequel/helpers.rb,
lib/minitest/sequel/plugins.rb,
lib/minitest/sequel/validations.rb,
lib/minitest/sequel/associations.rb

Overview

add support for Assert syntax

Instance Method Summary collapse

Instance Method Details

#assert_association(klass, association_type, attribute, opts = {}, msg = nil) ⇒ Boolean

Test for associations for the current model by passing the :association_type

This method asserts that the given class has an association of the specified type with the given attribute and options.

rubocop:disable Metrics/*

Examples:

Testing a many-to-many association

it "has a many-to-many association with tags" do
  assert_association(Post, :many_to_many, :tags)
end

Testing an association with options

it "has a one-to-many association with comments" do
  assert_association(Post, :one_to_many, :comments, { class: 'Comment', key: :post_id })
end

Parameters:

  • klass (Class)

    The class to test the association on

  • association_type (Symbol)

    The type of association to check for (e.g., :many_to_many)

  • attribute (Symbol)

    The name of the association

  • opts (Hash) (defaults to: {})

    Additional options for the association (default: {})

  • msg (String) (defaults to: nil)

    Custom error message (optional)

Returns:

  • (Boolean)

    true if the assertion passes, raises an error otherwise



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/minitest/sequel/associations.rb', line 146

def assert_association(klass, association_type, attribute, opts = {}, msg = nil)
  # Initialize error message
  msg = msg.nil? ? '' : "#{msg}\n"
  msg << "Expected #{klass} to have a #{association_type.inspect}"
  msg << " association #{attribute.inspect}"

  # Get association reflection or empty hash if not found
  assoc = klass.association_reflection(attribute) || {}

  if assoc.empty?
    # Association not found, prepare error message with available associations
    msg << ", but no association '#{attribute.inspect}' was found"
    arr = []
    klass.associations.each do |a|
      o = klass.association_reflection(a)
      arr << if o[:type] == :many_to_many
               # Prepare info for many-to-many association
               {
                 attribute: o[:name],
                 type: o[:type],
                 class: o[:class_name].to_s,
                 join_table: o[:join_table],
                 left_keys: o[:left_keys],
                 right_keys: o[:right_keys]
               }
             else
               # Prepare info for other association types
               {
                 attribute: o[:name],
                 type: o[:type],
                 class: o[:class_name].to_s,
                 keys: o[:keys]
               }
             end
    end
    # /klass.associations.each

    msg << " - \navailable associations are: [ #{arr.join(', ')} ]\n"
    assert(false, msg)
  else
    # Association found, check if it matches the expected type
    matching = assoc[:type] == association_type
    err_msg = []
    conf_msg = []

    # Check each option against the association
    opts.each do |key, value|
      conf_msg << { key => value }
      if assoc[key] != value
        err_msg << { key => assoc[key].to_s }
        matching = false
      end
    end

    # Prepare error message with mismatched options
    msg << " with given options: #{conf_msg.join(', ')} but should be #{err_msg.join(', ')}"
    assert(matching, msg)
  end
end

#assert_association_many_to_many(obj, attribute, opts = {}, msg = nil) ⇒ Boolean

Test for a :many_to_many association for the current model

This method asserts that the given object has a many-to-many association with the specified attribute and options.

Examples:

Testing a many-to-many association

let(:post) { Post.first }

it "has a many-to-many association with tags" do
  assert_association_many_to_many(post, :tags)
end

Using expectation syntax

it "has a many-to-many association with tags" do
  post.must_have_many_to_many_association(:tags)
end

Parameters:

  • obj (Object)

    The object to test the association on

  • attribute (Symbol)

    The name of the association

  • opts (Hash) (defaults to: {})

    Additional options for the association (default: {})

  • msg (String) (defaults to: nil)

    Custom error message (optional)

Returns:

  • (Boolean)

    true if the assertion passes, raises an error otherwise



118
119
120
# File 'lib/minitest/sequel/associations.rb', line 118

def assert_association_many_to_many(obj, attribute, opts = {}, msg = nil)
  assert_association(obj.class, :many_to_many, attribute, opts, msg)
end

#assert_association_many_to_one(obj, attribute, opts = {}, msg = nil) ⇒ Boolean

Test for a :many_to_one association for the current model

This method asserts that the given object has a many-to-one association with the specified attribute and options.

Examples:

Testing a many-to-one association

let(:comment) { Comment.first }

it "has a many-to-one association with post" do
  assert_association_many_to_one(comment, :post)
end

Using expectation syntax

it "has a many-to-one association with post" do
  comment.must_have_many_to_one_association(:post)
end

Parameters:

  • obj (Object)

    The object to test the association on

  • attribute (Symbol)

    The name of the association

  • opts (Hash) (defaults to: {})

    Additional options for the association (default: {})

  • msg (String) (defaults to: nil)

    Custom error message (optional)

Returns:

  • (Boolean)

    true if the assertion passes, raises an error otherwise



90
91
92
# File 'lib/minitest/sequel/associations.rb', line 90

def assert_association_many_to_one(obj, attribute, opts = {}, msg = nil)
  assert_association(obj.class, :many_to_one, attribute, opts, msg)
end

#assert_association_one_to_many(obj, attribute, opts = {}, msg = nil) ⇒ Boolean

Test for a :one_to_many association for the current model

This method asserts that the given object has a one-to-many association with the specified attribute and options.

Examples:

Testing a one-to-many association

let(:post) { Post.first }

it "has a one-to-many association with comments" do
  assert_association_one_to_many(post, :comments)
end

Using expectation syntax

it "has a one-to-many association with comments" do
  post.must_have_one_to_many_association(:comments)
end

Parameters:

  • obj (Object)

    The object to test the association on

  • attribute (Symbol)

    The name of the association

  • opts (Hash) (defaults to: {})

    Additional options for the association (default: {})

  • msg (String) (defaults to: nil)

    Custom error message (optional)

Returns:

  • (Boolean)

    true if the assertion passes, raises an error otherwise



62
63
64
# File 'lib/minitest/sequel/associations.rb', line 62

def assert_association_one_to_many(obj, attribute, opts = {}, msg = nil)
  assert_association(obj.class, :one_to_many, attribute, opts, msg)
end

#assert_association_one_to_one(obj, attribute, opts = {}, msg = nil) ⇒ Boolean

Test for a :one_to_one association for the current model

This method asserts that the given object has a one-to-one association with the specified attribute and options.

Examples:

Testing a one-to-one association

let(:post) { Post.first }

it "has a one-to-one association with first_comment" do
  assert_association_one_to_one(post, :first_comment, { class: :Comment, order: :id })
end

Using expectation syntax

it "has a one-to-one association with first_comment" do
  post.must_have_one_to_one_association(:first_comment, { class: :Comment, order: :id })
end

Parameters:

  • obj (Object)

    The object to test the association on

  • attribute (Symbol)

    The name of the association

  • opts (Hash) (defaults to: {})

    Additional options for the association (default: {})

  • msg (String) (defaults to: nil)

    Custom error message (optional)

Returns:

  • (Boolean)

    true if the assertion passes, raises an error otherwise



34
35
36
# File 'lib/minitest/sequel/associations.rb', line 34

def assert_association_one_to_one(obj, attribute, opts = {}, msg = nil)
  assert_association(obj.class, :one_to_one, attribute, opts, msg)
end

#assert_crud_can_create(model) ⇒ Object

Asserts that a model can be created successfully.

This method attempts to create a new instance of the given model using the :make method (typically provided by a factory). It then asserts that:

  1. The created instance is of the correct type.

  2. The instance has no errors after creation.

Parameters:

  • model (Class)

    The model class to test.

Raises:

  • (Minitest::Assertion)

    If the assertions fail.



22
23
24
25
26
27
28
29
30
# File 'lib/minitest/sequel/helpers.rb', line 22

def assert_crud_can_create(model)
  m = model.send(:make)

  msg = "CRUD:create - expected #{m.class} to be an instance of #{model}"
  assert_instance_of(model, m, msg)

  msg = "CRUD:create - expected .errors to be empty, but was: [#{m.errors.inspect}]"
  assert_empty(m.errors, msg)
end

#assert_crud_can_destroy(model) ⇒ Object

Asserts that a model can be destroyed successfully.

This method tests the destroy functionality of a model, considering both hard delete and soft delete (using :deleted_at) scenarios.

rubocop:disable Metrics/MethodLength, Metrics/AbcSize

Parameters:

  • model (Class)

    The model class to test.

Raises:

  • (Minitest::Assertion)

    If the assertions fail.



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/minitest/sequel/helpers.rb', line 101

def assert_crud_can_destroy(model)
  # Create a new instance of the model
  m = model.send(:make)

  # 1. test for Paranoid plugin
  plugs = model.instance_variable_get(:@plugins).map(&:to_s)
  paranoid = plugs.include?('Sequel::Plugins::Paranoid')

  if paranoid
    # If the model uses soft delete (has :deleted_at), ensure it's initially nil
    msg = "CRUD:destroy - expected :deleted_at to be nil, but was [#{m.deleted_at}]"
    assert_nil(m.deleted_at, msg)

    assert(m.soft_delete, 'CRUD:soft_delete - expected m.soft_delete to return true')

    # For soft delete, :deleted_at should be set to a timestamp
    refute_nil(m.deleted_at, 'CRUD:destroy - expected m.deleted_at to be NOT be nil')

    msg = 'CRUD:destroy - expected m.deleted_at to be an instance of Time'
    assert_instance_of(Time, m.deleted_at, msg)
  else
    # Attempt to destroy the model instance
    assert(m.destroy, 'CRUD:destroy - expected m.destroy to return true')
  end

  # Try to retrieve the first record from the database after destruction
  res = model.send(:first)

  if paranoid
    # By default the paranoid record should be returned from the database
    msg = "CRUD:destroy - expected #{model}.first to NOT return nil, but was: [#{res.inspect}]"
    refute_nil(res, msg)
  else
    # By default the record should not be returned from the database
    msg = "CRUD:destroy - expected #{model}.first to return nil, but was: [#{res.inspect}]"
    assert_nil(res, msg)
  end
end

#assert_crud_can_read(model) ⇒ Object

Asserts that a model can be read successfully.

This method attempts to create a new instance of the given model using the :make method, then retrieves the first record from the database. It then asserts that:

  1. The created instance is of the correct type.

  2. The retrieved record is equal to the created instance.

Parameters:

  • model (Class)

    The model class to test.

Raises:

  • (Minitest::Assertion)

    If the assertions fail.



44
45
46
47
48
49
50
51
52
# File 'lib/minitest/sequel/helpers.rb', line 44

def assert_crud_can_read(model)
  m = model.send(:make)
  res = model.send(:first)

  msg = "CRUD:read - expected #{res.class} to be an instance of #{model}"
  assert_instance_of(model, m, msg)

  assert_equal(m, res, "CRUD:read - expected [#{m.inspect}] to equal [#{res.inspect}]")
end

#assert_crud_can_update(model, attr) ⇒ Object

Asserts that a model can be updated successfully.

This method attempts to create a new instance of the given model, update a specific attribute, and then verify the update.

Parameters:

  • model (Class)

    The model class to test.

  • attr (Symbol, String)

    The attribute to update.

Raises:

  • (Minitest::Assertion)

    If the assertions fail.



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/minitest/sequel/helpers.rb', line 64

def assert_crud_can_update(model, attr)
  # Create a new instance of the model
  m = model.send(:make)

  # Generate a new value for the attribute by appending " Updated" to its current value
  tmp_str = "#{m.send(attr.to_sym)} Updated"

  # Retrieve the first record from the database
  res = model.send(:first)

  # Assert that the retrieved record matches the created instance
  assert_equal(m, res, "CRUD:update - expected [#{m.inspect}] to equal [#{res.inspect}]")

  # Update the attribute with the new value
  res.send(:"#{attr}=", tmp_str)
  res.save

  # Retrieve the updated record from the database
  res2 = model.send(:first)

  # Assert that the updated attribute matches the new value
  msg = "CRUD:update - expected [#{res2.send(attr.to_sym)}] to equal "
  msg << "the updated string: [#{tmp_str}]"

  assert_equal(tmp_str, res2.send(attr.to_sym), msg)
end

#assert_have_column(obj, attribute, opts = {}, msg = nil) ⇒ Object

Note:

When testing for ‘nil`, `true`, or `false` values, use `:nil`, `:true`, or `:false` symbols respectively. For numeric values, provide them as strings.

Asserts that a given model has a specific column with optional attribute checks

The method checks if the column exists in the model and then verifies any provided options. Valid options include:

* :type - The Ruby type of the column
* :db_type - The database-specific type of the column
* :allow_null - Whether the column allows NULL values
* :max_length - The maximum length for string-type columns
* :default - The default value for the column
* :primary_key - Whether the column is a primary key
* :auto_increment - Whether the column auto-increments

If the actual column attributes differ from the specified options, a detailed error message is provided:

Expected Post model to have column: :title with: \
  { type: 'string', db_type: 'varchar(250)', allow_null: 'false' } \
  but found: { db_type: 'varchar(255)' }

rubocop:disable Metrics/MethodLength

Examples:

Basic usage

let(:m) { Post.first }
assert_have_column(m, :title, type: :string, db_type: 'varchar(250)')

Using with Spec syntax

m.must_have_column(:title, type: :string, db_type: 'varchar(250)')

Parameters:

  • obj (Object)

    The model instance to check

  • attribute (Symbol)

    The name of the column to check

  • opts (Hash) (defaults to: {})

    Optional attributes to verify for the column

  • msg (String, nil) (defaults to: nil)

    Optional custom error message



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/minitest/sequel/columns.rb', line 47

def assert_have_column(obj, attribute, opts = {}, msg = nil)
  # Prepare the error message
  msg = build_message_column(obj, attribute, msg)

  # prepare output messages
  msg_conf = []
  msg_err = []

  # extract the db table information for the column
  dbcol = extract_column_info(obj, attribute)

  # set matching status
  matching = !dbcol.nil?

  # bail if there is no matching column
  bail_unless_column_exists(dbcol, msg) unless matching
  # bail if passed options are invalid
  bail_unless_valid_options(opts, msg)

  # loop through the options passed and check them and report the result
  opts.each do |key, value|
    expected = compare_column_attribute(dbcol, key, value)
    update_messages(msg_conf, msg_err, key, value, dbcol, expected)
    matching &&= expected
  end

  msg << " with: { #{msg_conf.join(', ')} } but found: { #{msg_err.join(', ')} }"
  assert(matching, msg)
end

#assert_paranoid_model(model, opts = {}) ⇒ Object

Test if a model class is paranoid with .plugin(:paranoid) via [Sequel-Paranoid](github.com/sdepold/sequel-paranoid)

This assertion checks if a given model class has been properly configured with the Sequel Paranoid plugin. It verifies the presence of the plugin, the existence of the required column (:deleted_at), and the correct behavior of soft deletion for both new and updated records.

rubocop:disable Metrics/AbcSize, Metrics/MethodLength

Examples:

Testing a paranoid model

class Comment < Sequel::Model
  plugin(:paranoid)
end
assert_no_error { assert_paranoid_model(Comment) }

Testing 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) }

Testing with additional attributes to create a valid model instance

assert_no_error do
   assert_paranoid_model(Comment, {body: "I think...", email: "[email protected]"})
end

Parameters:

  • model (Class)

    The model class to test

  • opts (Hash) (defaults to: {})

    Options to modify the assertion behavior

Raises:

  • (Minitest::Assertion)

    If the model class does not meet the paranoid criteria



185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# File 'lib/minitest/sequel/plugins.rb', line 185

def assert_paranoid_model(model, opts = {})
  m = opts.empty? ? model.send(:make) : model.send(:create, opts)

  # 1. test for Paranoid plugin
  plugs = model.instance_variable_get(:@plugins).map(&:to_s)

  unless plugs.include?('Sequel::Plugins::Paranoid')
    raise(
      Minitest::Assertion,
      "Not a plugin(:paranoid) model, available plugins are: #{plugs.inspect}"
    )
  end

  str = 'AssertParanoidModel - expected'

  msg = "#{str} #deleted_at to be NIL on new model"
  assert_nil(m.deleted_at, msg)

  # after update
  assert(m.save, "AssertParanoidModel:save - updated model failed. Debug: [#{m.inspect}]")

  msg = "#{str} #deleted_at to be NIL on updated model"
  assert_nil(m.deleted_at, msg)

  # after destroy
  assert(m.destroy, "AssertParanoidModel:destroy - destroy model failed. Debug: [#{m.inspect}]")

  # assert_instance_of(Time, m.deleted_at,
  #
  msg = "#{str} #deleted_at to be instance of Time on destroyed model, Debug: [#{m.inspect}]"
  assert_instance_of(NilClass, m.deleted_at, msg)
end

#assert_raises_validation_failed(obj) ⇒ Object Also known as: assert_fails_validation

Test that saving an object raises a ValidationFailed error

This method attempts to save the given object and asserts that it raises a Sequel::ValidationFailed error. It can be used to test that invalid objects fail validation when attempting to save.

Examples:

Using assertion style

assert_raises_validation_failed(invalid_user)

Using expectation style

invalid_user.must_fail_validation

Parameters:

  • obj (Object)

    The model object to test

Raises:

  • (Minitest::Assertion)

    If saving the object does not raise Sequel::ValidationFailed



935
936
937
# File 'lib/minitest/sequel/validations.rb', line 935

def assert_raises_validation_failed(obj)
  assert_raises(::Sequel::ValidationFailed) { obj.save }
end

#assert_timestamped_model(model, opts = {}) ⇒ Object

Test if a model class is timestamped with .plugin(:timestamps)

This assertion checks if a given model class has been properly configured with the Sequel Timestamps plugin. It verifies the presence of the plugin, the existence of the required columns, and the correct behavior of timestamps for both new and updated records.

rubocop:disable Metrics/AbcSize, Metrics/MethodLength

Examples:

Testing a timestamped model

class Comment < Sequel::Model
  plugin(:timestamps)
end

assert_no_error { assert_timestamped_model(Comment) }

Testing 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) }

Testing with additional attributes to create a valid model instance

assert_no_error do
  assert_timestamped_model(Comment, {body: "I think...", email: "[email protected]"})
end

Parameters:

  • model (Class)

    The model class to test

  • opts (Hash) (defaults to: {})

    Options to modify the assertion behavior

Raises:

  • (Minitest::Assertion)

    If the model class does not meet the timestamped criteria



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/minitest/sequel/plugins.rb', line 111

def assert_timestamped_model(model, opts = {})
  m = opts.empty? ? model.send(:make) : model.send(:create, opts)

  # 1. test for Timestamps plugin
  plugs = model.instance_variable_get(:@plugins).map(&:to_s)

  unless plugs.include?('Sequel::Plugins::Timestamps')
    msg = "Not a plugin(:timestamps) model, available plugins are: #{plugs.inspect}"
    raise(Minitest::Assertion, msg)
  end

  str = 'AssertTimestampedModel - expected'

  # 2. test for created_at / :updated_at columns
  msg = "#{str} model to have column :created_at. Debug: [#{m.inspect}]"
  assert_have_column(m, :created_at, {}, msg)

  msg = "#{str} model to have column :updated_at. Debug: [#{m.inspect}]"
  assert_have_column(m, :updated_at, {}, msg)

  # 3.  initial record
  msg = "#{str} :created_at to be an instance of Time on new record. Debug: [#{m.inspect}]"
  assert_instance_of(Time, m.created_at, msg)

  msg = "#{str} :updated_at to be an instance of Time on new record. Debug: [#{m.inspect}]"
  assert_instance_of(NilClass, m.updated_at, msg)

  # 4. updated record
  # old_ts = m.created_at
  # sleep 1  # TODO: could this be converted to timecop or similar?
  # m.title = "#{m.title} updated"
  assert(m.save, "AssertTimestampedModel:#save - updated model failed. Debug: [#{m.inspect}]")

  msg = "#{str} :created_at to be an instance of Time on updated record. Debug: [#{m.inspect}]"
  assert_instance_of(Time, m.created_at, msg)

  msg = "#{str} :updated_at to be an instance of Time on updated record. Debug: [#{m.inspect}]"
  assert_instance_of(Time, m.updated_at, msg)

  # assert_equal(old_ts, m.created_at, "#{str} the :created_at timestamp to be unchanged")
end

#assert_timestamped_model_instance(model, opts = {}) ⇒ Object

Test if a model instance is timestamped via .plugin(:timestamps)

This assertion checks if a given model instance has been properly timestamped using the Sequel Timestamps plugin. It verifies the presence of the plugin, the existence of the required columns, and the correct behavior of timestamps for both new and updated records.

rubocop:disable Metrics/AbcSize, Metrics/MethodLength

Examples:

Testing a new record

let(:m) { Post.create(title: 'Dummy') }
assert_no_error { assert_timestamped_model_instance(m) }

Testing an updated record

m.title = 'Updated'
m.save
assert_no_error { assert_timestamped_model_instance(m, updated_record: true) }

Testing an incorrectly timestamped record

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

Parameters:

  • model (Sequel::Model)

    The model instance to test

  • opts (Hash) (defaults to: {})

    Options to modify the assertion behavior

Options Hash (opts):

  • :updated_record (Boolean)

    Set to true to test an updated record

Raises:

  • (Minitest::Assertion)

    If the model instance does not meet the timestamped criteria



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/minitest/sequel/plugins.rb', line 41

def assert_timestamped_model_instance(model, opts = {})
  model_class = model.class

  # 1. test for Timestamps plugin
  plugs = model_class.instance_variable_get(:@plugins).map(&:to_s)

  unless plugs.include?('Sequel::Plugins::Timestamps')
    msg = "Not a plugin(:timestamps) model, available plugins are: #{plugs.inspect}"
    raise(Minitest::Assertion, msg)
  end

  str = 'AssertTimestampedModelInstance -'

  # 2. test for created_at / :updated_at columns
  msg = "#{str} expected model to have column :created_at. Debug: [#{model.inspect}]"
  assert_have_column(model, :created_at, {}, msg)

  msg = "#{str} expected model to have column :updated_at. Debug: [#{model.inspect}]"
  assert_have_column(model, :updated_at, {}, msg)

  if opts[:updated_record]
    # 4. updated record
    msg = "#{str} expected #created_at to be an instance of Time on updated record"
    assert_instance_of(Time, model.created_at, msg)

    msg = "#{str} expected #updated_at to be an instance of Time on updated record"
    assert_instance_of(Time, model.updated_at, msg)
  else
    # 3.  initial record
    msg = "#{str} expected #created_at to be an instance of Time on new record"
    assert_instance_of(Time, model.created_at, msg)

    msg = "#{str} expected #updated_at to be NIL on new record"
    assert_no_error { assert_nil(model.updated_at, msg) }
  end
end

#assert_validates(obj, validation_type, attribute, opts = {}, msg = nil) ⇒ Object

Base test for validations of a model, used mainly as a shortcut for other assertions

This method checks if the specified attribute of the given object has the expected validation type and options. It can be used to test various validation types such as ;presence, :format, :length, etc.

rubocop:disable Metrics/*

Examples:

Testing presence validation

assert_validates(User.new, :presence, :name, { message: "can't be blank" })

Testing length validation

assert_validates(Post.new, :length, :title, { minimum: 5, maximum: 100 })

Parameters:

  • obj (Object)

    The model object to test

  • validation_type (Symbol)

    The type of validation to check (e.g., :presence, :format, :length)

  • attribute (Symbol)

    The attribute to check for validation

  • opts (Hash) (defaults to: {})

    Additional options for the validation (default: {})

  • msg (String) (defaults to: nil)

    Custom error message (default: nil)

Raises:

  • (Minitest::Assertion)

    If the validation does not match the expected criteria



410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
# File 'lib/minitest/sequel/validations.rb', line 410

def assert_validates(obj, validation_type, attribute, opts = {}, msg = nil)
  msg = msg.nil? ? '' : "#{msg}\n"
  err_msg  = []
  conf_msg = []

  unless obj.respond_to?(attribute)
    assert(false, "Column :#{attribute} is not defined in #{obj.class}")
  end

  msg << "Expected #{obj.class} to validate :#{validation_type} for :#{attribute} column"

  if _validated_model?(obj)
    if _validated_column?(obj, attribute)
      # checks if the model column is validated by the validation type
      if _validated_with_validation_type?(obj, attribute, validation_type)
        matching = true

        # bail out if options provided are invalid
        val_opts = _valid_validation_options(validation_type)

        invalid_opts = opts.keys.reject { |o| val_opts.include?(o) }
        unless invalid_opts.empty?
          msg << ', but the following invalid option(s) was found: { '
          invalid_opts.each { |o| msg << "#{o.inspect}; " }
          msg << " }. Valid options are: #{val_opts.inspect}"
          assert(false, msg)
        end

        h = _validation_types_hash_for_column(obj, attribute)
        _available_validation_options.each do |ov|
          next if opts[ov].nil?

          expected = (h[validation_type][ov].to_s == opts[ov].to_s)
          conf_msg << "#{ov}: '#{opts[ov]}'"
          err_msg << "#{ov}: '#{h[validation_type][ov]}'" unless expected
          matching &&= expected
        end

        msg <<= " with: { #{conf_msg.join(', ')} }" unless conf_msg.empty?
        msg << " but found: { #{err_msg.join(', ')} }" unless err_msg.empty?
        assert(matching, msg)

      else
        msg << ", but no :#{validation_type} validation is defined for :#{attribute}"
        assert(false, msg)
      end
    else
      msg << ", but no validations are defined for :#{attribute}"
      assert(false, msg)
    end
  else
    assert(false, "No validations defined in #{obj.class}")
  end
end

#assert_validates_acceptance(obj, attribute, opts = {}, msg = nil) ⇒ Object Also known as: assert_validates_acceptance_of

Note:

The acceptance validation is typically used for checkboxes in web forms where the user needs to accept terms of service.

Test for validating the acceptance of a model’s attribute.

This method checks if the specified attribute of the given object has an acceptance validation. It can be used in both assertion and expectation styles.

Examples:

Using assertion style

assert_validates_acceptance(
  Order.new,
  :toc,
  { message: 'You must accept the terms and conditions' }
)

Using expectation style

model.must_validate_acceptance_of(:toc, { accept: 'yes' })

Parameters:

  • obj (Object)

    The model object to test

  • attribute (Symbol)

    The attribute to check for acceptance validation

  • opts (Hash) (defaults to: {})

    Additional options for the validation (default: {})

  • msg (String) (defaults to: nil)

    Custom error message (default: nil)



358
359
360
# File 'lib/minitest/sequel/validations.rb', line 358

def assert_validates_acceptance(obj, attribute, opts = {}, msg = nil)
  assert_validates(obj, :acceptance, attribute, opts, msg)
end

#assert_validates_confirmation(obj, attribute, opts = {}, msg = nil) ⇒ Object Also known as: assert_validates_confirmation_of

Note:

The confirmation validation is typically used for password fields where the user needs to enter the same password twice.

Test for validating the confirmation of a model’s attribute.

This method checks if the specified attribute of the given object has a confirmation validation. It can be used in both assertion and expectation styles.

Examples:

Using assertion style

assert_validates_confirmation(User.new, :password, { message: 'Passwords do not match' })

Using expectation style

User.new.must_validate_confirmation_of(:password, { message: 'Passwords do not match' })

Parameters:

  • obj (Object)

    The model object to test

  • attribute (Symbol)

    The attribute to check for confirmation validation

  • opts (Hash) (defaults to: {})

    Additional options for the validation (default: {})

  • msg (String) (defaults to: nil)

    Custom error message (default: nil)



383
384
385
# File 'lib/minitest/sequel/validations.rb', line 383

def assert_validates_confirmation(obj, attribute, opts = {}, msg = nil)
  assert_validates(obj, :confirmation, attribute, opts, msg)
end

#assert_validates_exact_length(obj, attribute, exact_length, opts = {}, msg = nil) ⇒ Object Also known as: assert_validates_exact_length_of

Test for validating the exact length of a model’s attribute.

This method checks if the specified attribute of the given object has a length validation for an exact length. It can be used in both assertion and expectation styles.

Examples:

Using assertion style

assert_validates_exact_length(
  model,
  :title,
  12,
  { message: 'Must be exactly 12 characters' }
)

Using expectation style

model.must_validate_exact_length_of(
  :title,
  12,
  { message: 'Must be exactly 12 characters' }
)

Parameters:

  • obj (Object)

    The model object to test

  • attribute (Symbol)

    The attribute to check for exact length validation

  • exact_length (Integer)

    The exact length to validate against

  • opts (Hash) (defaults to: {})

    Additional options for the validation (default: {})

  • msg (String) (defaults to: nil)

    Custom error message (default: nil)



102
103
104
105
# File 'lib/minitest/sequel/validations.rb', line 102

def assert_validates_exact_length(obj, attribute, exact_length, opts = {}, msg = nil)
  opts[:is] = exact_length
  assert_validates(obj, :length, attribute, opts, msg)
end

#assert_validates_format(obj, attribute, opts = {}, msg = nil) ⇒ Object Also known as: assert_validates_format_of

Test for validating the format of a model’s attribute with a regexp.

This method checks if the specified attribute of the given object has a format validation with the provided regular expression. It can be used in both assertion and expectation styles.

Examples:

Using assertion style

assert_validates_format(model, :title, { with: /[a-z]+/ })

Using expectation style

model.must_validate_format_of(:title, { with: /[a-z]+/ })

With custom error message

assert_validates_format(
  model,
  :title,
  { with: /[a-z]+/, message: 'must contain only lowercase letters' }
)

Parameters:

  • obj (Object)

    The model object to test

  • attribute (Symbol)

    The attribute to check for format validation

  • opts (Hash) (defaults to: {})

    Additional options for the validation (default: {})

  • msg (String) (defaults to: nil)

    Custom error message (default: nil)

Options Hash (opts):

  • :with (Regexp)

    The regular expression to validate against (required)



215
216
217
# File 'lib/minitest/sequel/validations.rb', line 215

def assert_validates_format(obj, attribute, opts = {}, msg = nil)
  assert_validates(obj, :format, attribute, opts, msg)
end

#assert_validates_inclusion(obj, attribute, opts = {}, msg = nil) ⇒ Object Also known as: assert_validates_inclusion_of

Test for validating that a model’s attribute is within a specified range or set of values.

This method checks if the specified attribute of the given object has an inclusion validation with the provided set of values. It can be used in both assertion and expectation styles.

Examples:

Using assertion style

assert_validates_inclusion(model, :status, { in: [:a, :b, :c] })

Using expectation style

model.must_validate_inclusion_of(:status, { in: [:a, :b, :c] })

With custom error message

assert_validates_inclusion(
  model,
  :status,
  { in: [:a, :b, :c], message: 'must be a valid status' }
)

Parameters:

  • obj (Object)

    The model object to test

  • attribute (Symbol)

    The attribute to check for inclusion validation

  • opts (Hash) (defaults to: {})

    Additional options for the validation (default: {})

  • msg (String) (defaults to: nil)

    Custom error message (default: nil)

Options Hash (opts):

  • :in (Array, Range)

    The set of valid values (required)



246
247
248
# File 'lib/minitest/sequel/validations.rb', line 246

def assert_validates_inclusion(obj, attribute, opts = {}, msg = nil)
  assert_validates(obj, :inclusion, attribute, opts, msg)
end

#assert_validates_integer(obj, attribute, opts = {}, msg = nil) ⇒ Object

Test for validating that a model’s attribute is an integer.

This method checks if the specified attribute of the given object has a numericality validation with the ‘only_integer’ option set to true. It can be used in both assertion and expectation styles.

Examples:

Using assertion style

assert_validates_integer(model, :author_id, { message: 'must be an integer' })

Using expectation style

model.must_validate_integer_of(:author_id, { message: 'must be an integer' })

Parameters:

  • obj (Object)

    The model object to test

  • attribute (Symbol)

    The attribute to check for integer validation

  • opts (Hash) (defaults to: {})

    Additional options for the validation (default: {})

  • msg (String) (defaults to: nil)

    Custom error message (default: nil)



268
269
270
271
# File 'lib/minitest/sequel/validations.rb', line 268

def assert_validates_integer(obj, attribute, opts = {}, msg = nil)
  opts[:only_integer] = true
  assert_validates(obj, :numericality, attribute, opts, msg)
end

#assert_validates_length(obj, attribute, opts = {}, msg = nil) ⇒ Object Also known as: assert_validates_length_of

Test for validating the length of a model’s attribute.

This method checks if the specified attribute of the given object has a length validation. It can be used in both assertion and expectation styles.

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 if :maximum option is used and the value is nil

    (default: 'is not present')
    
  • :too_long - The message to use if the value is too long (default: ‘is too long’)

  • :too_short - The message to use if the value is too short (default: ‘is too short’)

  • :wrong_length - The message to use if 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 value for the value (no default)

Examples:

Using assertion style

assert_validates_length(model, :title, { maximum: 12 })

Using expectation style

model.must_validate_length_of(:title, { within: 4..12 })

Parameters:

  • obj (Object)

    The model object to test

  • attribute (Symbol)

    The attribute to check for length validation

  • opts (Hash) (defaults to: {})

    Additional options for the validation (default: {})

  • msg (String) (defaults to: nil)

    Custom error message (default: nil)



70
71
72
# File 'lib/minitest/sequel/validations.rb', line 70

def assert_validates_length(obj, attribute, opts = {}, msg = nil)
  assert_validates(obj, :length, attribute, opts, msg)
end

#assert_validates_length_range(obj, attribute, range, opts = {}, msg = nil) ⇒ Object Also known as: assert_validates_length_range_of

Test for validating the length range of a model’s attribute.

This method checks if the specified attribute of the given object has a length validation within a specified range. It can be used in both assertion and expectation styles.

Examples:

Using assertion style

assert_validates_length_range(
  model,
  :title,
  4..12,
  { message: 'Title must be between 4 and 12 characters' }
)

Using expectation style

model.must_validate_length_range_of(
  :title,
  4..12,
  { message: 'Title must be between 4 and 12 characters' }
)

Parameters:

  • obj (Object)

    The model object to test

  • attribute (Symbol)

    The attribute to check for length range validation

  • range (Range)

    The range of acceptable lengths

  • opts (Hash) (defaults to: {})

    Additional options for the validation (default: {})

  • msg (String) (defaults to: nil)

    Custom error message (default: nil)



135
136
137
138
# File 'lib/minitest/sequel/validations.rb', line 135

def assert_validates_length_range(obj, attribute, range, opts = {}, msg = nil)
  opts[:within] = range
  assert_validates(obj, :length, attribute, opts, msg)
end

#assert_validates_max_length(obj, attribute, max_length, opts = {}, msg = nil) ⇒ Object Also known as: assert_validates_max_length_of

Test for validating the maximum length of a model’s attribute.

This method checks if the specified attribute of the given object has a length validation with a maximum value. It can be used in both assertion and expectation styles.

Examples:

Using assertion style

assert_validates_max_length(model, :title, 12, { message: 'Title is too long' })

Using expectation style

model.must_validate_max_length_of(:title, 12, { message: 'Title is too long' })

Parameters:

  • obj (Object)

    The model object to test

  • attribute (Symbol)

    The attribute to check for maximum length validation

  • max_length (Integer)

    The maximum length to validate against

  • opts (Hash) (defaults to: {})

    Additional options for the validation (default: {})

  • msg (String) (defaults to: nil)

    Custom error message (default: nil)



159
160
161
162
# File 'lib/minitest/sequel/validations.rb', line 159

def assert_validates_max_length(obj, attribute, max_length, opts = {}, msg = nil)
  opts[:maximum] = max_length
  assert_validates(obj, :length, attribute, opts, msg)
end

#assert_validates_min_length(obj, attribute, min_length, opts = {}, msg = nil) ⇒ Object Also known as: assert_validates_min_length_of

Test for validating the minimum length of a model’s attribute.

This method checks if the specified attribute of the given object has a length validation with a minimum value. It can be used in both assertion and expectation styles.

Examples:

Using assertion style

assert_validates_min_length(model, :title, 12, { message: 'Title is too short' })

Using expectation style

model.must_validate_min_length_of(:title, 12, { message: 'Title is too short' })

Parameters:

  • obj (Object)

    The model object to test

  • attribute (Symbol)

    The attribute to check for minimum length validation

  • min_length (Integer)

    The minimum length to validate against

  • opts (Hash) (defaults to: {})

    Additional options for the validation (default: {})

  • msg (String) (defaults to: nil)

    Custom error message (default: nil)



183
184
185
186
# File 'lib/minitest/sequel/validations.rb', line 183

def assert_validates_min_length(obj, attribute, min_length, opts = {}, msg = nil)
  opts[:minimum] = min_length
  assert_validates(obj, :length, attribute, opts, msg)
end

#assert_validates_numericality(obj, attribute, opts = {}, msg = nil) ⇒ Object Also known as: assert_validates_numericality_of

Test for validating that a model’s attribute is numeric (number).

This method checks if the specified attribute of the given object has a numericality validation. It can be used in both assertion and expectation styles.

Examples:

Using assertion style

assert_validates_numericality(model, :price, { greater_than: 0 })

Using expectation style

model.must_validate_numericality_of(:price, { less_than_or_equal_to: 1000 })

With custom error message

assert_validates_numericality(
  model,
  :quantity,
  { only_integer: true, message: 'must be a whole number' }
)

Parameters:

  • obj (Object)

    The model object to test

  • attribute (Symbol)

    The attribute to check for numericality validation

  • opts (Hash) (defaults to: {})

    Additional options for the validation (default: {})

  • msg (String) (defaults to: nil)

    Custom error message (default: nil)



297
298
299
# File 'lib/minitest/sequel/validations.rb', line 297

def assert_validates_numericality(obj, attribute, opts = {}, msg = nil)
  assert_validates(obj, :numericality, attribute, opts, msg)
end

#assert_validates_presence(obj, attribute, opts = {}, msg = nil) ⇒ Object Also known as: assert_validates_presence_of

Test for validating presence of a model attribute

This method checks if the specified attribute of the given object has a presence validation. It can be used in both assertion and expectation styles.

Examples:

Using assertion style

assert_validates_presence(model, :title)

Using expectation style

model.must_validate_presence_of(:title)

With custom error message

assert_validates_presence(model, :title, { message: 'Title cannot be blank' })

Parameters:

  • obj (Object)

    The model object to test

  • attribute (Symbol)

    The attribute to check for presence validation

  • opts (Hash) (defaults to: {})

    Additional options for the validation (default: {})

  • msg (String) (defaults to: nil)

    Custom error message (default: nil)



30
31
32
# File 'lib/minitest/sequel/validations.rb', line 30

def assert_validates_presence(obj, attribute, opts = {}, msg = nil)
  assert_validates(obj, :presence, attribute, opts, msg)
end

#assert_validates_uniqueness(obj, attribute, opts = {}, msg = nil) ⇒ Object Also known as: assert_validates_uniqueness_of

Test for validating that a model’s attribute is unique.

This method checks if the specified attribute of the given object has a uniqueness validation. It can be used in both assertion and expectation styles.

Examples:

Using assertion style

assert_validates_uniqueness(model, :urlslug, { message: 'must be unique' })

Using expectation style

model.must_validate_uniqueness_of(:urlslug, { case_sensitive: false })

With custom error message

assert_validates_uniqueness(
  model,
  :email,
  { scope: :account_id, message: 'already taken for this account' }
)

Parameters:

  • obj (Object)

    The model object to test

  • attribute (Symbol)

    The attribute to check for uniqueness validation

  • opts (Hash) (defaults to: {})

    Additional options for the validation (default: {})

  • msg (String) (defaults to: nil)

    Custom error message (default: nil)



326
327
328
# File 'lib/minitest/sequel/validations.rb', line 326

def assert_validates_uniqueness(obj, attribute, opts = {}, msg = nil)
  assert_validates(obj, :uniqueness, attribute, opts, msg)
end

#refute_association(klass, association_type, attribute, msg = nil) ⇒ Boolean

Test to ensure the current model does NOT have an association by type :association_type

This method asserts that the given class does not have an association of the specified type with the given attribute.

rubocop:disable Metrics/MethodLength

Examples:

Testing that a class does not have a many-to-many association

it "does not have a many-to-many association with tags" do
  refute_association(Post, :many_to_many, :tags)
end

Using expectation syntax

it "does not have a many-to-many association with tags" do
  Post.wont_have_association(:many_to_many, :tags)
end

Parameters:

  • klass (Class)

    The class to test the association on

  • association_type (Symbol)

    The type of association to check for (e.g., :many_to_many)

  • attribute (Symbol)

    The name of the association

  • msg (String) (defaults to: nil)

    Custom error message (optional)

Returns:

  • (Boolean)

    true if the assertion passes, raises an error otherwise



338
339
340
341
342
343
344
345
346
347
348
349
350
351
# File 'lib/minitest/sequel/associations.rb', line 338

def refute_association(klass, association_type, attribute, msg = nil)
  msg = msg.nil? ? '' : "#{msg}\n"
  msg << "Expected #{klass.inspect} to NOT have a #{association_type.inspect}"
  msg << " association #{attribute.inspect}"
  assoc = klass.association_reflection(attribute) || {}

  if assoc.empty?
    assert(true, msg)
  else
    matching = false if assoc[:type] == association_type
    msg << ', but such an association was found'
    assert(matching, msg)
  end
end

#refute_association_many_to_many(obj, attribute, msg = nil) ⇒ Boolean

Test to ensure there is no :many_to_many association for the current model

This method asserts that the given object does not have a many-to-many association with the specified attribute.

Examples:

Testing that an object does not have a many-to-many association

let(:post) { Post.first }

it "does not have a many-to-many association with tags" do
  refute_association_many_to_many(post, :tags)
end

Using expectation syntax

it "does not have a many-to-many association with tags" do
  post.wont_have_many_to_many_association(:tags)
end

Parameters:

  • obj (Object)

    The object to test the association on

  • attribute (Symbol)

    The name of the association

  • msg (String) (defaults to: nil)

    Custom error message (optional)

Returns:

  • (Boolean)

    true if the assertion passes, raises an error otherwise



311
312
313
# File 'lib/minitest/sequel/associations.rb', line 311

def refute_association_many_to_many(obj, attribute, msg = nil)
  refute_association(obj.class, :many_to_many, attribute, msg)
end

#refute_association_many_to_one(obj, attribute, msg = nil) ⇒ Boolean

Test to ensure there is no :many_to_one association for the current model

This method asserts that the given object does not have a many-to-one association with the specified attribute.

Examples:

Testing that an object does not have a many-to-one association

let(:comment) { Comment.first }

it "does not have a many-to-one association with post" do
  refute_association_many_to_one(comment, :post)
end

Using expectation syntax

it "does not have a many-to-one association with post" do
  comment.wont_have_many_to_one_association(:post)
end

Parameters:

  • obj (Object)

    The object to test the association on

  • attribute (Symbol)

    The name of the association

  • msg (String) (defaults to: nil)

    Custom error message (optional)

Returns:

  • (Boolean)

    true if the assertion passes, raises an error otherwise



284
285
286
# File 'lib/minitest/sequel/associations.rb', line 284

def refute_association_many_to_one(obj, attribute, msg = nil)
  refute_association(obj.class, :many_to_one, attribute, msg)
end

#refute_association_one_to_many(obj, attribute, msg = nil) ⇒ Boolean

Test to ensure there is no :one_to_many association for the current model

This method asserts that the given object does not have a one-to-many association with the specified attribute.

Examples:

Testing that an object does not have a one-to-many association

let(:post) { Post.first }

it "does not have a one-to-many association with comments" do
  refute_association_one_to_many(post, :comments)
end

Using expectation syntax

it "does not have a one-to-many association with comments" do
  post.wont_have_one_to_many_association(:comments)
end

Parameters:

  • obj (Object)

    The object to test the association on

  • attribute (Symbol)

    The name of the association

  • msg (String) (defaults to: nil)

    Custom error message (optional)

Returns:

  • (Boolean)

    true if the assertion passes, raises an error otherwise



257
258
259
# File 'lib/minitest/sequel/associations.rb', line 257

def refute_association_one_to_many(obj, attribute, msg = nil)
  refute_association(obj.class, :one_to_many, attribute, msg)
end

#refute_association_one_to_one(obj, attribute, msg = nil) ⇒ Boolean

Test to ensure there is no :one_to_one association for the current model

This method asserts that the given object does not have a one-to-one association with the specified attribute.

Examples:

Testing that an object does not have a one-to-one association

let(:post) { Post.first }

it "does not have a one-to-one association with first_comment" do
  refute_association_one_to_one(post, :first_comment)
end

Using expectation syntax

it "does not have a one-to-one association with first_comment" do
  post.wont_have_one_to_one_association(:first_comment)
end

Parameters:

  • obj (Object)

    The object to test the association on

  • attribute (Symbol)

    The name of the association

  • msg (String) (defaults to: nil)

    Custom error message (optional)

Returns:

  • (Boolean)

    true if the assertion passes, raises an error otherwise



230
231
232
# File 'lib/minitest/sequel/associations.rb', line 230

def refute_association_one_to_one(obj, attribute, msg = nil)
  refute_association(obj.class, :one_to_one, attribute, msg)
end

#refute_have_column(obj, attribute, msg = nil) ⇒ Object

Asserts that a given model does not have a specific column

Examples:

refute_have_column(user, :admin_flag)

Parameters:

  • obj (Object)

    The model instance to check

  • attribute (Symbol)

    The name of the column to check for absence

  • msg (String, nil) (defaults to: nil)

    Optional custom error message



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/minitest/sequel/columns.rb', line 87

def refute_have_column(obj, attribute, msg = nil)
  # Prepare the error message
  msg = build_message_column(obj, attribute, msg, refute: true)

  # extract the column information from the database schema
  dbcol = extract_column_info(obj, attribute)

  # If the column is not found (dcol is nil), the test passes
  matching = dbcol.nil?

  # Return early if the test passes (column doesn't exist)
  return if matching

  # If we reach here, it means the column was found when it shouldn't be
  msg << ' but such a column was found'

  # Assert that matching is true (which it isn't at this point)
  # This will raise an assertion error with the prepared message
  assert(matching, msg)
end

#refute_paranoid_model(model) ⇒ Object

Test to ensure the current model is NOT a :paranoid model

This assertion checks if a given model class has NOT been configured with the Sequel Paranoid plugin. It verifies the absence of the plugin in the model’s list of plugins.

Examples:

Testing a non-paranoid model

class Post < Sequel::Model; end
it { refute_paranoid_model(Post) }

Testing a paranoid model (will fail)

class Comment < Sequel::Model
  plugin :paranoid
end
it { refute_paranoid_model(Comment) } # This will fail

Parameters:

  • model (Class)

    The model class to test

Raises:

  • (Minitest::Assertion)

    If the model class is configured with the Paranoid plugin



269
270
271
272
273
274
275
276
# File 'lib/minitest/sequel/plugins.rb', line 269

def refute_paranoid_model(model)
  plugs = model.instance_variable_get(:@plugins).map(&:to_s)

  msg = "RefuteParanoidModel - expected #{model} to NOT be a :paranoid model, but it was. "
  msg << "Debug: [#{plugs.inspect}]"

  refute_includes(plugs, 'Sequel::Plugins::Paranoid', msg)
end

#refute_timestamped_model(model, _opts = {}) ⇒ Object

Test to ensure the current model is NOT a :timestamped model

This assertion checks if a given model class has NOT been configured with the Sequel Timestamps plugin. It verifies the absence of the plugin in the model’s list of plugins.

Examples:

Testing a non-timestamped model

class Post < Sequel::Model; end
it { refute_timestamped_model(Post) }

Testing a timestamped model (will fail)

class Comment < Sequel::Model
  plugin :timestamps
end
it { refute_timestamped_model(Comment) } # This will fail

Parameters:

  • model (Class)

    The model class to test

  • _opts (Hash) (defaults to: {})

    Unused options parameter (kept for consistency with other methods)

Raises:

  • (Minitest::Assertion)

    If the model class is configured with the Timestamps plugin



240
241
242
243
244
245
246
247
# File 'lib/minitest/sequel/plugins.rb', line 240

def refute_timestamped_model(model, _opts = {})
  plugs = model.instance_variable_get(:@plugins).map(&:to_s)

  msg = "RefuteTimestampedModel - expected #{model} to NOT be a :timestamps model, but it was."
  msg << " Debug: [#{plugs.inspect}]"

  refute_includes(plugs, 'Sequel::Plugins::Timestamps', msg)
end

#refute_validates(obj, validation_type, attribute, _opts = {}, msg = nil) ⇒ Object

Base test for refuting validations of a model

This method checks if the specified attribute of the given object does not have the specified validation type. It is used as a foundation for other refutation assertions.

rubocop:disable Metrics/MethodLength

Examples:

Refuting presence validation

refute_validates(User.new, :presence, :name)

Refuting length validation with custom message

refute_validates(Post.new, :length, :title, {}, "Title should not have length validation")

Parameters:

  • obj (Object)

    The model object to test

  • validation_type (Symbol)

    The type of validation to check for absence

  • attribute (Symbol)

    The attribute to check for absence of validation

  • _opts (Hash) (defaults to: {})

    Additional options for the validation (unused in this method)

  • msg (String) (defaults to: nil)

    Custom error message (default: nil)

Raises:

  • (Minitest::Assertion)

    If the validation exists when it should not



898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
# File 'lib/minitest/sequel/validations.rb', line 898

def refute_validates(obj, validation_type, attribute, _opts = {}, msg = nil)
  msg = msg.nil? ? '' : "#{msg}\n"

  unless obj.respond_to?(attribute)
    assert(false, "Column :#{attribute} is not defined in #{obj.class}, so cannot be validated")
  end

  msg << "Expected #{obj.class} NOT to validate :#{attribute} with :#{validation_type}"
  if _validated_model?(obj)
    if _validated_column?(obj, attribute)
      msg << ", but the column :#{attribute} was validated with :#{validation_type}"
      assert(false, msg)
    else
      assert(true, msg)
    end
  else
    assert(false, "No validations defined in #{obj.class}")
  end
end

#refute_validates_acceptance(obj, attribute, opts = {}, msg = nil) ⇒ Object Also known as: refute_validates_acceptance_of

Note:

The acceptance validation is typically used for checkboxes in web forms where the user needs to accept terms of service. This method ensures that such validation is not present.

Test for refuting the acceptance validation of a model’s attribute.

This method checks if the specified attribute of the given object does not have an acceptance validation. It can be used in both assertion and expectation styles.

Examples:

Using assertion style

refute_validates_acceptance(Order.new, :toc, { message: 'should not require acceptance' })

Using expectation style

model.wont_validate_acceptance_of(:toc, { accept: 'yes' })

Parameters:

  • obj (Object)

    The model object to test

  • attribute (Symbol)

    The attribute to check for absence of acceptance validation

  • opts (Hash) (defaults to: {})

    Additional options for the validation (default: {})

  • msg (String) (defaults to: nil)

    Custom error message (default: nil)



839
840
841
# File 'lib/minitest/sequel/validations.rb', line 839

def refute_validates_acceptance(obj, attribute, opts = {}, msg = nil)
  refute_validates(obj, :acceptance, attribute, opts, msg)
end

#refute_validates_confirmation(obj, attribute, opts = {}, msg = nil) ⇒ Object Also known as: refute_validates_confirmation_of

Note:

The confirmation validation is typically used for password fields where the user needs to enter the same password twice. This method ensures that such validation is not present.

Test for refuting the confirmation validation of a model’s attribute.

This method checks if the specified attribute of the given object does not have a confirmation validation. It can be used in both assertion and expectation styles.

Examples:

Using assertion style

refute_validates_confirmation(
  User.new,
  :password,
  { message: 'should not require confirmation' }
)

Using expectation style

User.new.wont_validate_confirmation_of(
  :password,
  { message: 'should not require confirmation' }
)

Parameters:

  • obj (Object)

    The model object to test

  • attribute (Symbol)

    The attribute to check for absence of confirmation validation

  • opts (Hash) (defaults to: {})

    Additional options for the validation (default: {})

  • msg (String) (defaults to: nil)

    Custom error message (default: nil)



872
873
874
# File 'lib/minitest/sequel/validations.rb', line 872

def refute_validates_confirmation(obj, attribute, opts = {}, msg = nil)
  refute_validates(obj, :confirmation, attribute, opts, msg)
end

#refute_validates_exact_length(obj, attribute, exact_length, opts = {}, msg = nil) ⇒ Object Also known as: refute_validates_exact_length_of

Test for refuting the validation of exact length for a model’s attribute.

This method checks if the specified attribute of the given object does not have a length validation for an exact length. It can be used in both assertion and expectation styles.

Examples:

Using assertion style

refute_validates_exact_length(
  model,
  :title,
  12,
  { message: 'Must not be exactly 12 characters' }
)

Using expectation style

model.wont_validate_exact_length_of(
  :title,
  12,
  { message: 'Must not be exactly 12 characters' }
)

Parameters:

  • obj (Object)

    The model object to test

  • attribute (Symbol)

    The attribute to check for absence of exact length validation

  • exact_length (Integer)

    The exact length to validate against

  • opts (Hash) (defaults to: {})

    Additional options for the validation (default: {})

  • msg (String) (defaults to: nil)

    Custom error message (default: nil)



567
568
569
570
571
# File 'lib/minitest/sequel/validations.rb', line 567

def refute_validates_exact_length(obj, attribute, exact_length, opts = {}, msg = nil)
  # opts.merge!(is: exact_length)
  opts[:is] = exact_length
  refute_validates(obj, :length, attribute, opts, msg)
end

#refute_validates_format(obj, attribute, opts = {}, msg = nil) ⇒ Object Also known as: refute_validates_format_of

Test for refuting the format validation of a model’s attribute with a regexp.

This method checks if the specified attribute of the given object does not have a format validation with the provided regular expression. It can be used in both assertion and expectation styles.

Examples:

Using assertion style

refute_validates_format(model, :title, { with: /[a-z]+/ })

Using expectation style

model.wont_validate_format_of(:title, { with: /[a-z]+/ })

With custom error message

refute_validates_format(
  model,
  :title,
  { with: /[a-z]+/ },
  "Title should not have format validation"
)

Parameters:

  • obj (Object)

    The model object to test

  • attribute (Symbol)

    The attribute to check for absence of format validation

  • opts (Hash) (defaults to: {})

    Additional options for the validation (default: {})

  • msg (String) (defaults to: nil)

    Custom error message (default: nil)

Options Hash (opts):

  • :with (Regexp)

    The regular expression to validate against (required)



700
701
702
# File 'lib/minitest/sequel/validations.rb', line 700

def refute_validates_format(obj, attribute, opts = {}, msg = nil)
  refute_validates(obj, :format, attribute, opts, msg)
end

#refute_validates_inclusion(obj, attribute, opts = {}, msg = nil) ⇒ Object Also known as: refute_validates_inclusion_of

Test for refuting the inclusion validation of a model’s attribute.

This method checks if the specified attribute of the given object does not have an inclusion validation with the provided set of values. It can be used in both assertion and expectation styles.

Examples:

Using assertion style

refute_validates_inclusion(model, :status, { in: [:a, :b, :c] })

Using expectation style

model.wont_validate_inclusion_of(:status, { in: [:a, :b, :c] })

With custom error message

refute_validates_inclusion(
  model,
  :status,
  { in: [:a, :b, :c] },
  "Status should not be limited to these values"
)

Parameters:

  • obj (Object)

    The model object to test

  • attribute (Symbol)

    The attribute to check for absence of inclusion validation

  • opts (Hash) (defaults to: {})

    Additional options for the validation (default: {})

  • msg (String) (defaults to: nil)

    Custom error message (default: nil)

Options Hash (opts):

  • :in (Array, Range)

    The set of valid values (required)



732
733
734
# File 'lib/minitest/sequel/validations.rb', line 732

def refute_validates_inclusion(obj, attribute, opts = {}, msg = nil)
  refute_validates(obj, :inclusion, attribute, opts, msg)
end

#refute_validates_integer(obj, attribute, opts = {}, msg = nil) ⇒ Object

Test for refuting the validation that a model’s attribute is an integer.

This method checks if the specified attribute of the given object does not have an integer validation. It can be used in both assertion and expectation styles.

Examples:

Using assertion style

refute_validates_integer(model, :author_id, { message: 'must not be an integer' })

Using expectation style

model.wont_validate_integer_of(:author_id, { message: 'must not be an integer' })

Parameters:

  • obj (Object)

    The model object to test

  • attribute (Symbol)

    The attribute to check for absence of integer validation

  • opts (Hash) (defaults to: {})

    Additional options for the validation (default: {})

  • msg (String) (defaults to: nil)

    Custom error message (default: nil)



754
755
756
757
# File 'lib/minitest/sequel/validations.rb', line 754

def refute_validates_integer(obj, attribute, opts = {}, msg = nil)
  opts[:only_integer] = true
  refute_validates(obj, :numericality, attribute, opts, msg)
end

#refute_validates_length(obj, attribute, opts = {}, msg = nil) ⇒ Object Also known as: refute_validates_length_of

Test for refuting the length validation of a model’s attribute.

This method checks if the specified attribute of the given object does not have a length validation with the provided options. It can be used in both assertion and expectation styles.

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 if :maximum option is used and the value is nil (default: ‘is not present’)

:too_long

The message to use if the value is too long (default: ‘is too long’)

:too_short

The message to use if the value is too short (default: ‘is too short’)

:wrong_length

The message to use if 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)

Examples:

Using assertion style

refute_validates_length(model, :title, { maximum: 12 })

Using expectation style

model.wont_validate_length_of(:title, { within: 4..12 })

With custom error message

refute_validates_length(
  model,
  :title,
  { maximum: 12 },
  "Title should not have length validation"
)

Parameters:

  • obj (Object)

    The model object to test

  • attribute (Symbol)

    The attribute to check for absence of length validation

  • opts (Hash) (defaults to: {})

    Additional options for the validation (default: {})

  • msg (String) (defaults to: nil)

    Custom error message (default: nil)



535
536
537
# File 'lib/minitest/sequel/validations.rb', line 535

def refute_validates_length(obj, attribute, opts = {}, msg = nil)
  refute_validates(obj, :length, attribute, opts, msg)
end

#refute_validates_length_range(obj, attribute, range, opts = {}, msg = nil) ⇒ Object Also known as: refute_validates_length_range_of

Test for refuting the validation of length range for a model’s attribute.

This method checks if the specified attribute of the given object does not have a length validation within a specified range. It can be used in both assertion and expectation styles.

Examples:

Using assertion style

refute_validates_length_range(
  model,
  :title,
  4..12,
  { message: 'Title length must not be between 4 and 12 characters' }
)

Using expectation style

model.wont_validate_length_range_of(
  :title,
  4..12,
  { message: 'Title length must not be between 4 and 12 characters' }
)

Parameters:

  • obj (Object)

    The model object to test

  • attribute (Symbol)

    The attribute to check for absence of length range validation

  • range (Range)

    The range of lengths to validate against

  • opts (Hash) (defaults to: {})

    Additional options for the validation (default: {})

  • msg (String) (defaults to: nil)

    Custom error message (default: nil)



601
602
603
604
# File 'lib/minitest/sequel/validations.rb', line 601

def refute_validates_length_range(obj, attribute, range, opts = {}, msg = nil)
  opts[:within] = range
  refute_validates(obj, :length, attribute, opts, msg)
end

#refute_validates_max_length(obj, attribute, max_length, opts = {}, msg = nil) ⇒ Object Also known as: refute_validates_max_length_of

Test for refuting the maximum length validation of a model’s attribute.

This method checks if the specified attribute of the given object does not have a length validation with a maximum value. It can be used in both assertion and expectation styles.

Examples:

Using assertion style

refute_validates_max_length(
  model,
  :title,
  12,
  { message: 'Title should not have maximum length validation' }
)

Using expectation style

model.wont_validate_max_length_of(
  :title,
  12,
  { message: 'Title should not have maximum length validation' }
)

Parameters:

  • obj (Object)

    The model object to test

  • attribute (Symbol)

    The attribute to check for absence of maximum length validation

  • max_length (Integer)

    The maximum length to validate against

  • opts (Hash) (defaults to: {})

    Additional options for the validation (default: {})

  • msg (String) (defaults to: nil)

    Custom error message (default: nil)



634
635
636
637
# File 'lib/minitest/sequel/validations.rb', line 634

def refute_validates_max_length(obj, attribute, max_length, opts = {}, msg = nil)
  opts[:maximum] = max_length
  refute_validates(obj, :length, attribute, opts, msg)
end

#refute_validates_min_length(obj, attribute, min_length, opts = {}, msg = nil) ⇒ Object Also known as: refute_validates_min_length_of

Test for refuting the minimum length validation of a model’s attribute.

This method checks if the specified attribute of the given object does not have a length validation with a minimum value. It can be used in both assertion and expectation styles.

Examples:

Using assertion style

refute_validates_min_length(
  model,
  :title,
  12,
  { message: 'Title should not have minimum length validation' }
)

Using expectation style

model.wont_validate_min_length_of(
  :title,
  12,
  { message: 'Title should not have minimum length validation' }
)

Parameters:

  • obj (Object)

    The model object to test

  • attribute (Symbol)

    The attribute to check for absence of minimum length validation

  • min_length (Integer)

    The minimum length to validate against

  • opts (Hash) (defaults to: {})

    Additional options for the validation (default: {})

  • msg (String) (defaults to: nil)

    Custom error message (default: nil)



667
668
669
670
# File 'lib/minitest/sequel/validations.rb', line 667

def refute_validates_min_length(obj, attribute, min_length, opts = {}, msg = nil)
  opts[:minimum] = min_length
  refute_validates(obj, :length, attribute, opts, msg)
end

#refute_validates_numericality(obj, attribute, opts = {}, msg = nil) ⇒ Object Also known as: refute_validates_numericality_of

Test for refuting the numericality validation of a model’s attribute.

This method checks if the specified attribute of the given object does not have a numericality validation. It can be used in both assertion and expectation styles.

Examples:

Using assertion style

refute_validates_numericality(model, :price, { greater_than: 0 })

Using expectation style

model.wont_validate_numericality_of(:price, { less_than_or_equal_to: 1000 })

With custom error message

refute_validates_numericality(
  model,
  :quantity,
  { only_integer: true, message: 'must not be a number' }
)

Parameters:

  • obj (Object)

    The model object to test

  • attribute (Symbol)

    The attribute to check for absence of numericality validation

  • opts (Hash) (defaults to: {})

    Additional options for the validation (default: {})

  • msg (String) (defaults to: nil)

    Custom error message (default: nil)



783
784
785
# File 'lib/minitest/sequel/validations.rb', line 783

def refute_validates_numericality(obj, attribute, opts = {}, msg = nil)
  refute_validates(obj, :numericality, attribute, opts, msg)
end

#refute_validates_presence(obj, attribute, opts = {}, msg = nil) ⇒ Object Also known as: refute_validates_presence_of

Test for refuting the presence validation of a model attribute

This method checks if the specified attribute of the given object does not have a presence validation. It can be used in both assertion and expectation styles.

Examples:

Using assertion style

refute_validates_presence(model, :title)

Using expectation style

model.wont_validate_presence_of(:title)

With custom error message

refute_validates_presence(model, :title, {}, "Title should not have presence validation")

Parameters:

  • obj (Object)

    The model object to test

  • attribute (Symbol)

    The attribute to check for absence of presence validation

  • opts (Hash) (defaults to: {})

    Additional options for the validation (default: {})

  • msg (String) (defaults to: nil)

    Custom error message (default: nil)



486
487
488
# File 'lib/minitest/sequel/validations.rb', line 486

def refute_validates_presence(obj, attribute, opts = {}, msg = nil)
  refute_validates(obj, :presence, attribute, opts, msg)
end

#refute_validates_uniqueness(obj, attribute, opts = {}, msg = nil) ⇒ Object Also known as: refute_validates_uniqueness_of

Test for refuting the uniqueness validation of a model’s attribute.

This method checks if the specified attribute of the given object does not have a uniqueness validation. It can be used in both assertion and expectation styles.

Examples:

Using assertion style

refute_validates_uniqueness(model, :urlslug, { message: 'should not be unique' })

Using expectation style

model.wont_validate_uniqueness_of(:urlslug, { case_sensitive: false })

With custom error message

refute_validates_uniqueness(
  model,
  :email,
  { scope: :account_id },
  "Email should not be unique within an account"
)

Parameters:

  • obj (Object)

    The model object to test

  • attribute (Symbol)

    The attribute to check for absence of uniqueness validation

  • opts (Hash) (defaults to: {})

    Additional options for the validation (default: {})

  • msg (String) (defaults to: nil)

    Custom error message (default: nil)



813
814
815
# File 'lib/minitest/sequel/validations.rb', line 813

def refute_validates_uniqueness(obj, attribute, opts = {}, msg = nil)
  refute_validates(obj, :uniqueness, attribute, opts, msg)
end