2016-05-04 02:54:51 -04:00
|
|
|
require 'test_helper'
|
|
|
|
|
|
|
|
class MiniRacerTest < Minitest::Test
|
2016-05-10 03:25:42 -04:00
|
|
|
|
2016-05-04 02:54:51 -04:00
|
|
|
def test_that_it_has_a_version_number
|
|
|
|
refute_nil ::MiniRacer::VERSION
|
|
|
|
end
|
|
|
|
|
2016-05-11 05:35:46 -04:00
|
|
|
def test_types
|
2016-05-04 02:54:51 -04:00
|
|
|
context = MiniRacer::Context.new
|
2016-05-11 05:35:46 -04:00
|
|
|
assert_equal 2, context.eval('2')
|
|
|
|
assert_equal "two", context.eval('"two"')
|
|
|
|
assert_equal 2.1, context.eval('2.1')
|
|
|
|
assert_equal true, context.eval('true')
|
|
|
|
assert_equal false, context.eval('false')
|
|
|
|
assert_equal nil, context.eval('null')
|
|
|
|
assert_equal nil, context.eval('undefined')
|
2016-05-04 02:54:51 -04:00
|
|
|
end
|
|
|
|
|
2016-05-11 05:35:46 -04:00
|
|
|
def test_array
|
2016-05-04 02:54:51 -04:00
|
|
|
context = MiniRacer::Context.new
|
2016-05-11 05:35:46 -04:00
|
|
|
assert_equal [1,"two"], context.eval('[1,"two"]')
|
2016-05-04 02:54:51 -04:00
|
|
|
end
|
|
|
|
|
2016-05-11 19:38:47 -04:00
|
|
|
def test_object
|
|
|
|
context = MiniRacer::Context.new
|
|
|
|
# remember JavaScript is quirky {"1" : 1} magically turns to {1: 1} cause magic
|
|
|
|
assert_equal({1 => 2, "two" => "two"}, context.eval('a={"1" : 2, "two" : "two"}'))
|
|
|
|
end
|
|
|
|
|
2016-05-11 03:02:20 -04:00
|
|
|
def test_it_returns_runtime_error
|
2016-05-04 02:54:51 -04:00
|
|
|
context = MiniRacer::Context.new
|
2016-05-11 03:02:20 -04:00
|
|
|
exp = nil
|
|
|
|
|
|
|
|
begin
|
|
|
|
context.eval('var foo=function(){boom;}; foo()')
|
|
|
|
rescue => e
|
|
|
|
exp = e
|
2016-05-04 02:54:51 -04:00
|
|
|
end
|
2016-05-11 03:02:20 -04:00
|
|
|
|
2016-05-11 20:14:33 -04:00
|
|
|
assert_equal MiniRacer::RuntimeError, exp.class
|
2016-05-11 03:02:20 -04:00
|
|
|
|
|
|
|
assert_match(/boom/, exp.message)
|
|
|
|
assert_match(/foo/, exp.backtrace[0])
|
|
|
|
assert_match(/mini_racer/, exp.backtrace[2])
|
|
|
|
|
2016-05-10 03:25:42 -04:00
|
|
|
# context should not be dead
|
|
|
|
assert_equal 2, context.eval('1+1')
|
2016-05-04 02:54:51 -04:00
|
|
|
end
|
|
|
|
|
2016-05-05 23:14:37 -04:00
|
|
|
def test_it_can_stop
|
|
|
|
context = MiniRacer::Context.new
|
2016-05-11 03:02:20 -04:00
|
|
|
exp = nil
|
|
|
|
|
|
|
|
begin
|
2016-05-05 23:14:37 -04:00
|
|
|
Thread.new do
|
|
|
|
sleep 0.001
|
|
|
|
context.stop
|
|
|
|
end
|
|
|
|
context.eval('while(true){}')
|
2016-05-11 03:02:20 -04:00
|
|
|
rescue => e
|
|
|
|
exp = e
|
2016-05-05 23:14:37 -04:00
|
|
|
end
|
2016-05-11 03:02:20 -04:00
|
|
|
|
2016-05-11 20:14:33 -04:00
|
|
|
assert_equal MiniRacer::ScriptTerminatedError, exp.class
|
2016-05-11 03:02:20 -04:00
|
|
|
assert_match(/terminated/, exp.message)
|
|
|
|
|
2016-05-05 23:14:37 -04:00
|
|
|
end
|
|
|
|
|
2016-05-06 03:08:06 -04:00
|
|
|
def test_it_can_automatically_time_out_context
|
|
|
|
# 2 millisecs is a very short timeout but we don't want test running forever
|
|
|
|
context = MiniRacer::Context.new(timeout: 2)
|
|
|
|
assert_raises do
|
|
|
|
context.eval('while(true){}')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-05-11 20:59:18 -04:00
|
|
|
def test_returns_javascript_function
|
|
|
|
context = MiniRacer::Context.new
|
|
|
|
assert_equal MiniRacer::JavaScriptFunction, context.eval("a = function(){}").class
|
|
|
|
end
|
|
|
|
|
2016-05-05 23:14:37 -04:00
|
|
|
def test_it_handles_malformed_js
|
|
|
|
context = MiniRacer::Context.new
|
2016-05-11 20:14:33 -04:00
|
|
|
assert_raises MiniRacer::ParseError do
|
2016-05-05 23:14:37 -04:00
|
|
|
context.eval('I am not JavaScript {')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-05-04 02:54:51 -04:00
|
|
|
def test_it_remembers_stuff_in_context
|
|
|
|
context = MiniRacer::Context.new
|
|
|
|
context.eval('var x = function(){return 22;}')
|
|
|
|
assert_equal 22, context.eval('x()')
|
|
|
|
end
|
|
|
|
|
2016-05-08 06:59:10 -04:00
|
|
|
def test_can_attach_functions
|
|
|
|
context = MiniRacer::Context.new
|
|
|
|
context.attach("adder", proc{|a,b| a+b})
|
|
|
|
assert_equal 3, context.eval('adder(1,2)')
|
|
|
|
end
|
|
|
|
|
2016-05-10 03:35:30 -04:00
|
|
|
def test_es6_arrow_functions
|
|
|
|
context = MiniRacer::Context.new
|
2016-05-10 04:30:37 -04:00
|
|
|
assert_equal 42, context.eval('adder=(x,y)=>x+y; adder(21,21);')
|
2016-05-10 03:35:30 -04:00
|
|
|
end
|
|
|
|
|
2016-05-10 22:26:52 -04:00
|
|
|
def test_concurrent_access
|
|
|
|
context = MiniRacer::Context.new
|
|
|
|
context.eval('counter=0; plus=()=>counter++;')
|
2016-05-10 04:06:40 -04:00
|
|
|
|
2016-05-10 22:26:52 -04:00
|
|
|
(1..10).map do
|
|
|
|
Thread.new {
|
|
|
|
context.eval("plus()")
|
|
|
|
}
|
|
|
|
end.each(&:join)
|
|
|
|
|
|
|
|
assert_equal 10, context.eval("counter")
|
|
|
|
end
|
|
|
|
|
2016-05-11 03:58:33 -04:00
|
|
|
class FooError < StandardError
|
|
|
|
def initialize(message)
|
|
|
|
super(message)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-05-10 22:26:52 -04:00
|
|
|
def test_attached_exceptions
|
2016-05-10 04:06:40 -04:00
|
|
|
context = MiniRacer::Context.new
|
2016-05-11 03:58:33 -04:00
|
|
|
context.attach("adder", proc{ raise FooError, "I like foos" })
|
2016-05-10 04:06:40 -04:00
|
|
|
assert_raises do
|
2016-05-11 03:58:33 -04:00
|
|
|
begin
|
|
|
|
raise FooError, "I like foos"
|
|
|
|
context.eval('adder()')
|
|
|
|
rescue => e
|
|
|
|
assert_equal FooError, e.class
|
|
|
|
assert_match( /I like foos/, e.message)
|
|
|
|
# TODO backtrace splicing so js frames are injected
|
|
|
|
raise
|
|
|
|
end
|
2016-05-10 04:06:40 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-05-16 21:34:24 -04:00
|
|
|
def test_attached_on_object
|
|
|
|
context = MiniRacer::Context.new
|
|
|
|
context.attach("minion.speak", proc{"banana"})
|
|
|
|
assert_equal "banana", context.eval("minion.speak()")
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_attached_on_nested_object
|
|
|
|
context = MiniRacer::Context.new
|
|
|
|
context.attach("minion.kevin.speak", proc{"banana"})
|
|
|
|
assert_equal "banana", context.eval("minion.kevin.speak()")
|
|
|
|
end
|
|
|
|
|
2016-05-19 02:17:20 -04:00
|
|
|
def test_return_arrays
|
|
|
|
context = MiniRacer::Context.new
|
|
|
|
context.attach("nose.type", proc{["banana",["nose"]]})
|
|
|
|
assert_equal ["banana", ["nose"]], context.eval("nose.type()")
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_return_hash
|
|
|
|
context = MiniRacer::Context.new
|
|
|
|
context.attach("test", proc{{banana: :nose, "inner" => {42 => 42}}})
|
|
|
|
assert_equal({"banana" => "nose", "inner" => {42 => 42}}, context.eval("test()"))
|
|
|
|
end
|
|
|
|
|
|
|
|
module Echo
|
|
|
|
def self.say(thing)
|
|
|
|
thing
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_can_attach_method
|
|
|
|
context = MiniRacer::Context.new
|
|
|
|
context.attach("Echo.say", Echo.method(:say))
|
|
|
|
assert_equal "hello", context.eval("Echo.say('hello')")
|
|
|
|
end
|
|
|
|
|
2016-05-18 23:11:39 -04:00
|
|
|
def test_attach_error
|
|
|
|
context = MiniRacer::Context.new
|
|
|
|
context.eval("minion = 2")
|
|
|
|
assert_raises do
|
|
|
|
begin
|
|
|
|
context.attach("minion.kevin.speak", proc{"banana"})
|
|
|
|
rescue => e
|
|
|
|
assert_equal MiniRacer::ParseError, e.class
|
|
|
|
assert_match(/expecting minion.kevin/, e.message)
|
|
|
|
raise
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
2016-05-16 20:47:21 -04:00
|
|
|
def test_load
|
|
|
|
context = MiniRacer::Context.new
|
|
|
|
context.load(File.dirname(__FILE__) + "/file.js")
|
|
|
|
assert_equal "world", context.eval("hello")
|
|
|
|
assert_raises do
|
|
|
|
context.load(File.dirname(__FILE__) + "/missing.js")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-05-04 02:54:51 -04:00
|
|
|
end
|