reek 6.0.2 → 6.1.1

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 (241) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +9 -0
  3. data/.github/workflows/ruby.yml +57 -0
  4. data/.rubocop.yml +5 -3
  5. data/.rubocop_todo.yml +6 -4
  6. data/CHANGELOG.md +30 -0
  7. data/CONTRIBUTING.md +3 -0
  8. data/Dockerfile +1 -1
  9. data/Gemfile +7 -7
  10. data/README.md +1 -1
  11. data/bin/code_climate_reek +2 -3
  12. data/lib/reek/ast/ast_node_class_map.rb +1 -1
  13. data/lib/reek/ast/node.rb +1 -1
  14. data/lib/reek/ast/sexp_extensions/arguments.rb +11 -0
  15. data/lib/reek/ast/sexp_extensions/case.rb +1 -1
  16. data/lib/reek/ast/sexp_extensions/if.rb +1 -1
  17. data/lib/reek/ast/sexp_extensions/send.rb +1 -1
  18. data/lib/reek/cli/command/todo_list_command.rb +1 -1
  19. data/lib/reek/cli/options.rb +1 -1
  20. data/lib/reek/code_comment.rb +22 -17
  21. data/lib/reek/configuration/excluded_paths.rb +2 -1
  22. data/lib/reek/context/code_context.rb +1 -1
  23. data/lib/reek/context/module_context.rb +4 -0
  24. data/lib/reek/context/refinement_context.rb +16 -0
  25. data/lib/reek/context/send_context.rb +6 -0
  26. data/lib/reek/context_builder.rb +17 -3
  27. data/lib/reek/rake/task.rb +1 -1
  28. data/lib/reek/report/code_climate/code_climate_formatter.rb +1 -3
  29. data/lib/reek/smell_detectors/base_detector.rb +1 -1
  30. data/lib/reek/smell_detectors/unused_private_method.rb +1 -0
  31. data/lib/reek/smell_warning.rb +1 -1
  32. data/lib/reek/source/source_locator.rb +1 -3
  33. data/lib/reek/spec/should_reek_of.rb +6 -4
  34. data/lib/reek/version.rb +2 -2
  35. data/reek.gemspec +28 -25
  36. metadata +10 -237
  37. data/.travis.yml +0 -40
  38. data/docs/API.md +0 -174
  39. data/docs/Attribute.md +0 -39
  40. data/docs/Basic-Smell-Options.md +0 -85
  41. data/docs/Boolean-Parameter.md +0 -54
  42. data/docs/Class-Variable.md +0 -40
  43. data/docs/Code-Smells.md +0 -39
  44. data/docs/Command-Line-Options.md +0 -119
  45. data/docs/Control-Couple.md +0 -26
  46. data/docs/Control-Parameter.md +0 -32
  47. data/docs/Data-Clump.md +0 -46
  48. data/docs/Duplicate-Method-Call.md +0 -264
  49. data/docs/Feature-Envy.md +0 -93
  50. data/docs/How-To-Write-New-Detectors.md +0 -132
  51. data/docs/How-reek-works-internally.md +0 -114
  52. data/docs/Instance-Variable-Assumption.md +0 -163
  53. data/docs/Irresponsible-Module.md +0 -47
  54. data/docs/Large-Class.md +0 -16
  55. data/docs/Long-Parameter-List.md +0 -39
  56. data/docs/Long-Yield-List.md +0 -37
  57. data/docs/Manual-Dispatch.md +0 -30
  58. data/docs/Missing-Safe-Method.md +0 -92
  59. data/docs/Module-Initialize.md +0 -62
  60. data/docs/Nested-Iterators.md +0 -59
  61. data/docs/Nil-Check.md +0 -47
  62. data/docs/RSpec-matchers.md +0 -129
  63. data/docs/Rake-Task.md +0 -66
  64. data/docs/Reek-4-to-Reek-5-migration.md +0 -188
  65. data/docs/Reek-Driven-Development.md +0 -46
  66. data/docs/Repeated-Conditional.md +0 -47
  67. data/docs/Simulated-Polymorphism.md +0 -16
  68. data/docs/Smell-Suppression.md +0 -96
  69. data/docs/Style-Guide.md +0 -19
  70. data/docs/Subclassed-From-Core-Class.md +0 -79
  71. data/docs/Too-Many-Constants.md +0 -37
  72. data/docs/Too-Many-Instance-Variables.md +0 -43
  73. data/docs/Too-Many-Methods.md +0 -56
  74. data/docs/Too-Many-Statements.md +0 -54
  75. data/docs/Uncommunicative-Method-Name.md +0 -94
  76. data/docs/Uncommunicative-Module-Name.md +0 -92
  77. data/docs/Uncommunicative-Name.md +0 -18
  78. data/docs/Uncommunicative-Parameter-Name.md +0 -90
  79. data/docs/Uncommunicative-Variable-Name.md +0 -96
  80. data/docs/Unused-Parameters.md +0 -28
  81. data/docs/Unused-Private-Method.md +0 -101
  82. data/docs/Utility-Function.md +0 -56
  83. data/docs/Versioning-Policy.md +0 -7
  84. data/docs/YAML-Reports.md +0 -93
  85. data/docs/defaults.reek.yml +0 -129
  86. data/docs/templates/default/docstring/html/public_api_marker.erb +0 -3
  87. data/docs/templates/default/docstring/setup.rb +0 -37
  88. data/docs/templates/default/fulldoc/html/css/common.css +0 -1
  89. data/docs/yard_plugin.rb +0 -17
  90. data/features/command_line_interface/basic_usage.feature +0 -15
  91. data/features/command_line_interface/options.feature +0 -123
  92. data/features/command_line_interface/show_progress.feature +0 -33
  93. data/features/command_line_interface/smell_selection.feature +0 -15
  94. data/features/command_line_interface/smells_count.feature +0 -38
  95. data/features/command_line_interface/stdin.feature +0 -65
  96. data/features/configuration_files/accept_setting.feature +0 -87
  97. data/features/configuration_files/directory_specific_directives.feature +0 -274
  98. data/features/configuration_files/exclude_directives.feature +0 -35
  99. data/features/configuration_files/exclude_paths_directives.feature +0 -42
  100. data/features/configuration_files/masking_smells.feature +0 -94
  101. data/features/configuration_files/mix_accept_reject_setting.feature +0 -84
  102. data/features/configuration_files/reject_setting.feature +0 -89
  103. data/features/configuration_files/schema_validation.feature +0 -59
  104. data/features/configuration_files/show_configuration_file.feature +0 -44
  105. data/features/configuration_files/unused_private_method.feature +0 -68
  106. data/features/configuration_loading.feature +0 -91
  107. data/features/configuration_via_source_comments/erroneous_source_comments.feature +0 -68
  108. data/features/configuration_via_source_comments/well_formed_source_comments.feature +0 -116
  109. data/features/locales.feature +0 -32
  110. data/features/programmatic_access.feature +0 -41
  111. data/features/rake_task/rake_task.feature +0 -138
  112. data/features/reports/codeclimate.feature +0 -59
  113. data/features/reports/json.feature +0 -59
  114. data/features/reports/reports.feature +0 -219
  115. data/features/reports/yaml.feature +0 -52
  116. data/features/rspec_matcher.feature +0 -41
  117. data/features/samples.feature +0 -305
  118. data/features/step_definitions/.rubocop.yml +0 -5
  119. data/features/step_definitions/reek_steps.rb +0 -102
  120. data/features/step_definitions/sample_file_steps.rb +0 -63
  121. data/features/support/env.rb +0 -33
  122. data/features/todo_list.feature +0 -108
  123. data/samples/checkstyle.xml +0 -7
  124. data/samples/clean_source/clean.rb +0 -6
  125. data/samples/configuration/accepts_rejects_and_excludes_for_detectors.reek.yml +0 -29
  126. data/samples/configuration/accepts_rejects_and_excludes_for_directory_directives.reek.yml +0 -30
  127. data/samples/configuration/corrupt.reek +0 -1
  128. data/samples/configuration/empty.reek +0 -0
  129. data/samples/configuration/full_configuration.reek +0 -13
  130. data/samples/configuration/full_mask.reek +0 -6
  131. data/samples/configuration/home/home.reek.yml +0 -4
  132. data/samples/configuration/partial_mask.reek +0 -4
  133. data/samples/configuration/regular_configuration/.reek.yml +0 -4
  134. data/samples/configuration/regular_configuration/empty_sub_directory/.gitignore +0 -0
  135. data/samples/configuration/with_excluded_paths.reek +0 -5
  136. data/samples/no_config_file/.keep +0 -0
  137. data/samples/paths.rb +0 -5
  138. data/samples/smelly_source/inline.rb +0 -704
  139. data/samples/smelly_source/optparse.rb +0 -1788
  140. data/samples/smelly_source/redcloth.rb +0 -1130
  141. data/samples/smelly_source/ruby.rb +0 -368
  142. data/samples/smelly_source/smelly.rb +0 -7
  143. data/samples/source_with_exclude_paths/ignore_me/uncommunicative_method_name.rb +0 -5
  144. data/samples/source_with_exclude_paths/nested/ignore_me_as_well/irresponsible_module.rb +0 -2
  145. data/samples/source_with_exclude_paths/nested/uncommunicative_parameter_name.rb +0 -6
  146. data/samples/source_with_exclude_paths/nested/uncommunicative_variable_name.rb +0 -6
  147. data/samples/source_with_hidden_directories/.hidden/hidden.rb +0 -1
  148. data/samples/source_with_hidden_directories/not_hidden.rb +0 -1
  149. data/samples/source_with_non_ruby_files/gibberish +0 -1
  150. data/samples/source_with_non_ruby_files/python_source.py +0 -1
  151. data/samples/source_with_non_ruby_files/ruby.rb +0 -6
  152. data/spec/performance/reek/smell_detectors/runtime_speed_spec.rb +0 -15
  153. data/spec/quality/documentation_spec.rb +0 -41
  154. data/spec/quality/reek_source_spec.rb +0 -11
  155. data/spec/reek/ast/node_spec.rb +0 -211
  156. data/spec/reek/ast/object_refs_spec.rb +0 -83
  157. data/spec/reek/ast/reference_collector_spec.rb +0 -47
  158. data/spec/reek/ast/sexp_extensions_spec.rb +0 -498
  159. data/spec/reek/cli/application_spec.rb +0 -168
  160. data/spec/reek/cli/command/report_command_spec.rb +0 -44
  161. data/spec/reek/cli/command/todo_list_command_spec.rb +0 -86
  162. data/spec/reek/cli/options_spec.rb +0 -51
  163. data/spec/reek/cli/silencer_spec.rb +0 -28
  164. data/spec/reek/code_comment_spec.rb +0 -184
  165. data/spec/reek/configuration/app_configuration_spec.rb +0 -195
  166. data/spec/reek/configuration/configuration_file_finder_spec.rb +0 -230
  167. data/spec/reek/configuration/default_directive_spec.rb +0 -13
  168. data/spec/reek/configuration/directory_directives_spec.rb +0 -122
  169. data/spec/reek/configuration/excluded_paths_spec.rb +0 -16
  170. data/spec/reek/configuration/rake_task_converter_spec.rb +0 -33
  171. data/spec/reek/configuration/schema_validator_spec.rb +0 -165
  172. data/spec/reek/context/code_context_spec.rb +0 -192
  173. data/spec/reek/context/ghost_context_spec.rb +0 -60
  174. data/spec/reek/context/method_context_spec.rb +0 -72
  175. data/spec/reek/context/module_context_spec.rb +0 -55
  176. data/spec/reek/context/root_context_spec.rb +0 -12
  177. data/spec/reek/context/statement_counter_spec.rb +0 -24
  178. data/spec/reek/context_builder_spec.rb +0 -457
  179. data/spec/reek/detector_repository_spec.rb +0 -22
  180. data/spec/reek/documentation_link_spec.rb +0 -20
  181. data/spec/reek/errors/base_error_spec.rb +0 -13
  182. data/spec/reek/examiner_spec.rb +0 -309
  183. data/spec/reek/logging_error_handler_spec.rb +0 -24
  184. data/spec/reek/rake/task_spec.rb +0 -56
  185. data/spec/reek/report/code_climate/code_climate_configuration_spec.rb +0 -22
  186. data/spec/reek/report/code_climate/code_climate_fingerprint_spec.rb +0 -126
  187. data/spec/reek/report/code_climate/code_climate_formatter_spec.rb +0 -51
  188. data/spec/reek/report/code_climate/code_climate_report_spec.rb +0 -56
  189. data/spec/reek/report/html_report_spec.rb +0 -19
  190. data/spec/reek/report/json_report_spec.rb +0 -58
  191. data/spec/reek/report/location_formatter_spec.rb +0 -32
  192. data/spec/reek/report/progress_formatter_spec.rb +0 -68
  193. data/spec/reek/report/text_report_spec.rb +0 -89
  194. data/spec/reek/report/xml_report_spec.rb +0 -24
  195. data/spec/reek/report/yaml_report_spec.rb +0 -55
  196. data/spec/reek/report_spec.rb +0 -28
  197. data/spec/reek/smell_configuration_spec.rb +0 -56
  198. data/spec/reek/smell_detectors/attribute_spec.rb +0 -197
  199. data/spec/reek/smell_detectors/base_detector_spec.rb +0 -50
  200. data/spec/reek/smell_detectors/boolean_parameter_spec.rb +0 -93
  201. data/spec/reek/smell_detectors/class_variable_spec.rb +0 -106
  202. data/spec/reek/smell_detectors/control_parameter_spec.rb +0 -300
  203. data/spec/reek/smell_detectors/data_clump_spec.rb +0 -134
  204. data/spec/reek/smell_detectors/duplicate_method_call_spec.rb +0 -211
  205. data/spec/reek/smell_detectors/feature_envy_spec.rb +0 -295
  206. data/spec/reek/smell_detectors/instance_variable_assumption_spec.rb +0 -96
  207. data/spec/reek/smell_detectors/irresponsible_module_spec.rb +0 -226
  208. data/spec/reek/smell_detectors/long_parameter_list_spec.rb +0 -61
  209. data/spec/reek/smell_detectors/long_yield_list_spec.rb +0 -49
  210. data/spec/reek/smell_detectors/manual_dispatch_spec.rb +0 -75
  211. data/spec/reek/smell_detectors/missing_safe_method_spec.rb +0 -68
  212. data/spec/reek/smell_detectors/module_initialize_spec.rb +0 -77
  213. data/spec/reek/smell_detectors/nested_iterators_spec.rb +0 -333
  214. data/spec/reek/smell_detectors/nil_check_spec.rb +0 -100
  215. data/spec/reek/smell_detectors/repeated_conditional_spec.rb +0 -100
  216. data/spec/reek/smell_detectors/subclassed_from_core_class_spec.rb +0 -77
  217. data/spec/reek/smell_detectors/too_many_constants_spec.rb +0 -144
  218. data/spec/reek/smell_detectors/too_many_instance_variables_spec.rb +0 -132
  219. data/spec/reek/smell_detectors/too_many_methods_spec.rb +0 -54
  220. data/spec/reek/smell_detectors/too_many_statements_spec.rb +0 -90
  221. data/spec/reek/smell_detectors/uncommunicative_method_name_spec.rb +0 -78
  222. data/spec/reek/smell_detectors/uncommunicative_module_name_spec.rb +0 -78
  223. data/spec/reek/smell_detectors/uncommunicative_parameter_name_spec.rb +0 -147
  224. data/spec/reek/smell_detectors/uncommunicative_variable_name_spec.rb +0 -201
  225. data/spec/reek/smell_detectors/unused_parameters_spec.rb +0 -114
  226. data/spec/reek/smell_detectors/unused_private_method_spec.rb +0 -205
  227. data/spec/reek/smell_detectors/utility_function_spec.rb +0 -293
  228. data/spec/reek/smell_warning_spec.rb +0 -137
  229. data/spec/reek/source/source_code_spec.rb +0 -79
  230. data/spec/reek/source/source_locator_spec.rb +0 -166
  231. data/spec/reek/spec/should_reek_of_spec.rb +0 -153
  232. data/spec/reek/spec/should_reek_only_of_spec.rb +0 -91
  233. data/spec/reek/spec/should_reek_spec.rb +0 -52
  234. data/spec/reek/spec/smell_matcher_spec.rb +0 -87
  235. data/spec/reek/tree_dresser_spec.rb +0 -46
  236. data/spec/spec_helper.rb +0 -110
  237. data/tasks/configuration.rake +0 -18
  238. data/tasks/console.rake +0 -5
  239. data/tasks/reek.rake +0 -6
  240. data/tasks/rubocop.rake +0 -11
  241. data/tasks/test.rake +0 -32
@@ -1,153 +0,0 @@
1
- require 'pathname'
2
- require_relative '../../spec_helper'
3
- require_lib 'reek/spec'
4
-
5
- RSpec.describe Reek::Spec::ShouldReekOf do
6
- describe 'smell type selection' do
7
- let(:ruby) { 'def double_thing() @other.thing.foo + @other.thing.foo end' }
8
-
9
- it 'reports duplicate calls by smell type' do
10
- expect(ruby).to reek_of(:DuplicateMethodCall)
11
- end
12
-
13
- it 'does not report any feature envy' do
14
- expect(ruby).not_to reek_of(:FeatureEnvy)
15
- end
16
- end
17
-
18
- describe 'different sources of input' do
19
- context 'when checking code in a string' do
20
- let(:clean_code) { 'def good() true; end' }
21
- let(:matcher) { described_class.new(:UncommunicativeVariableName, name: 'y') }
22
- let(:smelly_code) { 'def x() y = 4; end' }
23
-
24
- it 'matches a smelly String' do
25
- expect(matcher).to be_matches(smelly_code)
26
- end
27
-
28
- it 'doesnt match a fragrant String' do
29
- expect(matcher).not_to be_matches(clean_code)
30
- end
31
-
32
- it 're-calculates matches every time' do
33
- matcher.matches? smelly_code
34
- expect(matcher).not_to be_matches(clean_code)
35
- end
36
- end
37
-
38
- context 'when checking code in a File' do
39
- let(:matcher) { described_class.new(:UncommunicativeMethodName, name: 'x') }
40
-
41
- it 'matches a smelly file' do
42
- expect(matcher).to be_matches(SMELLY_FILE)
43
- end
44
-
45
- it 'doesnt match a fragrant file' do
46
- expect(matcher).not_to be_matches(CLEAN_FILE)
47
- end
48
- end
49
- end
50
-
51
- describe 'smell types and smell details' do
52
- context 'when passing in smell_details with unknown parameter name' do
53
- let(:matcher) { described_class.new(:UncommunicativeVariableName, foo: 'y') }
54
- let(:smelly_code) { 'def x() y = 4; end' }
55
-
56
- it 'raises ArgumentError' do
57
- expect { matcher.matches?(smelly_code) }.to raise_error(ArgumentError)
58
- end
59
- end
60
-
61
- context 'when both are matching' do
62
- let(:matcher) { described_class.new(:UncommunicativeVariableName, name: 'y') }
63
- let(:smelly_code) { 'def x() y = 4; end' }
64
-
65
- it 'is truthy' do
66
- expect(matcher).to be_matches(smelly_code)
67
- end
68
- end
69
-
70
- context 'when no smell_type is matching' do
71
- let(:smelly_code) { 'def dummy() y = 4; end' }
72
-
73
- let(:falsey_matcher) { described_class.new(:FeatureEnvy, name: 'y') }
74
- let(:truthy_matcher) { described_class.new(:UncommunicativeVariableName, name: 'y') }
75
-
76
- it 'is falsey' do
77
- expect(falsey_matcher).not_to be_matches(smelly_code)
78
- end
79
-
80
- it 'sets the proper error message' do
81
- falsey_matcher.matches?(smelly_code)
82
-
83
- expect(falsey_matcher.failure_message).to\
84
- match('Expected string to reek of FeatureEnvy, but it didn\'t')
85
- end
86
-
87
- it 'sets the proper error message when negated' do
88
- truthy_matcher.matches?(smelly_code)
89
-
90
- expect(truthy_matcher.failure_message_when_negated).to\
91
- match('Expected string not to reek of UncommunicativeVariableName, but it did')
92
- end
93
- end
94
-
95
- context 'when smell type is matching but smell details are not' do
96
- let(:smelly_code) { 'def double_thing() @other.thing.foo + @other.thing.foo end' }
97
- let(:matcher) { described_class.new(:DuplicateMethodCall, name: 'foo', count: 15) }
98
-
99
- it 'is falsey' do
100
- expect(matcher).not_to be_matches(smelly_code)
101
- end
102
-
103
- it 'sets the proper error message' do
104
- matcher.matches?(smelly_code)
105
- expected = <<~TEXT
106
- Expected string to reek of DuplicateMethodCall (which it did) with smell details {:name=>"foo", :count=>15}, which it didn't.
107
- The number of smell details I had to compare with the given one was 2 and here they are:
108
- 1.)
109
- {"context"=>"double_thing", "lines"=>[1, 1], "message"=>"calls '@other.thing' 2 times", "source"=>"string", "name"=>"@other.thing", "count"=>2}
110
- 2.)
111
- {"context"=>"double_thing", "lines"=>[1, 1], "message"=>"calls '@other.thing.foo' 2 times", "source"=>"string", "name"=>"@other.thing.foo", "count"=>2}
112
- TEXT
113
-
114
- expect(matcher.failure_message).to eq(expected)
115
- end
116
-
117
- it 'sets the proper error message when negated' do
118
- matcher.matches?(smelly_code)
119
-
120
- expect(matcher.failure_message_when_negated).to\
121
- match('Expected string not to reek of DuplicateMethodCall with smell '\
122
- 'details {:name=>"foo", :count=>15}, but it did')
123
- end
124
- end
125
- end
126
-
127
- context 'with a smell that is disabled by default' do
128
- it 'enables the smell detector to match automatically' do
129
- default_config = Reek::SmellDetectors::UnusedPrivateMethod.default_config
130
- src = 'class C; private; def foo; end; end'
131
-
132
- aggregate_failures do
133
- expect(default_config[Reek::SmellConfiguration::ENABLED_KEY]).to be_falsy
134
- expect(src).to reek_of(:UnusedPrivateMethod)
135
- end
136
- end
137
- end
138
-
139
- describe '#with_config' do
140
- let(:matcher) { described_class.new(:UncommunicativeVariableName) }
141
- let(:configured_matcher) { matcher.with_config('accept' => 'x') }
142
-
143
- it 'uses the passed-in configuration for matching' do
144
- expect(configured_matcher).to be_matches('def foo; q = 2; end')
145
- expect(configured_matcher).not_to be_matches('def foo; x = 2; end')
146
- end
147
-
148
- it 'leaves the original matcher intact' do
149
- expect(configured_matcher).not_to be_matches('def foo; x = 2; end')
150
- expect(matcher).to be_matches('def foo; x = 2; end')
151
- end
152
- end
153
- end
@@ -1,91 +0,0 @@
1
- require_relative '../../spec_helper'
2
- require_lib 'reek/spec'
3
-
4
- RSpec.describe Reek::Spec::ShouldReekOnlyOf do
5
- let(:examiner) { instance_double('Reek::Examiner').as_null_object }
6
- let(:expected_context_name) { 'SmellyClass#big_method' }
7
- let(:expected_smell_type) { :NestedIterators }
8
- let(:matcher) { described_class.new(expected_smell_type) }
9
- let(:matcher_matches) { matcher.matches_examiner?(examiner) }
10
-
11
- before do
12
- allow(examiner).to receive(:smells) { smells }
13
- matcher_matches
14
- end
15
-
16
- shared_examples_for 'no match' do
17
- it 'does not match' do
18
- expect(matcher_matches).to be_falsey
19
- end
20
-
21
- context 'when a match was expected' do
22
- let(:source) { 'the_path/to_a/source_file.rb' }
23
-
24
- before { allow(examiner).to receive(:origin).and_return(source) }
25
-
26
- it 'reports the source' do
27
- expect(matcher.failure_message).to match(source)
28
- end
29
-
30
- it 'reports the expected smell class' do
31
- expect(matcher.failure_message).to match(expected_smell_type.to_s)
32
- end
33
- end
34
- end
35
-
36
- context 'with no smells' do
37
- let(:smells) { [] }
38
-
39
- it_behaves_like 'no match'
40
- end
41
-
42
- context 'with 1 non-matching smell' do
43
- let(:smells) { [build_smell_warning(smell_type: 'ControlParameter')] }
44
-
45
- it_behaves_like 'no match'
46
- end
47
-
48
- context 'with 2 non-matching smells' do
49
- let(:smells) do
50
- [
51
- build_smell_warning(smell_type: 'ControlParameter'),
52
- build_smell_warning(smell_type: 'FeatureEnvy')
53
- ]
54
- end
55
-
56
- it_behaves_like 'no match'
57
- end
58
-
59
- context 'with 1 non-matching and 1 matching smell' do
60
- let(:smells) do
61
- [
62
- build_smell_warning(smell_type: 'ControlParameter'),
63
- build_smell_warning(smell_type: expected_smell_type.to_s,
64
- message: "message mentioning #{expected_context_name}")
65
- ]
66
- end
67
-
68
- it_behaves_like 'no match'
69
- end
70
-
71
- context 'with 1 matching smell' do
72
- let(:smells) do
73
- [build_smell_warning(smell_type: expected_smell_type.to_s,
74
- message: "message mentioning #{expected_context_name}")]
75
- end
76
-
77
- it 'matches' do
78
- expect(matcher_matches).to be_truthy
79
- end
80
-
81
- it 'reports the expected smell when no match was expected' do
82
- expect(matcher.failure_message_when_negated).to match(expected_smell_type.to_s)
83
- end
84
-
85
- it 'reports the source when no match was expected' do
86
- source = 'the_path/to_a/source_file.rb'
87
- allow(examiner).to receive(:origin).and_return(source)
88
- expect(matcher.failure_message_when_negated).to match(source)
89
- end
90
- end
91
- end
@@ -1,52 +0,0 @@
1
- require_relative '../../spec_helper'
2
- require_lib 'reek/spec'
3
-
4
- RSpec.describe Reek::Spec::ShouldReek do
5
- describe 'checking code in a string' do
6
- let(:matcher) { described_class.new }
7
- let(:clean_code) { 'def good() true; end' }
8
- let(:smelly_code) { 'def x() y = 4; end' }
9
-
10
- it 'matches a smelly String' do
11
- expect(matcher).to be_matches(smelly_code)
12
- end
13
-
14
- it 'doesnt match a fragrant String' do
15
- expect(matcher).not_to be_matches(clean_code)
16
- end
17
-
18
- it 'reports the smells when should_not fails' do
19
- matcher.matches?(smelly_code)
20
- expect(matcher.failure_message_when_negated).to match('UncommunicativeVariableName')
21
- end
22
- end
23
-
24
- describe 'checking code in a File' do
25
- context 'without masking' do
26
- let(:matcher) { described_class.new }
27
-
28
- it 'matches a smelly File' do
29
- expect(matcher).to be_matches(SMELLY_FILE)
30
- end
31
-
32
- it 'doesnt match a fragrant File' do
33
- expect(matcher).not_to be_matches(CLEAN_FILE)
34
- end
35
-
36
- it 'reports the smells when should_not fails' do
37
- matcher.matches?(SMELLY_FILE)
38
- expect(matcher.failure_message_when_negated).to match('UncommunicativeMethodName')
39
- end
40
- end
41
-
42
- context 'with masking' do
43
- let(:path) { CONFIGURATION_DIR.join('full_mask.reek') }
44
- let(:configuration) { test_configuration_for(path) }
45
- let(:matcher) { described_class.new(configuration: configuration) }
46
-
47
- it 'masks smells using the relevant configuration' do
48
- expect(matcher).not_to be_matches(SMELLY_FILE)
49
- end
50
- end
51
- end
52
- end
@@ -1,87 +0,0 @@
1
- require_relative '../../spec_helper'
2
- require_lib 'reek/spec/smell_matcher'
3
-
4
- RSpec.describe Reek::Spec::SmellMatcher do
5
- let(:smell_warning) do
6
- build_smell_warning(smell_type: 'UncommunicativeVariableName',
7
- message: "has the variable name '@s'",
8
- parameters: { test: 'something' })
9
- end
10
- let(:matcher) { described_class.new(smell_warning) }
11
-
12
- describe '#matches?' do
13
- it 'matches on class symbol' do
14
- expect(matcher).to be_matches(:UncommunicativeVariableName)
15
- end
16
-
17
- it 'matches on class symbol and params' do
18
- expect(matcher).to be_matches(:UncommunicativeVariableName,
19
- test: 'something')
20
- end
21
-
22
- it 'matches on class symbol, params and attributes' do
23
- expect(matcher).to be_matches(:UncommunicativeVariableName,
24
- test: 'something',
25
- message: "has the variable name '@s'")
26
- end
27
-
28
- it 'does not match on different class symbol' do
29
- expect(matcher).not_to be_matches(:FeatureEnvy)
30
- end
31
-
32
- it 'does not match on different params' do
33
- expect(matcher).not_to be_matches(:UncommunicativeVariableName,
34
- test: 'something else')
35
- end
36
-
37
- it 'does not match on different attributes' do
38
- expect(matcher).not_to be_matches(:UncommunicativeVariableName,
39
- test: 'something',
40
- message: 'nothing')
41
- end
42
-
43
- it 'raises error on uncomparable attribute' do
44
- expect do
45
- matcher.matches?(:UncommunicativeVariableName,
46
- test: 'something',
47
- random: 'nothing')
48
- end.to raise_error("The attribute 'random' is not available for comparison")
49
- end
50
- end
51
-
52
- describe '#matches_smell_type?' do
53
- it 'matches on class symbol' do
54
- expect(matcher).to be_matches_smell_type(:UncommunicativeVariableName)
55
- end
56
-
57
- it 'does not match on different class symbol' do
58
- expect(matcher).not_to be_matches_smell_type(:FeatureEnvy)
59
- end
60
- end
61
-
62
- describe '#matches_attributes?' do
63
- it 'matches on params' do
64
- expect(matcher).to be_matches_attributes(test: 'something')
65
- end
66
-
67
- it 'matches on class symbol, params and attributes' do
68
- expect(matcher).to be_matches_attributes(test: 'something',
69
- message: "has the variable name '@s'")
70
- end
71
-
72
- it 'does not match on different params' do
73
- expect(matcher).not_to be_matches_attributes(test: 'something else')
74
- end
75
-
76
- it 'does not match on different attributes' do
77
- expect(matcher).not_to be_matches_attributes(test: 'something',
78
- message: 'nothing')
79
- end
80
-
81
- it 'raises error on uncomparable attribute' do
82
- expect do
83
- matcher.matches_attributes? test: 'something', random: 'nothing'
84
- end.to raise_error("The attribute 'random' is not available for comparison")
85
- end
86
- end
87
- end
@@ -1,46 +0,0 @@
1
- require_relative '../spec_helper'
2
- Reek::CLI::Silencer.without_warnings { require 'parser/ruby25' }
3
- require_lib 'reek/tree_dresser'
4
-
5
- RSpec.describe Reek::TreeDresser do
6
- describe '#dress' do
7
- let(:dresser) { described_class.new }
8
- let(:sexp) do
9
- Parser::Ruby25.parse('class Klazz; def meth(argument); argument.call_me; end; end')
10
- end
11
- let(:dressed_ast) { dresser.dress(sexp, {}) }
12
-
13
- # The dressed AST looks like this:
14
- # (class
15
- # (const nil :Klazz) nil
16
- # (def :meth
17
- # (args
18
- # (arg :argument))
19
- # (send
20
- # (lvar :argument) :call_me)))
21
- let(:const_node) { dressed_ast.children.first }
22
- let(:def_node) { dressed_ast.children.last }
23
- let(:args_node) { def_node.children[1] }
24
- let(:send_node) { def_node.children[2] }
25
-
26
- it 'dresses `const` nodes properly' do
27
- expect(const_node).to be_a Reek::AST::SexpExtensions::ConstNode
28
- end
29
-
30
- it 'dresses `def` nodes properly' do
31
- expect(def_node).
32
- to be_a(Reek::AST::SexpExtensions::DefNode).
33
- and be_a(Reek::AST::SexpExtensions::MethodNodeBase)
34
- end
35
-
36
- it 'dresses `args` nodes properly' do
37
- expect(args_node).
38
- to be_a(Reek::AST::SexpExtensions::ArgsNode).
39
- and be_a(Reek::AST::SexpExtensions::NestedAssignables)
40
- end
41
-
42
- it 'dresses `send` nodes properly' do
43
- expect(send_node).to be_a Reek::AST::SexpExtensions::SendNode
44
- end
45
- end
46
- end
data/spec/spec_helper.rb DELETED
@@ -1,110 +0,0 @@
1
- require 'pathname'
2
- require 'timeout'
3
- require 'rspec-benchmark'
4
- require_relative '../lib/reek'
5
- require_relative '../lib/reek/spec'
6
- require_relative '../lib/reek/ast/ast_node_class_map'
7
- require_relative '../lib/reek/configuration/app_configuration'
8
-
9
- require_relative '../samples/paths'
10
-
11
- begin
12
- Reek::CLI::Silencer.without_warnings { require 'pry-byebug' }
13
- rescue LoadError # rubocop:disable Lint/SuppressedException
14
- end
15
-
16
- # Simple helpers for our specs.
17
- module Helpers
18
- def test_configuration_for(config)
19
- case config
20
- when Pathname
21
- configuration = Reek::Configuration::AppConfiguration.from_path(config)
22
- when Hash
23
- configuration = Reek::Configuration::AppConfiguration.from_hash config
24
- else
25
- raise "Unknown config given in `test_configuration_for`: #{config.inspect}"
26
- end
27
- configuration
28
- end
29
-
30
- # @param code [String] The given code.
31
- #
32
- # @return syntax_tree [Reek::AST::Node]
33
- def syntax_tree(code)
34
- Reek::Source::SourceCode.from(code).syntax_tree
35
- end
36
-
37
- # @param code [String] The given code.
38
- #
39
- # @return syntax_tree [Reek::Context::CodeContext]
40
- def code_context(code)
41
- Reek::Context::CodeContext.new(nil, syntax_tree(code))
42
- end
43
-
44
- # @param code [String] The given code.
45
- #
46
- # @return syntax_tree [Reek::Context::MethodContext]
47
- def method_context(code)
48
- Reek::Context::MethodContext.new(nil, syntax_tree(code))
49
- end
50
-
51
- # Helper methods to generate a configuration for smell types that support
52
- # `accept` and `reject` settings.
53
- %w(accept reject).each do |switch|
54
- define_method("#{switch}_configuration_for") do |smell_type, pattern:|
55
- hash = {
56
- smell_type => {
57
- switch => pattern
58
- }
59
- }
60
- Reek::Configuration::AppConfiguration.from_hash(hash)
61
- end
62
- end
63
-
64
- # :reek:UncommunicativeMethodName
65
- def sexp(type, *children)
66
- @klass_map ||= Reek::AST::ASTNodeClassMap.new
67
- @klass_map.klass_for(type).new(type, children)
68
- end
69
-
70
- def build_smell_warning(smell_type: 'FeatureEnvy',
71
- context: 'self',
72
- lines: [42],
73
- message: 'smell warning message',
74
- source: 'dummy_file',
75
- parameters: {})
76
- Reek::SmellWarning.new(smell_type,
77
- context: context,
78
- lines: lines,
79
- message: message,
80
- source: source,
81
- parameters: parameters)
82
- end
83
-
84
- def build_code_comment(comment: '', line: 1, source: 'string')
85
- Reek::CodeComment.new(comment: comment, line: line, source: source)
86
- end
87
- end
88
-
89
- RSpec.configure do |config|
90
- config.filter_run :focus
91
- config.run_all_when_everything_filtered = true
92
- config.include Helpers
93
- config.include RSpec::Benchmark::Matchers
94
- config.example_status_persistence_file_path = 'spec/examples.txt'
95
-
96
- config.disable_monkey_patching!
97
-
98
- config.mock_with :rspec do |mocks|
99
- mocks.verify_partial_doubles = true
100
- mocks.verify_doubled_constant_names = true
101
- end
102
- end
103
-
104
- RSpec::Matchers.define_negated_matcher :not_reek_of, :reek_of
105
-
106
- private
107
-
108
- def require_lib(path)
109
- require_relative "../lib/#{path}"
110
- end
@@ -1,18 +0,0 @@
1
- require_relative '../lib/reek'
2
- require_relative '../lib/reek/detector_repository'
3
- require_relative '../lib/reek/configuration/rake_task_converter'
4
- require_relative '../lib/reek/configuration/app_configuration'
5
-
6
- require 'yaml'
7
-
8
- namespace :configuration do
9
- desc 'Updates the default configuration file when smell defaults change'
10
- task :update_default_configuration do
11
- content = Reek::DetectorRepository.smell_types.each_with_object({}) do |klass, hash|
12
- hash[klass.smell_type] = Reek::Configuration::RakeTaskConverter.convert klass.default_config
13
- end
14
- File.open(Reek::DEFAULT_SMELL_CONFIGURATION, 'w') do |file|
15
- YAML.dump({ Reek::DETECTORS_KEY => content }, file)
16
- end
17
- end
18
- end
data/tasks/console.rake DELETED
@@ -1,5 +0,0 @@
1
- desc 'Starts the interactive console'
2
- task :console do
3
- require 'pry'
4
- Pry.start
5
- end
data/tasks/reek.rake DELETED
@@ -1,6 +0,0 @@
1
- require_relative '../lib/reek/rake/task'
2
-
3
- Reek::Rake::Task.new do |t|
4
- t.fail_on_error = true
5
- t.verbose = false
6
- end
data/tasks/rubocop.rake DELETED
@@ -1,11 +0,0 @@
1
- begin
2
- require 'rubocop/rake_task'
3
-
4
- RuboCop::RakeTask.new do |task|
5
- task.options << '--display-cop-names'
6
- end
7
- rescue LoadError
8
- task :rubocop do
9
- puts 'Install rubocop to run its rake tasks'
10
- end
11
- end
data/tasks/test.rake DELETED
@@ -1,32 +0,0 @@
1
- require 'cucumber/rake/task'
2
- require 'rspec/core/rake_task'
3
-
4
- namespace 'test' do
5
- RSpec::Core::RakeTask.new('spec') do |t|
6
- t.pattern = 'spec/reek/**/*_spec.rb'
7
- t.ruby_opts = ['-rbundler/setup -rsimplecov -Ilib -w']
8
- end
9
-
10
- RSpec::Core::RakeTask.new('performance') do |t|
11
- t.pattern = 'spec/performance/**/*_spec.rb'
12
- end
13
-
14
- desc 'Tests code quality'
15
- RSpec::Core::RakeTask.new('quality') do |t|
16
- t.pattern = 'spec/quality/**/*_spec.rb'
17
- t.ruby_opts = ['-rbundler/setup -Ilib']
18
- end
19
-
20
- Cucumber::Rake::Task.new(:features) do |t|
21
- t.cucumber_opts = 'features --format progress --color'
22
- end
23
-
24
- desc 'Runs all unit tests and acceptance tests'
25
- task 'all' => ['test:spec', 'test:features']
26
- end
27
-
28
- desc 'Synonym for test:spec'
29
- task 'spec' => 'test:spec'
30
-
31
- desc 'Synonym for test:all'
32
- task 'test' => 'test:all'