Class: Spy::Constant

Inherits:
Object
  • Object
show all
Includes:
Base
Defined in:
lib/spy/constant.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(base_module, constant_name) ⇒ Constant

Returns a new instance of Constant.

Parameters:

  • base_module (Module)

    the module this spy should be on

  • constant_name (Symbol)

    the constant this spy is watching

Raises:

  • (ArgumentError)


18
19
20
21
22
23
# File 'lib/spy/constant.rb', line 18

def initialize(base_module, constant_name)
  raise ArgumentError, "#{base_module.inspect} is not a kind of Module" unless base_module.is_a? Module
  raise ArgumentError, "#{constant_name.inspect} is not a kind of Symbol" unless constant_name.is_a? Symbol
  @base_module, @constant_name = base_module, constant_name.to_sym
  @original_value = @new_value = @previously_defined = nil
end

Instance Attribute Details

#base_moduleModule (readonly)

Returns the module that is being watched.

Returns:

  • (Module)

    the module that is being watched



# File 'lib/spy/constant.rb', line 4

#constant_nameSymbol (readonly)

Returns the name of the constant that is/will be stubbed.

Returns:

  • (Symbol)

    the name of the constant that is/will be stubbed



# File 'lib/spy/constant.rb', line 4

#original_valueObject (readonly)

Returns the original value that was set when it was hooked.

Returns:

  • (Object)

    the original value that was set when it was hooked



# File 'lib/spy/constant.rb', line 4

Class Method Details

.get(base_module, constant_name) ⇒ Nil, Constant

retrieves the spy for given constnat and module or returns nil

Returns:



117
118
119
120
121
122
# File 'lib/spy/constant.rb', line 117

def get(base_module, constant_name)
  nest = Nest.get(base_module)
  if nest
    nest.get(constant_name)
  end
end

.off(base_module, constant_name) ⇒ Constant

retrieves the spy for given constant and module and unhooks the constant from the module

Returns:

Raises:



109
110
111
112
113
# File 'lib/spy/constant.rb', line 109

def off(base_module, constant_name)
  spy = get(base_module, constant_name)
  raise NoSpyError, "#{constant_name} was not spied on #{base_module}" unless spy
  spy.unhook
end

.on(base_module, constant_name) ⇒ Constant

finds existing spy or creates a new constant spy and hooks the constant

Returns:



102
103
104
# File 'lib/spy/constant.rb', line 102

def on(base_module, constant_name)
  new(base_module, constant_name).hook
end

Instance Method Details

#and_hideself

unsets the constant

Returns:

  • (self)


60
61
62
63
# File 'lib/spy/constant.rb', line 60

def and_hide
  base_module.send(:remove_const, constant_name) if currently_defined?
  self
end

#and_return(value) ⇒ self

sets the constant to the requested value

Parameters:

  • value (Object)

Returns:

  • (self)


68
69
70
71
72
73
# File 'lib/spy/constant.rb', line 68

def and_return(value)
  @new_value = value
  and_hide
  base_module.const_set(constant_name, @new_value)
  self
end

#currently_defined?Boolean

checks to see if the constant is currently defined?

Returns:

  • (Boolean)


89
90
91
# File 'lib/spy/constant.rb', line 89

def currently_defined?
  base_module.const_defined?(constant_name, false)
end

#hidden?Boolean

checks to see if the constant is hidden?

Returns:

  • (Boolean)


83
84
85
# File 'lib/spy/constant.rb', line 83

def hidden?
  hooked? && currently_defined?
end

#hook(opts = {}) ⇒ self

stashes the original constant then overwrites it with nil

Parameters:

  • opts (Hash{force => false}) (defaults to: {})

    set :force => true if you want it to ignore if the constant exists

Returns:

  • (self)


33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/spy/constant.rb', line 33

def hook(opts = {})
  opts[:force] ||= false
  Nest.fetch(base_module).add(self)
  Agency.instance.recruit(self)

  @previously_defined = currently_defined?
  if previously_defined? || !opts[:force]
    @original_value = base_module.const_get(constant_name, false)
  end
  and_return(@new_value)
  self
end

#hooked?Boolean

checks to see if this spy is hooked?

Returns:

  • (Boolean)


77
78
79
# File 'lib/spy/constant.rb', line 77

def hooked?
  self.class.get(base_module, constant_name) == self
end

#nameObject

full name of spied constant



26
27
28
# File 'lib/spy/constant.rb', line 26

def name
  "#{base_module.name}::#{constant_name}"
end

#previously_defined?Boolean

checks to see if the constant is previously defined?

Returns:

  • (Boolean)


95
96
97
# File 'lib/spy/constant.rb', line 95

def previously_defined?
  @previously_defined
end

#unhookself

restores the original value of the constant or unsets it if it was unset

Returns:

  • (self)


48
49
50
51
52
53
54
55
56
# File 'lib/spy/constant.rb', line 48

def unhook
  Nest.get(base_module).remove(self)
  Agency.instance.retire(self)

  and_return(@original_value) if previously_defined?

  @original_value = @previously_defined = nil
  self
end