ridecharge-rubocop 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (219) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +14 -0
  5. data/CHANGELOG.md +0 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +35 -0
  9. data/Rakefile +22 -0
  10. data/bin/ridecharge-rubocop +49 -0
  11. data/config/0default.yml +8 -0
  12. data/config/fleet-magic-todo.yml +380 -0
  13. data/config/rc-todo.yml +190 -0
  14. data/config/ridecharge-rubocop_todo.yml +73 -0
  15. data/config/rubocop/default.yml +308 -0
  16. data/config/rubocop/disabled.yml +9 -0
  17. data/config/rubocop/enabled.yml +648 -0
  18. data/config/standard-todo.yml +24 -0
  19. data/config/tabs.yml +15 -0
  20. data/config/vehicle-todo.yml +195 -0
  21. data/lib/ridecharge/rubocop.rb +2 -0
  22. data/lib/ridecharge/rubocop/version.rb +5 -0
  23. data/lib/rubocop/config_loader_monkeypatch.rb +117 -0
  24. data/lib/rubocop/ridecharge.rb +1 -0
  25. data/ridecharge-rubocop.gemspec +25 -0
  26. data/spec/isolated_environment_spec.rb +24 -0
  27. data/spec/project_spec.rb +118 -0
  28. data/spec/rubocop/cli_spec.rb +1385 -0
  29. data/spec/rubocop/config_loader_spec.rb +328 -0
  30. data/spec/rubocop/config_spec.rb +179 -0
  31. data/spec/rubocop/config_store_spec.rb +53 -0
  32. data/spec/rubocop/cop/commissioner_spec.rb +83 -0
  33. data/spec/rubocop/cop/cop_spec.rb +114 -0
  34. data/spec/rubocop/cop/corrector_spec.rb +59 -0
  35. data/spec/rubocop/cop/lint/ambiguous_operator_spec.rb +113 -0
  36. data/spec/rubocop/cop/lint/ambiguous_regexp_literal_spec.rb +35 -0
  37. data/spec/rubocop/cop/lint/assignment_in_condition_spec.rb +107 -0
  38. data/spec/rubocop/cop/lint/block_alignment_spec.rb +411 -0
  39. data/spec/rubocop/cop/lint/condition_position_spec.rb +49 -0
  40. data/spec/rubocop/cop/lint/debugger_spec.rb +39 -0
  41. data/spec/rubocop/cop/lint/else_layout_spec.rb +65 -0
  42. data/spec/rubocop/cop/lint/empty_ensure_spec.rb +27 -0
  43. data/spec/rubocop/cop/lint/end_alignment_spec.rb +136 -0
  44. data/spec/rubocop/cop/lint/end_in_method_spec.rb +29 -0
  45. data/spec/rubocop/cop/lint/ensure_return_spec.rb +39 -0
  46. data/spec/rubocop/cop/lint/eval_spec.rb +35 -0
  47. data/spec/rubocop/cop/lint/handle_exceptions_spec.rb +30 -0
  48. data/spec/rubocop/cop/lint/invalid_character_literal_spec.rb +33 -0
  49. data/spec/rubocop/cop/lint/literal_in_condition_spec.rb +63 -0
  50. data/spec/rubocop/cop/lint/loop_spec.rb +27 -0
  51. data/spec/rubocop/cop/lint/parentheses_as_grouped_expression_spec.rb +57 -0
  52. data/spec/rubocop/cop/lint/require_parentheses_spec.rb +82 -0
  53. data/spec/rubocop/cop/lint/rescue_exception_spec.rb +131 -0
  54. data/spec/rubocop/cop/lint/shadowing_outer_local_variable_spec.rb +237 -0
  55. data/spec/rubocop/cop/lint/syntax_spec.rb +34 -0
  56. data/spec/rubocop/cop/lint/unreachable_code_spec.rb +63 -0
  57. data/spec/rubocop/cop/lint/useless_assignment_spec.rb +1570 -0
  58. data/spec/rubocop/cop/lint/useless_comparison_spec.rb +30 -0
  59. data/spec/rubocop/cop/lint/useless_else_without_rescue_spec.rb +48 -0
  60. data/spec/rubocop/cop/lint/useless_setter_call_spec.rb +149 -0
  61. data/spec/rubocop/cop/lint/void_spec.rb +57 -0
  62. data/spec/rubocop/cop/offence_spec.rb +133 -0
  63. data/spec/rubocop/cop/rails/default_scope_spec.rb +37 -0
  64. data/spec/rubocop/cop/rails/has_and_belongs_to_many_spec.rb +13 -0
  65. data/spec/rubocop/cop/rails/output_spec.rb +41 -0
  66. data/spec/rubocop/cop/rails/read_attribute_spec.rb +13 -0
  67. data/spec/rubocop/cop/rails/validation_spec.rb +21 -0
  68. data/spec/rubocop/cop/style/access_modifier_indentation_spec.rb +361 -0
  69. data/spec/rubocop/cop/style/accessor_method_name_spec.rb +81 -0
  70. data/spec/rubocop/cop/style/alias_spec.rb +59 -0
  71. data/spec/rubocop/cop/style/align_array_spec.rb +75 -0
  72. data/spec/rubocop/cop/style/align_hash_spec.rb +310 -0
  73. data/spec/rubocop/cop/style/align_parameters_spec.rb +222 -0
  74. data/spec/rubocop/cop/style/and_or_spec.rb +57 -0
  75. data/spec/rubocop/cop/style/ascii_comments_spec.rb +22 -0
  76. data/spec/rubocop/cop/style/ascii_identifiers_spec.rb +36 -0
  77. data/spec/rubocop/cop/style/attr_spec.rb +19 -0
  78. data/spec/rubocop/cop/style/begin_block_spec.rb +13 -0
  79. data/spec/rubocop/cop/style/block_comments_spec.rb +21 -0
  80. data/spec/rubocop/cop/style/block_nesting_spec.rb +156 -0
  81. data/spec/rubocop/cop/style/blocks_spec.rb +99 -0
  82. data/spec/rubocop/cop/style/braces_around_hash_parameters_spec.rb +284 -0
  83. data/spec/rubocop/cop/style/case_equality_spec.rb +12 -0
  84. data/spec/rubocop/cop/style/case_indentation_spec.rb +289 -0
  85. data/spec/rubocop/cop/style/character_literal_spec.rb +37 -0
  86. data/spec/rubocop/cop/style/class_and_module_camel_case_spec.rb +40 -0
  87. data/spec/rubocop/cop/style/class_length_spec.rb +131 -0
  88. data/spec/rubocop/cop/style/class_methods_spec.rb +45 -0
  89. data/spec/rubocop/cop/style/class_vars_spec.rb +19 -0
  90. data/spec/rubocop/cop/style/collection_methods_spec.rb +48 -0
  91. data/spec/rubocop/cop/style/colon_method_call_spec.rb +60 -0
  92. data/spec/rubocop/cop/style/comment_annotation_spec.rb +86 -0
  93. data/spec/rubocop/cop/style/constant_name_spec.rb +65 -0
  94. data/spec/rubocop/cop/style/cyclomatic_complexity_spec.rb +204 -0
  95. data/spec/rubocop/cop/style/def_with_parentheses_spec.rb +39 -0
  96. data/spec/rubocop/cop/style/documentation_spec.rb +123 -0
  97. data/spec/rubocop/cop/style/dot_position_spec.rb +94 -0
  98. data/spec/rubocop/cop/style/empty_line_between_defs_spec.rb +127 -0
  99. data/spec/rubocop/cop/style/empty_lines_around_access_modifier_spec.rb +56 -0
  100. data/spec/rubocop/cop/style/empty_lines_around_body_spec.rb +131 -0
  101. data/spec/rubocop/cop/style/empty_lines_spec.rb +40 -0
  102. data/spec/rubocop/cop/style/empty_literal_spec.rb +100 -0
  103. data/spec/rubocop/cop/style/encoding_spec.rb +56 -0
  104. data/spec/rubocop/cop/style/end_block_spec.rb +13 -0
  105. data/spec/rubocop/cop/style/end_of_line_spec.rb +47 -0
  106. data/spec/rubocop/cop/style/even_odd_spec.rb +75 -0
  107. data/spec/rubocop/cop/style/favor_join_spec.rb +31 -0
  108. data/spec/rubocop/cop/style/favor_sprintf_spec.rb +47 -0
  109. data/spec/rubocop/cop/style/favor_unless_over_negated_if_spec.rb +76 -0
  110. data/spec/rubocop/cop/style/favor_until_over_negated_while_spec.rb +41 -0
  111. data/spec/rubocop/cop/style/final_newline_spec.rb +30 -0
  112. data/spec/rubocop/cop/style/flip_flop_spec.rb +23 -0
  113. data/spec/rubocop/cop/style/for_spec.rb +105 -0
  114. data/spec/rubocop/cop/style/global_vars_spec.rb +34 -0
  115. data/spec/rubocop/cop/style/hash_methods_spec.rb +45 -0
  116. data/spec/rubocop/cop/style/hash_syntax_spec.rb +131 -0
  117. data/spec/rubocop/cop/style/if_unless_modifier_spec.rb +128 -0
  118. data/spec/rubocop/cop/style/if_with_semicolon_spec.rb +19 -0
  119. data/spec/rubocop/cop/style/indentation_consistency_spec.rb +490 -0
  120. data/spec/rubocop/cop/style/indentation_width_spec.rb +470 -0
  121. data/spec/rubocop/cop/style/lambda_call_spec.rb +65 -0
  122. data/spec/rubocop/cop/style/lambda_spec.rb +41 -0
  123. data/spec/rubocop/cop/style/leading_comment_space_spec.rb +64 -0
  124. data/spec/rubocop/cop/style/line_end_concatenation_spec.rb +34 -0
  125. data/spec/rubocop/cop/style/line_length_spec.rb +20 -0
  126. data/spec/rubocop/cop/style/method_call_parentheses_spec.rb +59 -0
  127. data/spec/rubocop/cop/style/method_called_on_do_end_block_spec.rb +60 -0
  128. data/spec/rubocop/cop/style/method_def_parentheses_spec.rb +106 -0
  129. data/spec/rubocop/cop/style/method_length_spec.rb +147 -0
  130. data/spec/rubocop/cop/style/method_name_spec.rb +125 -0
  131. data/spec/rubocop/cop/style/module_function_spec.rb +24 -0
  132. data/spec/rubocop/cop/style/multiline_block_chain_spec.rb +78 -0
  133. data/spec/rubocop/cop/style/multiline_if_then_spec.rb +107 -0
  134. data/spec/rubocop/cop/style/multiline_ternary_operator_spec.rb +18 -0
  135. data/spec/rubocop/cop/style/nested_ternary_operator_spec.rb +21 -0
  136. data/spec/rubocop/cop/style/nil_comparison_spec.rb +30 -0
  137. data/spec/rubocop/cop/style/not_spec.rb +22 -0
  138. data/spec/rubocop/cop/style/numeric_literals_spec.rb +64 -0
  139. data/spec/rubocop/cop/style/one_line_conditional_spec.rb +13 -0
  140. data/spec/rubocop/cop/style/op_method_spec.rb +74 -0
  141. data/spec/rubocop/cop/style/parameter_lists_spec.rb +44 -0
  142. data/spec/rubocop/cop/style/parentheses_around_condition_spec.rb +122 -0
  143. data/spec/rubocop/cop/style/perl_backrefs_spec.rb +17 -0
  144. data/spec/rubocop/cop/style/predicate_name_spec.rb +25 -0
  145. data/spec/rubocop/cop/style/proc_spec.rb +27 -0
  146. data/spec/rubocop/cop/style/raise_args_spec.rb +82 -0
  147. data/spec/rubocop/cop/style/redundant_begin_spec.rb +57 -0
  148. data/spec/rubocop/cop/style/redundant_exception_spec.rb +27 -0
  149. data/spec/rubocop/cop/style/redundant_return_spec.rb +171 -0
  150. data/spec/rubocop/cop/style/redundant_self_spec.rb +142 -0
  151. data/spec/rubocop/cop/style/regexp_literal_spec.rb +83 -0
  152. data/spec/rubocop/cop/style/rescue_modifier_spec.rb +116 -0
  153. data/spec/rubocop/cop/style/semicolon_spec.rb +100 -0
  154. data/spec/rubocop/cop/style/signal_exception_spec.rb +266 -0
  155. data/spec/rubocop/cop/style/single_line_block_params_spec.rb +68 -0
  156. data/spec/rubocop/cop/style/single_line_methods_spec.rb +52 -0
  157. data/spec/rubocop/cop/style/space_after_colon_spec.rb +38 -0
  158. data/spec/rubocop/cop/style/space_after_comma_spec.rb +30 -0
  159. data/spec/rubocop/cop/style/space_after_control_keyword_spec.rb +84 -0
  160. data/spec/rubocop/cop/style/space_after_method_name_spec.rb +70 -0
  161. data/spec/rubocop/cop/style/space_after_not_spec.rb +22 -0
  162. data/spec/rubocop/cop/style/space_after_semicolon_spec.rb +23 -0
  163. data/spec/rubocop/cop/style/space_around_block_braces_spec.rb +283 -0
  164. data/spec/rubocop/cop/style/space_around_equals_in_parameter_default_spec.rb +33 -0
  165. data/spec/rubocop/cop/style/space_around_operators_spec.rb +325 -0
  166. data/spec/rubocop/cop/style/space_before_modifier_keyword_spec.rb +70 -0
  167. data/spec/rubocop/cop/style/space_inside_brackets_spec.rb +52 -0
  168. data/spec/rubocop/cop/style/space_inside_hash_literal_braces_spec.rb +138 -0
  169. data/spec/rubocop/cop/style/space_inside_parens_spec.rb +34 -0
  170. data/spec/rubocop/cop/style/special_global_vars_spec.rb +56 -0
  171. data/spec/rubocop/cop/style/string_literals_spec.rb +212 -0
  172. data/spec/rubocop/cop/style/symbol_array_spec.rb +37 -0
  173. data/spec/rubocop/cop/style/tab_spec.rb +17 -0
  174. data/spec/rubocop/cop/style/trailing_blank_lines_spec.rb +43 -0
  175. data/spec/rubocop/cop/style/trailing_comma_spec.rb +230 -0
  176. data/spec/rubocop/cop/style/trailing_whitespace_spec.rb +30 -0
  177. data/spec/rubocop/cop/style/trivial_accessors_spec.rb +415 -0
  178. data/spec/rubocop/cop/style/unless_else_spec.rb +25 -0
  179. data/spec/rubocop/cop/style/variable_interpolation_spec.rb +47 -0
  180. data/spec/rubocop/cop/style/variable_name_spec.rb +107 -0
  181. data/spec/rubocop/cop/style/when_then_spec.rb +41 -0
  182. data/spec/rubocop/cop/style/while_until_do_spec.rb +53 -0
  183. data/spec/rubocop/cop/style/while_until_modifier_spec.rb +75 -0
  184. data/spec/rubocop/cop/style/word_array_spec.rb +97 -0
  185. data/spec/rubocop/cop/team_spec.rb +156 -0
  186. data/spec/rubocop/cop/util_spec.rb +49 -0
  187. data/spec/rubocop/cop/variable_inspector/assignment_spec.rb +213 -0
  188. data/spec/rubocop/cop/variable_inspector/locatable_spec.rb +734 -0
  189. data/spec/rubocop/cop/variable_inspector/scope_spec.rb +184 -0
  190. data/spec/rubocop/cop/variable_inspector/variable_spec.rb +73 -0
  191. data/spec/rubocop/cop/variable_inspector/variable_table_spec.rb +269 -0
  192. data/spec/rubocop/cop/variable_inspector_spec.rb +29 -0
  193. data/spec/rubocop/file_inspector_spec.rb +78 -0
  194. data/spec/rubocop/formatter/base_formatter_spec.rb +191 -0
  195. data/spec/rubocop/formatter/clang_style_formatter_spec.rb +114 -0
  196. data/spec/rubocop/formatter/colorizable_spec.rb +107 -0
  197. data/spec/rubocop/formatter/disabled_config_formatter_spec.rb +50 -0
  198. data/spec/rubocop/formatter/emacs_style_formatter_spec.rb +62 -0
  199. data/spec/rubocop/formatter/file_list_formatter_spec.rb +33 -0
  200. data/spec/rubocop/formatter/formatter_set_spec.rb +132 -0
  201. data/spec/rubocop/formatter/json_formatter_spec.rb +148 -0
  202. data/spec/rubocop/formatter/offence_count_formatter_spec.rb +52 -0
  203. data/spec/rubocop/formatter/progress_formatter_spec.rb +182 -0
  204. data/spec/rubocop/formatter/simple_text_formatter_spec.rb +123 -0
  205. data/spec/rubocop/options_spec.rb +145 -0
  206. data/spec/rubocop/path_util_spec.rb +42 -0
  207. data/spec/rubocop/processed_source_spec.rb +114 -0
  208. data/spec/rubocop/source_parser_spec.rb +139 -0
  209. data/spec/rubocop/target_finder_spec.rb +180 -0
  210. data/spec/rubocop/token_spec.rb +25 -0
  211. data/spec/spec_helper.rb +136 -0
  212. data/spec/support/ast_helper.rb +15 -0
  213. data/spec/support/file_helper.rb +21 -0
  214. data/spec/support/isolated_environment.rb +34 -0
  215. data/spec/support/mri_syntax_checker.rb +73 -0
  216. data/spec/support/shared_context.rb +22 -0
  217. data/spec/support/shared_examples.rb +33 -0
  218. data/spec/support/statement_modifier_helper.rb +41 -0
  219. metadata +511 -0
@@ -0,0 +1,1385 @@
1
+ # encoding: utf-8
2
+
3
+ require 'fileutils'
4
+ require 'tmpdir'
5
+ require 'spec_helper'
6
+
7
+ describe Rubocop::CLI, :isolated_environment do
8
+ include FileHelper
9
+
10
+ subject(:cli) { described_class.new }
11
+
12
+ before(:each) do
13
+ $stdout = StringIO.new
14
+ $stderr = StringIO.new
15
+ Rubocop::ConfigLoader.debug = false
16
+ end
17
+
18
+ after(:each) do
19
+ $stdout = STDOUT
20
+ $stderr = STDERR
21
+ end
22
+
23
+ def abs(path)
24
+ File.expand_path(path)
25
+ end
26
+
27
+ describe 'option' do
28
+ describe '--version' do
29
+ it 'exits cleanly' do
30
+ expect { cli.run ['-v'] }.to exit_with_code(0)
31
+ expect { cli.run ['--version'] }.to exit_with_code(0)
32
+ expect($stdout.string).to eq((Rubocop::Version::STRING + "\n") * 2)
33
+ end
34
+ end
35
+
36
+ describe '--auto-correct' do
37
+ it 'can correct two problems with blocks' do
38
+ # {} should be do..end and space is missing.
39
+ create_file('example.rb', ['# encoding: utf-8',
40
+ '(1..10).each{ |i|',
41
+ ' puts i',
42
+ '}'])
43
+ expect(cli.run(['--auto-correct'])).to eq(1)
44
+ expect(IO.read('example.rb'))
45
+ .to eq(['# encoding: utf-8',
46
+ '(1..10).each do |i|',
47
+ ' puts i',
48
+ 'end'].join("\n") + "\n")
49
+ end
50
+
51
+ # In this example, the auto-correction (changing "raise" to "fail")
52
+ # creates a new problem (alignment of parameters), which is also
53
+ # corrected automatically.
54
+ it 'can correct a problems and the problem it creates' do
55
+ create_file('example.rb',
56
+ ['# encoding: utf-8',
57
+ 'raise NotImplementedError,',
58
+ " 'Method should be overridden in child classes'"])
59
+ expect(cli.run(['--auto-correct'])).to eq(1)
60
+ expect(IO.read('example.rb'))
61
+ .to eq(['# encoding: utf-8',
62
+ 'fail NotImplementedError,',
63
+ " 'Method should be overridden in child classes'"]
64
+ .join("\n") + "\n")
65
+ expect($stdout.string)
66
+ .to eq(['Inspecting 1 file',
67
+ 'C',
68
+ '',
69
+ 'Offences:',
70
+ '',
71
+ 'example.rb:2:1: C: [Corrected] Use `fail` instead of ' \
72
+ '`raise` to signal exceptions.',
73
+ 'raise NotImplementedError,',
74
+ '^^^^^',
75
+ 'example.rb:3:7: C: [Corrected] Align the parameters of a ' \
76
+ 'method call if they span more than one line.',
77
+ " 'Method should be overridden in child classes'",
78
+ ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^',
79
+ '',
80
+ '1 file inspected, 2 offences detected, 2 offences ' \
81
+ 'corrected',
82
+ ''].join("\n"))
83
+ end
84
+
85
+ # Thanks to repeated auto-correction, we can get rid of the trailing
86
+ # spaces, and then the extra empty line.
87
+ it 'can correct two problems in the same place' do
88
+ create_file('example.rb',
89
+ ['# encoding: utf-8',
90
+ '# Example class.',
91
+ 'class Klass',
92
+ ' ',
93
+ ' def f',
94
+ ' end',
95
+ 'end'])
96
+ expect(cli.run(['--auto-correct'])).to eq(1)
97
+ expect(IO.read('example.rb'))
98
+ .to eq(['# encoding: utf-8',
99
+ '# Example class.',
100
+ 'class Klass',
101
+ ' def f',
102
+ ' end',
103
+ 'end'].join("\n") + "\n")
104
+ expect($stderr.string).to eq('')
105
+ expect($stdout.string)
106
+ .to eq(['Inspecting 1 file',
107
+ 'C',
108
+ '',
109
+ 'Offences:',
110
+ '',
111
+ 'example.rb:4:1: C: [Corrected] Trailing whitespace ' \
112
+ 'detected.',
113
+ 'example.rb:4:1: C: [Corrected] Extra empty line detected ' \
114
+ 'at body beginning.',
115
+ '',
116
+ '1 file inspected, 2 offences detected, 2 offences ' \
117
+ 'corrected',
118
+ ''].join("\n"))
119
+ end
120
+ end
121
+
122
+ describe '--auto-gen-config' do
123
+ it 'exits with error if asked to re-generate a todo list that is in ' \
124
+ 'use' do
125
+ create_file('example1.rb', ['# encoding: utf-8',
126
+ 'x= 0 ',
127
+ '#' * 85,
128
+ 'y ',
129
+ 'puts x'])
130
+ todo_contents = ['# This configuration was generated with `rubocop' \
131
+ ' --auto-gen-config`',
132
+ '',
133
+ 'LineLength:',
134
+ ' Enabled: false']
135
+ create_file('rubocop-todo.yml', todo_contents)
136
+ expect(IO.read('rubocop-todo.yml'))
137
+ .to eq(todo_contents.join("\n") + "\n")
138
+ create_file('.rubocop.yml', ['inherit_from: rubocop-todo.yml'])
139
+ expect(cli.run(['--auto-gen-config'])).to eq(1)
140
+ expect($stderr.string).to eq('Remove rubocop-todo.yml from the ' \
141
+ 'current configuration before ' +
142
+ "generating it again.\n")
143
+ end
144
+
145
+ it 'exits with error if file arguments are given' do
146
+ create_file('example1.rb', ['# encoding: utf-8',
147
+ 'x= 0 ',
148
+ '#' * 85,
149
+ 'y ',
150
+ 'puts x'])
151
+ expect(cli.run(['--auto-gen-config', 'example1.rb'])).to eq(1)
152
+ expect($stderr.string)
153
+ .to eq('--auto-gen-config can not be combined with any other ' \
154
+ "arguments.\n")
155
+ expect($stdout.string).to eq('')
156
+ end
157
+
158
+ it 'can generate a todo list' do
159
+ create_file('example1.rb', ['# encoding: utf-8',
160
+ '$x= 0 ',
161
+ '#' * 90,
162
+ '#' * 85,
163
+ 'y ',
164
+ 'puts x'])
165
+ create_file('example2.rb', ['# encoding: utf-8',
166
+ "\tx = 0",
167
+ 'puts x'])
168
+ expect(cli.run(['--auto-gen-config'])).to eq(1)
169
+ expect($stderr.string).to eq('')
170
+ expect($stdout.string)
171
+ .to include([
172
+ 'Created rubocop-todo.yml.',
173
+ 'Run rubocop with --config rubocop-todo.yml, or',
174
+ 'add inherit_from: rubocop-todo.yml in a ' \
175
+ '.rubocop.yml file.',
176
+ ''].join("\n"))
177
+ expected =
178
+ ['# This configuration was generated by `rubocop --auto-gen-config`',
179
+ /# on .* using RuboCop version .*/,
180
+ '# The point is for the user to remove these configuration records',
181
+ '# one by one as the offences are removed from the code base.',
182
+ '# Note that changes in the inspected code, or installation of new',
183
+ '# versions of RuboCop, may require this file to be generated ' \
184
+ 'again.',
185
+ '',
186
+ '# Offence count: 1',
187
+ '# Configuration parameters: AllowedVariables.',
188
+ 'GlobalVars:',
189
+ ' Enabled: false',
190
+ '',
191
+ '# Offence count: 1',
192
+ 'IndentationConsistency:',
193
+ ' Enabled: false',
194
+ '',
195
+ '# Offence count: 2',
196
+ 'LineLength:',
197
+ ' Max: 90',
198
+ '',
199
+ '# Offence count: 1',
200
+ '# Cop supports --auto-correct.',
201
+ 'SpaceAroundOperators:',
202
+ ' Enabled: false',
203
+ '',
204
+ '# Offence count: 1',
205
+ 'Tab:',
206
+ ' Enabled: false',
207
+ '',
208
+ '# Offence count: 2',
209
+ '# Cop supports --auto-correct.',
210
+ 'TrailingWhitespace:',
211
+ ' Enabled: false']
212
+ actual = IO.read('rubocop-todo.yml').split($RS)
213
+ expected.each_with_index do |line, ix|
214
+ if line.is_a?(String)
215
+ expect(actual[ix]).to eq(line)
216
+ else
217
+ expect(actual[ix]).to match(line)
218
+ end
219
+ end
220
+ end
221
+ end
222
+
223
+ describe '--only' do
224
+ it 'runs just one cop' do
225
+ create_file('example.rb', ['if x== 0 ',
226
+ "\ty",
227
+ 'end'])
228
+ # IfUnlessModifier depends on the configuration of LineLength.
229
+
230
+ expect(cli.run(['--format', 'simple',
231
+ '--only', 'IfUnlessModifier',
232
+ 'example.rb'])).to eq(1)
233
+ expect($stdout.string)
234
+ .to eq(['== example.rb ==',
235
+ 'C: 1: 1: Favor modifier if usage when you ' \
236
+ 'have a single-line body. Another good alternative is ' +
237
+ 'the usage of control flow &&/||.',
238
+ '',
239
+ '1 file inspected, 1 offence detected',
240
+ ''].join("\n"))
241
+ end
242
+ end
243
+
244
+ describe '--lint' do
245
+ it 'runs only lint cops' do
246
+ create_file('example.rb', ['if 0 ',
247
+ "\ty",
248
+ 'end'])
249
+ # IfUnlessModifier depends on the configuration of LineLength.
250
+
251
+ expect(cli.run(['--format', 'simple', '--lint',
252
+ 'example.rb'])).to eq(1)
253
+ expect($stdout.string)
254
+ .to eq(['== example.rb ==',
255
+ 'W: 1: 4: Literal 0 appeared in a condition.',
256
+ '',
257
+ '1 file inspected, 1 offence detected',
258
+ ''].join("\n"))
259
+ end
260
+ end
261
+
262
+ describe '-d/--debug' do
263
+ it 'shows config files' do
264
+ create_file('example1.rb', "\tputs 0")
265
+ expect(cli.run(['--debug', 'example1.rb'])).to eq(1)
266
+ home = File.dirname(File.dirname(File.dirname(__FILE__)))
267
+ expect($stdout.string.lines.grep(/configuration/).map(&:chomp))
268
+ .to eq(["For #{abs('')}:" +
269
+ " configuration from #{home}/config/default.yml",
270
+ "Inheriting configuration from #{home}/config/enabled.yml",
271
+ "Inheriting configuration from #{home}/config/disabled.yml"
272
+ ])
273
+ end
274
+
275
+ it 'shows cop names' do
276
+ create_file('example1.rb', "\tputs 0")
277
+ expect(cli.run(['--format',
278
+ 'emacs',
279
+ '--debug',
280
+ 'example1.rb'])).to eq(1)
281
+ expect($stdout.string.lines.to_a[-1])
282
+ .to eq(["#{abs('example1.rb')}:1:1: C: Tab: Tab detected.",
283
+ ''].join("\n"))
284
+ end
285
+ end
286
+
287
+ describe '-D/--display-cop-names' do
288
+ it 'shows cop names' do
289
+ create_file('example1.rb', "\tputs 0")
290
+ expect(cli.run(['--format',
291
+ 'emacs',
292
+ '--debug',
293
+ 'example1.rb'])).to eq(1)
294
+ expect($stdout.string.lines.to_a[-1])
295
+ .to eq(["#{abs('example1.rb')}:1:1: C: Tab: Tab detected.",
296
+ ''].join("\n"))
297
+ end
298
+ end
299
+
300
+ describe '--show-cops' do
301
+ shared_examples(:prints_config) do
302
+ it 'prints the current configuration' do
303
+ out = stdout.lines.to_a
304
+ printed_config = YAML.load(out.join)
305
+ cop_names = (cop_list[0] || '').split(',')
306
+ cop_names.each do |cop_name|
307
+ global_conf[cop_name].each do |key, value|
308
+ printed_value = printed_config[cop_name][key]
309
+ expect(printed_value).to eq(value)
310
+ end
311
+ end
312
+ end
313
+ end
314
+
315
+ let(:cops) { Rubocop::Cop::Cop.all }
316
+
317
+ let(:global_conf) do
318
+ config_path =
319
+ Rubocop::ConfigLoader.configuration_file_for(Dir.pwd.to_s)
320
+ Rubocop::ConfigLoader.configuration_from_file(config_path)
321
+ end
322
+
323
+ let(:stdout) { $stdout.string }
324
+
325
+ before do
326
+ expect { cli.run ['--show-cops'] + cop_list }.to exit_with_code(0)
327
+ end
328
+
329
+ context 'with no args' do
330
+ let(:cop_list) { [] }
331
+
332
+ # Extracts the first line out of the description
333
+ def short_description_of_cop(cop)
334
+ desc = full_description_of_cop(cop)
335
+ desc ? desc.lines.first.strip : ''
336
+ end
337
+
338
+ # Gets the full description of the cop or nil if no description is set.
339
+ def full_description_of_cop(cop)
340
+ cop_config = global_conf.for_cop(cop)
341
+ cop_config['Description']
342
+ end
343
+
344
+ it 'prints all available cops and their description' do
345
+ cops.each do |cop|
346
+ expect(stdout).to include cop.cop_name
347
+ # Because of line breaks, we will only find the beginning.
348
+ expect(stdout).to include short_description_of_cop(cop)[0..60]
349
+ end
350
+ end
351
+
352
+ it 'prints all types' do
353
+ cops
354
+ .types
355
+ .map(&:to_s)
356
+ .map(&:capitalize)
357
+ .each { |type| expect(stdout).to include(type) }
358
+ end
359
+
360
+ it 'prints all cops in their right type listing' do
361
+ lines = stdout.lines
362
+ lines.slice_before(/Type /).each do |slice|
363
+ types = cops.types.map(&:to_s).map(&:capitalize)
364
+ current = types.delete(slice.shift[/Type '(?<c>[^'']+)'/, 'c'])
365
+ # all cops in their type listing
366
+ cops.with_type(current).each do |cop|
367
+ expect(slice.any? { |l| l.include? cop.cop_name }).to be_true
368
+ end
369
+
370
+ # no cop in wrong type listing
371
+ types.each do |type|
372
+ cops.with_type(type).each do |cop|
373
+ expect(slice.any? { |l| l.include? cop.cop_name }).to be_false
374
+ end
375
+ end
376
+ end
377
+ end
378
+
379
+ include_examples :prints_config
380
+ end
381
+
382
+ context 'with one cop given' do
383
+ let(:cop_list) { ['Tab'] }
384
+
385
+ it 'prints that cop and nothing else' do
386
+ expect(stdout).to eq(['Tab:',
387
+ ' Description: No hard tabs.',
388
+ ' Enabled: true',
389
+ '',
390
+ ''].join("\n"))
391
+ end
392
+
393
+ include_examples :prints_config
394
+ end
395
+
396
+ context 'with two cops given' do
397
+ let(:cop_list) { ['Tab,LineLength'] }
398
+ include_examples :prints_config
399
+ end
400
+
401
+ context 'with one of the cops misspelled' do
402
+ let(:cop_list) { ['Tab,X123'] }
403
+
404
+ it 'skips the unknown cop' do
405
+ expect(stdout).to eq(['Tab:',
406
+ ' Description: No hard tabs.',
407
+ ' Enabled: true',
408
+ '',
409
+ ''].join("\n"))
410
+ end
411
+ end
412
+ end
413
+
414
+ describe '-f/--format' do
415
+ let(:target_file) { 'example.rb' }
416
+
417
+ before do
418
+ create_file(target_file, [
419
+ '# encoding: utf-8',
420
+ '#' * 90
421
+ ])
422
+ end
423
+
424
+ describe 'builtin formatters' do
425
+ context 'when simple format is specified' do
426
+ it 'outputs with simple format' do
427
+ cli.run(['--format', 'simple', 'example.rb'])
428
+ expect($stdout.string)
429
+ .to include([
430
+ "== #{target_file} ==",
431
+ 'C: 2: 80: Line is too long. [90/79]'
432
+ ].join("\n"))
433
+ end
434
+ end
435
+
436
+ context 'when clang format is specified' do
437
+ it 'outputs with clang format' do
438
+ create_file('example1.rb', ['# encoding: utf-8',
439
+ 'x= 0 ',
440
+ '#' * 85,
441
+ 'y ',
442
+ 'puts x'])
443
+ create_file('example2.rb', ['# encoding: utf-8',
444
+ "\tx",
445
+ 'def a',
446
+ ' puts',
447
+ 'end'])
448
+ create_file('example3.rb', ['# encoding: utf-8',
449
+ 'def badName',
450
+ ' if something',
451
+ ' test',
452
+ ' end',
453
+ 'end'])
454
+ expect(cli.run(['--format', 'clang', 'example1.rb',
455
+ 'example2.rb', 'example3.rb']))
456
+ .to eq(1)
457
+ expect($stdout.string)
458
+ .to eq(['example1.rb:2:2: C: Surrounding space missing for ' \
459
+ "operator '='.",
460
+ 'x= 0 ',
461
+ ' ^',
462
+ 'example1.rb:2:5: C: Trailing whitespace detected.',
463
+ 'x= 0 ',
464
+ ' ^',
465
+ 'example1.rb:3:80: C: Line is too long. [85/79]',
466
+ '###################################################' \
467
+ '##################################',
468
+ ' ' \
469
+ ' ^^^^^^',
470
+ 'example1.rb:4:2: C: Trailing whitespace detected.',
471
+ 'y ',
472
+ ' ^',
473
+ 'example2.rb:2:1: C: Tab detected.',
474
+ "\tx",
475
+ '^',
476
+ 'example2.rb:3:1: C: Inconsistent indentation ' \
477
+ 'detected.',
478
+ 'def a',
479
+ '',
480
+ 'example2.rb:4:1: C: Use 2 (not 3) spaces for ' \
481
+ 'indentation.',
482
+ ' puts',
483
+ '^^^',
484
+ 'example3.rb:2:5: C: Use snake_case for methods.',
485
+ 'def badName',
486
+ ' ^^^^^^^',
487
+ 'example3.rb:3:3: C: Favor modifier if usage ' \
488
+ 'when you have a single-line body. Another good ' +
489
+ 'alternative is the usage of control flow &&/||.',
490
+ ' if something',
491
+ ' ^^',
492
+ 'example3.rb:5:5: W: end at 5, 4 is not aligned ' \
493
+ 'with if at 3, 2',
494
+ ' end',
495
+ ' ^^^',
496
+ '',
497
+ '3 files inspected, 10 offences detected',
498
+ ''].join("\n"))
499
+ end
500
+ end
501
+
502
+ context 'when emacs format is specified' do
503
+ it 'outputs with emacs format' do
504
+ create_file('example1.rb', ['# encoding: utf-8',
505
+ 'x= 0 ',
506
+ 'y ',
507
+ 'puts x'])
508
+ create_file('example2.rb', ['# encoding: utf-8',
509
+ "\tx = 0",
510
+ 'puts x'])
511
+ expect(cli.run(['--format', 'emacs', 'example1.rb',
512
+ 'example2.rb'])).to eq(1)
513
+ expected_output =
514
+ ["#{abs('example1.rb')}:2:2: C: Surrounding space missing" +
515
+ " for operator '='.",
516
+ "#{abs('example1.rb')}:2:5: C: Trailing whitespace detected.",
517
+ "#{abs('example1.rb')}:3:2: C: Trailing whitespace detected.",
518
+ "#{abs('example2.rb')}:2:1: C: Tab detected.",
519
+ "#{abs('example2.rb')}:3:1: C: Inconsistent indentation " +
520
+ 'detected.',
521
+ ''].join("\n")
522
+ expect($stdout.string).to eq(expected_output)
523
+ end
524
+ end
525
+
526
+ context 'when unknown format name is specified' do
527
+ it 'aborts with error message' do
528
+ expect { cli.run(['--format', 'unknown', 'example.rb']) }
529
+ .to exit_with_code(1)
530
+ expect($stderr.string)
531
+ .to include('No formatter for "unknown"')
532
+ end
533
+ end
534
+ end
535
+
536
+ describe 'custom formatter' do
537
+ let(:target_file) { abs('example.rb') }
538
+
539
+ context 'when a class name is specified' do
540
+ it 'uses the class as a formatter' do
541
+ module ::MyTool
542
+ class RubocopFormatter < Rubocop::Formatter::BaseFormatter
543
+ def started(all_files)
544
+ output.puts "started: #{all_files.join(',')}"
545
+ end
546
+
547
+ def file_started(file, options)
548
+ output.puts "file_started: #{file}"
549
+ end
550
+
551
+ def file_finished(file, offences)
552
+ output.puts "file_finished: #{file}"
553
+ end
554
+
555
+ def finished(processed_files)
556
+ output.puts "finished: #{processed_files.join(',')}"
557
+ end
558
+ end
559
+ end
560
+
561
+ cli.run(['--format', 'MyTool::RubocopFormatter', 'example.rb'])
562
+ expect($stdout.string).to eq([
563
+ "started: #{target_file}",
564
+ "file_started: #{target_file}",
565
+ "file_finished: #{target_file}",
566
+ "finished: #{target_file}",
567
+ ''
568
+ ].join("\n"))
569
+ end
570
+ end
571
+
572
+ context 'when unknown class name is specified' do
573
+ it 'aborts with error message' do
574
+ args = '--format UnknownFormatter example.rb'
575
+ expect { cli.run(args.split) }.to exit_with_code(1)
576
+ expect($stderr.string).to include('UnknownFormatter')
577
+ end
578
+ end
579
+ end
580
+
581
+ it 'can be used multiple times' do
582
+ cli.run(['--format', 'simple', '--format', 'emacs', 'example.rb'])
583
+ expect($stdout.string)
584
+ .to include([
585
+ "== #{target_file} ==",
586
+ 'C: 2: 80: Line is too long. [90/79]',
587
+ "#{abs(target_file)}:2:80: C: Line is too long. " +
588
+ '[90/79]'
589
+ ].join("\n"))
590
+ end
591
+ end
592
+
593
+ describe '-o/--out option' do
594
+ let(:target_file) { 'example.rb' }
595
+
596
+ before do
597
+ create_file(target_file, [
598
+ '# encoding: utf-8',
599
+ '#' * 90
600
+ ])
601
+ end
602
+
603
+ it 'redirects output to the specified file' do
604
+ cli.run(['--out', 'output.txt', target_file])
605
+ expect(File.read('output.txt')).to include('Line is too long.')
606
+ end
607
+
608
+ it 'is applied to the previously specified formatter' do
609
+ cli.run([
610
+ '--format', 'simple',
611
+ '--format', 'emacs', '--out', 'emacs_output.txt',
612
+ target_file
613
+ ])
614
+
615
+ expect($stdout.string).to eq([
616
+ "== #{target_file} ==",
617
+ 'C: 2: 80: Line is too long. [90/79]',
618
+ '',
619
+ '1 file inspected, 1 offence detected',
620
+ ''
621
+ ].join("\n"))
622
+
623
+ expect(File.read('emacs_output.txt'))
624
+ .to eq("#{abs(target_file)}:2:80: C: Line is too long. [90/79]\n")
625
+ end
626
+ end
627
+ end
628
+
629
+ describe '#wants_to_quit?' do
630
+ it 'is initially false' do
631
+ expect(cli.wants_to_quit?).to be_false
632
+ end
633
+
634
+ context 'when true' do
635
+ it 'returns 1' do
636
+ create_file('example.rb', '# encoding: utf-8')
637
+ cli.wants_to_quit = true
638
+ expect(cli.run(['example.rb'])).to eq(1)
639
+ end
640
+ end
641
+ end
642
+
643
+ describe '#trap_interrupt' do
644
+ before do
645
+ @interrupt_handlers = []
646
+ allow(Signal).to receive(:trap).with('INT') do |&block|
647
+ @interrupt_handlers << block
648
+ end
649
+ end
650
+
651
+ def interrupt
652
+ @interrupt_handlers.each(&:call)
653
+ end
654
+
655
+ it 'adds a handler for SIGINT' do
656
+ expect(@interrupt_handlers).to be_empty
657
+ cli.trap_interrupt
658
+ expect(@interrupt_handlers.size).to eq(1)
659
+ end
660
+
661
+ context 'with SIGINT once' do
662
+ it 'sets #wants_to_quit? to true' do
663
+ cli.trap_interrupt
664
+ expect(cli.wants_to_quit?).to be_false
665
+ interrupt
666
+ expect(cli.wants_to_quit?).to be_true
667
+ end
668
+
669
+ it 'does not exit immediately' do
670
+ expect_any_instance_of(Object).not_to receive(:exit)
671
+ expect_any_instance_of(Object).not_to receive(:exit!)
672
+ cli.trap_interrupt
673
+ interrupt
674
+ end
675
+ end
676
+
677
+ context 'with SIGINT twice' do
678
+ it 'exits immediately' do
679
+ expect_any_instance_of(Object).to receive(:exit!).with(1)
680
+ cli.trap_interrupt
681
+ interrupt
682
+ interrupt
683
+ end
684
+ end
685
+ end
686
+
687
+ it 'checks a given correct file and returns 0' do
688
+ create_file('example.rb', [
689
+ '# encoding: utf-8',
690
+ 'x = 0',
691
+ 'puts x'
692
+ ])
693
+ expect(cli.run(['--format', 'simple', 'example.rb'])).to eq(0)
694
+ expect($stdout.string)
695
+ .to eq("\n1 file inspected, no offences detected\n")
696
+ end
697
+
698
+ it 'checks a given file with faults and returns 1' do
699
+ create_file('example.rb', [
700
+ '# encoding: utf-8',
701
+ 'x = 0 ',
702
+ 'puts x'
703
+ ])
704
+ expect(cli.run(['--format', 'simple', 'example.rb'])).to eq(1)
705
+ expect($stdout.string)
706
+ .to eq ['== example.rb ==',
707
+ 'C: 2: 6: Trailing whitespace detected.',
708
+ '',
709
+ '1 file inspected, 1 offence detected',
710
+ ''].join("\n")
711
+ end
712
+
713
+ it 'registers an offence for a syntax error' do
714
+ create_file('example.rb', [
715
+ '# encoding: utf-8',
716
+ 'class Test',
717
+ 'en'
718
+ ])
719
+ expect(cli.run(['--format', 'emacs', 'example.rb'])).to eq(1)
720
+ expect($stdout.string)
721
+ .to eq(["#{abs('example.rb')}:4:1: E: unexpected " +
722
+ 'token $end',
723
+ ''].join("\n"))
724
+ end
725
+
726
+ it 'registers an offence for Parser warnings' do
727
+ create_file('example.rb', [
728
+ '# encoding: utf-8',
729
+ 'puts *test',
730
+ 'if a then b else c end'
731
+ ])
732
+ expect(cli.run(['--format', 'emacs', 'example.rb'])).to eq(1)
733
+ expect($stdout.string)
734
+ .to eq(["#{abs('example.rb')}:2:6: W: " +
735
+ 'Ambiguous splat operator. Parenthesize the method arguments ' +
736
+ "if it's surely a splat operator, or add a whitespace to the " +
737
+ 'right of the * if it should be a multiplication.',
738
+ "#{abs('example.rb')}:3:1: C: " +
739
+ 'Favor the ternary operator (?:) over if/then/else/end ' +
740
+ 'constructs.',
741
+ ''].join("\n"))
742
+ end
743
+
744
+ it 'can process a file with an invalid UTF-8 byte sequence' do
745
+ create_file('example.rb', [
746
+ '# encoding: utf-8',
747
+ "# #{'f9'.hex.chr}#{'29'.hex.chr}"
748
+ ])
749
+ expect(cli.run(['--format', 'emacs', 'example.rb'])).to eq(1)
750
+ expect($stdout.string)
751
+ .to eq(["#{abs('example.rb')}:1:1: F: Invalid byte sequence in utf-8.",
752
+ ''].join("\n"))
753
+ end
754
+
755
+ describe 'rubocop:disable comment' do
756
+ it 'can disable all cops in a code section' do
757
+ create_file('example.rb',
758
+ ['# encoding: utf-8',
759
+ '# rubocop:disable all',
760
+ '#' * 90,
761
+ 'x(123456)',
762
+ 'y("123")',
763
+ 'def func',
764
+ ' # rubocop: enable LineLength, StringLiterals',
765
+ ' ' + '#' * 93,
766
+ ' x(123456)',
767
+ ' y("123")',
768
+ 'end'])
769
+ expect(cli.run(['--format', 'emacs', 'example.rb'])).to eq(1)
770
+ # all cops were disabled, then 2 were enabled again, so we
771
+ # should get 2 offences reported.
772
+ expect($stdout.string)
773
+ .to eq(["#{abs('example.rb')}:8:80: C: Line is too long. [95/79]",
774
+ "#{abs('example.rb')}:10:5: C: Prefer single-quoted " +
775
+ "strings when you don't need string interpolation or " +
776
+ 'special symbols.',
777
+ ''].join("\n"))
778
+ end
779
+
780
+ it 'can disable selected cops in a code section' do
781
+ create_file('example.rb',
782
+ ['# encoding: utf-8',
783
+ '# rubocop:disable LineLength,NumericLiterals,' +
784
+ 'StringLiterals',
785
+ '#' * 90,
786
+ 'x(123456)',
787
+ 'y("123")',
788
+ 'def func',
789
+ ' # rubocop: enable LineLength, StringLiterals',
790
+ ' ' + '#' * 93,
791
+ ' x(123456)',
792
+ ' y("123")',
793
+ 'end'])
794
+ expect(cli.run(['--format', 'emacs', 'example.rb'])).to eq(1)
795
+ # 3 cops were disabled, then 2 were enabled again, so we
796
+ # should get 2 offences reported.
797
+ expect($stdout.string)
798
+ .to eq(["#{abs('example.rb')}:8:80: C: Line is too long. [95/79]",
799
+ "#{abs('example.rb')}:10:5: C: Prefer single-quoted " +
800
+ "strings when you don't need string interpolation or " +
801
+ 'special symbols.',
802
+ ''].join("\n"))
803
+ end
804
+
805
+ it 'can disable all cops on a single line' do
806
+ create_file('example.rb', [
807
+ '# encoding: utf-8',
808
+ 'y("123", 123456) # rubocop:disable all'
809
+ ])
810
+ expect(cli.run(['--format', 'emacs', 'example.rb'])).to eq(0)
811
+ expect($stdout.string).to be_empty
812
+ end
813
+
814
+ it 'can disable selected cops on a single line' do
815
+ create_file('example.rb',
816
+ [
817
+ '# encoding: utf-8',
818
+ '#' * 90 + ' # rubocop:disable LineLength',
819
+ '#' * 95,
820
+ 'y("123") # rubocop:disable LineLength,StringLiterals'
821
+ ])
822
+ expect(cli.run(['--format', 'emacs', 'example.rb'])).to eq(1)
823
+ expect($stdout.string)
824
+ .to eq(
825
+ ["#{abs('example.rb')}:3:80: C: Line is too long. [95/79]",
826
+ ''].join("\n"))
827
+ end
828
+ end
829
+
830
+ it 'finds a file with no .rb extension but has a shebang line' do
831
+ create_file('example', [
832
+ '#!/usr/bin/env ruby',
833
+ '# encoding: utf-8',
834
+ 'x = 0',
835
+ 'puts x'
836
+ ])
837
+ expect(cli.run(%w(--format simple))).to eq(0)
838
+ expect($stdout.string)
839
+ .to eq(['', '1 file inspected, no offences detected', ''].join("\n"))
840
+ end
841
+
842
+ describe 'enabling/disabling rails cops' do
843
+ it 'by default does not run rails cops' do
844
+ create_file('app/models/example1.rb', ['# encoding: utf-8',
845
+ 'read_attribute(:test)'])
846
+ expect(cli.run(['--format', 'simple', 'app/models/example1.rb']))
847
+ .to eq(0)
848
+ end
849
+
850
+ it 'with -R given runs rails cops' do
851
+ create_file('app/models/example1.rb', ['# encoding: utf-8',
852
+ 'read_attribute(:test)'])
853
+ expect(cli.run(['--format', 'simple', '-R', 'app/models/example1.rb']))
854
+ .to eq(1)
855
+ expect($stdout.string).to include('Prefer self[:attribute]')
856
+ end
857
+
858
+ it 'with configation option true in one dir runs rails cops there' do
859
+ create_file('dir1/app/models/example1.rb', ['# encoding: utf-8',
860
+ 'read_attribute(:test)'])
861
+ create_file('dir1/.rubocop.yml', [
862
+ 'AllCops:',
863
+ ' RunRailsCops: true',
864
+ ])
865
+ create_file('dir2/app/models/example2.rb', ['# encoding: utf-8',
866
+ 'read_attribute(:test)'])
867
+ create_file('dir2/.rubocop.yml', [
868
+ 'AllCops:',
869
+ ' RunRailsCops: false',
870
+ ])
871
+ expect(cli.run(['--format', 'simple', 'dir1', 'dir2'])).to eq(1)
872
+ expect($stdout.string)
873
+ .to eq(['== dir1/app/models/example1.rb ==',
874
+ 'C: 2: 1: Prefer self[:attribute] over read_attribute' +
875
+ '(:attribute).',
876
+ '',
877
+ '2 files inspected, 1 offence detected',
878
+ ''].join("\n"))
879
+ end
880
+
881
+ it 'with configation option false but -R given runs rails cops' do
882
+ create_file('app/models/example1.rb', ['# encoding: utf-8',
883
+ 'read_attribute(:test)'])
884
+ create_file('.rubocop.yml', [
885
+ 'AllCops:',
886
+ ' RunRailsCops: false',
887
+ ])
888
+ expect(cli.run(['--format', 'simple', '-R', 'app/models/example1.rb']))
889
+ .to eq(1)
890
+ expect($stdout.string).to include('Prefer self[:attribute]')
891
+ end
892
+ end
893
+
894
+ describe 'cops can exclude files based on config' do
895
+ it 'ignores excluded files' do
896
+ create_file('example.rb', [
897
+ '# encoding: utf-8',
898
+ 'x = 0'
899
+ ])
900
+ create_file('regexp.rb', [
901
+ '# encoding: utf-8',
902
+ 'x = 0'
903
+ ])
904
+ create_file('exclude_glob.rb', [
905
+ '#!/usr/bin/env ruby',
906
+ '# encoding: utf-8',
907
+ 'x = 0'
908
+ ])
909
+ create_file('dir/thing.rb', [
910
+ '# encoding: utf-8',
911
+ 'x = 0'
912
+ ])
913
+ create_file('.rubocop.yml', [
914
+ 'UselessAssignment:',
915
+ ' Exclude:',
916
+ ' - example.rb',
917
+ ' - !ruby/regexp /regexp.rb\z/',
918
+ ' - "exclude_*"',
919
+ ' - "dir/*"'
920
+ ])
921
+ expect(cli.run(%w(--format simple))).to eq(0)
922
+ expect($stdout.string)
923
+ .to eq(['', '4 files inspected, no offences detected',
924
+ ''].join("\n"))
925
+ end
926
+
927
+ end
928
+
929
+ describe 'configuration from file' do
930
+ it 'finds included files' do
931
+ create_file('example', [
932
+ '# encoding: utf-8',
933
+ 'x = 0',
934
+ 'puts x'
935
+ ])
936
+ create_file('regexp', [
937
+ '# encoding: utf-8',
938
+ 'x = 0',
939
+ 'puts x'
940
+ ])
941
+ create_file('.rubocop.yml', [
942
+ 'AllCops:',
943
+ ' Includes:',
944
+ ' - example',
945
+ ' - !ruby/regexp /regexp$/'
946
+ ])
947
+ expect(cli.run(%w(--format simple))).to eq(0)
948
+ expect($stdout.string)
949
+ .to eq(['', '2 files inspected, no offences detected',
950
+ ''].join("\n"))
951
+ end
952
+
953
+ it 'ignores excluded files' do
954
+ create_file('example.rb', [
955
+ '# encoding: utf-8',
956
+ 'x = 0',
957
+ 'puts x'
958
+ ])
959
+ create_file('regexp.rb', [
960
+ '# encoding: utf-8',
961
+ 'x = 0',
962
+ 'puts x'
963
+ ])
964
+ create_file('exclude_glob.rb', [
965
+ '#!/usr/bin/env ruby',
966
+ '# encoding: utf-8',
967
+ 'x = 0',
968
+ 'puts x'
969
+ ])
970
+ create_file('.rubocop.yml', [
971
+ 'AllCops:',
972
+ ' Excludes:',
973
+ ' - example.rb',
974
+ ' - !ruby/regexp /regexp.rb$/',
975
+ ' - "exclude_*"'
976
+ ])
977
+ expect(cli.run(%w(--format simple))).to eq(0)
978
+ expect($stdout.string)
979
+ .to eq(['', '0 files inspected, no offences detected',
980
+ ''].join("\n"))
981
+ end
982
+
983
+ # With rubinius 2.0.0.rc1 + rspec 2.13.1,
984
+ # File.stub(:open).and_call_original causes SystemStackError.
985
+ it 'does not read files in excluded list', broken: :rbx do
986
+ %w(rb.rb non-rb.ext without-ext).each do |filename|
987
+ create_file("example/ignored/#{filename}", [
988
+ '# encoding: utf-8',
989
+ '#' * 90
990
+ ])
991
+ end
992
+
993
+ create_file('example/.rubocop.yml', [
994
+ 'AllCops:',
995
+ ' Excludes:',
996
+ ' - ignored/**',
997
+ ])
998
+ expect(File).not_to receive(:open).with(%r(/ignored/))
999
+ allow(File).to receive(:open).and_call_original
1000
+ expect(cli.run(%w(--format simple example))).to eq(0)
1001
+ expect($stdout.string)
1002
+ .to eq(['', '0 files inspected, no offences detected',
1003
+ ''].join("\n"))
1004
+ end
1005
+
1006
+ it 'can be configured with option to disable a certain error' do
1007
+ create_file('example1.rb', 'puts 0 ')
1008
+ create_file('rubocop.yml', [
1009
+ 'Encoding:',
1010
+ ' Enabled: false',
1011
+ '',
1012
+ 'CaseIndentation:',
1013
+ ' Enabled: false'
1014
+ ])
1015
+ expect(cli.run(['--format', 'simple',
1016
+ '-c', 'rubocop.yml', 'example1.rb'])).to eq(1)
1017
+ expect($stdout.string)
1018
+ .to eq(['== example1.rb ==',
1019
+ 'C: 1: 7: Trailing whitespace detected.',
1020
+ '',
1021
+ '1 file inspected, 1 offence detected',
1022
+ ''].join("\n"))
1023
+ end
1024
+
1025
+ it 'can disable parser-derived offences with warning severity' do
1026
+ # `-' interpreted as argument prefix
1027
+ create_file('example.rb', 'puts -1')
1028
+ create_file('.rubocop.yml', [
1029
+ 'Encoding:',
1030
+ ' Enabled: false',
1031
+ '',
1032
+ 'AmbiguousOperator:',
1033
+ ' Enabled: false'
1034
+ ])
1035
+ expect(cli.run(['--format', 'emacs', 'example.rb'])).to eq(0)
1036
+ end
1037
+
1038
+ it 'cannot disable Syntax offences with fatal/error severity' do
1039
+ create_file('example.rb', 'class Test')
1040
+ create_file('.rubocop.yml', [
1041
+ 'Encoding:',
1042
+ ' Enabled: false',
1043
+ '',
1044
+ 'Syntax:',
1045
+ ' Enabled: false'
1046
+ ])
1047
+ expect(cli.run(['--format', 'emacs', 'example.rb'])).to eq(1)
1048
+ expect($stdout.string).to include('unexpected token $end')
1049
+ end
1050
+
1051
+ it 'can be configured to override a parameter that is a hash' do
1052
+ create_file('example1.rb',
1053
+ ['# encoding: utf-8',
1054
+ 'arr.find_all { |e| e > 0 }.collect { |e| -e }'])
1055
+ # We only care about select over find_all. All other preferred methods
1056
+ # appearing in the default config are gone when we override
1057
+ # PreferredMethods. We get no report about collect.
1058
+ create_file('rubocop.yml',
1059
+ ['CollectionMethods:',
1060
+ ' PreferredMethods:',
1061
+ ' find_all: select'])
1062
+ cli.run(['--format', 'simple', '-c', 'rubocop.yml', 'example1.rb'])
1063
+ expect($stdout.string)
1064
+ .to eq(['== example1.rb ==',
1065
+ 'C: 2: 5: Prefer select over find_all.',
1066
+ '',
1067
+ '1 file inspected, 1 offence detected',
1068
+ ''].join("\n"))
1069
+ end
1070
+
1071
+ it 'works when a cop that others depend on is disabled' do
1072
+ create_file('example1.rb', ['if a',
1073
+ ' b',
1074
+ 'end'])
1075
+ create_file('rubocop.yml', [
1076
+ 'Encoding:',
1077
+ ' Enabled: false',
1078
+ '',
1079
+ 'LineLength:',
1080
+ ' Enabled: false'
1081
+ ])
1082
+ result = cli.run(['--format', 'simple',
1083
+ '-c', 'rubocop.yml', 'example1.rb'])
1084
+ expect($stdout.string)
1085
+ .to eq(['== example1.rb ==',
1086
+ 'C: 1: 1: Favor modifier if usage when you have ' +
1087
+ 'a single-line body. Another good alternative is the ' +
1088
+ 'usage of control flow &&/||.',
1089
+ '',
1090
+ '1 file inspected, 1 offence detected',
1091
+ ''].join("\n"))
1092
+ expect(result).to eq(1)
1093
+ end
1094
+
1095
+ it 'can be configured with project config to disable a certain error' do
1096
+ create_file('example_src/example1.rb', 'puts 0 ')
1097
+ create_file('example_src/.rubocop.yml', [
1098
+ 'Encoding:',
1099
+ ' Enabled: false',
1100
+ '',
1101
+ 'CaseIndentation:',
1102
+ ' Enabled: false'
1103
+ ])
1104
+ expect(cli.run(['--format', 'simple',
1105
+ 'example_src/example1.rb'])).to eq(1)
1106
+ expect($stdout.string)
1107
+ .to eq(['== example_src/example1.rb ==',
1108
+ 'C: 1: 7: Trailing whitespace detected.',
1109
+ '',
1110
+ '1 file inspected, 1 offence detected',
1111
+ ''].join("\n"))
1112
+ end
1113
+
1114
+ it 'can use an alternative max line length from a config file' do
1115
+ create_file('example_src/example1.rb', [
1116
+ '# encoding: utf-8',
1117
+ '#' * 90
1118
+ ])
1119
+ create_file('example_src/.rubocop.yml', [
1120
+ 'LineLength:',
1121
+ ' Enabled: true',
1122
+ ' Max: 100'
1123
+ ])
1124
+ expect(cli.run(['--format', 'simple',
1125
+ 'example_src/example1.rb'])).to eq(0)
1126
+ expect($stdout.string)
1127
+ .to eq(['', '1 file inspected, no offences detected', ''].join("\n"))
1128
+ end
1129
+
1130
+ it 'can have different config files in different directories' do
1131
+ %w(src lib).each do |dir|
1132
+ create_file("example/#{dir}/example1.rb", [
1133
+ '# encoding: utf-8',
1134
+ '#' * 90
1135
+ ])
1136
+ end
1137
+ create_file('example/src/.rubocop.yml', [
1138
+ 'LineLength:',
1139
+ ' Enabled: true',
1140
+ ' Max: 100'
1141
+ ])
1142
+ expect(cli.run(%w(--format simple example))).to eq(1)
1143
+ expect($stdout.string).to eq(
1144
+ ['== example/lib/example1.rb ==',
1145
+ 'C: 2: 80: Line is too long. [90/79]',
1146
+ '',
1147
+ '2 files inspected, 1 offence detected',
1148
+ ''].join("\n"))
1149
+ end
1150
+
1151
+ it 'prefers a config file in ancestor directory to another in home' do
1152
+ create_file('example_src/example1.rb', [
1153
+ '# encoding: utf-8',
1154
+ '#' * 90
1155
+ ])
1156
+ create_file('example_src/.rubocop.yml', [
1157
+ 'LineLength:',
1158
+ ' Enabled: true',
1159
+ ' Max: 100'
1160
+ ])
1161
+ create_file("#{Dir.home}/.rubocop.yml", [
1162
+ 'LineLength:',
1163
+ ' Enabled: true',
1164
+ ' Max: 80'
1165
+ ])
1166
+ expect(cli.run(['--format', 'simple',
1167
+ 'example_src/example1.rb'])).to eq(0)
1168
+ expect($stdout.string)
1169
+ .to eq(['', '1 file inspected, no offences detected', ''].join("\n"))
1170
+ end
1171
+
1172
+ it 'can exclude directories relative to .rubocop.yml' do
1173
+ %w(src etc/test etc/spec tmp/test tmp/spec).each do |dir|
1174
+ create_file("example/#{dir}/example1.rb", [
1175
+ '# encoding: utf-8',
1176
+ '#' * 90
1177
+ ])
1178
+ end
1179
+
1180
+ create_file('example/.rubocop.yml', [
1181
+ 'AllCops:',
1182
+ ' Excludes:',
1183
+ ' - src/**',
1184
+ ' - etc/**',
1185
+ ' - tmp/spec/**'
1186
+ ])
1187
+
1188
+ expect(cli.run(%w(--format simple example))).to eq(1)
1189
+ expect($stdout.string).to eq(
1190
+ ['== example/tmp/test/example1.rb ==',
1191
+ 'C: 2: 80: Line is too long. [90/79]',
1192
+ '',
1193
+ '1 file inspected, 1 offence detected',
1194
+ ''].join("\n"))
1195
+ end
1196
+
1197
+ it 'can exclude a typical vendor directory' do
1198
+ create_file('vendor/bundle/ruby/1.9.1/gems/parser-2.0.0/.rubocop.yml',
1199
+ ['AllCops:',
1200
+ ' Excludes:',
1201
+ ' - lib/parser/lexer.rb'])
1202
+
1203
+ create_file('vendor/bundle/ruby/1.9.1/gems/parser-2.0.0/lib/ex.rb',
1204
+ ['# encoding: utf-8',
1205
+ '#' * 90])
1206
+
1207
+ create_file('.rubocop.yml',
1208
+ ['AllCops:',
1209
+ ' Excludes:',
1210
+ ' - vendor/**'])
1211
+
1212
+ cli.run(%w(--format simple))
1213
+ expect($stdout.string)
1214
+ .to eq(['', '0 files inspected, no offences detected',
1215
+ ''].join("\n"))
1216
+ end
1217
+
1218
+ # Being immune to bad configuration files in excluded directories has
1219
+ # become important due to a bug in rubygems
1220
+ # (https://github.com/rubygems/rubygems/issues/680) that makes
1221
+ # installations of, for example, rubocop lack their .rubocop.yml in the
1222
+ # root directory.
1223
+ it 'can exclude a vendor directory with an erroneous config file' do
1224
+ create_file('vendor/bundle/ruby/1.9.1/gems/parser-2.0.0/.rubocop.yml',
1225
+ ['inherit_from: non_existent.yml'])
1226
+
1227
+ create_file('vendor/bundle/ruby/1.9.1/gems/parser-2.0.0/lib/ex.rb',
1228
+ ['# encoding: utf-8',
1229
+ '#' * 90])
1230
+
1231
+ create_file('.rubocop.yml',
1232
+ ['AllCops:',
1233
+ ' Excludes:',
1234
+ ' - vendor/**'])
1235
+
1236
+ cli.run(%w(--format simple))
1237
+ expect($stderr.string).to eq('')
1238
+ expect($stdout.string)
1239
+ .to eq(['', '0 files inspected, no offences detected',
1240
+ ''].join("\n"))
1241
+ end
1242
+
1243
+ # Relative exclude paths in .rubocop.yml files are relative to that file,
1244
+ # but in configuration files with other names they will be relative to
1245
+ # whatever file inherits from them.
1246
+ it 'can exclude a vendor directory indirectly' do
1247
+ create_file('vendor/bundle/ruby/1.9.1/gems/parser-2.0.0/.rubocop.yml',
1248
+ ['AllCops:',
1249
+ ' Excludes:',
1250
+ ' - lib/parser/lexer.rb'])
1251
+
1252
+ create_file('vendor/bundle/ruby/1.9.1/gems/parser-2.0.0/lib/ex.rb',
1253
+ ['# encoding: utf-8',
1254
+ '#' * 90])
1255
+
1256
+ create_file('.rubocop.yml',
1257
+ ['inherit_from: config/default.yml'])
1258
+
1259
+ create_file('config/default.yml',
1260
+ ['AllCops:',
1261
+ ' Excludes:',
1262
+ ' - vendor/**'])
1263
+
1264
+ cli.run(%w(--format simple))
1265
+ expect($stdout.string)
1266
+ .to eq(['', '0 files inspected, no offences detected',
1267
+ ''].join("\n"))
1268
+ end
1269
+
1270
+ it 'prints a warning for an unrecognized cop name in .rubocop.yml' do
1271
+ create_file('example/example1.rb', [
1272
+ '# encoding: utf-8',
1273
+ '#' * 90
1274
+ ])
1275
+
1276
+ create_file('example/.rubocop.yml', [
1277
+ 'LyneLenth:',
1278
+ ' Enabled: true',
1279
+ ' Max: 100'
1280
+ ])
1281
+
1282
+ expect(cli.run(%w(--format simple example))).to eq(1)
1283
+ expect($stderr.string)
1284
+ .to eq(
1285
+ ['Warning: unrecognized cop LyneLenth found in ' +
1286
+ abs('example/.rubocop.yml'),
1287
+ ''].join("\n"))
1288
+ end
1289
+
1290
+ it 'prints a warning for an unrecognized configuration parameter' do
1291
+ create_file('example/example1.rb', [
1292
+ '# encoding: utf-8',
1293
+ '#' * 90
1294
+ ])
1295
+
1296
+ create_file('example/.rubocop.yml', [
1297
+ 'LineLength:',
1298
+ ' Enabled: true',
1299
+ ' Min: 10'
1300
+ ])
1301
+
1302
+ expect(cli.run(%w(--format simple example))).to eq(1)
1303
+ expect($stderr.string)
1304
+ .to eq(
1305
+ ['Warning: unrecognized parameter LineLength:Min found in ' +
1306
+ abs('example/.rubocop.yml'),
1307
+ ''].join("\n"))
1308
+ end
1309
+
1310
+ it 'works when a configuration file passed by -c specifies Excludes with regexp' do
1311
+ create_file('example/example1.rb', [
1312
+ '# encoding: utf-8',
1313
+ '#' * 90
1314
+ ])
1315
+
1316
+ create_file('rubocop.yml', [
1317
+ 'AllCops:',
1318
+ ' Excludes:',
1319
+ ' - !ruby/regexp /example1\.rb$/'
1320
+ ])
1321
+
1322
+ cli.run(%w(--format simple -c rubocop.yml))
1323
+ expect($stdout.string)
1324
+ .to eq(['', '0 files inspected, no offences detected',
1325
+ ''].join("\n"))
1326
+ end
1327
+
1328
+ it 'works when a configuration file passed by -c specifies Excludes with strings' do
1329
+ create_file('example/example1.rb', [
1330
+ '# encoding: utf-8',
1331
+ '#' * 90
1332
+ ])
1333
+
1334
+ create_file('rubocop.yml', [
1335
+ 'AllCops:',
1336
+ ' Excludes:',
1337
+ ' - example/**'
1338
+ ])
1339
+
1340
+ cli.run(%w(--format simple -c rubocop.yml))
1341
+ expect($stdout.string)
1342
+ .to eq(['', '0 files inspected, no offences detected',
1343
+ ''].join("\n"))
1344
+ end
1345
+
1346
+ it 'works when a configuration file specifies a Severity' do
1347
+ create_file('example/example1.rb', [
1348
+ '# encoding: utf-8',
1349
+ '#' * 90
1350
+ ])
1351
+
1352
+ create_file('rubocop.yml', [
1353
+ 'LineLength:',
1354
+ ' Severity: error',
1355
+ ])
1356
+
1357
+ cli.run(%w(--format simple -c rubocop.yml))
1358
+ expect($stdout.string)
1359
+ .to eq(['== example/example1.rb ==',
1360
+ 'E: 2: 80: Line is too long. [90/79]',
1361
+ '',
1362
+ '1 file inspected, 1 offence detected',
1363
+ ''].join("\n"))
1364
+ expect($stderr.string).to eq('')
1365
+ end
1366
+
1367
+ it 'fails when a configuration file specifies an invalid Severity' do
1368
+ create_file('example/example1.rb', [
1369
+ '# encoding: utf-8',
1370
+ '#' * 90
1371
+ ])
1372
+
1373
+ create_file('rubocop.yml', [
1374
+ 'LineLength:',
1375
+ ' Severity: superbad',
1376
+ ])
1377
+
1378
+ cli.run(%w(--format simple -c rubocop.yml))
1379
+ expect($stderr.string)
1380
+ .to eq("Warning: Invalid severity 'superbad'. " +
1381
+ 'Valid severities are refactor, convention, ' +
1382
+ "warning, error, fatal.\n")
1383
+ end
1384
+ end
1385
+ end