Class: Sus::Mock

Inherits:
Object
  • Object
show all
Defined in:
lib/sus/mock.rb

Overview

Represents a mock object that can intercept and replace method calls on a target object.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(target) ⇒ Mock

Initialize a new mock for the given target.



13
14
15
16
17
18
# File 'lib/sus/mock.rb', line 13

def initialize(target)
	@target = target
	@interceptor = Module.new
	
	@target.singleton_class.prepend(@interceptor)
end

Instance Attribute Details

#targetObject (readonly)

Returns the value of attribute target.



21
22
23
# File 'lib/sus/mock.rb', line 21

def target
  @target
end

Instance Method Details

#after(method, &hook) ⇒ Object

Add a hook that runs after a method is called.



73
74
75
76
77
78
79
80
81
82
83
# File 'lib/sus/mock.rb', line 73

def after(method, &hook)
	execution_context = Thread.current
	
	@interceptor.define_method(method) do |*arguments, **options, &block|
		result = super(*arguments, **options, &block)
		hook.call(result, *arguments, **options, &block) if execution_context == Thread.current
		return result
	end
	
	return self
end

#before(method, &hook) ⇒ Object

Add a hook that runs before a method is called.



58
59
60
61
62
63
64
65
66
67
# File 'lib/sus/mock.rb', line 58

def before(method, &hook)
	execution_context = Thread.current
	
	@interceptor.define_method(method) do |*arguments, **options, &block|
		hook.call(*arguments, **options, &block) if execution_context == Thread.current
		super(*arguments, **options, &block)
	end
	
	return self
end

#clearObject

Clear all mocked methods from the target.



30
31
32
33
34
# File 'lib/sus/mock.rb', line 30

def clear
	@interceptor.instance_methods.each do |method_name|
		@interceptor.remove_method(method_name)
	end
end

Print a representation of this mock.



25
26
27
# File 'lib/sus/mock.rb', line 25

def print(output)
	output.write("mock ", :context, @target.inspect)
end

#replace(method, &hook) ⇒ Object

Replace a method implementation.



40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/sus/mock.rb', line 40

def replace(method, &hook)
	execution_context = Thread.current
	
	@interceptor.define_method(method) do |*arguments, **options, &block|
		if execution_context == Thread.current
			hook.call(*arguments, **options, &block)
		else
			super(*arguments, **options, &block)
		end
	end
	
	return self
end

#The target object being mocked.=(targetobjectbeingmocked. = (value)) ⇒ Object



21
# File 'lib/sus/mock.rb', line 21

attr :target

#wrap(method, &hook) ⇒ Object

Wrap a method, yielding the original method as the first argument, so you can call it from within the hook.



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/sus/mock.rb', line 88

def wrap(method, &hook)
	execution_context = Thread.current
	
	@interceptor.define_method(method) do |*arguments, **options, &block|
		if execution_context == Thread.current
			original = proc do |*arguments, **options|
				super(*arguments, **options)
			end
			
			hook.call(original, *arguments, **options, &block) 
		else
			super(*arguments, **options, &block)
		end
	end
end