Skip to content

Commit

Permalink
FEATURE: add support for activesupport dates
Browse files Browse the repository at this point in the history
  • Loading branch information
SamSaffron committed Mar 5, 2025
1 parent f4745f3 commit 3652c97
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 25 deletions.
14 changes: 14 additions & 0 deletions ext/mini_racer_extension/mini_racer_extension.c
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,20 @@ static int serialize1(Ser *s, VALUE refs, VALUE v)
case T_STRING:
add_string(s, v);
break;
case T_OBJECT:
// this is somewhat wide, but we have active support which creates
// entirely new objects
if (rb_respond_to(v, rb_intern("to_time"))) {
v = rb_funcall(v, rb_intern("to_time"), 0);
}
if (rb_obj_is_kind_of(v, rb_cTime)) {
struct timeval tv = rb_time_timeval(v);
ser_date(s, tv.tv_sec*1e3 + tv.tv_usec/1e3);
} else {
snprintf(s->err, sizeof(s->err), "unsupported type %s", rb_class2name(CLASS_OF(v)));
return -1;
}
break;
default:
snprintf(s->err, sizeof(s->err), "unsupported type %x", TYPE(v));
return -1;
Expand Down
1 change: 1 addition & 0 deletions mini_racer.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ Gem::Specification.new do |spec|
spec.add_development_dependency "rake", ">= 12.3.3"
spec.add_development_dependency "minitest", "~> 5.0"
spec.add_development_dependency "rake-compiler"
spec.add_development_dependency "activesupport", "> 6"
spec.add_development_dependency "m"

spec.add_dependency "libv8-node", MiniRacer::LIBV8_NODE_VERSION
Expand Down
54 changes: 29 additions & 25 deletions test/mini_racer_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -262,9 +262,7 @@ def test_return_hash
def test_date_nan
# NoMethodError: undefined method `source_location' for "<internal:core>
# core/float.rb:114:in `to_i'":Thread::Backtrace::Location
if RUBY_ENGINE == "truffleruby"
skip "TruffleRuby bug"
end
skip "TruffleRuby bug" if RUBY_ENGINE == "truffleruby"
context = MiniRacer::Context.new
assert_raises(RangeError) { context.eval("new Date(NaN)") } # should not crash process
end
Expand Down Expand Up @@ -893,11 +891,14 @@ def test_wasm_ref
end
context = MiniRacer::Context.new
expected = {}
actual = context.eval("
actual =
context.eval(
"
var b = [0,97,115,109,1,0,0,0,1,26,5,80,0,95,0,80,0,95,1,127,0,96,0,1,110,96,1,100,2,1,111,96,0,1,100,3,3,4,3,3,2,4,7,26,2,12,99,114,101,97,116,101,83,116,114,117,99,116,0,1,7,114,101,102,70,117,110,99,0,2,9,5,1,3,0,1,0,10,23,3,8,0,32,0,20,2,251,27,11,7,0,65,12,251,0,1,11,4,0,210,0,11,0,44,4,110,97,109,101,1,37,3,0,11,101,120,112,111,114,116,101,100,65,110,121,1,12,99,114,101,97,116,101,83,116,114,117,99,116,2,7,114,101,102,70,117,110,99]
var o = new WebAssembly.Instance(new WebAssembly.Module(new Uint8Array(b))).exports
o.refFunc()(o.createStruct) // exotic object
")
"
)
assert_equal expected, actual
end

Expand All @@ -923,7 +924,7 @@ def test_proxy_support

def test_proxy_uncloneable
context = MiniRacer::Context.new()
expected = {"x" => 42}
expected = { "x" => 42 }
assert_equal expected, context.eval(<<~JS)
const o = {x: 42}
const p = new Proxy(o, {})
Expand Down Expand Up @@ -1031,9 +1032,7 @@ def test_forking
skip "TruffleRuby forking is not supported"
else
`bundle exec ruby test/test_forking.rb`
if $?.exitstatus != 0
assert false, "forking test failed"
end
assert false, "forking test failed" if $?.exitstatus != 0
end
end

Expand All @@ -1053,19 +1052,22 @@ def test_poison

def test_map
context = MiniRacer::Context.new
expected = {"x" => 42, "y" => 43}
expected = { "x" => 42, "y" => 43 }
assert_equal expected, context.eval("new Map([['x', 42], ['y', 43]])")
if RUBY_ENGINE == "truffleruby"
# See https://github.com/rubyjs/mini_racer/pull/325#discussion_r1907187166
expected = [["x", 42], ["y", 43]]
else
expected = ["x", 42, "y", 43]
end
assert_equal expected, context.eval("new Map([['x', 42], ['y', 43]]).entries()")
expected = ["x", "y"]
assert_equal expected, context.eval("new Map([['x', 42], ['y', 43]]).keys()")
assert_equal expected,
context.eval("new Map([['x', 42], ['y', 43]]).entries()")
expected = %w[x y]
assert_equal expected,
context.eval("new Map([['x', 42], ['y', 43]]).keys()")
expected = [[42], [43]]
assert_equal expected, context.eval("new Map([['x', [42]], ['y', [43]]]).values()")
assert_equal expected,
context.eval("new Map([['x', [42]], ['y', [43]]]).values()")
end

def test_regexp_string_iterator
Expand All @@ -1083,17 +1085,9 @@ def test_regexp_string_iterator
def test_function_property
context = MiniRacer::Context.new
if RUBY_ENGINE == "truffleruby"
expected = {
"m" => {1 => 2, 3 => 4},
"s" => {},
"x" => 42,
}
expected = { "m" => { 1 => 2, 3 => 4 }, "s" => {}, "x" => 42 }
else
expected = {
"m" => {1 => 2, 3 => 4},
"s" => [5, 7, 11, 13],
"x" => 42,
}
expected = { "m" => { 1 => 2, 3 => 4 }, "s" => [5, 7, 11, 13], "x" => 42 }
end
script = <<~JS
({
Expand All @@ -1106,6 +1100,16 @@ def test_function_property
assert_equal expected, context.eval(script)
end

def test_dates_from_active_support
require "active_support"
require "active_support/time"
context = MiniRacer::Context.new
Time.zone = "UTC"
time = Time.current
context.attach("f", proc { time })
assert_in_delta time.to_f, context.call("f").to_f, 0.001
end

def test_string_encoding
context = MiniRacer::Context.new
assert_equal "ä", context.eval("'ä'")
Expand All @@ -1124,7 +1128,7 @@ def test_object_ref
context = MiniRacer::Context.new
context.eval("function f(o) { return o }")
expected = {}
expected["a"] = expected["b"] = {"x" => 42}
expected["a"] = expected["b"] = { "x" => 42 }
actual = context.call("f", expected)
assert_equal actual, expected
end
Expand Down

0 comments on commit 3652c97

Please sign in to comment.