Class: RR::DoubleInjection

Inherits:
Object
  • Object
show all
Includes:
Space::Reader
Defined in:
lib/rr/double_injection.rb

Overview

RR::DoubleInjection is the binding of an subject and a method. A double_injection has 0 to many Double objects. Each Double has Argument Expectations and Times called Expectations.

Defined Under Namespace

Classes: MethodArguments

Constant Summary collapse

LAZY_METHOD_DEFINITIONS =
[
  (lambda do |subject|
    subject.respond_to?(:descends_from_active_record?) && subject.descends_from_active_record?
  end)
]

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Space::Reader

#space

Constructor Details

#initialize(subject, method_name, subject_class) ⇒ DoubleInjection

Returns a new instance of DoubleInjection.



17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/rr/double_injection.rb', line 17

def initialize(subject, method_name, subject_class)
  @subject = subject
  @subject_class = subject_class
  @method_name = method_name.to_sym
  if subject_respond_to_method?(method_name)
    if LAZY_METHOD_DEFINITIONS.any? {|definition| definition.call(subject)} && !subject.methods.include?(method_name)
      subject.send(method_name)
    end
    subject_class.__send__(:alias_method, original_method_alias_name, method_name)
  end
  @doubles = []
end

Instance Attribute Details

#doublesObject (readonly)

Returns the value of attribute doubles.



15
16
17
# File 'lib/rr/double_injection.rb', line 15

def doubles
  @doubles
end

#method_nameObject (readonly)

Returns the value of attribute method_name.



15
16
17
# File 'lib/rr/double_injection.rb', line 15

def method_name
  @method_name
end

#subjectObject (readonly)

Returns the value of attribute subject.



15
16
17
# File 'lib/rr/double_injection.rb', line 15

def subject
  @subject
end

#subject_classObject (readonly)

Returns the value of attribute subject_class.



15
16
17
# File 'lib/rr/double_injection.rb', line 15

def subject_class
  @subject_class
end

Instance Method Details

#bindObject

RR::DoubleInjection#bind injects a method that acts as a dispatcher that dispatches to the matching Double when the method is called.



39
40
41
42
43
44
45
46
47
48
# File 'lib/rr/double_injection.rb', line 39

def bind
  returns_method = <<-METHOD
    def #{@method_name}(*args, &block)
      arguments = MethodArguments.new(args, block)
      RR::Space.double_injection(self, :#{@method_name}).call_method(arguments.arguments, arguments.block)
    end
  METHOD
  subject_class.class_eval(returns_method, __FILE__, __LINE__ - 5)
  self
end

#call_method(args, block) ⇒ Object



78
79
80
81
82
83
84
85
# File 'lib/rr/double_injection.rb', line 78

def call_method(args, block)
  space.record_call(subject, method_name, args, block)
  if double = find_double_to_attempt(args)
    double.call(self, *args, &block)
  else
    double_not_found_error(*args)
  end
end

#call_original_method(*args, &block) ⇒ Object



70
71
72
# File 'lib/rr/double_injection.rb', line 70

def call_original_method(*args, &block)
  @subject.__send__(original_method_alias_name, *args, &block)
end

#object_has_original_method?Boolean

Returns:

  • (Boolean)


74
75
76
# File 'lib/rr/double_injection.rb', line 74

def object_has_original_method?
  subject_respond_to_method?(original_method_alias_name)
end

#register_double(double) ⇒ Object

RR::DoubleInjection#register_double adds the passed in Double into this DoubleInjection’s list of Double objects.



32
33
34
# File 'lib/rr/double_injection.rb', line 32

def register_double(double)
  @doubles << double
end

#resetObject

RR::DoubleInjection#reset removes the injected dispatcher method. It binds the original method implementation on the subject if one exists.



61
62
63
64
65
66
67
68
# File 'lib/rr/double_injection.rb', line 61

def reset
  if object_has_original_method?
    subject_class.__send__(:alias_method, @method_name, original_method_alias_name)
    subject_class.__send__(:remove_method, original_method_alias_name)
  else
    subject_class.__send__(:remove_method, @method_name)
  end
end

#verifyObject

RR::DoubleInjection#verify verifies each Double TimesCalledExpectation are met.



52
53
54
55
56
# File 'lib/rr/double_injection.rb', line 52

def verify
  @doubles.each do |double|
    double.verify
  end
end