1
0
Fork 0
mirror of https://github.com/rubyjs/mini_racer synced 2023-03-27 23:21:28 -04:00

Merge pull request #16 from seanmakesgames/datetime

DateTime marshalling
This commit is contained in:
Sam 2016-06-08 11:57:50 +10:00
commit f3bf50ce72
2 changed files with 47 additions and 2 deletions

View file

@ -47,6 +47,8 @@ static VALUE rb_eParseError;
static VALUE rb_eScriptRuntimeError; static VALUE rb_eScriptRuntimeError;
static VALUE rb_cJavaScriptFunction; static VALUE rb_cJavaScriptFunction;
static VALUE rb_cDateTime = Qnil;
static Platform* current_platform = NULL; static Platform* current_platform = NULL;
static void init_v8() { static void init_v8() {
@ -265,8 +267,13 @@ static Handle<Value> convert_ruby_to_v8(Isolate* isolate, VALUE value) {
return scope.Escape(String::NewFromUtf8(isolate, RSTRING_PTR(value), NewStringType::kNormal, (int)RSTRING_LEN(value)).ToLocalChecked()); return scope.Escape(String::NewFromUtf8(isolate, RSTRING_PTR(value), NewStringType::kNormal, (int)RSTRING_LEN(value)).ToLocalChecked());
case T_DATA: case T_DATA:
klass = rb_funcall(value, rb_intern("class"), 0); klass = rb_funcall(value, rb_intern("class"), 0);
if (klass == rb_cTime) if (klass == rb_cTime || klass == rb_cDateTime)
{ {
if (klass == rb_cDateTime)
{
value = rb_funcall(value, rb_intern("to_time"), 0);
}
value = rb_funcall(value, rb_intern("to_f"), 0); value = rb_funcall(value, rb_intern("to_f"), 0);
return scope.Escape(Date::New(isolate, NUM2DBL(value) * 1000)); return scope.Escape(Date::New(isolate, NUM2DBL(value) * 1000));
} }
@ -596,6 +603,11 @@ VALUE allocate(VALUE klass) {
context_info->context = new Persistent<Context>(); context_info->context = new Persistent<Context>();
context_info->context->Reset(context_info->isolate, context); context_info->context->Reset(context_info->isolate, context);
if (Qnil == rb_cDateTime && rb_funcall(rb_cObject, rb_intern("const_defined?"), 1, rb_str_new2("DateTime")) == Qtrue)
{
rb_cDateTime = rb_const_get(rb_cObject, rb_intern("DateTime"));
}
return Data_Wrap_Struct(klass, NULL, deallocate, (void*)context_info); return Data_Wrap_Struct(klass, NULL, deallocate, (void*)context_info);
} }

View file

@ -179,7 +179,9 @@ raise FooError, "I like foos"
def test_return_date def test_return_date
context = MiniRacer::Context.new context = MiniRacer::Context.new
test_time = Time.new test_time = Time.new
test_datetime = test_time.to_datetime
context.attach("test", proc{test_time}) context.attach("test", proc{test_time})
context.attach("test_datetime", proc{test_datetime})
# check that marshalling to JS creates a date object (getTime()) # check that marshalling to JS creates a date object (getTime())
assert_equal((test_time.to_f*1000).to_i, context.eval("var result = test(); result.getTime();").to_i) assert_equal((test_time.to_f*1000).to_i, context.eval("var result = test(); result.getTime();").to_i)
@ -191,6 +193,28 @@ raise FooError, "I like foos"
# check that no precision is lost in the marshalling (js only stores milliseconds) # check that no precision is lost in the marshalling (js only stores milliseconds)
assert_equal((test_time.tv_usec/1000.0).floor, (result.tv_usec/1000.0).floor) assert_equal((test_time.tv_usec/1000.0).floor, (result.tv_usec/1000.0).floor)
# check that DateTime gets marshalled to js date and back out as rb Time
result = context.eval("test_datetime()")
assert_equal(test_time.class, result.class)
assert_equal(test_time.tv_sec, result.tv_sec)
assert_equal((test_time.tv_usec/1000.0).floor, (result.tv_usec/1000.0).floor)
end
def test_datetime_missing
Object.send(:remove_const, :DateTime)
# no exceptions should happen here, and non-datetime classes should marshall correctly still.
context = MiniRacer::Context.new
test_time = Time.new
context.attach("test", proc{test_time})
assert_equal((test_time.to_f*1000).to_i, context.eval("var result = test(); result.getTime();").to_i)
result = context.eval("test()")
assert_equal(test_time.class, result.class)
assert_equal(test_time.tv_sec, result.tv_sec)
assert_equal((test_time.tv_usec/1000.0).floor, (result.tv_usec/1000.0).floor)
end end
def test_return_large_number def test_return_large_number
@ -213,7 +237,16 @@ raise FooError, "I like foos"
def test_return_unknown def test_return_unknown
context = MiniRacer::Context.new context = MiniRacer::Context.new
test_unknown = DateTime.new # hits T_DATA in convert_ruby_to_v8 test_unknown = Date.new # hits T_DATA in convert_ruby_to_v8
context.attach("test", proc{test_unknown})
assert_equal("Undefined Conversion", context.eval("test()"))
# clean up and start up a new context
context = nil
GC.start
context = MiniRacer::Context.new
test_unknown = Date.new # hits T_DATA in convert_ruby_to_v8
context.attach("test", proc{test_unknown}) context.attach("test", proc{test_unknown})
assert_equal("Undefined Conversion", context.eval("test()")) assert_equal("Undefined Conversion", context.eval("test()"))
end end