jruby-lint 0.4.1 → 0.9.0
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 +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
|