class RSpec::SleepingKingStudios::Matchers::Core::HaveConstantMatcher

Matcher for testing whether an object has a specific constant. Includes functionality for testing the value of the constant and whether the constant is immutable.

@since 2.2.0

Public Class Methods

new(expected) click to toggle source

@param [String, Symbol] expected The name of the constant to check for on

the actual object.
# File lib/rspec/sleeping_king_studios/matchers/core/have_constant_matcher.rb, line 16
def initialize expected
  @expected = expected.intern
end

Public Instance Methods

description() click to toggle source

(see BaseMatcher#description)

# File lib/rspec/sleeping_king_studios/matchers/core/have_constant_matcher.rb, line 21
def description
  message =
    "have #{@immutable ? 'immutable ' : ''}constant #{@expected.inspect}"

  message << ' with value ' << value_to_string if @value_set

  message
end
does_not_match?(actual) click to toggle source

(see BaseMatcher#does_not_match?)

# File lib/rspec/sleeping_king_studios/matchers/core/have_constant_matcher.rb, line 31
def does_not_match? actual
  super

  @errors = {}

  !has_constant?
end
failure_message() click to toggle source

(see BaseMatcher#failure_message)

# File lib/rspec/sleeping_king_studios/matchers/core/have_constant_matcher.rb, line 40
def failure_message
  message = super

  messages = []

  if @errors[:does_not_define_constants]
    message <<
      ", but #{@actual.inspect} does not respond to ::const_defined?"

    return message
  end # if

  if @errors[:constant_is_not_defined]
    message <<
      ", but #{@actual.inspect} does not define constant #{@expected.inspect}"

    return message
  end # if

  if hsh = @errors[:value_does_not_match]
    messages <<
      "constant #{@expected.inspect} has value #{hsh[:received].inspect}"
  end # if

  if hsh = @errors[:value_is_mutable]
    messages <<
      "the value of #{@expected.inspect} was mutable"
  end # if

  unless messages.empty?
    tools = ::SleepingKingStudios::Tools::ArrayTools

    message << ', but ' << tools.humanize_list(messages)
  end # unless

  message
end
failure_message_when_negated() click to toggle source

(see BaseMatcher#failure_message_when_negated)

# File lib/rspec/sleeping_king_studios/matchers/core/have_constant_matcher.rb, line 79
def failure_message_when_negated
  message = super

  message <<
    ", but #{@actual.inspect} defines constant #{@expected.inspect} with "\
    "value #{actual.const_get(@expected).inspect}"

  message
end
frozen()
Alias for: immutable
frozen?()
Alias for: immutable?
immutable() click to toggle source

Sets a mutability expectation. The matcher will determine whether the value of the constant is mutable. Values of ‘nil`, `false`, `true` are always immutable, as are `Numeric` and `Symbol` primitives. `Array` values must be frozen and all array items must be immutable. `Hash` values must be frozen and all hash keys and values must be immutable.

@return [HaveConstantMatcher] self

# File lib/rspec/sleeping_king_studios/matchers/core/have_constant_matcher.rb, line 96
def immutable
  @immutable = true

  self
end
Also aliased as: frozen
immutable?() click to toggle source

@return [Boolean] True if a mutability expectation is set, otherwise

false.
# File lib/rspec/sleeping_king_studios/matchers/core/have_constant_matcher.rb, line 105
def immutable?
  !!@immutable
end
Also aliased as: frozen?
matches?(actual) click to toggle source

Checks if the object has a constant :expected. Additionally, if a value expectation is set, compares the value of expected to the specified value and checks the mutability of the constant.

@param [Object] actual The object to check.

@return [Boolean] true If the object has a constant :expected and matches

the value and mutability expectations (if any); otherwise false.
# File lib/rspec/sleeping_king_studios/matchers/core/have_constant_matcher.rb, line 118
def matches? actual
  super

  @errors = {}

  return false unless has_constant?

  matches_constant? :all?
end
with(value) click to toggle source

Sets a value expectation. The matcher will compare the value of the constant with the specified value.

@param [Object] value The value to compare.

@return [HaveConstantMatcher] self

# File lib/rspec/sleeping_king_studios/matchers/core/have_constant_matcher.rb, line 134
def with value
  @value     = value
  @value_set = true
  self
end
Also aliased as: with_value
with_value(value)
Alias for: with

Private Instance Methods

has_constant?() click to toggle source
# File lib/rspec/sleeping_king_studios/matchers/core/have_constant_matcher.rb, line 143
def has_constant?
  unless actual.respond_to?(:const_defined?)
    @errors[:does_not_define_constants] = true

    return false
  end # unless

  unless actual.const_defined?(@expected)
    @errors[:constant_is_not_defined] = true

    return false
  end # unless

  true
end
immutable_value?() click to toggle source
# File lib/rspec/sleeping_king_studios/matchers/core/have_constant_matcher.rb, line 159
def immutable_value?
  return true unless @immutable

  actual_value = actual.const_get(@expected)

  if mutable?(actual_value)
    @errors[:value_is_mutable] = true

    return false
  end # if

  true
end
matches_constant?(filter) click to toggle source
# File lib/rspec/sleeping_king_studios/matchers/core/have_constant_matcher.rb, line 173
def matches_constant? filter
  [ matches_constant_value?,
    immutable_value?
  ].send(filter) { |bool| bool }
end
matches_constant_value?() click to toggle source
# File lib/rspec/sleeping_king_studios/matchers/core/have_constant_matcher.rb, line 179
def matches_constant_value?
  return true unless @value_set

  actual_value = actual.const_get(@expected)
  match        = (@value.respond_to?(:matches?) && @value.respond_to?(:description)) ?
    @value.matches?(actual_value) :
    @value == actual_value

  unless match
    @errors[:value_does_not_match] = {
      :expected => @value,
      :received => actual_value
    } # end hash

    return false
  end # unless

  true
end
mutable?(value) click to toggle source
# File lib/rspec/sleeping_king_studios/matchers/core/have_constant_matcher.rb, line 199
def mutable? value
  case value
  when nil, false, true, Numeric, Symbol
    false
  when Array
    return true unless value.frozen?

    value.reduce(false) { |memo, item| memo || mutable?(item) }
  when Hash
    return true unless value.frozen?

    (value.keys + value.values).reduce(false) { |memo, item| memo || mutable?(item) }
  else
    !value.frozen?
  end # case
end
value_to_string() click to toggle source

Formats the expected value as a human-readable string. If the value looks like an RSpec matcher (it responds to :matches? and :description), calls value#description; otherwise calls value#inspect.

@return [String] the value as a human-readable string.

# File lib/rspec/sleeping_king_studios/matchers/core/have_constant_matcher.rb, line 221
def value_to_string
  return @value.description if @value.respond_to?(:matches?) && @value.respond_to?(:description)

  @value.inspect
end