reek 1.2.7.2 → 1.2.7.3
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +9 -1
- data/config/defaults.reek +4 -4
- data/features/masking_smells.feature +14 -57
- data/features/options.feature +1 -2
- data/features/rake_task.feature +6 -6
- data/features/reports.feature +8 -38
- data/features/samples.feature +181 -181
- data/features/stdin.feature +3 -3
- data/lib/reek.rb +1 -1
- data/lib/reek/cli/command_line.rb +2 -7
- data/lib/reek/cli/reek_command.rb +6 -6
- data/lib/reek/cli/report.rb +27 -49
- data/lib/reek/core/code_parser.rb +6 -15
- data/lib/reek/core/method_context.rb +1 -1
- data/lib/reek/core/module_context.rb +0 -18
- data/lib/reek/core/smell_configuration.rb +0 -4
- data/lib/reek/core/sniffer.rb +11 -19
- data/lib/reek/core/warning_collector.rb +27 -0
- data/lib/reek/examiner.rb +43 -35
- data/lib/reek/rake/task.rb +2 -0
- data/lib/reek/smell_warning.rb +10 -25
- data/lib/reek/smells/boolean_parameter.rb +1 -1
- data/lib/reek/smells/control_couple.rb +4 -1
- data/lib/reek/smells/data_clump.rb +40 -33
- data/lib/reek/smells/feature_envy.rb +1 -1
- data/lib/reek/smells/long_parameter_list.rb +4 -1
- data/lib/reek/smells/long_yield_list.rb +6 -3
- data/lib/reek/smells/simulated_polymorphism.rb +1 -1
- data/lib/reek/smells/smell_detector.rb +4 -32
- data/lib/reek/smells/uncommunicative_method_name.rb +1 -1
- data/lib/reek/smells/uncommunicative_module_name.rb +1 -1
- data/lib/reek/smells/uncommunicative_parameter_name.rb +2 -2
- data/lib/reek/smells/uncommunicative_variable_name.rb +11 -18
- data/lib/reek/smells/utility_function.rb +7 -4
- data/lib/reek/source/reference_collector.rb +9 -2
- data/lib/reek/source/source_locator.rb +6 -0
- data/lib/reek/spec/should_reek.rb +3 -6
- data/lib/reek/spec/should_reek_only_of.rb +4 -3
- data/reek.gemspec +4 -4
- data/spec/reek/cli/reek_command_spec.rb +3 -4
- data/spec/reek/cli/report_spec.rb +10 -6
- data/spec/reek/cli/yaml_command_spec.rb +1 -1
- data/spec/reek/core/code_context_spec.rb +1 -3
- data/spec/reek/core/module_context_spec.rb +1 -1
- data/spec/reek/core/warning_collector_spec.rb +27 -0
- data/spec/reek/examiner_spec.rb +80 -19
- data/spec/reek/smell_warning_spec.rb +4 -61
- data/spec/reek/smells/attribute_spec.rb +4 -7
- data/spec/reek/smells/behaves_like_variable_detector.rb +2 -2
- data/spec/reek/smells/class_variable_spec.rb +0 -1
- data/spec/reek/smells/control_couple_spec.rb +8 -15
- data/spec/reek/smells/data_clump_spec.rb +85 -1
- data/spec/reek/smells/duplication_spec.rb +7 -8
- data/spec/reek/smells/feature_envy_spec.rb +2 -32
- data/spec/reek/smells/long_parameter_list_spec.rb +9 -16
- data/spec/reek/smells/long_yield_list_spec.rb +8 -15
- data/spec/reek/smells/smell_detector_shared.rb +12 -0
- data/spec/reek/smells/uncommunicative_variable_name_spec.rb +9 -10
- data/spec/reek/smells/utility_function_spec.rb +11 -15
- data/spec/reek/spec/should_reek_only_of_spec.rb +6 -6
- data/spec/reek/spec/should_reek_spec.rb +3 -3
- metadata +36 -22
- data/lib/reek/core/class_context.rb +0 -22
- data/lib/reek/core/detector_stack.rb +0 -33
- data/lib/reek/core/masking_collection.rb +0 -52
- data/spec/reek/core/class_context_spec.rb +0 -53
- data/spec/reek/core/masking_collection_spec.rb +0 -235
@@ -35,6 +35,9 @@ module Reek
|
|
35
35
|
#
|
36
36
|
class UtilityFunction < SmellDetector
|
37
37
|
|
38
|
+
SMELL_SUBCLASS = self.name.split(/::/)[-1]
|
39
|
+
SMELL_CLASS = 'LowCohesion'
|
40
|
+
|
38
41
|
# The name of the config field that sets the maximum number of
|
39
42
|
# calls permitted within a helper method. Any method with more than
|
40
43
|
# this number of method calls on other objects will be considered a
|
@@ -62,12 +65,12 @@ module Reek
|
|
62
65
|
#
|
63
66
|
def examine_context(method_ctx)
|
64
67
|
return false if method_ctx.num_statements == 0
|
65
|
-
return false if depends_on_instance?(method_ctx.exp
|
68
|
+
return false if depends_on_instance?(method_ctx.exp)
|
66
69
|
return false if num_helper_methods(method_ctx) <= value(HELPER_CALLS_LIMIT_KEY, method_ctx, DEFAULT_HELPER_CALLS_LIMIT)
|
67
70
|
# SMELL: loads of calls to value{} with the above pattern
|
68
|
-
smell = SmellWarning.new(
|
69
|
-
"doesn't depend on instance state",
|
70
|
-
@source,
|
71
|
+
smell = SmellWarning.new(SMELL_CLASS, method_ctx.full_name, [method_ctx.exp.line],
|
72
|
+
"doesn't depend on instance state",
|
73
|
+
@source, SMELL_SUBCLASS)
|
71
74
|
@smells_found << smell
|
72
75
|
#SMELL: serious duplication
|
73
76
|
end
|
@@ -1,7 +1,14 @@
|
|
1
1
|
|
2
2
|
module Reek
|
3
3
|
module Source
|
4
|
+
|
5
|
+
#
|
6
|
+
# Locates references to the current object within a portion
|
7
|
+
# of an abstract syntax tree.
|
8
|
+
#
|
4
9
|
class ReferenceCollector
|
10
|
+
STOP_NODES = [:class, :module, :defn, :defs]
|
11
|
+
|
5
12
|
def initialize(ast)
|
6
13
|
@ast = ast
|
7
14
|
end
|
@@ -9,9 +16,9 @@ module Reek
|
|
9
16
|
def num_refs_to_self
|
10
17
|
result = 0
|
11
18
|
[:self, :zsuper, :ivar, :iasgn].each do |node_type|
|
12
|
-
@ast.look_for(node_type,
|
19
|
+
@ast.look_for(node_type, STOP_NODES) { result += 1}
|
13
20
|
end
|
14
|
-
@ast.look_for(:call,
|
21
|
+
@ast.look_for(:call, STOP_NODES) do |call|
|
15
22
|
result += 1 unless call.receiver
|
16
23
|
end
|
17
24
|
result
|
@@ -2,6 +2,10 @@ require File.join(File.dirname(File.expand_path(__FILE__)), 'core_extras')
|
|
2
2
|
|
3
3
|
module Reek
|
4
4
|
module Source
|
5
|
+
|
6
|
+
#
|
7
|
+
# Finds Ruby source files in a filesystem.
|
8
|
+
#
|
5
9
|
class SourceLocator
|
6
10
|
def initialize(paths)
|
7
11
|
@paths = paths
|
@@ -11,6 +15,8 @@ module Reek
|
|
11
15
|
valid_paths.map {|path| File.new(path).to_reek_source }
|
12
16
|
end
|
13
17
|
|
18
|
+
private
|
19
|
+
|
14
20
|
def all_ruby_source_files(paths)
|
15
21
|
paths.map do |path|
|
16
22
|
if test 'd', path
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), 'examiner')
|
2
|
+
require File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), 'cli', 'report')
|
2
3
|
|
3
4
|
module Reek
|
4
5
|
module Spec
|
@@ -15,12 +16,8 @@ module Reek
|
|
15
16
|
"Expected #{@examiner.description} to reek, but it didn't"
|
16
17
|
end
|
17
18
|
def failure_message_for_should_not
|
18
|
-
|
19
|
-
|
20
|
-
def list_smells(examiner)
|
21
|
-
examiner.smells.map do |smell|
|
22
|
-
"#{smell.report('%c %w (%s)')}"
|
23
|
-
end.join("\n")
|
19
|
+
rpt = Cli::ReportFormatter.format_list(@examiner.smells)
|
20
|
+
"Expected no smells, but got:\n#{rpt}"
|
24
21
|
end
|
25
22
|
end
|
26
23
|
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), 'examiner')
|
2
|
+
require File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), 'cli', 'report')
|
2
3
|
|
3
4
|
module Reek
|
4
5
|
module Spec
|
@@ -13,11 +14,11 @@ module Reek
|
|
13
14
|
end
|
14
15
|
def matches_examiner?(examiner)
|
15
16
|
@examiner = examiner
|
16
|
-
@
|
17
|
-
@
|
17
|
+
@warnings = @examiner.smells
|
18
|
+
@warnings.length == 1 and @warnings[0].matches?(@klass, @patterns)
|
18
19
|
end
|
19
20
|
def failure_message_for_should
|
20
|
-
rpt =
|
21
|
+
rpt = Cli::ReportFormatter.format_list(@warnings)
|
21
22
|
"Expected #{@examiner.description} to reek only of #{@klass}, but got:\n#{rpt}"
|
22
23
|
end
|
23
24
|
def failure_message_for_should_not
|
data/reek.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{reek}
|
5
|
-
s.version = "1.2.7.
|
5
|
+
s.version = "1.2.7.3"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Kevin Rutherford"]
|
9
|
-
s.date = %q{2010-03-
|
9
|
+
s.date = %q{2010-03-29}
|
10
10
|
s.default_executable = %q{reek}
|
11
11
|
s.description = %q{Reek is a tool that examines Ruby classes, modules and methods
|
12
12
|
and reports any code smells it finds.
|
@@ -14,7 +14,7 @@ and reports any code smells it finds.
|
|
14
14
|
s.email = ["kevin@rutherford-software.com"]
|
15
15
|
s.executables = ["reek"]
|
16
16
|
s.extra_rdoc_files = ["History.txt", "License.txt"]
|
17
|
-
s.files = [".yardopts", "History.txt", "License.txt", "README.md", "Rakefile", "bin/reek", "config/defaults.reek", "features/masking_smells.feature", "features/options.feature", "features/rake_task.feature", "features/reports.feature", "features/samples.feature", "features/stdin.feature", "features/step_definitions/reek_steps.rb", "features/support/env.rb", "features/yaml.feature", "lib/reek.rb", "lib/reek/cli/application.rb", "lib/reek/cli/command_line.rb", "lib/reek/cli/help_command.rb", "lib/reek/cli/reek_command.rb", "lib/reek/cli/report.rb", "lib/reek/cli/version_command.rb", "lib/reek/cli/yaml_command.rb", "lib/reek/core/
|
17
|
+
s.files = [".yardopts", "History.txt", "License.txt", "README.md", "Rakefile", "bin/reek", "config/defaults.reek", "features/masking_smells.feature", "features/options.feature", "features/rake_task.feature", "features/reports.feature", "features/samples.feature", "features/stdin.feature", "features/step_definitions/reek_steps.rb", "features/support/env.rb", "features/yaml.feature", "lib/reek.rb", "lib/reek/cli/application.rb", "lib/reek/cli/command_line.rb", "lib/reek/cli/help_command.rb", "lib/reek/cli/reek_command.rb", "lib/reek/cli/report.rb", "lib/reek/cli/version_command.rb", "lib/reek/cli/yaml_command.rb", "lib/reek/core/code_context.rb", "lib/reek/core/code_parser.rb", "lib/reek/core/method_context.rb", "lib/reek/core/module_context.rb", "lib/reek/core/object_refs.rb", "lib/reek/core/singleton_method_context.rb", "lib/reek/core/smell_configuration.rb", "lib/reek/core/sniffer.rb", "lib/reek/core/stop_context.rb", "lib/reek/core/warning_collector.rb", "lib/reek/examiner.rb", "lib/reek/rake/task.rb", "lib/reek/smell_warning.rb", "lib/reek/smells.rb", "lib/reek/smells/attribute.rb", "lib/reek/smells/boolean_parameter.rb", "lib/reek/smells/class_variable.rb", "lib/reek/smells/control_couple.rb", "lib/reek/smells/data_clump.rb", "lib/reek/smells/duplication.rb", "lib/reek/smells/feature_envy.rb", "lib/reek/smells/irresponsible_module.rb", "lib/reek/smells/large_class.rb", "lib/reek/smells/long_method.rb", "lib/reek/smells/long_parameter_list.rb", "lib/reek/smells/long_yield_list.rb", "lib/reek/smells/nested_iterators.rb", "lib/reek/smells/simulated_polymorphism.rb", "lib/reek/smells/smell_detector.rb", "lib/reek/smells/uncommunicative_method_name.rb", "lib/reek/smells/uncommunicative_module_name.rb", "lib/reek/smells/uncommunicative_parameter_name.rb", "lib/reek/smells/uncommunicative_variable_name.rb", "lib/reek/smells/utility_function.rb", "lib/reek/source.rb", "lib/reek/source/code_comment.rb", "lib/reek/source/config_file.rb", "lib/reek/source/core_extras.rb", "lib/reek/source/reference_collector.rb", "lib/reek/source/sexp_formatter.rb", "lib/reek/source/source_code.rb", "lib/reek/source/source_file.rb", "lib/reek/source/source_locator.rb", "lib/reek/source/tree_dresser.rb", "lib/reek/spec.rb", "lib/reek/spec/should_reek.rb", "lib/reek/spec/should_reek_of.rb", "lib/reek/spec/should_reek_only_of.rb", "reek.gemspec", "spec/reek/cli/help_command_spec.rb", "spec/reek/cli/reek_command_spec.rb", "spec/reek/cli/report_spec.rb", "spec/reek/cli/version_command_spec.rb", "spec/reek/cli/yaml_command_spec.rb", "spec/reek/core/code_context_spec.rb", "spec/reek/core/code_parser_spec.rb", "spec/reek/core/config_spec.rb", "spec/reek/core/method_context_spec.rb", "spec/reek/core/module_context_spec.rb", "spec/reek/core/object_refs_spec.rb", "spec/reek/core/singleton_method_context_spec.rb", "spec/reek/core/smell_configuration_spec.rb", "spec/reek/core/stop_context_spec.rb", "spec/reek/core/warning_collector_spec.rb", "spec/reek/examiner_spec.rb", "spec/reek/smell_warning_spec.rb", "spec/reek/smells/attribute_spec.rb", "spec/reek/smells/behaves_like_variable_detector.rb", "spec/reek/smells/boolean_parameter_spec.rb", "spec/reek/smells/class_variable_spec.rb", "spec/reek/smells/control_couple_spec.rb", "spec/reek/smells/data_clump_spec.rb", "spec/reek/smells/duplication_spec.rb", "spec/reek/smells/feature_envy_spec.rb", "spec/reek/smells/irresponsible_module_spec.rb", "spec/reek/smells/large_class_spec.rb", "spec/reek/smells/long_method_spec.rb", "spec/reek/smells/long_parameter_list_spec.rb", "spec/reek/smells/long_yield_list_spec.rb", "spec/reek/smells/nested_iterators_spec.rb", "spec/reek/smells/simulated_polymorphism_spec.rb", "spec/reek/smells/smell_detector_shared.rb", "spec/reek/smells/uncommunicative_method_name_spec.rb", "spec/reek/smells/uncommunicative_module_name_spec.rb", "spec/reek/smells/uncommunicative_parameter_name_spec.rb", "spec/reek/smells/uncommunicative_variable_name_spec.rb", "spec/reek/smells/utility_function_spec.rb", "spec/reek/source/code_comment_spec.rb", "spec/reek/source/object_source_spec.rb", "spec/reek/source/reference_collector_spec.rb", "spec/reek/source/source_code_spec.rb", "spec/reek/source/tree_dresser_spec.rb", "spec/reek/spec/should_reek_of_spec.rb", "spec/reek/spec/should_reek_only_of_spec.rb", "spec/reek/spec/should_reek_spec.rb", "spec/samples/all_but_one_masked/clean_one.rb", "spec/samples/all_but_one_masked/dirty.rb", "spec/samples/all_but_one_masked/masked.reek", "spec/samples/clean_due_to_masking/clean_one.rb", "spec/samples/clean_due_to_masking/clean_three.rb", "spec/samples/clean_due_to_masking/clean_two.rb", "spec/samples/clean_due_to_masking/dirty_one.rb", "spec/samples/clean_due_to_masking/dirty_two.rb", "spec/samples/clean_due_to_masking/masked.reek", "spec/samples/corrupt_config_file/corrupt.reek", "spec/samples/corrupt_config_file/dirty.rb", "spec/samples/empty_config_file/dirty.rb", "spec/samples/empty_config_file/empty.reek", "spec/samples/exceptions.reek", "spec/samples/inline.rb", "spec/samples/masked/dirty.rb", "spec/samples/masked/masked.reek", "spec/samples/mixed_results/clean_one.rb", "spec/samples/mixed_results/clean_three.rb", "spec/samples/mixed_results/clean_two.rb", "spec/samples/mixed_results/dirty_one.rb", "spec/samples/mixed_results/dirty_two.rb", "spec/samples/not_quite_masked/dirty.rb", "spec/samples/not_quite_masked/masked.reek", "spec/samples/optparse.rb", "spec/samples/overrides/masked/dirty.rb", "spec/samples/overrides/masked/lower.reek", "spec/samples/overrides/upper.reek", "spec/samples/redcloth.rb", "spec/samples/three_clean_files/clean_one.rb", "spec/samples/three_clean_files/clean_three.rb", "spec/samples/three_clean_files/clean_two.rb", "spec/samples/two_smelly_files/dirty_one.rb", "spec/samples/two_smelly_files/dirty_two.rb", "spec/spec.opts", "spec/spec_helper.rb", "tasks/reek.rake", "tasks/test.rake"]
|
18
18
|
s.homepage = %q{http://wiki.github.com/kevinrutherford/reek}
|
19
19
|
s.post_install_message = %q{
|
20
20
|
For more information on reek, see http://wiki.github.com/kevinrutherford/reek
|
@@ -22,7 +22,7 @@ For more information on reek, see http://wiki.github.com/kevinrutherford/reek
|
|
22
22
|
s.rdoc_options = ["--main", "README.md"]
|
23
23
|
s.require_paths = ["lib"]
|
24
24
|
s.rubyforge_project = %q{reek}
|
25
|
-
s.rubygems_version = %q{1.3.
|
25
|
+
s.rubygems_version = %q{1.3.6}
|
26
26
|
s.summary = %q{Code smell detector for Ruby}
|
27
27
|
|
28
28
|
if s.respond_to? :specification_version then
|
@@ -14,11 +14,11 @@ describe ReekCommand do
|
|
14
14
|
context 'with smells' do
|
15
15
|
before :each do
|
16
16
|
examiner = Examiner.new('def x(); end')
|
17
|
-
@cmd = ReekCommand.new(
|
17
|
+
@cmd = ReekCommand.new(QuietReport, ['def x(); end'])
|
18
18
|
end
|
19
19
|
|
20
20
|
it 'displays the correct text on the view' do
|
21
|
-
@view.should_receive(:output).with(/
|
21
|
+
@view.should_receive(:output).with(/UncommunicativeName/)
|
22
22
|
@cmd.execute(@view)
|
23
23
|
end
|
24
24
|
|
@@ -30,8 +30,7 @@ describe ReekCommand do
|
|
30
30
|
|
31
31
|
context 'with no smells' do
|
32
32
|
before :each do
|
33
|
-
|
34
|
-
@cmd = ReekCommand.new([examiner], QuietReport)
|
33
|
+
@cmd = ReekCommand.new(QuietReport, ['def clean(); end'])
|
35
34
|
end
|
36
35
|
|
37
36
|
it 'displays nothing on the view' do
|
@@ -5,20 +5,24 @@ require File.join(File.dirname(File.dirname(File.dirname(File.dirname(File.expan
|
|
5
5
|
include Reek
|
6
6
|
include Reek::Cli
|
7
7
|
|
8
|
-
describe
|
8
|
+
describe QuietReport, " when empty" do
|
9
9
|
context 'empty source' do
|
10
10
|
it 'has an empty quiet_report' do
|
11
11
|
examiner = Examiner.new('')
|
12
|
-
|
12
|
+
QuietReport.new(examiner).report.should == ''
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
16
|
context 'with a couple of smells' do
|
17
|
-
|
17
|
+
before :each do
|
18
18
|
examiner = Examiner.new('def simple(a) a[3] end')
|
19
|
-
rpt =
|
20
|
-
@lines = rpt.
|
21
|
-
|
19
|
+
rpt = QuietReport.new(examiner)
|
20
|
+
@lines = rpt.report.split("\n")
|
21
|
+
end
|
22
|
+
it 'has a header and a list of smells' do
|
23
|
+
@lines.should have_at_least(3).lines
|
24
|
+
end
|
25
|
+
it 'should mention every smell name' do
|
22
26
|
@lines[0].should match('[Utility Function]')
|
23
27
|
@lines[1].should match('[Feature Envy]')
|
24
28
|
end
|
@@ -29,7 +29,7 @@ describe YamlCommand do
|
|
29
29
|
|
30
30
|
context 'with smells' do
|
31
31
|
before :each do
|
32
|
-
@smell = SmellWarning.new('UncommunicativeName', "self", 27, "self"
|
32
|
+
@smell = SmellWarning.new('UncommunicativeName', "self", 27, "self")
|
33
33
|
@examiner.should_receive(:smells).and_return([@smell])
|
34
34
|
@cmd = YamlCommand.new([@examiner])
|
35
35
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
require File.join(File.dirname(File.dirname(File.dirname(File.expand_path(__FILE__)))), 'spec_helper')
|
2
|
-
require File.join(File.dirname(File.dirname(File.dirname(File.dirname(File.expand_path(__FILE__))))), 'lib', 'reek', 'core', 'class_context')
|
3
2
|
require File.join(File.dirname(File.dirname(File.dirname(File.dirname(File.expand_path(__FILE__))))), 'lib', 'reek', 'core', 'method_context')
|
4
3
|
require File.join(File.dirname(File.dirname(File.dirname(File.dirname(File.expand_path(__FILE__))))), 'lib', 'reek', 'core', 'module_context')
|
5
4
|
require File.join(File.dirname(File.dirname(File.dirname(File.dirname(File.expand_path(__FILE__))))), 'lib', 'reek', 'core', 'stop_context')
|
@@ -56,8 +55,7 @@ describe CodeContext do
|
|
56
55
|
stop = StopContext.new
|
57
56
|
def stop.bananas(arg1, arg2) arg1 + arg2 + 43 end
|
58
57
|
element = ModuleContext.new(stop, 'mod', s(:module, :mod, nil))
|
59
|
-
|
60
|
-
element = MethodContext.new(class_element, [0, :bad])
|
58
|
+
element = MethodContext.new(element, [0, :bad])
|
61
59
|
element.bananas(17, -5).should == 55
|
62
60
|
end
|
63
61
|
end
|
@@ -6,7 +6,7 @@ include Reek::Core
|
|
6
6
|
|
7
7
|
describe ModuleContext do
|
8
8
|
it 'should report module name for smell in method' do
|
9
|
-
'module Fred; def simple(x) true; end; end'.should reek_of(:UncommunicativeParameterName, /x/, /simple
|
9
|
+
'module Fred; def simple(x) true; end; end'.should reek_of(:UncommunicativeParameterName, /x/, /simple/)
|
10
10
|
end
|
11
11
|
|
12
12
|
it 'should not report module with empty class' do
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require File.join(File.dirname(File.dirname(File.dirname(File.expand_path(__FILE__)))), 'spec_helper')
|
2
|
+
require File.join(File.dirname(File.dirname(File.dirname(File.dirname(File.expand_path(__FILE__))))), 'lib', 'reek', 'core', 'warning_collector')
|
3
|
+
require File.join(File.dirname(File.dirname(File.dirname(File.dirname(File.expand_path(__FILE__))))), 'lib', 'reek', 'smell_warning')
|
4
|
+
|
5
|
+
include Reek::Core
|
6
|
+
|
7
|
+
describe WarningCollector do
|
8
|
+
before(:each) do
|
9
|
+
@collector = WarningCollector.new
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'when empty' do
|
13
|
+
it 'reports no warnings' do
|
14
|
+
@collector.warnings.should == []
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'with one warning' do
|
19
|
+
before :each do
|
20
|
+
@warning = Reek::SmellWarning.new('ControlCouple', 'fred', [1,2,3], 'hello')
|
21
|
+
@collector.found_smell(@warning)
|
22
|
+
end
|
23
|
+
it 'reports that warning' do
|
24
|
+
@collector.warnings.should == [@warning]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/spec/reek/examiner_spec.rb
CHANGED
@@ -3,40 +3,101 @@ require File.join(File.dirname(File.dirname(File.dirname(File.expand_path(__FILE
|
|
3
3
|
|
4
4
|
include Reek
|
5
5
|
|
6
|
+
shared_examples_for 'supports the deprecated api' do
|
7
|
+
it 'returns all smells as active' do
|
8
|
+
@examiner.all_active_smells.should == @examiner.smells
|
9
|
+
end
|
10
|
+
it 'returns all smells as active' do
|
11
|
+
@examiner.all_smells.should == @examiner.smells
|
12
|
+
end
|
13
|
+
it 'counts all smells as active smells' do
|
14
|
+
@examiner.num_active_smells.should == @examiner.smells.length
|
15
|
+
end
|
16
|
+
it 'never reports masked smells' do
|
17
|
+
@examiner.num_masked_smells.should == 0
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
shared_examples_for 'no smells found' do
|
22
|
+
it 'is not smelly' do
|
23
|
+
@examiner.should_not be_smelly
|
24
|
+
end
|
25
|
+
it 'finds no smells' do
|
26
|
+
@examiner.smells.length.should == 0
|
27
|
+
end
|
28
|
+
|
29
|
+
it_should_behave_like 'supports the deprecated api'
|
30
|
+
end
|
31
|
+
|
32
|
+
shared_examples_for 'one smell found' do
|
33
|
+
it 'is smelly' do
|
34
|
+
@examiner.should be_smelly
|
35
|
+
end
|
36
|
+
it 'reports the smell' do
|
37
|
+
@examiner.smells.length.should == 1
|
38
|
+
end
|
39
|
+
it 'reports the correct smell' do
|
40
|
+
@examiner.smells[0].smell_class.should == @expected_first_smell
|
41
|
+
end
|
42
|
+
|
43
|
+
it_should_behave_like 'supports the deprecated api'
|
44
|
+
end
|
45
|
+
|
6
46
|
describe Examiner do
|
7
|
-
|
8
|
-
|
9
|
-
Examiner.new(File.new(dirty_file)).should be_smelly
|
47
|
+
before :each do
|
48
|
+
@expected_first_smell = 'NestedIterators'
|
10
49
|
end
|
11
|
-
|
12
|
-
|
13
|
-
|
50
|
+
|
51
|
+
context 'with a fragrant String' do
|
52
|
+
before :each do
|
53
|
+
@examiner = Examiner.new('def good() true; end')
|
54
|
+
end
|
55
|
+
|
56
|
+
it_should_behave_like 'no smells found'
|
14
57
|
end
|
15
|
-
|
16
|
-
|
58
|
+
|
59
|
+
context 'with a smelly String' do
|
60
|
+
before :each do
|
61
|
+
@examiner = Examiner.new('def fine() y = 4; end')
|
62
|
+
@expected_first_smell = 'UncommunicativeName'
|
63
|
+
end
|
64
|
+
|
65
|
+
it_should_behave_like 'one smell found'
|
17
66
|
end
|
18
67
|
|
19
|
-
context '
|
20
|
-
|
68
|
+
context 'with a smelly Dir' do
|
69
|
+
before :each do
|
21
70
|
smelly_dir = Dir['spec/samples/all_but_one_masked/*.rb']
|
22
|
-
Examiner.new(smelly_dir)
|
71
|
+
@examiner = Examiner.new(smelly_dir)
|
23
72
|
end
|
24
|
-
|
73
|
+
|
74
|
+
it_should_behave_like 'one smell found'
|
75
|
+
end
|
76
|
+
|
77
|
+
context 'with a fragrant Dir' do
|
78
|
+
before :each do
|
25
79
|
clean_dir = Dir['spec/samples/three_clean_files/*.rb']
|
26
|
-
Examiner.new(clean_dir)
|
80
|
+
@examiner = Examiner.new(clean_dir)
|
27
81
|
end
|
82
|
+
|
83
|
+
it_should_behave_like 'no smells found'
|
28
84
|
end
|
29
85
|
|
30
|
-
context '
|
31
|
-
|
86
|
+
context 'with a smelly File' do
|
87
|
+
before :each do
|
32
88
|
smelly_file = File.new(Dir['spec/samples/all_but_one_masked/d*.rb'][0])
|
33
|
-
Examiner.new(smelly_file)
|
89
|
+
@examiner = Examiner.new(smelly_file)
|
34
90
|
end
|
35
91
|
|
36
|
-
|
92
|
+
it_should_behave_like 'one smell found'
|
93
|
+
end
|
94
|
+
|
95
|
+
context 'with a fragrant File' do
|
96
|
+
before :each do
|
37
97
|
clean_file = File.new(Dir['spec/samples/three_clean_files/*.rb'][0])
|
38
|
-
Examiner.new(clean_file)
|
98
|
+
@examiner = Examiner.new(clean_file)
|
39
99
|
end
|
40
|
-
end
|
41
100
|
|
101
|
+
it_should_behave_like 'no smells found'
|
102
|
+
end
|
42
103
|
end
|
@@ -5,27 +5,6 @@ include Reek
|
|
5
5
|
|
6
6
|
describe SmellWarning do
|
7
7
|
context 'sort order' do
|
8
|
-
context 'smells differing only by masking' do
|
9
|
-
before :each do
|
10
|
-
@first = SmellWarning.new('FeatureEnvy', "self", 27, "self", true)
|
11
|
-
@second = SmellWarning.new('FeatureEnvy', "self", 27, "self", false)
|
12
|
-
end
|
13
|
-
|
14
|
-
it 'should hash equal when the smell is the same' do
|
15
|
-
@first.hash.should == @second.hash
|
16
|
-
end
|
17
|
-
it 'should compare equal when the smell is the same' do
|
18
|
-
@first.should == @second
|
19
|
-
end
|
20
|
-
it 'should compare equal when using <=>' do
|
21
|
-
(@first <=> @second).should == 0
|
22
|
-
end
|
23
|
-
it 'matches using eql?' do
|
24
|
-
@first.should eql(@second)
|
25
|
-
@second.should eql(@first)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
8
|
shared_examples_for 'first sorts ahead of second' do
|
30
9
|
it 'hash differently' do
|
31
10
|
@first.hash.should_not == @second.hash
|
@@ -88,48 +67,12 @@ describe SmellWarning do
|
|
88
67
|
end
|
89
68
|
end
|
90
69
|
|
91
|
-
context 'masked reporting' do
|
92
|
-
class CountingReport
|
93
|
-
attr_reader :masked, :non_masked
|
94
|
-
def initialize
|
95
|
-
@masked = @non_masked = 0
|
96
|
-
end
|
97
|
-
def found_smell(sw)
|
98
|
-
@non_masked += 1
|
99
|
-
end
|
100
|
-
|
101
|
-
def found_masked_smell(sw)
|
102
|
-
@masked += 1
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
before :each do
|
107
|
-
@masked = SmellWarning.new('FeatureEnvy', 'Fred', 27, "self", true)
|
108
|
-
@visible = SmellWarning.new('FeatureEnvy', 'Fred', 27, "self", false)
|
109
|
-
end
|
110
|
-
|
111
|
-
it 'reports as masked when masked' do
|
112
|
-
rpt = CountingReport.new
|
113
|
-
@masked.report_on(rpt)
|
114
|
-
rpt.masked.should == 1
|
115
|
-
rpt.non_masked.should == 0
|
116
|
-
end
|
117
|
-
|
118
|
-
it 'reports as non-masked when non-masked' do
|
119
|
-
rpt = CountingReport.new
|
120
|
-
@visible.report_on(rpt)
|
121
|
-
rpt.masked.should == 0
|
122
|
-
rpt.non_masked.should == 1
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
70
|
context 'YAML representation' do
|
127
71
|
before :each do
|
128
72
|
@message = 'test message'
|
129
73
|
@lines = [24, 513]
|
130
74
|
@class = 'FeatureEnvy'
|
131
75
|
@context_name = 'Module::Class#method/block'
|
132
|
-
@is_active = true
|
133
76
|
# Use a random string and a random bool
|
134
77
|
end
|
135
78
|
|
@@ -144,7 +87,7 @@ describe SmellWarning do
|
|
144
87
|
@yaml.should match(/message:\s*#{@message}/)
|
145
88
|
end
|
146
89
|
it 'indicates the masking' do
|
147
|
-
@yaml.should match(/is_active:\s
|
90
|
+
@yaml.should match(/is_active:\s*true/)
|
148
91
|
end
|
149
92
|
it 'includes the line numbers' do
|
150
93
|
@lines.each do |line|
|
@@ -158,9 +101,9 @@ describe SmellWarning do
|
|
158
101
|
@source = 'a/ruby/source/file.rb'
|
159
102
|
@subclass = 'TooManyParties'
|
160
103
|
@parameters = {'one' => 34, 'two' => 'second'}
|
161
|
-
warning = SmellWarning.new(@class, @context_name, @lines, @message,
|
104
|
+
@warning = SmellWarning.new(@class, @context_name, @lines, @message,
|
162
105
|
@source, @subclass, @parameters)
|
163
|
-
@yaml = warning.to_yaml
|
106
|
+
@yaml = @warning.to_yaml
|
164
107
|
end
|
165
108
|
|
166
109
|
it_should_behave_like 'common fields'
|
@@ -180,7 +123,7 @@ describe SmellWarning do
|
|
180
123
|
|
181
124
|
context 'with all defaults used' do
|
182
125
|
before :each do
|
183
|
-
warning = SmellWarning.new(@class, @context_name, @lines, @message
|
126
|
+
warning = SmellWarning.new(@class, @context_name, @lines, @message)
|
184
127
|
@yaml = warning.to_yaml
|
185
128
|
end
|
186
129
|
|