Skip to content

Commit

Permalink
Merge pull request #10 from KitaitiMakoto/obsolete
Browse files Browse the repository at this point in the history
Add Obsolete decorator
  • Loading branch information
michaelfairley committed Dec 19, 2013
2 parents 6c9774b + faf20c6 commit bb9eabb
Show file tree
Hide file tree
Showing 2 changed files with 199 additions and 0 deletions.
84 changes: 84 additions & 0 deletions lib/method_decorators/deprecated.rb
@@ -0,0 +1,84 @@
require 'method_decorators'

module MethodDecorators
# Example:
# class MyClass
# extend MethodDecorators
#
# +MethodDecorators::Deprecated
# def deprecated_method
# brand_new_method
# end
# end
# When deprecated_method is called, message
# "MyClass#deprecated_method is deprecated"
# is output.
#
# Another example:
# class MyClass
# extend MethodDecorators
#
# +MethodDecorators::Deprecated.new('deprecated_method will be removed in the future')
# def deprecated_method
# brand_new_method
# end
# end
# Above output given message
# "deprecated_method will be removed in the future"
#
# Custom message example:
# class MyClass
# extend MethodDecorators
#
# +MethodDecorators::Deprecated.new {|class_name, method_name| "#{class_name}##{method_name} will be removed in the future. Use #{class_name}#brand_new_method instead"}
# def deprecated_method
# brand_new_method
# end
# end
# Outputs
# "MyClass#deprecated_method will be removed in the future. Use MyClass#brand_new_method instead"
# As you see, you can use class name as the first argument and method name as the second in the block.
#
# Formatter example:
# class Formatter2
# def call(class_name, method_name)
# "#{class_name}##{method_name} will be removed after the next version. Use #{class_name}#brand_new_method instead"
# end
# end
# class MyClass
# extend MethodDecorators
#
# formatter1 = ->(class_mane, method_name) {"#{class_name}##{method_name} will be removed in the next version. Use #{class_name}#brand_new_method instead"}
# +MethodDecorators::Deprecated.new(formatter1)
# def very_old_method
# brand_new_method
# end
#
# + MethodDecorators::Deprecated.new(Formatter2.new)
# def deprecated_method
# brand_new_method
# end
# end
# Outputs
# "MyClass#deprecated_method will be removed in the future. Use MyClass#brand_new_method instead"
# You can give any object which responds to method "call" like Proc.
class Deprecated < Decorator
DEFAULT_FORMATTER = lambda {|class_name, method_name| "#{class_name}##{method_name} is deprecated"}
def initialize(message=nil, &blk)
@message = message || blk || DEFAULT_FORMATTER
end

def call(orig, this, *args, &blk)
warn message(this.class, orig.name)
orig.call(*args, &blk)
end

def message(class_name, method_name)
if @message.respond_to? :call
@message.call(class_name, method_name)
else
@message.to_s
end
end
end
end
115 changes: 115 additions & 0 deletions spec/decorators/deprecated.rb
@@ -0,0 +1,115 @@
require 'spec_helper'
require 'method_decorators/deprecated'
require 'stringio'

describe MethodDecorators::Deprecated do
let(:method) { double(:method, :call => 'return value of original method', :name => 'deprecated_method') }

describe '#call' do
subject { MethodDecorators::Deprecated.new }

it 'calls original method' do
method.should_receive(:call)
subject.call(method, nil)
end

it 'warns' do
subject.should_receive(:warn)
subject.call(method, nil)
end

context 'when string given on initializing' do
subject { MethodDecorators::Deprecated.new('custom message') }

it 'warns with given string' do
subject.should_receive(:warn).with('custom message')
subject.call(method, nil)
end
end

context 'when block given on initializing' do
subject { MethodDecorators::Deprecated.new {|klass, method| "#{klass}##{method}"} }

it 'warns with message formatted by the block' do
subject.should_receive(:warn).with('NilClass#deprecated_method')
subject.call(method, nil)
end
end

context 'when object which has #call method given on initializing' do
subject { MethodDecorators::Deprecated.new(lambda { |klass, method| "#{klass}##{method}" }) }

it 'warns with message formatted by the object' do
subject.should_receive(:warn).with('NilClass#deprecated_method')
subject.call(method, nil)
end
end
end

describe 'acceptance' do
before do
$stderr = StringIO.new
subject.deprecated_method
$stderr.rewind
end

let(:klass) {
Class.new Base do
+MethodDecorators::Deprecated
def deprecated_method
'return value of original method'
end
end
}
subject { klass.new }

it 'warns' do
expect($stderr.read).to eq("#{klass}#deprecated_method is deprecated\n")
end

context 'when string given on initializing' do
let(:klass) {
Class.new Base do
+MethodDecorators::Deprecated.new('custom message')
def deprecated_method
'return value of original method'
end
end
}

it 'warns with given string' do
expect($stderr.read).to eq("custom message\n")
end
end

context 'when block given on initializing' do
let(:klass) {
Class.new Base do
+MethodDecorators::Deprecated.new {|class_name, method_name| "#{class_name}##{method_name} is deprecated"}
def deprecated_method
'return value of original method'
end
end
}

it 'warns with message formatted by the block' do
expect($stderr.read).to eq("#{klass}#deprecated_method is deprecated\n")
end
end

context 'when object witch has #call method givn on initializing' do
let(:klass) {
Class.new Base do
+MethodDecorators::Deprecated.new(lambda { |class_name, method_name| "#{class_name}##{method_name} is deprecated" })
def deprecated_method
'return value of original method'
end
end
}

it 'warns with message formatted by the object' do
expect($stderr.read).to eq("#{klass}#deprecated_method is deprecated\n")
end
end
end
end

0 comments on commit bb9eabb

Please sign in to comment.