jruby-lint 0.4.1 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +2 -1
- data/README.md +2 -8
- data/jruby-lint.gemspec +2 -3
- data/lib/jruby/lint/ast.rb +1 -1
- data/lib/jruby/lint/checkers.rb +18 -1
- data/lib/jruby/lint/checkers/fork_exec.rb +22 -39
- data/lib/jruby/lint/checkers/gem.rb +44 -30
- data/lib/jruby/lint/checkers/gemspec.rb +4 -4
- data/lib/jruby/lint/checkers/nonatomic.rb +38 -8
- data/lib/jruby/lint/checkers/object_space.rb +8 -6
- data/lib/jruby/lint/checkers/system.rb +4 -4
- data/lib/jruby/lint/checkers/thread_critical.rb +4 -4
- data/lib/jruby/lint/cli.rb +8 -1
- data/lib/jruby/lint/collectors.rb +18 -7
- data/lib/jruby/lint/finding.rb +1 -1
- data/lib/jruby/lint/libraries.rb +21 -30
- data/lib/jruby/lint/project.rb +3 -3
- data/lib/jruby/lint/reporters/html.rb +4 -3
- data/lib/jruby/lint/reporters/jruby-lint.html.erb +10 -1
- data/lib/jruby/lint/reporters/text.rb +5 -4
- data/lib/jruby/lint/version.rb +1 -1
- data/spec/fixtures/C-Extension-Alternatives.md +81 -0
- data/spec/jruby/lint/ast_spec.rb +6 -6
- data/spec/jruby/lint/checkers_spec.rb +91 -62
- data/spec/jruby/lint/collectors_spec.rb +3 -9
- data/spec/jruby/lint/finding_spec.rb +10 -10
- data/spec/jruby/lint/libraries_spec.rb +13 -13
- data/spec/jruby/lint/project_spec.rb +34 -40
- data/spec/jruby/lint/reporters_spec.rb +22 -13
- data/spec/jruby/lint/version_spec.rb +1 -1
- data/spec/spec_helper.rb +1 -1
- metadata +30 -96
- data/lib/jruby/lint/checkers/timeout.rb +0 -21
- data/lib/jruby/lint/github.crt +0 -23
- data/spec/fixtures/C-Extension-Alternatives.html +0 -339
- data/spec/jruby/lint/cli_spec.rb +0 -73
data/lib/jruby/lint/cli.rb
CHANGED
@@ -38,6 +38,10 @@ module JRuby
|
|
38
38
|
@options.ansi = true
|
39
39
|
end
|
40
40
|
|
41
|
+
opts.on('--no-source-line', 'do not print out line of source') do
|
42
|
+
@options.no_src_line = true
|
43
|
+
end
|
44
|
+
|
41
45
|
opts.on('--html [REPORT_FILE]', 'print report as html file') do |file|
|
42
46
|
@options.html = file || 'jruby-lint.html'
|
43
47
|
end
|
@@ -55,6 +59,9 @@ module JRuby
|
|
55
59
|
end.parse!(args)
|
56
60
|
|
57
61
|
@options.files = args.empty? ? nil : args
|
62
|
+
rescue OptionParser::InvalidOption
|
63
|
+
puts $!.message
|
64
|
+
exit -1
|
58
65
|
end
|
59
66
|
|
60
67
|
def run
|
@@ -71,7 +78,7 @@ module JRuby
|
|
71
78
|
puts "OK"
|
72
79
|
exit
|
73
80
|
else
|
74
|
-
puts "Found #{project.findings.
|
81
|
+
puts "Found #{project.findings.count { |e| !e.tags.include? "internal" } } items"
|
75
82
|
exit 1
|
76
83
|
end
|
77
84
|
end
|
@@ -1,16 +1,25 @@
|
|
1
1
|
module JRuby::Lint
|
2
2
|
class Collector
|
3
|
-
attr_accessor :checkers, :findings, :project, :contents, :file
|
3
|
+
attr_accessor :checkers, :findings, :project, :contents, :file, :stack
|
4
4
|
|
5
5
|
def initialize(project = nil, file = nil)
|
6
6
|
@checkers = Checker.loaded_checkers.map(&:new)
|
7
7
|
@checkers.each {|c| c.collector = self }
|
8
8
|
@findings = []
|
9
9
|
@project, @file = project, file || '<inline-script>'
|
10
|
+
|
11
|
+
# top to bottom list of elements as they are visited
|
12
|
+
@stack = [] # FIXME: ast visiting is not something checkers can see so stored here for now
|
13
|
+
end
|
14
|
+
|
15
|
+
def add_finding(message, tags, line=nil)
|
16
|
+
src_line = line ? contents.split(/\n/)[line-1] : nil
|
17
|
+
@findings << Finding.new(message, tags, file, line, src_line)
|
10
18
|
end
|
11
19
|
|
12
20
|
class CheckersVisitor < AST::Visitor
|
13
|
-
attr_reader :collector, :checkers
|
21
|
+
attr_reader :collector, :checkers, :stack
|
22
|
+
|
14
23
|
|
15
24
|
def initialize(ast, collector, checkers)
|
16
25
|
super(ast)
|
@@ -18,6 +27,7 @@ module JRuby::Lint
|
|
18
27
|
end
|
19
28
|
|
20
29
|
def visit(method, node)
|
30
|
+
@collector.stack.push node
|
21
31
|
after_hooks = []
|
22
32
|
checkers.each do |ch|
|
23
33
|
begin
|
@@ -26,19 +36,20 @@ module JRuby::Lint
|
|
26
36
|
after_hooks << res if res.respond_to?(:call)
|
27
37
|
end
|
28
38
|
rescue Exception => e
|
29
|
-
collector.
|
30
|
-
[:internal, :debug], node.
|
39
|
+
collector.add_finding("Exception while traversing: #{e.message}\n at #{e.backtrace.first}",
|
40
|
+
[:internal, :debug], node.line+1)
|
31
41
|
end
|
32
42
|
end
|
33
43
|
super
|
34
44
|
rescue Exception => e
|
35
|
-
collector.
|
36
|
-
[:internal, :debug], node.
|
45
|
+
collector.add_finding("Exception while traversing: #{e.message}\n at #{e.backtrace.first}",
|
46
|
+
[:internal, :debug], node.line+1)
|
37
47
|
ensure
|
38
48
|
begin
|
39
49
|
after_hooks.each {|h| h.call }
|
40
50
|
rescue
|
41
51
|
end
|
52
|
+
@collector.stack.pop
|
42
53
|
end
|
43
54
|
end
|
44
55
|
|
@@ -47,7 +58,7 @@ module JRuby::Lint
|
|
47
58
|
CheckersVisitor.new(ast, self, checkers).traverse
|
48
59
|
rescue SyntaxError => e
|
49
60
|
file, line, message = e.message.split(/:\s*/, 3)
|
50
|
-
|
61
|
+
add_finding(message, [:syntax, :error], line.to_i)
|
51
62
|
end
|
52
63
|
end
|
53
64
|
|
data/lib/jruby/lint/finding.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module JRuby::Lint
|
2
|
-
class Finding < Struct.new(:message, :tags, :file, :line)
|
2
|
+
class Finding < Struct.new(:message, :tags, :file, :line, :src_line)
|
3
3
|
def initialize(*args)
|
4
4
|
args[1].map! {|x| x.to_s } if args.size > 1
|
5
5
|
if args.size > 2 && args[2].respond_to?(:file) && args[2].respond_to?(:line)
|
data/lib/jruby/lint/libraries.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'net/https'
|
2
|
-
require 'nokogiri'
|
3
2
|
require 'tempfile'
|
4
3
|
require 'fileutils'
|
5
4
|
|
@@ -27,7 +26,7 @@ module JRuby::Lint
|
|
27
26
|
|
28
27
|
def filename_for(name)
|
29
28
|
name = File.basename(name)
|
30
|
-
File.join(@cache_dir, File.extname(name).empty? ? "#{name}.
|
29
|
+
File.join(@cache_dir, File.extname(name).empty? ? "#{name}.md" : name)
|
31
30
|
end
|
32
31
|
|
33
32
|
def stale?(filename)
|
@@ -35,28 +34,10 @@ module JRuby::Lint
|
|
35
34
|
end
|
36
35
|
|
37
36
|
def read_from_wiki(name, filename)
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
if uri.host == "github.com"
|
43
|
-
Net::HTTP.new(uri.host, uri.port).tap do |http|
|
44
|
-
if uri.scheme == "https"
|
45
|
-
http.use_ssl = true
|
46
|
-
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
47
|
-
# gd_bundle.crt from https://certs.godaddy.com/anonymous/repository.seam
|
48
|
-
http.ca_file = File.expand_path('../github.crt', __FILE__)
|
49
|
-
end
|
50
|
-
http.start do
|
51
|
-
response = http.get(uri.path)
|
52
|
-
content = response.body
|
53
|
-
File.open(filename, "w") do |f|
|
54
|
-
f << content
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
raise "Unknown location '#{uri}' for page '#{name}'" unless content
|
37
|
+
require 'open-uri'
|
38
|
+
download = open('https://github.com/jruby/jruby/wiki/C-Extension-Alternatives.md')
|
39
|
+
content = download.read(nil)
|
40
|
+
File.open(filename, "w") { |f| f << content }
|
60
41
|
content
|
61
42
|
rescue => e
|
62
43
|
raise "Error while reading from wiki: #{e.message}\nPlease try again later."
|
@@ -72,11 +53,21 @@ module JRuby::Lint
|
|
72
53
|
|
73
54
|
def load
|
74
55
|
@gems = {}
|
75
|
-
content = @cache.fetch('C-Extension-Alternatives')
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
56
|
+
content = @cache.fetch('C-Extension-Alternatives.md')
|
57
|
+
|
58
|
+
in_suggestions = false
|
59
|
+
content.split("\n").each do |line|
|
60
|
+
if line =~ /<!-- suggestions start/
|
61
|
+
in_suggestions = true
|
62
|
+
elsif !in_suggestions
|
63
|
+
next
|
64
|
+
elsif line =~ /<!-- suggestions end/
|
65
|
+
in_suggestions = false
|
66
|
+
break
|
67
|
+
else
|
68
|
+
_, key, value = line.gsub(/[\[\]]/, '').split("|", 3)
|
69
|
+
@gems[key.downcase] = value
|
70
|
+
end
|
80
71
|
end
|
81
72
|
rescue => e
|
82
73
|
@error = "Unable to load C Extension alternatives list: #{e.message}"
|
@@ -85,7 +76,7 @@ module JRuby::Lint
|
|
85
76
|
|
86
77
|
SOURCES = [CExtensions]
|
87
78
|
|
88
|
-
|
79
|
+
attr_accessor :gems
|
89
80
|
|
90
81
|
def initialize(cache)
|
91
82
|
@sources = SOURCES.map {|s| s.new(cache) }
|
data/lib/jruby/lint/project.rb
CHANGED
@@ -52,9 +52,9 @@ module JRuby::Lint
|
|
52
52
|
|
53
53
|
def load_reporters(options)
|
54
54
|
@reporters = []
|
55
|
-
@reporters << Reporters::Html.new(self, options.html) if options.html
|
56
|
-
@reporters << Reporters::ANSIColor.new(self, STDOUT) if options.ansi || STDOUT.tty?
|
57
|
-
@reporters << Reporters::Text.new(self, STDOUT) if options.text || @reporters.empty?
|
55
|
+
@reporters << Reporters::Html.new(self, options.html, options) if options.html
|
56
|
+
@reporters << Reporters::ANSIColor.new(self, STDOUT, options) if options.ansi || STDOUT.tty?
|
57
|
+
@reporters << Reporters::Text.new(self, STDOUT, options) if options.text || @reporters.empty?
|
58
58
|
end
|
59
59
|
|
60
60
|
def load_libraries
|
@@ -1,11 +1,12 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
1
3
|
module JRuby::Lint
|
2
4
|
module Reporters
|
3
5
|
class Html
|
4
6
|
require 'erb'
|
5
7
|
|
6
|
-
def initialize(project, output)
|
7
|
-
@tags = project.tags
|
8
|
-
@output = output
|
8
|
+
def initialize(project, output, options=OpenStruct.new)
|
9
|
+
@tags, @output, @options = project.tags, output, options
|
9
10
|
@template = ERB.new(File.read(File.expand_path('../jruby-lint.html.erb', __FILE__)))
|
10
11
|
end
|
11
12
|
|
@@ -29,10 +29,19 @@ nav { position: relative; }
|
|
29
29
|
<% @findings.each do |finding| %>
|
30
30
|
<% if finding.error? %>
|
31
31
|
<li class="error"><%= finding %></li>
|
32
|
-
|
32
|
+
<% if finding.src_line && !@options.no_src_line%>
|
33
|
+
<pre><%= finding.src_line %></pre>
|
34
|
+
<% end %>
|
35
|
+
<% elsif finding.warning? %>
|
33
36
|
<li class="warning"><%= finding %></li>
|
37
|
+
<% if finding.src_line && !@options.no_src_line%>
|
38
|
+
<pre><%= finding.src_line %></pre>
|
39
|
+
<% end %>
|
34
40
|
<% else %>
|
35
41
|
<li class="message"><%= finding %></li>
|
42
|
+
<% if finding.src_line && !@options.no_src_line%>
|
43
|
+
<pre><%= finding.src_line %></pre>
|
44
|
+
<% end %>
|
36
45
|
<% end %>
|
37
46
|
<% end %>
|
38
47
|
</ul>
|
@@ -1,8 +1,8 @@
|
|
1
1
|
module JRuby::Lint
|
2
2
|
module Reporters
|
3
3
|
class Text
|
4
|
-
def initialize(project, output)
|
5
|
-
@tags, @output = project.tags, output
|
4
|
+
def initialize(project, output, options=OpenStruct.new)
|
5
|
+
@tags, @output, @options = project.tags, output, options
|
6
6
|
end
|
7
7
|
|
8
8
|
def report(findings)
|
@@ -23,11 +23,12 @@ module JRuby::Lint
|
|
23
23
|
msg = if finding.error?
|
24
24
|
red(finding.to_s)
|
25
25
|
elsif finding.warning?
|
26
|
-
|
26
|
+
cyan(finding.to_s)
|
27
27
|
else
|
28
|
-
finding.to_s
|
28
|
+
blue(finding.to_s)
|
29
29
|
end
|
30
30
|
@output.puts msg
|
31
|
+
@output.puts finding.src_line if finding.src_line && !@options.no_src_line
|
31
32
|
end
|
32
33
|
end
|
33
34
|
end
|
data/lib/jruby/lint/version.rb
CHANGED
@@ -0,0 +1,81 @@
|
|
1
|
+
JRuby does not support native C extensions, but it does have it's own Java native extensions API. Several gems have implementations of both Java and C extensions rolled into the same gem and those will not be listed here since they will just work. In some cases there is a JRuby version with a slightly different name or possibly even a totally different name and we list these here so you can update your Gemfile:
|
2
|
+
|
3
|
+
```ruby
|
4
|
+
gem 'therubyracer', platform: :mri
|
5
|
+
gem 'therubyrhino', platform: :jruby
|
6
|
+
```
|
7
|
+
|
8
|
+
When there is not an exact match some gems come close enough where a little work on your part can make your application compatible with JRuby.
|
9
|
+
|
10
|
+
This page lists common C extensions and JRuby-friendly alternatives you can use to replace them.
|
11
|
+
|
12
|
+
If you are interested in helping us port an extension to JRuby, this article is helpful: [Your first Ruby native extension: Java](https://blog.jcoglan.com/2012/08/02/your-first-ruby-native-extension-java/) see also [JRuby examples](https://github.com/jruby/jruby-examples) for a maven build.
|
13
|
+
|
14
|
+
<!-- suggestions start -->
|
15
|
+
| Gem | Suggestions |
|
16
|
+
|-----|-------------|
|
17
|
+
|[RDiscount][]|Use [kramdown][], [Maruku][] (pure Ruby) or [markdown_j][] (wrapper around a Java library)|
|
18
|
+
|[RedCarpet][]|Same as with **RDiscount** use alternatives such as [kramdown][], [Maruku][] or [markdown_j][]|
|
19
|
+
|[RMagick][]|Try [RMagick4J][] (implements ImageMagick functionality in Java) or preferably use alternatives [mini_magick][] & [quick_magick][]. For simple resizing, cropping, greyscaling, etc look at [image_voodoo][]. You can also use Java's Graphics2D.|
|
20
|
+
|[Unicorn][]| Use [Puma][].|
|
21
|
+
|[Thin][]| Use [Puma][].|
|
22
|
+
|mysql|Use [activerecord-jdbcmysql-adapter][].|
|
23
|
+
|mysql2|Use [activerecord-jdbcmysql-adapter][].|
|
24
|
+
|sqlite3|Use [activerecord-jdbcsqlite3-adapter][].|
|
25
|
+
|pg|Use [activerecord-jdbcpostgresql-adapter][] instead or [pg_jruby][] (drop-in replacement).|
|
26
|
+
|[yajl-ruby][]|Try `json` or `json_pure` instead. Unfortunately there is no known equivalent JSON stream parser.|
|
27
|
+
|[oj][]|Try `gson`, `json` or `json_pure` instead.|
|
28
|
+
|[bson_ext][]|`bson_ext` isn't used with JRuby. Instead, some native Java extensions are bundled with the `bson` gem.|
|
29
|
+
|[win32ole][]|Use the `jruby-win32ole` gem (preinstalled in JRuby's Windows installer).|
|
30
|
+
|[curb][]|[Rurl][] is an example how to implement _some_ of curb's functionality using [Apache HttpClient][]|
|
31
|
+
|[therubyracer][]|Try using [therubyrhino][] instead (or [dienashorner][] on Java 8+).|
|
32
|
+
|[kyotocabinet][]|Try using [kyotocabinet-java][] instead. This isn't 100% complete yet, but it covers most of the API.|
|
33
|
+
|[memcached][]|Try using [jruby-memcached][] instead. Alternatively you can use [jruby-ehcache][], a JRuby interface to Java's (JSR-107 compliant) Ehcache.|
|
34
|
+
|[charlock_holmes][]|Use [charlock_holmes-jruby][] instead.|
|
35
|
+
<!-- suggestions end -->
|
36
|
+
|
37
|
+
Please add to this list with your findings.
|
38
|
+
|
39
|
+
*Note that the [JRuby-Lint][] gem parses the contents of the list above to use for its Ruby gem checker. In order for JRuby-Lint to use the information, please adhere to the table format above and the links to projects below (in the source for this page).
|
40
|
+
|
41
|
+
<!-- links start -->
|
42
|
+
[RDiscount]: http://dafoster.net/projects/rdiscount/
|
43
|
+
[RedCarpet]: https://github.com/vmg/redcarpet
|
44
|
+
[kramdown]: https://github.com/gettalong/kramdown
|
45
|
+
[Maruku]:https://github.com/bhollis/maruku
|
46
|
+
[markdown_j]: https://github.com/nate/markdown_j
|
47
|
+
[RMagick]: https://github.com/rmagick/rmagick
|
48
|
+
[RMagick4J]: https://github.com/Serabe/RMagick4J
|
49
|
+
[mini_magick]: https://github.com/minimagick/minimagick
|
50
|
+
[quick_magick]: https://github.com/aseldawy/quick_magick
|
51
|
+
[image_voodoo]: https://github.com/jruby/image_voodoo
|
52
|
+
[Unicorn]: http://unicorn.bogomips.org/
|
53
|
+
[Puma]: http://puma.io/
|
54
|
+
[Thin]: http://code.macournoyer.com/thin/
|
55
|
+
[Typhoeus]: https://github.com/dbalatero/typhoeus
|
56
|
+
[activerecord-jdbc-adapter]: https://github.com/jruby/activerecord-jdbc-adapter
|
57
|
+
[JRuby-Lint]: https://github.com/jruby/jruby-lint
|
58
|
+
[Nokogiri]: http://nokogiri.org/
|
59
|
+
[yajl-ruby]: https://github.com/brianmario/yajl-ruby
|
60
|
+
[bson_ext]: https://github.com/mongodb/mongo-ruby-driver
|
61
|
+
[Apache HttpClient]: http://hc.apache.org/httpcomponents-client-ga/
|
62
|
+
[HttpURLConnection]: http://download.oracle.com/javase/1,5.0/docs/api/java/net/HttpURLConnection.html
|
63
|
+
[win32ole]: http://www.ruby-doc.org/stdlib/libdoc/win32ole/rdoc/index.html
|
64
|
+
[Rurl]: https://github.com/rcyrus/Rurl
|
65
|
+
[curb]: https://github.com/taf2/curb
|
66
|
+
[therubyracer]: https://github.com/cowboyd/therubyracer
|
67
|
+
[therubyrhino]: https://github.com/cowboyd/therubyrhino
|
68
|
+
[dienashorner]: https://github.com/kares/dienashorner
|
69
|
+
[kyotocabinet]: http://fallabs.com/kyotocabinet/
|
70
|
+
[kyotocabinet-java]: https://github.com/csw/kyotocabinet-java
|
71
|
+
[memcached]: https://github.com/evan/memcached
|
72
|
+
[jruby-memcached]: https://github.com/aurorafeint/jruby-memcached
|
73
|
+
[jruby-ehcache]: https://github.com/dylanz/ehcache
|
74
|
+
[oj]: https://github.com/ohler55/oj
|
75
|
+
[activerecord-jdbcmysql-adapter]: https://rubygems.org/gems/activerecord-jdbcmysql-adapter
|
76
|
+
[activerecord-jdbcsqlite3-adapter]: https://rubygems.org/gems/activerecord-jdbcsqlite3-adapter
|
77
|
+
[activerecord-jdbcpostgresql-adapter]: https://rubygems.org/gems/activerecord-jdbcpostgresql-adapter
|
78
|
+
[pg_jruby]: https://rubygems.org/gems/pg_jruby
|
79
|
+
[charlock_holmes]: https://github.com/brianmario/charlock_holmes
|
80
|
+
[charlock_holmes-jruby]: https://github.com/siuying/charlock_holmes-jruby
|
81
|
+
<!-- links start -->
|
data/spec/jruby/lint/ast_spec.rb
CHANGED
@@ -5,19 +5,19 @@ describe JRuby::Lint::AST::Visitor do
|
|
5
5
|
Given(:visitor) { JRuby::Lint::AST::Visitor.new(ast) }
|
6
6
|
|
7
7
|
# RootNode
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
# StrNode =="hello"
|
8
|
+
# FCallOneArgNode |puts|
|
9
|
+
# ArrayNode
|
10
|
+
# StrNode =="hello"
|
12
11
|
Given(:script) { %{puts "hello"} }
|
13
12
|
|
14
13
|
context "visits all nodes" do
|
15
14
|
When { visitor.each_node { @count ||= 0; @count += 1} }
|
16
|
-
Then { @count.
|
15
|
+
Then { expect(@count).to eq(4) }
|
17
16
|
end
|
18
17
|
|
19
18
|
context "selects nodes" do
|
20
19
|
When { @nodes = visitor.select {|n| n.node_type == org.jruby.ast.NodeType::STRNODE } }
|
21
|
-
Then { @nodes.size.
|
20
|
+
Then { expect(@nodes.size).to(eq(1)) &&
|
21
|
+
expect(@nodes.first.value.to_s).to(eq("hello")) }
|
22
22
|
end
|
23
23
|
end
|
@@ -5,14 +5,14 @@ describe JRuby::Lint::Checker do
|
|
5
5
|
subject { Class.new { include JRuby::Lint::Checker } }
|
6
6
|
|
7
7
|
it "finds all loaded checkers" do
|
8
|
-
JRuby::Lint::Checker.loaded_checkers.
|
8
|
+
expect(JRuby::Lint::Checker.loaded_checkers).to include(subject)
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
13
|
describe JRuby::Lint::Checkers do
|
14
14
|
Given(:gems) { { "rdiscount" => "may not work", "bson_ext" => "not needed" } }
|
15
|
-
Given(:project) {
|
15
|
+
Given(:project) {JRuby::Lint::Project.new.tap {|p| p.libraries.gems = gems }}
|
16
16
|
Given(:collector) do
|
17
17
|
JRuby::Lint::Collector.new(project).tap do |c|
|
18
18
|
c.contents = script
|
@@ -26,16 +26,16 @@ describe JRuby::Lint::Checkers do
|
|
26
26
|
|
27
27
|
context "detects fcall-style" do
|
28
28
|
# FCallNoArgBlockNode |fork|
|
29
|
-
Given(:script) { "fork { }
|
29
|
+
Given(:script) { "fork { }" }
|
30
30
|
When { collector.run }
|
31
|
-
Then { collector.findings.size.
|
31
|
+
Then { expect(collector.findings.size).to eq(1) }
|
32
32
|
end
|
33
33
|
|
34
34
|
context "detects vcall-style" do
|
35
35
|
# VCallNode |fork|
|
36
36
|
Given(:script) { "fork" }
|
37
37
|
When { collector.run }
|
38
|
-
Then { collector.findings.size.
|
38
|
+
Then { expect(collector.findings.size).to eq(1) }
|
39
39
|
end
|
40
40
|
|
41
41
|
context "does not detect call-style" do
|
@@ -43,15 +43,15 @@ describe JRuby::Lint::Checkers do
|
|
43
43
|
# VCallNode |fork|
|
44
44
|
Given(:script) { "fork.fork" }
|
45
45
|
When { collector.run }
|
46
|
-
Then { collector.findings.size.
|
46
|
+
Then { expect(collector.findings.size).to eq(0) }
|
47
47
|
end
|
48
48
|
|
49
49
|
context "detects Kernel::fork style" do
|
50
50
|
# CallNoArgNode |fork|
|
51
51
|
# ConstNode |Kernel|
|
52
|
-
Given(:script) { "Kernel::fork
|
52
|
+
Given(:script) { "Kernel::fork" }
|
53
53
|
When { collector.run }
|
54
|
-
Then { collector.findings.size.
|
54
|
+
Then { expect(collector.findings.size).to eq(1) }
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
@@ -61,25 +61,43 @@ describe JRuby::Lint::Checkers do
|
|
61
61
|
context "creates a finding for a gem mentioned in the libraries" do
|
62
62
|
Given(:script) { "gem 'rdiscount'" }
|
63
63
|
When { collector.run }
|
64
|
-
Then { collector.findings.size.
|
64
|
+
Then { expect(collector.findings.size).to eq(2) }
|
65
65
|
end
|
66
66
|
|
67
67
|
context "creates one finding to mention the wiki for gem compatibility" do
|
68
68
|
Given(:script) { "gem 'rdiscount'; gem 'bson_ext'" }
|
69
69
|
When { collector.run }
|
70
|
-
Then { collector.findings.size.
|
70
|
+
Then { expect(collector.findings.size).to eq(3) }
|
71
|
+
end
|
72
|
+
|
73
|
+
context "ignores platform for gem compatibility if not right platform" do
|
74
|
+
Given(:script) { "gem 'rdiscount', platform: :ruby" }
|
75
|
+
When { collector.run }
|
76
|
+
Then { expect(collector.findings.size).to eq(0) }
|
77
|
+
end
|
78
|
+
|
79
|
+
context "creates a finding if platform for gem compatibility is ours" do
|
80
|
+
Given(:script) { "gem 'rdiscount', platform: :jruby" }
|
81
|
+
When { collector.run }
|
82
|
+
Then { expect(collector.findings.size).to eq(2) }
|
83
|
+
end
|
84
|
+
|
85
|
+
context "creates no finding if in wrong platform block" do
|
86
|
+
Given(:script) { "platforms :ruby { gem 'rdiscount' }" }
|
87
|
+
When { collector.run }
|
88
|
+
Then { expect(collector.findings.size).to eq(1) }
|
71
89
|
end
|
72
90
|
|
73
91
|
context "does not create a finding for a gem not mentioned in the gems info" do
|
74
92
|
Given(:script) { "gem 'json_pure'" }
|
75
93
|
When { collector.run }
|
76
|
-
Then { collector.findings.size.
|
94
|
+
Then { expect(collector.findings.size).to eq(0) }
|
77
95
|
end
|
78
96
|
|
79
97
|
context "only checks calls to #gem" do
|
80
98
|
Given(:script) { "require 'rdiscount'" }
|
81
99
|
When { collector.run }
|
82
|
-
Then { collector.findings.size.
|
100
|
+
Then { expect(collector.findings.size).to eq(0) }
|
83
101
|
end
|
84
102
|
end
|
85
103
|
|
@@ -91,8 +109,8 @@ describe JRuby::Lint::Checkers do
|
|
91
109
|
"s.add_development_dependency 'ruby-debug19'\nend\n" }
|
92
110
|
|
93
111
|
When { collector.run }
|
94
|
-
Then { collector.findings.size.
|
95
|
-
Then { collector.findings.detect{|f| f.message =~ /rdiscount/ }.
|
112
|
+
Then { expect(collector.findings.size).to eq(2) }
|
113
|
+
Then { expect(collector.findings.detect{|f| f.message =~ /rdiscount/ }).to be_truthy }
|
96
114
|
end
|
97
115
|
|
98
116
|
context "Thread.critical checker" do
|
@@ -101,13 +119,13 @@ describe JRuby::Lint::Checkers do
|
|
101
119
|
context "read" do
|
102
120
|
Given(:script) { "begin \n Thread.critical \n end"}
|
103
121
|
When { collector.run }
|
104
|
-
Then { collector.findings.size.
|
122
|
+
Then { expect(collector.findings.size).to eq(1) }
|
105
123
|
end
|
106
124
|
|
107
125
|
context "assign" do
|
108
126
|
Given(:script) { "begin \n Thread.critical = true \n ensure Thread.critical = false \n end"}
|
109
127
|
When { collector.run }
|
110
|
-
Then { collector.findings.size.
|
128
|
+
Then { expect(collector.findings.size).to eq(2) }
|
111
129
|
end
|
112
130
|
end
|
113
131
|
|
@@ -117,70 +135,53 @@ describe JRuby::Lint::Checkers do
|
|
117
135
|
context "_id2ref usage" do
|
118
136
|
Given(:script) { "ObjectSpace._id2ref(obj)"}
|
119
137
|
When { collector.run }
|
120
|
-
Then { collector.findings.size.
|
138
|
+
Then { expect(collector.findings.size).to eq(1) }
|
121
139
|
end
|
122
140
|
|
123
141
|
context "each_object usage" do
|
124
142
|
Given(:script) { "ObjectSpace.each_object { }"}
|
125
143
|
When { collector.run }
|
126
|
-
Then { collector.findings.size.
|
144
|
+
Then { expect(collector.findings.size).to eq(1) }
|
127
145
|
end
|
128
146
|
|
129
147
|
context "each_object(Class) usage is ok" do
|
130
148
|
Given(:script) { "ObjectSpace.each_object(Class) { }"}
|
131
149
|
When { collector.run }
|
132
|
-
Then { collector.findings.size.
|
150
|
+
Then { collector.findings; expect(collector.findings.size).to eq(0) }
|
133
151
|
end
|
134
152
|
end
|
135
153
|
|
136
|
-
context "Timeout::timeout" do
|
137
|
-
Given(:checker) { JRuby::Lint::Checkers::Timeout.new }
|
138
|
-
|
139
|
-
context "::timeout usage" do
|
140
|
-
Given(:script) { "Timeout::timeout(5) { sleep 10 }"}
|
141
|
-
When { collector.run }
|
142
|
-
Then { collector.findings.size.should == 1}
|
143
|
-
end
|
144
|
-
|
145
|
-
context ".timeout usage" do
|
146
|
-
Given(:script) { "Timeout.timeout(5) { sleep 10 }" }
|
147
|
-
When { collector.run }
|
148
|
-
Then { collector.findings.size.should == 1}
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
|
153
154
|
context "System" do
|
154
155
|
Given(:checker) { JRuby::Lint::Checkers::System.new }
|
155
156
|
|
156
157
|
context "calling ruby -v in system" do
|
157
158
|
Given(:script) { "system('echo'); system('/usr/bin/ruby -v')"}
|
158
159
|
When { collector.run }
|
159
|
-
Then { collector.findings.size.
|
160
|
+
Then { expect(collector.findings.size).to eq(1) }
|
160
161
|
end
|
161
162
|
|
162
163
|
context "calling ruby in the first argument to system" do
|
163
164
|
Given(:script) { "system('/usr/bin/ruby', '-v')"}
|
164
165
|
When { collector.run }
|
165
|
-
Then { collector.findings.size.
|
166
|
+
Then { expect(collector.findings.size).to eq(1) }
|
166
167
|
end
|
167
168
|
|
168
169
|
context "calling irb or jirb from system" do
|
169
170
|
Given(:script) { "system('jirb'); system('irb')"}
|
170
171
|
When { collector.run }
|
171
|
-
Then { collector.findings.size.
|
172
|
+
Then { expect(collector.findings.size).to eq(2) }
|
172
173
|
end
|
173
174
|
|
174
175
|
context "calling a .rb file from system" do
|
175
176
|
Given(:script) { "system('asdf.rb')" }
|
176
177
|
When { collector.run }
|
177
|
-
Then { collector.findings.size.
|
178
|
+
Then { expect(collector.findings.size).to eq(1) }
|
178
179
|
end
|
179
180
|
|
180
181
|
context "calling ruby -v in Kernel.system should have a finding" do
|
181
182
|
Given(:script) { "Kernel.system('ruby -v'); Kernel.system('echo \"zomg\"')"}
|
182
183
|
When { collector.run }
|
183
|
-
Then { collector.findings.size.
|
184
|
+
Then { expect(collector.findings.size).to eq(1) }
|
184
185
|
end
|
185
186
|
|
186
187
|
end
|
@@ -191,75 +192,103 @@ describe JRuby::Lint::Checkers do
|
|
191
192
|
context "class variable or-assignment" do
|
192
193
|
Given(:script) { "@@foo ||= 1" }
|
193
194
|
When { collector.run }
|
194
|
-
Then { collector.findings.size.
|
195
|
+
Then { expect(collector.findings.size).to eq(1) }
|
195
196
|
end
|
196
197
|
|
197
198
|
context "instance variable or-assignment" do
|
198
199
|
Given(:script) { "@foo ||= 1" }
|
199
200
|
When { collector.run }
|
200
|
-
Then { collector.findings.size.
|
201
|
+
Then { expect(collector.findings.size).to eq(1) }
|
202
|
+
Then { expect(collector.findings.first.message).to be =~ /\(@foo\)/ }
|
201
203
|
end
|
202
204
|
|
203
205
|
context "attribute or-assignment" do
|
204
206
|
Given(:script) { "foo.bar ||= 1" }
|
205
207
|
When { collector.run }
|
206
|
-
Then { collector.findings.size.
|
208
|
+
Then { expect(collector.findings.size).to eq(1) }
|
209
|
+
Then { expect(collector.findings.first.message).to be =~ /\(bar\)/ }
|
207
210
|
end
|
208
211
|
|
209
212
|
context "element or-assignment" do
|
210
213
|
Given(:script) { "foo[bar] ||= 1" }
|
211
214
|
When { collector.run }
|
212
|
-
Then { collector.findings.size.
|
215
|
+
Then { expect(collector.findings.size).to eq(1) }
|
216
|
+
Then { expect(collector.findings.first.message).to be =~ /\(foo\[bar\]\)/ }
|
213
217
|
end
|
214
218
|
|
215
219
|
context "class variable and-assignment" do
|
216
220
|
Given(:script) { "@@foo &&= 1" }
|
217
221
|
When { collector.run }
|
218
|
-
Then { collector.findings.size.
|
222
|
+
Then { expect(collector.findings.size).to eq(1) }
|
223
|
+
Then { expect(collector.findings.first.message).to be =~ /\(@@foo\)/ }
|
219
224
|
end
|
220
225
|
|
221
226
|
context "instance variable and-assignment" do
|
222
227
|
Given(:script) { "@foo &&= 1" }
|
223
228
|
When { collector.run }
|
224
|
-
Then { collector.findings.size.
|
229
|
+
Then { expect(collector.findings.size).to eq(1) }
|
230
|
+
Then { expect(collector.findings.first.message).to be =~ /\(@foo\)/ }
|
225
231
|
end
|
226
232
|
|
227
233
|
context "attribute and-assignment" do
|
228
234
|
Given(:script) { "foo.bar &&= 1" }
|
229
235
|
When { collector.run }
|
230
|
-
Then { collector.findings.size.
|
236
|
+
Then { expect(collector.findings.size).to eq(1) }
|
237
|
+
Then { expect(collector.findings.first.message).to be =~ /\(bar\)/ }
|
231
238
|
end
|
232
239
|
|
233
240
|
context "element and-assignment" do
|
234
241
|
Given(:script) { "foo[bar] &&= 1" }
|
235
242
|
When { collector.run }
|
236
|
-
Then { collector.findings.size.
|
243
|
+
Then { expect(collector.findings.size).to eq(1) }
|
244
|
+
Then { expect(collector.findings.first.message).to be =~ /\(foo\[bar\]\)/ }
|
237
245
|
end
|
238
246
|
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
247
|
+
context "element and-assignment (complicated name)" do
|
248
|
+
Given(:script) { "foo[bar(2, heh)] &&= 1" }
|
249
|
+
When { collector.run }
|
250
|
+
Then { expect(collector.findings.size).to eq(1) }
|
251
|
+
Then { expect(collector.findings.first.message).to be =~ /\(foo\[bar\(2, heh\)\]\)/ }
|
252
|
+
end
|
253
|
+
|
254
|
+
context "class variable op-assignment" do
|
255
|
+
Given(:script) { "@@foo += 1" }
|
256
|
+
When { collector.run }
|
257
|
+
Then { expect(collector.findings.size).to eq(1) }
|
258
|
+
Then { expect(collector.findings.first.message).to be =~ /\(@@foo\)/ }
|
259
|
+
end
|
245
260
|
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
261
|
+
context "instance variable op-assignment" do
|
262
|
+
Given(:script) { "@foo += 1" }
|
263
|
+
When { collector.run }
|
264
|
+
Then { expect(collector.findings.size).to eq(1) }
|
265
|
+
Then { expect(collector.findings.first.message).to be =~ /\(@foo\)/ }
|
251
266
|
end
|
252
267
|
|
253
268
|
context "attribute op-assignment" do
|
254
269
|
Given(:script) { "foo.bar += 1" }
|
255
270
|
When { collector.run }
|
256
|
-
Then { collector.findings.size.
|
271
|
+
Then { expect(collector.findings.size).to eq(1) }
|
272
|
+
Then { expect(collector.findings.first.message).to be =~ /\(bar\)/ }
|
257
273
|
end
|
258
274
|
|
259
275
|
context "element op-assignment" do
|
260
276
|
Given(:script) { "foo[bar] += 1" }
|
261
277
|
When { collector.run }
|
262
|
-
Then { collector.findings.size.
|
278
|
+
Then { expect(collector.findings.size).to eq(1) }
|
279
|
+
Then { expect(collector.findings.first.message).to be =~ /\(foo\[bar\]\)/ }
|
280
|
+
end
|
281
|
+
|
282
|
+
context "ignores simple inst assignment" do
|
283
|
+
Given(:script) { "@foo = 1" }
|
284
|
+
When { collector.run }
|
285
|
+
Then { expect(collector.findings.size).to eq(0) }
|
286
|
+
end
|
287
|
+
|
288
|
+
context "ignores simple cvar assignment" do
|
289
|
+
Given(:script) { "@@foo = 1" }
|
290
|
+
When { collector.run }
|
291
|
+
Then { expect(collector.findings.size).to eq(0) }
|
263
292
|
end
|
264
293
|
end
|
265
294
|
end
|