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 +4 -4
- data/Gemfile +6 -1
- data/Guardfile +2 -3
- data/lib/codeqa.rb +0 -1
- data/lib/codeqa/checker.rb +1 -10
- data/lib/codeqa/checkers/check_erb.rb +3 -3
- data/lib/codeqa/checkers/check_erb_html.rb +3 -3
- data/lib/codeqa/checkers/html_validator.rb +52 -0
- data/lib/codeqa/checkers/pattern_checker.rb +1 -1
- data/lib/codeqa/checkers/rubocop_full.rb +29 -3
- data/lib/codeqa/runner_decorator.rb +20 -7
- data/lib/codeqa/{check_errors.rb → utils/check_errors.rb} +0 -0
- data/lib/codeqa/utils/erb_sanitizer.rb +85 -0
- data/lib/codeqa/version.rb +1 -1
- data/lib/templates/pre-commit +1 -3
- data/spec/fixtures/erb_example.html +31 -0
- data/spec/fixtures/erb_example.html.erb +31 -0
- data/spec/lib/codeqa/checkers/check_conflict_spec.rb +3 -3
- data/spec/lib/codeqa/checkers/check_erb_html_spec.rb +3 -3
- data/spec/lib/codeqa/checkers/check_linkto_spec.rb +3 -1
- data/spec/lib/codeqa/checkers/check_strange_chars_spec.rb +6 -2
- data/spec/lib/codeqa/checkers/html_validator_spec.rb +78 -0
- data/spec/lib/codeqa/checkers/rubocop_lint_spec.rb +1 -1
- data/spec/lib/codeqa/runner_decorator_spec.rb +71 -12
- data/spec/lib/codeqa/utils/erb_sanitizer_spec.rb +58 -0
- metadata +15 -6
- data/lib/codeqa/fake_erb.rb +0 -80
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3ae0299a503f1cb9639e037907ade194edfe3db0
|
4
|
+
data.tar.gz: 859128b8f52f560cc2dedb79157134237179b042
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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(
|
13
|
-
watch(
|
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
|
data/lib/codeqa.rb
CHANGED
data/lib/codeqa/checker.rb
CHANGED
@@ -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
|
-
#{
|
30
|
-
#{
|
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/
|
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(
|
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 =
|
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(
|
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,
|
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
|
-
|
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(--
|
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}
|
39
|
-
msg << error("#{checker.hint}\n"
|
40
|
-
checker.errors.details.each do |
|
41
|
-
|
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
|
-
|
77
|
-
|
78
|
-
|
89
|
+
def yellow(txt)
|
90
|
+
colorize(33, txt)
|
91
|
+
end
|
79
92
|
|
80
93
|
# def pink(txt)
|
81
94
|
# colorize(35, txt)
|
File without changes
|
@@ -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
|
data/lib/codeqa/version.rb
CHANGED
data/lib/templates/pre-commit
CHANGED
@@ -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, :
|
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
|
+
<%= 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
|
-
[
|
19
|
-
[
|
20
|
-
[
|
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
|
-
[
|
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
|
-
[
|
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
|
-
[
|
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([
|
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([
|
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([
|
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
|
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
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
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
|
-
|
12
|
-
|
13
|
-
|
14
|
-
expect(
|
15
|
-
|
16
|
-
|
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.
|
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-
|
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:
|
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
|
data/lib/codeqa/fake_erb.rb
DELETED
@@ -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
|