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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
require_relative '../../spec_helper'
require_relative 'fixtures/singleton_method'
describe "BasicObject#singleton_method_added" do
before :each do
ScratchPad.clear
end
it "is a private method" do
BasicObject.should have_private_instance_method(:singleton_method_added)
end
it "is called when a singleton method is defined on an object" do
obj = BasicObject.new
def obj.singleton_method_added(name)
ScratchPad.record [:singleton_method_added, name]
end
def obj.new_singleton_method
end
ScratchPad.recorded.should == [:singleton_method_added, :new_singleton_method]
end
it "is not called for instance methods" do
ScratchPad.record []
Module.new do
def self.singleton_method_added(name)
ScratchPad << name
end
def new_instance_method
end
end
ScratchPad.recorded.should_not include(:new_instance_method)
end
it "is called when a singleton method is defined on a module" do
class BasicObjectSpecs::SingletonMethod
def self.new_method_on_self
end
end
ScratchPad.recorded.should == [:singleton_method_added, :new_method_on_self]
end
it "is called when a method is defined in the singleton class" do
class BasicObjectSpecs::SingletonMethod
class << self
def new_method_on_singleton
end
end
end
ScratchPad.recorded.should == [:singleton_method_added, :new_method_on_singleton]
end
it "is called when a method is defined with alias_method in the singleton class" do
class BasicObjectSpecs::SingletonMethod
class << self
alias_method :new_method_on_singleton_with_alias_method, :singleton_method_to_alias
end
end
ScratchPad.recorded.should == [:singleton_method_added, :new_method_on_singleton_with_alias_method]
end
it "is called when a method is defined with syntax alias in the singleton class" do
class BasicObjectSpecs::SingletonMethod
class << self
alias new_method_on_singleton_with_syntax_alias singleton_method_to_alias
end
end
ScratchPad.recorded.should == [:singleton_method_added, :new_method_on_singleton_with_syntax_alias]
end
it "is called when define_method is used in the singleton class" do
class BasicObjectSpecs::SingletonMethod
class << self
define_method :new_method_with_define_method do
end
end
end
ScratchPad.recorded.should == [:singleton_method_added, :new_method_with_define_method]
end
describe "when singleton_method_added is undefined" do
it "raises NoMethodError for a metaclass" do
class BasicObjectSpecs::NoSingletonMethodAdded
class << self
undef_method :singleton_method_added
end
-> {
def self.foo
end
}.should raise_error(NoMethodError, /undefined method [`']singleton_method_added' for/)
end
end
it "raises NoMethodError for a singleton instance" do
object = Object.new
class << object
undef_method :singleton_method_added
-> {
def foo
end
}.should raise_error(NoMethodError, /undefined method [`']singleton_method_added' for #<Object:/)
-> {
define_method(:bar) {}
}.should raise_error(NoMethodError, /undefined method [`']singleton_method_added' for #<Object:/)
end
-> {
object.define_singleton_method(:baz) {}
}.should raise_error(NoMethodError, /undefined method [`']singleton_method_added' for #<Object:/)
end
it "calls #method_missing" do
ScratchPad.record []
object = Object.new
class << object
def method_missing(*args)
ScratchPad << args
end
undef_method :singleton_method_added
def foo
end
define_method(:bar) {}
end
object.define_singleton_method(:baz) {}
ScratchPad.recorded.should == [
[:singleton_method_added, :foo],
[:singleton_method_added, :bar],
[:singleton_method_added, :baz],
]
end
end
end
|