wool 0.5.1

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.
Files changed (88) hide show
  1. data/.document +5 -0
  2. data/.gitignore +23 -0
  3. data/LICENSE +45 -0
  4. data/README.rdoc +17 -0
  5. data/Rakefile +77 -0
  6. data/TODO.md +17 -0
  7. data/VERSION +1 -0
  8. data/bin/wool +4 -0
  9. data/features/step_definitions/wool_steps.rb +39 -0
  10. data/features/support/env.rb +14 -0
  11. data/features/support/testdata/1_input +1 -0
  12. data/features/support/testdata/1_output +1 -0
  13. data/features/support/testdata/2_input +4 -0
  14. data/features/support/testdata/2_output +4 -0
  15. data/features/support/testdata/3_input +8 -0
  16. data/features/support/testdata/3_output +11 -0
  17. data/features/support/testdata/4_input +5 -0
  18. data/features/support/testdata/4_output +5 -0
  19. data/features/wool.feature +24 -0
  20. data/lib/wool.rb +40 -0
  21. data/lib/wool/advice/advice.rb +42 -0
  22. data/lib/wool/advice/comment_advice.rb +37 -0
  23. data/lib/wool/analysis/annotations.rb +34 -0
  24. data/lib/wool/analysis/annotations/next_annotation.rb +26 -0
  25. data/lib/wool/analysis/annotations/parent_annotation.rb +20 -0
  26. data/lib/wool/analysis/annotations/scope_annotation.rb +37 -0
  27. data/lib/wool/analysis/lexical_analysis.rb +165 -0
  28. data/lib/wool/analysis/protocol_registry.rb +32 -0
  29. data/lib/wool/analysis/protocols.rb +82 -0
  30. data/lib/wool/analysis/scope.rb +13 -0
  31. data/lib/wool/analysis/sexp_analysis.rb +98 -0
  32. data/lib/wool/analysis/signature.rb +16 -0
  33. data/lib/wool/analysis/symbol.rb +10 -0
  34. data/lib/wool/analysis/visitor.rb +36 -0
  35. data/lib/wool/analysis/wool_class.rb +47 -0
  36. data/lib/wool/rake/task.rb +42 -0
  37. data/lib/wool/runner.rb +156 -0
  38. data/lib/wool/scanner.rb +160 -0
  39. data/lib/wool/support/module_extensions.rb +84 -0
  40. data/lib/wool/third_party/trollop.rb +845 -0
  41. data/lib/wool/warning.rb +145 -0
  42. data/lib/wool/warnings/comment_spacing.rb +30 -0
  43. data/lib/wool/warnings/extra_blank_lines.rb +29 -0
  44. data/lib/wool/warnings/extra_whitespace.rb +15 -0
  45. data/lib/wool/warnings/line_length.rb +113 -0
  46. data/lib/wool/warnings/misaligned_unindentation.rb +16 -0
  47. data/lib/wool/warnings/operator_spacing.rb +63 -0
  48. data/lib/wool/warnings/rescue_exception.rb +41 -0
  49. data/lib/wool/warnings/semicolon.rb +24 -0
  50. data/lib/wool/warnings/useless_double_quotes.rb +37 -0
  51. data/spec/advice_specs/advice_spec.rb +69 -0
  52. data/spec/advice_specs/comment_advice_spec.rb +38 -0
  53. data/spec/advice_specs/spec_helper.rb +1 -0
  54. data/spec/analysis_specs/annotations_specs/next_prev_annotation_spec.rb +47 -0
  55. data/spec/analysis_specs/annotations_specs/parent_annotation_spec.rb +41 -0
  56. data/spec/analysis_specs/annotations_specs/spec_helper.rb +5 -0
  57. data/spec/analysis_specs/lexical_analysis_spec.rb +179 -0
  58. data/spec/analysis_specs/protocol_registry_spec.rb +58 -0
  59. data/spec/analysis_specs/protocols_spec.rb +49 -0
  60. data/spec/analysis_specs/scope_spec.rb +20 -0
  61. data/spec/analysis_specs/sexp_analysis_spec.rb +134 -0
  62. data/spec/analysis_specs/spec_helper.rb +2 -0
  63. data/spec/analysis_specs/visitor_spec.rb +53 -0
  64. data/spec/analysis_specs/wool_class_spec.rb +54 -0
  65. data/spec/rake_specs/spec_helper.rb +1 -0
  66. data/spec/rake_specs/task_spec.rb +67 -0
  67. data/spec/runner_spec.rb +171 -0
  68. data/spec/scanner_spec.rb +75 -0
  69. data/spec/spec.opts +1 -0
  70. data/spec/spec_helper.rb +93 -0
  71. data/spec/support_specs/module_extensions_spec.rb +91 -0
  72. data/spec/support_specs/spec_helper.rb +1 -0
  73. data/spec/warning_spec.rb +95 -0
  74. data/spec/warning_specs/comment_spacing_spec.rb +57 -0
  75. data/spec/warning_specs/extra_blank_lines_spec.rb +70 -0
  76. data/spec/warning_specs/extra_whitespace_spec.rb +33 -0
  77. data/spec/warning_specs/line_length_spec.rb +165 -0
  78. data/spec/warning_specs/misaligned_unindentation_spec.rb +35 -0
  79. data/spec/warning_specs/operator_spacing_spec.rb +101 -0
  80. data/spec/warning_specs/rescue_exception_spec.rb +105 -0
  81. data/spec/warning_specs/semicolon_spec.rb +58 -0
  82. data/spec/warning_specs/spec_helper.rb +1 -0
  83. data/spec/warning_specs/useless_double_quotes_spec.rb +62 -0
  84. data/spec/wool_spec.rb +8 -0
  85. data/status_reports/2010/12/2010-12-14.md +163 -0
  86. data/test/third_party_tests/test_trollop.rb +1181 -0
  87. data/wool.gemspec +173 -0
  88. metadata +235 -0
@@ -0,0 +1,171 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Runner do
4
+ before do
5
+ @runner = Runner.new(['a', :b])
6
+ end
7
+
8
+ context '#run' do
9
+ it 'collects options and arguments, decides what to scan, scans, and displays' do
10
+ runner = Runner.new(['--report-fixed', 'hello', 'world'])
11
+ expected_settings = {:"report-fixed_given"=>true, :"report-fixed"=>true,
12
+ :fix => false, :help => false, :debug => false,
13
+ InlineCommentSpaceWarning::OPTION_KEY => 2,
14
+ :"line-length" => nil, :only => nil, :stdin => false,
15
+ :display => true,
16
+ :__using__ => Warning.all_warnings,
17
+ :__fix__ => Warning.all_warnings}
18
+ scanner = mock(:scanner)
19
+ Scanner.should_receive(:new, expected_settings).and_return(scanner)
20
+
21
+ data1, data2 = mock(:data1), mock(:data2)
22
+ warning1, warning2 = mock(:warning1), mock(:warning2)
23
+ file1, file2 = mock(:file1), mock(:file2)
24
+
25
+ scanner.should_receive(:settings).exactly(3).times.and_return({:"report-fixed" => true})
26
+ File.should_receive(:read).with('hello').and_return(data1)
27
+ scanner.should_receive(:scan).
28
+ with(data1, 'hello').
29
+ and_return([warning1])
30
+ warning1.should_receive(:to_ary)
31
+
32
+ scanner.should_receive(:settings).and_return({})
33
+ File.should_receive(:read).with('world').and_return(data2)
34
+ scanner.should_receive(:scan).
35
+ with(data2, 'world').
36
+ and_return([warning2])
37
+ warning2.should_receive(:to_ary)
38
+
39
+ runner.should_receive(:display_warnings).with([warning1, warning2], expected_settings)
40
+
41
+ runner.run
42
+ end
43
+
44
+ it 'works with :stdin => true' do
45
+ runner = Runner.new(['--stdin', '--only', 'UselessDoubleQuotesWarning'])
46
+ expected_settings = {:"report-fixed"=>false, :fix => false, :help => false,
47
+ :debug => false, InlineCommentSpaceWarning::OPTION_KEY => 2,
48
+ :"line-length" => nil, :only => 'UselessDoubleQuotesWarning',
49
+ :stdin => true, :stdin_given => true, :only_given => true,
50
+ :display => true,
51
+ :__using__ => [UselessDoubleQuotesWarning],
52
+ :__fix__ => [UselessDoubleQuotesWarning]}
53
+ scanner = mock(:scanner)
54
+ Scanner.should_receive(:new, expected_settings).and_return(scanner)
55
+
56
+ data1 = mock(:data1)
57
+ warning1 = mock(:warning1)
58
+
59
+ scanner.should_receive(:settings).twice.and_return({:"report-fixed" => true})
60
+ STDIN.should_receive(:read).and_return(data1)
61
+ scanner.should_receive(:scan).
62
+ with(data1, '(stdin)').
63
+ and_return([warning1])
64
+ warning1.should_receive(:to_ary)
65
+
66
+ runner.should_receive(:display_warnings).with([warning1], expected_settings)
67
+ runner.run
68
+ end
69
+ end
70
+
71
+ context '#collect_options_and_arguments' do
72
+ before do
73
+ @runner = Runner.new(['--fix', '--report-fixed', 'hello', 'there'])
74
+ @settings, @arguments = @runner.collect_options_and_arguments
75
+ end
76
+
77
+ it 'finds both flags' do
78
+ @settings[:fix].should be_true
79
+ @settings[:"report-fixed"].should be_true
80
+ end
81
+
82
+ it 'finds both stray arguments' do
83
+ @arguments.should == ['hello', 'there']
84
+ end
85
+ end
86
+
87
+ context '#swizzling_argv' do
88
+ it 'changes ARGV to the runner\'s argv value' do
89
+ @runner.swizzling_argv do
90
+ ARGV.should == ['a', :b]
91
+ end
92
+ end
93
+
94
+ it 'restores ARGV despite an exception' do
95
+ old_argv = ARGV.dup
96
+ proc {
97
+ @runner.swizzling_argv do
98
+ raise SystemExit.new('exiting')
99
+ end
100
+ }.should raise_error(SystemExit)
101
+ ARGV.should == old_argv
102
+ end
103
+ end
104
+
105
+ context '#get_settings' do
106
+ it 'has a --fix option' do
107
+ runner = Runner.new(['--fix'])
108
+ settings = runner.swizzling_argv { runner.get_settings }
109
+ settings[:fix].should be_true
110
+ settings[:fix_given].should be_true
111
+ end
112
+
113
+ it 'has a --report-fixed option' do
114
+ runner = Runner.new(['--report-fixed'])
115
+ settings = runner.swizzling_argv { runner.get_settings }
116
+ settings[:"report-fixed"].should be_true
117
+ settings[:"report-fixed_given"].should be_true
118
+ end
119
+ end
120
+
121
+ context '#handle_global_options' do
122
+ it 'specifies :using and :fix when :only is provided' do
123
+ runner = Runner.new([])
124
+ runner.handle_global_options(:only => 'UselessDoubleQuotesWarning')
125
+ runner.using.should == [UselessDoubleQuotesWarning]
126
+ runner.fix.should == [UselessDoubleQuotesWarning]
127
+ end
128
+
129
+ it 'works with multiple short names' do
130
+ runner = Runner.new([])
131
+ runner.handle_global_options(:only => 'ST1,ST3')
132
+ runner.using.size.should == 2
133
+ runner.using.each {|w| w.ancestors.should include(Warning) }
134
+ end
135
+ end
136
+
137
+ context '#display_warnings' do
138
+ it 'prints the lines and files where there are warnings' do
139
+ warning = Warning.new('hello', 'a+b')
140
+ warning.line_number = 4
141
+ warning.severity = 3
142
+ warnings = [warning]
143
+ runner = Runner.new(['temp', 'hello'])
144
+ output = swizzling_io do
145
+ runner.display_warnings(warnings, {})
146
+ end
147
+ output.should =~ /hello:4/
148
+ output.should =~ /(3)/
149
+ output.should =~ /Warning/
150
+ output.should =~ /1 warning/
151
+ output.should =~ /0 are fixable/
152
+ end
153
+ end
154
+
155
+ context '#collect_warnings' do
156
+ it 'scans each file provided' do
157
+ scanner = mock(:scanner)
158
+ data1, data2 = mock(:data1), mock(:data2)
159
+ warning_list1, warning_list2 = mock(:wl1), mock(:wl2)
160
+ File.should_receive(:read).with('abc').and_return(data1)
161
+ scanner.should_receive(:settings).exactly(4).times.and_return({})
162
+ scanner.should_receive(:scan).with(data1, 'abc').and_return(warning_list1)
163
+ warning_list1.should_receive(:to_ary)
164
+ File.should_receive(:read).with('def').and_return(data2)
165
+ scanner.should_receive(:scan).with(data2, 'def').and_return(warning_list2)
166
+ warning_list2.should_receive(:to_ary)
167
+
168
+ @runner.collect_warnings(['abc', 'def'], scanner).should == [warning_list1, warning_list2]
169
+ end
170
+ end
171
+ end
@@ -0,0 +1,75 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require 'stringio'
3
+
4
+ describe Scanner do
5
+ before do
6
+ @scanner = Scanner.new(InlineCommentSpaceWarning::OPTION_KEY => 2)
7
+
8
+ @fix_scanner_stdout = StringIO.new
9
+ @fix_scanner = Scanner.new(:fix => true, :output_file => @fix_scanner_stdout)
10
+ end
11
+
12
+ context '#scan' do
13
+ it 'takes an input and gathers warnings about it' do
14
+ warnings = @scanner.scan('a + b ', '(stdin)')
15
+ warnings.size.should == 1
16
+ warnings[0].should be_a(ExtraWhitespaceWarning)
17
+ end
18
+
19
+ it "ignores warnings specified in the line's comments by class name" do
20
+ warnings = @scanner.scan('a +b # wool: ignore OperatorSpacing')
21
+ warnings.size.should == 0
22
+ end
23
+
24
+ it "ignores warnings specified in the line's comments by short name" do
25
+ warnings = @scanner.scan("a +b # wool: ignore #{OperatorSpacing.short_name}")
26
+ warnings.size.should == 0
27
+ end
28
+
29
+ it "ignores multiple warnings that are marked in the line's comments" do
30
+ warnings = @scanner.scan(
31
+ 'a +b; c + d # wool: ignore OperatorSpacing SemicolonWarning')
32
+ warnings.size.should == 0
33
+ end
34
+
35
+ it "ignores multiple warnings in the line's comments as short name" do
36
+ warnings = @scanner.scan(
37
+ "a +b; c + d # wool: ignore #{OperatorSpacing.short_name} #{SemicolonWarning.short_name}")
38
+ warnings.size.should == 0
39
+ end
40
+
41
+ it 'fixes the input and writes it to :output_file' do
42
+ warnings = @fix_scanner.scan('a + b ', '(stdin)')
43
+ warnings.size.should == 1
44
+ warnings[0].should be_a(ExtraWhitespaceWarning)
45
+ @fix_scanner_stdout.string.should == "a + b"
46
+ end
47
+
48
+ it 'fixes multiple errors on one line' do
49
+ warnings = @fix_scanner.scan('a +b ', '(stdin)')
50
+ warnings.size.should == 2
51
+ @fix_scanner_stdout.string.should == "a + b"
52
+ end
53
+
54
+ it 'fixes multiline inputs' do
55
+ warnings = @fix_scanner.scan("def plus(a, b)\n a + b \nend", '(stdin)')
56
+ warnings.size.should == 1
57
+ warnings[0].should be_a(ExtraWhitespaceWarning)
58
+ @fix_scanner_stdout.string.should == "def plus(a, b)\n a + b\nend"
59
+ end
60
+
61
+ it 'fixes multiline mis-indented inputs' do
62
+ warnings = @fix_scanner.scan("def plus(a, b)\n a + b\n end", '(stdin)')
63
+ warnings.size.should == 1
64
+ warnings[0].should be_a(MisalignedUnindentationWarning)
65
+ @fix_scanner_stdout.string.should == "def plus(a, b)\n a + b\nend"
66
+ end
67
+
68
+ it 'fixes class definitions' do
69
+ warnings = @fix_scanner.scan("class Hello\n a+b\nend", '(stdin)')
70
+ warnings.size.should == 1
71
+ warnings[0].should be_a(OperatorSpacing)
72
+ @fix_scanner_stdout.string.should == "class Hello\n a + b\nend"
73
+ end
74
+ end
75
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --color --backtrace
@@ -0,0 +1,93 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'simplecov'
4
+ require 'simplecov-gem-adapter'
5
+ SimpleCov.start 'gem'
6
+ require 'wool'
7
+ require 'spec'
8
+ require 'spec/autorun'
9
+ require 'stringio'
10
+
11
+
12
+ include Wool
13
+
14
+ module Wool
15
+ module RSpec
16
+ module Matchers
17
+ # Matcher for checking if #match? returns trues
18
+ class Warns
19
+ def initialize(input, *args)
20
+ @input, @args = input, args
21
+ end
22
+
23
+ def matches?(actual)
24
+ @class = actual
25
+ result = @class.new('(stdin)', @input, *@args).match?
26
+ result && result != [] # empty list is also failure to find any warnings
27
+ end
28
+
29
+ def failure_message
30
+ "expected '#{@actual}' to match #{@input.inspect}"
31
+ end
32
+
33
+ def negative_failure_message
34
+ "expected '#{@actual}' to not match #{@input.inspect}"
35
+ end
36
+ end
37
+
38
+ def warn(input, *args)
39
+ Warns.new(input, *args)
40
+ end
41
+
42
+ # Matcher for comparing input/output of #fix
43
+ class CorrectsTo
44
+ def initialize(input, output, *args)
45
+ @input, @output, @args = input, output, args
46
+ end
47
+
48
+ def matches?(actual)
49
+ @class = actual
50
+ @class.new('(stdin)', @input, *@args).fix == @output
51
+ end
52
+
53
+ def failure_message
54
+ "expected '#{@input}' to correct to #{@output.inspect}"
55
+ end
56
+
57
+ def negative_failure_message
58
+ "expected '#{@input}' to not correct to #{@output.inspect}"
59
+ end
60
+ end
61
+
62
+ def correct_to(input, output, *args)
63
+ CorrectsTo.new(input, output, *args)
64
+ end
65
+ end
66
+ end
67
+ end
68
+
69
+ Spec::Runner.configure do |config|
70
+ config.include(Wool::RSpec::Matchers)
71
+ end
72
+
73
+ def with_examples(*args)
74
+ args.each do |arg|
75
+ yield arg
76
+ end
77
+ end
78
+
79
+ def swizzling_io
80
+ old_stdout, $stdout = $stdout, StringIO.new
81
+ yield
82
+ return $stdout.string
83
+ ensure
84
+ $stdout = old_stdout
85
+ end
86
+
87
+ def swizzling_stdin
88
+ old_stdin, $stdin = $stdin, StringIO.new
89
+ yield $stdin
90
+ return $stdin.string
91
+ ensure
92
+ $stdin = old_stdin
93
+ end
@@ -0,0 +1,91 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe ModuleExtensions do
4
+ before do
5
+ @class = Class.new do
6
+ extend ModuleExtensions
7
+ cattr_reader :read1, :read2
8
+ cattr_writer :write1, :write2
9
+ cattr_accessor :both1, :both2
10
+ cattr_accessor_with_default :arr1, []
11
+ end
12
+ end
13
+
14
+ describe '#cattr_reader' do
15
+ it 'creates reading methods for the given variables' do
16
+ @class.__send__(:instance_variable_set, :@read1, 'hello')
17
+ @class.read1.should == 'hello'
18
+ @class.__send__(:instance_variable_set, :@read2, 5)
19
+ @class.read2.should == 5
20
+ end
21
+ end
22
+
23
+ describe '#cattr_writer' do
24
+ it 'creates writing methods for the given variables' do
25
+ @class.write1 = 'hello'
26
+ @class.__send__(:instance_variable_get, :@write1).should == 'hello'
27
+ @class.write2 = 5
28
+ @class.__send__(:instance_variable_get, :@write2).should == 5
29
+ end
30
+ end
31
+
32
+ describe '#cattr_accessor' do
33
+ it 'creates reading and writing methods for the given variables' do
34
+ @class.both1 = 'hello'
35
+ @class.both1.should == 'hello'
36
+ @class.__send__(:instance_variable_get, :@both1).should == 'hello'
37
+ @class.__send__(:instance_variable_set, :@both1, 'world')
38
+ @class.both1.should == 'world'
39
+ @class.both2 = 5
40
+ @class.both2.should == 5
41
+ @class.__send__(:instance_variable_get, :@both2).should == 5
42
+ @class.__send__(:instance_variable_set, :@both2, 10)
43
+ @class.both2.should == 10
44
+ end
45
+ end
46
+
47
+ describe '#cattr_accessor_with_default' do
48
+ it 'creates reading and writing methods, but defaults the ivar value' do
49
+ @class.arr1.should == []
50
+ @class.__send__(:instance_variable_get, :@arr1).should == []
51
+ @class.arr1.should == [] # second invocation, after default value set
52
+ @class.arr1 = [1, 2]
53
+ @class.arr1.should == [1, 2]
54
+ @class.__send__(:instance_variable_get, :@arr1).should == [1, 2]
55
+ end
56
+ end
57
+
58
+ describe '#cattr_get_and_setter' do
59
+ before do
60
+ @base = Class.new do
61
+ extend ModuleExtensions
62
+ cattr_get_and_setter :type
63
+ type :silly
64
+ end
65
+ end
66
+
67
+ it 'acts a setter and getter on the base class' do
68
+ @base.type.should == :silly
69
+ end
70
+
71
+ it 'is not inherited' do
72
+ @derived = Class.new(@base)
73
+ @derived.type.should_not == :silly
74
+ end
75
+
76
+ it 'can be used by inherited classes' do
77
+ @derived = Class.new(@base) do
78
+ type :laughable
79
+ end
80
+ @derived.type.should == :laughable
81
+ @base.type.should == :silly
82
+ end
83
+
84
+ it 'turns a block into a proc and sets it' do
85
+ @derived = Class.new(@base) do
86
+ type { 5 + 3 }
87
+ end
88
+ @derived.type.call.should == 8
89
+ end
90
+ end
91
+ end
@@ -0,0 +1 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
@@ -0,0 +1,95 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Warning do
4
+ context 'when subclassed' do
5
+ it 'registers the new class in all_warnings' do
6
+ klass = Class.new(Warning)
7
+ Warning.all_warnings.should include(klass)
8
+ end
9
+ end
10
+
11
+ it 'does not match anything' do
12
+ Warning.should_not warn('hello(world)')
13
+ Warning.should_not warn(' a +b ')
14
+ end
15
+
16
+ describe 'short names in warnings' do
17
+ before do
18
+ @real_warnings = Warning.all_warnings.select do |x|
19
+ x.name && x != Warning && x != FileWarning && x != LineWarning
20
+ end
21
+ end
22
+
23
+ it 'exist for every warning class' do
24
+ @real_warnings.select {|x| x.name && x.short_name == nil}.should be_empty
25
+ end
26
+
27
+ it 'do not conflict with each other' do
28
+ short_names = @real_warnings.map {|x| x.short_name}.uniq
29
+ short_names.size.should == @real_warnings.size
30
+ end
31
+ end
32
+
33
+ it 'does not change lines when it fixes them' do
34
+ Warning.should correct_to('a+b', 'a+b')
35
+ Warning.should correct_to(' b ** c+1 eval(string) ', ' b ** c+1 eval(string) ')
36
+ end
37
+
38
+ context '#concrete_warnings' do
39
+ before { @concrete = Warning.concrete_warnings }
40
+ it 'returns a list of classes that are subclasses of Warning' do
41
+ @concrete.should_not be_empty
42
+ @concrete.each {|w| w.ancestors.should include(Warning) }
43
+ end
44
+
45
+ it 'returns a list that does not contain Warning, FileWarning, or LineWarning' do
46
+ @concrete.should_not include(Warning)
47
+ @concrete.should_not include(FileWarning)
48
+ @concrete.should_not include(LineWarning)
49
+ end
50
+ end
51
+
52
+ context '#desc' do
53
+ it "defaults to the class's name with all info" do
54
+ warning = Warning.new('hello.rb', 'a+b')
55
+ warning.severity = 7
56
+ warning.line_number = 3
57
+ warning.desc.should == 'Wool::Warning hello.rb:3 (7)'
58
+ end
59
+
60
+ it 'when specified in a subclass as a string, just uses the string' do
61
+ subclass = Class.new(Warning) { desc 'hello' }
62
+ subclass.new('a', 'b').desc.should == 'hello'
63
+ end
64
+
65
+ it 'when specified in a subclass as a block, runs that proc as the instance' do
66
+ subclass = Class.new(Warning) do
67
+ severity 1024
68
+ desc { self.class.severity.to_s }
69
+ end
70
+ subclass.new('a', 'b').desc.should == '1024'
71
+ end
72
+ end
73
+
74
+ context '#type' do
75
+ it 'returns the current type when no args are provided' do
76
+ klass = Class.new(Warning) do
77
+ def self.set_type
78
+ @type = 'hai'
79
+ end
80
+ end
81
+ klass.set_type
82
+ klass.type.should == 'hai'
83
+ end
84
+
85
+ it 'sets the type when an argument is provided' do
86
+ klass = Class.new(Warning) { type :silly }
87
+ klass.type.should == 'silly'
88
+ end
89
+
90
+ it 'sets a short name based on the type provided' do
91
+ klass = Class.new(Warning) { type :silly }
92
+ klass.short_name.should =~ /SI\d/
93
+ end
94
+ end
95
+ end