reek 1.2.2 → 1.2.3
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/History.txt +4 -0
- data/Rakefile +0 -1
- data/config/defaults.reek +4 -6
- data/features/masking_smells.feature +9 -9
- data/features/options.feature +2 -2
- data/features/profile.feature +34 -0
- data/features/rake_task.feature +74 -0
- data/features/reports.feature +1 -1
- data/features/samples.feature +4 -4
- data/features/stdin.feature +1 -1
- data/features/step_definitions/reek_steps.rb +11 -7
- data/features/support/env.rb +26 -18
- data/lib/reek.rb +1 -1
- data/lib/reek/adapters/application.rb +9 -2
- data/lib/reek/adapters/command_line.rb +2 -2
- data/lib/reek/adapters/source.rb +4 -1
- data/lib/reek/adapters/spec.rb +1 -3
- data/lib/reek/block_context.rb +14 -8
- data/lib/reek/class_context.rb +6 -66
- data/lib/reek/code_context.rb +10 -0
- data/lib/reek/code_parser.rb +25 -53
- data/lib/reek/configuration.rb +12 -6
- data/lib/reek/if_context.rb +2 -3
- data/lib/reek/method_context.rb +3 -12
- data/lib/reek/module_context.rb +30 -22
- data/lib/reek/name.rb +2 -0
- data/lib/reek/object_refs.rb +0 -3
- data/lib/reek/sexp_formatter.rb +0 -2
- data/lib/reek/smells/class_variable.rb +17 -4
- data/lib/reek/smells/control_couple.rb +3 -10
- data/lib/reek/smells/data_clump.rb +10 -10
- data/lib/reek/smells/feature_envy.rb +1 -8
- data/lib/reek/smells/large_class.rb +3 -3
- data/lib/reek/smells/simulated_polymorphism.rb +17 -3
- data/lib/reek/smells/smell_detector.rb +11 -2
- data/lib/reek/smells/utility_function.rb +1 -1
- data/lib/reek/sniffer.rb +0 -8
- data/lib/reek/stop_context.rb +1 -1
- data/lib/reek/tree_dresser.rb +74 -0
- data/reek.gemspec +3 -3
- data/spec/reek/block_context_spec.rb +6 -6
- data/spec/reek/class_context_spec.rb +2 -23
- data/spec/reek/code_context_spec.rb +149 -67
- data/spec/reek/code_parser_spec.rb +0 -102
- data/spec/reek/method_context_spec.rb +4 -4
- data/spec/reek/singleton_method_context_spec.rb +1 -1
- data/spec/reek/smells/attribute_spec.rb +1 -1
- data/spec/reek/smells/class_variable_spec.rb +96 -7
- data/spec/reek/smells/control_couple_spec.rb +1 -1
- data/spec/reek/smells/data_clump_spec.rb +31 -13
- data/spec/reek/smells/feature_envy_spec.rb +1 -1
- data/spec/reek/smells/large_class_spec.rb +32 -18
- data/spec/reek/smells/simulated_polymorphism_spec.rb +66 -18
- data/spec/reek/sniffer_spec.rb +1 -0
- data/spec/samples/not_quite_masked/dirty.rb +2 -0
- data/spec/spec_helper.rb +1 -1
- data/tasks/reek.rake +1 -1
- metadata +5 -3
- data/lib/reek/exceptions.reek +0 -20
data/lib/reek/module_context.rb
CHANGED
@@ -1,32 +1,30 @@
|
|
1
1
|
require 'reek/code_context'
|
2
|
+
require 'reek/code_parser'
|
3
|
+
require 'reek/sniffer'
|
2
4
|
|
3
5
|
module Reek
|
4
6
|
class ModuleContext < CodeContext
|
5
7
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
8
|
+
class << self
|
9
|
+
def create(outer, exp)
|
10
|
+
res = Name.resolve(exp[1], outer)
|
11
|
+
new(res[0], res[1], exp)
|
12
|
+
end
|
10
13
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
14
|
+
def from_s(src)
|
15
|
+
source = src.to_reek_source
|
16
|
+
sniffer = Sniffer.new(source)
|
17
|
+
CodeParser.new(sniffer).do_module_or_class(source.syntax_tree, self)
|
18
|
+
end
|
15
19
|
end
|
16
20
|
|
17
|
-
attr_reader :
|
21
|
+
attr_reader :attributes
|
18
22
|
|
19
|
-
def initialize(outer, name)
|
20
|
-
super(outer,
|
23
|
+
def initialize(outer, name, exp)
|
24
|
+
super(outer, exp)
|
21
25
|
@name = name
|
22
26
|
@attributes = Set.new
|
23
|
-
@
|
24
|
-
end
|
25
|
-
|
26
|
-
def check_for_attribute_declaration(exp)
|
27
|
-
if [:attr, :attr_reader, :attr_writer, :attr_accessor].include? exp[2]
|
28
|
-
exp[3][1..-1].each {|arg| record_attribute(arg[1])}
|
29
|
-
end
|
27
|
+
@parsed_methods = []
|
30
28
|
end
|
31
29
|
|
32
30
|
def myself
|
@@ -38,16 +36,26 @@ module Reek
|
|
38
36
|
@myself.const_or_nil(modname.to_s)
|
39
37
|
end
|
40
38
|
|
41
|
-
def
|
42
|
-
|
39
|
+
def parameterized_methods(min_clump_size)
|
40
|
+
@parsed_methods.select {|meth| meth.parameters.length >= min_clump_size }
|
43
41
|
end
|
44
42
|
|
45
43
|
def record_attribute(attr)
|
46
44
|
@attributes << Name.new(attr)
|
47
45
|
end
|
48
46
|
|
49
|
-
def
|
50
|
-
@
|
47
|
+
def record_method(meth)
|
48
|
+
@parsed_methods << meth
|
49
|
+
end
|
50
|
+
|
51
|
+
def check_for_attribute_declaration(exp)
|
52
|
+
if [:attr, :attr_reader, :attr_writer, :attr_accessor].include? exp[2]
|
53
|
+
exp[3][1..-1].each {|arg| record_attribute(arg[1])}
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def outer_name
|
58
|
+
"#{@outer.outer_name}#{@name}::"
|
51
59
|
end
|
52
60
|
|
53
61
|
def variable_names
|
data/lib/reek/name.rb
CHANGED
data/lib/reek/object_refs.rb
CHANGED
data/lib/reek/sexp_formatter.rb
CHANGED
@@ -18,14 +18,27 @@ module Reek
|
|
18
18
|
end
|
19
19
|
|
20
20
|
#
|
21
|
-
# Checks whether the given class declares any class variables.
|
21
|
+
# Checks whether the given class or module declares any class variables.
|
22
22
|
# Remembers any smells found.
|
23
23
|
#
|
24
|
-
def examine_context(
|
25
|
-
|
26
|
-
found(
|
24
|
+
def examine_context(mod)
|
25
|
+
class_variables_in(mod).each do |cvar_name|
|
26
|
+
found(mod, "declares the class variable #{cvar_name}")
|
27
27
|
end
|
28
28
|
end
|
29
|
+
|
30
|
+
#
|
31
|
+
# Collects the names of the class variables declared and/or used
|
32
|
+
# in the given module.
|
33
|
+
#
|
34
|
+
def class_variables_in(mod)
|
35
|
+
result = Set.new
|
36
|
+
collector = proc { |cvar_node| result << cvar_node.name }
|
37
|
+
[:cvar, :cvasgn, :cvdecl].each do |stmt_type|
|
38
|
+
mod.each(stmt_type, [:class, :module], &collector)
|
39
|
+
end
|
40
|
+
result
|
41
|
+
end
|
29
42
|
end
|
30
43
|
end
|
31
44
|
end
|
@@ -34,19 +34,12 @@ module Reek
|
|
34
34
|
# because it includes at least two different code paths.
|
35
35
|
#
|
36
36
|
class ControlCouple < SmellDetector
|
37
|
+
include ExcludeInitialize
|
37
38
|
|
38
39
|
def self.contexts # :nodoc:
|
39
40
|
[:if]
|
40
41
|
end
|
41
42
|
|
42
|
-
def self.default_config
|
43
|
-
super.adopt(EXCLUDE_KEY => ['initialize'])
|
44
|
-
end
|
45
|
-
|
46
|
-
def initialize(config = ControlCouple.default_config)
|
47
|
-
super
|
48
|
-
end
|
49
|
-
|
50
43
|
#
|
51
44
|
# Checks whether the given conditional statement relies on a control couple.
|
52
45
|
# Remembers any smells found.
|
@@ -56,8 +49,8 @@ module Reek
|
|
56
49
|
# SMELL: Duplication
|
57
50
|
# This smell is reported once for each conditional that tests the
|
58
51
|
# same parameter. Which means that the same smell can recur within
|
59
|
-
# a single
|
60
|
-
#
|
52
|
+
# a single detector. Which in turn means that SmellDetector must
|
53
|
+
# use a Set to hold smells found.
|
61
54
|
found(cond, "is controlled by argument #{SexpFormatter.format(cond.if_expr)}")
|
62
55
|
end
|
63
56
|
end
|
@@ -20,7 +20,7 @@ module Reek
|
|
20
20
|
class DataClump < SmellDetector
|
21
21
|
|
22
22
|
def self.contexts # :nodoc:
|
23
|
-
[:class]
|
23
|
+
[:class, :module]
|
24
24
|
end
|
25
25
|
|
26
26
|
# The name of the config field that sets the maximum allowed
|
@@ -44,14 +44,14 @@ module Reek
|
|
44
44
|
end
|
45
45
|
|
46
46
|
#
|
47
|
-
# Checks the given
|
47
|
+
# Checks the given class or module for multiple identical parameter sets.
|
48
48
|
# Remembers any smells found.
|
49
49
|
#
|
50
|
-
def examine_context(
|
51
|
-
max_copies = value(MAX_COPIES_KEY,
|
52
|
-
min_clump_size = value(MIN_CLUMP_SIZE_KEY,
|
53
|
-
MethodGroup.new(
|
54
|
-
found(
|
50
|
+
def examine_context(ctx)
|
51
|
+
max_copies = value(MAX_COPIES_KEY, ctx, DEFAULT_MAX_COPIES)
|
52
|
+
min_clump_size = value(MIN_CLUMP_SIZE_KEY, ctx, DEFAULT_MIN_CLUMP_SIZE)
|
53
|
+
MethodGroup.new(ctx, min_clump_size, max_copies).clumps.each do |clump, occurs|
|
54
|
+
found(ctx, "takes parameters #{DataClump.print_clump(clump)} to #{occurs} methods")
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
@@ -68,15 +68,15 @@ module Reek
|
|
68
68
|
methods.map {|meth| meth.parameters.names.sort}.intersection
|
69
69
|
end
|
70
70
|
|
71
|
-
def initialize(
|
72
|
-
@
|
71
|
+
def initialize(ctx, min_clump_size, max_copies)
|
72
|
+
@ctx = ctx
|
73
73
|
@min_clump_size = min_clump_size
|
74
74
|
@max_copies = max_copies
|
75
75
|
end
|
76
76
|
|
77
77
|
def clumps
|
78
78
|
results = Hash.new(0)
|
79
|
-
@
|
79
|
+
@ctx.parameterized_methods(@min_clump_size).bounded_power_set(@max_copies).each do |methods|
|
80
80
|
clump = MethodGroup.intersection_of_parameters_of(methods)
|
81
81
|
if clump.length >= @min_clump_size
|
82
82
|
results[clump] = [methods.length, results[clump]].max
|
@@ -33,14 +33,7 @@ module Reek
|
|
33
33
|
# often than it refers to (ie. send messages to) some other object.
|
34
34
|
#
|
35
35
|
class FeatureEnvy < SmellDetector
|
36
|
-
|
37
|
-
def self.default_config
|
38
|
-
super.adopt(EXCLUDE_KEY => ['initialize'])
|
39
|
-
end
|
40
|
-
|
41
|
-
def initialize(config = FeatureEnvy.default_config)
|
42
|
-
super
|
43
|
-
end
|
36
|
+
include ExcludeInitialize
|
44
37
|
|
45
38
|
#
|
46
39
|
# Checks whether the given +context+ includes any code fragment that
|
@@ -45,9 +45,9 @@ module Reek
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def check_num_methods(klass) # :nodoc:
|
48
|
-
|
49
|
-
return if
|
50
|
-
found(klass, "has at least #{
|
48
|
+
actual = klass.each(:defn, [:class, :module]).length
|
49
|
+
return if actual <= value(MAX_ALLOWED_METHODS_KEY, klass, DEFAULT_MAX_METHODS)
|
50
|
+
found(klass, "has at least #{actual} methods")
|
51
51
|
end
|
52
52
|
|
53
53
|
def check_num_ivars(klass) # :nodoc:
|
@@ -47,12 +47,26 @@ module Reek
|
|
47
47
|
# Remembers any smells found.
|
48
48
|
#
|
49
49
|
def examine_context(klass)
|
50
|
-
|
51
|
-
klass.conditionals.each {|cond| counts[cond] += 1}
|
52
|
-
counts.each do |key, val|
|
50
|
+
conditional_counts(klass).each do |key, val|
|
53
51
|
found(klass, "tests #{SexpFormatter.format(key)} at least #{val} times") if val > value(MAX_IDENTICAL_IFS_KEY, klass, DEFAULT_MAX_IFS)
|
54
52
|
end
|
55
53
|
end
|
54
|
+
|
55
|
+
#
|
56
|
+
# Returns a Hash listing all of the conditional expressions in
|
57
|
+
# the given syntax tree together with the number of times each
|
58
|
+
# occurs. Ignores nested classes and modules.
|
59
|
+
#
|
60
|
+
def conditional_counts(klass)
|
61
|
+
result = Hash.new(0)
|
62
|
+
collector = proc { |node|
|
63
|
+
condition = node.condition
|
64
|
+
result[condition] += 1 unless condition == s(:call, nil, :block_given?, s(:arglist))
|
65
|
+
}
|
66
|
+
klass.each(:if, [:class, :module], &collector)
|
67
|
+
klass.each(:case, [:class, :module], &collector)
|
68
|
+
result
|
69
|
+
end
|
56
70
|
end
|
57
71
|
end
|
58
72
|
end
|
@@ -10,6 +10,15 @@ end
|
|
10
10
|
module Reek
|
11
11
|
module Smells
|
12
12
|
|
13
|
+
module ExcludeInitialize
|
14
|
+
def self.default_config
|
15
|
+
super.adopt(EXCLUDE_KEY => ['initialize'])
|
16
|
+
end
|
17
|
+
def initialize(config = self.class.default_config)
|
18
|
+
super
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
13
22
|
class SmellDetector
|
14
23
|
|
15
24
|
# The name of the config field that lists the names of code contexts
|
@@ -70,11 +79,11 @@ module Reek
|
|
70
79
|
end
|
71
80
|
|
72
81
|
def configure_with(config)
|
73
|
-
@config.
|
82
|
+
@config.adopt!(config)
|
74
83
|
end
|
75
84
|
|
76
85
|
def copy
|
77
|
-
self.class.new(@config.
|
86
|
+
self.class.new(@config.deep_copy)
|
78
87
|
end
|
79
88
|
|
80
89
|
def supersede_with(config)
|
data/lib/reek/sniffer.rb
CHANGED
@@ -125,10 +125,6 @@ module Reek
|
|
125
125
|
stack.has_smell?(patterns)
|
126
126
|
end
|
127
127
|
|
128
|
-
def smells_only_of?(klass, patterns)
|
129
|
-
num_smells == 1 and has_smell?(klass, patterns)
|
130
|
-
end
|
131
|
-
|
132
128
|
def sniff
|
133
129
|
self
|
134
130
|
end
|
@@ -175,10 +171,6 @@ private
|
|
175
171
|
total
|
176
172
|
end
|
177
173
|
|
178
|
-
def smells_only_of?(klass, patterns)
|
179
|
-
num_smells == 1 and has_smell?(klass, patterns)
|
180
|
-
end
|
181
|
-
|
182
174
|
def sniff
|
183
175
|
self
|
184
176
|
end
|
data/lib/reek/stop_context.rb
CHANGED
@@ -0,0 +1,74 @@
|
|
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 children
|
9
|
+
find_all { |item| Sexp === item }
|
10
|
+
end
|
11
|
+
|
12
|
+
def is_language_node?
|
13
|
+
first.class == Symbol
|
14
|
+
end
|
15
|
+
|
16
|
+
def has_type?(type)
|
17
|
+
is_language_node? and first == type
|
18
|
+
end
|
19
|
+
|
20
|
+
#
|
21
|
+
# Carries out a depth-first traversal of this syntax tree, yielding
|
22
|
+
# every Sexp of type +target_type+. The traversal ignores any node
|
23
|
+
# whose type is listed in the Array +ignoring+.
|
24
|
+
#
|
25
|
+
def look_for(target_type, ignoring, &blk)
|
26
|
+
each do |elem|
|
27
|
+
if Sexp === elem then
|
28
|
+
elem.look_for(target_type, ignoring, &blk) unless ignoring.include?(elem.first)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
blk.call(self) if first == target_type
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
module CvarNode
|
36
|
+
def name
|
37
|
+
self[1]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
module IfNode
|
42
|
+
def condition
|
43
|
+
self[1]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
module CaseNode
|
48
|
+
def condition
|
49
|
+
self[1]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class TreeDresser
|
54
|
+
# SMELL: Duplication
|
55
|
+
# Put these into a new module and build the mapping automagically
|
56
|
+
# based on the node type
|
57
|
+
EXTENSIONS = {
|
58
|
+
:cvar => CvarNode,
|
59
|
+
:cvasgn => CvarNode,
|
60
|
+
:cvdecl => CvarNode,
|
61
|
+
:if => IfNode,
|
62
|
+
:case => CaseNode,
|
63
|
+
}
|
64
|
+
|
65
|
+
def dress(sexp)
|
66
|
+
sexp.extend(SexpNode)
|
67
|
+
if EXTENSIONS.has_key?(sexp[0])
|
68
|
+
sexp.extend(EXTENSIONS[sexp[0]])
|
69
|
+
end
|
70
|
+
sexp[0..-1].each { |sub| dress(sub) if Array === sub }
|
71
|
+
sexp
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/reek.gemspec
CHANGED
@@ -2,17 +2,17 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{reek}
|
5
|
-
s.version = "1.2.
|
5
|
+
s.version = "1.2.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{2009-
|
9
|
+
s.date = %q{2009-11-02}
|
10
10
|
s.default_executable = %q{reek}
|
11
11
|
s.description = %q{Code smell detector for Ruby}
|
12
12
|
s.email = ["kevin@rutherford-software.com"]
|
13
13
|
s.executables = ["reek"]
|
14
14
|
s.extra_rdoc_files = ["History.txt", "License.txt", "README.rdoc"]
|
15
|
-
s.files = ["History.txt", "License.txt", "README.rdoc", "Rakefile", "bin/reek", "config/defaults.reek", "features/masking_smells.feature", "features/options.feature", "features/reports.feature", "features/samples.feature", "features/stdin.feature", "features/step_definitions/reek_steps.rb", "features/support/env.rb", "lib/reek.rb", "lib/reek/adapters/application.rb", "lib/reek/adapters/command_line.rb", "lib/reek/adapters/config_file.rb", "lib/reek/adapters/core_extras.rb", "lib/reek/adapters/rake_task.rb", "lib/reek/adapters/report.rb", "lib/reek/adapters/source.rb", "lib/reek/adapters/spec.rb", "lib/reek/block_context.rb", "lib/reek/class_context.rb", "lib/reek/code_context.rb", "lib/reek/code_parser.rb", "lib/reek/configuration.rb", "lib/reek/detector_stack.rb", "lib/reek/
|
15
|
+
s.files = ["History.txt", "License.txt", "README.rdoc", "Rakefile", "bin/reek", "config/defaults.reek", "features/masking_smells.feature", "features/options.feature", "features/profile.feature", "features/rake_task.feature", "features/reports.feature", "features/samples.feature", "features/stdin.feature", "features/step_definitions/reek_steps.rb", "features/support/env.rb", "lib/reek.rb", "lib/reek/adapters/application.rb", "lib/reek/adapters/command_line.rb", "lib/reek/adapters/config_file.rb", "lib/reek/adapters/core_extras.rb", "lib/reek/adapters/rake_task.rb", "lib/reek/adapters/report.rb", "lib/reek/adapters/source.rb", "lib/reek/adapters/spec.rb", "lib/reek/block_context.rb", "lib/reek/class_context.rb", "lib/reek/code_context.rb", "lib/reek/code_parser.rb", "lib/reek/configuration.rb", "lib/reek/detector_stack.rb", "lib/reek/if_context.rb", "lib/reek/method_context.rb", "lib/reek/module_context.rb", "lib/reek/name.rb", "lib/reek/object_refs.rb", "lib/reek/sexp_formatter.rb", "lib/reek/singleton_method_context.rb", "lib/reek/smell_warning.rb", "lib/reek/smells/attribute.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/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_name.rb", "lib/reek/smells/utility_function.rb", "lib/reek/sniffer.rb", "lib/reek/stop_context.rb", "lib/reek/tree_dresser.rb", "lib/reek/yield_call_context.rb", "reek.gemspec", "spec/reek/adapters/report_spec.rb", "spec/reek/adapters/should_reek_of_spec.rb", "spec/reek/adapters/should_reek_only_of_spec.rb", "spec/reek/adapters/should_reek_spec.rb", "spec/reek/block_context_spec.rb", "spec/reek/class_context_spec.rb", "spec/reek/code_context_spec.rb", "spec/reek/code_parser_spec.rb", "spec/reek/config_spec.rb", "spec/reek/configuration_spec.rb", "spec/reek/if_context_spec.rb", "spec/reek/method_context_spec.rb", "spec/reek/module_context_spec.rb", "spec/reek/name_spec.rb", "spec/reek/object_refs_spec.rb", "spec/reek/object_source_spec.rb", "spec/reek/singleton_method_context_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/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/large_class_spec.rb", "spec/reek/smells/long_method_spec.rb", "spec/reek/smells/long_parameter_list_spec.rb", "spec/reek/smells/nested_iterators_spec.rb", "spec/reek/smells/simulated_polymorphism_spec.rb", "spec/reek/smells/smell_detector_spec.rb", "spec/reek/smells/uncommunicative_name_spec.rb", "spec/reek/smells/utility_function_spec.rb", "spec/reek/sniffer_spec.rb", "spec/reek/stop_context_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"]
|
16
16
|
s.homepage = %q{http://wiki.github.com/kevinrutherford/reek}
|
17
17
|
s.post_install_message = %q{
|
18
18
|
For more information on reek, see http://wiki.github.com/kevinrutherford/reek
|