deprecatable 1.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.
@@ -0,0 +1,149 @@
1
+ require "helpers"
2
+
3
+ class TestDeprecatable < MiniTest::Unit::TestCase
4
+
5
+ def setup
6
+ Deprecatable.registry.clear
7
+ Deprecatable.options.reset
8
+
9
+ @deprecated_class = Class.new do
10
+ extend Deprecatable
11
+ def self.name
12
+ "TestDeprecatable::DeprecateMe"
13
+ end
14
+ def deprecate_me; end
15
+ deprecate :deprecate_me
16
+ end
17
+
18
+ @deprecatable_class = Class.new do
19
+ extend Deprecatable
20
+ def self.name
21
+ "TestDeprecatable::DeprecatableClass"
22
+ end
23
+ def deprecate_me; end
24
+ end
25
+ end
26
+
27
+ def test_deprecated_method_is_regsitered
28
+ assert_equal( 1, Deprecatable.registry.size )
29
+ end
30
+
31
+ def test_call_site_is_recorded
32
+ i = @deprecated_class.new
33
+ capture_io do
34
+ i.deprecate_me
35
+ end
36
+ assert_equal( 1, Deprecatable.registry.items.first.invocation_count )
37
+ end
38
+
39
+ def test_different_call_sites_are_recorded_independently
40
+ i = @deprecated_class.new
41
+ capture_io do
42
+ 42.times { i.deprecate_me }
43
+ 24.times { i.deprecate_me }
44
+ end
45
+ dm = Deprecatable.registry.items.first
46
+ assert_equal( 66, dm.invocation_count )
47
+ assert_equal( 2, dm.call_site_count )
48
+ end
49
+
50
+ def test_alerts_are_issued_only_once_for_a_callsite
51
+ i = @deprecated_class.new
52
+ callable = lambda { |c| c.deprecate_me }
53
+ stdout, stderr = capture_io do
54
+ callable.call( i )
55
+ end
56
+ line = __LINE__ - 4
57
+
58
+ assert_match( /#{File.expand_path( __FILE__ )}:#{line}/m, stderr )
59
+ assert_match( /---> #{line}:\s+callable = lambda \{ |c| c\.deprecate_me \}/, stderr )
60
+
61
+ assert_silent do
62
+ callable.call( i )
63
+ end
64
+ end
65
+
66
+ def test_alerts_are_issued_never_for_a_callsite
67
+ ::Deprecatable.options.alert_frequency = :never
68
+ i = @deprecated_class.new
69
+ assert_silent do
70
+ i.deprecate_me
71
+ end
72
+ end
73
+
74
+ def test_alerts_are_issued_for_every_call_to_a_callsite
75
+ ::Deprecatable.options.alert_frequency = :always
76
+ i = @deprecated_class.new
77
+ stdout, stderr = capture_io do
78
+ 42.times { i.deprecate_me }
79
+ end
80
+ line = __LINE__ - 2
81
+ lines = stderr.split(/\n/)
82
+ assert_equal( 42, lines.grep( /#{File.expand_path( __FILE__)}:#{line}/ ).size )
83
+ assert_equal( 42, lines.grep( /--->/ ).size )
84
+ end
85
+
86
+ def test_raise_an_exception_if_deprecating_a_method_that_does_not_exist
87
+ assert_raises( NameError ) do
88
+ @deprecatable_class.deprecate :wibble
89
+ end
90
+ end
91
+
92
+ def assert_alert_match( regex, klass, &block )
93
+ stdout, stderr = capture_io do
94
+ i = klass.new
95
+ i.deprecate_me
96
+ end
97
+ assert_match( regex, stderr )
98
+ return stderr
99
+ end
100
+
101
+ def test_adds_an_additional_message_when_given
102
+ @deprecatable_class.deprecate :deprecate_me, :message => "You should switch to using Something#bar"
103
+ assert_alert_match( /\* You should switch to using Something#bar/m, @deprecatable_class )
104
+ end
105
+
106
+ def test_adds_a_removal_date_when_given
107
+ @deprecatable_class.deprecate :deprecate_me, :removal_date => "2011-09-02"
108
+ assert_alert_match( /Will be removed after 2011-09-02/m, @deprecatable_class )
109
+ end
110
+
111
+ def test_adds_a_removal_version_when_given
112
+ @deprecatable_class.deprecate :deprecate_me, :removal_version => "4.2"
113
+ assert_alert_match( /Will be removed in version 4.2/m, @deprecatable_class )
114
+ end
115
+
116
+ def test_deprecating_an_included_method
117
+ mod = Module.new do
118
+ extend Deprecatable
119
+ def deprecate_me; end
120
+ deprecate :deprecate_me, :message => "KABOOM!"
121
+ end
122
+ klass = Class.new do
123
+ include mod
124
+ end
125
+
126
+ assert_alert_match( /KABOOM!/, klass )
127
+ end
128
+
129
+ def test_deprecating_a_class_method
130
+ klass = Class.new do
131
+ class << self
132
+ extend Deprecatable
133
+ def deprecate_me; end
134
+ deprecate :deprecate_me, :message => "Class Method KABOOM!"
135
+ end
136
+ end
137
+
138
+ stdout, stderr = capture_io do
139
+ klass.deprecate_me
140
+ end
141
+ assert_match( /Class Method KABOOM/, stderr )
142
+ end
143
+
144
+ def test_has_an_at_exit_handler
145
+ io = IO.popen( "ruby -Ilib examples/at_exit.rb 2>&1" )
146
+ lines = io.readlines.join('')
147
+ assert_match( /Deprecatable 'at_exit' Report/m, lines )
148
+ end
149
+ end
@@ -0,0 +1,41 @@
1
+ require 'helpers'
2
+
3
+ class TestDeprecatableAlerter < MiniTest::Unit::TestCase
4
+ def setup
5
+ Deprecatable.registry.clear
6
+ Deprecatable.options.reset
7
+
8
+ @old_alerter = Deprecatable.alerter
9
+ @alerter = ::Deprecatable::StringIOAlerter.new
10
+ Deprecatable.alerter = @alerter
11
+
12
+ @deprecated_class = Class.new do
13
+ extend Deprecatable
14
+ def self.name
15
+ "TestDeprecatable::DeprecateMe"
16
+ end
17
+ def deprecate_me; end
18
+ deprecate :deprecate_me
19
+ end
20
+ end
21
+
22
+ def teardown
23
+ Deprecatable.alerter = @old_alerter
24
+ end
25
+
26
+ def test_alert
27
+ i = @deprecated_class.new
28
+ i.deprecate_me
29
+
30
+ assert_match( /---> #{__LINE__ - 2}:/, Deprecatable.alerter.to_s )
31
+ end
32
+
33
+ def test_final_report
34
+ i = @deprecated_class.new
35
+ 12.times { i.deprecate_me }
36
+ 10.times { i.deprecate_me }
37
+ Deprecatable.alerter.final_report
38
+ assert_match( /Called 12 time/, Deprecatable.alerter.to_s )
39
+ assert_match( /Called 10 time/, Deprecatable.alerter.to_s )
40
+ end
41
+ end
@@ -0,0 +1,28 @@
1
+ require 'helpers'
2
+ # This file requires exact position of lines. If you should happent to chagen
3
+ # tne numer of lines in this file that appear before the first test, some of the
4
+ # tests will fail
5
+ class TestDeprecatableCallSite < MiniTest::Unit::TestCase
6
+ def setup
7
+ @file = __FILE__
8
+ @before = 'This is the line before'
9
+ @line = __LINE__
10
+ @after = 'This is the line after'
11
+ @call_site = ::Deprecatable::CallSite.new( @file, @line, 1 )
12
+ end
13
+
14
+ def test_initializes_with_a_filename_and_line_number
15
+ assert_equal( File.expand_path( @file ), @call_site.file )
16
+ assert_equal( @line, @call_site.line_number )
17
+ assert_equal( 1, @call_site.context_padding )
18
+ end
19
+
20
+ def test_captures_the_call_site_context
21
+ context = [
22
+ " 8: @before = 'This is the line before'\n",
23
+ "---> 9: @line = __LINE__\n",
24
+ " 10: @after = 'This is the line after'\n",
25
+ ]
26
+ assert_array_equal( context, @call_site.formatted_context_lines )
27
+ end
28
+ end
@@ -0,0 +1,57 @@
1
+ # Context line 1
2
+ # Context line 2
3
+ # Context line 3
4
+ # Context line 4
5
+
6
+
7
+ require 'helpers'
8
+
9
+ # Context line 9
10
+ # Context line 10
11
+ # Context line 11
12
+ # Context line 12
13
+ # Context line 13
14
+
15
+ class TestDeprecatableCallSiteContext < MiniTest::Unit::TestCase
16
+ def setup
17
+ @ctx = Deprecatable::CallSiteContext.new( File.expand_path(__FILE__), 11, 2 )
18
+ end
19
+
20
+ def context_lines_for( range, arrow_line )
21
+ width = ("%d" % range.to_a.last).length
22
+ range.map do |x|
23
+ prefix = ( x == arrow_line ) ? "--->" : " "
24
+ "#{prefix} #{("%d" % x).rjust( width )}: # Context line #{x}\n"
25
+ end
26
+ end
27
+
28
+ def test_gets_the_context_from_the_middle_of_a_file
29
+ context_lines = (9..13).map { |x| "# Context line #{x}\n" }
30
+ assert_array_equal( context_lines, @ctx.context_lines )
31
+ end
32
+
33
+ def test_properly_formats_the_context_from_the_middle_of_the_file
34
+ formatted_lines = [ ]
35
+ formatted_lines += context_lines_for( (9..13), 11 )
36
+ assert_array_equal( formatted_lines, @ctx.formatted_context_lines )
37
+ end
38
+
39
+ def test_properly_formats_the_context_at_the_beginning_of_the_file
40
+ ctx = Deprecatable::CallSiteContext.new( File.expand_path(__FILE__), 2, 2 )
41
+ formatted_lines = [ ]
42
+ formatted_lines += context_lines_for( (1..4), 2 )
43
+ assert_array_equal( formatted_lines, ctx.formatted_context_lines )
44
+ end
45
+
46
+ def test_properly_formats_the_context_at_the_end_of_the_file
47
+ ctx = Deprecatable::CallSiteContext.new( File.expand_path(__FILE__), 56, 2 )
48
+ formatted_lines = [ ]
49
+ formatted_lines += context_lines_for( (54..57), 56)
50
+ assert_array_equal( formatted_lines, ctx.formatted_context_lines )
51
+ end
52
+ end
53
+
54
+ # Context line 54
55
+ # Context line 55
56
+ # Context line 56
57
+ # Context line 57
@@ -0,0 +1,61 @@
1
+ require 'helpers'
2
+
3
+ class TestDeprecatableDeprecatedMethod < MiniTest::Unit::TestCase
4
+ def setup
5
+ @klass = Class.new do
6
+ def self.name
7
+ "TestDeprecatableDeprecatedMethod::DeprecatableClass"
8
+ end
9
+ def m1
10
+ "m1"
11
+ end
12
+ end
13
+
14
+ @module = Module.new do
15
+ def self.name
16
+ "TestDeprecatableDeprecatedMethod::DeprecatableModule"
17
+ end
18
+ def m2; "m2"; end
19
+ end
20
+
21
+ @dep_class = Deprecatable::DeprecatedMethod.new( @klass, "m1", __FILE__, 7 )
22
+ end
23
+
24
+ def test_records_meta_information_about_the_deprecation
25
+ assert_equal( @klass , @dep_class.klass )
26
+ assert_equal( "m1" , @dep_class.method )
27
+ assert_equal( File.expand_path( __FILE__ ) , @dep_class.file )
28
+ assert_equal( 7 , @dep_class.line_number )
29
+ assert_equal( "_deprecated_m1" , @dep_class.deprecated_method_name )
30
+ end
31
+
32
+ def test_records_an_invocation_of_an_instance_method
33
+ dc = @klass.new
34
+ m = nil
35
+ capture_io do
36
+ m = dc.m1
37
+ end
38
+ assert_equal( "m1", m )
39
+ assert_equal( 1, @dep_class.invocation_count )
40
+ end
41
+
42
+ def test_records_uniq_call_sites
43
+ dc = @klass.new
44
+ capture_io do
45
+ 3.times { dc.m1 }
46
+ 3.times { dc.m1 }
47
+ end
48
+ assert_equal( 6, @dep_class.invocation_count )
49
+ assert_equal( 2, @dep_class.call_site_count )
50
+ assert_equal( 2, @dep_class.call_sites.size )
51
+ end
52
+
53
+ def test_has_a_string_representation_of_a_deprecated_instance_method
54
+ assert_equal( "TestDeprecatableDeprecatedMethod::DeprecatableClass#m1 defined at #{File.expand_path(__FILE__)}:7", @dep_class.to_s )
55
+ end
56
+
57
+ def test_has_a_string_representation_of_a_deprecated_module_method
58
+ dm = Deprecatable::DeprecatedMethod.new( @module, "m2", __FILE__, 11 )
59
+ assert_equal( "TestDeprecatableDeprecatedMethod::DeprecatableModule.m2 defined at #{File.expand_path(__FILE__)}:11", dm.to_s )
60
+ end
61
+ end
@@ -0,0 +1,83 @@
1
+ require "helpers"
2
+
3
+ class TestDeprecatableOptions < MiniTest::Unit::TestCase
4
+
5
+ def setup
6
+ @options = Deprecatable::Options.new
7
+ end
8
+
9
+ def teardown
10
+ ENV.keys.each do |k|
11
+ next unless k =~/^DEPRECATABLE/
12
+ ENV.delete( k )
13
+ end
14
+ end
15
+
16
+ def test_defaults_exist
17
+ assert_equal( 2 , @options.caller_context_padding )
18
+ assert_equal( true , @options.has_at_exit_report? )
19
+ assert_equal( 1 , @options.alert_frequency )
20
+ end
21
+
22
+ def test_caller_context_padding_raises_error_if_set_to_negative_number
23
+ assert_raises( ArgumentError, "caller_context_mapping must be > 0" ) do
24
+ @options.caller_context_padding = -1
25
+ end
26
+ end
27
+
28
+ def test_caller_context_padding_raises_error_if_environemtn_set_to_negative_number
29
+ ENV['DEPRECATABLE_CALLER_CONTEXT_PADDING'] = "-1"
30
+ assert_raises( ArgumentError, "caller_context_mapping must be > 0" ) do
31
+ @options.caller_context_padding
32
+ end
33
+ end
34
+
35
+ def test_caller_context_padding_may_be_set
36
+ @options.caller_context_padding = 4
37
+ assert_equal( 4, @options.caller_context_padding )
38
+ end
39
+
40
+ def test_caller_context_padding_may_be_overridden_by_environment_variable
41
+ assert_equal( 2, @options.caller_context_padding )
42
+ @options.caller_context_padding = 4
43
+ assert_equal( 4, @options.caller_context_padding )
44
+ ENV['DEPRECATABLE_CALLER_CONTEXT_PADDING'] = "10"
45
+ assert_equal( 10, @options.caller_context_padding )
46
+ end
47
+
48
+ def test_has_at_exit_report_may_be_turned_off
49
+ @options.has_at_exit_report = false
50
+ refute @options.has_at_exit_report?, "has_at_exit_report? must be false"
51
+ end
52
+
53
+ def test_has_at_exit_report_may_be_overridden_by_environment_variable
54
+ @options.has_at_exit_report = false
55
+ refute @options.has_at_exit_report?
56
+ ENV['DEPRECATABLE_HAS_AT_EXIT_REPORT'] = "true"
57
+ assert @options.has_at_exit_report?, "has_at_exit_report? must be true"
58
+ end
59
+
60
+ def test_alert_frequency_may_be_set
61
+ @options.alert_frequency = :once
62
+ assert_equal( 1, @options.alert_frequency )
63
+
64
+ @options.alert_frequency = :never
65
+ assert_equal( 0, @options.alert_frequency )
66
+
67
+ @options.alert_frequency = :always
68
+ assert_equal( "Infinity", @options.alert_frequency.to_s )
69
+ assert @options.alert_frequency.infinite?
70
+ end
71
+
72
+ def test_alert_frequency_may_be_overridden_by_environment_variable
73
+ ENV['DEPRECATABLE_ALERT_FREQUENCY'] = "42"
74
+ assert_equal( 42, @options.alert_frequency)
75
+ ENV['DEPRECATABLE_ALERT_FREQUENCY'] = "once"
76
+ assert_equal( 1, @options.alert_frequency)
77
+ ENV['DEPRECATABLE_ALERT_FREQUENCY'] = "never"
78
+ assert_equal( 0, @options.alert_frequency)
79
+ ENV['DEPRECATABLE_ALERT_FREQUENCY'] = "always"
80
+ assert @options.alert_frequency.infinite?
81
+ end
82
+
83
+ end
@@ -0,0 +1,32 @@
1
+ require 'helpers'
2
+
3
+ class TestDeprecatableRegistry < MiniTest::Unit::TestCase
4
+ class DeprecatedExample
5
+ def boom; end
6
+ end
7
+
8
+ def setup
9
+ @registry = Deprecatable::Registry.new
10
+ @dm = Deprecatable::DeprecatedMethod.new( TestDeprecatableRegistry::DeprecatedExample, "boom", __FILE__, 6 )
11
+ end
12
+
13
+ def test_registers_a_deprecated_method
14
+ assert_equal( 0, @registry.size )
15
+ @registry.register( @dm )
16
+ assert_equal( 1, @registry.size )
17
+ end
18
+
19
+ def test_that_a_given_method_may_only_be_registered_once
20
+ assert_equal( 0, @registry.size )
21
+ @registry.register( @dm )
22
+ assert_equal( 1, @registry.size )
23
+ @registry.register( @dm )
24
+ assert_equal( 1, @registry.size )
25
+ end
26
+
27
+ def test_returns_all_the_items_in_the_registry
28
+ @registry.register( @dm )
29
+ assert_equal( 1, @registry.items.size )
30
+ end
31
+
32
+ end