module Minitest::Assertions
reopening to add additional functionality
reopening to add association functionality
reopening to add schema validation functionality
reopening to add validations functionality
reopening to add validations functionality
Public Instance Methods
Test for associations for the current model by passing the :association_type
it { assert_association(Post, :many_to_many, :tags) }
# 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
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) }
# 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
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) }
# 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
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) }
# 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
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 }) }
# 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
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.
# 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
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: "e@email.com"}) }.wont_have_error
# 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
# File lib/minitest/sequel/validations.rb, line 404 def assert_raises_validation_failed(obj) assert_raises(::Sequel::ValidationFailed) { obj.save } end
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: "e@email.com"}) }.wont_have_error
# 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
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/)
# 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
Base test for validations of a model, used mainly as a shortcut for other assertions
# 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
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: '...' }) }
# 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
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: '...' }) }
# 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
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: '...' }) }
# 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
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]+/ }) }
# 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
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] }) }
# 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
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: '...' }) }
# 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
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 }) }
# 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
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: '...' }) }
# 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
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: '...' }) }
# 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
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: '...' }) }
# 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
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: '...' }) }
# 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
Test for validating presence of a model attribute
it { assert_validates_presence(model, :title) } it { model.must_validate_presence_of(:title, { message: '...' }) }
# 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
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: '...' }) }
# 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
Test to ensure the current model does NOT have an association by type :association_type
it { refute_association(Post, :many_to_many, :tags) }
# 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
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) }
# 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
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) }
# 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
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) }
# 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
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 }) }
# 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
# 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
Test to ensure the current model is NOT a :paranoid model
it { refute_paranoid_model(Post) }
# 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
Test to ensure the current model is NOT a :timestamped model
it { refute_timestamped_model(Post) }
# 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
Base test for validations of a model, used mainly as a shortcut for other assertions
# 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
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: '...' }) }
# 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
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: '...' }) }
# 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
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: '...' }) }
# 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
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]+/ }) }
# 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
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] }) }
# 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
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: '...' }) }
# 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
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 }) }
# 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
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: '...' }) }
# 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
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: '...' }) }
# 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
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: '...' }) }
# 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
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: '...' }) }
# 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
Test for validating presence of a model attribute
it { refute_validates_presence(model, :title) } it { model.must_validate_presence_of(:title, { message: '...' }) }
# 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
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: '...' }) }
# 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
Private Instance Methods
# File lib/minitest/sequel/validations.rb, line 452 def _available_validation_options [ :message, :if, :is, :in, :allow_blank, :allow_missing, :allow_nil, :accept, :with, :within, :only_integer, :maximum, :minimum, :nil_message, :too_long, :too_short, :wrong_length ] end
# File lib/minitest/sequel/validations.rb, line 447 def _available_validation_types [:format, :length, :presence, :numericality, :confirmation, :acceptance, :inclusion, :uniqueness] end
handles converting `:nil`, `:false` values
# File lib/minitest/sequel.rb, line 12 def _convert_value(val) v = case val when :nil then nil when :false then false when :true then true else val end v end
# File lib/minitest/sequel/validations.rb, line 460 def _valid_validation_options(type = nil) arr = [:message] case type.to_sym when :each # validates_each (*atts, &block) # Adds a validation for each of the given attributes using the supplied block. [:allow_blank, :allow_missing, :allow_nil].each { |a| arr << a } when :acceptance # The value required for the object to be valid (default: '1') arr << :accept when :format # The regular expression to validate the value with (required). arr << :with when :inclusion # An array or range of values to check for validity (required) arr << :in when :numericality # Whether only integers are valid values (default: false) arr << :only_integer when :length # # :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 # :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) [:is, :maximum, :minimum, :nil_message, :too_long, :too_short, :within, :wrong_length].each { |a| arr << a } else arr end unless type.nil? arr end
# File lib/minitest/sequel/validations.rb, line 428 def _validated_column?(model, attribute) return false unless _validated_model?(model) model.class.validation_reflections.keys.include?(attribute.to_sym) end
# File lib/minitest/sequel/validations.rb, line 423 def _validated_model?(model) (model.class.respond_to?(:has_validations?) && model.class.has_validations?) end
# File lib/minitest/sequel/validations.rb, line 434 def _validated_with_validation_type?(model, attribute, validation_type) return false unless _validated_column?(model, attribute) _validation_types_hash_for_column(model, attribute).keys.include?(validation_type) end
# File lib/minitest/sequel/validations.rb, line 440 def _validation_types_hash_for_column(model, attribute) h = {} model.class.validation_reflections[attribute].each { |c| h[c[0]] = c[1] } h end