From f2a7f63d899662ea5e8e74e2b55dc6564e851207 Mon Sep 17 00:00:00 2001 From: Dmitri Shuralyov Date: Mon, 31 Aug 2015 02:08:14 -0700 Subject: [PATCH 1/4] Add TestInternalizeExternalizeNull. It's just like TestInternalizeExternalizeUndefined, but for null. It helped me uncover a bug in internalization code during development, and seems like a good idea to have it for better coverage. --- js/js_test.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/js/js_test.go b/js/js_test.go index 754fb1a1b..2aa839226 100644 --- a/js/js_test.go +++ b/js/js_test.go @@ -480,6 +480,21 @@ func TestNewArrayBuffer(t *testing.T) { } } +func TestInternalizeExternalizeNull(t *testing.T) { + type S struct { + *js.Object + } + r := js.Global.Call("eval", "(function(f) { return f(null); })").Invoke(func(s S) S { + if s.Object != nil { + t.Fail() + } + return s + }) + if r != nil { + t.Fail() + } +} + func TestInternalizeExternalizeUndefined(t *testing.T) { type S struct { *js.Object From 6cc2b7bc18f0f3ea806a7e7b5d2a8f69dd9ed92f Mon Sep 17 00:00:00 2001 From: Dmitri Shuralyov Date: Mon, 31 Aug 2015 02:10:28 -0700 Subject: [PATCH 2/4] Add failing test for internalization of Date into time.Time struct. Test case for https://github.com/gopherjs/gopherjs/issues/287, currently failing. --- js/js_test.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/js/js_test.go b/js/js_test.go index 2aa839226..189776525 100644 --- a/js/js_test.go +++ b/js/js_test.go @@ -287,6 +287,17 @@ func TestDate(t *testing.T) { } } +// https://github.com/gopherjs/gopherjs/issues/287 +func TestInternalizeDate(t *testing.T) { + var a = time.Unix(0, (123 * time.Millisecond).Nanoseconds()) + var b time.Time + js.Global.Set("internalizeDate", func(t time.Time) { b = t }) + js.Global.Call("eval", "(internalizeDate(new Date(123)))") + if a != b { + t.Fail() + } +} + func TestEquality(t *testing.T) { if js.Global.Get("Array") != js.Global.Get("Array") || js.Global.Get("Array") == js.Global.Get("String") { t.Fail() From 55f8e77931ba841edcc9ac65be0d68e716ed136a Mon Sep 17 00:00:00 2001 From: Dmitri Shuralyov Date: Mon, 31 Aug 2015 01:56:39 -0700 Subject: [PATCH 3/4] Fix internalize case for Date into time.Time struct. Fixes #287. --- compiler/prelude/jsmapping.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/compiler/prelude/jsmapping.go b/compiler/prelude/jsmapping.go index 24cdf8ed3..3cba9ead1 100644 --- a/compiler/prelude/jsmapping.go +++ b/compiler/prelude/jsmapping.go @@ -315,6 +315,13 @@ var $internalize = function(v, t, recv) { } return s; case $kindStruct: + if (v !== null && v !== undefined && v.constructor === Date) { + var timePkg = $packages["time"]; + if (timePkg !== undefined && t === timePkg.Time) { + return timePkg.Unix(new $Int64(0, 0), new $Int64(0, v.getTime() * 1000000)); + } + } + var noJsObject = {}; var searchJsObject = function(t) { if (t === $jsObjectPtr) { From fc96db63e7b69e6526eddf810cfb15019d835138 Mon Sep 17 00:00:00 2001 From: Dmitri Shuralyov Date: Tue, 1 Sep 2015 23:33:23 -0700 Subject: [PATCH 4/4] Handle t === timePkg.Time case on its own. Refactor based on suggestion at https://github.com/gopherjs/gopherjs/issues/287#issuecomment-136315076. Panic on null or undefined values instead of Date, no support for *time.Time. Remove unneeded declaration. The same variable is already declared in parent scope. --- compiler/prelude/jsmapping.go | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/compiler/prelude/jsmapping.go b/compiler/prelude/jsmapping.go index 3cba9ead1..ce0691b5a 100644 --- a/compiler/prelude/jsmapping.go +++ b/compiler/prelude/jsmapping.go @@ -181,6 +181,13 @@ var $internalize = function(v, t, recv) { if (t === $jsObjectPtr.elem) { $panic(new $String("cannot internalize js.Object, use *js.Object instead")); } + var timePkg = $packages["time"]; + if (timePkg !== undefined && t === timePkg.Time) { + if (!(v !== null && v !== undefined && v.constructor === Date)) { + $panic(new $String("cannot internalize time.Time from " + typeof v + ", must be Date")); + } + return timePkg.Unix(new $Int64(0, 0), new $Int64(0, v.getTime() * 1000000)); + } switch (t.kind) { case $kindBool: return !!v; @@ -270,12 +277,11 @@ var $internalize = function(v, t, recv) { case Boolean: return new $Bool(!!v); case Date: - var timePkg = $packages["time"]; if (timePkg === undefined) { /* time package is not present, internalize as &js.Object{Date} so it can be externalized into original Date. */ return new $jsObjectPtr(v); } - return new timePkg.Time(timePkg.Unix(new $Int64(0, 0), new $Int64(0, v.getTime() * 1000000))); + return new timePkg.Time($internalize(v, timePkg.Time)); case Function: var funcType = $funcType([$sliceType($emptyInterface)], [$jsObjectPtr], true); return new funcType($internalize(v, funcType)); @@ -315,13 +321,6 @@ var $internalize = function(v, t, recv) { } return s; case $kindStruct: - if (v !== null && v !== undefined && v.constructor === Date) { - var timePkg = $packages["time"]; - if (timePkg !== undefined && t === timePkg.Time) { - return timePkg.Unix(new $Int64(0, 0), new $Int64(0, v.getTime() * 1000000)); - } - } - var noJsObject = {}; var searchJsObject = function(t) { if (t === $jsObjectPtr) {