reek 4.7.3 → 5.0.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.
- checksums.yaml +4 -4
- data/.codeclimate.yml +17 -12
- data/.rubocop.yml +18 -3
- data/.simplecov +1 -0
- data/.travis.yml +3 -4
- data/.yardopts +1 -1
- data/CHANGELOG.md +45 -0
- data/Gemfile +4 -4
- data/README.md +134 -104
- data/Rakefile +16 -3
- data/bin/reek +1 -3
- data/docs/API.md +2 -9
- data/docs/Basic-Smell-Options.md +51 -11
- data/docs/Code-Smells.md +1 -1
- data/docs/Command-Line-Options.md +14 -4
- data/docs/Duplicate-Method-Call.md +49 -1
- data/docs/Feature-Envy.md +44 -0
- data/docs/How-To-Write-New-Detectors.md +2 -3
- data/docs/Instance-Variable-Assumption.md +1 -1
- data/docs/{Prima-Donna-Method.md → Missing-Safe-Method.md} +11 -9
- data/docs/Rake-Task.md +1 -1
- data/docs/Reek-4-to-Reek-5-migration.md +193 -0
- data/docs/Reek-Driven-Development.md +1 -1
- data/docs/Uncommunicative-Method-Name.md +45 -6
- data/docs/Uncommunicative-Module-Name.md +49 -7
- data/docs/Uncommunicative-Parameter-Name.md +43 -5
- data/docs/Uncommunicative-Variable-Name.md +73 -2
- data/docs/Unused-Private-Method.md +2 -2
- data/docs/defaults.reek.yml +129 -0
- data/docs/yard_plugin.rb +1 -0
- data/features/command_line_interface/basic_usage.feature +2 -2
- data/features/command_line_interface/options.feature +46 -4
- data/features/command_line_interface/show_progress.feature +4 -4
- data/features/command_line_interface/smell_selection.feature +1 -1
- data/features/command_line_interface/smells_count.feature +6 -6
- data/features/command_line_interface/stdin.feature +30 -8
- data/features/configuration_files/accept_setting.feature +45 -28
- data/features/configuration_files/directory_specific_directives.feature +78 -73
- data/features/configuration_files/exclude_directives.feature +11 -10
- data/features/configuration_files/exclude_paths_directives.feature +4 -4
- data/features/configuration_files/masking_smells.feature +38 -9
- data/features/configuration_files/mix_accept_reject_setting.feature +31 -28
- data/features/configuration_files/reject_setting.feature +52 -41
- data/features/configuration_files/schema_validation.feature +59 -0
- data/features/configuration_files/unused_private_method.feature +18 -16
- data/features/configuration_loading.feature +53 -10
- data/features/configuration_via_source_comments/erroneous_source_comments.feature +2 -2
- data/features/configuration_via_source_comments/well_formed_source_comments.feature +2 -2
- data/features/locales.feature +2 -2
- data/features/rake_task/rake_task.feature +15 -15
- data/features/reports/json.feature +3 -3
- data/features/reports/reports.feature +34 -34
- data/features/reports/yaml.feature +3 -3
- data/features/rspec_matcher.feature +9 -1
- data/features/samples.feature +287 -287
- data/features/step_definitions/reek_steps.rb +4 -0
- data/features/step_definitions/sample_file_steps.rb +9 -4
- data/features/support/env.rb +2 -2
- data/features/todo_list.feature +26 -23
- data/lib/reek/ast/node.rb +40 -55
- data/lib/reek/ast/object_refs.rb +1 -1
- data/lib/reek/ast/reference_collector.rb +2 -4
- data/lib/reek/ast/sexp_extensions/case.rb +1 -1
- data/lib/reek/ast/sexp_extensions/if.rb +8 -1
- data/lib/reek/ast/sexp_extensions/logical_operators.rb +1 -1
- data/lib/reek/ast/sexp_extensions/methods.rb +4 -6
- data/lib/reek/cli/application.rb +4 -3
- data/lib/reek/cli/command/report_command.rb +1 -2
- data/lib/reek/cli/command/todo_list_command.rb +8 -8
- data/lib/reek/cli/options.rb +29 -14
- data/lib/reek/cli/silencer.rb +14 -3
- data/lib/reek/code_comment.rb +14 -16
- data/lib/reek/configuration/app_configuration.rb +32 -28
- data/lib/reek/configuration/configuration_converter.rb +110 -0
- data/lib/reek/configuration/configuration_file_finder.rb +15 -40
- data/lib/reek/configuration/configuration_validator.rb +12 -23
- data/lib/reek/configuration/default_directive.rb +17 -3
- data/lib/reek/configuration/directory_directives.rb +17 -11
- data/lib/reek/configuration/excluded_paths.rb +1 -1
- data/lib/reek/configuration/rake_task_converter.rb +29 -0
- data/lib/reek/configuration/schema.yml +210 -0
- data/lib/reek/configuration/schema_validator.rb +38 -0
- data/lib/reek/context/attribute_context.rb +1 -1
- data/lib/reek/context/code_context.rb +8 -11
- data/lib/reek/context/method_context.rb +7 -12
- data/lib/reek/context/module_context.rb +4 -4
- data/lib/reek/context_builder.rb +11 -11
- data/lib/reek/detector_repository.rb +6 -0
- data/lib/reek/documentation_link.rb +28 -0
- data/lib/reek/errors/bad_detector_configuration_key_in_comment_error.rb +13 -12
- data/lib/reek/errors/bad_detector_in_comment_error.rb +11 -10
- data/lib/reek/errors/base_error.rb +3 -0
- data/lib/reek/errors/config_file_error.rb +11 -0
- data/lib/reek/errors/encoding_error.rb +16 -11
- data/lib/reek/errors/garbage_detector_configuration_in_comment_error.rb +11 -10
- data/lib/reek/errors/incomprehensible_source_error.rb +20 -22
- data/lib/reek/errors/syntax_error.rb +41 -0
- data/lib/reek/examiner.rb +19 -25
- data/lib/reek/logging_error_handler.rb +7 -5
- data/lib/reek/rake/task.rb +3 -3
- data/lib/reek/report/base_report.rb +8 -12
- data/lib/reek/report/code_climate/code_climate_configuration.rb +1 -1
- data/lib/reek/report/code_climate/code_climate_configuration.yml +6 -10
- data/lib/reek/report/documentation_link_warning_formatter.rb +17 -0
- data/lib/reek/report/heading_formatter.rb +54 -0
- data/lib/reek/report/json_report.rb +1 -1
- data/lib/reek/report/location_formatter.rb +40 -0
- data/lib/reek/report/progress_formatter.rb +79 -0
- data/lib/reek/report/simple_warning_formatter.rb +34 -0
- data/lib/reek/report/text_report.rb +1 -2
- data/lib/reek/report/xml_report.rb +3 -3
- data/lib/reek/report/yaml_report.rb +1 -1
- data/lib/reek/report.rb +15 -10
- data/lib/reek/smell_configuration.rb +2 -2
- data/lib/reek/smell_detectors/attribute.rb +0 -1
- data/lib/reek/smell_detectors/base_detector.rb +9 -12
- data/lib/reek/smell_detectors/boolean_parameter.rb +0 -1
- data/lib/reek/smell_detectors/class_variable.rb +3 -11
- data/lib/reek/smell_detectors/control_parameter.rb +17 -32
- data/lib/reek/smell_detectors/data_clump.rb +3 -4
- data/lib/reek/smell_detectors/duplicate_method_call.rb +6 -7
- data/lib/reek/smell_detectors/feature_envy.rb +1 -1
- data/lib/reek/smell_detectors/instance_variable_assumption.rb +1 -10
- data/lib/reek/smell_detectors/irresponsible_module.rb +0 -1
- data/lib/reek/smell_detectors/long_parameter_list.rb +1 -2
- data/lib/reek/smell_detectors/long_yield_list.rb +2 -3
- data/lib/reek/smell_detectors/manual_dispatch.rb +3 -3
- data/lib/reek/smell_detectors/{prima_donna_method.rb → missing_safe_method.rb} +6 -7
- data/lib/reek/smell_detectors/module_initialize.rb +1 -2
- data/lib/reek/smell_detectors/nested_iterators.rb +6 -6
- data/lib/reek/smell_detectors/nil_check.rb +0 -1
- data/lib/reek/smell_detectors/repeated_conditional.rb +3 -4
- data/lib/reek/smell_detectors/subclassed_from_core_class.rb +0 -1
- data/lib/reek/smell_detectors/too_many_constants.rb +2 -3
- data/lib/reek/smell_detectors/too_many_instance_variables.rb +1 -2
- data/lib/reek/smell_detectors/too_many_methods.rb +1 -2
- data/lib/reek/smell_detectors/too_many_statements.rb +1 -2
- data/lib/reek/smell_detectors/uncommunicative_method_name.rb +2 -3
- data/lib/reek/smell_detectors/uncommunicative_module_name.rb +2 -3
- data/lib/reek/smell_detectors/uncommunicative_parameter_name.rb +2 -3
- data/lib/reek/smell_detectors/uncommunicative_variable_name.rb +6 -7
- data/lib/reek/smell_detectors/unused_parameters.rb +0 -1
- data/lib/reek/smell_detectors/unused_private_method.rb +0 -1
- data/lib/reek/smell_detectors/utility_function.rb +2 -3
- data/lib/reek/smell_detectors.rb +1 -2
- data/lib/reek/smell_warning.rb +15 -8
- data/lib/reek/source/source_code.rb +50 -72
- data/lib/reek/source/source_locator.rb +7 -7
- data/lib/reek/spec/should_reek.rb +2 -2
- data/lib/reek/spec/should_reek_of.rb +9 -16
- data/lib/reek/spec/should_reek_only_of.rb +4 -4
- data/lib/reek/spec.rb +6 -6
- data/lib/reek/tree_dresser.rb +5 -5
- data/lib/reek/version.rb +1 -1
- data/reek.gemspec +5 -5
- data/samples/checkstyle.xml +1 -1
- data/samples/configuration/accepts_rejects_and_excludes_for_detectors.reek.yml +29 -0
- data/samples/configuration/accepts_rejects_and_excludes_for_directory_directives.reek.yml +30 -0
- data/samples/configuration/full_configuration.reek +8 -4
- data/samples/configuration/full_mask.reek +5 -4
- data/samples/configuration/partial_mask.reek +3 -2
- data/samples/configuration/regular_configuration/.reek.yml +4 -0
- data/samples/paths.rb +5 -4
- data/samples/source_with_hidden_directories/.hidden/hidden.rb +1 -0
- data/samples/source_with_hidden_directories/not_hidden.rb +1 -0
- data/spec/factories/factories.rb +2 -13
- data/spec/reek/ast/node_spec.rb +103 -10
- data/spec/reek/ast/reference_collector_spec.rb +1 -1
- data/spec/reek/ast/sexp_extensions_spec.rb +2 -2
- data/spec/reek/cli/application_spec.rb +50 -38
- data/spec/reek/cli/command/todo_list_command_spec.rb +6 -4
- data/spec/reek/cli/silencer_spec.rb +28 -0
- data/spec/reek/code_comment_spec.rb +31 -38
- data/spec/reek/configuration/app_configuration_spec.rb +46 -33
- data/spec/reek/configuration/configuration_file_finder_spec.rb +133 -49
- data/spec/reek/configuration/default_directive_spec.rb +1 -1
- data/spec/reek/configuration/directory_directives_spec.rb +6 -7
- data/spec/reek/configuration/excluded_paths_spec.rb +6 -6
- data/spec/reek/configuration/rake_task_converter_spec.rb +33 -0
- data/spec/reek/configuration/schema_validator_spec.rb +165 -0
- data/spec/reek/context/code_context_spec.rb +60 -96
- data/spec/reek/context/ghost_context_spec.rb +1 -1
- data/spec/reek/context/root_context_spec.rb +1 -1
- data/spec/reek/documentation_link_spec.rb +20 -0
- data/spec/reek/errors/base_error_spec.rb +13 -0
- data/spec/reek/examiner_spec.rb +100 -30
- data/spec/reek/report/code_climate/code_climate_fingerprint_spec.rb +82 -80
- data/spec/reek/report/code_climate/code_climate_formatter_spec.rb +6 -6
- data/spec/reek/report/json_report_spec.rb +13 -46
- data/spec/reek/report/{formatter/location_formatter_spec.rb → location_formatter_spec.rb} +5 -5
- data/spec/reek/report/{formatter/progress_formatter_spec.rb → progress_formatter_spec.rb} +4 -4
- data/spec/reek/report/text_report_spec.rb +4 -4
- data/spec/reek/report/xml_report_spec.rb +3 -3
- data/spec/reek/report/yaml_report_spec.rb +9 -38
- data/spec/reek/report_spec.rb +3 -3
- data/spec/reek/smell_detectors/boolean_parameter_spec.rb +2 -2
- data/spec/reek/smell_detectors/class_variable_spec.rb +26 -32
- data/spec/reek/smell_detectors/control_parameter_spec.rb +34 -4
- data/spec/reek/smell_detectors/duplicate_method_call_spec.rb +3 -3
- data/spec/reek/smell_detectors/feature_envy_spec.rb +47 -2
- data/spec/reek/smell_detectors/{prima_donna_method_spec.rb → missing_safe_method_spec.rb} +9 -9
- data/spec/reek/smell_detectors/module_initialize_spec.rb +14 -0
- data/spec/reek/smell_detectors/nested_iterators_spec.rb +1 -1
- data/spec/reek/smell_detectors/too_many_constants_spec.rb +3 -3
- data/spec/reek/smell_detectors/too_many_instance_variables_spec.rb +1 -1
- data/spec/reek/smell_detectors/uncommunicative_method_name_spec.rb +6 -6
- data/spec/reek/smell_detectors/uncommunicative_module_name_spec.rb +6 -4
- data/spec/reek/smell_detectors/uncommunicative_parameter_name_spec.rb +6 -4
- data/spec/reek/smell_detectors/uncommunicative_variable_name_spec.rb +9 -9
- data/spec/reek/smell_detectors/unused_parameters_spec.rb +3 -3
- data/spec/reek/smell_detectors/unused_private_method_spec.rb +10 -10
- data/spec/reek/smell_detectors/utility_function_spec.rb +5 -5
- data/spec/reek/smell_warning_spec.rb +12 -8
- data/spec/reek/source/source_code_spec.rb +17 -43
- data/spec/reek/source/source_locator_spec.rb +17 -17
- data/spec/reek/spec/should_reek_of_spec.rb +7 -11
- data/spec/reek/spec/should_reek_only_of_spec.rb +2 -2
- data/spec/reek/spec/should_reek_spec.rb +3 -3
- data/spec/reek/spec/smell_matcher_spec.rb +3 -3
- data/spec/reek/tree_dresser_spec.rb +12 -17
- data/spec/spec_helper.rb +6 -17
- data/tasks/configuration.rake +8 -5
- metadata +71 -41
- data/defaults.reek +0 -131
- data/features/configuration_files/warn_about_multiple_configuration_files.feature +0 -44
- data/lib/reek/report/formatter/heading_formatter.rb +0 -52
- data/lib/reek/report/formatter/location_formatter.rb +0 -42
- data/lib/reek/report/formatter/progress_formatter.rb +0 -81
- data/lib/reek/report/formatter/simple_warning_formatter.rb +0 -35
- data/lib/reek/report/formatter/wiki_link_warning_formatter.rb +0 -36
- data/lib/reek/report/formatter.rb +0 -33
- data/lib/reek/smell_detectors/syntax.rb +0 -37
- data/samples/configuration/non_public_modifiers_mask.reek +0 -3
- data/samples/smelly_with_inline_mask.rb +0 -8
- data/samples/smelly_with_modifiers.rb +0 -12
- data/samples/source_with_hidden_directories/.hidden/uncommunicative_method_name.rb +0 -5
- data/samples/source_with_non_ruby_files/uncommunicative_parameter_name.rb +0 -6
- data/spec/reek/smell_detectors/syntax_spec.rb +0 -17
- /data/{samples/configuration/more_than_one_configuration_file/regular.reek → .reek.yml} +0 -0
- /data/samples/{clean.rb → clean_source/clean.rb} +0 -0
- /data/samples/{exceptions.reek → configuration/home/home.reek.yml} +0 -0
- /data/samples/configuration/{more_than_one_configuration_file/todo.reek → regular_configuration/empty_sub_directory/.gitignore} +0 -0
- /data/samples/{configuration/single_configuration_file/.reek → no_config_file/.keep} +0 -0
- /data/samples/{inline.rb → smelly_source/inline.rb} +0 -0
- /data/samples/{optparse.rb → smelly_source/optparse.rb} +0 -0
- /data/samples/{redcloth.rb → smelly_source/redcloth.rb} +0 -0
- /data/samples/{smelly.rb → smelly_source/smelly.rb} +0 -0
- /data/samples/{source_with_hidden_directories/uncommunicative_parameter_name.rb → source_with_non_ruby_files/ruby.rb} +0 -0
|
@@ -150,7 +150,7 @@ RSpec.describe Reek::SmellDetectors::DuplicateMethodCall do
|
|
|
150
150
|
end
|
|
151
151
|
end
|
|
152
152
|
|
|
153
|
-
context 'non-repeated method calls' do
|
|
153
|
+
context 'with non-repeated method calls' do
|
|
154
154
|
it 'does not report similar calls' do
|
|
155
155
|
src = 'def alfa(bravo) bravo.charlie == self.charlie end'
|
|
156
156
|
expect(src).not_to reek_of(:DuplicateMethodCall)
|
|
@@ -162,7 +162,7 @@ RSpec.describe Reek::SmellDetectors::DuplicateMethodCall do
|
|
|
162
162
|
end
|
|
163
163
|
end
|
|
164
164
|
|
|
165
|
-
context 'allowing up to 3 calls' do
|
|
165
|
+
context 'when allowing up to 3 calls' do
|
|
166
166
|
let(:config) do
|
|
167
167
|
{ Reek::SmellDetectors::DuplicateMethodCall::MAX_ALLOWED_CALLS_KEY => 3 }
|
|
168
168
|
end
|
|
@@ -189,7 +189,7 @@ RSpec.describe Reek::SmellDetectors::DuplicateMethodCall do
|
|
|
189
189
|
end
|
|
190
190
|
end
|
|
191
191
|
|
|
192
|
-
context 'allowing calls to some methods' do
|
|
192
|
+
context 'when allowing calls to some methods' do
|
|
193
193
|
it 'does not report calls to some methods' do
|
|
194
194
|
config = { Reek::SmellDetectors::DuplicateMethodCall::ALLOW_CALLS_KEY => ['@bravo.charlie'] }
|
|
195
195
|
src = 'def alfa; @bravo.charlie + @bravo.charlie; end'
|
|
@@ -130,7 +130,7 @@ RSpec.describe Reek::SmellDetectors::FeatureEnvy do
|
|
|
130
130
|
delta += bravo.foxtrot
|
|
131
131
|
delta *= 1.15
|
|
132
132
|
end
|
|
133
|
-
|
|
133
|
+
EOS
|
|
134
134
|
|
|
135
135
|
expect(src).
|
|
136
136
|
to reek_of(:FeatureEnvy, name: 'delta').
|
|
@@ -145,7 +145,7 @@ RSpec.describe Reek::SmellDetectors::FeatureEnvy do
|
|
|
145
145
|
delta += bravo.echo
|
|
146
146
|
delta += bravo.foxtrot
|
|
147
147
|
end
|
|
148
|
-
|
|
148
|
+
EOS
|
|
149
149
|
|
|
150
150
|
expect(src).
|
|
151
151
|
to reek_of(:FeatureEnvy, name: 'delta').
|
|
@@ -247,4 +247,49 @@ RSpec.describe Reek::SmellDetectors::FeatureEnvy do
|
|
|
247
247
|
|
|
248
248
|
expect(src).not_to reek_of(:FeatureEnvy)
|
|
249
249
|
end
|
|
250
|
+
|
|
251
|
+
it 'does not report on class methods defined by opening the metaclass' do
|
|
252
|
+
src = <<-EOS
|
|
253
|
+
class Alfa
|
|
254
|
+
class << self
|
|
255
|
+
def bravo(charlie)
|
|
256
|
+
delta = new(charlie)
|
|
257
|
+
delta.echo
|
|
258
|
+
delta.echo
|
|
259
|
+
end
|
|
260
|
+
end
|
|
261
|
+
end
|
|
262
|
+
EOS
|
|
263
|
+
|
|
264
|
+
expect(src).not_to reek_of(:FeatureEnvy)
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
it 'does not report on class methods defined with an explicit receiver' do
|
|
268
|
+
src = <<-EOS
|
|
269
|
+
class Alfa
|
|
270
|
+
def self.bravo(charlie)
|
|
271
|
+
delta = new(charlie)
|
|
272
|
+
delta.echo
|
|
273
|
+
delta.echo
|
|
274
|
+
end
|
|
275
|
+
end
|
|
276
|
+
EOS
|
|
277
|
+
|
|
278
|
+
expect(src).not_to reek_of(:FeatureEnvy)
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
it 'does not report module functions' do
|
|
282
|
+
src = <<-EOF
|
|
283
|
+
module Alfa
|
|
284
|
+
module_function
|
|
285
|
+
def bravo(charlie)
|
|
286
|
+
echo = delta(charlie)
|
|
287
|
+
echo.foxtrot
|
|
288
|
+
echo.foxtrot
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
EOF
|
|
292
|
+
|
|
293
|
+
expect(src).not_to reek_of(:FeatureEnvy)
|
|
294
|
+
end
|
|
250
295
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require_relative '../../spec_helper'
|
|
2
|
-
require_lib 'reek/smell_detectors/
|
|
2
|
+
require_lib 'reek/smell_detectors/missing_safe_method'
|
|
3
3
|
|
|
4
|
-
RSpec.describe Reek::SmellDetectors::
|
|
4
|
+
RSpec.describe Reek::SmellDetectors::MissingSafeMethod do
|
|
5
5
|
it 'reports the right values' do
|
|
6
6
|
src = <<-EOS
|
|
7
7
|
class Alfa
|
|
@@ -10,10 +10,10 @@ RSpec.describe Reek::SmellDetectors::PrimaDonnaMethod do
|
|
|
10
10
|
end
|
|
11
11
|
EOS
|
|
12
12
|
|
|
13
|
-
expect(src).to reek_of(:
|
|
13
|
+
expect(src).to reek_of(:MissingSafeMethod,
|
|
14
14
|
lines: [2],
|
|
15
15
|
context: 'Alfa',
|
|
16
|
-
message: "has
|
|
16
|
+
message: "has missing safe method 'bravo!'",
|
|
17
17
|
source: 'string',
|
|
18
18
|
name: 'bravo!')
|
|
19
19
|
end
|
|
@@ -30,8 +30,8 @@ RSpec.describe Reek::SmellDetectors::PrimaDonnaMethod do
|
|
|
30
30
|
EOS
|
|
31
31
|
|
|
32
32
|
expect(src).
|
|
33
|
-
to reek_of(:
|
|
34
|
-
and reek_of(:
|
|
33
|
+
to reek_of(:MissingSafeMethod, lines: [2], name: 'bravo!').
|
|
34
|
+
and reek_of(:MissingSafeMethod, lines: [5], name: 'charlie!')
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
it 'reports nothing when method and bang counterpart exist' do
|
|
@@ -45,18 +45,18 @@ RSpec.describe Reek::SmellDetectors::PrimaDonnaMethod do
|
|
|
45
45
|
end
|
|
46
46
|
EOS
|
|
47
47
|
|
|
48
|
-
expect(src).not_to reek_of(:
|
|
48
|
+
expect(src).not_to reek_of(:MissingSafeMethod)
|
|
49
49
|
end
|
|
50
50
|
|
|
51
51
|
it 'does not report methods we excluded via comment' do
|
|
52
52
|
source = <<-EOF
|
|
53
|
-
# :reek:
|
|
53
|
+
# :reek:MissingSafeMethod: { exclude: [ bravo! ] }
|
|
54
54
|
class Alfa
|
|
55
55
|
def bravo!
|
|
56
56
|
end
|
|
57
57
|
end
|
|
58
58
|
EOF
|
|
59
59
|
|
|
60
|
-
expect(source).not_to reek_of(:
|
|
60
|
+
expect(source).not_to reek_of(:MissingSafeMethod)
|
|
61
61
|
end
|
|
62
62
|
end
|
|
@@ -50,6 +50,20 @@ RSpec.describe Reek::SmellDetectors::ModuleInitialize do
|
|
|
50
50
|
expect(src).not_to reek_of(:ModuleInitialize)
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
+
it 'reports nothing for a method named initialize in a nested dynamic class' do
|
|
54
|
+
src = <<-EOF
|
|
55
|
+
module Alfa
|
|
56
|
+
def self.bravo
|
|
57
|
+
Class.new do
|
|
58
|
+
def initialize; end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
EOF
|
|
63
|
+
|
|
64
|
+
expect(src).not_to reek_of(:ModuleInitialize)
|
|
65
|
+
end
|
|
66
|
+
|
|
53
67
|
it 'can be disabled via comment' do
|
|
54
68
|
src = <<-EOS
|
|
55
69
|
# :reek:ModuleInitialize
|
|
@@ -223,7 +223,7 @@ RSpec.describe Reek::SmellDetectors::NestedIterators do
|
|
|
223
223
|
expect(src).not_to reek_of(:NestedIterators)
|
|
224
224
|
end
|
|
225
225
|
|
|
226
|
-
context 'setting the allowed nesting depth to 3' do
|
|
226
|
+
context 'when setting the allowed nesting depth to 3' do
|
|
227
227
|
let(:config) do
|
|
228
228
|
{ Reek::SmellDetectors::NestedIterators::MAX_ALLOWED_NESTING_KEY => 3 }
|
|
229
229
|
end
|
|
@@ -33,7 +33,7 @@ RSpec.describe Reek::SmellDetectors::TooManyConstants do
|
|
|
33
33
|
|
|
34
34
|
it 'does not report when increasing default' do
|
|
35
35
|
src = <<-EOS
|
|
36
|
-
# :reek:TooManyConstants
|
|
36
|
+
# :reek:TooManyConstants { max_constants: 3 }
|
|
37
37
|
class Alfa
|
|
38
38
|
Bravo = Charlie = Delta = 1
|
|
39
39
|
end
|
|
@@ -44,7 +44,7 @@ RSpec.describe Reek::SmellDetectors::TooManyConstants do
|
|
|
44
44
|
|
|
45
45
|
it 'does not report when disabled' do
|
|
46
46
|
src = <<-EOS
|
|
47
|
-
# :reek:TooManyConstants
|
|
47
|
+
# :reek:TooManyConstants { enabled: false }
|
|
48
48
|
class Alfa
|
|
49
49
|
Bravo = Charlie = Delta = 1
|
|
50
50
|
end
|
|
@@ -96,7 +96,7 @@ RSpec.describe Reek::SmellDetectors::TooManyConstants do
|
|
|
96
96
|
it 'does not report outer module when inner module suppressed' do
|
|
97
97
|
src = <<-EOS
|
|
98
98
|
module Alfa
|
|
99
|
-
# ignore :reek:TooManyConstants
|
|
99
|
+
# ignore :reek:TooManyConstants
|
|
100
100
|
module Bravo
|
|
101
101
|
Charlie = Delta = Echo = 1
|
|
102
102
|
end
|
|
@@ -37,7 +37,7 @@ RSpec.describe Reek::SmellDetectors::TooManyInstanceVariables do
|
|
|
37
37
|
|
|
38
38
|
it 'has a configurable maximum' do
|
|
39
39
|
src = <<-EOS
|
|
40
|
-
# :reek:TooManyInstanceVariables
|
|
40
|
+
# :reek:TooManyInstanceVariables { max_instance_variables: 3 }
|
|
41
41
|
class Alfa
|
|
42
42
|
def bravo
|
|
43
43
|
@charlie = @delta = @echo = 1
|
|
@@ -41,18 +41,18 @@ RSpec.describe Reek::SmellDetectors::UncommunicativeMethodName do
|
|
|
41
41
|
describe '`accept` patterns' do
|
|
42
42
|
let(:source) { 'def x; end' }
|
|
43
43
|
|
|
44
|
-
it 'make smelly names pass
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
end
|
|
44
|
+
it 'make smelly names pass' do
|
|
45
|
+
pattern = /x/
|
|
46
|
+
expect(source).not_to reek_of(:UncommunicativeMethodName).with_config('accept' => pattern)
|
|
48
47
|
end
|
|
49
48
|
end
|
|
50
49
|
|
|
51
50
|
describe '`reject` patterns' do
|
|
52
51
|
let(:source) { 'def alfa; end' }
|
|
53
52
|
|
|
54
|
-
it 'reject smelly names
|
|
55
|
-
[
|
|
53
|
+
it 'reject smelly names' do
|
|
54
|
+
patterns = [/alf/, /lfa/]
|
|
55
|
+
patterns.each do |pattern|
|
|
56
56
|
expect(source).to reek_of(:UncommunicativeMethodName).with_config('reject' => pattern)
|
|
57
57
|
end
|
|
58
58
|
end
|
|
@@ -39,8 +39,9 @@ RSpec.describe Reek::SmellDetectors::UncommunicativeModuleName do
|
|
|
39
39
|
describe '`accept` patterns' do
|
|
40
40
|
let(:source) { 'class Alfa1; end' }
|
|
41
41
|
|
|
42
|
-
it '
|
|
43
|
-
[
|
|
42
|
+
it 'make smelly names pass ' do
|
|
43
|
+
patterns = [/lfa1/, /Alfa1/]
|
|
44
|
+
patterns.each do |pattern|
|
|
44
45
|
expect(source).not_to reek_of(:UncommunicativeModuleName).with_config('accept' => pattern)
|
|
45
46
|
end
|
|
46
47
|
end
|
|
@@ -49,8 +50,9 @@ RSpec.describe Reek::SmellDetectors::UncommunicativeModuleName do
|
|
|
49
50
|
describe '`reject` patterns' do
|
|
50
51
|
let(:source) { 'class Alfa; end' }
|
|
51
52
|
|
|
52
|
-
it '
|
|
53
|
-
[
|
|
53
|
+
it 'reject smelly names' do
|
|
54
|
+
patterns = [/lfa/, /Alf/]
|
|
55
|
+
patterns.each do |pattern|
|
|
54
56
|
expect(source).to reek_of(:UncommunicativeModuleName).with_config('reject' => pattern)
|
|
55
57
|
end
|
|
56
58
|
end
|
|
@@ -107,8 +107,9 @@ RSpec.describe Reek::SmellDetectors::UncommunicativeParameterName do
|
|
|
107
107
|
describe '`accept` patterns' do
|
|
108
108
|
let(:source) { 'def alfa(bar2); charlie(bar2); end' }
|
|
109
109
|
|
|
110
|
-
it 'make smelly names pass
|
|
111
|
-
[
|
|
110
|
+
it 'make smelly names pass' do
|
|
111
|
+
patterns = [/bar2/, /ar2/]
|
|
112
|
+
patterns.each do |pattern|
|
|
112
113
|
expect(source).not_to reek_of(:UncommunicativeParameterName).with_config('accept' => pattern)
|
|
113
114
|
end
|
|
114
115
|
end
|
|
@@ -117,8 +118,9 @@ RSpec.describe Reek::SmellDetectors::UncommunicativeParameterName do
|
|
|
117
118
|
describe '`reject` patterns' do
|
|
118
119
|
let(:source) { 'def alfa(bravo); charlie(bravo); end' }
|
|
119
120
|
|
|
120
|
-
it 'reject smelly names
|
|
121
|
-
[
|
|
121
|
+
it 'reject smelly names' do
|
|
122
|
+
patterns = [/brav/, /ravo/]
|
|
123
|
+
patterns.each do |pattern|
|
|
122
124
|
expect(source).to reek_of(:UncommunicativeParameterName).with_config('reject' => pattern)
|
|
123
125
|
end
|
|
124
126
|
end
|
|
@@ -29,7 +29,7 @@ RSpec.describe Reek::SmellDetectors::UncommunicativeVariableName do
|
|
|
29
29
|
and reek_of(:UncommunicativeVariableName, lines: [3], name: 'y')
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
-
context 'instance variables' do
|
|
32
|
+
context 'when examining instance variables' do
|
|
33
33
|
it 'does not report use of one-letter names' do
|
|
34
34
|
src = 'class Alfa; def bravo; @x; end; end'
|
|
35
35
|
expect(src).not_to reek_of(:UncommunicativeVariableName)
|
|
@@ -41,7 +41,7 @@ RSpec.describe Reek::SmellDetectors::UncommunicativeVariableName do
|
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
-
context 'local variables' do
|
|
44
|
+
context 'when examining local variables' do
|
|
45
45
|
it 'does not report single underscore as a variable name' do
|
|
46
46
|
src = 'def alfa; _ = bravo(); end'
|
|
47
47
|
expect(src).not_to reek_of(:UncommunicativeVariableName)
|
|
@@ -78,7 +78,7 @@ RSpec.describe Reek::SmellDetectors::UncommunicativeVariableName do
|
|
|
78
78
|
end
|
|
79
79
|
end
|
|
80
80
|
|
|
81
|
-
context 'block parameters' do
|
|
81
|
+
context 'when examining block parameters' do
|
|
82
82
|
it 'reports all relevant block parameters' do
|
|
83
83
|
src = <<-EOS
|
|
84
84
|
def alfa
|
|
@@ -159,9 +159,9 @@ RSpec.describe Reek::SmellDetectors::UncommunicativeVariableName do
|
|
|
159
159
|
describe '`accept` patterns' do
|
|
160
160
|
let(:src) { 'def alfa; bravo2 = 42; end' }
|
|
161
161
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
162
|
+
it 'make smelly names pass' do
|
|
163
|
+
patterns = [/ravo2/, /bravo2/]
|
|
164
|
+
patterns.each do |pattern|
|
|
165
165
|
expect(src).to reek_of(:UncommunicativeVariableName).
|
|
166
166
|
and not_reek_of(:UncommunicativeVariableName).with_config('accept' => pattern)
|
|
167
167
|
end
|
|
@@ -171,9 +171,9 @@ RSpec.describe Reek::SmellDetectors::UncommunicativeVariableName do
|
|
|
171
171
|
describe '`reject` patterns' do
|
|
172
172
|
let(:src) { 'def alfa; foobar = 42; end' }
|
|
173
173
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
174
|
+
it 'reject smelly names' do
|
|
175
|
+
patterns = [/fooba/, /oobar/]
|
|
176
|
+
patterns.each do |pattern|
|
|
177
177
|
expect(src).to not_reek_of(:UncommunicativeVariableName).
|
|
178
178
|
and reek_of(:UncommunicativeVariableName).with_config('reject' => pattern)
|
|
179
179
|
end
|
|
@@ -61,7 +61,7 @@ RSpec.describe Reek::SmellDetectors::UnusedParameters do
|
|
|
61
61
|
expect(src).not_to reek_of(:UnusedParameters)
|
|
62
62
|
end
|
|
63
63
|
|
|
64
|
-
context 'using super' do
|
|
64
|
+
context 'when using super' do
|
|
65
65
|
it 'reports nothing with implicit arguments' do
|
|
66
66
|
src = 'def alfa(*bravo); super; end'
|
|
67
67
|
expect(src).not_to reek_of(:UnusedParameters)
|
|
@@ -83,7 +83,7 @@ RSpec.describe Reek::SmellDetectors::UnusedParameters do
|
|
|
83
83
|
end
|
|
84
84
|
end
|
|
85
85
|
|
|
86
|
-
context 'anonymous parameters' do
|
|
86
|
+
context 'with anonymous parameters' do
|
|
87
87
|
it 'reports nothing for unused anonymous parameter' do
|
|
88
88
|
src = 'def alfa(_); end'
|
|
89
89
|
expect(src).not_to reek_of(:UnusedParameters)
|
|
@@ -95,7 +95,7 @@ RSpec.describe Reek::SmellDetectors::UnusedParameters do
|
|
|
95
95
|
end
|
|
96
96
|
end
|
|
97
97
|
|
|
98
|
-
context 'splatted parameters' do
|
|
98
|
+
context 'with splatted parameters' do
|
|
99
99
|
it 'reports nothing for used splatted parameter' do
|
|
100
100
|
src = 'def alfa(*bravo); bravo; end'
|
|
101
101
|
expect(src).not_to reek_of(:UnusedParameters)
|
|
@@ -38,7 +38,7 @@ RSpec.describe Reek::SmellDetectors::UnusedPrivateMethod do
|
|
|
38
38
|
and reek_of(:UnusedPrivateMethod, lines: [7], name: 'charlie')
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
-
context 'unused private methods' do
|
|
41
|
+
context 'when a class has unused private methods' do
|
|
42
42
|
it 'reports instance methods' do
|
|
43
43
|
source = <<-EOF
|
|
44
44
|
class Alfa
|
|
@@ -116,10 +116,10 @@ RSpec.describe Reek::SmellDetectors::UnusedPrivateMethod do
|
|
|
116
116
|
end
|
|
117
117
|
end
|
|
118
118
|
|
|
119
|
-
|
|
119
|
+
context 'when the detector is configured via a source code comment' do
|
|
120
120
|
it 'does not report methods we excluded' do
|
|
121
121
|
source = <<-EOF
|
|
122
|
-
# :reek:UnusedPrivateMethod
|
|
122
|
+
# :reek:UnusedPrivateMethod { exclude: [ bravo ] }
|
|
123
123
|
class Alfa
|
|
124
124
|
private
|
|
125
125
|
def bravo; end
|
|
@@ -133,8 +133,8 @@ RSpec.describe Reek::SmellDetectors::UnusedPrivateMethod do
|
|
|
133
133
|
end
|
|
134
134
|
end
|
|
135
135
|
|
|
136
|
-
context 'used private methods' do
|
|
137
|
-
it '
|
|
136
|
+
context 'when a class has only used private methods' do
|
|
137
|
+
it 'reports nothing' do
|
|
138
138
|
source = <<-EOF
|
|
139
139
|
class Alfa
|
|
140
140
|
def bravo
|
|
@@ -150,8 +150,8 @@ RSpec.describe Reek::SmellDetectors::UnusedPrivateMethod do
|
|
|
150
150
|
end
|
|
151
151
|
end
|
|
152
152
|
|
|
153
|
-
context 'unused protected methods' do
|
|
154
|
-
it '
|
|
153
|
+
context 'when a class has unused protected methods' do
|
|
154
|
+
it 'reports nothing' do
|
|
155
155
|
source = <<-EOF
|
|
156
156
|
class Alfa
|
|
157
157
|
protected
|
|
@@ -163,8 +163,8 @@ RSpec.describe Reek::SmellDetectors::UnusedPrivateMethod do
|
|
|
163
163
|
end
|
|
164
164
|
end
|
|
165
165
|
|
|
166
|
-
context 'unused public methods' do
|
|
167
|
-
it '
|
|
166
|
+
context 'when a class has unused public methods' do
|
|
167
|
+
it 'reports nothing' do
|
|
168
168
|
source = <<-EOF
|
|
169
169
|
class Alfa
|
|
170
170
|
def bravo; end
|
|
@@ -175,7 +175,7 @@ RSpec.describe Reek::SmellDetectors::UnusedPrivateMethod do
|
|
|
175
175
|
end
|
|
176
176
|
end
|
|
177
177
|
|
|
178
|
-
describe '
|
|
178
|
+
describe 'preventing methods from being reported' do
|
|
179
179
|
let(:source) do
|
|
180
180
|
<<-EOF
|
|
181
181
|
class Alfa
|
|
@@ -98,7 +98,7 @@ RSpec.describe Reek::SmellDetectors::UtilityFunction do
|
|
|
98
98
|
expect(src).to reek_of(:UtilityFunction, context: 'simple')
|
|
99
99
|
end
|
|
100
100
|
|
|
101
|
-
context '
|
|
101
|
+
context 'when examining singleton methods' do
|
|
102
102
|
['class', 'module'].each do |scope|
|
|
103
103
|
it "does not report for #{scope} with `class << self` notation" do
|
|
104
104
|
src = "#{scope} Alfa; class << self; def bravo(charlie) charlie.to_s; end; end; end"
|
|
@@ -111,7 +111,7 @@ RSpec.describe Reek::SmellDetectors::UtilityFunction do
|
|
|
111
111
|
end
|
|
112
112
|
end
|
|
113
113
|
|
|
114
|
-
context 'by using `module_function`' do
|
|
114
|
+
context 'when defined by using `module_function`' do
|
|
115
115
|
it 'does not report UtilityFunction also when using multiple arguments' do
|
|
116
116
|
src = <<-EOS
|
|
117
117
|
class Alfa
|
|
@@ -194,7 +194,7 @@ RSpec.describe Reek::SmellDetectors::UtilityFunction do
|
|
|
194
194
|
{ Reek::SmellDetectors::UtilityFunction::PUBLIC_METHODS_ONLY_KEY => true }
|
|
195
195
|
end
|
|
196
196
|
|
|
197
|
-
context 'public methods' do
|
|
197
|
+
context 'when examining public methods' do
|
|
198
198
|
it 'still reports UtilityFunction' do
|
|
199
199
|
src = <<-EOS
|
|
200
200
|
class Alfa
|
|
@@ -208,7 +208,7 @@ RSpec.describe Reek::SmellDetectors::UtilityFunction do
|
|
|
208
208
|
end
|
|
209
209
|
end
|
|
210
210
|
|
|
211
|
-
context 'private methods' do
|
|
211
|
+
context 'when examining private methods' do
|
|
212
212
|
it 'does not report UtilityFunction' do
|
|
213
213
|
src = <<-EOS
|
|
214
214
|
class Alfa
|
|
@@ -235,7 +235,7 @@ RSpec.describe Reek::SmellDetectors::UtilityFunction do
|
|
|
235
235
|
end
|
|
236
236
|
end
|
|
237
237
|
|
|
238
|
-
context 'protected methods' do
|
|
238
|
+
context 'when examining protected methods' do
|
|
239
239
|
it 'does not report UtilityFunction' do
|
|
240
240
|
src = <<-EOS
|
|
241
241
|
class Alfa
|
|
@@ -7,7 +7,7 @@ RSpec.describe Reek::SmellWarning do
|
|
|
7
7
|
let(:utility_function_detector) { build(:smell_detector, smell_type: 'UtilityFunction') }
|
|
8
8
|
let(:uncommunicative_name_detector) { build(:smell_detector, smell_type: 'UncommunicativeVariableName') }
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
describe 'sort order' do
|
|
11
11
|
shared_examples_for 'first sorts ahead of second' do
|
|
12
12
|
it 'hash differently' do
|
|
13
13
|
expect(first.hash).not_to eq(second.hash)
|
|
@@ -26,21 +26,21 @@ RSpec.describe Reek::SmellWarning do
|
|
|
26
26
|
end
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
context 'smells
|
|
29
|
+
context 'when smells differ only by detector' do
|
|
30
30
|
let(:first) { build(:smell_warning, smell_detector: duplication_detector) }
|
|
31
31
|
let(:second) { build(:smell_warning, smell_detector: feature_envy_detector) }
|
|
32
32
|
|
|
33
33
|
it_behaves_like 'first sorts ahead of second'
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
-
context 'smells
|
|
36
|
+
context 'when smells differ only by lines' do
|
|
37
37
|
let(:first) { build(:smell_warning, smell_detector: feature_envy_detector, lines: [2]) }
|
|
38
38
|
let(:second) { build(:smell_warning, smell_detector: feature_envy_detector, lines: [3]) }
|
|
39
39
|
|
|
40
40
|
it_behaves_like 'first sorts ahead of second'
|
|
41
41
|
end
|
|
42
42
|
|
|
43
|
-
context 'smells
|
|
43
|
+
context 'when smells differ only by context' do
|
|
44
44
|
let(:first) { build(:smell_warning, smell_detector: duplication_detector, context: 'first') }
|
|
45
45
|
let(:second) do
|
|
46
46
|
build(:smell_warning, smell_detector: duplication_detector, context: 'second')
|
|
@@ -49,7 +49,7 @@ RSpec.describe Reek::SmellWarning do
|
|
|
49
49
|
it_behaves_like 'first sorts ahead of second'
|
|
50
50
|
end
|
|
51
51
|
|
|
52
|
-
context 'smells
|
|
52
|
+
context 'when smells differ only by message' do
|
|
53
53
|
let(:first) do
|
|
54
54
|
build(:smell_warning, smell_detector: duplication_detector,
|
|
55
55
|
context: 'ctx', message: 'first message')
|
|
@@ -62,7 +62,7 @@ RSpec.describe Reek::SmellWarning do
|
|
|
62
62
|
it_behaves_like 'first sorts ahead of second'
|
|
63
63
|
end
|
|
64
64
|
|
|
65
|
-
context '
|
|
65
|
+
context 'when smells differ by name and message' do
|
|
66
66
|
let(:first) do
|
|
67
67
|
build(:smell_warning, smell_detector: feature_envy_detector, message: 'second message')
|
|
68
68
|
end
|
|
@@ -73,7 +73,7 @@ RSpec.describe Reek::SmellWarning do
|
|
|
73
73
|
it_behaves_like 'first sorts ahead of second'
|
|
74
74
|
end
|
|
75
75
|
|
|
76
|
-
context 'smells
|
|
76
|
+
context 'when smells differ everywhere' do
|
|
77
77
|
let(:first) do
|
|
78
78
|
build(:smell_warning, smell_detector: duplication_detector,
|
|
79
79
|
context: 'Dirty#a',
|
|
@@ -97,7 +97,7 @@ RSpec.describe Reek::SmellWarning do
|
|
|
97
97
|
end
|
|
98
98
|
end
|
|
99
99
|
|
|
100
|
-
|
|
100
|
+
describe '#yaml_hash' do
|
|
101
101
|
let(:context_name) { 'Module::Class#method/block' }
|
|
102
102
|
let(:lines) { [24, 513] }
|
|
103
103
|
let(:message) { 'test message' }
|
|
@@ -135,6 +135,10 @@ RSpec.describe Reek::SmellWarning do
|
|
|
135
135
|
expect(yaml['source']).to eq source
|
|
136
136
|
end
|
|
137
137
|
|
|
138
|
+
it 'includes the documentation link' do
|
|
139
|
+
expect(yaml['documentation_link']).to eq Reek::DocumentationLink.build('FeatureEnvy')
|
|
140
|
+
end
|
|
141
|
+
|
|
138
142
|
it 'includes the parameters' do
|
|
139
143
|
parameters.each do |key, value|
|
|
140
144
|
expect(yaml[key]).to eq value
|
|
@@ -6,86 +6,60 @@ RSpec.describe Reek::Source::SourceCode do
|
|
|
6
6
|
describe '#syntax_tree' do
|
|
7
7
|
it 'associates comments with the AST' do
|
|
8
8
|
source = "# this is\n# a comment\ndef foo; end"
|
|
9
|
-
source_code = described_class.new(
|
|
9
|
+
source_code = described_class.new(source: source, origin: '(string)')
|
|
10
10
|
result = source_code.syntax_tree
|
|
11
11
|
expect(result.leading_comment).to eq "# this is\n# a comment"
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
it 'cleanly processes empty source' do
|
|
15
|
-
source_code = described_class.new(
|
|
15
|
+
source_code = described_class.new(source: '', origin: '(string)')
|
|
16
16
|
result = source_code.syntax_tree
|
|
17
|
-
expect(result).to
|
|
17
|
+
expect(result.type).to eq :empty
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
it 'cleanly processes empty source with comments' do
|
|
21
21
|
source = "# this is\n# a comment\n"
|
|
22
|
-
source_code = described_class.new(
|
|
22
|
+
source_code = described_class.new(source: source, origin: '(string)')
|
|
23
23
|
result = source_code.syntax_tree
|
|
24
|
-
expect(result).to
|
|
24
|
+
expect(result.type).to eq :empty
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
it 'does not crash with sequences incompatible with UTF-8' do
|
|
28
28
|
source = '"\xFF"'
|
|
29
|
-
source_code = described_class.new(
|
|
29
|
+
source_code = described_class.new(source: source, origin: '(string)')
|
|
30
30
|
result = source_code.syntax_tree
|
|
31
31
|
expect(result.children.first).to eq "\xFF"
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
it 'returns a :lambda node for lambda expressions' do
|
|
35
35
|
source = '->() { }'
|
|
36
|
-
source_code = described_class.new(
|
|
36
|
+
source_code = described_class.new(source: source, origin: '(string)')
|
|
37
37
|
result = source_code.syntax_tree
|
|
38
38
|
expect(result.children.first.type).to eq :lambda
|
|
39
39
|
end
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
context 'with a source that triggers an encoding error' do
|
|
43
|
-
let(:source_name) { 'Bad source' }
|
|
44
|
-
let(:code) do
|
|
45
|
-
<<-SRC.strip_heredoc
|
|
46
|
-
# encoding: US-ASCII
|
|
47
|
-
puts 'こんにちは世界'
|
|
48
|
-
SRC
|
|
49
|
-
end
|
|
50
|
-
let(:src) { described_class.new(code: code, origin: source_name) }
|
|
51
40
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
it 'explains the origin of the error' do
|
|
57
|
-
message = "Source '#{source_name}' cannot be processed by Reek due to an encoding error in the source file."
|
|
58
|
-
expect { src.syntax_tree }.to raise_error.with_message(/#{message}/)
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
context 'when the parser fails' do
|
|
63
|
-
let(:source_name) { 'Test source' }
|
|
64
|
-
let(:src) { described_class.new(code: code, origin: source_name, **parser) }
|
|
65
|
-
|
|
66
|
-
context 'with a Parser::SyntaxError' do
|
|
41
|
+
context 'when the parser fails with a Parser::SyntaxError' do
|
|
42
|
+
let(:src) { described_class.new(source: code) }
|
|
67
43
|
let(:code) { '== Invalid Syntax ==' }
|
|
68
|
-
let(:parser) { {} }
|
|
69
44
|
|
|
70
|
-
it '
|
|
71
|
-
expect
|
|
45
|
+
it 'raises the error' do
|
|
46
|
+
expect { src.syntax_tree }.to raise_error Parser::SyntaxError
|
|
72
47
|
end
|
|
73
48
|
end
|
|
74
49
|
|
|
75
|
-
context 'with a generic error' do
|
|
50
|
+
context 'when the parser fails with a generic error' do
|
|
76
51
|
let(:code) { '' }
|
|
52
|
+
let(:parser) { instance_double('Parser::Ruby25') }
|
|
53
|
+
let(:src) { described_class.new(source: code, parser: parser) }
|
|
77
54
|
let(:error_class) { RuntimeError }
|
|
78
55
|
let(:error_message) { 'An error' }
|
|
79
|
-
|
|
80
|
-
|
|
56
|
+
|
|
57
|
+
before do
|
|
81
58
|
allow(parser).to receive(:parse_with_comments).and_raise(error_class, error_message)
|
|
82
|
-
{
|
|
83
|
-
parser: parser
|
|
84
|
-
}
|
|
85
59
|
end
|
|
86
60
|
|
|
87
61
|
it 'raises the error' do
|
|
88
|
-
expect { src.
|
|
62
|
+
expect { src.syntax_tree }.to raise_error error_class, error_message
|
|
89
63
|
end
|
|
90
64
|
end
|
|
91
65
|
end
|