File: space.rb

package info (click to toggle)
ruby-rr 3.1.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,424 kB
  • sloc: ruby: 11,405; makefile: 7
file content (133 lines) | stat: -rw-r--r-- 4,210 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
module RR
  # RR::Space.instance is the global state subject for the RR framework.
  class Space
    module Reader
      def space
        RR::Space.instance
      end
    end

    class << self
      def instance
        @instance ||= new
      end
      attr_writer :instance

      protected
      if KeywordArguments.fully_supported?
        def method_missing(method_name, *args, **kwargs, &block)
          instance.__send__(method_name, *args, **kwargs, &block)
        end
      else
        def method_missing(method_name, *args, &block)
          instance.__send__(method_name, *args, &block)
        end
        ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
      end
    end

    attr_reader :ordered_doubles, :recorded_calls
    attr_accessor :trim_backtrace

    def initialize
      @ordered_doubles = []
      @trim_backtrace = false
      @recorded_calls = RR::RecordedCalls.new
    end

    # Registers the ordered Double to be verified.
    def register_ordered_double(double)
      @ordered_doubles << double unless ordered_doubles.include?(double)
    end

    # Verifies that the passed in ordered Double is being called
    # in the correct position.
    def verify_ordered_double(double)
      unless double.terminal?
        raise RR::Errors.build_error(:DoubleOrderError,
          "Ordered Doubles cannot have a NonTerminal TimesCalledExpectation")
      end
      unless @ordered_doubles.first == double
        message = Double.formatted_name(double.method_name, double.expected_arguments)
        message << " called out of order in list\n"
        message << Double.list_message_part(@ordered_doubles)
        raise RR::Errors.build_error(:DoubleOrderError, message)
      end
      @ordered_doubles.shift unless double.attempt?
      double
    end

    # Verifies all the DoubleInjection objects have met their
    # TimesCalledExpectations.
    def verify_doubles(*subjects)
      Injections::DoubleInjection.verify(*subjects)
    end
    alias_method :verify, :verify_doubles

    # Resets the registered Doubles and ordered Doubles
    def reset
      RR.trim_backtrace = false
      RR.overridden_error_class = nil
      reset_ordered_doubles
      Injections::DoubleInjection.reset
      reset_method_missing_injections
      reset_singleton_method_added_injections
      reset_recorded_calls
      reset_bound_objects
    end

    # Verifies the DoubleInjection for the passed in subject and method_name.
    def verify_double(subject, method_name)
      Injections::DoubleInjection.verify_double(class << subject; self; end, method_name)
    end

    # Resets the DoubleInjection for the passed in subject and method_name.
    def reset_double(subject, method_name)
      Injections::DoubleInjection.reset_double(class << subject; self; end, method_name)
    end

    def record_call(subject, method_name, arguments, keyword_arguments, block)
      @recorded_calls.add(subject,
                          method_name,
                          arguments,
                          keyword_arguments,
                          block)
    end

    def blank_slate_whitelist
      @blank_slate_whitelist ||= [
        "object_id", "respond_to?", "respond_to_missing?", "method_missing", "instance_eval", "instance_exec", "class_eval"
      ]
    end

  protected
    # Removes the ordered Doubles from the list
    def reset_ordered_doubles
      @ordered_doubles.clear
    end

    def reset_method_missing_injections
      Injections::MethodMissingInjection.instances.each do |subject_class, injection|
        injection.reset
      end
      Injections::MethodMissingInjection.instances.clear
    end

    def reset_singleton_method_added_injections
      Injections::SingletonMethodAddedInjection.instances.each do |subject, injection|
        injection.reset
      end
      Injections::SingletonMethodAddedInjection.instances.clear
    end

    def reset_recorded_calls
      @recorded_calls.clear
    end

    def reset_bound_objects
      # TODO: Figure out how to clear and reset these bindings
      #RR::Injections::DoubleInjection::BoundObjects.clear
      #RR::Injections::DoubleInjection::MethodMissingInjection.clear
    end
  end
end