codeqa 0.3.1 → 0.4.0.pre

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8c09b3131b75904946b9e3e24a598b59ab86d40b
4
- data.tar.gz: 19994d97490645b0fd3badda12d8e9cafd70f50d
3
+ metadata.gz: 3ae0299a503f1cb9639e037907ade194edfe3db0
4
+ data.tar.gz: 859128b8f52f560cc2dedb79157134237179b042
5
5
  SHA512:
6
- metadata.gz: 809b78c163111c868e33489ca63044cf3da990bb1f84eed7a3add12fe40869d15e8768923896fd3dad1701b13e23e372b1e4cc9ca9b2aa842b90dff774cba2ea
7
- data.tar.gz: da7709431d55c0b3244f81b9034d619e7906dcc110bcf3082ac7cca7db80137d4ae74b0433aa9c00f84ff93b0a760042737fac1f8f676d33681755bbb6f2e6dc
6
+ metadata.gz: 198df6738b57d3fbfb076bd3522b7b715b10245ce40769bbfb6b67e3e4af07df622504edc2d867d98cf8fc713582cbf95aa63de01c9a69e914e78c7d6d00c991
7
+ data.tar.gz: ec6c8833e4b66ba642b0ee30016f2c7d5d7e477f64cc59f69c5d6c49202c41667496e998631687e2ae863fa95f8f9c37a3cbbe0bfab81370ff2ceddecb5dc626
data/Gemfile CHANGED
@@ -4,7 +4,6 @@ source 'https://rubygems.org'
4
4
  gemspec
5
5
 
6
6
  group :development do
7
- gem 'rubocop'
8
7
  gem 'guard-rspec'
9
8
  gem 'guard-rubocop'
10
9
  gem 'rb-inotify', :require => false
@@ -12,6 +11,12 @@ group :development do
12
11
  # gem 'rb-fchange', :require => false #windows only
13
12
  end
14
13
 
14
+ group :development, :test do
15
+ gem 'pry-byebug'
16
+ gem 'nokogiri'
17
+ gem 'rubocop'
18
+ end
19
+
15
20
  group :test do
16
21
  gem 'simplecov', :require => false
17
22
  gem 'coveralls', :require => false
data/Guardfile CHANGED
@@ -9,9 +9,8 @@ group :red_green_refactor, halt_on_fail: true do
9
9
  watch(%r{^spec/.+_spec\.rb$})
10
10
  watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
11
11
  watch('spec/spec_helper.rb') { 'spec' }
12
- watch('spec/factories.rb') { 'spec' }
13
- watch('spec/support/jobs.json') { 'spec' }
14
- watch(%r{^spec/factories/(.+)\.rb}) { 'spec' }
12
+ watch(%r{^spec/support/(.+)\.rb}) { 'spec' }
13
+ watch(%r{^spec/fixtures/(.+)}) { 'spec' }
15
14
  end
16
15
 
17
16
  guard :rubocop, cli: %w(--display-cop-names --auto-correct) do
@@ -64,7 +64,6 @@ end
64
64
  require 'codeqa/version'
65
65
  require 'codeqa/sourcefile'
66
66
  require 'codeqa/checker'
67
- require 'codeqa/check_errors'
68
67
  require 'codeqa/runner'
69
68
  require 'codeqa/runner_decorator'
70
69
 
@@ -1,6 +1,7 @@
1
1
  require 'stringio'
2
2
  require 'tempfile'
3
3
  require 'forwardable'
4
+ require 'codeqa/utils/check_errors'
4
5
 
5
6
  module Codeqa
6
7
  class Checker
@@ -33,15 +34,5 @@ module Codeqa
33
34
  end
34
35
  end
35
36
  end
36
-
37
- def capture
38
- $stdout, stdout = StringIO.new, $stdout
39
- $stderr, stderr = StringIO.new, $stderr
40
- result = yield
41
- [result, $stdout.string + $stderr.string]
42
- ensure
43
- $stdout = stdout
44
- $stderr = stderr
45
- end
46
37
  end
47
38
  end
@@ -24,10 +24,10 @@ module Codeqa
24
24
  else
25
25
  ERB.new(sourcefile.content.gsub('<%=', '<%'), nil, '-').result
26
26
  end
27
- rescue SyntaxError
27
+ rescue SyntaxError => e
28
28
  errors.add(nil, <<-EOF)
29
- #{$!.message}
30
- #{$!.backtrace.join("\n")}
29
+ #{e.message}
30
+ #{e.backtrace.join("\n")}
31
31
  EOF
32
32
  rescue Exception
33
33
  true # valid syntax - just the proper setup for the template/rendering is missing
@@ -1,4 +1,4 @@
1
- require 'codeqa/fake_erb'
1
+ require 'codeqa/utils/erb_sanitizer'
2
2
  require 'open3'
3
3
  module Codeqa
4
4
  module Checkers
@@ -25,13 +25,13 @@ module Codeqa
25
25
  end # Tempfile
26
26
 
27
27
  return unless result
28
- errors.add(nil, html)
28
+ errors.add(:source, html)
29
29
  errors.add(nil, result)
30
30
  end
31
31
 
32
32
  def html
33
33
  @html ||= begin
34
- html = FakeERB.new(sourcefile.content.gsub('<%=', '<%')).result
34
+ html = ErbSanitizer.new(sourcefile.content).result
35
35
  html = html.force_encoding('UTF-8') if html.respond_to?(:force_encoding)
36
36
  html.gsub(%r{<script[ >].*?</script>|<style[ >].*?</style>}m,
37
37
  '<!--removed script/style tag-->')
@@ -0,0 +1,52 @@
1
+ require 'codeqa/utils/erb_sanitizer'
2
+
3
+ module Codeqa
4
+ module Checkers
5
+ class HtmlValidator < Checker
6
+ def self.check?(sourcefile)
7
+ sourcefile.html?
8
+ end
9
+
10
+ def self.available?
11
+ nokogiri?
12
+ end
13
+
14
+ def name
15
+ 'html'
16
+ end
17
+
18
+ def hint
19
+ 'Nokogiri found XHTML errors, please fix them.'
20
+ end
21
+
22
+ REMOVED_NOKOGIRI_ERRORS = Regexp.union(
23
+ /Opening and ending tag mismatch: (special line 1|\w+ line 1 and special)/,
24
+ /Premature end of data in tag special/,
25
+ /Extra content at the end of the document/,
26
+ /xmlParseEntityRef: no name/
27
+ )
28
+ def check
29
+ return unless self.class.nokogiri?
30
+ doc = Nokogiri::XML "<special>#{stripped_html}</special>"
31
+
32
+ doc.errors.delete_if{ |e| e.message =~ REMOVED_NOKOGIRI_ERRORS }
33
+ errors.add(:source, sourcefile.content) unless doc.errors.empty?
34
+ # errors.add(:source, stripped_html) unless doc.errors.empty?
35
+ doc.errors.each do |error|
36
+ errors.add(error.line, error.message) unless error.warning?
37
+ end
38
+ end
39
+
40
+ def stripped_html
41
+ @html ||= ErbSanitizer.new(sourcefile.content).result
42
+ end
43
+
44
+ def self.nokogiri?
45
+ @loaded ||= begin
46
+ require 'nokogiri'
47
+ true
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -4,7 +4,7 @@ module Codeqa
4
4
  def check
5
5
  sourcefile.content.lines.each.with_index do |line, line_number|
6
6
  pos = (line =~ pattern)
7
- errors.add("#{line_number + 1},#{pos + 1}", error_msg(line, line_number + 1, pos)) if pos
7
+ errors.add([line_number + 1, pos + 1], error_msg(line, line_number + 1, pos)) if pos
8
8
  end
9
9
  end
10
10
 
@@ -1,3 +1,5 @@
1
+ require 'ostruct'
2
+
1
3
  module Codeqa
2
4
  module Checkers
3
5
  class Rubocop < Checker
@@ -21,14 +23,14 @@ module Codeqa
21
23
  return unless self.class.rubocop?
22
24
  with_existing_file do |filename|
23
25
  args = config_args << filename
24
- success, captured = capture do
26
+ success, raw_json = capture do
25
27
  if defined?(RuboCop) # its RuboCop since 0.24
26
28
  ::RuboCop::CLI.new.run(default_args + args) == 0
27
29
  else
28
30
  ::Rubocop::CLI.new.run(default_args + args) == 0
29
31
  end
30
32
  end
31
- errors.add(nil, captured) unless success
33
+ handle_rubocop_results(raw_json) unless success
32
34
  end
33
35
  end
34
36
 
@@ -39,15 +41,39 @@ module Codeqa
39
41
  end
40
42
 
41
43
  def default_args
42
- %w(--display-cop-names --format emacs)
44
+ %w(--format json)
43
45
  end
44
46
 
47
+ def handle_rubocop_results(raw)
48
+ data = JSON.parse raw, :object_class => OpenStruct
49
+ data.files.
50
+ reject{ |f| f.offenses.empty? }.
51
+ each do |file|
52
+ file.offenses.each do |offense|
53
+ position = [offense.location.line, offense.location.column]
54
+ errors.add(position, "#{offense.cop_name}: #{offense.message}")
55
+ end
56
+ end
57
+ end
45
58
  def self.rubocop?
46
59
  @loaded ||= begin
47
60
  require 'rubocop'
48
61
  true
49
62
  end
50
63
  end
64
+
65
+ # Since using the json format we only care about stdout
66
+ # stderr will be silent
67
+ def capture
68
+ $stdout, stdout = StringIO.new, $stdout
69
+ $stderr, stderr = StringIO.new, $stderr
70
+ result = yield
71
+ # [result, $stdout.string + $stderr.string]
72
+ [result, $stdout.string]
73
+ ensure
74
+ $stdout = stdout
75
+ $stderr = stderr
76
+ end
51
77
  end
52
78
  end
53
79
  end
@@ -32,13 +32,26 @@ module Codeqa
32
32
 
33
33
  private
34
34
 
35
+ # TODO: move this error formating into check error class
35
36
  def error_details
36
37
  msg = ''
37
38
  @runner.failures.each do |checker|
38
- msg << error("------- #{checker.name} -------\n")
39
- msg << error("#{checker.hint}\n")
40
- checker.errors.details.each do |detail|
41
- msg << info("#{detail[1]}\n")
39
+ msg << error("------- #{checker.name} -------") << "\n"
40
+ msg << error("#{checker.hint}") << "\n"
41
+ checker.errors.details.each do |type, content|
42
+ case type
43
+ when :source
44
+ content.each_line.with_index do |l, i|
45
+ msg << yellow((i + 1).to_s.rjust(3)) << '|' << l
46
+ end
47
+ when Integer
48
+ msg << info('Line: ') << yellow(type) << '|' << info(content)
49
+ when Array
50
+ msg << info('Pos: ') << yellow(type.join(',')) << '|' << info(content)
51
+ when nil
52
+ msg << info(content)
53
+ end
54
+ msg << "\n"
42
55
  end
43
56
  end
44
57
  msg
@@ -73,9 +86,9 @@ module Codeqa
73
86
  colorize(32, txt)
74
87
  end
75
88
 
76
- # def yellow(txt)
77
- # colorize(33, txt)
78
- # end
89
+ def yellow(txt)
90
+ colorize(33, txt)
91
+ end
79
92
 
80
93
  # def pink(txt)
81
94
  # colorize(35, txt)
@@ -0,0 +1,85 @@
1
+ require 'erb'
2
+ # Based on ERB source from ruby 2.1.2
3
+ # https://github.com/ruby/ruby/blob/v2_1_2/lib/erb.rb#L597
4
+ module Codeqa
5
+ class ErbSanitizer < ERB
6
+ def make_compiler(trim_mode)
7
+ ErbSanitizer::Compiler.new(trim_mode)
8
+ end
9
+
10
+ class Compiler < ERB::Compiler
11
+ # Compiles an ERB template into Ruby code. Returns an array of the code
12
+ # and encoding like ["code", Encoding].
13
+ # rubocop:disable Style/CyclomaticComplexity
14
+ def compile(s)
15
+ enc = s.encoding
16
+ raise ArgumentError, "#{enc} is not ASCII compatible" if enc.dummy?
17
+ s = s.b # see String#b
18
+ enc = detect_magic_comment(s) || enc
19
+ out = Buffer.new(self, enc)
20
+
21
+ content = ''
22
+ scanner = make_scanner(s)
23
+ scanner.scan do |token|
24
+ next if token.nil?
25
+ next if token == ''
26
+ if scanner.stag.nil?
27
+ case token
28
+ when PercentLine
29
+ add_put_cmd(out, content) if content.size > 0
30
+ content = ''
31
+ out.push(token.to_s)
32
+ out.cr
33
+ when :cr
34
+ out.cr
35
+ when '<%', '<%=', '<%#'
36
+ scanner.stag = token
37
+ add_put_cmd(out, content) if content.size > 0
38
+ content = ''
39
+ when "\n"
40
+ content << "\n"
41
+ add_put_cmd(out, content)
42
+ content = ''
43
+ when '<%%'
44
+ content << '<%'
45
+ else
46
+ content << token
47
+ end
48
+ else
49
+ case token
50
+ when '%>'
51
+ # in here we deal with the content of a erb tag
52
+ (content.scan("\n").count).times do
53
+ add_put_cmd(out, "\n")
54
+ end
55
+ # case scanner.stag
56
+ # when '<%'
57
+ # if content[-1] == ?\n
58
+ # content.chop!
59
+ # out.push(content)
60
+ # out.cr
61
+ # else
62
+ # out.push(content)
63
+ # end
64
+ # when '<%='
65
+ # add_insert_cmd(out, content)
66
+ # when '<%#'
67
+ # # out.push("# #{content_dump(content)}")
68
+ # end
69
+ scanner.stag = nil
70
+ content = ''
71
+ when '%%>'
72
+ content << '%>'
73
+ else
74
+ content << token
75
+ end
76
+ end
77
+ end
78
+ add_put_cmd(out, content) if content.size > 0
79
+ out.close
80
+ [out.script, enc]
81
+ end
82
+ # rubocop:enable Style/CyclomaticComplexity
83
+ end
84
+ end
85
+ end
@@ -1,3 +1,3 @@
1
1
  module Codeqa
2
- VERSION = '0.3.1'
2
+ VERSION = '0.4.0.pre'
3
3
  end
@@ -38,13 +38,11 @@ print "Codeqa checking #{files_to_check.count} files"
38
38
  # fail fast
39
39
  success = files_to_check.all? do |file|
40
40
  print '.'
41
- Codeqa.check(file, :silent => true)
41
+ Codeqa.check(file, :silent_success => true)
42
42
  end
43
43
 
44
44
  if success
45
- puts 'success'
46
45
  exit 0
47
46
  else
48
- puts 'error'
49
47
  exit 1
50
48
  end
@@ -0,0 +1,31 @@
1
+ <body>
2
+ <div class="jobdetail">
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+
13
+
14
+
15
+ <iframe src="" scrolling="no">
16
+ </iframe>
17
+
18
+ </div>
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
27
+
28
+ <script>
29
+ ujsOpenDialog('.ujsDialog');
30
+ </script>
31
+ </body>
@@ -0,0 +1,31 @@
1
+ <body>
2
+ <div class="jobdetail">
3
+ <%= render :partial => 'header',
4
+ :locals => @header_options.reverse_merge(
5
+ :position_presenter => @position_presenter,
6
+ :bookmark => @bookmark,
7
+ :account_id => @account.id,
8
+ :social_share => @social_share) if @position_presenter.show_header? %>
9
+ <% if @position_presenter.internal_view? %>
10
+ <%= render :partial => 'intern',
11
+ :locals => @header_options.reverse_merge(
12
+ :position_presenter => @position_presenter,
13
+ :account_id => @account.id) %>
14
+ <% else %>
15
+ <iframe src="<%= raw @position_presenter.url %>" scrolling="no">
16
+ </iframe>
17
+ <% end %>
18
+ </div>
19
+
20
+ <%#
21
+ params:
22
+ @header_options
23
+ @account_id
24
+ @bookmark
25
+ @position
26
+ @position_presenter
27
+ %>
28
+ <script>
29
+ ujsOpenDialog('.ujsDialog');
30
+ </script>
31
+ </body>
@@ -15,9 +15,9 @@ describe Codeqa::Checkers::CheckConflict do
15
15
  checker = check_with(described_class, source)
16
16
  expect(checker).to be_error
17
17
  expect(checker.errors.details).to eq([
18
- ['2,1', 'conflict leftovers in line 2, please merge properly'],
19
- ['3,1', 'conflict leftovers in line 3, please merge properly'],
20
- ['5,1', 'conflict leftovers in line 5, please merge properly']
18
+ [[2, 1], 'conflict leftovers in line 2, please merge properly'],
19
+ [[3, 1], 'conflict leftovers in line 3, please merge properly'],
20
+ [[5, 1], 'conflict leftovers in line 5, please merge properly']
21
21
  ])
22
22
  end
23
23
 
@@ -21,7 +21,7 @@ unless ENV['TRAVIS']
21
21
  checker = check_with(described_class, source)
22
22
  expect(checker).to be_error
23
23
  expect(checker.errors.details).to eq([
24
- [nil, '<div><ul></div>'],
24
+ [:source, '<div><ul></div>'],
25
25
  [nil, "line 1 column 10 - Error: unexpected </div> in <ul>\n"]])
26
26
  end
27
27
 
@@ -30,7 +30,7 @@ unless ENV['TRAVIS']
30
30
  checker = check_with(described_class, source)
31
31
  expect(checker).to be_error
32
32
  expect(checker.errors.details).to eq([
33
- [nil, "<div class='halfopen></div>"],
33
+ [:source, "<div class='halfopen></div>"],
34
34
  [nil, "line 1 column 28 - Warning: <div> end of file while parsing attributes\n"]])
35
35
 
36
36
  end
@@ -39,7 +39,7 @@ unless ENV['TRAVIS']
39
39
  checker = check_with(described_class, source)
40
40
  expect(checker).to be_error
41
41
  expect(checker.errors.details).to eq([
42
- [nil, "<div class=\"halfopen next=\"ok\"></div>"],
42
+ [:source, "<div class=\"halfopen next=\"ok\"></div>"],
43
43
  [nil, "line 1 column 1 - Warning: <div> attribute with missing trailing quote mark\n"]])
44
44
 
45
45
  end
@@ -14,7 +14,9 @@ describe Codeqa::Checkers::CheckLinkto do
14
14
  source = source_with("<% link_to '/page',do_some_paths do%>", 'file.html.erb')
15
15
  checker = check_with(described_class, source)
16
16
  expect(checker).to be_error
17
- expect(checker.errors.details).to eq([['1,1', 'old style block link_to in line 1']])
17
+ expect(checker.errors.details).to eq([
18
+ [[1, 1], 'old style block link_to in line 1']
19
+ ])
18
20
  end
19
21
 
20
22
  it 'should find not find if not there ' do
@@ -14,14 +14,18 @@ describe Codeqa::Checkers::CheckStrangeChars do
14
14
  source = source_with("one\x09two")
15
15
  checker = check_with(described_class, source)
16
16
  expect(checker).to be_error
17
- expect(checker.errors.details).to eq([['1,4', 'TAB x09 at line 1 column 4']])
17
+ expect(checker.errors.details).to eq([
18
+ [[1, 4], 'TAB x09 at line 1 column 4']
19
+ ])
18
20
  end
19
21
 
20
22
  it 'should detect form feeds' do
21
23
  source = source_with("one\n\x0ctwo")
22
24
  checker = check_with(described_class, source)
23
25
  expect(checker).to be_error
24
- expect(checker.errors.details).to eq([['2,1', 'FORM FEED x0C at line 2 column 1']])
26
+ expect(checker.errors.details).to eq([
27
+ [[2, 1], 'FORM FEED x0C at line 2 column 1']
28
+ ])
25
29
  end
26
30
 
27
31
  end
@@ -0,0 +1,78 @@
1
+ require 'spec_helper'
2
+ describe Codeqa::Checkers::HtmlValidator do
3
+ it_behaves_like 'a checker'
4
+
5
+ it 'should check erb files' do
6
+ source = source_with('', 'file.html.erb')
7
+ expect(described_class.check?(source)).to be_truthy
8
+ source = source_with('', 'test.rhtml')
9
+ expect(described_class.check?(source)).to be_truthy
10
+ source = source_with('', 'test.text.html')
11
+ expect(described_class.check?(source)).to be_truthy
12
+
13
+ source = source_with('', 'zipped.zip')
14
+ expect(described_class.check?(source)).to be_falsey
15
+ end
16
+
17
+ it 'should detect html tag errors' do
18
+ text = '<div><ul></div>'
19
+ source = source_with(text)
20
+ checker = check_with(described_class, source)
21
+ expect(checker).to be_error
22
+ expect(checker.errors.details).to eq([
23
+ [:source, text],
24
+ [1, 'Opening and ending tag mismatch: ul line 1 and div']
25
+ ])
26
+ end
27
+
28
+ it 'should detect attribute till end of file errors' do
29
+ text = "<div class='halfopen></div>"
30
+ source = source_with(text)
31
+ checker = check_with(described_class, source)
32
+ expect(checker).to be_error
33
+ expect(checker.errors.details).to eq([
34
+ [:source, text],
35
+ [1, "Unescaped '<' not allowed in attributes values"],
36
+ [1, 'attributes construct error'],
37
+ [1, "Couldn't find end of Start Tag div line 1"]
38
+ ])
39
+ end
40
+ it 'should detect attribute with missing trailing qute mark' do
41
+ text = '<div class="halfopen next="ok"></div>'
42
+ source = source_with(text)
43
+ checker = check_with(described_class, source)
44
+ expect(checker).to be_error
45
+ expect(checker.errors.details).to eq([
46
+ [:source, text],
47
+ [1, 'attributes construct error'],
48
+ [1, "Couldn't find end of Start Tag div line 1"]
49
+ ])
50
+ end
51
+
52
+ it 'should find not find errors if html is ok ' do
53
+ source = source_with('<div><ul></ul></div>')
54
+ checker = check_with(described_class, source)
55
+ expect(checker).to be_success
56
+ end
57
+
58
+ # context 'javascript' do
59
+ # it 'should ignore javascript' do
60
+ # source = source_with('<div><script></ul></script></div>')
61
+ # checker = check_with(described_class, source)
62
+ # expect(checker).to be_success
63
+ # end
64
+ # it 'should ignore javascript' do
65
+ # source = source_with('<div><script type="text/javascript" charset="utf-8"></ul></script></div>')
66
+ # checker = check_with(described_class, source)
67
+ # expect(checker).to be_success
68
+ # source = source_with("<div><script>multiline\n</ul></script></div>")
69
+ # checker = check_with(described_class, source)
70
+ # expect(checker).to be_success
71
+ # end
72
+ # it 'should ignore javascript' do
73
+ # source = source_with('<div><style></ul></style></div>')
74
+ # checker = check_with(described_class, source)
75
+ # expect(checker).to be_success
76
+ # end
77
+ # end
78
+ end
@@ -14,7 +14,7 @@ describe Codeqa::Checkers::RubocopLint do
14
14
  source = source_with('class MyClass')
15
15
  checker = check_with(described_class, source)
16
16
  expect(checker).to be_error
17
- expect(checker.errors.details.first[1]).to match(/unexpected token/)
17
+ expect(checker.errors.details.first).to eq([[1, 14], 'Syntax: unexpected token $end'])
18
18
  end
19
19
 
20
20
  it 'should find not find if not there ' do
@@ -1,19 +1,78 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Codeqa::RunnerDecorator do
4
- it 'should run provide the errors if the checker failed' do
5
- source = source_with('def syntax_error', 'ruby.rb')
6
- runner = Codeqa::Runner.run(source)
7
- expect(runner.success?).to be false
8
- decorator = Codeqa::RunnerDecorator.new(runner)
9
- expect(decorator.to_s).to match(/syntax/)
4
+ let(:errors){ Codeqa::CheckErrors.new }
5
+ let(:decorator) do
6
+ checker = double(Codeqa::Checker, :errors => errors,
7
+ :name => 'test',
8
+ :hint => 'testtest')
9
+ runner = double(Codeqa::Runner, :failures => [checker],
10
+ :sourcefile => Codeqa::Sourcefile.new('foo.rb', 'foo'),
11
+ :success? => false)
12
+ Codeqa::RunnerDecorator.new(runner)
10
13
  end
11
- it 'should run list the ran checkers' do
12
- source = source_with('def foo; end', 'ruby.rb')
13
- runner = Codeqa::Runner.run(source)
14
- expect(runner.success?).to be true
15
- decorator = Codeqa::RunnerDecorator.new(runner)
16
- expect(decorator.to_s).to match(/Passed tests.+strange chars/)
14
+
15
+ it 'should format error as line if number given' do
16
+ errors.add(77, 'test message')
17
+ expect(decorator.details_to_s).to eq(<<-EOF)
18
+ \e[31m------- test -------\e[0m
19
+ \e[31mtesttest\e[0m
20
+ Line: \e[33m77\e[0m|test message
21
+ EOF
22
+ end
23
+
24
+ it 'should format error as position if array given' do
25
+ errors.add([22, 77], 'test message')
26
+ expect(decorator.details_to_s).to eq(<<-EOF)
27
+ \e[31m------- test -------\e[0m
28
+ \e[31mtesttest\e[0m
29
+ Pos: \e[33m22,77\e[0m|test message
30
+ EOF
31
+ end
32
+
33
+ it 'should simply print error content if no context is given' do
34
+ errors.add(nil, 'test message')
35
+ expect(decorator.details_to_s).to eq(<<-EOF)
36
+ \e[31m------- test -------\e[0m
37
+ \e[31mtesttest\e[0m
38
+ test message
39
+ EOF
40
+ end
41
+
42
+ it 'should format error as source if :source token given' do
43
+ errors.add(:source, 'test message')
44
+ expect(decorator.details_to_s).to eq(<<-EOF)
45
+ \e[31m------- test -------\e[0m
46
+ \e[31mtesttest\e[0m
47
+ \e[33m 1\e[0m|test message
48
+ EOF
49
+ end
50
+
51
+ it 'should correctly format multiline source' do
52
+ errors.add(:source, "test message\nline two\nthird\n\nfifth")
53
+ expect(decorator.details_to_s).to eq(<<-EOF)
54
+ \e[31m------- test -------\e[0m
55
+ \e[31mtesttest\e[0m
56
+ \e[33m 1\e[0m|test message
57
+ \e[33m 2\e[0m|line two
58
+ \e[33m 3\e[0m|third
59
+ \e[33m 4\e[0m|
60
+ \e[33m 5\e[0m|fifth
61
+ EOF
17
62
  end
63
+ # it 'should run provide the errors if the checker failed' do
64
+ # source = source_with('def syntax_error', 'ruby.rb')
65
+ # runner = Codeqa::Runner.run(source)
66
+ # expect(runner.success?).to be false
67
+ # decorator = Codeqa::RunnerDecorator.new(runner)
68
+ # expect(decorator.to_s).to match(/syntax/)
69
+ # end
70
+ # it 'should run list the ran checkers' do
71
+ # source = source_with('def foo; end', 'ruby.rb')
72
+ # runner = Codeqa::Runner.run(source)
73
+ # expect(runner.success?).to be true
74
+ # decorator = Codeqa::RunnerDecorator.new(runner)
75
+ # expect(decorator.to_s).to match(/Passed tests.+strange chars/)
76
+ # end
18
77
 
19
78
  end
@@ -0,0 +1,58 @@
1
+ require 'spec_helper'
2
+
3
+ describe Codeqa::ErbSanitizer do
4
+ context 'erb' do
5
+ # let(:source) do
6
+ # source_with(
7
+ # IO.read(
8
+ # Codeqa.root.join('spec', 'fixtures', 'erb_example.html.erb')
9
+ # )
10
+ # )
11
+ # end
12
+ def compile(content)
13
+ described_class.new(content).result
14
+ end
15
+
16
+ it 'should remove erb tags' do
17
+ source = '<div><% some ruby %></div>'
18
+ expected = '<div></div>'
19
+ doc = compile(source)
20
+ expect(doc).to eq(expected)
21
+ expect(Nokogiri::XML(doc).errors).to be_empty
22
+ end
23
+ it 'should remove erb tags within attributes' do
24
+ source = '<div <%dont touch this%> baz="bla <%=inside%> <%=inside2%> stuff" after="meh"></div>'
25
+ expected = '<div baz="bla stuff" after="meh"></div>'
26
+ doc = compile(source)
27
+ expect(doc).to eq(expected)
28
+ expect(Nokogiri::XML(doc).errors).to be_empty
29
+ end
30
+ it 'should properly remove multiline erb tags and keep the correct line numbers' do
31
+ source = <<-EOR
32
+ <div>
33
+ <% render :partial => :foo, :locals => { :foo => 'foo',
34
+ :bar => 'bar'
35
+ :baz => 'baz' }%>
36
+ </div>
37
+ EOR
38
+ expected = <<-EOR
39
+ <div>
40
+
41
+
42
+
43
+ </div>
44
+ EOR
45
+ doc = compile(source)
46
+ expect(doc).to eq(expected)
47
+ expect(Nokogiri::XML(doc).errors).to be_empty
48
+ end
49
+
50
+ it 'should work on a more difficult example' do
51
+ source = IO.read(Codeqa.root.join('spec', 'fixtures', 'erb_example.html.erb'))
52
+ expected = IO.read(Codeqa.root.join('spec', 'fixtures', 'erb_example.html'))
53
+ doc = compile(source)
54
+ expect(doc).to eq(expected)
55
+ expect(Nokogiri::XML(doc).errors).to be_empty
56
+ end
57
+ end
58
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: codeqa
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0.pre
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Schrammel
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-08-20 00:00:00.000000000 Z
12
+ date: 2014-08-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -79,7 +79,6 @@ files:
79
79
  - codeqa.gemspec
80
80
  - config/default.rb
81
81
  - lib/codeqa.rb
82
- - lib/codeqa/check_errors.rb
83
82
  - lib/codeqa/checker.rb
84
83
  - lib/codeqa/checkers/check_conflict.rb
85
84
  - lib/codeqa/checkers/check_erb.rb
@@ -91,17 +90,21 @@ files:
91
90
  - lib/codeqa/checkers/check_strange_chars.rb
92
91
  - lib/codeqa/checkers/check_utf8_encoding.rb
93
92
  - lib/codeqa/checkers/check_yard.rb
93
+ - lib/codeqa/checkers/html_validator.rb
94
94
  - lib/codeqa/checkers/pattern_checker.rb
95
95
  - lib/codeqa/checkers/rubocop_formatter.rb
96
96
  - lib/codeqa/checkers/rubocop_full.rb
97
97
  - lib/codeqa/checkers/rubocop_lint.rb
98
98
  - lib/codeqa/configuration.rb
99
- - lib/codeqa/fake_erb.rb
100
99
  - lib/codeqa/runner.rb
101
100
  - lib/codeqa/runner_decorator.rb
102
101
  - lib/codeqa/sourcefile.rb
102
+ - lib/codeqa/utils/check_errors.rb
103
+ - lib/codeqa/utils/erb_sanitizer.rb
103
104
  - lib/codeqa/version.rb
104
105
  - lib/templates/pre-commit
106
+ - spec/fixtures/erb_example.html
107
+ - spec/fixtures/erb_example.html.erb
105
108
  - spec/fixtures/html_error.html.erb
106
109
  - spec/fixtures/html_error.text.html
107
110
  - spec/fixtures/isolation/home/project/dir/.gitkeep
@@ -119,6 +122,7 @@ files:
119
122
  - spec/lib/codeqa/checkers/check_strange_chars_spec.rb
120
123
  - spec/lib/codeqa/checkers/check_utf8_encoding_spec.rb
121
124
  - spec/lib/codeqa/checkers/check_yard_spec.rb
125
+ - spec/lib/codeqa/checkers/html_validator_spec.rb
122
126
  - spec/lib/codeqa/checkers/rubocop_formatter_spec.rb
123
127
  - spec/lib/codeqa/checkers/rubocop_full_spec.rb
124
128
  - spec/lib/codeqa/checkers/rubocop_lint_spec.rb
@@ -126,6 +130,7 @@ files:
126
130
  - spec/lib/codeqa/runner_decorator_spec.rb
127
131
  - spec/lib/codeqa/runner_spec.rb
128
132
  - spec/lib/codeqa/sourcefile_spec.rb
133
+ - spec/lib/codeqa/utils/erb_sanitizer_spec.rb
129
134
  - spec/lib/codeqa_spec.rb
130
135
  - spec/spec_helper.rb
131
136
  - spec/support/checker.rb
@@ -144,9 +149,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
144
149
  version: '2.0'
145
150
  required_rubygems_version: !ruby/object:Gem::Requirement
146
151
  requirements:
147
- - - ">="
152
+ - - ">"
148
153
  - !ruby/object:Gem::Version
149
- version: '0'
154
+ version: 1.3.1
150
155
  requirements: []
151
156
  rubyforge_project:
152
157
  rubygems_version: 2.2.2
@@ -154,6 +159,8 @@ signing_key:
154
159
  specification_version: 4
155
160
  summary: Code checker
156
161
  test_files:
162
+ - spec/fixtures/erb_example.html
163
+ - spec/fixtures/erb_example.html.erb
157
164
  - spec/fixtures/html_error.html.erb
158
165
  - spec/fixtures/html_error.text.html
159
166
  - spec/fixtures/isolation/home/project/dir/.gitkeep
@@ -171,6 +178,7 @@ test_files:
171
178
  - spec/lib/codeqa/checkers/check_strange_chars_spec.rb
172
179
  - spec/lib/codeqa/checkers/check_utf8_encoding_spec.rb
173
180
  - spec/lib/codeqa/checkers/check_yard_spec.rb
181
+ - spec/lib/codeqa/checkers/html_validator_spec.rb
174
182
  - spec/lib/codeqa/checkers/rubocop_formatter_spec.rb
175
183
  - spec/lib/codeqa/checkers/rubocop_full_spec.rb
176
184
  - spec/lib/codeqa/checkers/rubocop_lint_spec.rb
@@ -178,6 +186,7 @@ test_files:
178
186
  - spec/lib/codeqa/runner_decorator_spec.rb
179
187
  - spec/lib/codeqa/runner_spec.rb
180
188
  - spec/lib/codeqa/sourcefile_spec.rb
189
+ - spec/lib/codeqa/utils/erb_sanitizer_spec.rb
181
190
  - spec/lib/codeqa_spec.rb
182
191
  - spec/spec_helper.rb
183
192
  - spec/support/checker.rb
@@ -1,80 +0,0 @@
1
- require 'erb'
2
- module Codeqa
3
- # copied from ERB
4
- # throws away all the erb stuff so only html remains
5
- # rubocop:disable MethodLength, LineLength, CyclomaticComplexity, BlockNesting
6
- class FakeERB < ERB
7
- def initialize(str, safe_level=nil, trim_mode=nil, eoutvar='_erbout', compiler_class=FakeERB::Compiler)
8
- @safe_level = safe_level
9
- compiler = compiler_class.new(trim_mode)
10
- set_eoutvar(compiler, eoutvar)
11
- @src = compiler.compile(str)
12
- @filename = nil
13
- end
14
-
15
- class Compiler < ERB::Compiler # :nodoc:
16
- def compile(s)
17
- out = Buffer.new(self)
18
-
19
- content = ''
20
- scanner = make_scanner(s)
21
- scanner.scan do |token|
22
- next if token.nil?
23
- next if token == ''
24
- if scanner.stag.nil?
25
- case token
26
- when PercentLine
27
- out.push("#{@put_cmd} #{content_dump(content)}") if content.size > 0
28
- content = ''
29
- out.push(token.to_s)
30
- out.cr
31
- when :cr
32
- out.cr
33
- when '<%', '<%=', '<%#'
34
- scanner.stag = token
35
- out.push("#{@put_cmd} #{content_dump(content)}") if content.size > 0
36
- content = ''
37
- when "\n"
38
- content << "\n"
39
- out.push("#{@put_cmd} #{content_dump(content)}")
40
- content = ''
41
- when '<%%'
42
- content << '<%'
43
- else
44
- content << token
45
- end
46
- else
47
- case token
48
- when '%>'
49
- case scanner.stag
50
- when '<%'
51
- if content[-1] == "\n"
52
- content.chop!
53
- # out.push(content)
54
- out.cr
55
- else
56
- # out.push(content)
57
- end
58
- when '<%='
59
- # out.push("#{@insert_cmd}((#{content}).to_s)")
60
- when '<%#'
61
- # out.push("# #{content_dump(content)}")
62
- end
63
- scanner.stag = nil
64
- content = ''
65
- when '%%>'
66
- content << '%>'
67
- else
68
- content << token
69
- end
70
- end
71
- end
72
- # puts "pushed2 #{content}"
73
- out.push("#{@put_cmd} #{content_dump(content)}") if content.size > 0
74
- out.close
75
- out.script
76
- end
77
- end
78
- end
79
- # rubocop:enable MethodLength, LineLength, CyclomaticComplexity, BlockNesting
80
- end