reek 2.1.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (179) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -21
  3. data/.travis.yml +1 -0
  4. data/.yardopts +3 -6
  5. data/CHANGELOG +6 -0
  6. data/CONTRIBUTING.md +8 -3
  7. data/README.md +94 -42
  8. data/config/defaults.reek +0 -1
  9. data/docs/API.md +50 -0
  10. data/docs/Attribute.md +43 -0
  11. data/docs/Basic-Smell-Options.md +44 -0
  12. data/docs/Boolean-Parameter.md +52 -0
  13. data/docs/Class-Variable.md +40 -0
  14. data/docs/Code-Smells.md +34 -0
  15. data/docs/Command-Line-Options.md +84 -0
  16. data/docs/Configuration-Files.md +38 -0
  17. data/docs/Control-Couple.md +22 -0
  18. data/docs/Control-Parameter.md +29 -0
  19. data/docs/Data-Clump.md +44 -0
  20. data/docs/Duplicate-Method-Call.md +49 -0
  21. data/docs/Feature-Envy.md +29 -0
  22. data/docs/How-reek-works-internally.md +44 -0
  23. data/docs/Irresponsible-Module.md +39 -0
  24. data/docs/Large-Class.md +20 -0
  25. data/docs/Long-Parameter-List.md +38 -0
  26. data/docs/Long-Yield-List.md +36 -0
  27. data/docs/Module-Initialize.md +62 -0
  28. data/docs/Nested-Iterators.md +38 -0
  29. data/docs/Nil-Check.md +39 -0
  30. data/docs/Prima-Donna-Method.md +53 -0
  31. data/docs/RSpec-matchers.md +133 -0
  32. data/docs/Rake-Task.md +58 -0
  33. data/docs/Reek-Driven-Development.md +45 -0
  34. data/docs/Repeated-Conditional.md +44 -0
  35. data/docs/Simulated-Polymorphism.md +16 -0
  36. data/docs/Smell-Suppression.md +32 -0
  37. data/docs/Too-Many-Instance-Variables.md +43 -0
  38. data/docs/Too-Many-Methods.md +55 -0
  39. data/docs/Too-Many-Statements.md +50 -0
  40. data/docs/Uncommunicative-Method-Name.md +24 -0
  41. data/docs/Uncommunicative-Module-Name.md +23 -0
  42. data/docs/Uncommunicative-Name.md +16 -0
  43. data/docs/Uncommunicative-Parameter-Name.md +24 -0
  44. data/docs/Uncommunicative-Variable-Name.md +24 -0
  45. data/docs/Unused-Parameters.md +27 -0
  46. data/docs/Utility-Function.md +46 -0
  47. data/docs/Versioning-Policy.md +7 -0
  48. data/docs/YAML-Reports.md +111 -0
  49. data/docs/yard_plugin.rb +14 -0
  50. data/features/command_line_interface/options.feature +1 -0
  51. data/features/programmatic_access.feature +1 -1
  52. data/features/samples.feature +3 -3
  53. data/lib/reek.rb +2 -2
  54. data/lib/reek/cli/input.rb +2 -2
  55. data/lib/reek/cli/option_interpreter.rb +2 -0
  56. data/lib/reek/cli/options.rb +10 -4
  57. data/lib/reek/cli/reek_command.rb +2 -2
  58. data/lib/reek/cli/report/report.rb +60 -0
  59. data/lib/reek/cli/silencer.rb +13 -0
  60. data/lib/reek/{source → core}/ast_node.rb +1 -1
  61. data/lib/reek/{source → core}/ast_node_class_map.rb +10 -11
  62. data/lib/reek/{source → core}/code_comment.rb +1 -1
  63. data/lib/reek/core/code_context.rb +1 -1
  64. data/lib/reek/core/examiner.rb +85 -0
  65. data/lib/reek/core/method_context.rb +1 -1
  66. data/lib/reek/core/module_context.rb +2 -2
  67. data/lib/reek/core/reference_collector.rb +31 -0
  68. data/lib/reek/core/singleton_method_context.rb +0 -4
  69. data/lib/reek/core/smell_repository.rb +4 -2
  70. data/lib/reek/{source → core}/tree_dresser.rb +1 -1
  71. data/lib/reek/{source → sexp}/sexp_extensions.rb +5 -5
  72. data/lib/reek/sexp/sexp_formatter.rb +29 -0
  73. data/lib/reek/sexp/sexp_node.rb +91 -0
  74. data/lib/reek/smells.rb +4 -2
  75. data/lib/reek/smells/attribute.rb +35 -7
  76. data/lib/reek/smells/boolean_parameter.rb +1 -1
  77. data/lib/reek/smells/class_variable.rb +1 -1
  78. data/lib/reek/smells/control_parameter.rb +1 -1
  79. data/lib/reek/smells/data_clump.rb +1 -1
  80. data/lib/reek/smells/duplicate_method_call.rb +12 -4
  81. data/lib/reek/smells/feature_envy.rb +1 -1
  82. data/lib/reek/smells/irresponsible_module.rb +3 -3
  83. data/lib/reek/smells/long_parameter_list.rb +1 -1
  84. data/lib/reek/smells/long_yield_list.rb +1 -1
  85. data/lib/reek/smells/module_initialize.rb +1 -1
  86. data/lib/reek/smells/nested_iterators.rb +1 -1
  87. data/lib/reek/smells/nil_check.rb +3 -2
  88. data/lib/reek/smells/prima_donna_method.rb +18 -11
  89. data/lib/reek/smells/repeated_conditional.rb +3 -3
  90. data/lib/reek/smells/smell_detector.rb +5 -1
  91. data/lib/reek/smells/smell_warning.rb +99 -0
  92. data/lib/reek/smells/too_many_instance_variables.rb +1 -1
  93. data/lib/reek/smells/too_many_methods.rb +1 -1
  94. data/lib/reek/smells/too_many_statements.rb +1 -1
  95. data/lib/reek/smells/uncommunicative_method_name.rb +1 -1
  96. data/lib/reek/smells/uncommunicative_module_name.rb +1 -1
  97. data/lib/reek/smells/uncommunicative_parameter_name.rb +1 -1
  98. data/lib/reek/smells/uncommunicative_variable_name.rb +1 -1
  99. data/lib/reek/smells/unused_parameters.rb +1 -1
  100. data/lib/reek/smells/utility_function.rb +3 -16
  101. data/lib/reek/source/source_code.rb +31 -13
  102. data/lib/reek/source/source_locator.rb +16 -17
  103. data/lib/reek/source/source_repository.rb +10 -11
  104. data/lib/reek/spec/should_reek.rb +2 -2
  105. data/lib/reek/spec/should_reek_of.rb +2 -2
  106. data/lib/reek/spec/should_reek_only_of.rb +2 -2
  107. data/lib/reek/version.rb +1 -1
  108. data/reek.gemspec +3 -4
  109. data/spec/factories/factories.rb +1 -1
  110. data/spec/gem/yard_spec.rb +1 -1
  111. data/spec/quality/reek_source_spec.rb +2 -2
  112. data/spec/reek/cli/html_report_spec.rb +3 -3
  113. data/spec/reek/cli/json_report_spec.rb +3 -3
  114. data/spec/reek/cli/{option_interperter_spec.rb → option_interpreter_spec.rb} +1 -1
  115. data/spec/reek/cli/options_spec.rb +19 -0
  116. data/spec/reek/cli/text_report_spec.rb +7 -7
  117. data/spec/reek/cli/xml_report_spec.rb +34 -0
  118. data/spec/reek/cli/yaml_report_spec.rb +3 -3
  119. data/spec/reek/configuration/app_configuration_spec.rb +1 -1
  120. data/spec/reek/configuration/configuration_file_finder_spec.rb +22 -1
  121. data/spec/reek/{source → core}/code_comment_spec.rb +14 -14
  122. data/spec/reek/core/code_context_spec.rb +1 -1
  123. data/spec/reek/{examiner_spec.rb → core/examiner_spec.rb} +12 -12
  124. data/spec/reek/core/method_context_spec.rb +27 -22
  125. data/spec/reek/core/module_context_spec.rb +2 -2
  126. data/spec/reek/core/object_refs_spec.rb +1 -1
  127. data/spec/reek/{source → core}/object_source_spec.rb +1 -1
  128. data/spec/reek/{source → core}/reference_collector_spec.rb +25 -16
  129. data/spec/reek/core/singleton_method_context_spec.rb +12 -2
  130. data/spec/reek/core/smell_configuration_spec.rb +1 -1
  131. data/spec/reek/core/smell_repository_spec.rb +12 -1
  132. data/spec/reek/core/stop_context_spec.rb +1 -1
  133. data/spec/reek/core/tree_dresser_spec.rb +16 -0
  134. data/spec/reek/core/tree_walker_spec.rb +3 -3
  135. data/spec/reek/core/warning_collector_spec.rb +6 -6
  136. data/spec/reek/{source → sexp}/sexp_extensions_spec.rb +8 -8
  137. data/spec/reek/{source → sexp}/sexp_formatter_spec.rb +11 -5
  138. data/spec/reek/{source → sexp}/sexp_node_spec.rb +3 -3
  139. data/spec/reek/smells/attribute_spec.rb +89 -85
  140. data/spec/reek/smells/behaves_like_variable_detector.rb +1 -1
  141. data/spec/reek/smells/boolean_parameter_spec.rb +1 -1
  142. data/spec/reek/smells/class_variable_spec.rb +1 -1
  143. data/spec/reek/smells/control_parameter_spec.rb +1 -1
  144. data/spec/reek/smells/data_clump_spec.rb +2 -2
  145. data/spec/reek/smells/duplicate_method_call_spec.rb +1 -1
  146. data/spec/reek/smells/feature_envy_spec.rb +2 -2
  147. data/spec/reek/smells/irresponsible_module_spec.rb +1 -1
  148. data/spec/reek/smells/long_parameter_list_spec.rb +2 -2
  149. data/spec/reek/smells/long_yield_list_spec.rb +1 -1
  150. data/spec/reek/smells/module_initialize_spec.rb +1 -1
  151. data/spec/reek/smells/nested_iterators_spec.rb +2 -2
  152. data/spec/reek/smells/nil_check_spec.rb +1 -1
  153. data/spec/reek/smells/prima_donna_method_spec.rb +1 -1
  154. data/spec/reek/smells/repeated_conditional_spec.rb +1 -1
  155. data/spec/reek/smells/smell_detector_shared.rb +2 -2
  156. data/spec/reek/{smell_warning_spec.rb → smells/smell_warning_spec.rb} +7 -7
  157. data/spec/reek/smells/too_many_instance_variables_spec.rb +1 -1
  158. data/spec/reek/smells/too_many_methods_spec.rb +1 -1
  159. data/spec/reek/smells/too_many_statements_spec.rb +4 -4
  160. data/spec/reek/smells/uncommunicative_method_name_spec.rb +1 -1
  161. data/spec/reek/smells/uncommunicative_module_name_spec.rb +1 -1
  162. data/spec/reek/smells/uncommunicative_parameter_name_spec.rb +1 -1
  163. data/spec/reek/smells/uncommunicative_variable_name_spec.rb +1 -1
  164. data/spec/reek/smells/unused_parameters_spec.rb +1 -1
  165. data/spec/reek/smells/utility_function_spec.rb +1 -1
  166. data/spec/reek/source/source_code_spec.rb +1 -1
  167. data/spec/reek/spec/should_reek_of_spec.rb +1 -1
  168. data/spec/reek/spec/should_reek_only_of_spec.rb +1 -1
  169. data/spec/reek/spec/should_reek_spec.rb +1 -1
  170. data/spec/samples/checkstyle.xml +2 -0
  171. data/spec/spec_helper.rb +15 -3
  172. metadata +68 -38
  173. data/.ruby-gemset +0 -1
  174. data/lib/reek/examiner.rb +0 -79
  175. data/lib/reek/smell_warning.rb +0 -87
  176. data/lib/reek/source/reference_collector.rb +0 -27
  177. data/lib/reek/source/sexp_formatter.rb +0 -22
  178. data/lib/reek/source/sexp_node.rb +0 -79
  179. data/spec/reek/source/tree_dresser_spec.rb +0 -16
@@ -2,7 +2,7 @@ require_relative '../../spec_helper'
2
2
  require_relative '../../../lib/reek/core/module_context'
3
3
  require_relative '../../../lib/reek/core/stop_context'
4
4
 
5
- describe Reek::Core::ModuleContext do
5
+ RSpec.describe Reek::Core::ModuleContext do
6
6
  it 'should report module name for smell in method' do
7
7
  expect('
8
8
  module Fred
@@ -19,7 +19,7 @@ module Fred
19
19
  end
20
20
  end
21
21
 
22
- describe Reek::Core::ModuleContext do
22
+ RSpec.describe Reek::Core::ModuleContext do
23
23
  it 'should recognise global constant' do
24
24
  expect('# module for test
25
25
  module ::Global
@@ -1,7 +1,7 @@
1
1
  require_relative '../../spec_helper'
2
2
  require_relative '../../../lib/reek/core/object_refs'
3
3
 
4
- describe Reek::Core::ObjectRefs do
4
+ RSpec.describe Reek::Core::ObjectRefs do
5
5
  before(:each) do
6
6
  @refs = Reek::Core::ObjectRefs.new
7
7
  end
@@ -1,6 +1,6 @@
1
1
  require_relative '../../spec_helper'
2
2
 
3
- describe Dir do
3
+ RSpec.describe Dir do
4
4
  it 'reports correct smells via the Dir matcher' do
5
5
  files = Dir['spec/samples/two_smelly_files/*.rb']
6
6
  expect(files).to reek
@@ -1,50 +1,59 @@
1
1
  require_relative '../../spec_helper'
2
- require_relative '../../../lib/reek/source/reference_collector'
2
+ require_relative '../../../lib/reek/core/reference_collector'
3
3
 
4
- describe Reek::Source::ReferenceCollector do
4
+ RSpec.describe Reek::Core::ReferenceCollector do
5
5
  context 'counting refs to self' do
6
6
  def refs_to_self(src)
7
7
  syntax_tree = Reek::Source::SourceCode.from(src).syntax_tree
8
- Reek::Source::ReferenceCollector.new(syntax_tree).num_refs_to_self
8
+ described_class.new(syntax_tree).num_refs_to_self
9
9
  end
10
+
10
11
  it 'with no refs to self' do
11
12
  expect(refs_to_self('def no_envy(arga) arga.barg end')).to eq(0)
12
13
  end
14
+
13
15
  it 'counts a call to super' do
14
16
  expect(refs_to_self('def simple() super; end')).to eq(1)
15
17
  end
18
+
16
19
  it 'counts a local call' do
17
20
  expect(refs_to_self('def simple() to_s; end')).to eq(1)
18
21
  end
22
+
19
23
  it 'counts a use of self' do
20
24
  expect(refs_to_self('def simple() lv = self; end')).to eq(1)
21
25
  end
26
+
22
27
  it 'counts a call with self as receiver' do
23
28
  expect(refs_to_self('def simple() self.to_s; end')).to eq(1)
24
29
  end
30
+
25
31
  it 'counts uses of an ivar' do
26
32
  expect(refs_to_self('def no_envy() @item.to_a; @item = 4; @item end')).to eq(3)
27
33
  end
34
+
28
35
  it 'counts an ivar passed to a method' do
29
36
  expect(refs_to_self('def no_envy(arga) arga.barg(@item); arga end')).to eq(1)
30
37
  end
38
+
31
39
  it 'ignores global variables' do
32
40
  expect(refs_to_self('def no_envy(arga) $s2.to_a; $s2[arga] end')).to eq(0)
33
41
  end
42
+
34
43
  it 'ignores global variables' do
35
- src = <<EOS
36
- def accept(t, pat = /.*/nm, &block)
37
- if pat
38
- pat.respond_to?(:match) or raise TypeError, "has no `match'"
39
- else
40
- pat = t if t.respond_to?(:match)
41
- end
42
- unless block
43
- block = pat.method(:convert).to_proc if pat.respond_to?(:convert)
44
- end
45
- @atype[t] = [pat, block]
46
- end
47
- EOS
44
+ src = <<-EOS
45
+ def accept(t, pat = /.*/nm, &block)
46
+ if pat
47
+ pat.respond_to?(:match) or raise TypeError, "has no `match'"
48
+ else
49
+ pat = t if t.respond_to?(:match)
50
+ end
51
+ unless block
52
+ block = pat.method(:convert).to_proc if pat.respond_to?(:convert)
53
+ end
54
+ @atype[t] = [pat, block]
55
+ end
56
+ EOS
48
57
  expect(refs_to_self(src)).to eq(2)
49
58
  end
50
59
  end
@@ -1,7 +1,17 @@
1
1
  require_relative '../../spec_helper'
2
- require_relative '../../../lib/reek/core/module_context'
3
2
  require_relative '../../../lib/reek/core/singleton_method_context'
4
3
  require_relative '../../../lib/reek/core/stop_context'
5
4
 
6
- describe Reek::Core::SingletonMethodContext do
5
+ RSpec.describe Reek::Core::SingletonMethodContext do
6
+ let(:smc) do
7
+ sexp = s(:def, :foo, s(:args, s(:arg, :bar)), nil)
8
+ Reek::Core::SingletonMethodContext.new(Reek::Core::StopContext.new, sexp)
9
+ end
10
+
11
+ describe '#envious_receivers' do
12
+ it 'should not record envious calls' do
13
+ smc.record_call_to s(:send, s(:lvar, :bar), :baz)
14
+ expect(smc.envious_receivers).to be_empty
15
+ end
16
+ end
7
17
  end
@@ -1,7 +1,7 @@
1
1
  require_relative '../../spec_helper'
2
2
  require_relative '../../../lib/reek/core/smell_configuration'
3
3
 
4
- describe Reek::Core::SmellConfiguration do
4
+ RSpec.describe Reek::Core::SmellConfiguration do
5
5
  it 'returns the default value when key not found' do
6
6
  cf = Reek::Core::SmellConfiguration.new({})
7
7
  expect(cf.value('fred', nil, 27)).to eq(27)
@@ -1,7 +1,7 @@
1
1
  require_relative '../../spec_helper'
2
2
  require_relative '../../../lib/reek/core/smell_repository'
3
3
 
4
- describe Reek::Core::SmellRepository do
4
+ RSpec.describe Reek::Core::SmellRepository do
5
5
  describe '.smell_types' do
6
6
  let(:smell_types) { Reek::Core::SmellRepository.smell_types }
7
7
 
@@ -13,5 +13,16 @@ describe Reek::Core::SmellRepository do
13
13
  it 'should exclude certain smell_types' do
14
14
  expect(smell_types).to_not include(Reek::Smells::SmellDetector)
15
15
  end
16
+
17
+ it 'should return the smell types in alphabetic order' do
18
+ expect(smell_types).to eq(smell_types.sort_by(&:name))
19
+ end
20
+
21
+ it "should raise an ArgumentError if smell to configure doesn't exist" do
22
+ repository = Reek::Core::SmellRepository.new
23
+ expect { repository.configure('SomethingNonExistant', {}) }.
24
+ to raise_error ArgumentError,
25
+ 'Unknown smell type SomethingNonExistant found in configuration'
26
+ end
16
27
  end
17
28
  end
@@ -1,7 +1,7 @@
1
1
  require_relative '../../spec_helper'
2
2
  require_relative '../../../lib/reek/core/stop_context'
3
3
 
4
- describe Reek::Core::StopContext do
4
+ RSpec.describe Reek::Core::StopContext do
5
5
  before :each do
6
6
  @stop = Reek::Core::StopContext.new
7
7
  end
@@ -0,0 +1,16 @@
1
+ require_relative '../../spec_helper'
2
+ require_relative '../../../lib/reek/core/tree_dresser'
3
+
4
+ RSpec.describe Reek::Core::TreeDresser do
5
+ let(:ifnode) { Parser::AST::Node.new(:if) }
6
+ let(:sendnode) { Parser::AST::Node.new(:send) }
7
+ let(:dresser) { described_class.new }
8
+
9
+ it 'dresses :if sexp with IfNode' do
10
+ expect(dresser.dress(ifnode, {})).to be_a Reek::Sexp::SexpExtensions::IfNode
11
+ end
12
+
13
+ it 'dresses :send sexp with SendNode' do
14
+ expect(dresser.dress(sendnode, {})).to be_a Reek::Sexp::SexpExtensions::SendNode
15
+ end
16
+ end
@@ -1,7 +1,7 @@
1
1
  require_relative '../../spec_helper'
2
2
  require_relative '../../../lib/reek/core/tree_walker'
3
3
 
4
- describe Reek::Core::TreeWalker, 'with no method definitions' do
4
+ RSpec.describe Reek::Core::TreeWalker, 'with no method definitions' do
5
5
  it 'reports no problems for empty source code' do
6
6
  expect('').not_to reek
7
7
  end
@@ -11,14 +11,14 @@ class Fred; end').not_to reek
11
11
  end
12
12
  end
13
13
 
14
- describe Reek::Core::TreeWalker, 'with a global method definition' do
14
+ RSpec.describe Reek::Core::TreeWalker, 'with a global method definition' do
15
15
  it 'reports no problems for simple method' do
16
16
  src = 'def Outermost::fred() true; end'
17
17
  expect(src).not_to reek
18
18
  end
19
19
  end
20
20
 
21
- describe Reek::Core::TreeWalker, 'when a yield is the receiver' do
21
+ RSpec.describe Reek::Core::TreeWalker, 'when a yield is the receiver' do
22
22
  it 'reports no problems' do
23
23
  src = <<EOS
24
24
  def values(*args)
@@ -1,8 +1,8 @@
1
1
  require_relative '../../spec_helper'
2
2
  require_relative '../../../lib/reek/core/warning_collector'
3
- require_relative '../../../lib/reek/smell_warning'
3
+ require_relative '../../../lib/reek/smells/smell_warning'
4
4
 
5
- describe Reek::Core::WarningCollector do
5
+ RSpec.describe Reek::Core::WarningCollector do
6
6
  before(:each) do
7
7
  @collector = Reek::Core::WarningCollector.new
8
8
  end
@@ -15,10 +15,10 @@ describe Reek::Core::WarningCollector do
15
15
 
16
16
  context 'with one warning' do
17
17
  before :each do
18
- @warning = Reek::SmellWarning.new(Reek::Smells::FeatureEnvy.new(''),
19
- context: 'fred',
20
- lines: [1, 2, 3],
21
- message: 'hello')
18
+ @warning = Reek::Smells::SmellWarning.new(Reek::Smells::FeatureEnvy.new(''),
19
+ context: 'fred',
20
+ lines: [1, 2, 3],
21
+ message: 'hello')
22
22
  @collector.found_smell(@warning)
23
23
  end
24
24
  it 'reports that warning' do
@@ -1,7 +1,7 @@
1
1
  require_relative '../../spec_helper'
2
- require_relative '../../../lib/reek/source/sexp_extensions'
2
+ require_relative '../../../lib/reek/sexp/sexp_extensions'
3
3
 
4
- describe Reek::Source::SexpExtensions::DefNode do
4
+ RSpec.describe Reek::Sexp::SexpExtensions::DefNode do
5
5
  context 'with no parameters' do
6
6
  before :each do
7
7
  @node = s(:def, :hello, s(:args))
@@ -110,7 +110,7 @@ describe Reek::Source::SexpExtensions::DefNode do
110
110
 
111
111
  it 'has a body extended with SexpNode' do
112
112
  b = @node.body
113
- expect(b.class.included_modules.first).to eq Reek::Source::SexpNode
113
+ expect(b.class.included_modules.first).to eq Reek::Sexp::SexpNode
114
114
  end
115
115
 
116
116
  it 'finds nodes in the body with #body_nodes' do
@@ -133,7 +133,7 @@ describe Reek::Source::SexpExtensions::DefNode do
133
133
  end
134
134
  end
135
135
 
136
- describe Reek::Source::SexpExtensions::DefsNode do
136
+ RSpec.describe Reek::Sexp::SexpExtensions::DefsNode do
137
137
  context 'with no parameters' do
138
138
  before :each do
139
139
  @node = s(:defs, s(:lvar, :obj), :hello, s(:args))
@@ -242,12 +242,12 @@ describe Reek::Source::SexpExtensions::DefsNode do
242
242
 
243
243
  it 'has a body extended with SexpNode' do
244
244
  b = @node.body
245
- expect(b.class.included_modules.first).to eq Reek::Source::SexpNode
245
+ expect(b.class.included_modules.first).to eq Reek::Sexp::SexpNode
246
246
  end
247
247
  end
248
248
  end
249
249
 
250
- describe Reek::Source::SexpExtensions::SendNode do
250
+ RSpec.describe Reek::Sexp::SexpExtensions::SendNode do
251
251
  context 'with no parameters' do
252
252
  before :each do
253
253
  @node = s(:send, nil, :hello)
@@ -279,7 +279,7 @@ describe Reek::Source::SexpExtensions::SendNode do
279
279
  end
280
280
  end
281
281
 
282
- describe Reek::Source::SexpExtensions::BlockNode do
282
+ RSpec.describe Reek::Sexp::SexpExtensions::BlockNode do
283
283
  context 'with no parameters' do
284
284
  before :each do
285
285
  @node = s(:block, s(:send, nil, :map), s(:args), nil)
@@ -311,7 +311,7 @@ describe Reek::Source::SexpExtensions::BlockNode do
311
311
  end
312
312
  end
313
313
 
314
- describe Reek::Source::SexpExtensions::ModuleNode do
314
+ RSpec.describe Reek::Sexp::SexpExtensions::ModuleNode do
315
315
  context 'with a simple name' do
316
316
  subject do
317
317
  mod = ast(:module, :Fred, nil)
@@ -1,16 +1,16 @@
1
1
  require_relative '../../spec_helper'
2
- require_relative '../../../lib/reek/source/sexp_formatter'
2
+ require_relative '../../../lib/reek/sexp/sexp_formatter'
3
3
 
4
- describe Reek::Source::SexpFormatter do
4
+ RSpec.describe Reek::Sexp::SexpFormatter do
5
5
  describe '::format' do
6
6
  it 'formats a simple s-expression' do
7
- result = Reek::Source::SexpFormatter.format s(:lvar, :foo)
7
+ result = described_class.format s(:lvar, :foo)
8
8
  expect(result).to eq('foo')
9
9
  end
10
10
 
11
11
  it 'formats a more complex s-expression' do
12
12
  ast = s(:send, nil, :foo, s(:lvar, :bar))
13
- result = Reek::Source::SexpFormatter.format(ast)
13
+ result = described_class.format(ast)
14
14
  expect(result).to eq('foo(bar)')
15
15
  end
16
16
 
@@ -21,9 +21,15 @@ describe Reek::Source::SexpFormatter do
21
21
  s(:begin,
22
22
  s(:send, nil, :baz),
23
23
  s(:send, nil, :qux)))
24
- result = Reek::Source::SexpFormatter.format ast
24
+ result = described_class.format ast
25
25
 
26
26
  expect(result).to eq 'if foo ... end'
27
27
  end
28
+
29
+ it "doesn't reduce two-line ASTs" do
30
+ ast = s(:def, 'my_method', s(:args))
31
+ result = described_class.format ast
32
+ expect(result).to eq 'def my_method; end'
33
+ end
28
34
  end
29
35
  end
@@ -1,11 +1,11 @@
1
1
  require_relative '../../spec_helper'
2
- require_relative '../../../lib/reek/source/sexp_node'
2
+ require_relative '../../../lib/reek/sexp/sexp_node'
3
3
 
4
- describe Reek::Source::SexpNode do
4
+ RSpec.describe Reek::Sexp::SexpNode do
5
5
  context 'format' do
6
6
  it 'formats self' do
7
7
  @node = s(:self)
8
- expect(@node.format_ruby).to eq('self')
8
+ expect(@node.format_to_ruby).to eq('self')
9
9
  end
10
10
  end
11
11
 
@@ -1,118 +1,122 @@
1
1
  require_relative '../../spec_helper'
2
2
  require_relative '../../../lib/reek/smells/attribute'
3
- require_relative '../../../lib/reek/core/module_context'
4
3
  require_relative 'smell_detector_shared'
5
4
 
6
- describe Reek::Smells::Attribute do
7
- before :each do
5
+ RSpec.describe Reek::Smells::Attribute do
6
+ let(:config) do
7
+ {
8
+ Attribute: { Reek::Core::SmellConfiguration::ENABLED_KEY => true }
9
+ }
10
+ end
11
+
12
+ before(:each) do
8
13
  @source_name = 'dummy_source'
9
14
  @detector = build(:smell_detector, smell_type: :Attribute, source: @source_name)
10
15
  end
11
16
 
17
+ around(:each) do |example|
18
+ with_test_config(config) do
19
+ example.run
20
+ end
21
+ end
22
+
12
23
  it_should_behave_like 'SmellDetector'
13
24
 
14
25
  context 'with no attributes' do
15
- it 'records nothing in the module' do
16
- src = 'module Fred; end'
17
- ctx = Reek::Core::CodeContext.new(nil, Reek::Source::SourceCode.from(src).syntax_tree)
18
- expect(@detector.examine_context(ctx)).to be_empty
26
+ it 'records nothing' do
27
+ expect('
28
+ class Klass
29
+ end
30
+ ').to_not reek_of(:Attribute)
19
31
  end
20
32
  end
21
33
 
22
- context 'with one attribute' do
23
- before :each do
24
- @attr_name = 'super_thing'
25
- end
26
-
27
- shared_examples_for 'one attribute found' do
28
- before :each do
29
- ctx = Reek::Core::CodeContext.new(nil, Reek::Source::SourceCode.from(@src).syntax_tree)
30
- @smells = @detector.examine_context(ctx)
31
- end
32
-
33
- it 'records only that attribute' do
34
- expect(@smells.length).to eq(1)
35
- end
36
-
37
- it 'reports the attribute name' do
38
- expect(@smells[0].parameters[:name]).to eq(@attr_name)
39
- end
40
-
41
- it 'reports the declaration line number' do
42
- expect(@smells[0].lines).to eq([1])
43
- end
44
-
45
- it 'reports the correct smell class' do
46
- expect(@smells[0].smell_category).to eq(described_class.smell_category)
47
- end
48
-
49
- it 'reports the context fq name' do
50
- expect(@smells[0].context).to eq('Fred')
51
- end
34
+ context 'with attributes' do
35
+ it 'records nothing' do
36
+ expect('
37
+ class Klass
38
+ attr :super_private, :super_private2
39
+ private :super_private, :super_private2
40
+ private
41
+ attr :super_thing
42
+ public
43
+ attr :super_thing2
44
+ private
45
+ attr :super_thing2
46
+ end
47
+ ').to_not reek_of(:Attribute)
52
48
  end
53
49
 
54
- context 'declared in a class' do
55
- before :each do
56
- @src = "class Fred; attr :#{@attr_name}; end"
57
- end
58
-
59
- it_should_behave_like 'one attribute found'
50
+ it 'records attr attribute in a module' do
51
+ expect('
52
+ module Mod
53
+ attr :my_attr
54
+ end
55
+ ').to reek_of(:Attribute, name: 'my_attr')
60
56
  end
61
57
 
62
- context 'reader in a class' do
63
- before :each do
64
- @src = "class Fred; attr_reader :#{@attr_name}; end"
65
- end
66
-
67
- it_should_behave_like 'one attribute found'
58
+ it 'records attr attribute' do
59
+ expect('
60
+ class Klass
61
+ attr :my_attr
62
+ end
63
+ ').to reek_of(:Attribute, name: 'my_attr')
68
64
  end
69
65
 
70
- context 'writer in a class' do
71
- before :each do
72
- @src = "class Fred; attr_writer :#{@attr_name}; end"
73
- end
74
-
75
- it_should_behave_like 'one attribute found'
66
+ it 'records reader attribute' do
67
+ expect('
68
+ class Klass
69
+ attr_reader :my_attr
70
+ end
71
+ ').to reek_of(:Attribute, name: 'my_attr')
76
72
  end
77
73
 
78
- context 'accessor in a class' do
79
- before :each do
80
- @src = "class Fred; attr_accessor :#{@attr_name}; end"
81
- end
82
-
83
- it_should_behave_like 'one attribute found'
74
+ it 'records writer attribute' do
75
+ expect('
76
+ class Klass
77
+ attr_writer :my_attr
78
+ end
79
+ ').to reek_of(:Attribute, name: 'my_attr')
84
80
  end
85
81
 
86
- context 'declared in a module' do
87
- before :each do
88
- @src = "module Fred; attr :#{@attr_name}; end"
89
- end
90
-
91
- it_should_behave_like 'one attribute found'
82
+ it 'records accessor attribute' do
83
+ expect('
84
+ class Klass
85
+ attr_accessor :my_attr
86
+ end
87
+ ').to reek_of(:Attribute, name: 'my_attr')
92
88
  end
93
89
 
94
- context 'reader in a module' do
95
- before :each do
96
- @src = "module Fred; attr_reader :#{@attr_name}; end"
97
- end
98
-
99
- it_should_behave_like 'one attribute found'
90
+ it 'records attr attribute after switching visbility' do
91
+ expect('
92
+ class Klass
93
+ private
94
+ attr :my_attr
95
+ public :my_attr
96
+ private :my_attr
97
+ public :my_attr
98
+ end
99
+ ').to reek_of(:Attribute, name: 'my_attr')
100
100
  end
101
101
 
102
- context 'writer in a module' do
103
- before :each do
104
- @src = "module Fred; attr_writer :#{@attr_name}; end"
105
- end
106
-
107
- it_should_behave_like 'one attribute found'
102
+ it "doesn't record protected attributes" do
103
+ src = '
104
+ class Klass
105
+ protected
106
+ attr :iam_protected
107
+ end
108
+ '
109
+ expect(src).to_not reek_of(:Attribute, name: 'iam_protected')
108
110
  end
109
111
 
110
- context 'accessor in a module' do
111
- before :each do
112
- @src = "module Fred; attr_accessor :#{@attr_name}; end"
113
- end
114
-
115
- it_should_behave_like 'one attribute found'
112
+ it "doesn't record private attributes" do
113
+ src = '
114
+ class Klass
115
+ private
116
+ attr :iam_private
117
+ end
118
+ '
119
+ expect(src).to_not reek_of(:Attribute, name: 'iam_private')
116
120
  end
117
121
  end
118
122
  end