File: expectation_director.rb

package info (click to toggle)
ruby-flexmock 3.0.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 836 kB
  • sloc: ruby: 7,572; makefile: 6
file content (93 lines) | stat: -rw-r--r-- 2,894 bytes parent folder | download
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
#!/usr/bin/env ruby

#---
# Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com).
# All rights reserved.

# Permission is granted for use, copying, modification, distribution,
# and distribution of modified versions of this work as long as the
# above copyright notice is included.
#+++

require 'flexmock/noop'
require 'flexmock/errors'

class FlexMock

  # The expectation director is responsible for routing calls to the
  # correct expectations for a given argument list.
  #
  class ExpectationDirector

    # Create an ExpectationDirector for a mock object.
    def initialize(sym)
      @sym = sym
      @expectations = []
      @defaults = []
      @expected_order = nil
    end

    # Invoke the expectations for a given set of arguments.
    #
    # First, look for an expectation that matches the arguments and
    # is eligible to be called.  Failing that, look for a expectation
    # that matches the arguments (at this point it will be ineligible,
    # but at least we will get a good failure message).  Finally,
    # check for expectations that don't have any argument matching
    # criteria.
    def call(args, kw, block, call_record=nil)
      exp = find_expectation(args, kw, block)
      call_record.expectation = exp if call_record
      FlexMock.check(
        proc { "no matching handler found for " +
               FlexMock.format_call(@sym, args, kw) +
               "\nDefined expectations:\n  " +
               @expectations.map(&:description).join("\n  ") }
      ) { !exp.nil? }
      returned_value = exp.verify_call(args, kw, block)
      returned_value
    end

    # Append an expectation to this director.
    def <<(expectation)
      @expectations << expectation
    end

    # Find an expectation matching the given arguments.
    def find_expectation(args, kw, block) # :nodoc:
      if @expectations.empty?
        find_expectation_in(@defaults, args, kw, block)
      else
        find_expectation_in(@expectations, args, kw, block)
      end
    end

    # Do the post test verification for this director.  Check all the
    # expectations.  Only check the default expecatations if there are
    # no non-default expectations.
    def flexmock_verify         # :nodoc:
      (@expectations.empty? ? @defaults : @expectations).each do |exp|
        exp.flexmock_verify
      end
    end

    # Move the last defined expectation a default.
    def defaultify_expectation(exp) # :nodoc:
      last_exp = @expectations.last
      if last_exp != exp
        fail UsageError,
          "Cannot make a previously defined expection into a default"
      end
      @expectations.pop
      @defaults << exp
    end

    private

    def find_expectation_in(expectations, args, kw, block)
      expectations.find { |e| e.match_args(args, kw, block) && e.eligible? } ||
        expectations.find { |e| e.match_args(args, kw, block) }
    end
  end

end