reek 1.2.6 → 1.2.7
Sign up to get free protection for your applications and to get access to all the features.
- data/.yardopts +10 -0
- data/History.txt +20 -0
- data/README.md +90 -0
- data/bin/reek +2 -2
- data/config/defaults.reek +34 -4
- data/features/masking_smells.feature +35 -15
- data/features/options.feature +2 -0
- data/features/rake_task.feature +11 -18
- data/features/reports.feature +13 -15
- data/features/samples.feature +90 -105
- data/features/stdin.feature +3 -6
- data/features/step_definitions/reek_steps.rb +8 -4
- data/features/support/env.rb +2 -3
- data/features/yaml.feature +124 -0
- data/lib/reek.rb +8 -4
- data/lib/reek/cli/application.rb +46 -0
- data/lib/reek/cli/command_line.rb +106 -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 +91 -0
- data/lib/reek/cli/version_command.rb +19 -0
- data/lib/reek/cli/yaml_command.rb +32 -0
- data/lib/reek/core/block_context.rb +18 -0
- data/lib/reek/core/class_context.rb +23 -0
- data/lib/reek/core/code_context.rb +72 -0
- data/lib/reek/core/code_parser.rb +192 -0
- data/lib/reek/core/detector_stack.rb +29 -0
- data/lib/reek/core/masking_collection.rb +46 -0
- data/lib/reek/core/method_context.rb +132 -0
- data/lib/reek/core/module_context.rb +64 -0
- data/lib/reek/{object_refs.rb → core/object_refs.rb} +8 -6
- data/lib/reek/{singleton_method_context.rb → core/singleton_method_context.rb} +10 -5
- data/lib/reek/core/smell_configuration.rb +66 -0
- data/lib/reek/core/sniffer.rb +110 -0
- data/lib/reek/core/stop_context.rb +26 -0
- data/lib/reek/examiner.rb +88 -0
- data/lib/reek/rake/task.rb +124 -0
- data/lib/reek/smell_warning.rb +69 -13
- data/lib/reek/smells.rb +29 -0
- data/lib/reek/smells/attribute.rb +13 -14
- data/lib/reek/smells/boolean_parameter.rb +33 -0
- data/lib/reek/smells/class_variable.rb +8 -6
- data/lib/reek/smells/control_couple.rb +33 -17
- data/lib/reek/smells/data_clump.rb +10 -6
- data/lib/reek/smells/duplication.rb +24 -14
- data/lib/reek/smells/feature_envy.rb +11 -6
- data/lib/reek/smells/irresponsible_module.rb +28 -0
- data/lib/reek/smells/large_class.rb +9 -7
- data/lib/reek/smells/long_method.rb +6 -5
- data/lib/reek/smells/long_parameter_list.rb +11 -9
- data/lib/reek/smells/long_yield_list.rb +37 -7
- data/lib/reek/smells/nested_iterators.rb +34 -9
- data/lib/reek/smells/simulated_polymorphism.rb +15 -11
- data/lib/reek/smells/smell_detector.rb +24 -12
- data/lib/reek/smells/uncommunicative_method_name.rb +76 -0
- data/lib/reek/smells/uncommunicative_module_name.rb +76 -0
- data/lib/reek/smells/{uncommunicative_name.rb → uncommunicative_parameter_name.rb} +14 -26
- data/lib/reek/smells/uncommunicative_variable_name.rb +90 -0
- data/lib/reek/smells/utility_function.rb +33 -9
- data/lib/reek/source.rb +18 -0
- data/lib/reek/source/code_comment.rb +19 -0
- data/lib/reek/source/config_file.rb +72 -0
- data/lib/reek/source/core_extras.rb +46 -0
- data/lib/reek/source/sexp_formatter.rb +16 -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 +36 -0
- data/lib/reek/source/tree_dresser.rb +128 -0
- data/lib/reek/spec.rb +51 -0
- data/lib/reek/spec/should_reek.rb +34 -0
- data/lib/reek/spec/should_reek_of.rb +37 -0
- data/lib/reek/spec/should_reek_only_of.rb +36 -0
- data/reek.gemspec +5 -5
- data/spec/reek/{help_command_spec.rb → cli/help_command_spec.rb} +3 -4
- data/spec/reek/{reek_command_spec.rb → cli/reek_command_spec.rb} +8 -7
- data/spec/reek/cli/report_spec.rb +26 -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/block_context_spec.rb +26 -0
- data/spec/reek/core/class_context_spec.rb +53 -0
- data/spec/reek/{code_context_spec.rb → core/code_context_spec.rb} +15 -37
- data/spec/reek/{code_parser_spec.rb → core/code_parser_spec.rb} +5 -5
- data/spec/reek/{config_spec.rb → core/config_spec.rb} +2 -6
- data/spec/reek/{masking_collection_spec.rb → core/masking_collection_spec.rb} +3 -4
- data/spec/reek/{method_context_spec.rb → core/method_context_spec.rb} +6 -7
- data/spec/reek/core/module_context_spec.rb +42 -0
- data/spec/reek/{object_refs_spec.rb → core/object_refs_spec.rb} +5 -6
- data/spec/reek/core/singleton_method_context_spec.rb +15 -0
- data/spec/reek/core/smell_configuration_spec.rb +11 -0
- data/spec/reek/core/stop_context_spec.rb +17 -0
- data/spec/reek/examiner_spec.rb +42 -0
- data/spec/reek/smell_warning_spec.rb +82 -33
- data/spec/reek/smells/attribute_spec.rb +33 -7
- data/spec/reek/smells/boolean_parameter_spec.rb +76 -0
- data/spec/reek/smells/class_variable_spec.rb +15 -6
- data/spec/reek/smells/control_couple_spec.rb +40 -29
- data/spec/reek/smells/data_clump_spec.rb +28 -7
- data/spec/reek/smells/duplication_spec.rb +47 -41
- data/spec/reek/smells/feature_envy_spec.rb +76 -18
- data/spec/reek/smells/irresponsible_module_spec.rb +37 -0
- data/spec/reek/smells/large_class_spec.rb +91 -56
- data/spec/reek/smells/long_method_spec.rb +32 -7
- data/spec/reek/smells/long_parameter_list_spec.rb +42 -13
- data/spec/reek/smells/long_yield_list_spec.rb +65 -0
- data/spec/reek/smells/nested_iterators_spec.rb +94 -3
- data/spec/reek/smells/simulated_polymorphism_spec.rb +48 -20
- data/spec/reek/smells/smell_detector_shared.rb +28 -0
- data/spec/reek/smells/uncommunicative_method_name_spec.rb +57 -0
- data/spec/reek/smells/uncommunicative_module_name_spec.rb +67 -0
- data/spec/reek/smells/uncommunicative_parameter_name_spec.rb +61 -0
- data/spec/reek/smells/uncommunicative_variable_name_spec.rb +124 -0
- data/spec/reek/smells/utility_function_spec.rb +45 -3
- data/spec/reek/source/code_comment_spec.rb +24 -0
- data/spec/reek/source/object_source_spec.rb +20 -0
- data/spec/reek/{adapters/source_spec.rb → source/source_code_spec.rb} +7 -8
- data/spec/reek/source/tree_dresser_spec.rb +165 -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/corrupt_config_file/dirty.rb +1 -1
- data/spec/samples/empty_config_file/dirty.rb +2 -1
- data/spec/samples/exceptions.reek +1 -1
- 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 +1 -2
- data/tasks/reek.rake +2 -2
- data/tasks/test.rake +12 -3
- metadata +81 -62
- data/README.rdoc +0 -84
- 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/reek_command.rb +0 -28
- data/lib/reek/sexp_formatter.rb +0 -10
- 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/configuration_spec.rb +0 -12
- data/spec/reek/if_context_spec.rb +0 -17
- 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/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
@@ -1,31 +0,0 @@
|
|
1
|
-
require 'yaml'
|
2
|
-
|
3
|
-
module Reek
|
4
|
-
class ConfigFile
|
5
|
-
|
6
|
-
def initialize(file_path)
|
7
|
-
@file_path = file_path
|
8
|
-
@hash = YAML.load_file(@file_path) || {}
|
9
|
-
problem('not a Hash') unless Hash === @hash
|
10
|
-
end
|
11
|
-
|
12
|
-
#
|
13
|
-
# Configure the given sniffer using the contents of the config file.
|
14
|
-
#
|
15
|
-
def configure(sniffer)
|
16
|
-
@hash.each { |klass_name, config|
|
17
|
-
sniffer.configure(find_class(klass_name), config)
|
18
|
-
}
|
19
|
-
end
|
20
|
-
|
21
|
-
def find_class(name)
|
22
|
-
klass = Reek::Smells.const_get(name)
|
23
|
-
problem("#{name} is not a code smell") unless klass
|
24
|
-
klass
|
25
|
-
end
|
26
|
-
|
27
|
-
def problem(reason)
|
28
|
-
raise "Invalid configuration file \"#{File.basename(@file_path)}\" -- #{reason}"
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,64 +0,0 @@
|
|
1
|
-
require 'reek/adapters/source'
|
2
|
-
require 'reek/sniffer'
|
3
|
-
|
4
|
-
class Object
|
5
|
-
#
|
6
|
-
# Creates a new +Sniffer+ that assumes this object contains Ruby source
|
7
|
-
# code and examines that code for smells. Calls +to_reek_source+ on self
|
8
|
-
# to obtain the +Source+ object wrapper.
|
9
|
-
#
|
10
|
-
def sniff
|
11
|
-
Reek::Sniffer.new(self.to_reek_source)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
class File
|
16
|
-
#
|
17
|
-
# Creates a new +Source+ that assumes this File contains Ruby source
|
18
|
-
# code and prepares it to be examined for code smells.
|
19
|
-
#
|
20
|
-
def to_reek_source
|
21
|
-
Reek::SourceFile.new(self)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
class IO
|
26
|
-
#
|
27
|
-
# Creates a new +Source+ that assumes this IO stream contains Ruby source
|
28
|
-
# code and prepares it to be examined for code smells.
|
29
|
-
#
|
30
|
-
def to_reek_source(description = 'io')
|
31
|
-
Reek::Source.new(self.readlines.join, description)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
class String
|
36
|
-
#
|
37
|
-
# Creates a new +Source+ that assumes this string contains Ruby source
|
38
|
-
# code and prepares it to be examined for code smells.
|
39
|
-
#
|
40
|
-
def to_reek_source
|
41
|
-
Reek::Source.new(self, 'string')
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
class Array
|
46
|
-
def paths
|
47
|
-
self.map do |path|
|
48
|
-
if test 'd', path
|
49
|
-
Dir["#{path}/**/*.rb"].paths
|
50
|
-
else
|
51
|
-
path
|
52
|
-
end
|
53
|
-
end.flatten.sort
|
54
|
-
end
|
55
|
-
|
56
|
-
#
|
57
|
-
# Creates a new +Sniffer+ that assumes this Array contains the names
|
58
|
-
# of Ruby source files and examines those files for smells.
|
59
|
-
#
|
60
|
-
def sniff
|
61
|
-
sniffers = paths.map {|path| File.new(path).sniff}
|
62
|
-
Reek::SnifferSet.new(sniffers, 'dir')
|
63
|
-
end
|
64
|
-
end
|
@@ -1,121 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
# Define a task library for running reek.
|
4
|
-
|
5
|
-
require 'rake'
|
6
|
-
require 'rake/tasklib'
|
7
|
-
|
8
|
-
module Reek
|
9
|
-
|
10
|
-
# A Rake task that runs reek on a set of source files.
|
11
|
-
#
|
12
|
-
# Example:
|
13
|
-
#
|
14
|
-
# Reek::RakeTask.new do |t|
|
15
|
-
# t.fail_on_error = false
|
16
|
-
# end
|
17
|
-
#
|
18
|
-
# This will create a task that can be run with:
|
19
|
-
#
|
20
|
-
# rake reek
|
21
|
-
#
|
22
|
-
# Examples:
|
23
|
-
#
|
24
|
-
# rake reek # checks lib/**/*.rb
|
25
|
-
# rake reek REEK_SRC=just_one_file.rb # checks a single source file
|
26
|
-
# rake reek REEK_OPTS=-s # sorts the report by smell
|
27
|
-
#
|
28
|
-
class RakeTask < ::Rake::TaskLib
|
29
|
-
|
30
|
-
# Name of reek task.
|
31
|
-
# Defaults to :reek.
|
32
|
-
attr_accessor :name
|
33
|
-
|
34
|
-
# Array of directories to be added to $LOAD_PATH before running reek.
|
35
|
-
# Defaults to ['<the absolute path to reek's lib directory>']
|
36
|
-
attr_accessor :libs
|
37
|
-
|
38
|
-
# Glob pattern to match source files.
|
39
|
-
# Setting the REEK_SRC environment variable overrides this.
|
40
|
-
# Defaults to 'lib/**/*.rb'.
|
41
|
-
attr_accessor :source_files
|
42
|
-
|
43
|
-
# String containing commandline options to be passed to Reek.
|
44
|
-
# Setting the REEK_OPTS environment variable overrides this value.
|
45
|
-
# Defaults to ''.
|
46
|
-
attr_accessor :reek_opts
|
47
|
-
|
48
|
-
# Array of commandline options to pass to ruby. Defaults to [].
|
49
|
-
attr_accessor :ruby_opts
|
50
|
-
|
51
|
-
# Whether or not to fail Rake when an error occurs (typically when smells are found).
|
52
|
-
# Defaults to true.
|
53
|
-
attr_accessor :fail_on_error
|
54
|
-
|
55
|
-
# Use verbose output. If this is set to true, the task will print
|
56
|
-
# the reek command to stdout. Defaults to false.
|
57
|
-
attr_accessor :verbose
|
58
|
-
|
59
|
-
# Defines a new task, using the name +name+.
|
60
|
-
def initialize(name = :reek)
|
61
|
-
@name = name
|
62
|
-
@libs = [File.expand_path(File.dirname(__FILE__) + '/../../../lib')]
|
63
|
-
@source_files = nil
|
64
|
-
@ruby_opts = []
|
65
|
-
@reek_opts = ''
|
66
|
-
@fail_on_error = true
|
67
|
-
@sort = nil
|
68
|
-
|
69
|
-
yield self if block_given?
|
70
|
-
@source_files ||= 'lib/**/*.rb'
|
71
|
-
define
|
72
|
-
end
|
73
|
-
|
74
|
-
private
|
75
|
-
|
76
|
-
def define # :nodoc:
|
77
|
-
desc 'Check for code smells' unless ::Rake.application.last_comment
|
78
|
-
task(name) { run_task }
|
79
|
-
self
|
80
|
-
end
|
81
|
-
|
82
|
-
def run_task
|
83
|
-
return if source_file_list.empty?
|
84
|
-
cmd = cmd_words.join(' ')
|
85
|
-
puts cmd if @verbose
|
86
|
-
raise('Smells found!') if !system(cmd) and fail_on_error
|
87
|
-
end
|
88
|
-
|
89
|
-
def self.reek_script
|
90
|
-
File.expand_path(File.dirname(__FILE__) + '/../../../bin/reek')
|
91
|
-
end
|
92
|
-
|
93
|
-
def self.ruby_exe
|
94
|
-
File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
|
95
|
-
end
|
96
|
-
|
97
|
-
def cmd_words
|
98
|
-
[RakeTask.ruby_exe] +
|
99
|
-
ruby_options +
|
100
|
-
[ %Q|"#{RakeTask.reek_script}"| ] +
|
101
|
-
[sort_option] +
|
102
|
-
source_file_list.collect { |fn| %["#{fn}"] }
|
103
|
-
end
|
104
|
-
|
105
|
-
def ruby_options
|
106
|
-
lib_path = @libs.join(File::PATH_SEPARATOR)
|
107
|
-
@ruby_opts.clone << "-I\"#{lib_path}\""
|
108
|
-
end
|
109
|
-
|
110
|
-
def sort_option
|
111
|
-
ENV['REEK_OPTS'] || @reek_opts
|
112
|
-
end
|
113
|
-
|
114
|
-
def source_file_list # :nodoc:
|
115
|
-
files = ENV['REEK_SRC'] || @source_files
|
116
|
-
return [] unless files
|
117
|
-
return FileList[files]
|
118
|
-
end
|
119
|
-
|
120
|
-
end
|
121
|
-
end
|
data/lib/reek/adapters/report.rb
DELETED
@@ -1,86 +0,0 @@
|
|
1
|
-
require 'set'
|
2
|
-
require 'reek/adapters/command_line' # SMELL: Global Variable
|
3
|
-
require 'reek/masking_collection'
|
4
|
-
|
5
|
-
module Reek
|
6
|
-
class ReportSection
|
7
|
-
|
8
|
-
SMELL_FORMAT = '%m%c %w (%s)'
|
9
|
-
|
10
|
-
def initialize(sniffer, display_masked_warnings)
|
11
|
-
@cwarnings = MaskingCollection.new
|
12
|
-
@desc = sniffer.desc
|
13
|
-
@display_masked_warnings = display_masked_warnings # SMELL: Control Couple
|
14
|
-
sniffer.report_on(@cwarnings)
|
15
|
-
end
|
16
|
-
|
17
|
-
# Creates a formatted report of all the +Smells::SmellWarning+ objects recorded in
|
18
|
-
# this report, with a heading.
|
19
|
-
def verbose_report
|
20
|
-
result = header
|
21
|
-
result += ":\n#{smell_list}" if should_report
|
22
|
-
result += "\n"
|
23
|
-
result
|
24
|
-
end
|
25
|
-
|
26
|
-
def quiet_report
|
27
|
-
return '' unless should_report
|
28
|
-
# SMELL: duplicate knowledge of the header layout
|
29
|
-
"#{header}:\n#{smell_list}\n"
|
30
|
-
end
|
31
|
-
|
32
|
-
def header
|
33
|
-
"#{@desc} -- #{visible_header}#{masked_header}"
|
34
|
-
end
|
35
|
-
|
36
|
-
# Creates a formatted report of all the +Smells::SmellWarning+ objects recorded in
|
37
|
-
# this report.
|
38
|
-
def smell_list
|
39
|
-
result = []
|
40
|
-
if @display_masked_warnings
|
41
|
-
@cwarnings.each_item {|smell| result << " #{smell.report(SMELL_FORMAT)}"}
|
42
|
-
else
|
43
|
-
@cwarnings.each_visible_item {|smell| result << " #{smell.report(SMELL_FORMAT)}"}
|
44
|
-
end
|
45
|
-
result.join("\n")
|
46
|
-
end
|
47
|
-
|
48
|
-
private
|
49
|
-
|
50
|
-
def should_report
|
51
|
-
@cwarnings.num_visible_items > 0 or (@display_masked_warnings and @cwarnings.num_masked_items > 0)
|
52
|
-
end
|
53
|
-
|
54
|
-
def visible_header
|
55
|
-
num_smells = @cwarnings.num_visible_items
|
56
|
-
result = "#{num_smells} warning"
|
57
|
-
result += 's' unless num_smells == 1
|
58
|
-
result
|
59
|
-
end
|
60
|
-
|
61
|
-
def masked_header
|
62
|
-
num_masked_warnings = @cwarnings.num_masked_items
|
63
|
-
num_masked_warnings == 0 ? '' : " (+#{num_masked_warnings} masked)"
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
class Report
|
68
|
-
def initialize(sniffers, display_masked_warnings = false)
|
69
|
-
@partials = Array(sniffers).map {|sn| ReportSection.new(sn, display_masked_warnings)}
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
class VerboseReport < Report
|
74
|
-
# SMELL: Implementation Inheritance
|
75
|
-
def report
|
76
|
-
@partials.map { |section| section.verbose_report }.join
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
class QuietReport < Report
|
81
|
-
# SMELL: Implementation Inheritance
|
82
|
-
def report
|
83
|
-
@partials.map { |section| section.quiet_report }.join
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
data/lib/reek/adapters/source.rb
DELETED
@@ -1,72 +0,0 @@
|
|
1
|
-
require 'ruby_parser'
|
2
|
-
require 'reek/adapters/config_file'
|
3
|
-
require 'reek/tree_dresser'
|
4
|
-
|
5
|
-
module Reek
|
6
|
-
|
7
|
-
#
|
8
|
-
# A +Source+ object represents a chunk of Ruby source code.
|
9
|
-
#
|
10
|
-
class Source
|
11
|
-
|
12
|
-
@@err_io = $stderr
|
13
|
-
|
14
|
-
class << self
|
15
|
-
def err_io=(io)
|
16
|
-
original = @@err_io
|
17
|
-
@@err_io = io
|
18
|
-
original
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
attr_reader :desc
|
23
|
-
|
24
|
-
def initialize(code, desc, parser = RubyParser.new)
|
25
|
-
@source = code
|
26
|
-
@desc = desc
|
27
|
-
@parser = parser
|
28
|
-
end
|
29
|
-
|
30
|
-
def configure(sniffer) end
|
31
|
-
|
32
|
-
def syntax_tree
|
33
|
-
begin
|
34
|
-
ast = @parser.parse(@source, @desc)
|
35
|
-
rescue Exception => error
|
36
|
-
@@err_io.puts "#{desc}: #{error.class.name}: #{error}"
|
37
|
-
end
|
38
|
-
ast ||= s()
|
39
|
-
TreeDresser.new.dress(ast)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
#
|
44
|
-
# Represents a file of Ruby source, whose contents will be examined
|
45
|
-
# for code smells.
|
46
|
-
#
|
47
|
-
class SourceFile < Source
|
48
|
-
|
49
|
-
def self.lines(file)
|
50
|
-
IO.readlines(file.path)
|
51
|
-
end
|
52
|
-
|
53
|
-
def initialize(file)
|
54
|
-
@file = file
|
55
|
-
super(SourceFile.lines(@file).join, @file.path)
|
56
|
-
end
|
57
|
-
|
58
|
-
def configure(sniffer)
|
59
|
-
path = File.expand_path(File.dirname(@file.path))
|
60
|
-
all_config_files(path).each { |cf| ConfigFile.new(cf).configure(sniffer) }
|
61
|
-
end
|
62
|
-
|
63
|
-
private
|
64
|
-
|
65
|
-
def all_config_files(path)
|
66
|
-
return [] unless File.exist?(path)
|
67
|
-
parent = File.dirname(path)
|
68
|
-
return [] if path == parent
|
69
|
-
all_config_files(parent) + Dir["#{path}/*.reek"]
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
data/lib/reek/adapters/spec.rb
DELETED
@@ -1,133 +0,0 @@
|
|
1
|
-
require 'reek/sniffer'
|
2
|
-
require 'reek/adapters/core_extras'
|
3
|
-
require 'reek/adapters/report'
|
4
|
-
|
5
|
-
module Reek
|
6
|
-
|
7
|
-
#
|
8
|
-
# Provides matchers for Rspec, making it easy to check code quality.
|
9
|
-
#
|
10
|
-
# If you require this module somewhere within your spec (or in your spec_helper),
|
11
|
-
# Reek will arrange to update Spec::Runner's config so that it knows about the
|
12
|
-
# matchers defined here.
|
13
|
-
#
|
14
|
-
# === Examples
|
15
|
-
#
|
16
|
-
# Here's a spec that ensures there are no smell warnings in the current project:
|
17
|
-
#
|
18
|
-
# describe 'source code quality' do
|
19
|
-
# Dir['lib/**/*.rb'].each do |path|
|
20
|
-
# it "reports no smells in #{path}" do
|
21
|
-
# File.new(path).should_not reek
|
22
|
-
# end
|
23
|
-
# end
|
24
|
-
# end
|
25
|
-
#
|
26
|
-
# And here's an even simpler way to do the same:
|
27
|
-
#
|
28
|
-
# it 'has no code smells' do
|
29
|
-
# Dir['lib/**/*.rb'].should_not reek
|
30
|
-
# end
|
31
|
-
#
|
32
|
-
# Here's a simple check of a code fragment:
|
33
|
-
#
|
34
|
-
# 'def equals(other) other.thing == self.thing end'.should_not reek
|
35
|
-
#
|
36
|
-
# And a more complex example, making use of one of the factory methods for
|
37
|
-
# +Source+ so that the code is parsed and analysed only once:
|
38
|
-
#
|
39
|
-
# ruby = 'def double_thing() @other.thing.foo + @other.thing.foo end'.sniff
|
40
|
-
# ruby.should reek_of(:Duplication, /@other.thing[^\.]/)
|
41
|
-
# ruby.should reek_of(:Duplication, /@other.thing.foo/)
|
42
|
-
# ruby.should_not reek_of(:FeatureEnvy)
|
43
|
-
#
|
44
|
-
module Spec
|
45
|
-
module ReekMatcher
|
46
|
-
def create_reporter(sniffers)
|
47
|
-
QuietReport.new(sniffers, false)
|
48
|
-
end
|
49
|
-
def report
|
50
|
-
create_reporter(@sniffer.sniffers).report
|
51
|
-
end
|
52
|
-
|
53
|
-
module_function :create_reporter
|
54
|
-
end
|
55
|
-
|
56
|
-
class ShouldReek # :nodoc:
|
57
|
-
include ReekMatcher
|
58
|
-
|
59
|
-
def matches?(actual)
|
60
|
-
@sniffer = actual.sniff
|
61
|
-
@sniffer.smelly?
|
62
|
-
end
|
63
|
-
def failure_message_for_should
|
64
|
-
"Expected #{@sniffer.desc} to reek, but it didn't"
|
65
|
-
end
|
66
|
-
def failure_message_for_should_not
|
67
|
-
"Expected no smells, but got:\n#{report}"
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
class ShouldReekOf # :nodoc:
|
72
|
-
include ReekMatcher
|
73
|
-
|
74
|
-
def initialize(klass, patterns)
|
75
|
-
@klass = klass
|
76
|
-
@patterns = patterns
|
77
|
-
end
|
78
|
-
def matches?(actual)
|
79
|
-
@sniffer = actual.sniff
|
80
|
-
@sniffer.has_smell?(@klass, @patterns)
|
81
|
-
end
|
82
|
-
def failure_message_for_should
|
83
|
-
"Expected #{@sniffer.desc} to reek of #{@klass}, but it didn't"
|
84
|
-
end
|
85
|
-
def failure_message_for_should_not
|
86
|
-
"Expected #{@sniffer.desc} not to reek of #{@klass}, but got:\n#{report}"
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
class ShouldReekOnlyOf < ShouldReekOf # :nodoc:
|
91
|
-
def matches?(actual)
|
92
|
-
@sniffer = actual.sniff
|
93
|
-
@sniffer.num_smells == 1 and @sniffer.has_smell?(@klass, @patterns)
|
94
|
-
end
|
95
|
-
def failure_message_for_should
|
96
|
-
"Expected #{@sniffer.desc} to reek only of #{@klass}, but got:\n#{report}"
|
97
|
-
end
|
98
|
-
def failure_message_for_should_not
|
99
|
-
"Expected #{@sniffer.desc} not to reek only of #{@klass}, but it did"
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
#
|
104
|
-
# Returns +true+ if and only if the target source code contains smells.
|
105
|
-
#
|
106
|
-
def reek
|
107
|
-
ShouldReek.new
|
108
|
-
end
|
109
|
-
|
110
|
-
#
|
111
|
-
# Checks the target source code for instances of +smell_class+,
|
112
|
-
# and returns +true+ only if one of them has a report string matching
|
113
|
-
# all of the +patterns+.
|
114
|
-
#
|
115
|
-
def reek_of(smell_class, *patterns)
|
116
|
-
ShouldReekOf.new(smell_class, patterns)
|
117
|
-
end
|
118
|
-
|
119
|
-
#
|
120
|
-
# As for reek_of, but the matched smell warning must be the only warning of
|
121
|
-
# any kind in the target source code's Reek report.
|
122
|
-
#
|
123
|
-
def reek_only_of(smell_class, *patterns)
|
124
|
-
ShouldReekOnlyOf.new(smell_class, patterns)
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
if Object.const_defined?(:Spec)
|
130
|
-
Spec::Runner.configure do |config|
|
131
|
-
config.include(Reek::Spec)
|
132
|
-
end
|
133
|
-
end
|