blob: ff10177ca9c095f3e14a4ada9de0e61fdf51b4c2 [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
16end
17
Kevin Clark3eca0782008-06-18 00:54:53 +000018describe 'deprecate!' do
Kevin Clark96cc5162008-06-18 00:56:08 +000019 it_should_behave_like "deprecation"
20
Kevin Clarkfc964ee2008-06-18 00:57:46 +000021 def stub_stderr(callstr, offset=1)
Kevin Clark3eca0782008-06-18 00:54:53 +000022 STDERR.should_receive(:puts).with("Warning: calling deprecated method #{callstr}")
Kevin Clarkfc964ee2008-06-18 00:57:46 +000023 line = caller.first[/\d+$/].to_i + offset
24 STDERR.should_receive(:puts).with(" from #{__FILE__}:#{line}")
Kevin Clark3eca0782008-06-18 00:54:53 +000025 end
26
27 it "should work for Module methods" do
28 mod = Module.new do
29 class << self
30 def new
31 "new"
32 end
33 deprecate! :old => :new
34 end
35 end
36 stub_stderr "#{mod.inspect}.old"
37 mod.old.should == "new"
38 end
39
40 it "should work with Modules that extend themselves" do
41 mod = Module.new do
42 extend self
43 def new
44 "new"
45 end
46 deprecate! :old => :new
47 end
48 stub_stderr "#{mod.inspect}.old"
49 mod.old.should == "new"
50 end
51
52 it "should work wtih Class methods" do
53 klass = Class.new do
54 class << self
55 def new
56 "new"
57 end
58 deprecate! :old => :new
59 end
60 end
61 stub_stderr "#{klass.inspect}.old"
62 klass.old.should == "new"
63 end
64
65 it "should work with Classes that include Modules" do
66 mod = Module.new do
67 def new
68 "new"
69 end
70 deprecate! :old => :new
71 end
72 klass = Class.new do
73 include mod
74 end
75 stub_stderr "#{klass.inspect}#old"
76 klass.new.old.should == "new"
77 end
78
79 it "should work with instance methods" do
80 klass = Class.new do
81 def new
82 "new"
83 end
84 deprecate! :old => :new
85 end
86 stub_stderr "#{klass.inspect}#old"
87 klass.new.old.should == "new"
88 end
89
90 it "should work with multiple method names" do
91 klass = Class.new do
92 def new1
93 "new 1"
94 end
95 def new2
96 "new 2"
97 end
98 deprecate! :old1 => :new1, :old2 => :new2
99 end
Kevin Clarkfc964ee2008-06-18 00:57:46 +0000100 stub_stderr("#{klass.inspect}#old1", 3).ordered
101 stub_stderr("#{klass.inspect}#old2", 3).ordered
Kevin Clark3eca0782008-06-18 00:54:53 +0000102 inst = klass.new
103 inst.old1.should == "new 1"
104 inst.old2.should == "new 2"
105 end
106
107 it "should only log a message once, even across multiple instances" do
108 klass = Class.new do
109 def new
110 "new"
111 end
112 deprecate! :old => :new
113 end
114 stub_stderr("#{klass.inspect}#old").once
115 klass.new.old.should == "new"
116 klass.new.old.should == "new"
117 end
118
119 it "should pass arguments" do
120 klass = Class.new do
121 def new(a, b)
122 "new: #{a + b}"
123 end
124 deprecate! :old => :new
125 end
126 stub_stderr("#{klass.inspect}#old")
127 klass.new.old(3, 5).should == "new: 8"
128 end
129
130 it "should pass blocks" do
131 klass = Class.new do
132 def new
133 "new #{yield}"
134 end
135 deprecate! :old => :new
136 end
137 stub_stderr("#{klass.inspect}#old")
138 klass.new.old { "block" }.should == "new block"
139 end
140
141 it "should not freeze the definition of the new method" do
142 klass = Class.new do
143 def new
144 "new"
145 end
146 deprecate! :old => :new
147 end
148 klass.send :define_method, :new do
149 "new 2"
150 end
151 stub_stderr("#{klass.inspect}#old")
152 klass.new.old.should == "new 2"
153 end
Kevin Clarkda40e8d2008-06-18 00:58:04 +0000154
155 it "should call the forwarded method in the same context as the original" do
156 klass = Class.new do
157 def myself
158 self
159 end
160 deprecate! :me => :myself
161 end
162 inst = klass.new
163 stub_stderr("#{klass.inspect}#me")
164 inst.me.should eql(inst.myself)
165 end
Kevin Clark3eca0782008-06-18 00:54:53 +0000166end
167
168describe "deprecate_class!" do
Kevin Clark96cc5162008-06-18 00:56:08 +0000169 it_should_behave_like "deprecation"
170
Kevin Clark2a8a7312008-06-18 01:01:07 +0000171 def stub_stderr(callstr, offset=1)
172 STDERR.should_receive(:puts).with("Warning: class #{callstr} is deprecated")
173 line = caller.first[/\d+$/].to_i + offset
174 STDERR.should_receive(:puts).with(" from #{__FILE__}:#{line}")
175 end
176
Kevin Clark3eca0782008-06-18 00:54:53 +0000177 it "should create a new global constant that points to the old one" do
178 begin
179 klass = Class.new do
180 def foo
181 "foo"
182 end
183 end
184 deprecate_class! :DeprecationSpecOldClass => klass
Kevin Clark2a8a7312008-06-18 01:01:07 +0000185 stub_stderr(klass)
Kevin Clarkf5754ac2008-06-18 01:00:12 +0000186 ::DeprecationSpecOldClass.should eql(klass)
187 ::DeprecationSpecOldClass.new.foo.should == "foo"
188 ensure
189 Object.send :remove_const, :DeprecationSpecOldClass if Object.const_defined? :DeprecationSpecOldClass
190 end
191 end
192
193 it "should create a global constant even from inside a module" do
194 begin
195 klass = nil #define scoping
196 mod = Module.new do
197 klass = Class.new do
198 def foo
199 "foo"
200 end
201 end
202 deprecate_class! :DeprecationSpecOldClass => klass
203 end
Kevin Clark2a8a7312008-06-18 01:01:07 +0000204 stub_stderr(klass)
Kevin Clarkf5754ac2008-06-18 01:00:12 +0000205 ::DeprecationSpecOldClass.should eql(klass)
206 ::DeprecationSpecOldClass.new.foo.should == "foo"
Kevin Clark3eca0782008-06-18 00:54:53 +0000207 ensure
Kevin Clark96cc5162008-06-18 00:56:08 +0000208 Object.send :remove_const, :DeprecationSpecOldClass if Object.const_defined? :DeprecationSpecOldClass
Kevin Clark3eca0782008-06-18 00:54:53 +0000209 end
210 end
Kevin Clark2a8a7312008-06-18 01:01:07 +0000211
212 it "should not prevent the deprecated class from being a superclass" do
213 begin
214 klass = Class.new do
215 def foo
216 "foo"
217 end
218 end
219 deprecate_class! :DeprecationSpecOldClass => klass
220 subklass = Class.new(::DeprecationSpecOldClass) do
221 def foo
222 "subclass #{super}"
223 end
224 end
225 stub_stderr(klass)
226 subklass.superclass.should eql(klass)
227 subklass.new.foo.should == "subclass foo"
228 ensure
229 Object.send :remove_const, :DeprecationSpecOldClass if Object.const_defined? :DeprecationSpecOldClass
230 end
231 end
Kevin Clark3eca0782008-06-18 00:54:53 +0000232end