reek 5.4.1 → 6.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +8 -6
  4. data/.rubocop_todo.yml +25 -20
  5. data/.simplecov +1 -0
  6. data/.travis.yml +17 -11
  7. data/CHANGELOG.md +31 -3
  8. data/Dockerfile +1 -0
  9. data/Gemfile +14 -17
  10. data/README.md +15 -11
  11. data/bin/code_climate_reek +12 -2
  12. data/docs/Attribute.md +1 -1
  13. data/docs/Boolean-Parameter.md +1 -1
  14. data/docs/Control-Couple.md +1 -1
  15. data/docs/Nil-Check.md +4 -1
  16. data/features/command_line_interface/options.feature +2 -3
  17. data/features/configuration_files/schema_validation.feature +1 -1
  18. data/features/reports/codeclimate.feature +2 -2
  19. data/features/reports/json.feature +3 -3
  20. data/features/reports/reports.feature +4 -4
  21. data/features/reports/yaml.feature +3 -3
  22. data/features/step_definitions/reek_steps.rb +5 -1
  23. data/features/step_definitions/sample_file_steps.rb +2 -2
  24. data/features/support/env.rb +1 -2
  25. data/lib/reek.rb +1 -0
  26. data/lib/reek/ast/sexp_extensions/arguments.rb +11 -0
  27. data/lib/reek/cli/options.rb +3 -3
  28. data/lib/reek/code_comment.rb +45 -38
  29. data/lib/reek/configuration/app_configuration.rb +4 -3
  30. data/lib/reek/configuration/configuration_converter.rb +2 -2
  31. data/lib/reek/configuration/directory_directives.rb +9 -3
  32. data/lib/reek/context/module_context.rb +3 -1
  33. data/lib/reek/errors/legacy_comment_separator_error.rb +36 -0
  34. data/lib/reek/examiner.rb +3 -3
  35. data/lib/reek/report.rb +5 -7
  36. data/lib/reek/report/code_climate/code_climate_configuration.yml +1 -1
  37. data/lib/reek/report/code_climate/code_climate_report.rb +2 -1
  38. data/lib/reek/report/simple_warning_formatter.rb +0 -7
  39. data/lib/reek/report/text_report.rb +2 -2
  40. data/lib/reek/smell_detectors/base_detector.rb +1 -9
  41. data/lib/reek/smell_detectors/boolean_parameter.rb +3 -1
  42. data/lib/reek/smell_detectors/data_clump.rb +23 -56
  43. data/lib/reek/smell_detectors/nil_check.rb +1 -12
  44. data/lib/reek/smell_detectors/subclassed_from_core_class.rb +3 -7
  45. data/lib/reek/smell_detectors/uncommunicative_variable_name.rb +1 -1
  46. data/lib/reek/smell_warning.rb +1 -2
  47. data/lib/reek/source/source_code.rb +3 -2
  48. data/lib/reek/source/source_locator.rb +13 -10
  49. data/lib/reek/spec/smell_matcher.rb +2 -1
  50. data/lib/reek/version.rb +1 -1
  51. data/reek.gemspec +13 -6
  52. data/spec/performance/reek/smell_detectors/runtime_speed_spec.rb +2 -4
  53. data/spec/quality/documentation_spec.rb +2 -1
  54. data/spec/reek/ast/sexp_extensions_spec.rb +15 -33
  55. data/spec/reek/code_comment_spec.rb +41 -42
  56. data/spec/reek/configuration/directory_directives_spec.rb +6 -0
  57. data/spec/reek/context_builder_spec.rb +110 -113
  58. data/spec/reek/report/code_climate/code_climate_configuration_spec.rb +1 -3
  59. data/spec/reek/report/code_climate/code_climate_fingerprint_spec.rb +26 -26
  60. data/spec/reek/report/code_climate/code_climate_formatter_spec.rb +6 -6
  61. data/spec/reek/report/code_climate/code_climate_report_spec.rb +1 -1
  62. data/spec/reek/report/json_report_spec.rb +1 -1
  63. data/spec/reek/report/location_formatter_spec.rb +3 -3
  64. data/spec/reek/report/text_report_spec.rb +1 -7
  65. data/spec/reek/report/yaml_report_spec.rb +1 -1
  66. data/spec/reek/smell_detectors/base_detector_spec.rb +3 -13
  67. data/spec/reek/smell_detectors/data_clump_spec.rb +14 -0
  68. data/spec/reek/smell_detectors/missing_safe_method_spec.rb +8 -2
  69. data/spec/reek/smell_detectors/nil_check_spec.rb +3 -3
  70. data/spec/reek/smell_warning_spec.rb +12 -12
  71. data/spec/reek/source/source_code_spec.rb +13 -0
  72. data/spec/reek/spec/should_reek_of_spec.rb +0 -1
  73. data/spec/reek/spec/should_reek_only_of_spec.rb +6 -6
  74. data/spec/reek/spec/smell_matcher_spec.rb +1 -1
  75. data/spec/spec_helper.rb +20 -6
  76. data/tasks/configuration.rake +1 -2
  77. metadata +15 -25
  78. data/spec/factories/factories.rb +0 -37
@@ -443,73 +443,55 @@ end
443
443
 
444
444
  RSpec.describe Reek::AST::SexpExtensions::CasgnNode do
445
445
  describe '#defines_module?' do
446
- context 'with single assignment' do
447
- it 'does not define a module' do
448
- exp = sexp(:casgn, nil, :Foo)
449
- expect(exp).not_to be_defines_module
450
- end
446
+ it 'is false for single assignment' do
447
+ exp = sexp(:casgn, nil, :Foo)
448
+ expect(exp).not_to be_defines_module
451
449
  end
452
450
 
453
- context 'with implicit receiver to new' do
454
- it 'does not define a module' do
455
- exp = sexp(:casgn, nil, :Foo, sexp(:send, nil, :new))
456
- expect(exp).not_to be_defines_module
457
- end
451
+ it 'is false for implicit receiver to new' do
452
+ exp = sexp(:casgn, nil, :Foo, sexp(:send, nil, :new))
453
+ expect(exp).not_to be_defines_module
458
454
  end
459
455
 
460
- context 'with implicit receiver to new' do
461
- it 'does not define a module' do
462
- exp = Reek::Source::SourceCode.from('Foo = Class.new(Bar)').syntax_tree
463
-
464
- expect(exp).to be_defines_module
465
- end
456
+ it 'is true for explicit receiver to new' do
457
+ exp = Reek::Source::SourceCode.from('Foo = Class.new(Bar)').syntax_tree
458
+ expect(exp).to be_defines_module
466
459
  end
467
460
 
468
- context 'when assigning a lambda to a constant' do
469
- it 'does not define a module' do
470
- exp = Reek::Source::SourceCode.from('C = ->{}').syntax_tree
471
-
472
- expect(exp).not_to be_defines_module
473
- end
461
+ it 'is false for assigning a lambda to a constant' do
462
+ exp = Reek::Source::SourceCode.from('C = ->{}').syntax_tree
463
+ expect(exp).not_to be_defines_module
474
464
  end
475
465
 
476
- context 'when assigning a string to a constant' do
477
- it 'does not define a module' do
478
- exp = Reek::Source::SourceCode.from('C = "hello"').syntax_tree
479
-
480
- expect(exp).not_to be_defines_module
481
- end
466
+ it 'is false for assigning a string to a constant' do
467
+ exp = Reek::Source::SourceCode.from('C = "hello"').syntax_tree
468
+ expect(exp).not_to be_defines_module
482
469
  end
483
470
  end
484
471
 
485
472
  describe '#superclass' do
486
473
  it 'returns the superclass from the class definition' do
487
474
  exp = Reek::Source::SourceCode.from('Foo = Class.new(Bar)').syntax_tree
488
-
489
475
  expect(exp.superclass).to eq sexp(:const, nil, :Bar)
490
476
  end
491
477
 
492
478
  it 'returns nil in case of no class definition' do
493
479
  exp = Reek::Source::SourceCode.from('Foo = 23').syntax_tree
494
-
495
480
  expect(exp.superclass).to be_nil
496
481
  end
497
482
 
498
483
  it 'returns nil in case of no superclass' do
499
484
  exp = Reek::Source::SourceCode.from('Foo = Class.new').syntax_tree
500
-
501
485
  expect(exp.superclass).to be_nil
502
486
  end
503
487
 
504
488
  it 'returns nothing for a class definition using Struct.new' do
505
489
  exp = Reek::Source::SourceCode.from('Foo = Struct.new("Bar")').syntax_tree
506
-
507
490
  expect(exp.superclass).to be_nil
508
491
  end
509
492
 
510
493
  it 'returns nothing for a constant assigned with a bare method call' do
511
494
  exp = Reek::Source::SourceCode.from('Foo = foo("Bar")').syntax_tree
512
-
513
495
  expect(exp.superclass).to be_nil
514
496
  end
515
497
  end
@@ -3,7 +3,7 @@ require_lib 'reek/code_comment'
3
3
 
4
4
  RSpec.describe Reek::CodeComment do
5
5
  context 'with an empty comment' do
6
- let(:comment) { build(:code_comment, comment: '') }
6
+ let(:comment) { build_code_comment(comment: '') }
7
7
 
8
8
  it 'is not descriptive' do
9
9
  expect(comment).not_to be_descriptive
@@ -16,77 +16,63 @@ RSpec.describe Reek::CodeComment do
16
16
 
17
17
  describe '#descriptive' do
18
18
  it 'rejects an empty comment' do
19
- comment = build(:code_comment, comment: '#')
19
+ comment = build_code_comment(comment: '#')
20
20
  expect(comment).not_to be_descriptive
21
21
  end
22
22
 
23
23
  it 'rejects a 1-word comment' do
24
- comment = build(:code_comment, comment: "# alpha\n# ")
24
+ comment = build_code_comment(comment: "# alpha\n# ")
25
25
  expect(comment).not_to be_descriptive
26
26
  end
27
27
 
28
28
  it 'accepts a 2-word comment' do
29
- comment = build(:code_comment, comment: '# alpha bravo ')
29
+ comment = build_code_comment(comment: '# alpha bravo ')
30
30
  expect(comment).to be_descriptive
31
31
  end
32
32
 
33
33
  it 'accepts a multi-word comment' do
34
- comment = build(:code_comment, comment: "# alpha bravo \n# charlie \n # delta ")
34
+ comment = build_code_comment(comment: "# alpha bravo \n# charlie \n # delta ")
35
35
  expect(comment).to be_descriptive
36
36
  end
37
37
  end
38
38
 
39
39
  describe 'good comment config' do
40
40
  it 'parses hashed options' do
41
- comment = '# :reek:DuplicateMethodCall { enabled: false }'
42
- config = build(:code_comment,
43
- comment: comment).config
41
+ comment = '# :reek:DuplicateMethodCall { max_calls: 3 }'
42
+ config = build_code_comment(comment: comment).config
44
43
 
45
44
  expect(config).to include('DuplicateMethodCall')
46
- expect(config['DuplicateMethodCall']).to include('enabled')
47
- expect(config['DuplicateMethodCall']['enabled']).to be_falsey
48
- end
49
-
50
- it "supports hashed options with the legacy separator ':' after the smell detector" do
51
- comment = '# :reek:DuplicateMethodCall: { enabled: false }'
52
- config = build(:code_comment,
53
- comment: comment).config
54
-
55
- expect(config).to include('DuplicateMethodCall')
56
- expect(config['DuplicateMethodCall']).to include('enabled')
57
- expect(config['DuplicateMethodCall']['enabled']).to be_falsey
45
+ expect(config['DuplicateMethodCall']).to have_key 'max_calls'
46
+ expect(config['DuplicateMethodCall']['max_calls']).to eq 3
58
47
  end
59
48
 
60
49
  it 'parses multiple hashed options' do
61
50
  comment = <<-RUBY
62
- # :reek:DuplicateMethodCall { enabled: false }
51
+ # :reek:DuplicateMethodCall { max_calls: 3 }
63
52
  # :reek:NestedIterators { enabled: true }
64
53
  RUBY
65
- config = build(:code_comment, comment: comment).config
54
+ config = build_code_comment(comment: comment).config
66
55
 
67
56
  expect(config).to include('DuplicateMethodCall', 'NestedIterators')
68
- expect(config['DuplicateMethodCall']).to include('enabled')
69
- expect(config['DuplicateMethodCall']['enabled']).to be_falsey
70
- expect(config['NestedIterators']).to include('enabled')
57
+ expect(config['DuplicateMethodCall']['max_calls']).to eq 3
71
58
  expect(config['NestedIterators']['enabled']).to be_truthy
72
59
  end
73
60
 
74
61
  it 'parses multiple hashed options on the same line' do
75
62
  comment = <<-RUBY
76
- #:reek:DuplicateMethodCall { enabled: false } and :reek:NestedIterators { enabled: true }
63
+ #:reek:DuplicateMethodCall { max_calls: 3 } and :reek:NestedIterators { enabled: true }
77
64
  RUBY
78
- config = build(:code_comment, comment: comment).config
65
+ config = build_code_comment(comment: comment).config
79
66
 
80
67
  expect(config).to include('DuplicateMethodCall', 'NestedIterators')
81
- expect(config['DuplicateMethodCall']).to include('enabled')
82
- expect(config['DuplicateMethodCall']['enabled']).to be_falsey
68
+ expect(config['DuplicateMethodCall']['max_calls']).to eq 3
83
69
  expect(config['NestedIterators']).to include('enabled')
84
70
  expect(config['NestedIterators']['enabled']).to be_truthy
85
71
  end
86
72
 
87
73
  it 'parses multiple unhashed options on the same line' do
88
74
  comment = '# :reek:DuplicateMethodCall and :reek:NestedIterators'
89
- config = build(:code_comment, comment: comment).config
75
+ config = build_code_comment(comment: comment).config
90
76
 
91
77
  expect(config).to include('DuplicateMethodCall', 'NestedIterators')
92
78
  expect(config['DuplicateMethodCall']).to include('enabled')
@@ -97,27 +83,33 @@ RSpec.describe Reek::CodeComment do
97
83
 
98
84
  it 'disables the smell if no options are specifed' do
99
85
  comment = '# :reek:DuplicateMethodCall'
100
- config = build(:code_comment, comment: comment).config
86
+ config = build_code_comment(comment: comment).config
101
87
 
102
88
  expect(config).to include('DuplicateMethodCall')
103
89
  expect(config['DuplicateMethodCall']).to include('enabled')
104
90
  expect(config['DuplicateMethodCall']['enabled']).to be_falsey
105
91
  end
106
92
 
93
+ it 'does not disable the smell if options are specifed' do
94
+ comment = '# :reek:DuplicateMethodCall { max_calls: 3 }'
95
+ config = build_code_comment(comment: comment).config
96
+
97
+ expect(config['DuplicateMethodCall']).not_to include('enabled')
98
+ end
99
+
107
100
  it 'ignores smells after a space' do
108
- config = build(:code_comment,
109
- comment: '# :reek: DuplicateMethodCall').config
101
+ config = build_code_comment(comment: '# :reek: DuplicateMethodCall').config
110
102
  expect(config).not_to include('DuplicateMethodCall')
111
103
  end
112
104
 
113
105
  it 'removes the configuration options from the comment' do
114
106
  original_comment = <<-RUBY
115
107
  # Actual
116
- # :reek:DuplicateMethodCall { enabled: false }
108
+ # :reek:DuplicateMethodCall { max_calls: 3 }
117
109
  # :reek:NestedIterators { enabled: true }
118
110
  # comment
119
111
  RUBY
120
- comment = build(:code_comment, comment: original_comment)
112
+ comment = build_code_comment(comment: original_comment)
121
113
 
122
114
  expect(comment.send(:sanitized_comment)).to eq('Actual comment')
123
115
  end
@@ -128,8 +120,7 @@ RSpec.describe Reek::CodeComment::CodeCommentValidator do
128
120
  context 'when the comment contains an unknown detector name' do
129
121
  it 'raises BadDetectorInCommentError' do
130
122
  expect do
131
- build(:code_comment,
132
- comment: '# :reek:DoesNotExist')
123
+ build_code_comment(comment: '# :reek:DoesNotExist')
133
124
  end.to raise_error(Reek::Errors::BadDetectorInCommentError)
134
125
  end
135
126
  end
@@ -138,18 +129,26 @@ RSpec.describe Reek::CodeComment::CodeCommentValidator do
138
129
  it 'raises GarbageDetectorConfigurationInCommentError' do
139
130
  expect do
140
131
  comment = '# :reek:UncommunicativeMethodName { thats: a: bad: config }'
141
- build(:code_comment, comment: comment)
132
+ build_code_comment(comment: comment)
142
133
  end.to raise_error(Reek::Errors::GarbageDetectorConfigurationInCommentError)
143
134
  end
144
135
  end
145
136
 
137
+ context 'when the legacy comment format was used' do
138
+ it 'raises LegacyCommentSeparatorError' do
139
+ comment = '# :reek:DuplicateMethodCall:'
140
+ expect { build_code_comment(comment: comment) }.
141
+ to raise_error Reek::Errors::LegacyCommentSeparatorError
142
+ end
143
+ end
144
+
146
145
  describe 'validating configuration keys' do
147
146
  context 'when basic options are mispelled' do
148
147
  it 'raises BadDetectorConfigurationKeyInCommentError' do
149
148
  expect do
150
149
  # exclude -> exlude and enabled -> nabled
151
150
  comment = '# :reek:UncommunicativeMethodName { exlude: alfa, nabled: true }'
152
- build(:code_comment, comment: comment)
151
+ build_code_comment(comment: comment)
153
152
  end.to raise_error(Reek::Errors::BadDetectorConfigurationKeyInCommentError)
154
153
  end
155
154
  end
@@ -158,7 +157,7 @@ RSpec.describe Reek::CodeComment::CodeCommentValidator do
158
157
  it 'does not raise' do
159
158
  expect do
160
159
  comment = '# :reek:UncommunicativeMethodName { exclude: alfa, enabled: true }'
161
- build(:code_comment, comment: comment)
160
+ build_code_comment(comment: comment)
162
161
  end.not_to raise_error
163
162
  end
164
163
  end
@@ -168,7 +167,7 @@ RSpec.describe Reek::CodeComment::CodeCommentValidator do
168
167
  expect do
169
168
  # max_copies -> mx_copies and min_clump_size -> mn_clump_size
170
169
  comment = '# :reek:DataClump { mx_copies: 4, mn_clump_size: 3 }'
171
- build(:code_comment, comment: comment)
170
+ build_code_comment(comment: comment)
172
171
  end.to raise_error(Reek::Errors::BadDetectorConfigurationKeyInCommentError)
173
172
  end
174
173
  end
@@ -177,7 +176,7 @@ RSpec.describe Reek::CodeComment::CodeCommentValidator do
177
176
  it 'does not raise' do
178
177
  expect do
179
178
  comment = '# :reek:DataClump { max_copies: 4, min_clump_size: 3 }'
180
- build(:code_comment, comment: comment)
179
+ build_code_comment(comment: comment)
181
180
  end.not_to raise_error
182
181
  end
183
182
  end
@@ -89,6 +89,12 @@ RSpec.describe Reek::Configuration::DirectoryDirectives do
89
89
  expect(hit.to_s).to eq('bar/**/.spec/*')
90
90
  end
91
91
 
92
+ it 'returns the corresponding directory when source_base_dir is an absolute_path' do
93
+ source_base_dir = Pathname.new('foo/bar').expand_path
94
+ hit = directives.send :best_match_for, source_base_dir
95
+ expect(hit.to_s).to eq('foo/bar')
96
+ end
97
+
92
98
  it 'does not match an arbitrary directory when source_base_dir contains a character that could match the .' do
93
99
  source_base_dir = 'bar/something/aspec/direct'
94
100
  hit = directives.send :best_match_for, source_base_dir
@@ -3,42 +3,126 @@ require_lib 'reek/context_builder'
3
3
 
4
4
  RSpec.describe Reek::ContextBuilder do
5
5
  describe '#context_tree' do
6
- let(:walker) do
7
- code = 'class Car; def drive; end; end'
8
- described_class.new(syntax_tree(code))
6
+ context 'with some simple example code' do
7
+ let(:walker) do
8
+ code = 'class Car; def drive; end; end'
9
+ described_class.new(syntax_tree(code))
10
+ end
11
+ let(:context_tree) { walker.context_tree }
12
+ let(:module_context) { context_tree.children.first }
13
+ let(:method_context) { module_context.children.first }
14
+
15
+ describe 'the starting node' do
16
+ it 'is a root node' do
17
+ expect(context_tree.type).to eq(:root)
18
+ expect(context_tree).to be_a(Reek::Context::RootContext)
19
+ end
20
+
21
+ it 'has one module_context child' do
22
+ aggregate_failures do
23
+ expect(context_tree.children.count).to eq 1
24
+ expect(module_context).to be_a(Reek::Context::ModuleContext)
25
+ end
26
+ end
27
+ end
28
+
29
+ describe 'the module node' do
30
+ it 'has one method_context child' do
31
+ aggregate_failures do
32
+ expect(method_context).to be_a(Reek::Context::MethodContext)
33
+ expect(module_context.children.size).to eq(1)
34
+ end
35
+ end
36
+
37
+ it 'holds a reference to the parent context' do
38
+ expect(method_context.parent).to eq(module_context)
39
+ end
40
+ end
9
41
  end
10
- let(:context_tree) { walker.context_tree }
11
- let(:module_context) { context_tree.children.first }
12
- let(:method_context) { module_context.children.first }
13
42
 
14
- it 'starts with a root node' do
15
- expect(context_tree.type).to eq(:root)
16
- expect(context_tree).to be_a(Reek::Context::RootContext)
43
+ it 'creates the proper context for all kinds of singleton methods' do
44
+ src = <<-RUBY
45
+ class Car
46
+ def self.start; end
47
+
48
+ class << self
49
+ def drive; end
50
+ end
51
+ end
52
+ RUBY
53
+
54
+ syntax_tree = Reek::Source::SourceCode.from(src).syntax_tree
55
+ context_tree = described_class.new(syntax_tree).context_tree
56
+
57
+ class_node = context_tree.children.first
58
+ start_method = class_node.children.first
59
+ drive_method = class_node.children.last
60
+
61
+ expect(start_method).to be_instance_of Reek::Context::SingletonMethodContext
62
+ expect(drive_method).to be_instance_of Reek::Context::SingletonMethodContext
17
63
  end
18
64
 
19
- it 'has one child' do
20
- expect(context_tree.children.size).to eq(1)
65
+ it 'returns something sensible for nested metaclasses' do
66
+ src = <<-RUBY
67
+ class Foo
68
+ class << self
69
+ class << self
70
+ def bar; end
71
+ end
72
+ end
73
+ end
74
+ RUBY
75
+
76
+ syntax_tree = Reek::Source::SourceCode.from(src).syntax_tree
77
+ context_tree = described_class.new(syntax_tree).context_tree
78
+
79
+ class_context = context_tree.children.first
80
+ method_context = class_context.children.first
81
+
82
+ expect(method_context).to be_instance_of Reek::Context::SingletonMethodContext
83
+ expect(method_context.parent).to eq class_context
21
84
  end
22
85
 
23
- describe 'the root node' do
24
- it 'has one module_context' do
25
- expect(module_context).to be_a(Reek::Context::ModuleContext)
26
- end
86
+ it 'returns something sensible for nested method definitions' do
87
+ src = <<-RUBY
88
+ class Foo
89
+ def foo
90
+ def bar
91
+ end
92
+ end
93
+ end
94
+ RUBY
27
95
 
28
- it 'holds a reference to the parent context' do
29
- expect(module_context.parent).to eq(context_tree)
30
- end
96
+ syntax_tree = Reek::Source::SourceCode.from(src).syntax_tree
97
+ context_tree = described_class.new(syntax_tree).context_tree
98
+
99
+ class_context = context_tree.children.first
100
+ foo_context = class_context.children.first
101
+
102
+ bar_context = foo_context.children.first
103
+ expect(bar_context).to be_instance_of Reek::Context::MethodContext
104
+ expect(bar_context.parent).to eq foo_context
31
105
  end
32
106
 
33
- describe 'the module node' do
34
- it 'has one method_context' do
35
- expect(method_context).to be_a(Reek::Context::MethodContext)
36
- expect(module_context.children.size).to eq(1)
37
- end
107
+ it 'returns something sensible for method definitions nested in singleton methods' do
108
+ src = <<-RUBY
109
+ class Foo
110
+ def self.foo
111
+ def bar
112
+ end
113
+ end
114
+ end
115
+ RUBY
38
116
 
39
- it 'holds a reference to the parent context' do
40
- expect(method_context.parent).to eq(module_context)
41
- end
117
+ syntax_tree = Reek::Source::SourceCode.from(src).syntax_tree
118
+ context_tree = described_class.new(syntax_tree).context_tree
119
+
120
+ class_context = context_tree.children.first
121
+ foo_context = class_context.children.first
122
+
123
+ bar_context = foo_context.children.first
124
+ expect(bar_context).to be_instance_of Reek::Context::SingletonMethodContext
125
+ expect(bar_context.parent).to eq foo_context
42
126
  end
43
127
  end
44
128
 
@@ -370,91 +454,4 @@ RSpec.describe Reek::ContextBuilder do
370
454
  expect(nested_baz_context.visibility).to eq :public
371
455
  end
372
456
  end
373
-
374
- describe '#context_tree' do
375
- it 'creates the proper context for all kinds of singleton methods' do
376
- src = <<-RUBY
377
- class Car
378
- def self.start; end
379
-
380
- class << self
381
- def drive; end
382
- end
383
- end
384
- RUBY
385
-
386
- syntax_tree = Reek::Source::SourceCode.from(src).syntax_tree
387
- context_tree = described_class.new(syntax_tree).context_tree
388
-
389
- class_node = context_tree.children.first
390
- start_method = class_node.children.first
391
- drive_method = class_node.children.last
392
-
393
- expect(start_method).to be_instance_of Reek::Context::SingletonMethodContext
394
- expect(drive_method).to be_instance_of Reek::Context::SingletonMethodContext
395
- end
396
-
397
- it 'returns something sensible for nested metaclasses' do
398
- src = <<-RUBY
399
- class Foo
400
- class << self
401
- class << self
402
- def bar; end
403
- end
404
- end
405
- end
406
- RUBY
407
-
408
- syntax_tree = Reek::Source::SourceCode.from(src).syntax_tree
409
- context_tree = described_class.new(syntax_tree).context_tree
410
-
411
- class_context = context_tree.children.first
412
- method_context = class_context.children.first
413
-
414
- expect(method_context).to be_instance_of Reek::Context::SingletonMethodContext
415
- expect(method_context.parent).to eq class_context
416
- end
417
-
418
- it 'returns something sensible for nested method definitions' do
419
- src = <<-RUBY
420
- class Foo
421
- def foo
422
- def bar
423
- end
424
- end
425
- end
426
- RUBY
427
-
428
- syntax_tree = Reek::Source::SourceCode.from(src).syntax_tree
429
- context_tree = described_class.new(syntax_tree).context_tree
430
-
431
- class_context = context_tree.children.first
432
- foo_context = class_context.children.first
433
-
434
- bar_context = foo_context.children.first
435
- expect(bar_context).to be_instance_of Reek::Context::MethodContext
436
- expect(bar_context.parent).to eq foo_context
437
- end
438
-
439
- it 'returns something sensible for method definitions nested in singleton methods' do
440
- src = <<-RUBY
441
- class Foo
442
- def self.foo
443
- def bar
444
- end
445
- end
446
- end
447
- RUBY
448
-
449
- syntax_tree = Reek::Source::SourceCode.from(src).syntax_tree
450
- context_tree = described_class.new(syntax_tree).context_tree
451
-
452
- class_context = context_tree.children.first
453
- foo_context = class_context.children.first
454
-
455
- bar_context = foo_context.children.first
456
- expect(bar_context).to be_instance_of Reek::Context::SingletonMethodContext
457
- expect(bar_context.parent).to eq foo_context
458
- end
459
- end
460
457
  end