reek 1.2.6 → 1.2.8
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.
- data/.yardopts +10 -0
- data/History.txt +62 -0
- data/README.md +74 -0
- data/bin/reek +2 -2
- data/config/defaults.reek +44 -5
- data/features/api.feature +20 -0
- data/features/masking_smells.feature +60 -42
- data/features/options.feature +7 -2
- data/features/rake_task.feature +29 -22
- data/features/reports.feature +9 -41
- data/features/samples.feature +184 -196
- data/features/stdin.feature +5 -8
- data/features/step_definitions/reek_steps.rb +8 -4
- data/features/support/env.rb +2 -3
- data/features/yaml.feature +85 -0
- data/lib/reek/cli/application.rb +46 -0
- data/lib/reek/cli/command_line.rb +108 -0
- data/lib/reek/cli/help_command.rb +18 -0
- data/lib/reek/cli/reek_command.rb +37 -0
- data/lib/reek/cli/report.rb +58 -0
- data/lib/reek/cli/version_command.rb +19 -0
- data/lib/reek/cli/yaml_command.rb +32 -0
- data/lib/reek/core/code_context.rb +64 -0
- data/lib/reek/core/code_parser.rb +166 -0
- data/lib/reek/core/method_context.rb +84 -0
- data/lib/reek/core/module_context.rb +20 -0
- data/lib/reek/core/object_refs.rb +51 -0
- data/lib/reek/core/singleton_method_context.rb +20 -0
- data/lib/reek/core/smell_configuration.rb +62 -0
- data/lib/reek/core/sniffer.rb +105 -0
- data/lib/reek/core/stop_context.rb +30 -0
- data/lib/reek/core/warning_collector.rb +27 -0
- data/lib/reek/examiner.rb +104 -0
- data/lib/reek/rake/task.rb +142 -0
- data/lib/reek/smell_warning.rb +73 -23
- data/lib/reek/smells/attribute.rb +26 -21
- data/lib/reek/smells/boolean_parameter.rb +38 -0
- data/lib/reek/smells/class_variable.rb +22 -9
- data/lib/reek/smells/control_couple.rb +40 -16
- data/lib/reek/smells/data_clump.rb +114 -23
- data/lib/reek/smells/duplication.rb +55 -15
- data/lib/reek/smells/feature_envy.rb +16 -7
- data/lib/reek/smells/irresponsible_module.rb +37 -0
- data/lib/reek/smells/large_class.rb +37 -19
- data/lib/reek/smells/long_method.rb +20 -9
- data/lib/reek/smells/long_parameter_list.rb +22 -10
- data/lib/reek/smells/long_yield_list.rb +43 -7
- data/lib/reek/smells/nested_iterators.rb +68 -8
- data/lib/reek/smells/simulated_polymorphism.rb +26 -15
- data/lib/reek/smells/smell_detector.rb +29 -51
- data/lib/reek/smells/uncommunicative_method_name.rb +74 -0
- data/lib/reek/smells/uncommunicative_module_name.rb +74 -0
- data/lib/reek/smells/uncommunicative_parameter_name.rb +79 -0
- data/lib/reek/smells/uncommunicative_variable_name.rb +89 -0
- data/lib/reek/smells/utility_function.rb +51 -12
- data/lib/reek/smells.rb +29 -0
- data/lib/reek/source/code_comment.rb +37 -0
- data/lib/reek/source/config_file.rb +72 -0
- data/lib/reek/source/core_extras.rb +46 -0
- data/lib/reek/source/reference_collector.rb +28 -0
- data/lib/reek/source/sexp_formatter.rb +17 -0
- data/lib/reek/source/source_code.rb +44 -0
- data/lib/reek/source/source_file.rb +32 -0
- data/lib/reek/source/source_locator.rb +42 -0
- data/lib/reek/source/tree_dresser.rb +204 -0
- data/lib/reek/source.rb +18 -0
- data/lib/reek/spec/should_reek.rb +31 -0
- data/lib/reek/spec/should_reek_of.rb +37 -0
- data/lib/reek/spec/should_reek_only_of.rb +37 -0
- data/lib/reek/spec.rb +51 -0
- data/lib/reek.rb +8 -4
- data/reek.gemspec +9 -7
- data/spec/matchers/smell_of_matcher.rb +58 -0
- data/spec/reek/{help_command_spec.rb → cli/help_command_spec.rb} +3 -4
- data/spec/reek/cli/reek_command_spec.rb +46 -0
- data/spec/reek/cli/report_spec.rb +30 -0
- data/spec/reek/{version_command_spec.rb → cli/version_command_spec.rb} +3 -3
- data/spec/reek/cli/yaml_command_spec.rb +47 -0
- data/spec/reek/core/code_context_spec.rb +145 -0
- data/spec/reek/{code_parser_spec.rb → core/code_parser_spec.rb} +7 -6
- data/spec/reek/{config_spec.rb → core/config_spec.rb} +2 -6
- data/spec/reek/{method_context_spec.rb → core/method_context_spec.rb} +16 -36
- data/spec/reek/core/module_context_spec.rb +27 -0
- data/spec/reek/{object_refs_spec.rb → core/object_refs_spec.rb} +5 -6
- data/spec/reek/core/singleton_method_context_spec.rb +9 -0
- data/spec/reek/core/smell_configuration_spec.rb +11 -0
- data/spec/reek/core/stop_context_spec.rb +17 -0
- data/spec/reek/core/warning_collector_spec.rb +27 -0
- data/spec/reek/examiner_spec.rb +103 -0
- data/spec/reek/smell_warning_spec.rb +74 -82
- data/spec/reek/smells/attribute_spec.rb +42 -23
- data/spec/reek/smells/behaves_like_variable_detector.rb +2 -2
- data/spec/reek/smells/boolean_parameter_spec.rb +66 -0
- data/spec/reek/smells/class_variable_spec.rb +60 -75
- data/spec/reek/smells/control_couple_spec.rb +37 -32
- data/spec/reek/smells/data_clump_spec.rb +63 -24
- data/spec/reek/smells/duplication_spec.rb +106 -57
- data/spec/reek/smells/feature_envy_spec.rb +113 -92
- data/spec/reek/smells/irresponsible_module_spec.rb +58 -0
- data/spec/reek/smells/large_class_spec.rb +67 -57
- data/spec/reek/smells/long_method_spec.rb +40 -10
- data/spec/reek/smells/long_parameter_list_spec.rb +50 -28
- data/spec/reek/smells/long_yield_list_spec.rb +57 -0
- data/spec/reek/smells/nested_iterators_spec.rb +115 -7
- data/spec/reek/smells/simulated_polymorphism_spec.rb +56 -20
- data/spec/reek/smells/smell_detector_shared.rb +42 -0
- data/spec/reek/smells/uncommunicative_method_name_spec.rb +42 -0
- data/spec/reek/smells/uncommunicative_module_name_spec.rb +66 -0
- data/spec/reek/smells/uncommunicative_parameter_name_spec.rb +71 -0
- data/spec/reek/smells/uncommunicative_variable_name_spec.rb +120 -0
- data/spec/reek/smells/utility_function_spec.rb +50 -4
- data/spec/reek/source/code_comment_spec.rb +82 -0
- data/spec/reek/source/object_source_spec.rb +20 -0
- data/spec/reek/source/reference_collector_spec.rb +53 -0
- data/spec/reek/{adapters/source_spec.rb → source/source_code_spec.rb} +7 -8
- data/spec/reek/source/tree_dresser_spec.rb +270 -0
- data/spec/reek/spec/should_reek_of_spec.rb +76 -0
- data/spec/reek/spec/should_reek_only_of_spec.rb +89 -0
- data/spec/reek/{adapters → spec}/should_reek_spec.rb +8 -32
- data/spec/samples/all_but_one_masked/clean_one.rb +1 -0
- data/spec/samples/all_but_one_masked/dirty.rb +1 -0
- data/spec/samples/all_but_one_masked/masked.reek +5 -1
- data/spec/samples/clean_due_to_masking/clean_one.rb +1 -0
- data/spec/samples/clean_due_to_masking/clean_three.rb +1 -0
- data/spec/samples/clean_due_to_masking/clean_two.rb +1 -0
- data/spec/samples/clean_due_to_masking/dirty_one.rb +1 -1
- data/spec/samples/clean_due_to_masking/dirty_two.rb +1 -1
- data/spec/samples/clean_due_to_masking/masked.reek +5 -1
- data/spec/samples/config/allow_duplication.reek +3 -0
- data/spec/samples/config/deeper_nested_iterators.reek +3 -0
- data/spec/samples/corrupt_config_file/dirty.rb +1 -1
- data/spec/samples/demo/demo.rb +8 -0
- data/spec/samples/empty_config_file/dirty.rb +2 -1
- data/spec/samples/exceptions.reek +1 -1
- data/spec/samples/inline_config/dirty.rb +16 -0
- data/spec/samples/inline_config/masked.reek +7 -0
- data/spec/samples/mask_some/dirty.rb +8 -0
- data/spec/samples/mask_some/some.reek +8 -0
- data/spec/samples/masked/dirty.rb +2 -1
- data/spec/samples/masked/masked.reek +3 -1
- data/spec/samples/mixed_results/clean_one.rb +1 -0
- data/spec/samples/mixed_results/clean_three.rb +1 -0
- data/spec/samples/mixed_results/clean_two.rb +1 -0
- data/spec/samples/mixed_results/dirty_one.rb +1 -0
- data/spec/samples/mixed_results/dirty_two.rb +1 -0
- data/spec/samples/not_quite_masked/dirty.rb +2 -1
- data/spec/samples/not_quite_masked/masked.reek +1 -1
- data/spec/samples/overrides/masked/dirty.rb +2 -1
- data/spec/samples/overrides/masked/lower.reek +3 -1
- data/spec/samples/three_clean_files/clean_one.rb +1 -0
- data/spec/samples/three_clean_files/clean_three.rb +1 -0
- data/spec/samples/three_clean_files/clean_two.rb +1 -0
- data/spec/samples/two_smelly_files/dirty_one.rb +2 -1
- data/spec/samples/two_smelly_files/dirty_two.rb +2 -1
- data/spec/spec_helper.rb +10 -2
- data/tasks/reek.rake +2 -2
- data/tasks/test.rake +12 -3
- metadata +121 -79
- data/README.rdoc +0 -84
- data/features/profile.feature +0 -34
- data/lib/reek/adapters/application.rb +0 -46
- data/lib/reek/adapters/command_line.rb +0 -77
- data/lib/reek/adapters/config_file.rb +0 -31
- data/lib/reek/adapters/core_extras.rb +0 -64
- data/lib/reek/adapters/rake_task.rb +0 -121
- data/lib/reek/adapters/report.rb +0 -86
- data/lib/reek/adapters/source.rb +0 -72
- data/lib/reek/adapters/spec.rb +0 -133
- data/lib/reek/block_context.rb +0 -62
- data/lib/reek/class_context.rb +0 -41
- data/lib/reek/code_context.rb +0 -68
- data/lib/reek/code_parser.rb +0 -203
- data/lib/reek/configuration.rb +0 -57
- data/lib/reek/detector_stack.rb +0 -37
- data/lib/reek/help_command.rb +0 -14
- data/lib/reek/if_context.rb +0 -18
- data/lib/reek/masking_collection.rb +0 -33
- data/lib/reek/method_context.rb +0 -138
- data/lib/reek/module_context.rb +0 -49
- data/lib/reek/name.rb +0 -57
- data/lib/reek/object_refs.rb +0 -49
- data/lib/reek/reek_command.rb +0 -28
- data/lib/reek/sexp_formatter.rb +0 -10
- data/lib/reek/singleton_method_context.rb +0 -26
- data/lib/reek/smells/uncommunicative_name.rb +0 -84
- data/lib/reek/sniffer.rb +0 -177
- data/lib/reek/stop_context.rb +0 -35
- data/lib/reek/tree_dresser.rb +0 -82
- data/lib/reek/version_command.rb +0 -14
- data/lib/reek/yield_call_context.rb +0 -12
- data/spec/reek/adapters/report_spec.rb +0 -31
- data/spec/reek/adapters/should_reek_of_spec.rb +0 -138
- data/spec/reek/adapters/should_reek_only_of_spec.rb +0 -87
- data/spec/reek/block_context_spec.rb +0 -65
- data/spec/reek/class_context_spec.rb +0 -161
- data/spec/reek/code_context_spec.rb +0 -182
- data/spec/reek/configuration_spec.rb +0 -12
- data/spec/reek/if_context_spec.rb +0 -17
- data/spec/reek/masking_collection_spec.rb +0 -236
- data/spec/reek/module_context_spec.rb +0 -46
- data/spec/reek/name_spec.rb +0 -37
- data/spec/reek/object_source_spec.rb +0 -23
- data/spec/reek/reek_command_spec.rb +0 -45
- data/spec/reek/singleton_method_context_spec.rb +0 -16
- data/spec/reek/smells/smell_detector_spec.rb +0 -36
- data/spec/reek/smells/uncommunicative_name_spec.rb +0 -146
- data/spec/reek/sniffer_spec.rb +0 -11
- data/spec/reek/stop_context_spec.rb +0 -33
- data/spec/reek/tree_dresser_spec.rb +0 -20
data/lib/reek/tree_dresser.rb
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
module Reek
|
|
2
|
-
|
|
3
|
-
#
|
|
4
|
-
# Extensions to +Sexp+ to allow +CodeParser+ to navigate the abstract
|
|
5
|
-
# syntax tree more easily.
|
|
6
|
-
#
|
|
7
|
-
module SexpNode
|
|
8
|
-
def is_language_node?
|
|
9
|
-
first.class == Symbol
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def has_type?(type)
|
|
13
|
-
is_language_node? and first == type
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
#
|
|
17
|
-
# Carries out a depth-first traversal of this syntax tree, yielding
|
|
18
|
-
# every Sexp of type +target_type+. The traversal ignores any node
|
|
19
|
-
# whose type is listed in the Array +ignoring+.
|
|
20
|
-
#
|
|
21
|
-
def look_for(target_type, ignoring, &blk)
|
|
22
|
-
each do |elem|
|
|
23
|
-
if Sexp === elem then
|
|
24
|
-
elem.look_for(target_type, ignoring, &blk) unless ignoring.include?(elem.first)
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
blk.call(self) if first == target_type
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
module SexpExtensions
|
|
32
|
-
module CaseNode
|
|
33
|
-
def condition
|
|
34
|
-
self[1]
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
module CallNode
|
|
39
|
-
def receiver() self[1] end
|
|
40
|
-
def method_name() self[2] end
|
|
41
|
-
def args() self[3] end
|
|
42
|
-
def arg_names
|
|
43
|
-
args[1..-1].map {|arg| arg[1]}
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
module CvarNode
|
|
48
|
-
def name() self[1] end
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
CvasgnNode = CvarNode
|
|
52
|
-
CvdeclNode = CvarNode
|
|
53
|
-
|
|
54
|
-
module DefnNode
|
|
55
|
-
def method_name() self[1] end
|
|
56
|
-
def parameters() self[2] end
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
module IfNode
|
|
60
|
-
def condition
|
|
61
|
-
self[1]
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
class TreeDresser
|
|
67
|
-
|
|
68
|
-
def dress(sexp)
|
|
69
|
-
sexp.extend(SexpNode)
|
|
70
|
-
module_name = extensions_for(sexp.sexp_type)
|
|
71
|
-
if Reek::SexpExtensions.const_defined?(module_name)
|
|
72
|
-
sexp.extend(Reek::SexpExtensions.const_get(module_name))
|
|
73
|
-
end
|
|
74
|
-
sexp[0..-1].each { |sub| dress(sub) if Array === sub }
|
|
75
|
-
sexp
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def extensions_for(node_type)
|
|
79
|
-
"#{node_type.to_s.capitalize}Node"
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
end
|
data/lib/reek/version_command.rb
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
require File.dirname(__FILE__) + '/../../spec_helper.rb'
|
|
2
|
-
|
|
3
|
-
require 'reek/adapters/core_extras'
|
|
4
|
-
require 'reek/adapters/report'
|
|
5
|
-
require 'reek/adapters/source'
|
|
6
|
-
require 'reek/smells/feature_envy'
|
|
7
|
-
|
|
8
|
-
include Reek
|
|
9
|
-
|
|
10
|
-
describe ReportSection, " when empty" do
|
|
11
|
-
before(:each) do
|
|
12
|
-
@rpt = ReportSection.new(''.sniff, false)
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
it 'has an empty quiet_report' do
|
|
16
|
-
@rpt.quiet_report.should == ''
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
describe ReportSection, "smell_list" do
|
|
21
|
-
before(:each) do
|
|
22
|
-
rpt = ReportSection.new('def simple(a) a[3] end'.sniff, false)
|
|
23
|
-
@lines = rpt.smell_list.split("\n")
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
it 'should mention every smell name' do
|
|
27
|
-
@lines.should have_at_least(2).lines
|
|
28
|
-
@lines[0].should match(/[Utility Function]/)
|
|
29
|
-
@lines[1].should match(/[Feature Envy]/)
|
|
30
|
-
end
|
|
31
|
-
end
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
require File.dirname(__FILE__) + '/../../spec_helper.rb'
|
|
2
|
-
|
|
3
|
-
require 'reek/adapters/report'
|
|
4
|
-
require 'reek/adapters/spec'
|
|
5
|
-
|
|
6
|
-
include Reek
|
|
7
|
-
include Reek::Spec
|
|
8
|
-
|
|
9
|
-
# belongs in its own spec file
|
|
10
|
-
describe ReekMatcher do
|
|
11
|
-
before :each do
|
|
12
|
-
smelly_code = Dir['spec/samples/two_smelly_files/*.rb']
|
|
13
|
-
@sniffers = smelly_code.sniff.sniffers
|
|
14
|
-
@full = VerboseReport.new(@sniffers, false).report
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
it 'reports quietly' do
|
|
18
|
-
ReekMatcher.create_reporter(@sniffers).should_not == @full
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
describe ShouldReekOf do
|
|
23
|
-
context 'rdoc demo example' do
|
|
24
|
-
before :each do
|
|
25
|
-
@ruby = 'def double_thing() @other.thing.foo + @other.thing.foo end'
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
shared_examples_for 'reek as documented' do
|
|
29
|
-
it 'reports duplicate calls to @other.thing' do
|
|
30
|
-
@ruby.should reek_of(:Duplication, /@other.thing[^\.]/)
|
|
31
|
-
end
|
|
32
|
-
it 'reports duplicate calls to @other.thing.foo' do
|
|
33
|
-
@ruby.should reek_of(:Duplication, /@other.thing.foo/)
|
|
34
|
-
end
|
|
35
|
-
it 'does not report any feature envy' do
|
|
36
|
-
@ruby.should_not reek_of(:FeatureEnvy)
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
context 'using source code' do
|
|
41
|
-
it_should_behave_like 'reek as documented'
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
context 'using a sniffer' do
|
|
45
|
-
before :each do
|
|
46
|
-
@ruby = @ruby.sniff
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
it_should_behave_like 'reek as documented'
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
context 'checking code in a string' do
|
|
54
|
-
before :each do
|
|
55
|
-
@clean_code = 'def good() true; end'
|
|
56
|
-
@smelly_code = 'def x() y = 4; end'
|
|
57
|
-
@expected_report = Reek::Spec::ReekMatcher::create_reporter(@smelly_code.sniff).report
|
|
58
|
-
@matcher = ShouldReekOf.new(:UncommunicativeName, [/x/, /y/])
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
it 'matches a smelly String' do
|
|
62
|
-
@matcher.matches?(@smelly_code).should be_true
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
it 'doesnt match a fragrant String' do
|
|
66
|
-
@matcher.matches?(@clean_code).should be_false
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
it 'reports the smells when should_not fails' do
|
|
70
|
-
@matcher.matches?(@smelly_code).should be_true
|
|
71
|
-
@matcher.failure_message_for_should_not.should include(@expected_report)
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
context 'checking code in a Dir' do
|
|
76
|
-
before :each do
|
|
77
|
-
@clean_dir = Dir['spec/samples/three_clean_files/*.rb']
|
|
78
|
-
@smelly_dir = Dir['spec/samples/two_smelly_files/*.rb']
|
|
79
|
-
@matcher = ShouldReekOf.new(:UncommunicativeName, [/Dirty/, /@s/])
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
it 'matches a smelly String' do
|
|
83
|
-
@matcher.matches?(@smelly_dir).should be_true
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
it 'doesnt match a fragrant String' do
|
|
87
|
-
@matcher.matches?(@clean_dir).should be_false
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
it 'reports the smells when should_not fails' do
|
|
91
|
-
@matcher.matches?(@smelly_dir).should be_true
|
|
92
|
-
@matcher.failure_message_for_should_not.should include(QuietReport.new(@smelly_dir.sniff.sniffers, '%m%c %w (%s)').report)
|
|
93
|
-
end
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
context 'checking code in a File' do
|
|
97
|
-
before :each do
|
|
98
|
-
@clean_file = File.new(Dir['spec/samples/three_clean_files/*.rb'][0])
|
|
99
|
-
@smelly_file = File.new(Dir['spec/samples/two_smelly_files/*.rb'][0])
|
|
100
|
-
@matcher = ShouldReekOf.new(:UncommunicativeName, [/Dirty/, /@s/])
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
it 'matches a smelly String' do
|
|
104
|
-
@matcher.matches?(@smelly_file).should be_true
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
it 'doesnt match a fragrant String' do
|
|
108
|
-
@matcher.matches?(@clean_file).should be_false
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
it 'reports the smells when should_not fails' do
|
|
112
|
-
@matcher.matches?(@smelly_file).should be_true
|
|
113
|
-
@matcher.failure_message_for_should_not.should include(QuietReport.new(@smelly_file.sniff, '%m%c %w (%s)').report)
|
|
114
|
-
end
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
context 'report formatting' do
|
|
118
|
-
before :each do
|
|
119
|
-
sn_clean = 'def clean() @thing = 4; end'.sniff
|
|
120
|
-
sn_dirty = 'def dirty() thing.cool + thing.cool; end'.sniff
|
|
121
|
-
sniffers = SnifferSet.new([sn_clean, sn_dirty], '')
|
|
122
|
-
@matcher = ShouldReekOf.new(:UncommunicativeName, [/Dirty/, /@s/])
|
|
123
|
-
@matcher.matches?(sniffers)
|
|
124
|
-
@lines = @matcher.failure_message_for_should_not.split("\n").map {|str| str.chomp}
|
|
125
|
-
@error_message = @lines.shift
|
|
126
|
-
@smells = @lines.grep(/^ /)
|
|
127
|
-
@headers = (@lines - @smells)
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
it 'mentions every smell in the report' do
|
|
131
|
-
@smells.should have(2).warnings
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
it 'doesnt mention the clean source' do
|
|
135
|
-
@headers.should have(1).headers
|
|
136
|
-
end
|
|
137
|
-
end
|
|
138
|
-
end
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
require File.dirname(__FILE__) + '/../../spec_helper.rb'
|
|
2
|
-
|
|
3
|
-
require 'reek/adapters/report'
|
|
4
|
-
require 'reek/adapters/spec'
|
|
5
|
-
|
|
6
|
-
include Reek
|
|
7
|
-
include Reek::Spec
|
|
8
|
-
|
|
9
|
-
describe ShouldReekOnlyOf, 'checking code in a string' do
|
|
10
|
-
before :each do
|
|
11
|
-
@clean_code = 'def good() true; end'
|
|
12
|
-
@smelly_code = 'def fine() y = 4; end'
|
|
13
|
-
@matcher = ShouldReekOnlyOf.new(:UncommunicativeName, [/y/])
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
it 'matches a smelly String' do
|
|
17
|
-
@matcher.matches?(@smelly_code).should be_true
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
it 'doesnt match a fragrant String' do
|
|
21
|
-
@matcher.matches?(@clean_code).should be_false
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
it 'reports the smells when should_not fails' do
|
|
25
|
-
@matcher.matches?(@smelly_code).should be_true
|
|
26
|
-
@matcher.failure_message_for_should_not.should include('UncommunicativeName')
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
describe ShouldReekOnlyOf, 'checking code in a Dir' do
|
|
31
|
-
before :each do
|
|
32
|
-
@clean_dir = Dir['spec/samples/three_clean_files/*.rb']
|
|
33
|
-
@smelly_dir = Dir['spec/samples/all_but_one_masked/*.rb']
|
|
34
|
-
@matcher = ShouldReekOnlyOf.new(:NestedIterators, [/Dirty\#a/])
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
it 'matches a smelly String' do
|
|
38
|
-
@matcher.matches?(@smelly_dir).should be_true
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
it 'doesnt match a fragrant String' do
|
|
42
|
-
@matcher.matches?(@clean_dir).should be_false
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
it 'reports the smells when should_not fails' do
|
|
46
|
-
@matcher.matches?(@smelly_dir).should be_true
|
|
47
|
-
@matcher.failure_message_for_should.should include(QuietReport.new(@smelly_dir.sniff.sniffers).report)
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
describe ShouldReekOnlyOf, 'checking code in a File' do
|
|
52
|
-
before :each do
|
|
53
|
-
@clean_file = File.new(Dir['spec/samples/three_clean_files/*.rb'][0])
|
|
54
|
-
@smelly_file = File.new(Dir['spec/samples/all_but_one_masked/d*.rb'][0])
|
|
55
|
-
@matcher = ShouldReekOnlyOf.new(:NestedIterators, [/Dirty\#a/])
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
it 'matches a smelly String' do
|
|
59
|
-
@matcher.matches?(@smelly_file).should be_true
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
it 'doesnt match a fragrant String' do
|
|
63
|
-
@matcher.matches?(@clean_file).should be_false
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
it 'reports the smells when should_not fails' do
|
|
67
|
-
@matcher.matches?(@smelly_file).should be_true
|
|
68
|
-
@matcher.failure_message_for_should.should include(QuietReport.new(@smelly_file.sniff).report)
|
|
69
|
-
end
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
describe ShouldReekOnlyOf, 'report formatting' do
|
|
73
|
-
before :each do
|
|
74
|
-
@smelly_dir = Dir['spec/samples/all_but_one_masked/*.rb']
|
|
75
|
-
@matcher = ShouldReekOnlyOf.new(:NestedIterators, [/Dirty\#a/])
|
|
76
|
-
@matcher.matches?(@smelly_dir)
|
|
77
|
-
@lines = @matcher.failure_message_for_should.split("\n").map {|str| str.chomp}
|
|
78
|
-
@error_message = @lines.shift
|
|
79
|
-
@smells = @lines.grep(/^ /)
|
|
80
|
-
@headers = (@lines - @smells)
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
it 'doesnt mention the clean files' do
|
|
84
|
-
@headers.should have(1).header
|
|
85
|
-
@headers.should_not include('clean')
|
|
86
|
-
end
|
|
87
|
-
end
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
|
2
|
-
|
|
3
|
-
require 'reek/block_context'
|
|
4
|
-
require 'reek/method_context'
|
|
5
|
-
|
|
6
|
-
include Reek
|
|
7
|
-
|
|
8
|
-
describe BlockContext do
|
|
9
|
-
|
|
10
|
-
it "should record single parameter" do
|
|
11
|
-
element = StopContext.new
|
|
12
|
-
element = BlockContext.new(element, s(:iter, nil, s(:lasgn, :x), nil))
|
|
13
|
-
element.variable_names.should == [Name.new(:x)]
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
it "should record single parameter within a method" do
|
|
17
|
-
element = StopContext.new
|
|
18
|
-
element = MethodContext.new(element, s(:defn, :help))
|
|
19
|
-
element = BlockContext.new(element, s(:iter, nil, s(:lasgn, :x), nil))
|
|
20
|
-
element.variable_names.should == [Name.new(:x)]
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
it "records multiple parameters" do
|
|
24
|
-
element = StopContext.new
|
|
25
|
-
element = BlockContext.new(element, s(:iter, nil, s(:masgn, s(:array, s(:lasgn, :x), s(:lasgn, :y))), nil))
|
|
26
|
-
element.variable_names.should == [Name.new(:x), Name.new(:y)]
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
it "should not pass parameters upward" do
|
|
30
|
-
mc = MethodContext.new(StopContext.new, s(:defn, :help, s(:args)))
|
|
31
|
-
element = BlockContext.new(mc, s(:iter, nil, s(:lasgn, :x)))
|
|
32
|
-
mc.variable_names.should be_empty
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
it 'records local variables' do
|
|
36
|
-
bctx = BlockContext.new(StopContext.new, s(nil, nil))
|
|
37
|
-
bctx.record_local_variable(:q2)
|
|
38
|
-
bctx.variable_names.should include(Name.new(:q2))
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
it 'copes with a yield to an ivar' do
|
|
42
|
-
scope = BlockContext.new(StopContext.new, s(:iter, nil, s(:iasgn, :@list), s(:self)))
|
|
43
|
-
scope.record_instance_variable(:@list)
|
|
44
|
-
scope.variable_names.should == [:@list]
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
context 'full_name' do
|
|
48
|
-
it "reports full context" do
|
|
49
|
-
bctx = BlockContext.new(StopContext.new, s(nil, nil))
|
|
50
|
-
bctx.full_name.should == 'block'
|
|
51
|
-
end
|
|
52
|
-
it 'uses / to connect to the class name' do
|
|
53
|
-
element = StopContext.new
|
|
54
|
-
element = ClassContext.new(element, :Fred, s(:class, :Fred))
|
|
55
|
-
element = BlockContext.new(element, s(:iter, nil, s(:lasgn, :x), nil))
|
|
56
|
-
element.full_name.should == 'Fred/block'
|
|
57
|
-
end
|
|
58
|
-
it 'uses / to connect to the module name' do
|
|
59
|
-
element = StopContext.new
|
|
60
|
-
element = ModuleContext.new(element, :Fred, s(:module, :Fred))
|
|
61
|
-
element = BlockContext.new(element, s(:iter, nil, s(:lasgn, :x), nil))
|
|
62
|
-
element.full_name.should == 'Fred/block'
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
end
|
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
|
2
|
-
|
|
3
|
-
require 'reek/class_context'
|
|
4
|
-
require 'reek/stop_context'
|
|
5
|
-
require 'reek/smells/feature_envy'
|
|
6
|
-
|
|
7
|
-
include Reek
|
|
8
|
-
include Reek::Smells
|
|
9
|
-
|
|
10
|
-
describe ClassContext do
|
|
11
|
-
it 'should report Long Parameter List' do
|
|
12
|
-
ruby = 'class Inner; def simple(arga, argb, argc, argd) f(3);true end end'
|
|
13
|
-
ruby.should reek_of(:LongParameterList, /Inner/, /simple/, /4 parameters/)
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
it 'should report two different methods' do
|
|
17
|
-
src = <<EOEX
|
|
18
|
-
class Fred
|
|
19
|
-
def simple(arga, argb, argc, argd) f(3);true end
|
|
20
|
-
def simply(arga, argb, argc, argd) f(3);false end
|
|
21
|
-
end
|
|
22
|
-
EOEX
|
|
23
|
-
|
|
24
|
-
src.should reek_of(:LongParameterList, /Fred/, /simple/)
|
|
25
|
-
src.should reek_of(:LongParameterList, /Fred/, /simply/)
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
it 'should report many different methods' do
|
|
29
|
-
src = <<EOEX
|
|
30
|
-
class Fred
|
|
31
|
-
def textile_bq(tag, atts, cite, content) f(3);end
|
|
32
|
-
def textile_p(tag, atts, cite, content) f(3);end
|
|
33
|
-
def textile_fn_(tag, num, atts, cite, content) f(3);end
|
|
34
|
-
def textile_popup_help(name, windowW, windowH) f(3);end
|
|
35
|
-
end
|
|
36
|
-
EOEX
|
|
37
|
-
|
|
38
|
-
src.should reek_of(:LongParameterList, /Fred/, /textile_bq/)
|
|
39
|
-
src.should reek_of(:LongParameterList, /Fred/, /textile_fn_/)
|
|
40
|
-
src.should reek_of(:LongParameterList, /Fred/, /textile_p/)
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
class Above
|
|
45
|
-
def above() end
|
|
46
|
-
def both() end
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
class Below < Above
|
|
50
|
-
def both() end
|
|
51
|
-
def below() end
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
describe ClassContext, 'overridden methods' do
|
|
55
|
-
describe 'of loaded class' do
|
|
56
|
-
before :each do
|
|
57
|
-
@ctx = ClassContext.create(StopContext.new, [0, :Below])
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
it 'should recognise non-overridden method' do
|
|
61
|
-
@ctx.is_overriding_method?('below').should == false
|
|
62
|
-
@ctx.is_overriding_method?('above').should == false
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
it 'should recognise overridden method' do
|
|
66
|
-
@ctx.is_overriding_method?('both').should == true
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
it 'should recognise methods in current codebase' do
|
|
70
|
-
ctx = ClassContext.create(StopContext.new, [0, :FeatureEnvy])
|
|
71
|
-
ctx.is_overriding_method?('examine_context').should == true
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
describe 'of non-loaded class' do
|
|
76
|
-
before :each do
|
|
77
|
-
@ctx = ClassContext.create(StopContext.new, [0, :Missing])
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
it 'should recognise non-overridden method' do
|
|
81
|
-
@ctx.is_overriding_method?('below').should == false
|
|
82
|
-
@ctx.is_overriding_method?('above').should == false
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
it 'should recognise overridden method' do
|
|
86
|
-
@ctx.is_overriding_method?('both').should == false
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
describe 'Integration defect:' do
|
|
92
|
-
it 'should not report UtilityFunction for FeatureEnvy#examine_context' do
|
|
93
|
-
kelement = ClassContext.create(StopContext.new, [0, :FeatureEnvy, s(:const, :SmellDetector)])
|
|
94
|
-
meth = Name.new(:examine_context)
|
|
95
|
-
kelement.is_overriding_method?(meth).should == true
|
|
96
|
-
melement = MethodContext.new(kelement, [0, :examine_context])
|
|
97
|
-
melement.is_overriding_method?(meth).should == true
|
|
98
|
-
melement.depends_on_instance?.should == true
|
|
99
|
-
end
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
module Mod1
|
|
103
|
-
class Klass1
|
|
104
|
-
module Mod2
|
|
105
|
-
class Klass2
|
|
106
|
-
end
|
|
107
|
-
end
|
|
108
|
-
end
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
describe CodeContext, 'find class' do
|
|
112
|
-
before :each do
|
|
113
|
-
@stop = StopContext.new
|
|
114
|
-
@mod1 = ModuleContext.create(@stop, [0, :Mod1])
|
|
115
|
-
@klass1 = ClassContext.create(@mod1, [0, :Klass1])
|
|
116
|
-
@mod2 = ModuleContext.create(@klass1, [0, :Mod2])
|
|
117
|
-
@klass2 = ClassContext.create(@mod2, [0, :Klass2])
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
describe ModuleContext do
|
|
121
|
-
it 'should find local name' do
|
|
122
|
-
@mod1.find_module('Klass1').name.should == 'Mod1::Klass1'
|
|
123
|
-
@mod2.find_module('Klass2').name.should == 'Mod1::Klass1::Mod2::Klass2'
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
it 'should not find deeper class' do
|
|
127
|
-
@mod1.find_module('Klass2').should == nil
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
it 'should find own Module' do
|
|
131
|
-
@mod1.myself.name.should == 'Mod1'
|
|
132
|
-
@mod2.myself.name.should == 'Mod1::Klass1::Mod2'
|
|
133
|
-
end
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
describe ClassContext do
|
|
137
|
-
it 'should find local module' do
|
|
138
|
-
@klass1.find_module('Mod2').name.should == 'Mod1::Klass1::Mod2'
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
it 'should not find deeper module' do
|
|
142
|
-
@klass1.find_module('Klass2').should == nil
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
it 'should find own Class' do
|
|
146
|
-
@klass1.myself.name.should == 'Mod1::Klass1'
|
|
147
|
-
@klass2.myself.name.should == 'Mod1::Klass1::Mod2::Klass2'
|
|
148
|
-
end
|
|
149
|
-
end
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
describe ClassContext do
|
|
153
|
-
it 'does not report empty class in another module' do
|
|
154
|
-
'class Treetop::Runtime::SyntaxNode; end'.should_not reek
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
it 'deals with :: scoped names' do
|
|
158
|
-
element = ClassContext.create(StopContext.new, [:colon2, [:colon2, [:const, :Treetop], :Runtime], :SyntaxNode])
|
|
159
|
-
element.num_methods.should == 0
|
|
160
|
-
end
|
|
161
|
-
end
|