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:
commit
f3bf50ce72
2 changed files with 47 additions and 2 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Reference in a new issue