File: stub_const.rb

package info (click to toggle)
ruby-minitest-stub-const 0.6-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 100 kB
  • sloc: ruby: 143; makefile: 4
file content (98 lines) | stat: -rw-r--r-- 2,379 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
94
95
96
97
98
class Object
  # Replace the +value+ of constant +name+ for the duration of a
  # +block+. This is especially useful when testing that the expected
  # class methods are being called on a Module or Class instance.
  #
  # Example:
  #
  #   module Foo
  #     BAR = :original
  #   end
  #
  #   Foo.stub_const(:BAR, :stubbed) do
  #     Foo::BAR
  #   end
  #   # => :stubbed
  #
  #   Foo::BAR
  #   # => :original
  def stub_const(name, val = nil, &block)
    stub_consts(name => val, &block)
  end

  # Same as stub_const except it supports a Hash of +name+ to +value+ pairs
  # of the constants that will be stubbed for the duration of the +block+.
  #
  # Example:
  #
  #   module Foo
  #     BAR = :original1
  #     BAZ = :original2
  #   end
  #
  #   Foo.stub_consts(BAR: :stubble, BAZ: :stubby) do
  #     [Foo::BAR, Foo::BAZ]
  #   end
  #   # => [:stubble, :stubby]
  #
  #   [Foo::BAR, Foo::BAZ]
  #   # => [:original1, :original2]
  def stub_consts(consts, &block)
    original_values = {}
    consts.each_pair do |name, val|
      if const_defined?(name)
        original_value = const_get(name)
        original_values[name] = original_value
      end
      silence_warnings { const_set(name, val) }
    end

    yield

  ensure
    consts.keys.each do |name|
      if original_values.key?(name)
        silence_warnings { const_set(name, original_values[name]) }
      else
        remove_const(name)
      end
    end
  end

  # Remove the constant +name+ for the duration of a block. This is
  # useful when testing code that checks whether a constant is defined
  # or not. Simply yields to the passed block if the constant is not
  # currently defined.
  #
  # Example:
  #
  #   Object.stub_remove_const(:File) do
  #     "Look ma, no File!" unless defined?(File)
  #   end
  #   # => "Look ma, no File!"
  def stub_remove_const(name)
    if const_defined?(name)
      begin
        orig = const_get(name)
        remove_const(name)
        yield
      ensure
        const_set(name, orig)
      end
    else
      yield
    end
  end

  # Add a minimal implementation of ActiveSupport's silence_warnings if it
  # hasn't already been defined, to call a block with warnings disabled.
  unless respond_to?(:silence_warnings)
    def silence_warnings
      orig = $VERBOSE
      $VERBOSE = nil
      yield
    ensure
      $VERBOSE = orig
    end
  end
end