You can use this matcher like so:
RSpec.describe User, type: :model do
it { is_expected.to validate_not_nil(:favorite_numbers) }
endYou can use this matcher like so:
RSpec.describe User, type: :model do
it { is_expected.to validate_not_nil(:favorite_numbers) }
end| # do this, or just uncomment the line that requires support files | |
| require_relative 'support/matchers/validate_not_nil_matcher' | |
| RSpec.configure do |config| | |
| config.include Matchers, type: :model | |
| end |
| # spec/support/matchers/validate_not_nil_matcher.rb | |
| module Matchers | |
| def validate_not_nil(attribute_name) | |
| ValidateNotNilMatcher.new(attribute_name) | |
| end | |
| class ValidateNotNilMatcher | |
| def initialize(attribute_name) | |
| @attribute_name = attribute_name | |
| @submatchers = [ | |
| disallow_value(nil).for(attribute_name), | |
| allow_value([]).for(attribute_name), | |
| allow_value(["something"]).for(attribute_name) | |
| ] | |
| end | |
| def matches?(record) | |
| @record = record | |
| first_failing_submatcher.nil? | |
| end | |
| def does_not_match?(record) | |
| @record = record | |
| first_passing_submatcher.nil? | |
| end | |
| def failure_message | |
| first_failing_submatcher.failure_message | |
| end | |
| def failure_message_when_negated | |
| first_passing_submatcher.failure_message_when_negated | |
| end | |
| private | |
| attr_reader :attribute_name, :submatchers, :record | |
| def allow_value(value) | |
| # Using this class like this is the same as using the `allow_value` matcher. | |
| Shoulda::Matchers::ActiveModel::AllowValueMatcher.new(value) | |
| end | |
| def disallow_value(value) | |
| # The gem doesn't ship with a `disallow_value` matcher, but it does have a | |
| # complement to AllowValueMatcher which such a matcher would probably use, | |
| # if it did exist. Technically this is a private API, but I don't plan on | |
| # removing this any time soon. | |
| Shoulda::Matchers::ActiveModel::DisallowValueMatcher.new(value) | |
| end | |
| def first_failing_submatcher | |
| @first_failing_submatcher ||= submatchers.find do |submatcher| | |
| !submatcher.matches?(record) | |
| end | |
| end | |
| def first_passing_submatcher | |
| @first_passing_submatcher ||= submatchers.find do |submatcher| | |
| !submatcher.does_not_match?(record) | |
| end | |
| end | |
| end | |
| end |