rubocop 0.9.1 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rubocop might be problematic. Click here for more details.

Files changed (149) hide show
  1. data/.travis.yml +3 -1
  2. data/CHANGELOG.md +38 -0
  3. data/README.md +34 -0
  4. data/Rakefile +3 -0
  5. data/config/default.yml +14 -1
  6. data/config/enabled.yml +30 -7
  7. data/lib/rubocop.rb +15 -0
  8. data/lib/rubocop/cli.rb +48 -154
  9. data/lib/rubocop/config.rb +19 -22
  10. data/lib/rubocop/config_store.rb +2 -4
  11. data/lib/rubocop/cop/commissioner.rb +90 -0
  12. data/lib/rubocop/cop/cop.rb +38 -31
  13. data/lib/rubocop/cop/corrector.rb +84 -0
  14. data/lib/rubocop/cop/lint/assignment_in_condition.rb +0 -3
  15. data/lib/rubocop/cop/lint/block_alignment.rb +151 -0
  16. data/lib/rubocop/cop/lint/empty_ensure.rb +18 -0
  17. data/lib/rubocop/cop/lint/end_alignment.rb +0 -124
  18. data/lib/rubocop/cop/lint/end_in_method.rb +0 -2
  19. data/lib/rubocop/cop/lint/ensure_return.rb +3 -3
  20. data/lib/rubocop/cop/lint/eval.rb +0 -2
  21. data/lib/rubocop/cop/lint/handle_exceptions.rb +0 -2
  22. data/lib/rubocop/cop/lint/literal_in_condition.rb +0 -10
  23. data/lib/rubocop/cop/lint/loop.rb +0 -2
  24. data/lib/rubocop/cop/lint/rescue_exception.rb +0 -2
  25. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +2 -2
  26. data/lib/rubocop/cop/lint/unreachable_code.rb +0 -2
  27. data/lib/rubocop/cop/lint/unused_local_variable.rb +2 -2
  28. data/lib/rubocop/cop/lint/void.rb +0 -2
  29. data/lib/rubocop/cop/offence.rb +9 -0
  30. data/lib/rubocop/cop/rails/validation.rb +2 -1
  31. data/lib/rubocop/cop/style/access_control.rb +4 -3
  32. data/lib/rubocop/cop/style/alias.rb +2 -4
  33. data/lib/rubocop/cop/style/align_parameters.rb +0 -2
  34. data/lib/rubocop/cop/style/and_or.rb +4 -6
  35. data/lib/rubocop/cop/style/ascii_comments.rb +2 -2
  36. data/lib/rubocop/cop/style/ascii_identifiers.rb +2 -2
  37. data/lib/rubocop/cop/style/attr.rb +0 -2
  38. data/lib/rubocop/cop/style/avoid_class_vars.rb +0 -1
  39. data/lib/rubocop/cop/style/avoid_for.rb +0 -2
  40. data/lib/rubocop/cop/style/avoid_global_vars.rb +3 -7
  41. data/lib/rubocop/cop/style/avoid_perl_backrefs.rb +0 -2
  42. data/lib/rubocop/cop/style/avoid_perlisms.rb +2 -4
  43. data/lib/rubocop/cop/style/begin_block.rb +0 -2
  44. data/lib/rubocop/cop/style/block_comments.rb +2 -2
  45. data/lib/rubocop/cop/style/block_nesting.rb +3 -3
  46. data/lib/rubocop/cop/style/blocks.rb +0 -2
  47. data/lib/rubocop/cop/style/case_equality.rb +0 -2
  48. data/lib/rubocop/cop/style/case_indentation.rb +0 -2
  49. data/lib/rubocop/cop/style/character_literal.rb +10 -6
  50. data/lib/rubocop/cop/style/class_and_module_camel_case.rb +0 -4
  51. data/lib/rubocop/cop/style/class_methods.rb +1 -1
  52. data/lib/rubocop/cop/style/collection_methods.rb +3 -5
  53. data/lib/rubocop/cop/style/colon_method_call.rb +3 -3
  54. data/lib/rubocop/cop/style/comment_annotation.rb +44 -0
  55. data/lib/rubocop/cop/style/constant_name.rb +0 -2
  56. data/lib/rubocop/cop/style/def_parentheses.rb +0 -8
  57. data/lib/rubocop/cop/style/documentation.rb +6 -2
  58. data/lib/rubocop/cop/style/dot_position.rb +0 -2
  59. data/lib/rubocop/cop/style/empty_line_between_defs.rb +0 -2
  60. data/lib/rubocop/cop/style/empty_lines.rb +10 -8
  61. data/lib/rubocop/cop/style/empty_literal.rb +3 -1
  62. data/lib/rubocop/cop/style/encoding.rb +7 -6
  63. data/lib/rubocop/cop/style/end_block.rb +0 -2
  64. data/lib/rubocop/cop/style/end_of_line.rb +4 -3
  65. data/lib/rubocop/cop/style/favor_join.rb +0 -2
  66. data/lib/rubocop/cop/style/favor_modifier.rb +9 -9
  67. data/lib/rubocop/cop/style/favor_sprintf.rb +0 -2
  68. data/lib/rubocop/cop/style/favor_unless_over_negated_if.rb +0 -2
  69. data/lib/rubocop/cop/style/hash_syntax.rb +0 -2
  70. data/lib/rubocop/cop/style/if_then_else.rb +0 -2
  71. data/lib/rubocop/cop/style/lambda.rb +0 -2
  72. data/lib/rubocop/cop/style/leading_comment_space.rb +2 -2
  73. data/lib/rubocop/cop/style/line_continuation.rb +4 -3
  74. data/lib/rubocop/cop/style/line_length.rb +4 -3
  75. data/lib/rubocop/cop/style/method_and_variable_snake_case.rb +4 -3
  76. data/lib/rubocop/cop/style/method_call_parentheses.rb +0 -2
  77. data/lib/rubocop/cop/style/method_length.rb +0 -4
  78. data/lib/rubocop/cop/style/not.rb +0 -2
  79. data/lib/rubocop/cop/style/op_method.rb +0 -2
  80. data/lib/rubocop/cop/style/parameter_lists.rb +0 -2
  81. data/lib/rubocop/cop/style/parentheses_around_condition.rb +12 -6
  82. data/lib/rubocop/cop/style/proc.rb +0 -2
  83. data/lib/rubocop/cop/style/reduce_arguments.rb +0 -2
  84. data/lib/rubocop/cop/style/redundant_begin.rb +45 -0
  85. data/lib/rubocop/cop/style/redundant_return.rb +59 -0
  86. data/lib/rubocop/cop/style/redundant_self.rb +83 -0
  87. data/lib/rubocop/cop/style/regexp_literal.rb +0 -2
  88. data/lib/rubocop/cop/style/rescue_modifier.rb +13 -21
  89. data/lib/rubocop/cop/style/semicolon.rb +15 -9
  90. data/lib/rubocop/cop/style/single_line_methods.rb +0 -4
  91. data/lib/rubocop/cop/style/space_after_comma_etc.rb +2 -2
  92. data/lib/rubocop/cop/style/space_after_control_keyword.rb +0 -1
  93. data/lib/rubocop/cop/style/string_literals.rb +5 -2
  94. data/lib/rubocop/cop/style/surrounding_space.rb +106 -91
  95. data/lib/rubocop/cop/style/tab.rb +4 -3
  96. data/lib/rubocop/cop/style/ternary_operator.rb +0 -4
  97. data/lib/rubocop/cop/style/trailing_whitespace.rb +4 -3
  98. data/lib/rubocop/cop/style/trivial_accessors.rb +51 -6
  99. data/lib/rubocop/cop/style/unless_else.rb +0 -2
  100. data/lib/rubocop/cop/style/variable_interpolation.rb +0 -2
  101. data/lib/rubocop/cop/style/when_then.rb +3 -3
  102. data/lib/rubocop/cop/style/while_until_do.rb +3 -5
  103. data/lib/rubocop/cop/style/word_array.rb +0 -2
  104. data/lib/rubocop/cop/util.rb +0 -4
  105. data/lib/rubocop/formatter/file_list_formatter.rb +18 -0
  106. data/lib/rubocop/formatter/formatter_set.rb +2 -1
  107. data/lib/rubocop/processed_source.rb +27 -0
  108. data/lib/rubocop/rake_task.rb +50 -0
  109. data/lib/rubocop/source_parser.rb +105 -0
  110. data/lib/rubocop/target_finder.rb +67 -0
  111. data/lib/rubocop/token.rb +22 -0
  112. data/lib/rubocop/version.rb +1 -1
  113. data/rubocop.gemspec +5 -3
  114. data/spec/project_spec.rb +0 -11
  115. data/spec/rubocop/cli_spec.rb +112 -6
  116. data/spec/rubocop/config_spec.rb +13 -17
  117. data/spec/rubocop/config_store_spec.rb +8 -23
  118. data/spec/rubocop/cops/commissioner_spec.rb +72 -0
  119. data/spec/rubocop/cops/corrector_spec.rb +63 -0
  120. data/spec/rubocop/cops/lint/assignment_in_condition_spec.rb +2 -2
  121. data/spec/rubocop/cops/lint/block_alignment_spec.rb +357 -0
  122. data/spec/rubocop/cops/lint/empty_ensure_spec.rb +33 -0
  123. data/spec/rubocop/cops/lint/end_alignment_spec.rb +0 -263
  124. data/spec/rubocop/cops/lint/ensure_return_spec.rb +6 -9
  125. data/spec/rubocop/cops/offence_spec.rb +28 -0
  126. data/spec/rubocop/cops/style/and_or_spec.rb +21 -11
  127. data/spec/rubocop/cops/style/ascii_identifiers_spec.rb +14 -0
  128. data/spec/rubocop/cops/style/avoid_global_vars_spec.rb +10 -14
  129. data/spec/rubocop/cops/style/character_literal_spec.rb +17 -2
  130. data/spec/rubocop/cops/style/colon_method_call_spec.rb +20 -15
  131. data/spec/rubocop/cops/style/comment_annotation_spec.rb +62 -0
  132. data/spec/rubocop/cops/style/encoding_spec.rb +7 -0
  133. data/spec/rubocop/cops/style/parentheses_around_condition_spec.rb +37 -9
  134. data/spec/rubocop/cops/style/redundant_begin_spec.rb +63 -0
  135. data/spec/rubocop/cops/style/redundant_return_spec.rb +64 -0
  136. data/spec/rubocop/cops/style/redundant_self_spec.rb +76 -0
  137. data/spec/rubocop/cops/style/string_literals_spec.rb +18 -13
  138. data/spec/rubocop/cops/style/trivial_accessors_spec.rb +110 -52
  139. data/spec/rubocop/cops/style/when_then_spec.rb +14 -7
  140. data/spec/rubocop/cops/style/while_until_do_spec.rb +12 -0
  141. data/spec/rubocop/cops/variable_inspector_spec.rb +3 -5
  142. data/spec/rubocop/formatter/file_list_formatter_spec.rb +33 -0
  143. data/spec/rubocop/processed_source_spec.rb +67 -0
  144. data/spec/rubocop/source_parser_spec.rb +141 -0
  145. data/spec/rubocop/target_finder_spec.rb +180 -0
  146. data/spec/rubocop/token_spec.rb +27 -0
  147. data/spec/spec_helper.rb +24 -4
  148. metadata +108 -18
  149. checksums.yaml +0 -7
@@ -6,25 +6,25 @@ module Rubocop
6
6
  module Cop
7
7
  module Style
8
8
  describe WhenThen do
9
- let(:wt) { WhenThen.new }
9
+ let(:cop) { WhenThen.new }
10
10
 
11
11
  it 'registers an offence for when x;' do
12
- inspect_source(wt, ['case a',
12
+ inspect_source(cop, ['case a',
13
13
  'when b; c',
14
14
  'end'])
15
- expect(wt.offences.map(&:message)).to eq(
15
+ expect(cop.offences.map(&:message)).to eq(
16
16
  ['Never use "when x;". Use "when x then" instead.'])
17
17
  end
18
18
 
19
19
  it 'accepts when x then' do
20
- inspect_source(wt, ['case a',
20
+ inspect_source(cop, ['case a',
21
21
  'when b then c',
22
22
  'end'])
23
- expect(wt.offences.map(&:message)).to be_empty
23
+ expect(cop.offences.map(&:message)).to be_empty
24
24
  end
25
25
 
26
26
  it 'accepts ; separating statements in the body of when' do
27
- inspect_source(wt, ['case a',
27
+ inspect_source(cop, ['case a',
28
28
  'when b then c; d',
29
29
  'end',
30
30
  '',
@@ -32,7 +32,14 @@ module Rubocop
32
32
  'when f',
33
33
  ' g; h',
34
34
  'end'])
35
- expect(wt.offences.map(&:message)).to be_empty
35
+ expect(cop.offences.map(&:message)).to be_empty
36
+ end
37
+
38
+ it 'auto-corrects "when x;" with "when x then"' do
39
+ new_source = autocorrect_source(cop, ['case a',
40
+ 'when b; c',
41
+ 'end'])
42
+ expect(new_source).to eq("case a\nwhen b then c\nend")
36
43
  end
37
44
  end
38
45
  end
@@ -41,6 +41,18 @@ module Rubocop
41
41
  'end'])
42
42
  expect(cop.offences).to be_empty
43
43
  end
44
+
45
+ it 'auto-corrects the usage of "do" in multiline while' do
46
+ new_source = autocorrect_source(cop, ['while cond do',
47
+ 'end'])
48
+ expect(new_source).to eq("while cond \nend")
49
+ end
50
+
51
+ it 'auto-corrects the usage of "do" in multiline until' do
52
+ new_source = autocorrect_source(cop, ['until cond do',
53
+ 'end'])
54
+ expect(new_source).to eq("until cond \nend")
55
+ end
44
56
  end
45
57
  end
46
58
  end
@@ -32,7 +32,7 @@ module Rubocop
32
32
  context 'when begin node is passed' do
33
33
  it 'accepts that as pseudo scope for top level scope' do
34
34
  node = s(:begin)
35
- expect { Scope.new(node) }.not_to raise_error(ArgumentError)
35
+ expect { Scope.new(node) }.not_to raise_error
36
36
  end
37
37
  end
38
38
  end
@@ -260,10 +260,8 @@ module Rubocop
260
260
  end
261
261
 
262
262
  let(:ast) do
263
- ast, *_ = Rubocop::CLI.parse('(string)') do |sb|
264
- sb.source = source
265
- end
266
- ast
263
+ processed_source = Rubocop::SourceParser.parse(source)
264
+ processed_source.ast
267
265
  end
268
266
 
269
267
  # (class
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+ require 'stringio'
5
+
6
+ module Rubocop
7
+ module Formatter
8
+ describe FileListFormatter do
9
+ let(:formatter) { FileListFormatter.new(output) }
10
+ let(:output) { StringIO.new }
11
+
12
+ describe '#report_file' do
13
+ it 'displays parsable text' do
14
+ cop = Cop::Cop.new
15
+ source_buffer = Parser::Source::Buffer.new('test', 1)
16
+ source_buffer.source = %w(a b cdefghi).join("\n")
17
+
18
+ cop.add_offence(:convention,
19
+ Parser::Source::Range.new(source_buffer, 0, 1),
20
+ 'message 1')
21
+ cop.add_offence(:fatal,
22
+ Parser::Source::Range.new(source_buffer, 9, 10),
23
+ 'message 2')
24
+
25
+ formatter.report_file('test', cop.offences)
26
+ formatter.report_file('test_2', cop.offences)
27
+ expect(output.string).to eq ['test',
28
+ "test_2\n"].join("\n")
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,67 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ module Rubocop
6
+ describe ProcessedSource do
7
+ subject(:processed_source) do
8
+ ProcessedSource.new(
9
+ buffer,
10
+ double('ast'),
11
+ double('comments'),
12
+ double('tokens'),
13
+ double('diagnostics')
14
+ )
15
+ end
16
+
17
+ let(:source) do
18
+ [
19
+ 'def some_method',
20
+ " puts 'foo'",
21
+ 'end',
22
+ 'some_method'
23
+ ].join("\n")
24
+ end
25
+
26
+ let(:buffer) do
27
+ buffer = Parser::Source::Buffer.new('(string)', 1)
28
+ buffer.source = source
29
+ buffer
30
+ end
31
+
32
+ describe '#lines' do
33
+ it 'is an array' do
34
+ expect(processed_source.lines).to be_a(Array)
35
+ end
36
+
37
+ it 'has same number of elements as line count' do
38
+ expect(processed_source.lines).to have(4).items
39
+ end
40
+
41
+ it 'contains lines as string without linefeed' do
42
+ first_line = processed_source.lines.first
43
+ expect(first_line).to eq('def some_method')
44
+ end
45
+ end
46
+
47
+ describe '#[]' do
48
+ context 'when an index is passed' do
49
+ it 'returns the line' do
50
+ expect(processed_source[2]).to eq('end')
51
+ end
52
+ end
53
+
54
+ context 'when a range is passed' do
55
+ it 'returns the array of lines' do
56
+ expect(processed_source[2..3]).to eq(%w(end some_method))
57
+ end
58
+ end
59
+
60
+ context 'when start index and length are passed' do
61
+ it 'returns the array of lines' do
62
+ expect(processed_source[2, 2]).to eq(%w(end some_method))
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,141 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ module Rubocop
6
+ describe SourceParser, :isolated_environment do
7
+ include FileHelper
8
+
9
+ describe '.parse_file' do
10
+ let(:file) { 'example.rb' }
11
+
12
+ let(:source) do
13
+ [
14
+ '# encoding: utf-8',
15
+ '',
16
+ 'def some_method',
17
+ " puts 'foo'",
18
+ 'end',
19
+ '',
20
+ 'some_method'
21
+ ]
22
+ end
23
+
24
+ before do
25
+ create_file(file, source)
26
+ end
27
+
28
+ let (:processed_source) do
29
+ SourceParser.parse_file(file)
30
+ end
31
+
32
+ it 'returns ProcessedSource' do
33
+ expect(processed_source).to be_a(ProcessedSource)
34
+ end
35
+
36
+ describe 'the returned processed source' do
37
+ it 'has the root node of AST' do
38
+ expect(processed_source.ast).to be_a(Parser::AST::Node)
39
+ end
40
+
41
+ it 'has an array of comments' do
42
+ expect(processed_source.comments).to be_a(Array)
43
+ expect(processed_source.comments.first)
44
+ .to be_a(Parser::Source::Comment)
45
+ end
46
+
47
+ it 'has an array of tokens' do
48
+ expect(processed_source.tokens).to be_a(Array)
49
+ expect(processed_source.tokens.first).to be_a(Token)
50
+ end
51
+
52
+ it 'has a source buffer' do
53
+ expect(processed_source.buffer).to be_a(Parser::Source::Buffer)
54
+ end
55
+
56
+ context 'when the source is valid' do
57
+ it 'does not have diagnostics' do
58
+ expect(processed_source.diagnostics).to be_a(Array)
59
+ expect(processed_source.diagnostics).to be_empty
60
+ end
61
+ end
62
+
63
+ context 'when the source has invalid syntax' do
64
+ let(:source) do
65
+ [
66
+ '# encoding: utf-8',
67
+ '',
68
+ 'def some_method',
69
+ " puts 'foo'",
70
+ 'end',
71
+ '',
72
+ 'some_method',
73
+ '',
74
+ '?invalid_syntax'
75
+ ]
76
+ end
77
+
78
+ it 'has an array of diagnostics' do
79
+ expect(processed_source.diagnostics).to be_a(Array)
80
+ expect(processed_source.diagnostics.first)
81
+ .to be_a(Parser::Diagnostic)
82
+ end
83
+ end
84
+ end
85
+ end
86
+
87
+ describe '.cop_disabled_lines_in' do
88
+ let(:source) do
89
+ [
90
+ '# encoding: utf-8',
91
+ '',
92
+ '# rubocop:disable MethodLength',
93
+ 'def some_method',
94
+ " puts 'foo'",
95
+ 'end',
96
+ '# rubocop:enable MethodLength',
97
+ '',
98
+ '# rubocop:disable all',
99
+ 'some_method',
100
+ '# rubocop:enable all',
101
+ '',
102
+ "code = 'This is evil.'",
103
+ 'eval(code) # rubocop:disable Eval',
104
+ "puts 'This is not evil.'"
105
+ ]
106
+ end
107
+
108
+ let(:disabled_lines) { SourceParser.cop_disabled_lines_in(source) }
109
+
110
+ it 'has keys for disabled cops' do
111
+ expect(disabled_lines).to have_key('MethodLength')
112
+ expect(disabled_lines).to have_key('Eval')
113
+ end
114
+
115
+ it 'supports disabling multiple lines with a pair of directive' do
116
+ method_length_disabled_lines = disabled_lines['MethodLength']
117
+ expected_part = (3..6).to_a
118
+ expect(method_length_disabled_lines & expected_part)
119
+ .to eq(expected_part)
120
+ end
121
+
122
+ it 'supports disabling single line with a direcive at end of line' do
123
+ eval_disabled_lines = disabled_lines['Eval']
124
+ expect(eval_disabled_lines).to include(14)
125
+ expect(eval_disabled_lines).not_to include(15)
126
+ end
127
+
128
+ it 'supports disabling all cops with keyword all' do
129
+ all_cop_names = Cop::Cop.all.map(&:cop_name).sort
130
+ expect(disabled_lines.keys.sort).to eq(all_cop_names)
131
+
132
+ expected_part = (9..10).to_a
133
+
134
+ disabled_lines.each_value do |each_cop_disabled_lines|
135
+ expect(each_cop_disabled_lines & expected_part)
136
+ .to eq(expected_part)
137
+ end
138
+ end
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,180 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ module Rubocop
6
+ describe TargetFinder, :isolated_environment do
7
+ include FileHelper
8
+
9
+ subject(:target_finder) { TargetFinder.new(config_store, debug) }
10
+ let(:config_store) { ConfigStore.new }
11
+ let(:debug) { false }
12
+
13
+ before do
14
+ create_file('dir1/ruby1.rb', '# encoding: utf-8')
15
+ create_file('dir1/ruby2.rb', '# encoding: utf-8')
16
+ create_file('dir1/file.txt', '# encoding: utf-8')
17
+ create_file('dir1/file', '# encoding: utf-8')
18
+ create_file('dir1/executable', '#!/usr/bin/env ruby')
19
+ create_file('dir2/ruby3.rb', '# encoding: utf-8')
20
+ end
21
+
22
+ describe '#find' do
23
+ let(:found_files) { target_finder.find(args) }
24
+ let(:found_basenames) { found_files.map { |f| File.basename(f) } }
25
+ let(:args) { [] }
26
+
27
+ it 'returns absolute paths' do
28
+ expect(found_files).not_to be_empty
29
+ found_files.each do |file|
30
+ expect(file).to start_with('/')
31
+ end
32
+ end
33
+
34
+ context 'when no argument is passed' do
35
+ let(:args) { [] }
36
+
37
+ it 'finds files under the current directory' do
38
+ Dir.chdir('dir1') do
39
+ expect(found_files).not_to be_empty
40
+ found_files.each do |file|
41
+ expect(file).to include('/dir1/')
42
+ expect(file).not_to include('/dir2/')
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ context 'when a directory path is passed' do
49
+ let(:args) { ['../dir2'] }
50
+
51
+ it 'finds files under the specified directory' do
52
+ Dir.chdir('dir1') do
53
+ expect(found_files).not_to be_empty
54
+ found_files.each do |file|
55
+ expect(file).to include('/dir2/')
56
+ expect(file).not_to include('/dir1/')
57
+ end
58
+ end
59
+ end
60
+ end
61
+
62
+ context 'when a file is passed' do
63
+ let(:args) { ['dir2/file'] }
64
+
65
+ it 'picks the file' do
66
+ expect(found_basenames).to eq(['file'])
67
+ end
68
+ end
69
+
70
+ context 'when a pattern is passed' do
71
+ let(:args) { ['dir1/*2.rb'] }
72
+
73
+ it 'finds files which match the pattern' do
74
+ expect(found_basenames).to eq(['ruby2.rb'])
75
+ end
76
+ end
77
+
78
+ context 'when same paths are passed' do
79
+ let(:args) { %w(dir1 dir1) }
80
+
81
+ it 'does not return duplicated file paths' do
82
+ count = found_basenames.count { |f| f == 'ruby1.rb' }
83
+ expect(count).to eq(1)
84
+ end
85
+ end
86
+ end
87
+
88
+ describe '#target_files_in_dir' do
89
+ let(:found_files) { target_finder.target_files_in_dir(base_dir) }
90
+ let(:found_basenames) { found_files.map { |f| File.basename(f) } }
91
+ let(:base_dir) { '.' }
92
+
93
+ it 'picks files with extension .rb' do
94
+ rb_file_count = found_files.count { |f| f.end_with?('.rb') }
95
+ expect(rb_file_count).to eq(3)
96
+ end
97
+
98
+ it 'picks ruby executable files with no extension' do
99
+ expect(found_basenames).to include('executable')
100
+ end
101
+
102
+ it 'does not pick files with no extension and no ruby shebang' do
103
+ expect(found_basenames).not_to include('file')
104
+ end
105
+
106
+ it 'picks ruby executable files with no extension' do
107
+ expect(found_basenames).to include('executable')
108
+ end
109
+
110
+ it 'does not pick directories' do
111
+ found_basenames = found_files.map { |f| File.basename(f) }
112
+ expect(found_basenames).not_to include('dir1')
113
+ end
114
+
115
+ it 'picks files specified to be included in config' do
116
+ config = double('config')
117
+ config.stub(:file_to_include?) do |file|
118
+ File.basename(file) == 'file'
119
+ end
120
+ config.stub(:file_to_exclude?).and_return(false)
121
+ config_store.stub(:for).and_return(config)
122
+
123
+ expect(found_basenames).to include('file')
124
+ end
125
+
126
+ it 'does not pick files specified to be excluded in config' do
127
+ config = double('config').as_null_object
128
+ config.stub(:file_to_include?).and_return(false)
129
+ config.stub(:file_to_exclude?) do |file|
130
+ File.basename(file) == 'ruby2.rb'
131
+ end
132
+ config_store.stub(:for).and_return(config)
133
+
134
+ expect(found_basenames).not_to include('ruby2.rb')
135
+ end
136
+
137
+ it 'does not return duplicated paths' do
138
+ config = double('config').as_null_object
139
+ config.stub(:file_to_include?).and_return(true)
140
+ config.stub(:file_to_exclude?).and_return(false)
141
+ config_store.stub(:for).and_return(config)
142
+
143
+ count = found_basenames.count { |f| f == 'ruby1.rb' }
144
+ expect(count).to eq(1)
145
+ end
146
+
147
+ context 'when an exception is raised while reading file' do
148
+ around do |example|
149
+ File.any_instance.stub(:readline).and_raise(EOFError)
150
+
151
+ original_stderr = $stderr
152
+ $stderr = StringIO.new
153
+ begin
154
+ example.run
155
+ ensure
156
+ $stderr = original_stderr
157
+ end
158
+ end
159
+
160
+ context 'and debug mode is enabled' do
161
+ let(:debug) { true }
162
+
163
+ it 'outputs error message' do
164
+ found_files
165
+ expect($stderr.string).to include('Unprocessable file')
166
+ end
167
+ end
168
+
169
+ context 'and debug mode is disabled' do
170
+ let(:debug) { false }
171
+
172
+ it 'outputs nothing' do
173
+ found_files
174
+ expect($stderr.string).to be_empty
175
+ end
176
+ end
177
+ end
178
+ end
179
+ end
180
+ end