Class: RSpec::Mocks::ConstantMutator::DefinedConstantReplacer

Inherits:
BaseMutator
  • Object
show all
Defined in:
lib/rspec/mocks/mutate_const.rb

Overview

Replaces a defined constant for the duration of an example.

Instance Attribute Summary

Attributes inherited from BaseMutator

#full_constant_name, #original_value

Instance Method Summary (collapse)

Methods inherited from BaseMutator

#idempotently_reset, #initialize

Methods included from RecursiveConstMethods

#const_defined_on?, #constants_defined_on, #get_const_defined_on, #normalize_const_name, #recursive_const_defined?, #recursive_const_get

Constructor Details

This class inherits a constructor from RSpec::Mocks::ConstantMutator::BaseMutator

Instance Method Details

- (Object) mutate



260
261
262
263
264
265
266
267
268
269
270
# File 'lib/rspec/mocks/mutate_const.rb', line 260

def mutate
  @context = recursive_const_get(@context_parts.join('::'))
  @original_value = get_const_defined_on(@context, @const_name)

  constants_to_transfer = verify_constants_to_transfer!

  @context.__send__(:remove_const, @const_name)
  @context.const_set(@const_name, @mutated_value)

  transfer_nested_constants(constants_to_transfer)
end

- (Object) reset



280
281
282
283
# File 'lib/rspec/mocks/mutate_const.rb', line 280

def reset
  @context.__send__(:remove_const, @const_name)
  @context.const_set(@const_name, @original_value)
end

- (Object) to_constant



272
273
274
275
276
277
278
# File 'lib/rspec/mocks/mutate_const.rb', line 272

def to_constant
  const = super
  const.stubbed = true
  const.previously_defined = true

  const
end

- (Object) transfer_nested_constants(constants)



285
286
287
288
289
# File 'lib/rspec/mocks/mutate_const.rb', line 285

def transfer_nested_constants(constants)
  constants.each do |const|
    @mutated_value.const_set(const, get_const_defined_on(original_value, const))
  end
end

- (Object) verify_constants_to_transfer!



291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
# File 'lib/rspec/mocks/mutate_const.rb', line 291

def verify_constants_to_transfer!
  return [] unless @transfer_nested_constants

  { @original_value => "the original value", @mutated_value => "the stubbed value" }.each do |value, description|
    unless value.respond_to?(:constants)
      raise ArgumentError,
        "Cannot transfer nested constants for #{@full_constant_name} " +
        "since #{description} is not a class or module and only classes " +
        "and modules support nested constants."
    end
  end

  if Array === @transfer_nested_constants
    @transfer_nested_constants = @transfer_nested_constants.map(&:to_s) if RUBY_VERSION == '1.8.7'
    undefined_constants = @transfer_nested_constants - constants_defined_on(@original_value)

    if undefined_constants.any?
      available_constants = constants_defined_on(@original_value) - @transfer_nested_constants
      raise ArgumentError,
        "Cannot transfer nested constant(s) #{undefined_constants.join(' and ')} " +
        "for #{@full_constant_name} since they are not defined. Did you mean " +
        "#{available_constants.join(' or ')}?"
    end

    @transfer_nested_constants
  else
    constants_defined_on(@original_value)
  end
end