Skip to content
This repository has been archived by the owner on Nov 9, 2017. It is now read-only.

Commit

Permalink
Raising useful exceptions
Browse files Browse the repository at this point in the history
  • Loading branch information
marcandre authored and rgrove committed Dec 15, 2009
1 parent 5d4b18b commit 2760282
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 20 deletions.
2 changes: 1 addition & 1 deletion Rakefile
Expand Up @@ -26,7 +26,7 @@ require 'rake/rdoctask'

gemspec = Gem::Specification.new do |s|
s.name = 'jsmin'
s.version = '1.0.1'
s.version = '1.0.2'
s.author = 'Ryan Grove'
s.email = 'ryan@wonko.com'
s.homepage = 'http://github.com/rgrove/jsmin/'
Expand Down
51 changes: 32 additions & 19 deletions lib/jsmin.rb
Expand Up @@ -55,22 +55,30 @@ module JSMin
CHR_QUOTE = '"'.freeze
CHR_SPACE = ' '.freeze

if RUBY_VERSION >= '1.9'
ORD_LF = "\n".freeze
ORD_SPACE = ' '.freeze
ORD_TILDE = '~'.freeze
else
ORD_LF = "\n"[0].freeze
ORD_SPACE = ' '[0].freeze
ORD_TILDE = '~'[0].freeze
ORD_LF = "\n"[0].freeze
ORD_SPACE = ' '[0].freeze
ORD_TILDE = '~'[0].freeze

class ParseError < RuntimeError
attr_accessor :source, :line
def initialize(err, source, line)
@source = source,
@line = line
super "JSMin Parse Error: #{err} at line #{line} of #{source}"
end
end

class << self
def raise(err)
super ParseError.new(err, @source, @line)
end

# Reads JavaScript from _input_ (which can be a String or an IO object) and
# returns a String containing minified JS.
def minify(input)
@js = StringScanner.new(input.is_a?(IO) ? input.read : input.to_s)
@source = input.is_a?(IO) ? input.inspect : input.to_s[0..100]
@line = 1

@a = "\n"
@b = nil
Expand Down Expand Up @@ -147,15 +155,15 @@ def action_copy
break if @a == @b

if @a[0] <= ORD_LF
raise "JSMin parse error: unterminated string literal: #{@a}"
raise "unterminated string literal: #{@a.inspect}"
end

if @a == CHR_BACKSLASH
@output << @a
@a = get

if @a[0] <= ORD_LF
raise "JSMin parse error: unterminated string literal: #{@a}"
raise "unterminated string literal: #{@a.inspect}"
end
end
end
Expand All @@ -181,8 +189,7 @@ def action_get
@output << @a
@a = get
elsif @a[0] <= ORD_LF
raise "JSMin parse error: unterminated regular expression " +
"literal: #{@a}"
raise "unterminated regular expression : #{@a.inspect}"
end

@output << @a
Expand All @@ -201,12 +208,18 @@ def alphanum?(c)
# Returns the next character from the input. If the character is a control
# character, it will be translated to a space or linefeed.
def get
c = @lookahead.nil? ? @js.getch : @lookahead
@lookahead = nil

return c if c.nil? || c == CHR_LF || c[0] >= ORD_SPACE
return "\n" if c == CHR_CR
return ' '
if @lookahead
c = @lookahead
@lookahead = nil
else
c = @js.getch
if c == CHR_LF || c == CHR_CR
@line += 1
return CHR_LF
end
return ' ' unless c.nil? || c[0] >= ORD_SPACE
end
c
end

# Gets the next character, excluding comments.
Expand All @@ -232,7 +245,7 @@ def nextchar
end

when nil
raise 'JSMin parse error: unterminated comment'
raise 'unterminated comment'
end
end

Expand Down
4 changes: 4 additions & 0 deletions test/js/error.js
@@ -0,0 +1,4 @@
// This javascript is bad
var whatever;
whatever = "hello
function (
14 changes: 14 additions & 0 deletions test/test_exception.rb
@@ -0,0 +1,14 @@
require File.expand_path(File.dirname(__FILE__) + "/../lib/jsmin")
require 'test/unit'

class ExceptionTest < Test::Unit::TestCase
def test_exception
File.open("js/error.js") do |i|
JSMin.minify(i)
end
assert_raise {}
rescue JSMin::ParseError => e
assert_equal %q{JSMin Parse Error: unterminated string literal: "\n" at line 4 of #<File:js/error.js>},
e.to_s
end
end

0 comments on commit 2760282

Please sign in to comment.