class Mongoid::Matchers::HaveCallbackMatcher

Create an matcher for callback method

Usage:

it { is_expected.to callback(:callback1).before(:save) } it { is_expected.to callback(:callback2).after(:save) } it { is_expected.to callback(:callback1, :callback2).before(:validation) } it { is_expected.to callback(:callback3).after(:validation).on(:create) }

Constants

KINDS

Public Class Methods

new(*args) click to toggle source

Set methods to look for

# File lib/matchers/callbacks.rb, line 17
def initialize(*args)
  @methods = args || []
end

Public Instance Methods

description() click to toggle source
# File lib/matchers/callbacks.rb, line 58
def description
  methods = @methods

  "be callback(:#{methods.join(', ')})#{expl_operation}#{expl_context}"
end
failure_message() click to toggle source
# File lib/matchers/callbacks.rb, line 50
def failure_message
  message(true)
end
failure_message_when_negated() click to toggle source
# File lib/matchers/callbacks.rb, line 54
def failure_message_when_negated
  message(false)
end
matches?(klass) click to toggle source
# File lib/matchers/callbacks.rb, line 36
def matches?(klass)
  return false unless @kind
  if @no_op == !klass.class.respond_to?(:"_#{@operation}_callbacks")
    return false
  end

  @guess = nil
  @methods.each do |method|
    filter = filters_method(klass, method)

    return false unless filter
  end
end
on(action) click to toggle source

Set on condition

# File lib/matchers/callbacks.rb, line 31
def on(action)
  @context = action
  self
end

Protected Instance Methods

expl_context() click to toggle source
# File lib/matchers/callbacks.rb, line 70
def expl_context
  @context ? ".on(:#{@context})" : ''
end
expl_operation() click to toggle source
# File lib/matchers/callbacks.rb, line 66
def expl_operation
  @operation ? ".#{@kind}(:#{@operation})" : ''
end
expr_called(should) click to toggle source
# File lib/matchers/callbacks.rb, line 96
def expr_called(should)
  "#{@methods.join(', ')} #{should ? '' : 'not '}to be called"
end
message(should) click to toggle source
# File lib/matchers/callbacks.rb, line 74
def message(should)
  return msg_op_invalid if @no_op

  @kind ? message_kind(should) : message_not_kind
end
message_kind(should) click to toggle source
# File lib/matchers/callbacks.rb, line 85
      def message_kind(should)
        <<-MESSAGE
          Expected method#{@methods.size > 1 ? 's' : ''}#{expr_called(should)}
            #{"#{@kind}" "#{@operation}" if @operation}
            #{"on #{@context}" if @context}
            #{msg_guess}
            #{"#{@guess.kind}   #{@operation}" if @guess}
            #{'on another context' if @guess && !@context_match}
        MESSAGE
      end
message_not_kind() click to toggle source
# File lib/matchers/callbacks.rb, line 108
      def message_not_kind
        <<-MESSAGE
          Callback#{@methods.size > 1 ? 's' : ''} #{@methods.join(', ')} can
          not be tested against undefined lifecycle.
          Use .before, .after or .around
        MESSAGE
      end
msg_guess() click to toggle source
# File lib/matchers/callbacks.rb, line 100
def msg_guess
  if @guess
    ", but got method #{@guess.filter} called"
  else
    ', but no callback found'
  end
end
msg_op_invalid() click to toggle source
# File lib/matchers/callbacks.rb, line 80
def msg_op_invalid
  'Invalid operation. Use :initialize, :build, :validation,' \
  ':create, :find, :update, :upsert, :save or :destroy'
end

Private Instance Methods

check_context?(callback, context) click to toggle source
# File lib/matchers/callbacks.rb, line 139
def check_context?(callback, context)
  return true unless context

  options = callback.instance_variable_get(:@if)
  @context_match = options.select { |option| option.is_a?(Proc) }

  @context_match.detect do |option|
    option.call(ValidationContext.new(context))
  end
end
check_filter?(callback, method) click to toggle source
# File lib/matchers/callbacks.rb, line 131
def check_filter?(callback, method)
  callback.filter == method
end
check_kind?(callback, kind) click to toggle source
# File lib/matchers/callbacks.rb, line 135
def check_kind?(callback, kind)
  callback.kind == kind
end
filters_method(klass, method) click to toggle source
# File lib/matchers/callbacks.rb, line 118
def filters_method(klass, method)
  klass.class.send(:"_#{@operation}_callbacks").detect do |callback|
    # Save callback instance in order to print information
    # about it in case of failure
    @guess = callback if callback.filter == method
    check_filter?(callback,
                  method) and check_kind?(callback,
                                          @kind) and check_context?(
                                            callback, @context
                                          )
  end
end