From: Kevin Clark Date: Wed, 18 Jun 2008 01:01:25 +0000 (+0000) Subject: Implement deprecate_module! and fully spec it X-Git-Tag: 0.2.0~622 X-Git-Url: https://source.supwisdom.com/gerrit/gitweb?a=commitdiff_plain;h=03a5fb1dd7982367d733b43786935b982120b987;p=common%2Fthrift.git 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 d237ee49..f2b57ae1 100644 --- a/lib/rb/lib/thrift/deprecation.rb +++ b/lib/rb/lib/thrift/deprecation.rb @@ -32,7 +32,7 @@ class Module 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 @@ module Thrift::DeprecationProxy 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 @@ module Kernel 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 ff10177c..0b994fd8 100644 --- a/lib/rb/spec/deprecation_spec.rb +++ b/lib/rb/spec/deprecation_spec.rb @@ -13,6 +13,14 @@ shared_examples_for "deprecation" do 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 @@ describe "deprecate_class!" do 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 @@ describe "deprecate_class!" do 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 @@ describe "deprecate_class!" do 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 @@ describe "deprecate_class!" do 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