Module: Minitest::Assertions

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

Overview

reopening to add additional functionality

Instance Method Summary collapse

Instance Method Details

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

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

it { assert_association(Post, :many_to_many, :tags) }


54
55
56
57
58
59
60
61
62
63
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
90
91
92
93
94
95
96
97
98
# File 'lib/minitest/sequel/associations.rb', line 54

def assert_association(klass, association_type, attribute, opts = {}, msg = nil)
  msg = msg.nil? ? "" : "#{msg}\n"
  msg << "Expected #{klass.inspect} to have a #{association_type.inspect}"
  msg << " association #{attribute.inspect}"
  assoc = klass.association_reflection(attribute) || {}
  if assoc.empty?
    msg << " but no association '#{attribute.inspect}' was found"
    arr = []
    klass.associations.each do |a|
      o = klass.association_reflection(a)
      if o[:type] == :many_to_many
        arr << {
          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
        arr << {
          attribute:  o[:name],
          type:       o[:type],
          class:      o[:class_name].to_s,
          keys:       o[:keys]
        }
      end
    end
    msg << " - \navailable associations are: [ #{arr.join(', ')} ]\n"
    assert(false, msg)
  else
    matching = assoc[:type] == association_type
    err_msg = []
    conf_msg = []
    opts.each do |key, value|
      conf_msg << { key => value }
      if assoc[key] != value
        err_msg << { key => assoc[key].to_s }
        matching = false
      end
    end
    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) ⇒ Object

Test for a :many_to_many association for the current model

let(:m) { Post.first }

it { assert_association_many_to_many(m, :tags) }
it { m.must_have_many_to_many_association(:tags) }


46
47
48
# File 'lib/minitest/sequel/associations.rb', line 46

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) ⇒ Object

Test for a :many_to_one association for the current model

let(:m) { Post.first }

it { assert_association_many_to_one(m, :author) }
it { m.must_have_many_to_one_association(:author) }


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

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) ⇒ Object

Test for a :one_to_many association for the current model

let(:m) { Post.first }

it { assert_association_one_to_many(m, :comments) }
it { m.must_have_one_to_many_association(:comments) }


24
25
26
# File 'lib/minitest/sequel/associations.rb', line 24

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) ⇒ Object

Test for a :one_to_one association for the current model

let(:m) { Post.first }

it { assert_association_one_to_one(m, :first_comment, { class: :Comment, order: :id }) }
it { m.must_have_one_to_one_association(:first_comment, { class: :Comment, order: :id }) }


13
14
15
# File 'lib/minitest/sequel/associations.rb', line 13

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

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

Conveniently test your Model definitions as follows:

let(:m) { Post.first }

it { assert_have_column(m, :title, type: :string, db_type: 'varchar(250)') }
it { m.must_have_column(:title, type: :string, db_type: 'varchar(250)') }

# assert_have_column(<instance>, <column_name>, <options>, <custom_error_message>)

# <instance>.must_have_column(<column_name>, <options>, <custom_error_message>)

‘assert_have_column()` 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)' }

**Please NOTE!**

To test options with a value that is either ‘nil`, `true` or `false`, please use `:nil`, `:false` or `:true` and provide numbers as ’strings’ instead.



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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
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
139
# File 'lib/minitest/sequel/columns.rb', line 43

def assert_have_column(obj, attribute, opts = {}, msg = nil)
  msg = msg.nil? ? "" : "#{msg}\n"
  msg << "Expected #{obj.class} model to have column: :#{attribute}"
  err_msg  = []
  conf_msg = []
  # check if column exists
  dcol = obj.db.schema(obj.class.table_name).detect { |c| c[0] == attribute }
  matching = !dcol.nil?

  # bail out if no matching column
  unless matching
    msg << " but no such column exists"
    assert(false, msg)
  end

  # bail out if options provided are invalid
  val_opts = [:type, :db_type, :allow_null, :max_length, :default, :primary_key, :auto_increment]
  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

  # TODO: simplify this mess. quick fix didn't work, so look at it again when time permits.

  unless opts[:type].nil?
    expected = (dcol[1][:type].to_s == opts[:type].to_s)
    conf_msg << "type: '#{opts[:type]}'"
    unless expected
      err_msg << "type: '#{dcol[1][:type]}'"
    end
    matching &&= expected
  end

  unless opts[:db_type].nil?
    expected = (dcol[1][:db_type].to_s == opts[:db_type].to_s)
    conf_msg << "db_type: '#{opts[:db_type]}'"
    unless expected
      err_msg << "db_type: '#{dcol[1][:db_type]}'"
    end
    matching &&= expected
  end

  unless opts[:max_length].nil?
    expected = (dcol[1][:max_length] === opts[:max_length])
    conf_msg << "max_length: '#{opts[:max_length]}'"
    unless expected
      err_msg << "max_length: '#{dcol[1][:max_length]}'"
    end
    matching &&= expected
  end

  unless opts[:allow_null].nil?
    v = _convert_value(opts[:allow_null])
    expected = (dcol[1][:allow_null] === v)
    conf_msg << "allow_null: '#{opts[:allow_null]}'"
    unless expected
      err_msg << "allow_null: '#{dcol[1][:allow_null]}'"
    end
    matching &&= expected
  end

  unless opts[:default].nil?
    v = _convert_value(opts[:default])
    expected = (dcol[1][:default] === v)
    conf_msg << "default: '#{opts[:default]}'"
    unless expected
      err_msg << "default: '#{dcol[1][:default].inspect}'"
    end
    matching &&= expected
  end

  unless opts[:primary_key].nil?
    v = _convert_value(opts[:primary_key])
    expected = (dcol[1][:primary_key] === v)
    conf_msg << "primary_key: '#{opts[:primary_key]}'"
    unless expected
      err_msg << "primary_key: '#{dcol[1][:primary_key]}'"
    end
    matching &&= expected
  end

  unless opts[:auto_increment].nil?
    v = _convert_value(opts[:auto_increment])
    expected = (dcol[1][:auto_increment] === v)
    conf_msg << "auto_increment: '#{opts[:auto_increment]}'"
    unless expected
      err_msg << "auto_increment: '#{dcol[1][:auto_increment]}'"
    end
    matching &&= expected
  end

  msg = msg << " with: { #{conf_msg.join(', ')} } but found: { #{err_msg.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)

   # Declared locally in the Model
   class Comment < Sequel::Model
     plugin(:paranoid)
   end
   proc { assert_paranoid_model(Comment) }.wont_have_error

   # on a non-paranoid model
   class Post < Sequel::Model; end
   proc { assert_paranoid_model(Post) }.must_have_error(/Not a plugin\(:paranoid\) model, available plugins are/)

NOTE!

You can also pass attributes to the created model in the tests via the `opts` hash like this:

   proc { assert_timestamped_model(Comment, {body: "I think...", email: "[email protected]"}) }.wont_have_error


114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/minitest/sequel/plugins.rb', line 114

def assert_paranoid_model(model, opts = {})
  m = model.create(opts)
  # 1. test for Paranoid plugin
  plugs = model.instance_variable_get("@plugins").map(&:to_s)
  if plugs.include?("Sequel::Plugins::Paranoid")
    assert_nil(m.deleted_at, "AssertParanoidModel:deleted_at - expected #deleted_at to be NIL on new model")
    # after update
    assert(m.save, "AssertParanoidModel:save - updated model failed. Debug: [#{m.inspect}]")
    assert_nil(m.deleted_at, "AssertParanoidModel:deleted_at - expected #deleted_at to be NIL on updated model")
    # after destroy
    assert(m.destroy, "AssertParanoidModel:destroy - destroy model failed. Debug: [#{m.inspect}]")
    assert_instance_of(Time, m.deleted_at, "AssertParanoidModel:deleted_at - expected #deleted_at to be instance of Time on destroyed model, Debug: [#{m.inspect}]")
  else
    raise(Minitest::Assertion, "Not a plugin(:paranoid) model, available plugins are: #{plugs.inspect}")
  end
end

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



404
405
406
# File 'lib/minitest/sequel/validations.rb', line 404

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)

   # Declared locally in the Model
   class Comment < Sequel::Model
     plugin(:timestamps)
   end
   proc { assert_timestamped_model(Comment) }.wont_have_error

   # on a non-timestamped model
   class Post < Sequel::Model; end
   proc { assert_timestamped_model(Post) }.must_have_error(/Not a \.plugin\(:timestamps\) model, available plugins are/)

NOTE!

You can also pass attributes to the created model in the tests via the `opts` hash like this:

   proc { assert_timestamped_model(Comment, {body: "I think...", email: "[email protected]"}) }.wont_have_error


68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/minitest/sequel/plugins.rb', line 68

def assert_timestamped_model(model, opts = {})
  m = model.create(opts)
  # 1. test for Timestamps plugin
  plugs = model.instance_variable_get("@plugins").map(&:to_s)
  if plugs.include?("Sequel::Plugins::Timestamps")
    # 2. test for created_at / :updated_at columns
    assert_have_column(m, :created_at, {}, "AssertTimestampedModel - expected model to have column :created_at. Debug: [#{m.inspect}]")
    assert_have_column(m, :updated_at, {}, "AssertTimestampedModel - expected model to have column :updated_at. Debug: [#{m.inspect}]")

    # 3.  initial record
    assert_instance_of(Time, m.created_at, "AssertTimestampedModel:created_at - expected #created_at to be an instance of Time on new record. Debug: [#{m.inspect}]")
    assert_instance_of(NilClass, m.updated_at, "AssertTimestampedModel:updated_at - expected #updated_at to be an instance of NilClass on new record. Debug: [#{m.inspect}]")

    # 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}]")
    assert_instance_of(Time, m.created_at, "AssertTimestampedModel:created_at - expected #created_at to be an instance of Time on updated record. Debug: [#{m.inspect}]")
    assert_instance_of(Time, m.updated_at, "AssertTimestampedModel:updated_at - expected #updated_at to be an instance of Time on updated record. Debug: [#{m.inspect}]")
    # assert_equal(old_ts, m.created_at, "AssertTimestampedModel - expected the :created_at timestamp to be unchanged")
  else
    raise(Minitest::Assertion, "Not a plugin(:timestamps) model, available plugins are: #{plugs.inspect}")
  end
end

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

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

let(:m) { Post.create(title: "Dummy") }
proc { assert_timestamped_model_instance(m) }.wont_have_error

You can also test if an updated record is correctly timestamped

m.title = "Updated"
m.save
proc { assert_timestamped_model_instance(m, updated_record: true) }.wont_have_error

Or alternatively test if an updated record is wrongly timestamped

let(:m) { Post.create(title: "Dummy", updated_at: Time.now) }
proc { assert_timestamped_model_instance(m, updated_record: false) }.must_have_error(/expected #.updated_at to be NIL on new record/)


23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/minitest/sequel/plugins.rb', line 23

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)
  if plugs.include?("Sequel::Plugins::Timestamps")
    # 2. test for created_at / :updated_at columns
    assert_have_column(model, :created_at, {}, "AssertTimestampedModelInstance - expected model to have column :created_at, Debug: [#{model.inspect}]")
    assert_have_column(model, :updated_at, {}, "AssertTimestampedModelInstance - expected model to have column :updated_at, Debug: [#{model.inspect}]")

    if opts[:updated_record]
      # 4. updated record
      assert_instance_of(Time, model.created_at, "AssertTimestampedModelInstance:created_at - expected #created_at to be an instance of Time on updated record")
      assert_instance_of(Time, model.updated_at, "AssertTimestampedModelInstance:updated_at - expected #updated_at to be an instance of Time on updated record")
    else
      # 3.  initial record
      assert_instance_of(Time, model.created_at, "AssertTimestampedModelInstance:created_at - expected #created_at to be an instance of Time on new record")
      proc {
        assert_nil(model.updated_at, "AssertTimestampedModelInstance:updated - expected #updated_at to be NIL on new record")
      }.wont_have_error
    end
  else
    raise(Minitest::Assertion, "Not a plugin(:timestamps) model, available plugins are: #{plugs.inspect}")
  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



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
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/minitest/sequel/validations.rb', line 165

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|
          unless opts[ov].nil?
            expected = (h[validation_type][ov].to_s == opts[ov].to_s)
              conf_msg << "#{ov}: '#{opts[ov]}'"
            unless expected
              err_msg << "#{ov}: '#{h[validation_type][ov]}'"
            end
            matching &&= expected
          end
        end

        msg = 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

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

it { assert_validates_acceptance(Order.new, :toc, { message: '...' }) }
it { model.must_validate_acceptance_of(:toc, { message: '...' }) }


149
150
151
# File 'lib/minitest/sequel/validations.rb', line 149

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

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

it { assert_validates_confirmation(User.new, :password, { message: '...' }) }
it { User.new.must_validate_confirmation_of(:password, { message: '...' }) }


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

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.

it { assert_validates_exact_length(model, :title, 12, { message: '...' }) }
it { model.must_validate_exact_length_of(:title, 12, { message: '...' }) }


53
54
55
56
# File 'lib/minitest/sequel/validations.rb', line 53

def assert_validates_exact_length(obj, attribute, exact_length, opts = {}, msg = nil)
  opts.merge!(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.

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


97
98
99
# File 'lib/minitest/sequel/validations.rb', line 97

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.

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


107
108
109
# File 'lib/minitest/sequel/validations.rb', line 107

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 a model’s attribute is an integer.

it { assert_validates_integer(model, :author_id, { message: '...' }) }
it { model.must_validate_integer_of(:author_id, { message: '...' }) }


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

def assert_validates_integer(obj, attribute, opts = {}, msg = nil)
  opts.merge!(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.

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)

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


43
44
45
# File 'lib/minitest/sequel/validations.rb', line 43

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 exact length of a model’s attribute.

it { assert_validates_length_range(model, :title, 4..12, { message: '...' }) }
it { model.must_validate_length_range_of(:title, 4..12, { message: '...' }) }


64
65
66
67
# File 'lib/minitest/sequel/validations.rb', line 64

def assert_validates_length_range(obj, attribute, range, opts = {}, msg = nil)
  opts.merge!(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.

it { assert_validates_max_length(model, :title, 12, { message: '...' }) }
it { model.must_validate_max_length_of(:title, 12, { message: '...' }) }


75
76
77
78
# File 'lib/minitest/sequel/validations.rb', line 75

def assert_validates_max_length(obj, attribute, max_length, opts = {}, msg = nil)
  opts.merge!(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.

it { assert_validates_min_length(model, :title, 12, { message: '...' }) }
it { model.must_validate_min_length_of(:title, 12, { message: '...' }) }


86
87
88
89
# File 'lib/minitest/sequel/validations.rb', line 86

def assert_validates_min_length(obj, attribute, min_length, opts = {}, msg = nil)
  opts.merge!(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).

it { assert_validates_numericality(model, :author_id, { message: '...' }) }
it { model.must_validate_numericality_of(:author_id, { message: '...' }) }


127
128
129
# File 'lib/minitest/sequel/validations.rb', line 127

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

it { assert_validates_presence(model, :title) }
it { model.must_validate_presence_of(:title, { message: '...' }) }


11
12
13
# File 'lib/minitest/sequel/validations.rb', line 11

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.

it { assert_validates_uniqueness(model, :urlslug, { message: '...' }) }
it { model.must_validate_uniqueness_of(:urlslug, { message: '...' }) }


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

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) ⇒ Object

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

it { refute_association(Post, :many_to_many, :tags) }


149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/minitest/sequel/associations.rb', line 149

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) ⇒ Object

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

let(:m) { Post.first }

it { refute_association_many_to_many(m, :tags) }
it { m.must_have_many_to_many_association(:tags) }


141
142
143
# File 'lib/minitest/sequel/associations.rb', line 141

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) ⇒ Object

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

let(:m) { Post.first }

it { refute_association_many_to_one(m, :author) }
it { m.must_have_many_to_one_association(:author) }


130
131
132
# File 'lib/minitest/sequel/associations.rb', line 130

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) ⇒ Object

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

let(:m) { Post.first }

it { refute_association_one_to_many(m, :comments) }
it { m.must_have_one_to_many_association(:comments) }


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

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) ⇒ Object

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

let(:m) { Post.first }

it { refute_association_one_to_one(m, :first_comment, { class: :Comment, order: :id }) }
it { m.must_have_one_to_one_association(:first_comment, { class: :Comment, order: :id }) }


108
109
110
# File 'lib/minitest/sequel/associations.rb', line 108

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



142
143
144
145
146
147
148
149
150
151
152
# File 'lib/minitest/sequel/columns.rb', line 142

def refute_have_column(obj, attribute, msg = nil)
  msg = msg.nil? ? "" : "#{msg}\n"
  msg << "Expected #{obj.class} model to NOT have column: :#{attribute}"
  # check if column exists
  dcol = obj.db.schema(obj.class.table_name).detect { |col| col[0] == attribute }
  matching = dcol.nil?
  unless matching
    msg << " but such a column was found"
    assert(matching, msg)
  end
end

#refute_paranoid_model(model) ⇒ Object

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

it { refute_paranoid_model(Post) }


146
147
148
149
# File 'lib/minitest/sequel/plugins.rb', line 146

def refute_paranoid_model(model)
  plugs = model.instance_variable_get("@plugins").map(&:to_s)
  refute_includes(plugs, "Sequel::Plugins::Paranoid", "RefuteParanoidModel - expected #{model} to NOT be a :paranoid model, but it was, Debug: [#{plugs.inspect}]")
end

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

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

it { refute_timestamped_model(Post) }


137
138
139
140
# File 'lib/minitest/sequel/plugins.rb', line 137

def refute_timestamped_model(model, opts = {})
  plugs = model.instance_variable_get("@plugins").map(&:to_s)
  refute_includes(plugs, "Sequel::Plugins::Timestamps", "RefuteTimestampedModel - expected #{model} to NOT be a :timestamped model, but it was, Debug: [#{plugs.inspect}]")
end

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

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



385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
# File 'lib/minitest/sequel/validations.rb', line 385

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

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

it { refute_validates_acceptance(Order.new, :toc, { message: '...' }) }
it { model.must_validate_acceptance_of(:toc, { message: '...' }) }


369
370
371
# File 'lib/minitest/sequel/validations.rb', line 369

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

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

it { refute_validates_confirmation(User.new, :password, { message: '...' }) }
it { User.new.must_validate_confirmation_of(:password, { message: '...' }) }


379
380
381
# File 'lib/minitest/sequel/validations.rb', line 379

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 validating the exact length of a model’s attribute.

it { refute_validates_exact_length(model, :title, 12, { message: '...' }) }
it { model.must_validate_exact_length_of(:title, 12, { message: '...' }) }


273
274
275
276
# File 'lib/minitest/sequel/validations.rb', line 273

def refute_validates_exact_length(obj, attribute, exact_length, opts = {}, msg = nil)
  opts.merge!(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 validating the format of a model’s attribute with a regexp.

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


317
318
319
# File 'lib/minitest/sequel/validations.rb', line 317

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 validating that a model’s attribute is within a specified range or set of values.

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


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

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 validating that a a model’s attribute is an integer.

it { refute_validates_integer(model, :author_id, { message: '...' }) }
it { model.must_validate_integer_of(:author_id, { message: '...' }) }


337
338
339
340
# File 'lib/minitest/sequel/validations.rb', line 337

def refute_validates_integer(obj, attribute, opts = {}, msg = nil)
  opts.merge!(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 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)
it { refute_validates_length(model, :title, { maximum: 12 }) }
it { model.must_validate_length_of(:title, { within: 4..12 }) }


263
264
265
# File 'lib/minitest/sequel/validations.rb', line 263

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 validating the exact length of a model’s attribute.

it { refute_validates_length_range(model, :title, 4..12, { message: '...' }) }
it { model.must_validate_length_range_of(:title, 4..12, { message: '...' }) }


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

def refute_validates_length_range(obj, attribute, range, opts = {}, msg = nil)
  opts.merge!(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 validating the maximum length of a model’s attribute.

it { refute_validates_max_length(model, :title, 12, { message: '...' }) }
it { model.must_validate_max_length_of(:title, 12, { message: '...' }) }


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

def refute_validates_max_length(obj, attribute, max_length, opts = {}, msg = nil)
  opts.merge!(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 validating the minimum length of a model’s attribute.

it { refute_validates_min_length(model, :title, 12, { message: '...' }) }
it { model.must_validate_min_length_of(:title, 12, { message: '...' }) }


306
307
308
309
# File 'lib/minitest/sequel/validations.rb', line 306

def refute_validates_min_length(obj, attribute, min_length, opts = {}, msg = nil)
  opts.merge!(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 validating that a model’s attribute is numeric (number).

it { refute_validates_numericality(model, :author_id, { message: '...' }) }
it { model.must_validate_numericality_of(:author_id, { message: '...' }) }


347
348
349
# File 'lib/minitest/sequel/validations.rb', line 347

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 validating presence of a model attribute

it { refute_validates_presence(model, :title) }
it { model.must_validate_presence_of(:title, { message: '...' }) }


229
230
231
# File 'lib/minitest/sequel/validations.rb', line 229

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 validating that a model’s attribute is unique.

it { refute_validates_uniqueness(model, :urlslug, { message: '...' }) }
it { model.must_validate_uniqueness_of(:urlslug, { message: '...' }) }


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

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