blob: 6c3bdc9cf2c86e69a5c9426322d18c41b255280a [file] [log] [blame]
Kevin Clark3eca0782008-06-18 00:54:53 +00001require File.dirname(__FILE__) + '/spec_helper'
2
Kevin Clark96cc5162008-06-18 00:56:08 +00003shared_examples_for "deprecation" do
4 before(:all) do
5 # ensure deprecation is turned on
6 Thrift.send :remove_const, :DEPRECATION
7 Thrift.const_set :DEPRECATION, true
8 end
9
10 after(:all) do
11 # now turn it off again
12 # no other specs should want it
13 Thrift.send :remove_const, :DEPRECATION
14 Thrift.const_set :DEPRECATION, false
15 end
Kevin Clark03a5fb12008-06-18 01:01:25 +000016
17 def ensure_const_removed(name, &block)
18 begin
19 block.call
20 ensure
21 Object.send :remove_const, name if Object.const_defined? name
22 end
23 end
Kevin Clark96cc5162008-06-18 00:56:08 +000024end
25
Kevin Clark3eca0782008-06-18 00:54:53 +000026describe 'deprecate!' do
Kevin Clark96cc5162008-06-18 00:56:08 +000027 it_should_behave_like "deprecation"
28
Kevin Clarkfc964ee2008-06-18 00:57:46 +000029 def stub_stderr(callstr, offset=1)
Kevin Clark3eca0782008-06-18 00:54:53 +000030 STDERR.should_receive(:puts).with("Warning: calling deprecated method #{callstr}")
Kevin Clarkfc964ee2008-06-18 00:57:46 +000031 line = caller.first[/\d+$/].to_i + offset
32 STDERR.should_receive(:puts).with(" from #{__FILE__}:#{line}")
Kevin Clark3eca0782008-06-18 00:54:53 +000033 end
34
35 it "should work for Module methods" do
36 mod = Module.new do
37 class << self
38 def new
39 "new"
40 end
41 deprecate! :old => :new
42 end
43 end
44 stub_stderr "#{mod.inspect}.old"
45 mod.old.should == "new"
46 end
47
48 it "should work with Modules that extend themselves" do
49 mod = Module.new do
50 extend self
51 def new
52 "new"
53 end
54 deprecate! :old => :new
55 end
56 stub_stderr "#{mod.inspect}.old"
57 mod.old.should == "new"
58 end
59
60 it "should work wtih Class methods" do
61 klass = Class.new do
62 class << self
63 def new
64 "new"
65 end
66 deprecate! :old => :new
67 end
68 end
69 stub_stderr "#{klass.inspect}.old"
70 klass.old.should == "new"
71 end
72
73 it "should work with Classes that include Modules" do
74 mod = Module.new do
75 def new
76 "new"
77 end
78 deprecate! :old => :new
79 end
80 klass = Class.new do
81 include mod
82 end
83 stub_stderr "#{klass.inspect}#old"
84 klass.new.old.should == "new"
85 end
86
87 it "should work with instance methods" do
88 klass = Class.new do
89 def new
90 "new"
91 end
92 deprecate! :old => :new
93 end
94 stub_stderr "#{klass.inspect}#old"
95 klass.new.old.should == "new"
96 end
97
98 it "should work with multiple method names" do
99 klass = Class.new do
100 def new1
101 "new 1"
102 end
103 def new2
104 "new 2"
105 end
106 deprecate! :old1 => :new1, :old2 => :new2
107 end
Kevin Clarkfc964ee2008-06-18 00:57:46 +0000108 stub_stderr("#{klass.inspect}#old1", 3).ordered
109 stub_stderr("#{klass.inspect}#old2", 3).ordered
Kevin Clark3eca0782008-06-18 00:54:53 +0000110 inst = klass.new
111 inst.old1.should == "new 1"
112 inst.old2.should == "new 2"
113 end
114
115 it "should only log a message once, even across multiple instances" do
116 klass = Class.new do
117 def new
118 "new"
119 end
120 deprecate! :old => :new
121 end
122 stub_stderr("#{klass.inspect}#old").once
123 klass.new.old.should == "new"
124 klass.new.old.should == "new"
125 end
126
127 it "should pass arguments" do
128 klass = Class.new do
129 def new(a, b)
130 "new: #{a + b}"
131 end
132 deprecate! :old => :new
133 end
134 stub_stderr("#{klass.inspect}#old")
135 klass.new.old(3, 5).should == "new: 8"
136 end
137
138 it "should pass blocks" do
139 klass = Class.new do
140 def new
141 "new #{yield}"
142 end
143 deprecate! :old => :new
144 end
145 stub_stderr("#{klass.inspect}#old")
146 klass.new.old { "block" }.should == "new block"
147 end
148
149 it "should not freeze the definition of the new method" do
150 klass = Class.new do
151 def new
152 "new"
153 end
154 deprecate! :old => :new
155 end
156 klass.send :define_method, :new do
157 "new 2"
158 end
159 stub_stderr("#{klass.inspect}#old")
160 klass.new.old.should == "new 2"
161 end
Kevin Clarkda40e8d2008-06-18 00:58:04 +0000162
163 it "should call the forwarded method in the same context as the original" do
164 klass = Class.new do
165 def myself
166 self
167 end
168 deprecate! :me => :myself
169 end
170 inst = klass.new
171 stub_stderr("#{klass.inspect}#me")
172 inst.me.should eql(inst.myself)
173 end
Kevin Clark3eca0782008-06-18 00:54:53 +0000174end
175
176describe "deprecate_class!" do
Kevin Clark96cc5162008-06-18 00:56:08 +0000177 it_should_behave_like "deprecation"
178
Kevin Clarkde7864e2008-06-18 01:02:14 +0000179 def stub_stderr(klass, offset=1)
180 STDERR.should_receive(:puts).with("Warning: class #{klass} is deprecated")
Kevin Clark2a8a7312008-06-18 01:01:07 +0000181 line = caller.first[/\d+$/].to_i + offset
182 STDERR.should_receive(:puts).with(" from #{__FILE__}:#{line}")
183 end
184
Kevin Clark3eca0782008-06-18 00:54:53 +0000185 it "should create a new global constant that points to the old one" do
Kevin Clark03a5fb12008-06-18 01:01:25 +0000186 ensure_const_removed :DeprecationSpecOldClass do
Kevin Clark3eca0782008-06-18 00:54:53 +0000187 klass = Class.new do
188 def foo
189 "foo"
190 end
191 end
192 deprecate_class! :DeprecationSpecOldClass => klass
Kevin Clarkeff97fc2008-06-18 01:01:40 +0000193 stub_stderr(:DeprecationSpecOldClass)
Kevin Clarkf5754ac2008-06-18 01:00:12 +0000194 ::DeprecationSpecOldClass.should eql(klass)
195 ::DeprecationSpecOldClass.new.foo.should == "foo"
Kevin Clarkf5754ac2008-06-18 01:00:12 +0000196 end
197 end
198
199 it "should create a global constant even from inside a module" do
Kevin Clark03a5fb12008-06-18 01:01:25 +0000200 ensure_const_removed :DeprecationSpecOldClass do
Kevin Clarkf5754ac2008-06-18 01:00:12 +0000201 klass = nil #define scoping
Kevin Clark03a5fb12008-06-18 01:01:25 +0000202 Module.new do
Kevin Clarkf5754ac2008-06-18 01:00:12 +0000203 klass = Class.new do
204 def foo
205 "foo"
206 end
207 end
208 deprecate_class! :DeprecationSpecOldClass => klass
209 end
Kevin Clarkeff97fc2008-06-18 01:01:40 +0000210 stub_stderr(:DeprecationSpecOldClass)
Kevin Clarkf5754ac2008-06-18 01:00:12 +0000211 ::DeprecationSpecOldClass.should eql(klass)
212 ::DeprecationSpecOldClass.new.foo.should == "foo"
Kevin Clark3eca0782008-06-18 00:54:53 +0000213 end
214 end
Kevin Clark2a8a7312008-06-18 01:01:07 +0000215
216 it "should not prevent the deprecated class from being a superclass" do
Kevin Clark03a5fb12008-06-18 01:01:25 +0000217 ensure_const_removed :DeprecationSpecOldClass do
Kevin Clark2a8a7312008-06-18 01:01:07 +0000218 klass = Class.new do
219 def foo
220 "foo"
221 end
222 end
223 deprecate_class! :DeprecationSpecOldClass => klass
224 subklass = Class.new(::DeprecationSpecOldClass) do
225 def foo
226 "subclass #{super}"
227 end
228 end
Kevin Clarkeff97fc2008-06-18 01:01:40 +0000229 stub_stderr(:DeprecationSpecOldClass)
Kevin Clark2a8a7312008-06-18 01:01:07 +0000230 subklass.superclass.should eql(klass)
231 subklass.new.foo.should == "subclass foo"
Kevin Clark03a5fb12008-06-18 01:01:25 +0000232 end
233 end
Kevin Clarkfc311642008-06-18 01:01:57 +0000234
235 it "should not bleed info between deprecations" do
236 ensure_const_removed :DeprecationSpecOldClass do
237 ensure_const_removed :DeprecationSpecOldClass2 do
238 klass = Class.new do
239 def foo
240 "foo"
241 end
242 end
243 deprecate_class! :DeprecationSpecOldClass => klass
244 klass2 = Class.new do
245 def bar
246 "bar"
247 end
248 end
249 deprecate_class! :DeprecationSpecOldClass2 => klass2
250 stub_stderr(:DeprecationSpecOldClass)
251 ::DeprecationSpecOldClass.new.foo.should == "foo"
252 stub_stderr(:DeprecationSpecOldClass2)
253 ::DeprecationSpecOldClass2.new.bar.should == "bar"
254 end
255 end
256 end
Kevin Clark03a5fb12008-06-18 01:01:25 +0000257end
258
259describe "deprecate_module!" do
260 it_should_behave_like "deprecation"
261
Kevin Clarkde7864e2008-06-18 01:02:14 +0000262 def stub_stderr(mod, offset=1)
263 STDERR.should_receive(:puts).with("Warning: module #{mod} is deprecated")
Kevin Clark03a5fb12008-06-18 01:01:25 +0000264 line = caller.first[/\d+$/].to_i + offset
265 STDERR.should_receive(:puts).with(" from #{__FILE__}:#{line}")
266 end
267
268 it "should create a new global constant that points to the old one" do
269 ensure_const_removed :DeprecationSpecOldModule do
270 mod = Module.new do
271 def self.foo
272 "foo"
273 end
274 end
275 deprecate_module! :DeprecationSpecOldModule => mod
Kevin Clarkeff97fc2008-06-18 01:01:40 +0000276 stub_stderr(:DeprecationSpecOldModule)
Kevin Clark03a5fb12008-06-18 01:01:25 +0000277 ::DeprecationSpecOldModule.should eql(mod)
278 ::DeprecationSpecOldModule.foo.should == "foo"
279 end
280 end
281
282 it "should create a global constant even from inside a module" do
283 ensure_const_removed :DeprecationSpecOldModule do
284 mod = nil # scoping
285 Module.new do
286 mod = Module.new do
287 def self.foo
288 "foo"
289 end
290 end
291 deprecate_module! :DeprecationSpecOldModule => mod
292 end
Kevin Clarkeff97fc2008-06-18 01:01:40 +0000293 stub_stderr(:DeprecationSpecOldModule)
Kevin Clark03a5fb12008-06-18 01:01:25 +0000294 ::DeprecationSpecOldModule.should eql(mod)
295 ::DeprecationSpecOldModule.foo.should == "foo"
296 end
297 end
298
299 it "should work for modules that extend themselves" do
300 ensure_const_removed :DeprecationSpecOldModule do
301 mod = Module.new do
302 extend self
303 def foo
304 "foo"
305 end
306 end
307 deprecate_module! :DeprecationSpecOldModule => mod
Kevin Clarkeff97fc2008-06-18 01:01:40 +0000308 stub_stderr(:DeprecationSpecOldModule)
Kevin Clark03a5fb12008-06-18 01:01:25 +0000309 ::DeprecationSpecOldModule.should eql(mod)
310 ::DeprecationSpecOldModule.foo.should == "foo"
311 end
312 end
313
314 it "should work for modules included in other modules" do
315 ensure_const_removed :DeprecationSpecOldModule do
316 mod = Module.new do
317 def foo
318 "foo"
319 end
320 end
321 deprecate_module! :DeprecationSpecOldModule => mod
322 mod2 = Module.new do
323 class << self
324 include ::DeprecationSpecOldModule
325 end
326 end
Kevin Clarkeff97fc2008-06-18 01:01:40 +0000327 stub_stderr(:DeprecationSpecOldModule)
Kevin Clark03a5fb12008-06-18 01:01:25 +0000328 mod2.foo.should == "foo"
329 end
330 end
331
332 it "should work for modules included in classes" do
333 ensure_const_removed :DeprecationSpecOldModule do
334 mod = Module.new do
335 def foo
336 "foo"
337 end
338 end
339 deprecate_module! :DeprecationSpecOldModule => mod
340 klass = Class.new do
341 include ::DeprecationSpecOldModule
342 end
Kevin Clarkeff97fc2008-06-18 01:01:40 +0000343 stub_stderr(:DeprecationSpecOldModule)
Kevin Clark03a5fb12008-06-18 01:01:25 +0000344 klass.new.foo.should == "foo"
Kevin Clark2a8a7312008-06-18 01:01:07 +0000345 end
346 end
Kevin Clarkde7864e2008-06-18 01:02:14 +0000347
348 it "should not bleed info between deprecations" do
349 ensure_const_removed :DeprecationSpecOldModule do
350 ensure_const_removed :DeprecationSpecOldModule2 do
351 mod = Module.new do
352 def self.foo
353 "foo"
354 end
355 end
356 deprecate_module! :DeprecationSpecOldModule => mod
357 mod2 = Module.new do
358 def self.bar
359 "bar"
360 end
361 end
362 deprecate_module! :DeprecationSpecOldModule2 => mod2
363 stub_stderr(:DeprecationSpecOldModule)
364 ::DeprecationSpecOldModule.foo.should == "foo"
365 stub_stderr(:DeprecationSpecOldModule2)
366 ::DeprecationSpecOldModule2.bar.should == "bar"
367 end
368 end
369 end
Kevin Clark3eca0782008-06-18 00:54:53 +0000370end