deprecator 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -2,11 +2,17 @@
2
2
 
3
3
  Yet another library for dealing with code deprecation in ruby gracefully.
4
4
 
5
+ Allows you to replace behavior. For example before some important release you want to revise all deprecated code that is being called by your tests (and you have near 100% coverage, don't you?) - you can just throw in a strategy, that raises an error.
6
+
7
+ The same technique also provides for ability to make deprecation messages localized via l10n/i18n etc.
8
+
5
9
  ## Installation
6
10
 
7
11
  Add this line to your application's Gemfile:
8
12
 
13
+ ```ruby
9
14
  gem 'deprecator'
15
+ ```
10
16
 
11
17
  And then execute:
12
18
 
@@ -20,7 +26,73 @@ Or install it yourself as:
20
26
 
21
27
  ```ruby
22
28
 
29
+ #!/usr/bin/env ruby
30
+
31
+ require 'deprecator'
32
+
33
+ class SomeClass
34
+ deprecated
35
+
36
+ def method1
37
+ deprecated
38
+ end
39
+
40
+ def method2
41
+ if true
42
+ deprecated "this is deprecated when true is true"
43
+ end
44
+ end
45
+
46
+ deprecated_method
47
+ def method3
48
+ end
49
+
50
+ deprecated_method :method4, "%{method} is no longer here, use some other method!"
51
+ deprecated_method [:method5, :method6], "%{method} is no longer here, use some other method!"
52
+ end
53
+
54
+ obj = SomeClass.new # outputs to stderr: [DEPRECATED] deprecated class SomeClass instantiated at /Users/vasfed/work/deprecator/examples/example.rb:26:in `new'
55
+ obj.method1 # [DEPRECATED] method1 is deprecated!
56
+ obj.method2 # [DEPRECATED] this is deprecated when true is true
57
+ obj.method3 # [DEPRECATED] method method3 is deprecated. Called from /Users/vasfed/work/deprecator/examples/example.rb:28:in `<top (required)>'
58
+ obj.method4 # [DEPRECATED] method4 is no longer here, use some other method!
59
+ obj.method6 # [DEPRECATED] method6 is no longer here, use some other method!
60
+
61
+ ```
62
+
63
+ changing strategies:
64
+
65
+ ```ruby
66
+
67
+ Deprecator.strategy = :raise # included: warning(default), raise, raiseHard
68
+
69
+ class SomeClass
70
+ deprecated "some reason"
71
+ def initialize
72
+ puts "SomeClass#initialize called"
73
+ end
74
+ end
75
+
76
+ begin
77
+ SomeClass.new
78
+ rescue Deprecator::Deprecated => e
79
+ puts "caught exception #{e.class}: #{e}"
80
+ end
81
+
82
+
83
+ class CustomStrategy < Deprecator::Strategy::Base
84
+ def object_found *args
85
+ puts "Deprecated object created."
86
+ end
87
+ end
88
+
89
+ Deprecator.strategy = CustomStrategy
90
+ SomeClass.new
23
91
 
92
+ # outputs:
93
+ # caught exception Deprecator::DeprecatedObjectCreated: some reason
94
+ # Deprecated object created.
95
+ # SomeClass#initialize called
24
96
 
25
97
  ```
26
98
 
data/Rakefile CHANGED
@@ -13,3 +13,7 @@ end
13
13
  # task :test => :compile
14
14
 
15
15
  task :default => :test
16
+
17
+ task :run_example do
18
+ load File.expand_path('../examples/example.rb', __FILE__)
19
+ end
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'deprecator'
4
+
5
+ class SomeClass
6
+ deprecated
7
+
8
+ def method1
9
+ deprecated
10
+ end
11
+
12
+ def method2
13
+ if true
14
+ deprecated "this is deprecated when true is true"
15
+ end
16
+ end
17
+
18
+ deprecated_method
19
+ def method3
20
+ end
21
+
22
+ deprecated_method :method4, "%{method} is no longer here, use some other method!"
23
+ deprecated_method [:method5, :method6], "%{method} is no longer here, use some other method!"
24
+ end
25
+
26
+ obj = SomeClass.new # outputs to stderr: [DEPRECATED] deprecated class SomeClass instantiated at /Users/vasfed/work/deprecator/examples/example.rb:26:in `new'
27
+ obj.method1 # [DEPRECATED] method1 is deprecated!
28
+ obj.method2 # [DEPRECATED] this is deprecated when true is true
29
+ obj.method3 # [DEPRECATED] method method3 is deprecated. Called from /Users/vasfed/work/deprecator/examples/example.rb:28:in `<top (required)>'
30
+ obj.method4 # [DEPRECATED] method4 is no longer here, use some other method!
31
+ obj.method6 # [DEPRECATED] method6 is no longer here, use some other method!
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'deprecator'
4
+
5
+ Deprecator.strategy = :raise # included: warning(default), raise, raiseHard
6
+
7
+ class SomeClass
8
+ deprecated "some reason"
9
+ def initialize
10
+ puts "SomeClass#initialize called"
11
+ end
12
+ end
13
+
14
+ begin
15
+ SomeClass.new
16
+ rescue Deprecator::Deprecated => e
17
+ puts "caught exception #{e.class}: #{e}"
18
+ end
19
+
20
+
21
+ class CustomStrategy < Deprecator::Strategy::Base
22
+ def object_found *args
23
+ puts "Deprecated object created."
24
+ end
25
+ end
26
+
27
+ Deprecator.strategy = CustomStrategy
28
+ SomeClass.new
29
+
30
+ # outputs:
31
+ # caught exception Deprecator::DeprecatedObjectCreated: some reason
32
+ # Deprecated object created.
33
+ # SomeClass#initialize called
@@ -4,28 +4,48 @@ require 'is_a'
4
4
 
5
5
  module Deprecator
6
6
 
7
+ class UnknownStrategy < ArgumentError; end
8
+
9
+ class Deprecated < RuntimeError; end
10
+ class DeprecatedMethodCalled < Deprecated; end
11
+ class DeprecatedObjectCreated < Deprecated; end
12
+
13
+ class CodeError < RuntimeError; end
14
+ class NotImplemented < CodeError; end
15
+ class Fixme < CodeError; end
16
+ class Todo < CodeError; end
17
+
18
+
19
+
20
+
7
21
  class DeprecatedClass
8
22
  def self.inherited cls
9
- cls.extend(Deprecated)
23
+ ::Deprecator.strategy.class_found(cls, caller_line)
24
+ # cls.extend(Deprecated::ClassMethods)
25
+ # cls.send :include, Deprecated::InstanceMethods
10
26
  end
11
27
  end
12
28
 
13
- module Deprecated
29
+ module DeprecatorModule
14
30
  def self.included cls
15
31
  cls.extend self
16
32
  end
17
33
 
18
34
  def self.extended cls
19
35
  ::Deprecator.strategy.class_found(cls, caller_line)
20
- cls.send :include, InstanceMethods
36
+ # cls.send :include, InstanceMethods
37
+ # cls.extend ClassMethods
21
38
  end
22
39
 
23
- module InstanceMethods
24
- # SMELL: initialize in module is no good, but in this case may help for some cases
25
- def initialize *args
26
- ::Deprecator.strategy.object_found(self, caller_line)
27
- end
28
- end
40
+ # module ClassMethods
41
+ # end
42
+
43
+ # module InstanceMethods
44
+ # # SMELL: initialize in module is no good, but in this case may help for some cases
45
+ # def initialize *args
46
+ # ::Deprecator.strategy.object_found(self, caller_line)
47
+ # end
48
+ # end
29
49
  Class = DeprecatedClass
30
50
  end
31
51
 
@@ -42,17 +62,21 @@ module Deprecator
42
62
  @method_added_stack.push(m)
43
63
  end
44
64
 
65
+ @skip_next_method_added_addition = true
45
66
  define_singleton_method(:method_added, ->(name){
46
67
  return if name == :method_added
47
68
  super(name)
48
69
  old = @method_added_stack.pop
49
70
  if old
71
+ @skip_next_method_added_addition = true
50
72
  define_singleton_method(:method_added, old)
73
+ remove_instance_variable :@skip_next_method_added_addition
51
74
  else
52
75
  class <<self; remove_method(:method_added); end
53
76
  end
54
77
  blk.call(name)
55
78
  })
79
+ remove_instance_variable :@skip_next_method_added_addition
56
80
  end
57
81
 
58
82
  def deprecated_method name=nil, reason=nil, &blk
@@ -78,8 +102,6 @@ module Deprecator
78
102
 
79
103
  DefaultStrategy = Strategy::Warning
80
104
 
81
- class UnknownStrategy < ArgumentError; end
82
- class NotImplemented < RuntimeError; end
83
105
 
84
106
  @@strategy = nil
85
107
  def self.strategy
@@ -22,5 +22,5 @@ module Kernel
22
22
  alias NOT_IMPLEMENTED not_implemented
23
23
  end
24
24
 
25
- DEPRECATED = Deprecator::Deprecated
25
+ DEPRECATED = Deprecator::DeprecatorModule
26
26
  Deprecated = DEPRECATED unless Object.const_defined?(:Deprecated)
@@ -1,15 +1,38 @@
1
1
  module Deprecator
2
2
  module Strategy
3
3
 
4
-
5
4
  class Base
6
- def class_found o, where=nil, reason=nil, args=nil
7
- # msg(if reason
8
- # reason.gsub(/%{cls}/, o)
9
- # else
10
- # "#{o} is deprecated!"
11
- # end, where)
5
+ #on class/module definition/extenting with deprecater or deprecate statement
6
+ def class_found cls, where=nil, reason=nil, args=nil
7
+ this = self
8
+ cls.send(:define_method, :initialize){|*args|
9
+ ::Deprecator.strategy.object_found(cls, self, reason, caller_line, where)
10
+ }
11
+
12
+ cls.send(:define_singleton_method, :method_added, ->(name){
13
+ super(name)
14
+ if name == :initialize && !@skip_next_initialize_addition
15
+ meth = instance_method(name)
16
+ @skip_next_initialize_addition = true
17
+ define_method(name){|*args|
18
+ ::Deprecator.strategy.object_found(cls, self, reason, caller_line, where)
19
+ meth.bind(self).call(*args)
20
+ }
21
+ remove_instance_variable :@skip_next_initialize_addition
22
+ end
23
+ })
24
+ cls.send(:define_singleton_method, :singleton_method_added, ->(name){
25
+ #guard for self?
26
+ if name == :method_added && !@skip_next_method_added_addition
27
+ warn "[WARNING] when you replace method_added for deprecated class - you can no longer autotrack its object creation, use deprecation of initialize method."
28
+ end
29
+ })
30
+ end
31
+
32
+ # on deprecated class initialize
33
+ def object_found cls, object, reason, where, deprecated_at
12
34
  end
35
+ # on method definition
13
36
  def method_found cls,name, reason, where=nil
14
37
  this = self
15
38
  unless cls.method_defined?(name) # also we may place stubs there for existing methods in other strategies
@@ -24,6 +47,8 @@ module Deprecator
24
47
  }
25
48
  end
26
49
  end
50
+ def method_called cls,name,reason=nil,where,defined_at; end
51
+ def deprecated reason=nil, where=caller_line, args=nil; end
27
52
  def fixme! msg, where, args; end
28
53
  def todo! msg, where, args; end
29
54
  def not_implemented msg, where, args
@@ -31,18 +56,20 @@ module Deprecator
31
56
  end
32
57
  end
33
58
 
59
+
60
+
34
61
  class Warning < Base
35
62
  def msg msg, where=nil
36
- warn "[DEPRECATED] #{msg}"
63
+ warn "[DEPRECATED] #{msg}".gsub('%{where}', where)
37
64
  end
38
65
 
39
- def object_found o, where=nil, reason=nil # deprecated class initialize
40
- msg "deprecated class #{o.class} instantiated", where
66
+ def object_found cls, object, reason, where, deprecated_at # deprecated class initialize
67
+ msg "deprecated class #{cls} instantiated at %{where}", where
41
68
  end
42
69
 
43
- # this is not entry point
44
70
  def method_called cls,name,reason=nil,where,defined_at
45
- msg "method #{name} is deprecated. Called from #{caller_line}"
71
+ reason ||= "method %{method} is deprecated. Called from %{where}"
72
+ msg reason.gsub('%{method}', name.to_s), where
46
73
  end
47
74
 
48
75
  def deprecated reason=nil, where=caller_line, args=nil
@@ -55,5 +82,45 @@ module Deprecator
55
82
  end
56
83
 
57
84
 
85
+
86
+ class Raise < Base
87
+ def object_found cls, object, reason, where, deprecated_at # deprecated class initialize
88
+ raise DeprecatedObjectCreated, reason || "deprecated"
89
+ end
90
+
91
+ def method_called cls,name,reason=nil,where,defined_at
92
+ reason ||= "method %{method} is deprecated."
93
+ raise DeprecatedMethodCalled, (reason || "deprecated").gsub('%{method}', name.to_s)
94
+ end
95
+
96
+ def deprecated reason=nil, where=caller_line, args=nil
97
+ where =~ /in `(.+)'$/
98
+ method_name = $1 || '<unknown>'
99
+ reason ||= "%{method} is deprecated!"
100
+ reason.gsub!('%{method}', method_name)
101
+ raise Deprecated, reason
102
+ end
103
+ end
104
+
105
+
106
+
107
+ class RaiseHard < Raise
108
+ def class_found cls, where=nil, reason=nil, args=nil
109
+ raise Deprecated, "#{cls} is deprecated"
110
+ end
111
+
112
+ def method_found cls,name, reason, where=nil
113
+ raise Deprecated, "#{cls}##{name} is deprecated"
114
+ end
115
+
116
+ def fixme! msg, where, args;
117
+ raise Deprecator::Fixme, msg
118
+ end
119
+
120
+ def todo! msg, where, args
121
+ raise Deprecator::Todo, msg
122
+ end
123
+ end
124
+
58
125
  end
59
126
  end
@@ -1,3 +1,3 @@
1
1
  module Deprecator
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -46,7 +46,7 @@ describe Deprecator do
46
46
 
47
47
  context "methods" do
48
48
  before{
49
- subject.strategy = :warning
49
+ subject.strategy = :base
50
50
  }
51
51
  it "simple" do
52
52
  subject.strategy.should_receive(:deprecated).with("reason", duck_type(:to_s), [])
@@ -73,6 +73,34 @@ describe Deprecator do
73
73
  end
74
74
 
75
75
  context "strategy" do
76
+ context "also installs hooks for class instantiation" do
77
+ before{ subject.strategy = :base }
78
+ it "without a reason passed" do
79
+ cls = Class.new(DEPRECATED::Class)
80
+ subject.strategy.should_receive(:object_found).with(cls, kind_of(cls), nil, /#{Regexp.escape __FILE__}:#{__LINE__+1}/, /#{Regexp.escape __FILE__}:#{__LINE__-1}/)
81
+ cls.new
82
+ end
83
+
84
+ it "with reason passed" do
85
+ cls = Class.new{ deprecated "reason" }
86
+ subject.strategy.should_receive(:object_found).with(cls, kind_of(cls), "reason", /#{Regexp.escape __FILE__}:#{__LINE__+1}/, /#{Regexp.escape __FILE__}:#{__LINE__-1}/)
87
+ cls.new
88
+ end
89
+
90
+ it "and guards for initialize method" do
91
+ cls = Class.new{
92
+ deprecated "reason"
93
+ # def self.method_added(name); puts "method added #{name}"; end
94
+ def initialize
95
+ self.class.initialize_called
96
+ end
97
+ }
98
+ cls.should_receive(:initialize_called).once
99
+ subject.strategy.should_receive(:object_found).with(cls, kind_of(cls), "reason", /#{Regexp.escape __FILE__}:#{__LINE__+1}/, /#{Regexp.escape __FILE__}:#{__LINE__-7}/)
100
+ cls.new
101
+ end
102
+ end
103
+
76
104
  context "set" do
77
105
  it "via object" do
78
106
  obj = Object.new
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: deprecator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -89,6 +89,8 @@ files:
89
89
  - README.md
90
90
  - Rakefile
91
91
  - deprecator.gemspec
92
+ - examples/example.rb
93
+ - examples/example2.rb
92
94
  - lib/deprecator.rb
93
95
  - lib/deprecator/core_ext.rb
94
96
  - lib/deprecator/strategy.rb
@@ -116,7 +118,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
116
118
  version: '0'
117
119
  segments:
118
120
  - 0
119
- hash: -2851817988265802731
121
+ hash: 2302177472746095841
120
122
  requirements: []
121
123
  rubyforge_project:
122
124
  rubygems_version: 1.8.24