github.com/megatontech/mynoteforgo@v0.0.0-20200507084910-5d0c6ea6e890/源码/syscall/js/js_test.go (about) 1 // Copyright 2018 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // +build js,wasm 6 7 // To run these tests: 8 // 9 // - Install Node 10 // - Add /path/to/go/misc/wasm to your $PATH (so that "go test" can find 11 // "go_js_wasm_exec"). 12 // - GOOS=js GOARCH=wasm go test 13 // 14 // See -exec in "go help test", and "go help run" for details. 15 16 package js_test 17 18 import ( 19 "fmt" 20 "math" 21 "syscall/js" 22 "testing" 23 ) 24 25 var dummys = js.Global().Call("eval", `({ 26 someBool: true, 27 someString: "abc\u1234", 28 someInt: 42, 29 someFloat: 42.123, 30 someArray: [41, 42, 43], 31 someDate: new Date(), 32 add: function(a, b) { 33 return a + b; 34 }, 35 zero: 0, 36 stringZero: "0", 37 NaN: NaN, 38 emptyObj: {}, 39 emptyArray: [], 40 Infinity: Infinity, 41 NegInfinity: -Infinity, 42 objNumber0: new Number(0), 43 objBooleanFalse: new Boolean(false), 44 })`) 45 46 func TestBool(t *testing.T) { 47 want := true 48 o := dummys.Get("someBool") 49 if got := o.Bool(); got != want { 50 t.Errorf("got %#v, want %#v", got, want) 51 } 52 dummys.Set("otherBool", want) 53 if got := dummys.Get("otherBool").Bool(); got != want { 54 t.Errorf("got %#v, want %#v", got, want) 55 } 56 if dummys.Get("someBool") != dummys.Get("someBool") { 57 t.Errorf("same value not equal") 58 } 59 } 60 61 func TestString(t *testing.T) { 62 want := "abc\u1234" 63 o := dummys.Get("someString") 64 if got := o.String(); got != want { 65 t.Errorf("got %#v, want %#v", got, want) 66 } 67 dummys.Set("otherString", want) 68 if got := dummys.Get("otherString").String(); got != want { 69 t.Errorf("got %#v, want %#v", got, want) 70 } 71 if dummys.Get("someString") != dummys.Get("someString") { 72 t.Errorf("same value not equal") 73 } 74 75 wantInt := "42" 76 o = dummys.Get("someInt") 77 if got := o.String(); got != wantInt { 78 t.Errorf("got %#v, want %#v", got, wantInt) 79 } 80 } 81 82 func TestInt(t *testing.T) { 83 want := 42 84 o := dummys.Get("someInt") 85 if got := o.Int(); got != want { 86 t.Errorf("got %#v, want %#v", got, want) 87 } 88 dummys.Set("otherInt", want) 89 if got := dummys.Get("otherInt").Int(); got != want { 90 t.Errorf("got %#v, want %#v", got, want) 91 } 92 if dummys.Get("someInt") != dummys.Get("someInt") { 93 t.Errorf("same value not equal") 94 } 95 if got := dummys.Get("zero").Int(); got != 0 { 96 t.Errorf("got %#v, want %#v", got, 0) 97 } 98 } 99 100 func TestIntConversion(t *testing.T) { 101 testIntConversion(t, 0) 102 testIntConversion(t, 1) 103 testIntConversion(t, -1) 104 testIntConversion(t, 1<<20) 105 testIntConversion(t, -1<<20) 106 testIntConversion(t, 1<<40) 107 testIntConversion(t, -1<<40) 108 testIntConversion(t, 1<<60) 109 testIntConversion(t, -1<<60) 110 } 111 112 func testIntConversion(t *testing.T, want int) { 113 if got := js.ValueOf(want).Int(); got != want { 114 t.Errorf("got %#v, want %#v", got, want) 115 } 116 } 117 118 func TestFloat(t *testing.T) { 119 want := 42.123 120 o := dummys.Get("someFloat") 121 if got := o.Float(); got != want { 122 t.Errorf("got %#v, want %#v", got, want) 123 } 124 dummys.Set("otherFloat", want) 125 if got := dummys.Get("otherFloat").Float(); got != want { 126 t.Errorf("got %#v, want %#v", got, want) 127 } 128 if dummys.Get("someFloat") != dummys.Get("someFloat") { 129 t.Errorf("same value not equal") 130 } 131 } 132 133 func TestObject(t *testing.T) { 134 if dummys.Get("someArray") != dummys.Get("someArray") { 135 t.Errorf("same value not equal") 136 } 137 138 // An object and its prototype should not be equal. 139 proto := js.Global().Get("Object").Get("prototype") 140 o := js.Global().Call("eval", "new Object()") 141 if proto == o { 142 t.Errorf("object equals to its prototype") 143 } 144 } 145 146 func TestFrozenObject(t *testing.T) { 147 o := js.Global().Call("eval", "(function () { let o = new Object(); o.field = 5; Object.freeze(o); return o; })()") 148 want := 5 149 if got := o.Get("field").Int(); want != got { 150 t.Errorf("got %#v, want %#v", got, want) 151 } 152 } 153 154 func TestTypedArrayOf(t *testing.T) { 155 testTypedArrayOf(t, "[]int8", []int8{0, -42, 0}, -42) 156 testTypedArrayOf(t, "[]int16", []int16{0, -42, 0}, -42) 157 testTypedArrayOf(t, "[]int32", []int32{0, -42, 0}, -42) 158 testTypedArrayOf(t, "[]uint8", []uint8{0, 42, 0}, 42) 159 testTypedArrayOf(t, "[]uint16", []uint16{0, 42, 0}, 42) 160 testTypedArrayOf(t, "[]uint32", []uint32{0, 42, 0}, 42) 161 testTypedArrayOf(t, "[]float32", []float32{0, -42.5, 0}, -42.5) 162 testTypedArrayOf(t, "[]float64", []float64{0, -42.5, 0}, -42.5) 163 } 164 165 func testTypedArrayOf(t *testing.T, name string, slice interface{}, want float64) { 166 t.Run(name, func(t *testing.T) { 167 a := js.TypedArrayOf(slice) 168 got := a.Index(1).Float() 169 a.Release() 170 if got != want { 171 t.Errorf("got %#v, want %#v", got, want) 172 } 173 }) 174 } 175 176 func TestNaN(t *testing.T) { 177 want := js.ValueOf(math.NaN()) 178 got := dummys.Get("NaN") 179 if got != want { 180 t.Errorf("got %#v, want %#v", got, want) 181 } 182 } 183 184 func TestUndefined(t *testing.T) { 185 dummys.Set("test", js.Undefined()) 186 if dummys == js.Undefined() || dummys.Get("test") != js.Undefined() || dummys.Get("xyz") != js.Undefined() { 187 t.Errorf("js.Undefined expected") 188 } 189 } 190 191 func TestNull(t *testing.T) { 192 dummys.Set("test1", nil) 193 dummys.Set("test2", js.Null()) 194 if dummys == js.Null() || dummys.Get("test1") != js.Null() || dummys.Get("test2") != js.Null() { 195 t.Errorf("js.Null expected") 196 } 197 } 198 199 func TestLength(t *testing.T) { 200 if got := dummys.Get("someArray").Length(); got != 3 { 201 t.Errorf("got %#v, want %#v", got, 3) 202 } 203 } 204 205 func TestIndex(t *testing.T) { 206 if got := dummys.Get("someArray").Index(1).Int(); got != 42 { 207 t.Errorf("got %#v, want %#v", got, 42) 208 } 209 } 210 211 func TestSetIndex(t *testing.T) { 212 dummys.Get("someArray").SetIndex(2, 99) 213 if got := dummys.Get("someArray").Index(2).Int(); got != 99 { 214 t.Errorf("got %#v, want %#v", got, 99) 215 } 216 } 217 218 func TestCall(t *testing.T) { 219 var i int64 = 40 220 if got := dummys.Call("add", i, 2).Int(); got != 42 { 221 t.Errorf("got %#v, want %#v", got, 42) 222 } 223 if got := dummys.Call("add", js.Global().Call("eval", "40"), 2).Int(); got != 42 { 224 t.Errorf("got %#v, want %#v", got, 42) 225 } 226 } 227 228 func TestInvoke(t *testing.T) { 229 var i int64 = 40 230 if got := dummys.Get("add").Invoke(i, 2).Int(); got != 42 { 231 t.Errorf("got %#v, want %#v", got, 42) 232 } 233 } 234 235 func TestNew(t *testing.T) { 236 if got := js.Global().Get("Array").New(42).Length(); got != 42 { 237 t.Errorf("got %#v, want %#v", got, 42) 238 } 239 } 240 241 func TestInstanceOf(t *testing.T) { 242 someArray := js.Global().Get("Array").New() 243 if got, want := someArray.InstanceOf(js.Global().Get("Array")), true; got != want { 244 t.Errorf("got %#v, want %#v", got, want) 245 } 246 if got, want := someArray.InstanceOf(js.Global().Get("Function")), false; got != want { 247 t.Errorf("got %#v, want %#v", got, want) 248 } 249 } 250 251 func TestType(t *testing.T) { 252 if got, want := js.Undefined().Type(), js.TypeUndefined; got != want { 253 t.Errorf("got %s, want %s", got, want) 254 } 255 if got, want := js.Null().Type(), js.TypeNull; got != want { 256 t.Errorf("got %s, want %s", got, want) 257 } 258 if got, want := js.ValueOf(true).Type(), js.TypeBoolean; got != want { 259 t.Errorf("got %s, want %s", got, want) 260 } 261 if got, want := js.ValueOf(0).Type(), js.TypeNumber; got != want { 262 t.Errorf("got %s, want %s", got, want) 263 } 264 if got, want := js.ValueOf(42).Type(), js.TypeNumber; got != want { 265 t.Errorf("got %s, want %s", got, want) 266 } 267 if got, want := js.ValueOf("test").Type(), js.TypeString; got != want { 268 t.Errorf("got %s, want %s", got, want) 269 } 270 if got, want := js.Global().Get("Symbol").Invoke("test").Type(), js.TypeSymbol; got != want { 271 t.Errorf("got %s, want %s", got, want) 272 } 273 if got, want := js.Global().Get("Array").New().Type(), js.TypeObject; got != want { 274 t.Errorf("got %s, want %s", got, want) 275 } 276 if got, want := js.Global().Get("Array").Type(), js.TypeFunction; got != want { 277 t.Errorf("got %s, want %s", got, want) 278 } 279 } 280 281 type object = map[string]interface{} 282 type array = []interface{} 283 284 func TestValueOf(t *testing.T) { 285 a := js.ValueOf(array{0, array{0, 42, 0}, 0}) 286 if got := a.Index(1).Index(1).Int(); got != 42 { 287 t.Errorf("got %v, want %v", got, 42) 288 } 289 290 o := js.ValueOf(object{"x": object{"y": 42}}) 291 if got := o.Get("x").Get("y").Int(); got != 42 { 292 t.Errorf("got %v, want %v", got, 42) 293 } 294 } 295 296 func TestZeroValue(t *testing.T) { 297 var v js.Value 298 if v != js.Undefined() { 299 t.Error("zero js.Value is not js.Undefined()") 300 } 301 } 302 303 func TestFuncOf(t *testing.T) { 304 c := make(chan struct{}) 305 cb := js.FuncOf(func(this js.Value, args []js.Value) interface{} { 306 if got := args[0].Int(); got != 42 { 307 t.Errorf("got %#v, want %#v", got, 42) 308 } 309 c <- struct{}{} 310 return nil 311 }) 312 defer cb.Release() 313 js.Global().Call("setTimeout", cb, 0, 42) 314 <-c 315 } 316 317 func TestInvokeFunction(t *testing.T) { 318 called := false 319 cb := js.FuncOf(func(this js.Value, args []js.Value) interface{} { 320 cb2 := js.FuncOf(func(this js.Value, args []js.Value) interface{} { 321 called = true 322 return 42 323 }) 324 defer cb2.Release() 325 return cb2.Invoke() 326 }) 327 defer cb.Release() 328 if got := cb.Invoke().Int(); got != 42 { 329 t.Errorf("got %#v, want %#v", got, 42) 330 } 331 if !called { 332 t.Error("function not called") 333 } 334 } 335 336 func ExampleFuncOf() { 337 var cb js.Func 338 cb = js.FuncOf(func(this js.Value, args []js.Value) interface{} { 339 fmt.Println("button clicked") 340 cb.Release() // release the function if the button will not be clicked again 341 return nil 342 }) 343 js.Global().Get("document").Call("getElementById", "myButton").Call("addEventListener", "click", cb) 344 } 345 346 // See 347 // - https://developer.mozilla.org/en-US/docs/Glossary/Truthy 348 // - https://stackoverflow.com/questions/19839952/all-falsey-values-in-javascript/19839953#19839953 349 // - http://www.ecma-international.org/ecma-262/5.1/#sec-9.2 350 func TestTruthy(t *testing.T) { 351 want := true 352 for _, key := range []string{ 353 "someBool", "someString", "someInt", "someFloat", "someArray", "someDate", 354 "stringZero", // "0" is truthy 355 "add", // functions are truthy 356 "emptyObj", "emptyArray", "Infinity", "NegInfinity", 357 // All objects are truthy, even if they're Number(0) or Boolean(false). 358 "objNumber0", "objBooleanFalse", 359 } { 360 if got := dummys.Get(key).Truthy(); got != want { 361 t.Errorf("%s: got %#v, want %#v", key, got, want) 362 } 363 } 364 365 want = false 366 if got := dummys.Get("zero").Truthy(); got != want { 367 t.Errorf("got %#v, want %#v", got, want) 368 } 369 if got := dummys.Get("NaN").Truthy(); got != want { 370 t.Errorf("got %#v, want %#v", got, want) 371 } 372 if got := js.ValueOf("").Truthy(); got != want { 373 t.Errorf("got %#v, want %#v", got, want) 374 } 375 if got := js.Null().Truthy(); got != want { 376 t.Errorf("got %#v, want %#v", got, want) 377 } 378 if got := js.Undefined().Truthy(); got != want { 379 t.Errorf("got %#v, want %#v", got, want) 380 } 381 }