rubocop 0.2.0 → 0.2.1

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.

data/CONTRIBUTING.md ADDED
@@ -0,0 +1,9 @@
1
+ # Contributing to Rubocop
2
+
3
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
4
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
5
+ * Fork the project.
6
+ * Start a feature/bugfix branch.
7
+ * Commit and push until you are happy with your contribution.
8
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
9
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
data/Gemfile CHANGED
@@ -6,11 +6,10 @@ source 'http://rubygems.org'
6
6
  # Add dependencies to develop your gem here.
7
7
  # Include everything needed to run rake, tests, features, etc.
8
8
  group :development do
9
- gem 'rspec', '~> 2.8.0'
10
- gem 'yard', '~> 0.7'
11
- gem 'redcarpet'
12
- gem 'cucumber', '>= 0'
13
- gem 'bundler', '~> 1.1.0'
9
+ gem 'rake', '~> 10.0.0'
10
+ gem 'rspec', '~> 2.12.0'
11
+ gem 'yard', '~> 0.8.0'
12
+ gem 'bundler', '~> 1.2.0'
14
13
  gem 'jeweler', '~> 1.8.3'
15
14
  gem 'simplecov'
16
15
  end
data/Gemfile.lock CHANGED
@@ -1,51 +1,39 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
- builder (3.0.0)
5
- cucumber (1.1.9)
6
- builder (>= 2.1.2)
7
- diff-lcs (>= 1.1.2)
8
- gherkin (~> 2.9.0)
9
- json (>= 1.4.6)
10
- term-ansicolor (>= 1.0.6)
11
4
  diff-lcs (1.1.3)
12
- gherkin (2.9.3)
13
- json (>= 1.4.6)
14
5
  git (1.2.5)
15
- jeweler (1.8.3)
6
+ jeweler (1.8.4)
16
7
  bundler (~> 1.0)
17
8
  git (>= 1.2.5)
18
9
  rake
19
10
  rdoc
20
- json (1.6.6)
21
- multi_json (1.3.2)
22
- rake (0.9.2.2)
11
+ json (1.7.6)
12
+ multi_json (1.5.0)
13
+ rake (10.0.3)
23
14
  rdoc (3.12)
24
15
  json (~> 1.4)
25
- redcarpet (2.1.1)
26
- rspec (2.8.0)
27
- rspec-core (~> 2.8.0)
28
- rspec-expectations (~> 2.8.0)
29
- rspec-mocks (~> 2.8.0)
30
- rspec-core (2.8.0)
31
- rspec-expectations (2.8.0)
32
- diff-lcs (~> 1.1.2)
33
- rspec-mocks (2.8.0)
34
- simplecov (0.6.2)
35
- multi_json (~> 1.3)
36
- simplecov-html (~> 0.5.3)
37
- simplecov-html (0.5.3)
38
- term-ansicolor (1.0.7)
39
- yard (0.7.5)
16
+ rspec (2.12.0)
17
+ rspec-core (~> 2.12.0)
18
+ rspec-expectations (~> 2.12.0)
19
+ rspec-mocks (~> 2.12.0)
20
+ rspec-core (2.12.2)
21
+ rspec-expectations (2.12.1)
22
+ diff-lcs (~> 1.1.3)
23
+ rspec-mocks (2.12.1)
24
+ simplecov (0.7.1)
25
+ multi_json (~> 1.0)
26
+ simplecov-html (~> 0.7.1)
27
+ simplecov-html (0.7.1)
28
+ yard (0.8.3)
40
29
 
41
30
  PLATFORMS
42
31
  ruby
43
32
 
44
33
  DEPENDENCIES
45
- bundler (~> 1.1.0)
46
- cucumber
34
+ bundler (~> 1.2.0)
47
35
  jeweler (~> 1.8.3)
48
- redcarpet
49
- rspec (~> 2.8.0)
36
+ rake (~> 10.0.0)
37
+ rspec (~> 2.12.0)
50
38
  simplecov
51
- yard (~> 0.7)
39
+ yard (~> 0.8.0)
data/README.md CHANGED
@@ -18,18 +18,8 @@ Alternatively you can `rubocop` a list of files and folders to check:
18
18
  $ rubocop app spec lib/something.rb
19
19
  ```
20
20
 
21
- ## Contributing to Rubocop
22
-
23
- * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
24
- * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
25
- * Fork the project.
26
- * Start a feature/bugfix branch.
27
- * Commit and push until you are happy with your contribution.
28
- * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
29
- * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
30
-
31
21
  ## Copyright
32
22
 
33
- Copyright (c) 2012 Bozhidar Batsov. See LICENSE.txt for
23
+ Copyright (c) 2012-2013 Bozhidar Batsov. See LICENSE.txt for
34
24
  further details.
35
25
 
data/Rakefile CHANGED
@@ -36,9 +36,6 @@ RSpec::Core::RakeTask.new(:rcov) do |spec|
36
36
  spec.rcov = true
37
37
  end
38
38
 
39
- require 'cucumber/rake/task'
40
- Cucumber::Rake::Task.new(:features)
41
-
42
39
  task :default => :spec
43
40
 
44
41
  require 'yard'
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 0.2.1
@@ -5,7 +5,7 @@ begin
5
5
  Bundler.setup(:default, :development)
6
6
  rescue Bundler::BundlerError => e
7
7
  $stderr.puts e.message
8
- $stderr.puts "Run `bundle install` to install missing gems"
8
+ $stderr.puts 'Run `bundle install` to install missing gems'
9
9
  exit e.status_code
10
10
  end
11
11
 
data/lib/rubocop.rb CHANGED
@@ -18,6 +18,10 @@ require 'rubocop/cop/numeric_literals'
18
18
  require 'rubocop/cop/align_parameters'
19
19
  require 'rubocop/cop/def_parentheses'
20
20
  require 'rubocop/cop/if_then_else'
21
+ require 'rubocop/cop/blocks'
22
+ require 'rubocop/cop/parameter_lists'
23
+ require 'rubocop/cop/string_literals'
24
+ require 'rubocop/cop/ternary_operator'
21
25
 
22
26
  require 'rubocop/report/report'
23
27
  require 'rubocop/report/plain_text'
data/lib/rubocop/cli.rb CHANGED
@@ -14,12 +14,12 @@ module Rubocop
14
14
  $options = { mode: :default }
15
15
 
16
16
  OptionParser.new do |opts|
17
- opts.banner = "Usage: rubocop [options] [file1, file2, ...]"
17
+ opts.banner = 'Usage: rubocop [options] [file1, file2, ...]'
18
18
 
19
- opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
19
+ opts.on('-v', '--[no-]verbose', 'Run verbosely') do |v|
20
20
  $options[:verbose] = v
21
21
  end
22
- opts.on("-e", "--emacs", "Emacs style output") do
22
+ opts.on('-e', '--emacs', 'Emacs style output') do
23
23
  $options[:mode] = :emacs_style
24
24
  end
25
25
  end.parse!(args)
@@ -31,18 +31,15 @@ module Rubocop
31
31
  target_files(args).each do |file|
32
32
  report = Report.create(file, $options[:mode])
33
33
  source = File.readlines(file).map do |line|
34
- enc = line.encoding.name
35
- # Get rid of invalid byte sequences
36
- line.encode!('UTF-16', enc, invalid: :replace, replace: '')
37
- line.encode!(enc, 'UTF-16')
38
-
34
+ get_rid_of_invalid_byte_sequences(line)
39
35
  line.chomp
40
36
  end
41
37
 
42
- tokens, sexp = CLI.rip_source(source)
38
+ tokens, sexp, correlations = CLI.rip_source(source)
43
39
 
44
40
  cops.each do |cop_klass|
45
41
  cop = cop_klass.new
42
+ cop.correlations = correlations
46
43
  cop.inspect(file, source, tokens, sexp)
47
44
  total_offences += cop.offences.count
48
45
  report << cop if cop.has_report?
@@ -57,17 +54,26 @@ module Rubocop
57
54
  return total_offences == 0 ? 0 : 1
58
55
  end
59
56
 
57
+ def get_rid_of_invalid_byte_sequences(line)
58
+ enc = line.encoding.name
59
+ # UTF-16 works better in this algorithm but is not supported in 1.9.2.
60
+ temporary_encoding = (RUBY_VERSION == '1.9.2') ? 'UTF-8' : 'UTF-16'
61
+ line.encode!(temporary_encoding, enc, invalid: :replace, replace: '')
62
+ line.encode!(enc, temporary_encoding)
63
+ end
64
+
60
65
  def self.rip_source(source)
61
66
  tokens = Ripper.lex(source.join("\n")).map { |t| Cop::Token.new(*t) }
62
67
  sexp = Ripper.sexp(source.join("\n"))
63
68
  Cop::Position.make_position_objects(sexp)
64
- [tokens, sexp]
69
+ correlations = Cop::Grammar.new(tokens).correlate(sexp)
70
+ [tokens, sexp, correlations]
65
71
  end
66
72
 
67
73
  def show_cops_on_duty(cops)
68
- puts "Reporting for duty:"
74
+ puts 'Reporting for duty:'
69
75
  cops.each { |c| puts c }
70
- puts "*******************"
76
+ puts '*******************'
71
77
  end
72
78
 
73
79
  # Generate a list of target files by expanding globing patterns
@@ -33,7 +33,7 @@ module Rubocop
33
33
  def get_args(method_add_arg)
34
34
  fcall = method_add_arg[1]
35
35
  return nil if fcall[0] != :fcall
36
- return nil if fcall[1][0..1] == [:@ident, "lambda"]
36
+ return nil if fcall[1][0..1] == [:@ident, 'lambda']
37
37
  arg_paren = method_add_arg[2..-1][0]
38
38
  return nil if arg_paren[0] != :arg_paren || arg_paren[1].nil?
39
39
 
@@ -0,0 +1,48 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ class Blocks < Cop
6
+ ERROR_MESSAGE = ['Avoid using {...} for multi-line blocks.',
7
+ 'Prefer {...} over do...end for single-line blocks.']
8
+
9
+ def inspect(file, source, tokens, sexp)
10
+ @file = file
11
+
12
+ # The reverse_correlations maps grammar path object ids to
13
+ # token indexes, so we can use it to find the corresponding }
14
+ # for each {.
15
+ reverse_correlations = Hash.new([])
16
+ @correlations.each do |ix, path|
17
+ reverse_correlations[path.object_id] += [ix]
18
+ end
19
+ tokens.each_with_index do |t, ix|
20
+ case [t.type, t.text]
21
+ when [:on_lbrace, '{']
22
+ path = @correlations[ix] or next
23
+ if path.last == :brace_block
24
+ rbrace_ix = reverse_correlations[path.object_id] - [ix]
25
+ if rbrace_ix.empty?
26
+ fail "\n#@file:#{t.pos.lineno}:#{t.pos.column}: " +
27
+ 'Matching brace not found'
28
+ end
29
+ if tokens[*rbrace_ix].pos.lineno > t.pos.lineno
30
+ add_offence(:convention, t.pos.lineno, ERROR_MESSAGE[0])
31
+ end
32
+ end
33
+ when [:on_kw, 'do']
34
+ end_offset = tokens[ix..-1].index { |t2| t2.text == 'end' }
35
+ unless end_offset
36
+ fail "\n#@file:#{t.pos.lineno}:#{t.pos.column}: " +
37
+ 'Matching end not found'
38
+ end
39
+ end_token_ix = ix + end_offset
40
+ if tokens[end_token_ix].pos.lineno == t.pos.lineno
41
+ add_offence(:convention, t.pos.lineno, ERROR_MESSAGE[1])
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -32,6 +32,7 @@ module Rubocop
32
32
 
33
33
  class Cop
34
34
  attr_accessor :offences
35
+ attr_writer :correlations
35
36
 
36
37
  @all = []
37
38
  @enabled = []
@@ -4,7 +4,7 @@ module Rubocop
4
4
  module Cop
5
5
  class DefParentheses < Cop
6
6
  ERROR_MESSAGE = ['Use def with parentheses when there are arguments.',
7
- "Omit the parentheses in defs when the method " +
7
+ 'Omit the parentheses in defs when the method ' +
8
8
  "doesn't accept any arguments."]
9
9
  EMPTY_PARAMS = [:params, nil, nil, nil, nil, nil]
10
10
 
@@ -7,10 +7,10 @@ module Rubocop
7
7
  @tokens_without_pos = tokens.map { |t| [t.type, t.text] }
8
8
  process_embedded_expressions
9
9
  @token_indexes = {}
10
- @tokens_without_pos.each_with_index { |t, i|
10
+ @tokens_without_pos.each_with_index do |t, i|
11
11
  @token_indexes[t] ||= []
12
12
  @token_indexes[t] << i
13
- }
13
+ end
14
14
  @ix = 0
15
15
  @table = {}
16
16
  token_positions = tokens.map { |t| [t.pos.lineno, t.pos.column] }
@@ -122,12 +122,12 @@ module Rubocop
122
122
 
123
123
  def add_matching_rbrace(ix)
124
124
  brace_depth = 0
125
- rbrace_offset = @tokens_without_pos[@ix..-1].index do |t|
125
+ rbrace_offset = @tokens_without_pos[ix..-1].index do |t|
126
126
  brace_depth += 1 if t == [:on_lbrace, '{']
127
127
  brace_depth -= 1 if t == [:on_rbrace, '}']
128
128
  brace_depth == 0 && t == [:on_rbrace, '}']
129
129
  end
130
- @table[@ix + rbrace_offset] = @table[ix] if rbrace_offset
130
+ @table[ix + rbrace_offset] = @table[ix] if rbrace_offset
131
131
  end
132
132
  end
133
133
  end
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ class ParameterLists < Cop
6
+ ERROR_MESSAGE = 'Avoid parameter lists longer than four parameters.'
7
+
8
+ def inspect(file, source, tokens, sexp)
9
+ each(:params, sexp) do |params|
10
+ if params[1] && params[1].size > 4
11
+ add_offence(:convention, params[1][0][-1].lineno, ERROR_MESSAGE)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,36 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ class StringLiterals < Cop
6
+ ERROR_MESSAGE = "Prefer single-quoted strings when you don't need " +
7
+ 'string interpolation or special symbols.'
8
+
9
+ def inspect(file, source, tokens, sexp)
10
+ state = :outside
11
+ tokens.each do |t|
12
+ state = case [state, t.type]
13
+ when [:outside, :on_tstring_beg]
14
+ :double_quote if t.text == '"'
15
+
16
+ when [:double_quote, :on_tstring_content]
17
+ :valid_double_quote if t.text =~ /'|\\[ntrx]/
18
+
19
+ when [:double_quote, :on_embexpr_beg]
20
+ :embedded_expression
21
+
22
+ when [:double_quote, :on_tstring_end]
23
+ add_offence(:convention, t.pos.lineno, ERROR_MESSAGE)
24
+ :outside
25
+
26
+ when [:embedded_expression, :on_rbrace]
27
+ :valid_double_quote
28
+
29
+ when [:valid_double_quote, :on_tstring_end]
30
+ :outside
31
+ end || state
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -8,7 +8,7 @@ module Rubocop
8
8
  ERROR_MESSAGE = 'Surrounding space missing for '
9
9
 
10
10
  def inspect(file, source, tokens, sexp)
11
- Grammar.new(tokens).correlate(sexp).sort.each do |ix, grammar_path|
11
+ @correlations.sort.each do |ix, grammar_path|
12
12
  t = tokens[ix]
13
13
  case t.type
14
14
  when :on_op
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ class TernaryOperator < Cop
6
+ ERROR_MESSAGE = 'Avoid multi-line ?: (the ternary operator); use ' +
7
+ 'if/unless instead.'
8
+
9
+ def inspect(file, source, tokens, sexp)
10
+ each(:ifop, sexp) do |ifop|
11
+ line_numbers = all_positions(ifop).map(&:lineno)
12
+ if line_numbers.uniq.size > 1
13
+ add_offence(:convention, line_numbers[0], ERROR_MESSAGE)
14
+ end
15
+ end
16
+ end
17
+
18
+ def all_positions(sexp)
19
+ return [sexp[2]] if sexp[0] =~ /^@/
20
+ sexp.grep(Array).inject([]) { |memo, s| memo + all_positions(s) }
21
+ end
22
+ end
23
+ end
24
+ end
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Rubocop
4
- VERSION = "0.0.1"
4
+ VERSION = '0.0.1'
5
5
  end
data/rubocop.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "rubocop"
8
- s.version = "0.2.0"
8
+ s.version = "0.2.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Bozhidar Batsov"]
12
- s.date = "2013-01-02"
12
+ s.date = "2013-01-12"
13
13
  s.description = "Automatic Ruby code style checking tool. Aims to enforce the community-driven Ruby Style Guide."
14
14
  s.email = "bozhidar@batsov.com"
15
15
  s.executables = ["rubocop"]
@@ -23,6 +23,7 @@ Gem::Specification.new do |s|
23
23
  ".rspec",
24
24
  ".rvmrc",
25
25
  ".travis.yml",
26
+ "CONTRIBUTING.md",
26
27
  "Gemfile",
27
28
  "Gemfile.lock",
28
29
  "LICENSE.txt",
@@ -36,6 +37,7 @@ Gem::Specification.new do |s|
36
37
  "lib/rubocop.rb",
37
38
  "lib/rubocop/cli.rb",
38
39
  "lib/rubocop/cop/align_parameters.rb",
40
+ "lib/rubocop/cop/blocks.rb",
39
41
  "lib/rubocop/cop/cop.rb",
40
42
  "lib/rubocop/cop/def_parentheses.rb",
41
43
  "lib/rubocop/cop/empty_lines.rb",
@@ -48,9 +50,12 @@ Gem::Specification.new do |s|
48
50
  "lib/rubocop/cop/line_length.rb",
49
51
  "lib/rubocop/cop/numeric_literals.rb",
50
52
  "lib/rubocop/cop/offence.rb",
53
+ "lib/rubocop/cop/parameter_lists.rb",
51
54
  "lib/rubocop/cop/space_after_comma_etc.rb",
55
+ "lib/rubocop/cop/string_literals.rb",
52
56
  "lib/rubocop/cop/surrounding_space.rb",
53
57
  "lib/rubocop/cop/tab.rb",
58
+ "lib/rubocop/cop/ternary_operator.rb",
54
59
  "lib/rubocop/cop/trailing_whitespace.rb",
55
60
  "lib/rubocop/report/emacs_style.rb",
56
61
  "lib/rubocop/report/plain_text.rb",
@@ -59,6 +64,7 @@ Gem::Specification.new do |s|
59
64
  "rubocop.gemspec",
60
65
  "spec/rubocop/cli_spec.rb",
61
66
  "spec/rubocop/cops/align_parameters_spec.rb",
67
+ "spec/rubocop/cops/blocks_spec.rb",
62
68
  "spec/rubocop/cops/cop_spec.rb",
63
69
  "spec/rubocop/cops/def_parentheses_spec.rb",
64
70
  "spec/rubocop/cops/empty_lines_spec.rb",
@@ -70,9 +76,12 @@ Gem::Specification.new do |s|
70
76
  "spec/rubocop/cops/line_length_spec.rb",
71
77
  "spec/rubocop/cops/numeric_literals_spec.rb",
72
78
  "spec/rubocop/cops/offence_spec.rb",
79
+ "spec/rubocop/cops/parameter_lists_spec.rb",
73
80
  "spec/rubocop/cops/space_after_comma_etc_spec.rb",
81
+ "spec/rubocop/cops/string_literals_spec.rb",
74
82
  "spec/rubocop/cops/surrounding_space_spec.rb",
75
83
  "spec/rubocop/cops/tab_spec.rb",
84
+ "spec/rubocop/cops/ternary_operator_spec.rb",
76
85
  "spec/rubocop/cops/trailing_whitespace_spec.rb",
77
86
  "spec/rubocop/reports/emacs_style_spec.rb",
78
87
  "spec/rubocop/reports/report_spec.rb",
@@ -88,28 +97,25 @@ Gem::Specification.new do |s|
88
97
  s.specification_version = 3
89
98
 
90
99
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
91
- s.add_development_dependency(%q<rspec>, ["~> 2.8.0"])
92
- s.add_development_dependency(%q<yard>, ["~> 0.7"])
93
- s.add_development_dependency(%q<redcarpet>, [">= 0"])
94
- s.add_development_dependency(%q<cucumber>, [">= 0"])
95
- s.add_development_dependency(%q<bundler>, ["~> 1.1.0"])
100
+ s.add_development_dependency(%q<rake>, ["~> 10.0.0"])
101
+ s.add_development_dependency(%q<rspec>, ["~> 2.12.0"])
102
+ s.add_development_dependency(%q<yard>, ["~> 0.8.0"])
103
+ s.add_development_dependency(%q<bundler>, ["~> 1.2.0"])
96
104
  s.add_development_dependency(%q<jeweler>, ["~> 1.8.3"])
97
105
  s.add_development_dependency(%q<simplecov>, [">= 0"])
98
106
  else
99
- s.add_dependency(%q<rspec>, ["~> 2.8.0"])
100
- s.add_dependency(%q<yard>, ["~> 0.7"])
101
- s.add_dependency(%q<redcarpet>, [">= 0"])
102
- s.add_dependency(%q<cucumber>, [">= 0"])
103
- s.add_dependency(%q<bundler>, ["~> 1.1.0"])
107
+ s.add_dependency(%q<rake>, ["~> 10.0.0"])
108
+ s.add_dependency(%q<rspec>, ["~> 2.12.0"])
109
+ s.add_dependency(%q<yard>, ["~> 0.8.0"])
110
+ s.add_dependency(%q<bundler>, ["~> 1.2.0"])
104
111
  s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
105
112
  s.add_dependency(%q<simplecov>, [">= 0"])
106
113
  end
107
114
  else
108
- s.add_dependency(%q<rspec>, ["~> 2.8.0"])
109
- s.add_dependency(%q<yard>, ["~> 0.7"])
110
- s.add_dependency(%q<redcarpet>, [">= 0"])
111
- s.add_dependency(%q<cucumber>, [">= 0"])
112
- s.add_dependency(%q<bundler>, ["~> 1.1.0"])
115
+ s.add_dependency(%q<rake>, ["~> 10.0.0"])
116
+ s.add_dependency(%q<rspec>, ["~> 2.12.0"])
117
+ s.add_dependency(%q<yard>, ["~> 0.8.0"])
118
+ s.add_dependency(%q<bundler>, ["~> 1.2.0"])
113
119
  s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
114
120
  s.add_dependency(%q<simplecov>, [">= 0"])
115
121
  end
@@ -71,6 +71,18 @@ module Rubocop
71
71
  cli.run
72
72
  $stdout.string.should =~ /files inspected, 0 offences detected\n/
73
73
  end
74
+
75
+ it 'can process a file with an invalide UTF-8 byte sequence' do
76
+ File.open('example.rb', 'w') do |f|
77
+ f.puts '# encoding: utf-8'
78
+ f.puts "# \xf9\x29"
79
+ end
80
+ begin
81
+ cli.run(['--emacs', 'example.rb']).should == 0
82
+ ensure
83
+ File.delete 'example.rb'
84
+ end
85
+ end
74
86
  end
75
87
  end
76
88
  end
@@ -91,7 +91,7 @@ module Rubocop
91
91
  align.offences.map(&:message).should == []
92
92
  end
93
93
 
94
- it "accepts braceless hashes" do
94
+ it 'accepts braceless hashes' do
95
95
  inspect_source(align, '',
96
96
  ['run(collection, :entry_name => label,',
97
97
  ' :paginator => paginator)'])
@@ -0,0 +1,35 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ module Rubocop
6
+ module Cop
7
+ describe Blocks do
8
+ let (:blocks) { Blocks.new }
9
+
10
+ it 'registers an offence for a multiline block with braces' do
11
+ inspect_source(blocks, '', ['each { |x|',
12
+ '}'])
13
+ blocks.offences.map(&:message).should ==
14
+ ['Avoid using {...} for multi-line blocks.']
15
+ end
16
+
17
+ it 'registers an offence for a single line block with do-end' do
18
+ inspect_source(blocks, '', ['each do |x| end'])
19
+ blocks.offences.map(&:message).should ==
20
+ ['Prefer {...} over do...end for single-line blocks.']
21
+ end
22
+
23
+ it 'accepts a single line block with braces' do
24
+ inspect_source(blocks, '', ['each { |x| }'])
25
+ blocks.offences.map(&:message).should == []
26
+ end
27
+
28
+ it 'accepts a multiline block with do-end' do
29
+ inspect_source(blocks, '', ['each do |x|',
30
+ 'end'])
31
+ blocks.offences.map(&:message).should == []
32
+ end
33
+ end
34
+ end
35
+ end
@@ -21,7 +21,7 @@ module Rubocop
21
21
  inspect_source(def_par, '', src)
22
22
  def_par.offences.map(&:message).should ==
23
23
  ["Omit the parentheses in defs when the method doesn't accept any " +
24
- "arguments."]
24
+ 'arguments.']
25
25
  end
26
26
 
27
27
  it 'accepts def with arg and parens' do
@@ -9,38 +9,40 @@ module Rubocop
9
9
  tokens = Ripper.lex(EXAMPLE).map { |t| Token.new(*t) }
10
10
  let (:grammar) { Grammar.new(tokens) }
11
11
 
12
- it "correlates token indices to grammar paths" do
12
+ it 'correlates token indices to grammar paths' do
13
13
  method_block = [:program, :method_add_block]
14
14
  brace_block = method_block + [:brace_block]
15
15
  Ripper.lex(EXAMPLE).should ==
16
- [[[1, 0], :on_int, "3"],
17
- [[1, 1], :on_period, "."],
18
- [[1, 2], :on_ident, "times"],
19
- [[1, 7], :on_sp, " "],
20
- [[1, 8], :on_lbrace, "{"],
21
- [[1, 9], :on_sp, " "], # 5
22
- [[1, 10], :on_op, "|"],
23
- [[1, 11], :on_ident, "i"],
24
- [[1, 12], :on_op, "|"],
25
- [[1, 13], :on_sp, " "],
26
- [[1, 14], :on_ident, "x"], # 10
27
- [[1, 15], :on_sp, " "],
28
- [[1, 16], :on_op, "="],
29
- [[1, 17], :on_sp, " "],
30
- [[1, 18], :on_tstring_beg, "\""],
31
- [[1, 19], :on_embexpr_beg, "\#{"], # 15
32
- [[1, 21], :on_ident, "y"],
33
- [[1, 22], :on_rbrace, "}"],
34
- [[1, 23], :on_embexpr_beg, "\#{"],
35
- [[1, 25], :on_ident, "z"],
36
- [[1, 26], :on_rbrace, "}"], # 20
37
- [[1, 27], :on_tstring_content, "}"],
38
- [[1, 28], :on_tstring_end, "\""],
39
- [[1, 29], :on_sp, " "],
40
- [[1, 30], :on_rbrace, "}"]]
16
+ [[[1, 0], :on_int, '3'],
17
+ [[1, 1], :on_period, '.'],
18
+ [[1, 2], :on_ident, 'times'],
19
+ [[1, 7], :on_sp, ' '],
20
+ [[1, 8], :on_lbrace, '{'],
21
+ [[1, 9], :on_sp, ' '], # 5
22
+ [[1, 10], :on_op, '|'],
23
+ [[1, 11], :on_ident, 'i'],
24
+ [[1, 12], :on_op, '|'],
25
+ [[1, 13], :on_sp, ' '],
26
+ [[1, 14], :on_ident, 'x'], # 10
27
+ [[1, 15], :on_sp, ' '],
28
+ [[1, 16], :on_op, '='],
29
+ [[1, 17], :on_sp, ' '],
30
+ [[1, 18], :on_tstring_beg, '"'],
31
+ [[1, 19], :on_embexpr_beg, '#{'], # 15
32
+ [[1, 21], :on_ident, 'y'],
33
+ [[1, 22], :on_rbrace, '}'],
34
+ [[1, 23], :on_embexpr_beg, '#{'],
35
+ [[1, 25], :on_ident, 'z'],
36
+ [[1, 26], :on_rbrace, '}'], # 20
37
+ [[1, 27], :on_tstring_content, '}'],
38
+ [[1, 28], :on_tstring_end, '"'],
39
+ [[1, 29], :on_sp, ' '],
40
+ [[1, 30], :on_rbrace, '}']]
41
41
 
42
42
  sexp = Ripper.sexp(EXAMPLE)
43
43
  Position.make_position_objects(sexp)
44
+
45
+ varref = (RUBY_VERSION == '1.9.2') ? :var_ref : :vcall
44
46
  grammar.correlate(sexp).should == {
45
47
  0 => method_block + [:call, :@int], # 3
46
48
  2 => method_block + [:call, :@ident], # times
@@ -51,9 +53,9 @@ module Rubocop
51
53
  10 => brace_block + [:assign, :var_field, :@ident], # x
52
54
  12 => brace_block + [:assign], # =
53
55
  16 => brace_block + [:assign, :string_literal, :string_content,
54
- :string_embexpr, :vcall, :@ident], # y
56
+ :string_embexpr, varref, :@ident], # y
55
57
  19 => brace_block + [:assign, :string_literal, :string_content,
56
- :string_embexpr, :vcall, :@ident], # z
58
+ :string_embexpr, varref, :@ident], # z
57
59
  21 => brace_block + [:assign, :string_literal, :string_content,
58
60
  :@tstring_content], # }
59
61
  24 => brace_block, # }
@@ -8,35 +8,35 @@ module Rubocop
8
8
  let (:hash_syntax) { HashSyntax.new }
9
9
 
10
10
  it 'registers an offence for hash rocket syntax when new is possible' do
11
- inspect_source(hash_syntax, "", ['x = { :a => 0 }'])
11
+ inspect_source(hash_syntax, '', ['x = { :a => 0 }'])
12
12
  hash_syntax.offences.map(&:message).should ==
13
13
  ['Ruby 1.8 hash syntax detected']
14
14
  end
15
15
 
16
16
  it 'registers an offence for mixed syntax when new is possible' do
17
- inspect_source(hash_syntax, "", ['x = { :a => 0, b: 1 }'])
17
+ inspect_source(hash_syntax, '', ['x = { :a => 0, b: 1 }'])
18
18
  hash_syntax.offences.map(&:message).should ==
19
19
  ['Ruby 1.8 hash syntax detected']
20
20
  end
21
21
 
22
22
  it 'registers an offence for hash rockets in method calls' do
23
- inspect_source(hash_syntax, "", ['func(3, :a => 0)'])
23
+ inspect_source(hash_syntax, '', ['func(3, :a => 0)'])
24
24
  hash_syntax.offences.map(&:message).should ==
25
25
  ['Ruby 1.8 hash syntax detected']
26
26
  end
27
27
 
28
28
  it 'accepts hash rockets when keys have different types' do
29
- inspect_source(hash_syntax, "", ['x = { :a => 0, "b" => 1 }'])
29
+ inspect_source(hash_syntax, '', ['x = { :a => 0, "b" => 1 }'])
30
30
  hash_syntax.offences.map(&:message).should == []
31
31
  end
32
32
 
33
33
  it 'accepts new syntax in a hash literal' do
34
- inspect_source(hash_syntax, "", ['x = { a: 0, b: 1 }'])
34
+ inspect_source(hash_syntax, '', ['x = { a: 0, b: 1 }'])
35
35
  hash_syntax.offences.map(&:message).should == []
36
36
  end
37
37
 
38
38
  it 'accepts new syntax in method calls' do
39
- inspect_source(hash_syntax, "", ['func(3, a: 0)'])
39
+ inspect_source(hash_syntax, '', ['func(3, a: 0)'])
40
40
  hash_syntax.offences.map(&:message).should == []
41
41
  end
42
42
  end
@@ -14,7 +14,7 @@ module Rubocop
14
14
  'end',
15
15
  "if cond then\t",
16
16
  'end',
17
- "if cond then ",
17
+ 'if cond then ',
18
18
  'end',
19
19
  'if cond then # bad',
20
20
  'end'])
@@ -7,39 +7,39 @@ module Rubocop
7
7
  describe NumericLiterals do
8
8
  let (:num) { NumericLiterals.new }
9
9
 
10
- it "registers an offence for a long integer without underscores" do
10
+ it 'registers an offence for a long integer without underscores' do
11
11
  inspect_source(num, 'file.rb', ['a = 123456'])
12
12
  num.offences.map(&:message).should ==
13
13
  ['Add underscores to large numeric literals to improve their ' +
14
14
  'readability.']
15
15
  end
16
16
 
17
- it "registers an offence for an integer with not enough underscores" do
17
+ it 'registers an offence for an integer with not enough underscores' do
18
18
  inspect_source(num, 'file.rb', ['a = 123456_789000'])
19
19
  num.offences.map(&:message).should ==
20
20
  ['Add underscores to large numeric literals to improve their ' +
21
21
  'readability.']
22
22
  end
23
23
 
24
- it "registers an offence for a long float without underscores" do
24
+ it 'registers an offence for a long float without underscores' do
25
25
  inspect_source(num, 'file.rb', ['a = 1.234567'])
26
26
  num.offences.map(&:message).should ==
27
27
  ['Add underscores to large numeric literals to improve their ' +
28
28
  'readability.']
29
29
  end
30
30
 
31
- it "accepts long numbers with underscore" do
31
+ it 'accepts long numbers with underscore' do
32
32
  inspect_source(num, 'file.rb', ['a = 123_456',
33
33
  'b = 1.234_56'])
34
34
  num.offences.map(&:message).should == []
35
35
  end
36
36
 
37
- it "accepts a short integer without underscore" do
37
+ it 'accepts a short integer without underscore' do
38
38
  inspect_source(num, 'file.rb', ['a = 123'])
39
39
  num.offences.map(&:message).should == []
40
40
  end
41
41
 
42
- it "accepts short numbers without underscore" do
42
+ it 'accepts short numbers without underscore' do
43
43
  inspect_source(num, 'file.rb', ['a = 123',
44
44
  'b = 123.456'])
45
45
  num.offences.map(&:message).should == []
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ module Rubocop
6
+ module Cop
7
+ describe ParameterLists do
8
+ let (:list) { ParameterLists.new }
9
+
10
+ it 'registers an offence for a method def with 5 parameters' do
11
+ inspect_source(list, 'file.rb', ['def meth(a, b, c, d, e)',
12
+ 'end'])
13
+ list.offences.map(&:message).should ==
14
+ ['Avoid parameter lists longer than four parameters.']
15
+ end
16
+
17
+ it 'accepts a method def with 4 parameters' do
18
+ inspect_source(list, 'file.rb', ['def meth(a, b, c, d)',
19
+ 'end'])
20
+ list.offences.map(&:message).should == []
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,32 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ module Rubocop
6
+ module Cop
7
+ describe StringLiterals do
8
+ let (:sl) { StringLiterals.new }
9
+
10
+ it 'registers an offence for double quotes when single quotes suffice' do
11
+ inspect_source(sl, 'file.rb', ['s = "abc"'])
12
+ sl.offences.map(&:message).should ==
13
+ ["Prefer single-quoted strings when you don't need string " +
14
+ 'interpolation or special symbols.']
15
+ end
16
+
17
+ it 'accepts double quotes when they are needed' do
18
+ src = ['a = "\n"',
19
+ 'b = "#{encode_severity}:#{sprintf("%3d", line_number)}: #{m}"',
20
+ 'c = "\'"']
21
+ inspect_source(sl, 'file.rb', src)
22
+ sl.offences.map(&:message).should == []
23
+ end
24
+
25
+ it 'can handle double quotes within embedded expression' do
26
+ src = ['"#{"A"}"']
27
+ inspect_source(sl, 'file.rb', src)
28
+ sl.offences.map(&:message).should == []
29
+ end
30
+ end
31
+ end
32
+ end
@@ -161,7 +161,7 @@ module Rubocop
161
161
  it 'registers an offences for exponent operator with spaces' do
162
162
  inspect_source(space, 'file.rb', ['x = a * b ** 2'])
163
163
  space.offences.map(&:message).should ==
164
- ["Space around operator ** detected."]
164
+ ['Space around operator ** detected.']
165
165
  end
166
166
 
167
167
  it 'accepts exponent operator without spaces' do
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ module Rubocop
6
+ module Cop
7
+ describe TernaryOperator do
8
+ let (:num) { TernaryOperator.new }
9
+
10
+ it 'registers an offence for a multiline ternary operator expression' do
11
+ inspect_source(num, 'file.rb', ['a = cond ?',
12
+ ' b : c'])
13
+ num.offences.map(&:message).should ==
14
+ ['Avoid multi-line ?: (the ternary operator); use if/unless ' +
15
+ 'instead.']
16
+ end
17
+
18
+ it 'accepts a single line ternary operator expression' do
19
+ inspect_source(num, 'file.rb', ['a = cond ? b : c'])
20
+ num.offences.map(&:message).should == []
21
+ end
22
+ end
23
+ end
24
+ end
@@ -17,7 +17,7 @@ module Rubocop
17
17
 
18
18
  s = StringIO.new
19
19
  emacs_style.display(s)
20
- s.string.should == ["test:1: C: message 1",
20
+ s.string.should == ['test:1: C: message 1',
21
21
  "test:11: F: message 2\n"].join("\n")
22
22
  end
23
23
  end
data/spec/spec_helper.rb CHANGED
@@ -23,7 +23,7 @@ module ExitCodeMatchers
23
23
  end
24
24
  failure_message_for_should do |block|
25
25
  "expected block to call exit(#{code}) but exit" +
26
- (actual.nil? ? " not called" : "(#{actual}) was called")
26
+ (actual.nil? ? ' not called' : "(#{actual}) was called")
27
27
  end
28
28
  failure_message_for_should_not do |block|
29
29
  "expected block not to call exit(#{code})"
@@ -39,6 +39,7 @@ RSpec.configure do |config|
39
39
  end
40
40
 
41
41
  def inspect_source(cop, file, source)
42
- tokens, sexp = Rubocop::CLI.rip_source(source)
42
+ tokens, sexp, correlations = Rubocop::CLI.rip_source(source)
43
+ cop.correlations = correlations
43
44
  cop.inspect(file, source, tokens, sexp)
44
45
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,16 +9,16 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-02 00:00:00.000000000 Z
12
+ date: 2013-01-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
- name: rspec
15
+ name: rake
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
20
20
  - !ruby/object:Gem::Version
21
- version: 2.8.0
21
+ version: 10.0.0
22
22
  type: :development
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
@@ -26,15 +26,15 @@ dependencies:
26
26
  requirements:
27
27
  - - ~>
28
28
  - !ruby/object:Gem::Version
29
- version: 2.8.0
29
+ version: 10.0.0
30
30
  - !ruby/object:Gem::Dependency
31
- name: yard
31
+ name: rspec
32
32
  requirement: !ruby/object:Gem::Requirement
33
33
  none: false
34
34
  requirements:
35
35
  - - ~>
36
36
  - !ruby/object:Gem::Version
37
- version: '0.7'
37
+ version: 2.12.0
38
38
  type: :development
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
@@ -42,39 +42,23 @@ dependencies:
42
42
  requirements:
43
43
  - - ~>
44
44
  - !ruby/object:Gem::Version
45
- version: '0.7'
45
+ version: 2.12.0
46
46
  - !ruby/object:Gem::Dependency
47
- name: redcarpet
48
- requirement: !ruby/object:Gem::Requirement
49
- none: false
50
- requirements:
51
- - - ! '>='
52
- - !ruby/object:Gem::Version
53
- version: '0'
54
- type: :development
55
- prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
- requirements:
59
- - - ! '>='
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- - !ruby/object:Gem::Dependency
63
- name: cucumber
47
+ name: yard
64
48
  requirement: !ruby/object:Gem::Requirement
65
49
  none: false
66
50
  requirements:
67
- - - ! '>='
51
+ - - ~>
68
52
  - !ruby/object:Gem::Version
69
- version: '0'
53
+ version: 0.8.0
70
54
  type: :development
71
55
  prerelease: false
72
56
  version_requirements: !ruby/object:Gem::Requirement
73
57
  none: false
74
58
  requirements:
75
- - - ! '>='
59
+ - - ~>
76
60
  - !ruby/object:Gem::Version
77
- version: '0'
61
+ version: 0.8.0
78
62
  - !ruby/object:Gem::Dependency
79
63
  name: bundler
80
64
  requirement: !ruby/object:Gem::Requirement
@@ -82,7 +66,7 @@ dependencies:
82
66
  requirements:
83
67
  - - ~>
84
68
  - !ruby/object:Gem::Version
85
- version: 1.1.0
69
+ version: 1.2.0
86
70
  type: :development
87
71
  prerelease: false
88
72
  version_requirements: !ruby/object:Gem::Requirement
@@ -90,7 +74,7 @@ dependencies:
90
74
  requirements:
91
75
  - - ~>
92
76
  - !ruby/object:Gem::Version
93
- version: 1.1.0
77
+ version: 1.2.0
94
78
  - !ruby/object:Gem::Dependency
95
79
  name: jeweler
96
80
  requirement: !ruby/object:Gem::Requirement
@@ -138,6 +122,7 @@ files:
138
122
  - .rspec
139
123
  - .rvmrc
140
124
  - .travis.yml
125
+ - CONTRIBUTING.md
141
126
  - Gemfile
142
127
  - Gemfile.lock
143
128
  - LICENSE.txt
@@ -151,6 +136,7 @@ files:
151
136
  - lib/rubocop.rb
152
137
  - lib/rubocop/cli.rb
153
138
  - lib/rubocop/cop/align_parameters.rb
139
+ - lib/rubocop/cop/blocks.rb
154
140
  - lib/rubocop/cop/cop.rb
155
141
  - lib/rubocop/cop/def_parentheses.rb
156
142
  - lib/rubocop/cop/empty_lines.rb
@@ -163,9 +149,12 @@ files:
163
149
  - lib/rubocop/cop/line_length.rb
164
150
  - lib/rubocop/cop/numeric_literals.rb
165
151
  - lib/rubocop/cop/offence.rb
152
+ - lib/rubocop/cop/parameter_lists.rb
166
153
  - lib/rubocop/cop/space_after_comma_etc.rb
154
+ - lib/rubocop/cop/string_literals.rb
167
155
  - lib/rubocop/cop/surrounding_space.rb
168
156
  - lib/rubocop/cop/tab.rb
157
+ - lib/rubocop/cop/ternary_operator.rb
169
158
  - lib/rubocop/cop/trailing_whitespace.rb
170
159
  - lib/rubocop/report/emacs_style.rb
171
160
  - lib/rubocop/report/plain_text.rb
@@ -174,6 +163,7 @@ files:
174
163
  - rubocop.gemspec
175
164
  - spec/rubocop/cli_spec.rb
176
165
  - spec/rubocop/cops/align_parameters_spec.rb
166
+ - spec/rubocop/cops/blocks_spec.rb
177
167
  - spec/rubocop/cops/cop_spec.rb
178
168
  - spec/rubocop/cops/def_parentheses_spec.rb
179
169
  - spec/rubocop/cops/empty_lines_spec.rb
@@ -185,9 +175,12 @@ files:
185
175
  - spec/rubocop/cops/line_length_spec.rb
186
176
  - spec/rubocop/cops/numeric_literals_spec.rb
187
177
  - spec/rubocop/cops/offence_spec.rb
178
+ - spec/rubocop/cops/parameter_lists_spec.rb
188
179
  - spec/rubocop/cops/space_after_comma_etc_spec.rb
180
+ - spec/rubocop/cops/string_literals_spec.rb
189
181
  - spec/rubocop/cops/surrounding_space_spec.rb
190
182
  - spec/rubocop/cops/tab_spec.rb
183
+ - spec/rubocop/cops/ternary_operator_spec.rb
191
184
  - spec/rubocop/cops/trailing_whitespace_spec.rb
192
185
  - spec/rubocop/reports/emacs_style_spec.rb
193
186
  - spec/rubocop/reports/report_spec.rb
@@ -207,7 +200,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
207
200
  version: '0'
208
201
  segments:
209
202
  - 0
210
- hash: -2416637958385031259
203
+ hash: 3978981872359853745
211
204
  required_rubygems_version: !ruby/object:Gem::Requirement
212
205
  none: false
213
206
  requirements: