diff --git a/src/syscall/js/js.go b/src/syscall/js/js.go index bccf188fa5..0acc7da9bf 100644 --- a/src/syscall/js/js.go +++ b/src/syscall/js/js.go @@ -422,9 +422,35 @@ func (v Value) Truthy() bool { } } -// String returns the value v converted to string according to JavaScript type conversions. +// String returns the value v as a string. +// String is a special case because of Go's String method convention. Unlike the other getters, +// it does not panic if v's Type is not TypeString. Instead, it returns a string of the form "" +// or "" where T is v's type and V is a string representation of v's value. func (v Value) String() string { - str, length := valuePrepareString(v.ref) + switch v.Type() { + case TypeString: + return jsString(v.ref) + case TypeUndefined: + return "" + case TypeNull: + return "" + case TypeBoolean: + return "" + case TypeNumber: + return "" + case TypeSymbol: + return "" + case TypeObject: + return "" + case TypeFunction: + return "" + default: + panic("bad type") + } +} + +func jsString(v ref) string { + str, length := valuePrepareString(v) b := make([]byte, length) valueLoadString(str, b) return string(b) diff --git a/src/syscall/js/js_test.go b/src/syscall/js/js_test.go index 594284faf9..20ccac7779 100644 --- a/src/syscall/js/js_test.go +++ b/src/syscall/js/js_test.go @@ -72,10 +72,26 @@ func TestString(t *testing.T) { t.Errorf("same value not equal") } - wantInt := "42" - o = dummys.Get("someInt") - if got := o.String(); got != wantInt { - t.Errorf("got %#v, want %#v", got, wantInt) + if got, want := js.Undefined().String(), ""; got != want { + t.Errorf("got %#v, want %#v", got, want) + } + if got, want := js.Null().String(), ""; got != want { + t.Errorf("got %#v, want %#v", got, want) + } + if got, want := js.ValueOf(true).String(), ""; got != want { + t.Errorf("got %#v, want %#v", got, want) + } + if got, want := js.ValueOf(42.5).String(), ""; got != want { + t.Errorf("got %#v, want %#v", got, want) + } + if got, want := js.Global().Call("Symbol").String(), ""; got != want { + t.Errorf("got %#v, want %#v", got, want) + } + if got, want := js.Global().String(), ""; got != want { + t.Errorf("got %#v, want %#v", got, want) + } + if got, want := js.Global().Get("setTimeout").String(), ""; got != want { + t.Errorf("got %#v, want %#v", got, want) } }