From b0321a604315d272f2f0d26d771ff7ceddfdbdec Mon Sep 17 00:00:00 2001 From: Larry Clapp <larry@theclapp.org> Date: Fri, 26 Oct 2018 01:32:27 +0000 Subject: [PATCH] syscall/js: add the Value.Truthy method Truthy returns the JavaScript "truthiness" of the given value. In JavaScript, false, 0, "", null, undefined, and NaN are "falsy", and everything else is "truthy". Fixes #28264 Change-Id: I4586f98646c05a4147d06a7c4a5d9c61d956fc83 GitHub-Last-Rev: 649b353ebc23b09d840faf927a2eeca41ee164bf GitHub-Pull-Request: golang/go#28358 Reviewed-on: https://go-review.googlesource.com/c/144384 Reviewed-by: Richard Musiol <neelance@gmail.com> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Richard Musiol <neelance@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> --- src/syscall/js/js.go | 20 +++++++++++++++ src/syscall/js/js_test.go | 54 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/src/syscall/js/js.go b/src/syscall/js/js.go index dc741e79a7e..19cdedc309a 100644 --- a/src/syscall/js/js.go +++ b/src/syscall/js/js.go @@ -370,6 +370,26 @@ func (v Value) Bool() bool { } } +// Truthy returns the JavaScript "truthiness" of the value v. In JavaScript, +// false, 0, "", null, undefined, and NaN are "falsy", and everything else is +// "truthy". See https://developer.mozilla.org/en-US/docs/Glossary/Truthy. +func (v Value) Truthy() bool { + switch v.Type() { + case TypeUndefined, TypeNull: + return false + case TypeBoolean: + return v.Bool() + case TypeNumber: + return v.ref != valueNaN.ref && v.ref != valueZero.ref + case TypeString: + return v.String() != "" + case TypeSymbol, TypeFunction, TypeObject: + return true + default: + panic("bad type") + } +} + // String returns the value v converted to string according to JavaScript type conversions. func (v Value) String() string { str, length := valuePrepareString(v.ref) diff --git a/src/syscall/js/js_test.go b/src/syscall/js/js_test.go index ed39fe37141..73d112a2e8f 100644 --- a/src/syscall/js/js_test.go +++ b/src/syscall/js/js_test.go @@ -4,6 +4,15 @@ // +build js,wasm +// To run these tests: +// +// - Install Node +// - Add /path/to/go/misc/wasm to your $PATH (so that "go test" can find +// "go_js_wasm_exec"). +// - GOOS=js GOARCH=wasm go test +// +// See -exec in "go help test", and "go help run" for details. + package js_test import ( @@ -19,11 +28,19 @@ var dummys = js.Global().Call("eval", `({ someInt: 42, someFloat: 42.123, someArray: [41, 42, 43], + someDate: new Date(), add: function(a, b) { return a + b; }, zero: 0, + stringZero: "0", NaN: NaN, + emptyObj: {}, + emptyArray: [], + Infinity: Infinity, + NegInfinity: -Infinity, + objNumber0: new Number(0), + objBooleanFalse: new Boolean(false), })`) func TestBool(t *testing.T) { @@ -331,3 +348,40 @@ func ExampleNewCallback() { }) js.Global().Get("document").Call("getElementById", "myButton").Call("addEventListener", "click", cb) } + +// See +// - https://developer.mozilla.org/en-US/docs/Glossary/Truthy +// - https://stackoverflow.com/questions/19839952/all-falsey-values-in-javascript/19839953#19839953 +// - http://www.ecma-international.org/ecma-262/5.1/#sec-9.2 +func TestTruthy(t *testing.T) { + want := true + for _, key := range []string{ + "someBool", "someString", "someInt", "someFloat", "someArray", "someDate", + "stringZero", // "0" is truthy + "add", // functions are truthy + "emptyObj", "emptyArray", "Infinity", "NegInfinity", + // All objects are truthy, even if they're Number(0) or Boolean(false). + "objNumber0", "objBooleanFalse", + } { + if got := dummys.Get(key).Truthy(); got != want { + t.Errorf("%s: got %#v, want %#v", key, got, want) + } + } + + want = false + if got := dummys.Get("zero").Truthy(); got != want { + t.Errorf("got %#v, want %#v", got, want) + } + if got := dummys.Get("NaN").Truthy(); got != want { + t.Errorf("got %#v, want %#v", got, want) + } + if got := js.ValueOf("").Truthy(); got != want { + t.Errorf("got %#v, want %#v", got, want) + } + if got := js.Null().Truthy(); got != want { + t.Errorf("got %#v, want %#v", got, want) + } + if got := js.Undefined().Truthy(); got != want { + t.Errorf("got %#v, want %#v", got, want) + } +} -- GitLab