deprecatable 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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