blob: 94b255df6208562112e15ea76ab22ada8c3a0916 (
plain)
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
|
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
module ModuleSpecs
class Parent
def method_to_remove; 1; end
end
class First
def method_to_remove; 1; end
end
class Second < First
def method_to_remove; 2; end
end
end
describe "Module#remove_method" do
before :each do
@module = Module.new { def method_to_remove; end }
end
it "is a public method" do
Module.should have_public_instance_method(:remove_method, false)
end
it "removes the method from a class" do
klass = Class.new do
def method_to_remove; 1; end
end
x = klass.new
klass.send(:remove_method, :method_to_remove)
x.respond_to?(:method_to_remove).should == false
end
it "removes method from subclass, but not parent" do
child = Class.new(ModuleSpecs::Parent) do
def method_to_remove; 2; end
remove_method :method_to_remove
end
x = child.new
x.respond_to?(:method_to_remove).should == true
x.method_to_remove.should == 1
end
it "updates the method implementation" do
m_module = Module.new do
def foo
'm'
end
end
a_class = Class.new do
include m_module
def foo
'a'
end
end
a = a_class.new
foo = -> { a.foo }
foo.call.should == 'a'
a_class.remove_method(:foo)
foo.call.should == 'm'
end
it "removes multiple methods with 1 call" do
klass = Class.new do
def method_to_remove_1; 1; end
def method_to_remove_2; 2; end
remove_method :method_to_remove_1, :method_to_remove_2
end
x = klass.new
x.respond_to?(:method_to_remove_1).should == false
x.respond_to?(:method_to_remove_2).should == false
end
it "accepts multiple arguments" do
Module.instance_method(:remove_method).arity.should < 0
end
it "does not remove any instance methods when argument not given" do
before = @module.instance_methods(true) + @module.private_instance_methods(true)
@module.send :remove_method
after = @module.instance_methods(true) + @module.private_instance_methods(true)
before.sort.should == after.sort
end
it "returns self" do
@module.send(:remove_method, :method_to_remove).should equal(@module)
end
it "raises a NameError when attempting to remove method further up the inheritance tree" do
Class.new(ModuleSpecs::Second) do
-> {
remove_method :method_to_remove
}.should raise_error(NameError)
end
end
it "raises a NameError when attempting to remove a missing method" do
Class.new(ModuleSpecs::Second) do
-> {
remove_method :blah
}.should raise_error(NameError)
end
end
describe "on frozen instance" do
before :each do
@frozen = @module.dup.freeze
end
it "raises a FrozenError when passed a name" do
-> { @frozen.send :remove_method, :method_to_remove }.should raise_error(FrozenError)
end
it "raises a FrozenError when passed a missing name" do
-> { @frozen.send :remove_method, :not_exist }.should raise_error(FrozenError)
end
it "raises a TypeError when passed a not name" do
-> { @frozen.send :remove_method, Object.new }.should raise_error(TypeError)
end
it "does not raise exceptions when no arguments given" do
@frozen.send(:remove_method).should equal(@frozen)
end
end
end
|