reek 2.1.0 → 2.2.0

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.
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