Implement deprecate_module! and fully spec it
git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@668927 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/rb/lib/thrift/deprecation.rb b/lib/rb/lib/thrift/deprecation.rb
index d237ee4..f2b57ae 100644
--- a/lib/rb/lib/thrift/deprecation.rb
+++ b/lib/rb/lib/thrift/deprecation.rb
@@ -32,7 +32,7 @@
end
module Thrift::DeprecationProxy
- def self.new(obj)
+ def self.new_class(obj)
Class.new(obj) do
klass = self
@@self = klass
@@ -65,6 +65,36 @@
end
end
end
+ def self.new_module(obj)
+ Module.new do
+ @@obj = obj
+ @warned = false
+ include obj
+ instance_methods.sort.reject { |x| [:__id__,:__send__].include? x.to_sym }.each do |sym|
+ undef_method sym
+ end
+ def method_missing(sym, *args, &block)
+ STDERR.puts "Warning: module #{@@obj.inspect} is deprecated"
+ STDERR.puts " from #{caller.first}"
+ @@obj.instance_method(sym).bind(self).call(*args, &block)
+ end
+ (class << self;self;end).class_eval do
+ @@obj = obj
+ @@warned = false
+ instance_methods.sort.reject { |x| [:__id__,:__send__].include? x.to_sym }.each do |sym|
+ undef_method sym
+ end
+ def method_missing(sym, *args, &block)
+ unless @@warned
+ STDERR.puts "Warning: module #{@@obj.inspect} is deprecated"
+ STDERR.puts " from #{caller.first}"
+ @@warned = true
+ end
+ @@obj.send sym, *args, &block
+ end
+ end
+ end
+ end
end
module Kernel
@@ -78,7 +108,15 @@
def deprecate_class!(klasses)
return unless Thrift::DEPRECATION
klasses.each_pair do |old, new|
- Object.const_set old, Thrift::DeprecationProxy.new(new)
+ Object.const_set old, Thrift::DeprecationProxy.new_class(new)
+ end
+ end
+
+ # like deprecate_class! but for Modules
+ def deprecate_module!(modules)
+ return unless Thrift::DEPRECATION
+ modules.each_pair do |old, new|
+ Object.const_set old, Thrift::DeprecationProxy.new_module(new)
end
end
end
diff --git a/lib/rb/spec/deprecation_spec.rb b/lib/rb/spec/deprecation_spec.rb
index ff10177..0b994fd 100644
--- a/lib/rb/spec/deprecation_spec.rb
+++ b/lib/rb/spec/deprecation_spec.rb
@@ -13,6 +13,14 @@
Thrift.send :remove_const, :DEPRECATION
Thrift.const_set :DEPRECATION, false
end
+
+ def ensure_const_removed(name, &block)
+ begin
+ block.call
+ ensure
+ Object.send :remove_const, name if Object.const_defined? name
+ end
+ end
end
describe 'deprecate!' do
@@ -175,7 +183,7 @@
end
it "should create a new global constant that points to the old one" do
- begin
+ ensure_const_removed :DeprecationSpecOldClass do
klass = Class.new do
def foo
"foo"
@@ -185,15 +193,13 @@
stub_stderr(klass)
::DeprecationSpecOldClass.should eql(klass)
::DeprecationSpecOldClass.new.foo.should == "foo"
- ensure
- Object.send :remove_const, :DeprecationSpecOldClass if Object.const_defined? :DeprecationSpecOldClass
end
end
it "should create a global constant even from inside a module" do
- begin
+ ensure_const_removed :DeprecationSpecOldClass do
klass = nil #define scoping
- mod = Module.new do
+ Module.new do
klass = Class.new do
def foo
"foo"
@@ -204,13 +210,11 @@
stub_stderr(klass)
::DeprecationSpecOldClass.should eql(klass)
::DeprecationSpecOldClass.new.foo.should == "foo"
- ensure
- Object.send :remove_const, :DeprecationSpecOldClass if Object.const_defined? :DeprecationSpecOldClass
end
end
it "should not prevent the deprecated class from being a superclass" do
- begin
+ ensure_const_removed :DeprecationSpecOldClass do
klass = Class.new do
def foo
"foo"
@@ -225,8 +229,96 @@
stub_stderr(klass)
subklass.superclass.should eql(klass)
subklass.new.foo.should == "subclass foo"
- ensure
- Object.send :remove_const, :DeprecationSpecOldClass if Object.const_defined? :DeprecationSpecOldClass
+ end
+ end
+end
+
+describe "deprecate_module!" do
+ it_should_behave_like "deprecation"
+
+ def stub_stderr(callstr, offset=1)
+ STDERR.should_receive(:puts).with("Warning: module #{callstr} is deprecated")
+ line = caller.first[/\d+$/].to_i + offset
+ STDERR.should_receive(:puts).with(" from #{__FILE__}:#{line}")
+ end
+
+ it "should create a new global constant that points to the old one" do
+ ensure_const_removed :DeprecationSpecOldModule do
+ mod = Module.new do
+ def self.foo
+ "foo"
+ end
+ end
+ deprecate_module! :DeprecationSpecOldModule => mod
+ stub_stderr(mod)
+ ::DeprecationSpecOldModule.should eql(mod)
+ ::DeprecationSpecOldModule.foo.should == "foo"
+ end
+ end
+
+ it "should create a global constant even from inside a module" do
+ ensure_const_removed :DeprecationSpecOldModule do
+ mod = nil # scoping
+ Module.new do
+ mod = Module.new do
+ def self.foo
+ "foo"
+ end
+ end
+ deprecate_module! :DeprecationSpecOldModule => mod
+ end
+ stub_stderr(mod)
+ ::DeprecationSpecOldModule.should eql(mod)
+ ::DeprecationSpecOldModule.foo.should == "foo"
+ end
+ end
+
+ it "should work for modules that extend themselves" do
+ ensure_const_removed :DeprecationSpecOldModule do
+ mod = Module.new do
+ extend self
+ def foo
+ "foo"
+ end
+ end
+ deprecate_module! :DeprecationSpecOldModule => mod
+ stub_stderr(mod)
+ ::DeprecationSpecOldModule.should eql(mod)
+ ::DeprecationSpecOldModule.foo.should == "foo"
+ end
+ end
+
+ it "should work for modules included in other modules" do
+ ensure_const_removed :DeprecationSpecOldModule do
+ mod = Module.new do
+ def foo
+ "foo"
+ end
+ end
+ deprecate_module! :DeprecationSpecOldModule => mod
+ mod2 = Module.new do
+ class << self
+ include ::DeprecationSpecOldModule
+ end
+ end
+ stub_stderr(mod)
+ mod2.foo.should == "foo"
+ end
+ end
+
+ it "should work for modules included in classes" do
+ ensure_const_removed :DeprecationSpecOldModule do
+ mod = Module.new do
+ def foo
+ "foo"
+ end
+ end
+ deprecate_module! :DeprecationSpecOldModule => mod
+ klass = Class.new do
+ include ::DeprecationSpecOldModule
+ end
+ stub_stderr(mod)
+ klass.new.foo.should == "foo"
end
end
end