deprecations 1.0.6 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +29 -12
- data/Rakefile +1 -2
- data/deprecations.gemspec +6 -4
- data/lib/deprecations/behavior.rb +55 -0
- data/lib/deprecations/extension.rb +12 -7
- data/lib/deprecations/version.rb +1 -1
- data/lib/deprecations.rb +8 -34
- data/spec/deprecations/behavior_spec.rb +98 -0
- data/spec/deprecations/version_spec.rb +2 -2
- data/spec/deprecations_spec.rb +167 -318
- data/spec/spec_helper.rb +0 -2
- metadata +25 -5
- data/lib/deprecations/configuration.rb +0 -35
- data/spec/deprecations/configuration_spec.rb +0 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8f1b32b67d233b85169a77021d6f79004ee7c71e
|
4
|
+
data.tar.gz: 2e30cbd6b533b5282053117e232f970161e94f61
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 78d456e28cd58b8789578f6bd38a3a2014b764a2e6f3ff8701974310fa6cfc88896a56922e024960a52e2ac84854ff357e864798ed579ce7deb1fde51c8c1de0
|
7
|
+
data.tar.gz: e3917883e117b8016fe92bc747a6c48bd8b0f9d753134bc4c482af9fd2084f0e496baed1b4704fe0d8c213734923ee4f6fa440a8b2e25309f588e4ef3a08c287
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
### deprecations 2.0.0
|
2
|
+
- supports custom behavior
|
3
|
+
- supports temporary behavior change
|
4
|
+
- supports inheritance of deprecated methods
|
5
|
+
- `Deprecations#configure` and `Deprecations#configuration` are obsolete (use `Deprecations#behavior`)
|
6
|
+
|
1
7
|
### deprecations 1.0.6
|
2
8
|
- support for textual alternative of deprecated methods
|
3
9
|
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Deprecations
|
2
2
|
|
3
|
-
This gem provides transparent declaration of deprecated methods and classes.
|
3
|
+
This gem provides transparent declaration of deprecated methods and classes. It's easy, small, has no dependencies and no overhead.
|
4
4
|
|
5
5
|
[](https://codeclimate.com/github/mblumtritt/deprecations)
|
6
6
|
|
@@ -46,7 +46,8 @@ class MySample
|
|
46
46
|
def clean
|
47
47
|
clear
|
48
48
|
end
|
49
|
-
|
49
|
+
|
50
|
+
deprecated :clean, :clear, 'next version'
|
50
51
|
|
51
52
|
end
|
52
53
|
```
|
@@ -55,27 +56,43 @@ Whenever the method `MySample#clean` is called this warning appears:
|
|
55
56
|
|
56
57
|
> [DEPRECATION] `MySample#clean` is deprecated and will be outdated next version. Please use `MySample#clear` instead.
|
57
58
|
|
58
|
-
|
59
|
+
Marking a complete class as deprecated will present the deprecation warning whenever this class is instantiated:
|
59
60
|
|
60
61
|
```ruby
|
61
|
-
|
62
|
-
|
62
|
+
class MySample
|
63
|
+
deprecated!
|
64
|
+
|
65
|
+
# some more code here...
|
63
66
|
end
|
64
67
|
```
|
65
68
|
|
66
|
-
|
69
|
+
You can change the behavior of notifying:
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
Deprecations.behavior = :raise
|
73
|
+
```
|
74
|
+
|
75
|
+
There are 3 pre-defined behaviors:
|
67
76
|
|
68
77
|
- `:raise` will raise an `DeprecationException` when a deprecated method is called
|
69
|
-
- `:silence` will do nothing
|
78
|
+
- `:silence` will do nothing (ignore the deprecation)
|
70
79
|
- `:warn` will print a warning (default behavior)
|
71
80
|
|
72
|
-
|
81
|
+
Besides this you can implement your own:
|
73
82
|
|
74
83
|
```ruby
|
75
|
-
|
76
|
-
deprecated
|
77
|
-
|
78
|
-
|
84
|
+
Deprecations.behavior = proc do |subject, _alternative, _outdated|
|
85
|
+
SuperLogger.warning "deprecated: #{subject}"
|
86
|
+
end
|
87
|
+
```
|
88
|
+
|
89
|
+
Any object responding to `#call` will be accepted as a valid handler.
|
90
|
+
|
91
|
+
Whenever you need to temporary change the standard behavior (like e.g. in your specs) you can do this like
|
92
|
+
|
93
|
+
```ruby
|
94
|
+
Deprecations.set_behavior(:silent) do
|
95
|
+
MyDeprecatedClass.new.do_some_magic
|
79
96
|
end
|
80
97
|
```
|
81
98
|
|
data/Rakefile
CHANGED
data/deprecations.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require File.expand_path('../lib/deprecations/version', __FILE__)
|
2
2
|
|
3
|
-
GemSpec= Gem::Specification.new do |spec|
|
3
|
+
GemSpec = Gem::Specification.new do |spec|
|
4
4
|
spec.required_rubygems_version = Gem::Requirement.new('>= 1.3.6')
|
5
5
|
spec.platform = Gem::Platform::RUBY
|
6
6
|
spec.required_ruby_version = '>= 2.0.0'
|
@@ -9,13 +9,14 @@ GemSpec= Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ['Mike Blumtritt']
|
10
10
|
spec.email = %w[mike.blumtritt@injixo.com]
|
11
11
|
spec.summary = 'Deprecation support for your project.'
|
12
|
-
spec.description =
|
12
|
+
spec.description = "This gem provides transparent declaration of deprecated methods and classes. "\
|
13
|
+
"It's easy, small, has no dependencies and no overhead."
|
13
14
|
spec.homepage = 'https://github.com/mblumtritt/deprecations'
|
14
15
|
spec.date = Time.now.strftime('%Y-%m-%d')
|
15
16
|
spec.require_paths = %w[lib]
|
16
17
|
spec.files = %x[git ls-files].split($/)
|
17
|
-
spec.test_files = spec.files.grep(%r[^
|
18
|
-
spec.extra_rdoc_files = %w[README.md]
|
18
|
+
spec.test_files = spec.files.grep(%r[^spec/])
|
19
|
+
spec.extra_rdoc_files = %w[README.md CHANGELOG.md]
|
19
20
|
spec.has_rdoc = false # TODO!
|
20
21
|
spec.add_development_dependency 'rake'
|
21
22
|
spec.add_development_dependency 'rspec', '>= 3.0.0'
|
@@ -23,6 +24,7 @@ GemSpec= Gem::Specification.new do |spec|
|
|
23
24
|
spec.add_development_dependency 'guard-rspec'
|
24
25
|
if /darwin|mac os/i =~ RUBY_PLATFORM
|
25
26
|
spec.add_development_dependency 'rb-fsevent'
|
27
|
+
spec.add_development_dependency 'terminal-notifier'
|
26
28
|
spec.add_development_dependency 'terminal-notifier-guard'
|
27
29
|
end
|
28
30
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Deprecations
|
2
|
+
class << self
|
3
|
+
|
4
|
+
def behavior
|
5
|
+
BEHAVIOR.key(@behavior) || @behavior
|
6
|
+
end
|
7
|
+
|
8
|
+
def behavior=(behavior)
|
9
|
+
@behavior = as_behavior(behavior)
|
10
|
+
end
|
11
|
+
|
12
|
+
def set_behavior(behavior)
|
13
|
+
behavior = as_behavior(behavior)
|
14
|
+
block_given? or raise(ArgumentError, 'block expected')
|
15
|
+
current_behavior = @behavior
|
16
|
+
begin
|
17
|
+
@behavior = behavior
|
18
|
+
yield
|
19
|
+
ensure
|
20
|
+
@behavior = current_behavior
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def as_behavior(arg)
|
27
|
+
defined?(arg.call) ? arg : BEHAVIOR.fetch(arg) do
|
28
|
+
raise(ArgumentError, "invalid parameter - behavior has to be #{valid_behavior} or need to respond to `call`")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def valid_behavior
|
33
|
+
BEHAVIOR.keys.map(&:inspect).join(' | ')
|
34
|
+
end
|
35
|
+
|
36
|
+
BEHAVIOR = {
|
37
|
+
silence: ->(*){},
|
38
|
+
raise: proc do |subject, alternative|
|
39
|
+
msg = "`#{subject}` is deprecated"
|
40
|
+
alternative and msg << " - use #{alternative} instead"
|
41
|
+
ex = ::DeprecationError.new(msg)
|
42
|
+
ex.set_backtrace(caller(4))
|
43
|
+
raise(ex)
|
44
|
+
end,
|
45
|
+
warn: proc do |subject, alternative, outdated |
|
46
|
+
location = caller_locations(4, 1).last and location = "#{location.path}:#{location.lineno}: "
|
47
|
+
msg = "#{location}[DEPRECATION] `#{subject}` is deprecated"
|
48
|
+
msg << (outdated ? " and will be outdated #{outdated}." : '.')
|
49
|
+
alternative and msg << " Please use `#{alternative}` instead."
|
50
|
+
::Kernel.warn(msg)
|
51
|
+
end
|
52
|
+
}
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
@@ -14,10 +14,11 @@ module Deprecations
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def __method_deprecated!(method, alternative, outdated)
|
17
|
+
defining_context = self
|
17
18
|
define_method(method.name) do |*a, &b|
|
18
|
-
decorated = Class === self ? "#{self}." : "#{
|
19
|
+
decorated = Class === self ? "#{self}." : "#{defining_context}#"
|
19
20
|
Deprecations.call(
|
20
|
-
"#{decorated}#{__method__}",
|
21
|
+
"#{decorated}#{::Kernel.__method__}",
|
21
22
|
UnboundMethod === alternative ? "#{decorated}#{alternative.name}" : alternative,
|
22
23
|
outdated
|
23
24
|
)
|
@@ -29,6 +30,9 @@ module Deprecations
|
|
29
30
|
raise(NameError, "undefined method `#{method_name}` for class `#{self}`")
|
30
31
|
end
|
31
32
|
|
33
|
+
def __method_alternative(alternative)
|
34
|
+
Symbol === alternative ? (__method(alternative) or __method_not_found!(alternative)) : alternative
|
35
|
+
end
|
32
36
|
end
|
33
37
|
|
34
38
|
module ClassMethods
|
@@ -36,9 +40,11 @@ module Deprecations
|
|
36
40
|
include Helper
|
37
41
|
|
38
42
|
def deprecated(method_name, alternative = nil, outdated = nil)
|
39
|
-
|
40
|
-
|
41
|
-
|
43
|
+
__method_deprecated!(
|
44
|
+
(__method(method_name) or __method_not_found!(method_name)),
|
45
|
+
__method_alternative(alternative),
|
46
|
+
outdated
|
47
|
+
)
|
42
48
|
end
|
43
49
|
end
|
44
50
|
|
@@ -48,8 +54,7 @@ module Deprecations
|
|
48
54
|
|
49
55
|
def deprecated(method_name, alternative = nil, outdated = nil)
|
50
56
|
m = __method(method_name) or return singleton_class.send(:deprecated, method_name, alternative, outdated)
|
51
|
-
|
52
|
-
__method_deprecated!(m, a, outdated)
|
57
|
+
__method_deprecated!(m, __method_alternative(alternative), outdated)
|
53
58
|
end
|
54
59
|
|
55
60
|
def deprecated!(alternative = nil, outdated = nil)
|
data/lib/deprecations/version.rb
CHANGED
data/lib/deprecations.rb
CHANGED
@@ -1,40 +1,14 @@
|
|
1
|
-
|
2
|
-
DeprecationError = Class.new(ScriptError)
|
3
|
-
|
4
1
|
module Deprecations
|
5
2
|
autoload(:VERSION, "#{__FILE__[/.*(?=\..+$)/]}/version")
|
6
|
-
require_relative 'deprecations/configuration'
|
7
3
|
require_relative 'deprecations/extension'
|
4
|
+
require_relative 'deprecations/behavior'
|
8
5
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
case configuration.behavior
|
13
|
-
when :warn
|
14
|
-
warn(subject, alternative, outdated)
|
15
|
-
when :raise
|
16
|
-
throw!(subject, alternative)
|
17
|
-
end
|
18
|
-
self
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def throw!(subject, alternative)
|
24
|
-
msg = "`#{subject}` is deprecated"
|
25
|
-
alternative and msg << " - use #{alternative} instead"
|
26
|
-
ex = DeprecationError.new(msg)
|
27
|
-
ex.set_backtrace(caller(3))
|
28
|
-
raise(ex)
|
29
|
-
end
|
30
|
-
|
31
|
-
def warn(subject, alternative, outdated)
|
32
|
-
location = ::Kernel.caller_locations(3,1).last and location = "#{location.path}:#{location.lineno}: "
|
33
|
-
msg = "#{location}[DEPRECATION] `#{subject}` is deprecated"
|
34
|
-
msg << (outdated ? " and will be outdated #{outdated}." : '.')
|
35
|
-
alternative and msg << " Please use `#{alternative}` instead."
|
36
|
-
::Kernel.warn(msg)
|
37
|
-
end
|
38
|
-
|
6
|
+
def self.call(subject, alternative, outdated)
|
7
|
+
@behavior.call(subject, alternative, outdated)
|
8
|
+
self
|
39
9
|
end
|
10
|
+
|
11
|
+
self.behavior = :warn
|
40
12
|
end
|
13
|
+
|
14
|
+
DeprecationError = Class.new(ScriptError)
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Deprecations do
|
4
|
+
context 'behavior' do
|
5
|
+
|
6
|
+
it 'is possible to configure the behavior with a pre-defined value' do
|
7
|
+
%i(silence raise warn).each do |behavior|
|
8
|
+
Deprecations.behavior = behavior
|
9
|
+
expect(Deprecations.behavior).to be(behavior)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'is possible to configure a custom behavior' do
|
14
|
+
custom = proc do |*args|
|
15
|
+
FantasticLogger.log(*args)
|
16
|
+
end
|
17
|
+
Deprecations.behavior = custom
|
18
|
+
expect(Deprecations.behavior).to be(custom)
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'standard behavior :silence' do
|
22
|
+
before do
|
23
|
+
Deprecations.behavior = :silence
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'does simply nothing' do
|
27
|
+
expect(subject.call(*%w(should be silent))).to be(subject)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'standard behavior :warn' do
|
32
|
+
before do
|
33
|
+
Deprecations.behavior = :warn
|
34
|
+
end
|
35
|
+
after do
|
36
|
+
Deprecations.call('Bad#method', 'Bad#alternative', 'after next version')
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'warns about the deprecation' do
|
40
|
+
expect(Kernel).to receive(:warn).once.with(/DEPRECATION/)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'points to the deprecated method' do
|
44
|
+
expect(Kernel).to receive(:warn).once.with(/Bad#method.*deprecated/)
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'suggests the alternative method' do
|
48
|
+
expect(Kernel).to receive(:warn).once.with(/Bad#alternative.*instead/)
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'contains information about when it will not longer supported' do
|
52
|
+
expect(Kernel).to receive(:warn).once.with(/outdated after next version/)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'standard behavior :raise' do
|
57
|
+
before do
|
58
|
+
Deprecations.behavior = :raise
|
59
|
+
end
|
60
|
+
subject{ Deprecations.call('Bad#method', 'Bad#alternative', 'after next version') }
|
61
|
+
|
62
|
+
it 'raises a Deprecations::Error' do
|
63
|
+
expect{ subject }.to raise_error(DeprecationError)
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'points to the deprecated method' do
|
67
|
+
expect{ subject }.to raise_error(DeprecationError, /Bad#method.*deprecated/)
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'suggests the alternative method' do
|
71
|
+
expect{ subject }.to raise_error(DeprecationError, /Bad#alternative.*instead/)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'change behavior temporary' do
|
76
|
+
let(:sample_class) do
|
77
|
+
Class.new(BasicObject) do
|
78
|
+
deprecated!
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
before do
|
83
|
+
Deprecations.behavior = :raise
|
84
|
+
end
|
85
|
+
|
86
|
+
after do
|
87
|
+
Deprecations.set_behavior(:warn) do
|
88
|
+
sample_class.new.__id__
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'is possible to temporary use a different behavior' do
|
93
|
+
expect(Kernel).to receive(:warn).once
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
RSpec.describe Deprecations::VERSION do
|
3
|
+
RSpec.describe 'Deprecations::VERSION' do
|
4
4
|
it 'has format <major>.<minor>.<build>' do
|
5
|
-
expect(
|
5
|
+
expect(Deprecations::VERSION).to match(/^\d{1,2}\.\d{1,2}\.\d{1,3}/)
|
6
6
|
end
|
7
7
|
end
|
data/spec/deprecations_spec.rb
CHANGED
@@ -1,380 +1,229 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
module DeprecationsSamples # samples how to use
|
4
|
-
|
5
|
-
# mixin with some methods for demonstration
|
6
|
-
module MethodSamples
|
7
|
-
def foo(*parameters)
|
8
|
-
block_given? ? yield(parameters) : {foo: parameters}
|
9
|
-
end
|
10
|
-
|
11
|
-
def alt
|
12
|
-
:nop
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
# mixin with initializer method for demonstration
|
17
|
-
module InitializerSample
|
18
|
-
attr_reader :parameters
|
19
|
-
def initialize(*parameters)
|
20
|
-
@parameters = block_given? ? yield(parameters) : {foo: parameters}
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
# here we go:
|
25
|
-
|
26
|
-
class Sample1
|
27
|
-
include MethodSamples
|
28
|
-
deprecated :foo # Sample1#foo is deprecated
|
29
|
-
end
|
30
|
-
|
31
|
-
class Sample2
|
32
|
-
include MethodSamples
|
33
|
-
deprecated :foo, :alt # Sample2#foo is deprecated, Sample2#alt should be used
|
34
|
-
end
|
35
|
-
|
36
|
-
class Sample3
|
37
|
-
include MethodSamples
|
38
|
-
deprecated :foo, :alt, 'next version' # Sample3#foo is deprecated and will be outdated in next version, Sample3#alt should be used
|
39
|
-
end
|
40
|
-
|
41
|
-
class Sample4
|
42
|
-
extend MethodSamples
|
43
|
-
deprecated :foo # class method Sample4::foo is deprecated
|
44
|
-
end
|
45
|
-
|
46
|
-
class Sample5
|
47
|
-
extend MethodSamples
|
48
|
-
deprecated :foo, :alt # class method Sample5::foo is deprecated, Sample5::alt should be used
|
49
|
-
end
|
50
|
-
|
51
|
-
class Sample6
|
52
|
-
extend MethodSamples
|
53
|
-
deprecated :foo, :alt, 'next version' # class method Sample6::foo is deprecated and will be outdated in next version, Sample6::alt should be used
|
54
|
-
end
|
55
|
-
|
56
|
-
class Sample7
|
57
|
-
deprecated! # class Sample7 is deprecated
|
58
|
-
include InitializerSample
|
59
|
-
end
|
60
|
-
|
61
|
-
class Sample8
|
62
|
-
deprecated! Sample1 # class Sample8 is deprecated, class Sample1 should be used
|
63
|
-
include InitializerSample
|
64
|
-
end
|
65
|
-
|
66
|
-
class Sample9
|
67
|
-
deprecated! Sample1, 'in 2.0.0' # class Sample9 is deprecated and will be outdated in version 2.0.0, class Sample1 should be used
|
68
|
-
include InitializerSample
|
69
|
-
end
|
70
|
-
|
71
|
-
module AnonymousDefined
|
72
|
-
AnnoSample7 = Class.new do
|
73
|
-
deprecated! # class AnonymousDefined::AnnoSample7 is deprecated
|
74
|
-
include InitializerSample
|
75
|
-
end
|
76
|
-
|
77
|
-
AnnoSample8 = Class.new do
|
78
|
-
deprecated! Sample1 # class AnonymousDefined::AnnoSample8 is deprecated, class Sample1 should be used
|
79
|
-
include InitializerSample
|
80
|
-
end
|
81
|
-
|
82
|
-
AnnoSample9 = Class.new do
|
83
|
-
deprecated! Sample1, 'in 2.0.0' # class AnonymousDefined::AnnoSample9 is deprecated and will be outdated in version 2.0.0, class Sample1 should be used
|
84
|
-
include InitializerSample
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
end
|
89
|
-
|
90
|
-
RSpec.shared_examples_for 'a transparent deprecated method' do
|
91
|
-
it 'forwards all parameter and returns the original method`s result' do
|
92
|
-
allow(Kernel).to receive(:warn)
|
93
|
-
expect(sample.foo(:arg1, :arg2, 42)).to eq(foo: [:arg1, :arg2, 42])
|
94
|
-
end
|
95
|
-
|
96
|
-
it 'forwards a given Proc to the original method' do
|
97
|
-
allow(Kernel).to receive(:warn)
|
98
|
-
expect(sample.foo(:arg1, 'test', 42){ |p| {via_block: p} }).to eq(via_block: [:arg1, 'test', 42])
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
RSpec.shared_examples_for 'a deprecated method (warnings enabled)' do
|
103
|
-
it_should_behave_like 'a transparent deprecated method'
|
104
|
-
|
105
|
-
it 'warns about the deprecation' do
|
106
|
-
expect(Kernel).to receive(:warn).once.with(/\bDeprecationsSamples::Sample\d[\.#]foo\b.*\bdeprecated\b/)
|
107
|
-
sample.foo
|
108
|
-
end
|
109
|
-
|
110
|
-
it 'points to the calling line' do
|
111
|
-
expect(Kernel).to receive(:warn).with(/#{__FILE__}:#{__LINE__ + 1}/)
|
112
|
-
sample.foo
|
113
|
-
end
|
114
|
-
|
115
|
-
end
|
116
|
-
|
117
|
-
RSpec.shared_examples_for 'a deprecated method (should throw)' do
|
118
|
-
it 'raises an DeprecationError' do
|
119
|
-
expect{ sample.foo }.to raise_error(DeprecationError, /\bDeprecationsSamples::Sample\d[\.#]foo\b.*\bdeprecated\b/)
|
120
|
-
end
|
121
|
-
|
122
|
-
it 'has a helpful backtrace' do
|
123
|
-
backtrace = nil
|
124
|
-
begin
|
125
|
-
sample.foo
|
126
|
-
rescue DeprecationError => err
|
127
|
-
backtrace = err.backtrace
|
128
|
-
end
|
129
|
-
expect(backtrace.first).to match(/#{__FILE__}:#{__LINE__ - 4}/)
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
RSpec.shared_examples_for 'a transparent deprecated class' do
|
134
|
-
it 'calls the original initializer with all parameters' do
|
135
|
-
allow(Kernel).to receive(:warn)
|
136
|
-
instance = sample.new(:arg1, :arg2, 42)
|
137
|
-
expect(instance.parameters).to eq(foo: [:arg1, :arg2, 42])
|
138
|
-
end
|
139
|
-
|
140
|
-
it 'forwards a given Proc to the original initializer' do
|
141
|
-
allow(Kernel).to receive(:warn)
|
142
|
-
instance = sample.new(:arg1, 'test', 42){ |p| {via_block: p} }
|
143
|
-
expect(instance.parameters).to eq(via_block: [:arg1, 'test', 42])
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
RSpec.shared_examples_for 'a deprecated class (warnings enabled)' do
|
148
|
-
it_should_behave_like 'a transparent deprecated class'
|
149
|
-
|
150
|
-
it 'warns about the deprecation' do
|
151
|
-
expect(Kernel).to receive(:warn).once.with(/\b#{sample}\b.*\bdeprecated\b/)
|
152
|
-
sample.new
|
153
|
-
end
|
154
|
-
|
155
|
-
it 'points to the calling line' do
|
156
|
-
expect(Kernel).to receive(:warn).with(/#{__FILE__}:#{__LINE__ + 1}/)
|
157
|
-
sample.new
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
RSpec.shared_examples_for 'a deprecated class (should throw)' do
|
162
|
-
it 'raises an DeprecationError' do
|
163
|
-
expect{ sample.new }.to raise_error(DeprecationError, /\bDeprecationsSamples::Sample\d\b.*\bdeprecated\b/)
|
164
|
-
end
|
165
|
-
|
166
|
-
it 'has a helpful backtrace' do
|
167
|
-
backtrace = nil
|
168
|
-
begin
|
169
|
-
sample.new
|
170
|
-
rescue DeprecationError => err
|
171
|
-
backtrace = err.backtrace
|
172
|
-
end
|
173
|
-
expect(backtrace.first).to match(/#{__FILE__}:#{__LINE__ - 4}/)
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
3
|
RSpec.describe Deprecations do
|
178
|
-
context '
|
179
|
-
before
|
180
|
-
Deprecations.
|
181
|
-
end
|
182
|
-
|
183
|
-
context 'when an instance method is marked as deprecated' do
|
184
|
-
let(:sample){ DeprecationsSamples::Sample1.new }
|
185
|
-
it_should_behave_like 'a transparent deprecated method'
|
4
|
+
context 'policy' do
|
5
|
+
before do
|
6
|
+
Deprecations.behavior = :silence
|
186
7
|
end
|
187
8
|
|
188
|
-
context '
|
189
|
-
let(:sample){ DeprecationsSamples::Sample4 }
|
190
|
-
it_should_behave_like 'a transparent deprecated method'
|
191
|
-
end
|
192
|
-
|
193
|
-
context 'when a class is marked as deprecated' do
|
194
|
-
let(:sample){ DeprecationsSamples::Sample7 }
|
195
|
-
it_should_behave_like 'a transparent deprecated class'
|
196
|
-
end
|
197
|
-
end
|
9
|
+
context 'parameter forwarding' do
|
198
10
|
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
it_should_behave_like 'a deprecated method (warnings enabled)'
|
208
|
-
|
209
|
-
context 'when an optional alternative method is given' do
|
210
|
-
let(:sample){ DeprecationsSamples::Sample2.new }
|
211
|
-
|
212
|
-
it_should_behave_like 'a deprecated method (warnings enabled)'
|
213
|
-
|
214
|
-
it 'suggests the alternative method' do
|
215
|
-
expect(Kernel).to receive(:warn).with(/DeprecationsSamples::Sample2#alt.*instead/)
|
216
|
-
sample.foo
|
11
|
+
context 'when an instance method is marked as deprecated' do
|
12
|
+
subject do
|
13
|
+
Class.new(BasicObject) do
|
14
|
+
def foo(*args)
|
15
|
+
{foo: args}
|
16
|
+
end
|
17
|
+
deprecated :foo
|
18
|
+
end
|
217
19
|
end
|
218
|
-
end
|
219
20
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
it_should_behave_like 'a deprecated method (warnings enabled)'
|
224
|
-
|
225
|
-
it 'informs about when it will become outdated' do
|
226
|
-
expect(Kernel).to receive(:warn).with(/outdated next version/)
|
227
|
-
sample.foo
|
21
|
+
it 'forwards all parameters and returns the original method`s result' do
|
22
|
+
result = subject.new.foo(:arg1, :arg2, 42)
|
23
|
+
expect(result).to eq(foo: [:arg1, :arg2, 42])
|
228
24
|
end
|
229
25
|
end
|
230
|
-
end
|
231
|
-
|
232
|
-
context 'when a class method is marked as deprecated' do
|
233
|
-
let(:sample){ DeprecationsSamples::Sample4 }
|
234
|
-
|
235
|
-
it_should_behave_like 'a deprecated method (warnings enabled)'
|
236
26
|
|
237
|
-
context 'when
|
238
|
-
|
239
|
-
|
240
|
-
|
27
|
+
context 'when a class method is marked as deprecated' do
|
28
|
+
subject do
|
29
|
+
Class.new(BasicObject) do
|
30
|
+
def self.foo(*args)
|
31
|
+
{foo: args}
|
32
|
+
end
|
33
|
+
deprecated :foo
|
34
|
+
end
|
35
|
+
end
|
241
36
|
|
242
|
-
it '
|
243
|
-
|
244
|
-
|
37
|
+
it 'forwards all parameters and returns the original method`s result' do
|
38
|
+
result = subject.foo(:arg1, :arg2, 42)
|
39
|
+
expect(result).to eq(foo: [:arg1, :arg2, 42])
|
245
40
|
end
|
246
41
|
end
|
247
42
|
|
248
|
-
context 'when
|
249
|
-
|
250
|
-
|
251
|
-
|
43
|
+
context 'when a class is marked as deprecated' do
|
44
|
+
subject do
|
45
|
+
Class.new(BasicObject) do
|
46
|
+
attr_reader :parameters
|
47
|
+
def initialize(*parameters)
|
48
|
+
@parameters = parameters
|
49
|
+
end
|
50
|
+
deprecated!
|
51
|
+
end
|
52
|
+
end
|
252
53
|
|
253
|
-
it '
|
254
|
-
expect(
|
255
|
-
sample.foo
|
54
|
+
it 'forwards all parameters to the initializer and returns the original method`s result' do
|
55
|
+
expect(subject.new(:arg1, :arg2, 42).parameters).to eq([:arg1, :arg2, 42])
|
256
56
|
end
|
257
57
|
end
|
258
58
|
|
259
59
|
end
|
260
60
|
|
261
|
-
context '
|
262
|
-
let(:sample){ DeprecationsSamples::Sample7 }
|
61
|
+
context 'block forwarding' do
|
263
62
|
|
264
|
-
|
63
|
+
context 'when an instance method is marked as deprecated' do
|
64
|
+
subject do
|
65
|
+
Class.new(BasicObject) do
|
66
|
+
def foo(arg)
|
67
|
+
yield(arg)
|
68
|
+
end
|
69
|
+
deprecated :foo
|
70
|
+
end
|
71
|
+
end
|
265
72
|
|
266
|
-
|
267
|
-
|
73
|
+
it 'forwards a given Proc to the original method' do
|
74
|
+
result = subject.new.foo(41) do |arg|
|
75
|
+
{my_blocks_result: arg + 1}
|
76
|
+
end
|
77
|
+
expect(result).to eq(my_blocks_result: 42)
|
78
|
+
end
|
79
|
+
end
|
268
80
|
|
269
|
-
|
81
|
+
context 'when a class method is marked as deprecated' do
|
82
|
+
subject do
|
83
|
+
Class.new(BasicObject) do
|
84
|
+
def self.foo(arg)
|
85
|
+
yield(arg)
|
86
|
+
end
|
87
|
+
deprecated :foo
|
88
|
+
end
|
89
|
+
end
|
270
90
|
|
271
|
-
it '
|
272
|
-
|
273
|
-
|
91
|
+
it 'forwards a given Proc to the original method' do
|
92
|
+
result = subject.foo(665) do |arg|
|
93
|
+
{my_blocks_result: arg + 1}
|
94
|
+
end
|
95
|
+
expect(result).to eq(my_blocks_result: 666)
|
274
96
|
end
|
275
97
|
end
|
276
98
|
|
277
|
-
context 'when
|
278
|
-
|
279
|
-
|
280
|
-
|
99
|
+
context 'when a class is marked as deprecated' do
|
100
|
+
subject do
|
101
|
+
Class.new(BasicObject) do
|
102
|
+
attr_reader :value
|
103
|
+
def initialize(arg)
|
104
|
+
@value = yield(arg)
|
105
|
+
end
|
106
|
+
deprecated!
|
107
|
+
end
|
108
|
+
end
|
281
109
|
|
282
|
-
it '
|
283
|
-
|
284
|
-
|
110
|
+
it 'forwards a given Proc to the initializer' do
|
111
|
+
instance = subject.new(41) do |arg|
|
112
|
+
{my_blocks_result: arg + 1}
|
113
|
+
end
|
114
|
+
expect(instance.value).to eq(my_blocks_result: 42)
|
285
115
|
end
|
286
116
|
end
|
287
|
-
end
|
288
117
|
|
289
|
-
|
290
|
-
let(:sample){ DeprecationsSamples::AnonymousDefined::AnnoSample7 }
|
118
|
+
end
|
291
119
|
|
292
|
-
|
120
|
+
end
|
293
121
|
|
294
|
-
|
295
|
-
let(:sample){ DeprecationsSamples::AnonymousDefined::AnnoSample8 }
|
122
|
+
context 'handling' do
|
296
123
|
|
297
|
-
|
124
|
+
context 'when a method is marked as deprecated' do
|
298
125
|
|
299
|
-
|
300
|
-
|
301
|
-
|
126
|
+
context 'when an alternative method and a comment are present ' do
|
127
|
+
subject do
|
128
|
+
Class.new(BasicObject) do
|
129
|
+
def foo
|
130
|
+
end
|
131
|
+
def bar
|
132
|
+
end
|
133
|
+
deprecated :foo, :bar, 'next version'
|
134
|
+
end
|
302
135
|
end
|
303
|
-
end
|
304
136
|
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
it_should_behave_like 'a deprecated class (warnings enabled)'
|
137
|
+
after do
|
138
|
+
subject.new.foo
|
139
|
+
end
|
309
140
|
|
310
|
-
it '
|
311
|
-
expect(
|
312
|
-
|
141
|
+
it 'calls the handler with correct subject' do
|
142
|
+
expect(Deprecations).to receive(:call).once.with("#{subject}#foo", anything, anything)
|
143
|
+
end
|
144
|
+
it 'calls the handler with correct alternative method' do
|
145
|
+
expect(Deprecations).to receive(:call).once.with(anything, "#{subject}#bar", anything)
|
146
|
+
end
|
147
|
+
it 'calls the handler with a comment' do
|
148
|
+
expect(Deprecations).to receive(:call).once.with(anything, anything, 'next version')
|
313
149
|
end
|
314
150
|
end
|
315
|
-
end
|
316
|
-
|
317
|
-
context 'error cases' do
|
318
151
|
|
319
|
-
context 'when
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
deprecated :does_not_exist
|
152
|
+
context 'when no alternative method and no comment are present' do
|
153
|
+
subject do
|
154
|
+
Class.new(BasicObject) do
|
155
|
+
def bar
|
324
156
|
end
|
325
|
-
|
157
|
+
deprecated :bar
|
158
|
+
end
|
326
159
|
end
|
327
|
-
end
|
328
160
|
|
329
|
-
|
330
|
-
|
331
|
-
expect do
|
332
|
-
Class.new do
|
333
|
-
def foo; end
|
334
|
-
deprecated :foo, :not_existing_alternative
|
335
|
-
end
|
336
|
-
end.to raise_error(NameError, /undefined method.*not_existing_alternative/)
|
161
|
+
after do
|
162
|
+
subject.new.bar
|
337
163
|
end
|
338
|
-
end
|
339
164
|
|
340
|
-
|
341
|
-
|
165
|
+
it 'calls handler without an alternative method' do
|
166
|
+
expect(Deprecations).to receive(:call).once.with(anything, nil, anything)
|
167
|
+
end
|
168
|
+
it 'calls handler without a comment' do
|
169
|
+
expect(Deprecations).to receive(:call).once.with(anything, anything, nil)
|
170
|
+
end
|
171
|
+
end
|
342
172
|
|
343
|
-
context 'when configured to raise' do
|
344
|
-
before :all do
|
345
|
-
Deprecations.configuration.behavior = :raise
|
346
173
|
end
|
347
174
|
|
348
|
-
context 'when
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
let(:sample){ DeprecationsSamples::Sample2.new }
|
355
|
-
|
356
|
-
it_should_behave_like 'a deprecated method (should throw)'
|
175
|
+
context 'when a class is anonymous defined' do
|
176
|
+
module Samples
|
177
|
+
AnonymousDefined = Class.new(::BasicObject) do
|
178
|
+
def clean; end
|
179
|
+
def clear; end
|
180
|
+
deprecated :clean, :clear
|
357
181
|
|
358
|
-
|
359
|
-
|
182
|
+
def self.create; end
|
183
|
+
def self.make; end
|
184
|
+
deprecated :create, :make
|
360
185
|
end
|
361
186
|
end
|
362
|
-
end
|
363
187
|
|
364
|
-
|
365
|
-
|
188
|
+
it 'uses correct decorated instance method names' do
|
189
|
+
expect(Deprecations).to receive(:call).once.with(
|
190
|
+
'Samples::AnonymousDefined#clean',
|
191
|
+
'Samples::AnonymousDefined#clear',
|
192
|
+
nil
|
193
|
+
)
|
194
|
+
Samples::AnonymousDefined.new.clean
|
195
|
+
end
|
366
196
|
|
367
|
-
|
197
|
+
it 'uses correct decorated singleton method names' do
|
198
|
+
expect(Deprecations).to receive(:call).once.with(
|
199
|
+
'Samples::AnonymousDefined.create',
|
200
|
+
'Samples::AnonymousDefined.make',
|
201
|
+
nil
|
202
|
+
)
|
203
|
+
Samples::AnonymousDefined.create
|
204
|
+
end
|
205
|
+
end
|
368
206
|
|
369
|
-
|
370
|
-
|
207
|
+
context 'when a sub-class is used' do
|
208
|
+
module Samples
|
209
|
+
class Parent < ::BasicObject
|
210
|
+
def clean; end
|
211
|
+
def clear; end
|
212
|
+
deprecated :clean, :clear
|
213
|
+
end
|
371
214
|
|
372
|
-
|
215
|
+
class Child < Parent; end
|
216
|
+
end
|
373
217
|
|
374
|
-
|
375
|
-
|
376
|
-
|
218
|
+
it 'uses correct decorated method names' do
|
219
|
+
expect(Deprecations).to receive(:call).once.with(
|
220
|
+
'Samples::Parent#clean',
|
221
|
+
'Samples::Parent#clear',
|
222
|
+
nil
|
223
|
+
)
|
224
|
+
Samples::Child.new.clean
|
377
225
|
end
|
378
226
|
end
|
227
|
+
|
379
228
|
end
|
380
229
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
# configure RSpec
|
2
1
|
RSpec.configure do |config|
|
3
2
|
config.raise_errors_for_deprecations!
|
4
3
|
config.disable_monkey_patching!
|
@@ -6,5 +5,4 @@ RSpec.configure do |config|
|
|
6
5
|
config.expect_with(:rspec){ |c| c.syntax = :expect }
|
7
6
|
config.mock_with(:rspec){ |c| c.syntax = :expect }
|
8
7
|
end
|
9
|
-
|
10
8
|
require 'deprecations'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: deprecations
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Blumtritt
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-02-
|
11
|
+
date: 2015-02-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: terminal-notifier
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: terminal-notifier-guard
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -95,12 +109,14 @@ dependencies:
|
|
95
109
|
- !ruby/object:Gem::Version
|
96
110
|
version: '0'
|
97
111
|
description: This gem provides transparent declaration of deprecated methods and classes.
|
112
|
+
It's easy, small, has no dependencies and no overhead.
|
98
113
|
email:
|
99
114
|
- mike.blumtritt@injixo.com
|
100
115
|
executables: []
|
101
116
|
extensions: []
|
102
117
|
extra_rdoc_files:
|
103
118
|
- README.md
|
119
|
+
- CHANGELOG.md
|
104
120
|
files:
|
105
121
|
- ".gitignore"
|
106
122
|
- CHANGELOG.md
|
@@ -110,10 +126,10 @@ files:
|
|
110
126
|
- Rakefile
|
111
127
|
- deprecations.gemspec
|
112
128
|
- lib/deprecations.rb
|
113
|
-
- lib/deprecations/
|
129
|
+
- lib/deprecations/behavior.rb
|
114
130
|
- lib/deprecations/extension.rb
|
115
131
|
- lib/deprecations/version.rb
|
116
|
-
- spec/deprecations/
|
132
|
+
- spec/deprecations/behavior_spec.rb
|
117
133
|
- spec/deprecations/version_spec.rb
|
118
134
|
- spec/deprecations_spec.rb
|
119
135
|
- spec/spec_helper.rb
|
@@ -140,4 +156,8 @@ rubygems_version: 2.4.5
|
|
140
156
|
signing_key:
|
141
157
|
specification_version: 4
|
142
158
|
summary: Deprecation support for your project.
|
143
|
-
test_files:
|
159
|
+
test_files:
|
160
|
+
- spec/deprecations/behavior_spec.rb
|
161
|
+
- spec/deprecations/version_spec.rb
|
162
|
+
- spec/deprecations_spec.rb
|
163
|
+
- spec/spec_helper.rb
|
@@ -1,35 +0,0 @@
|
|
1
|
-
|
2
|
-
module Deprecations
|
3
|
-
class << self
|
4
|
-
|
5
|
-
def configure
|
6
|
-
yield(@@cfg = Cfg.new)
|
7
|
-
end
|
8
|
-
|
9
|
-
def configuration
|
10
|
-
@@cfg
|
11
|
-
end
|
12
|
-
|
13
|
-
BEHAVIORS = [:warn, :raise, :silence]
|
14
|
-
|
15
|
-
private
|
16
|
-
|
17
|
-
class Cfg < BasicObject
|
18
|
-
attr_reader :behavior
|
19
|
-
|
20
|
-
def initialize
|
21
|
-
@behavior = :warn
|
22
|
-
end
|
23
|
-
|
24
|
-
def behavior=(how)
|
25
|
-
BEHAVIORS.include?(how) and return @behavior = how
|
26
|
-
::Kernel.raise(
|
27
|
-
::ArgumentError, "invalid parameter `#{how}` - have to be #{BEHAVIORS.map(&:inspect).join(' | ')}"
|
28
|
-
)
|
29
|
-
end
|
30
|
-
|
31
|
-
end
|
32
|
-
|
33
|
-
@@cfg = Cfg.new
|
34
|
-
end
|
35
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
RSpec.describe 'Deprecations::Configuration' do
|
4
|
-
it 'is possible to configure the module' do
|
5
|
-
Deprecations.configure do |config|
|
6
|
-
config.behavior = :silence
|
7
|
-
end
|
8
|
-
expect(Deprecations.configuration.behavior).to be :silence
|
9
|
-
end
|
10
|
-
|
11
|
-
context 'when invalid arguments are given' do
|
12
|
-
it 'raises an error' do
|
13
|
-
expect do
|
14
|
-
Deprecations.configure do |config|
|
15
|
-
config.behavior = :invalid_value
|
16
|
-
end
|
17
|
-
end.to raise_error(ArgumentError, /invalid_value/)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|