github.com/goplusjs/gopherjs@v1.2.6-0.20211206034512-f187917453b8/tests/misc_test.go (about) 1 package tests 2 3 import ( 4 "math" 5 "reflect" 6 "runtime" 7 "strings" 8 "testing" 9 "time" 10 11 "github.com/goplusjs/gopherjs/tests/otherpkg" 12 ) 13 14 func TestSyntax1(t *testing.T) { 15 a := 42 16 if *&*&a != 42 { 17 t.Fail() 18 } 19 } 20 21 func TestPointerEquality(t *testing.T) { 22 a := 1 23 b := 1 24 if &a != &a || &a == &b { 25 t.Fail() 26 } 27 m := make(map[*int]int) 28 m[&a] = 2 29 m[&b] = 3 30 if m[&a] != 2 || m[&b] != 3 { 31 t.Fail() 32 } 33 34 for { 35 c := 1 36 d := 1 37 if &c != &c || &c == &d { 38 t.Fail() 39 } 40 break 41 } 42 43 s := struct { 44 e int 45 f int 46 }{1, 1} 47 if &s.e != &s.e || &s.e == &s.f { 48 t.Fail() 49 } 50 51 g := [3]int{1, 2, 3} 52 if &g[0] != &g[0] || &g[:][0] != &g[0] || &g[:][0] != &g[:][0] { 53 t.Fail() 54 } 55 } 56 57 type SingleValue struct { 58 Value uint16 59 } 60 61 type OtherSingleValue struct { 62 Value uint16 63 } 64 65 func TestStructKey(t *testing.T) { 66 m := make(map[SingleValue]int) 67 m[SingleValue{Value: 1}] = 42 68 m[SingleValue{Value: 2}] = 43 69 if m[SingleValue{Value: 1}] != 42 || m[SingleValue{Value: 2}] != 43 || reflect.ValueOf(m).MapIndex(reflect.ValueOf(SingleValue{Value: 1})).Interface() != 42 { 70 t.Fail() 71 } 72 73 m2 := make(map[interface{}]int) 74 m2[SingleValue{Value: 1}] = 42 75 m2[SingleValue{Value: 2}] = 43 76 m2[OtherSingleValue{Value: 1}] = 44 77 if m2[SingleValue{Value: 1}] != 42 || m2[SingleValue{Value: 2}] != 43 || m2[OtherSingleValue{Value: 1}] != 44 || reflect.ValueOf(m2).MapIndex(reflect.ValueOf(SingleValue{Value: 1})).Interface() != 42 { 78 t.Fail() 79 } 80 } 81 82 func TestSelectOnNilChan(t *testing.T) { 83 var c1 chan bool 84 c2 := make(chan bool) 85 86 go func() { 87 close(c2) 88 }() 89 90 select { 91 case <-c1: 92 t.Fail() 93 case <-c2: 94 // ok 95 } 96 } 97 98 type StructA struct { 99 x int 100 } 101 102 type StructB struct { 103 StructA 104 } 105 106 func TestEmbeddedStruct(t *testing.T) { 107 a := StructA{ 108 42, 109 } 110 b := StructB{ 111 StructA: a, 112 } 113 b.x = 0 114 if a.x != 42 { 115 t.Fail() 116 } 117 } 118 119 func TestMapStruct(t *testing.T) { 120 a := StructA{ 121 42, 122 } 123 m := map[int]StructA{ 124 1: a, 125 } 126 m[2] = a 127 a.x = 0 128 if m[1].x != 42 || m[2].x != 42 { 129 t.Fail() 130 } 131 } 132 133 func TestUnnamedParameters(t *testing.T) { 134 ok := false 135 defer func() { 136 if !ok { 137 t.Fail() 138 } 139 }() 140 blockingWithUnnamedParameter(false) // used to cause non-blocking call error, which is ignored by testing 141 ok = true 142 } 143 144 func blockingWithUnnamedParameter(bool) { 145 c := make(chan int, 1) 146 c <- 42 147 } 148 149 func TestGotoLoop(t *testing.T) { 150 goto loop 151 loop: 152 for i := 42; ; { 153 if i != 42 { 154 t.Fail() 155 } 156 break 157 } 158 } 159 160 func TestMaxUint64(t *testing.T) { 161 if math.MaxUint64 != 18446744073709551615 { 162 t.Fail() 163 } 164 } 165 166 func TestCopyBuiltin(t *testing.T) { 167 { 168 s := []string{"a", "b", "c"} 169 copy(s, s[1:]) 170 if s[0] != "b" || s[1] != "c" || s[2] != "c" { 171 t.Fail() 172 } 173 } 174 { 175 s := []string{"a", "b", "c"} 176 copy(s[1:], s) 177 if s[0] != "a" || s[1] != "a" || s[2] != "b" { 178 t.Fail() 179 } 180 } 181 } 182 183 func TestPointerOfStructConversion(t *testing.T) { 184 type A struct { 185 Value int 186 } 187 188 type B A 189 190 a1 := &A{Value: 1} 191 b1 := (*B)(a1) 192 b1.Value = 2 193 a2 := (*A)(b1) 194 a2.Value = 3 195 b2 := (*B)(a2) 196 b2.Value = 4 197 if a1 != a2 || b1 != b2 || a1.Value != 4 || a2.Value != 4 || b1.Value != 4 || b2.Value != 4 { 198 t.Fail() 199 } 200 } 201 202 func TestCompareStruct(t *testing.T) { 203 type A struct { 204 Value int 205 } 206 207 a := A{42} 208 var b interface{} = a 209 x := A{0} 210 211 if a != b || a == x || b == x { 212 t.Fail() 213 } 214 } 215 216 func TestLoopClosure(t *testing.T) { 217 type S struct{ fn func() int } 218 var fns []*S 219 for i := 0; i < 2; i++ { 220 z := i 221 fns = append(fns, &S{ 222 fn: func() int { 223 return z 224 }, 225 }) 226 } 227 for i, f := range fns { 228 if f.fn() != i { 229 t.Fail() 230 } 231 } 232 } 233 234 func TestLoopClosureWithStruct(t *testing.T) { 235 type T struct{ A int } 236 ts := []T{{0}, {1}, {2}} 237 fns := make([]func() T, 3) 238 for i, t := range ts { 239 t := t 240 fns[i] = func() T { 241 return t 242 } 243 } 244 for i := range fns { 245 if fns[i]().A != i { 246 t.Fail() 247 } 248 } 249 } 250 251 func TestNilInterfaceError(t *testing.T) { 252 defer func() { 253 if err := recover(); err == nil || !strings.Contains(err.(error).Error(), "nil pointer dereference") { 254 t.Fail() 255 } 256 }() 257 var err error 258 _ = err.Error() 259 } 260 261 func TestIndexOutOfRangeError(t *testing.T) { 262 defer func() { 263 if err := recover(); err == nil || !strings.Contains(err.(error).Error(), "index out of range") { 264 t.Fail() 265 } 266 }() 267 x := []int{1, 2, 3}[10] 268 _ = x 269 } 270 271 func TestNilAtLhs(t *testing.T) { 272 type F func(string) string 273 var f F 274 if nil != f { 275 t.Fail() 276 } 277 } 278 279 func TestZeroResultByPanic(t *testing.T) { 280 if zero() != 0 { 281 t.Fail() 282 } 283 } 284 285 func zero() int { 286 defer func() { 287 recover() 288 }() 289 panic("") 290 } 291 292 func TestNumGoroutine(t *testing.T) { 293 n := runtime.NumGoroutine() 294 c := make(chan bool) 295 go func() { 296 <-c 297 <-c 298 <-c 299 <-c 300 }() 301 c <- true 302 c <- true 303 c <- true 304 if got, want := runtime.NumGoroutine(), n+1; got != want { 305 t.Errorf("runtime.NumGoroutine(): Got %d, want %d.", got, want) 306 } 307 c <- true 308 } 309 310 func TestMapAssign(t *testing.T) { 311 x := 0 312 m := map[string]string{} 313 x, m["foo"] = 5, "bar" 314 if x != 5 || m["foo"] != "bar" { 315 t.Fail() 316 } 317 } 318 319 func TestSwitchStatement(t *testing.T) { 320 zero := 0 321 var interfaceZero interface{} = zero 322 switch { 323 case interfaceZero: 324 t.Fail() 325 default: 326 // ok 327 } 328 } 329 330 func TestAddAssignOnPackageVar(t *testing.T) { 331 otherpkg.Test = 0 332 otherpkg.Test += 42 333 if otherpkg.Test != 42 { 334 t.Fail() 335 } 336 } 337 338 func TestPointerOfPackageVar(t *testing.T) { 339 otherpkg.Test = 42 340 p := &otherpkg.Test 341 if *p != 42 { 342 t.Fail() 343 } 344 } 345 346 func TestFuncInSelect(t *testing.T) { 347 f := func(_ func()) chan int { 348 return make(chan int, 1) 349 } 350 select { 351 case <-f(func() {}): 352 case _ = <-f(func() {}): 353 case f(func() {}) <- 42: 354 } 355 } 356 357 func TestEscapeAnalysisOnForLoopVariableScope(t *testing.T) { 358 for i := 0; ; { 359 p := &i 360 time.Sleep(0) 361 i = 42 362 if *p != 42 { 363 t.Fail() 364 } 365 break 366 } 367 } 368 369 func TestGoStmtWithStructArg(t *testing.T) { 370 type S struct { 371 i int 372 } 373 374 f := func(s S, c chan int) { 375 c <- s.i 376 c <- s.i 377 } 378 379 c := make(chan int) 380 s := S{42} 381 go f(s, c) 382 s.i = 0 383 if <-c != 42 { 384 t.Fail() 385 } 386 if <-c != 42 { 387 t.Fail() 388 } 389 } 390 391 type methodExprCallType int 392 393 func (i methodExprCallType) test() int { 394 return int(i) + 2 395 } 396 397 func TestMethodExprCall(t *testing.T) { 398 if methodExprCallType.test(40) != 42 { 399 t.Fail() 400 } 401 } 402 403 func TestCopyOnSend(t *testing.T) { 404 type S struct{ i int } 405 c := make(chan S, 2) 406 go func() { 407 var s S 408 s.i = 42 409 c <- s 410 select { 411 case c <- s: 412 } 413 s.i = 10 414 }() 415 if (<-c).i != 42 { 416 t.Fail() 417 } 418 if (<-c).i != 42 { 419 t.Fail() 420 } 421 } 422 423 func TestEmptySelectCase(t *testing.T) { 424 ch := make(chan int, 1) 425 ch <- 42 426 427 var v = 0 428 select { 429 case v = <-ch: 430 } 431 if v != 42 { 432 t.Fail() 433 } 434 } 435 436 var a int 437 var b int 438 var C int 439 var D int 440 441 var a1 = &a 442 var a2 = &a 443 var b1 = &b 444 var C1 = &C 445 var C2 = &C 446 var D1 = &D 447 448 func TestPkgVarPointers(t *testing.T) { 449 if a1 != a2 || a1 == b1 || C1 != C2 || C1 == D1 { 450 t.Fail() 451 } 452 } 453 454 func TestStringMap(t *testing.T) { 455 m := make(map[string]interface{}) 456 if m["__proto__"] != nil { 457 t.Fail() 458 } 459 m["__proto__"] = 42 460 if m["__proto__"] != 42 { 461 t.Fail() 462 } 463 } 464 465 type Int int 466 467 func (i Int) Value() int { 468 return int(i) 469 } 470 471 func (i *Int) ValueByPtr() int { 472 return int(*i) 473 } 474 475 func TestWrappedTypeMethod(t *testing.T) { 476 i := Int(42) 477 p := &i 478 if p.Value() != 42 { 479 t.Fail() 480 } 481 } 482 483 type EmbeddedInt struct { 484 Int 485 } 486 487 func TestEmbeddedMethod(t *testing.T) { 488 e := EmbeddedInt{42} 489 if e.ValueByPtr() != 42 { 490 t.Fail() 491 } 492 } 493 494 func TestBoolConvert(t *testing.T) { 495 if !reflect.ValueOf(true).Convert(reflect.TypeOf(true)).Bool() { 496 t.Fail() 497 } 498 } 499 500 func TestGoexit(t *testing.T) { 501 go func() { 502 runtime.Goexit() 503 }() 504 } 505 506 func TestShift(t *testing.T) { 507 if x := uint(32); uint32(1)<<x != 0 { 508 t.Fail() 509 } 510 if x := uint64(0); uint32(1)<<x != 1 { 511 t.Fail() 512 } 513 if x := uint(4294967295); x>>32 != 0 { 514 t.Fail() 515 } 516 if x := uint(4294967295); x>>35 != 0 { 517 t.Fail() 518 } 519 } 520 521 func TestTrivialSwitch(t *testing.T) { 522 for { 523 switch { 524 default: 525 break 526 } 527 return 528 } 529 t.Fail() 530 } 531 532 func TestTupleFnReturnImplicitCast(t *testing.T) { 533 var ycalled int = 0 534 x := func(fn func() (int, error)) (interface{}, error) { 535 return fn() 536 } 537 y, _ := x(func() (int, error) { 538 ycalled++ 539 return 14, nil 540 }) 541 if y != 14 || ycalled != 1 { 542 t.Fail() 543 } 544 } 545 546 var tuple2called = 0 547 548 func tuple1() (interface{}, error) { 549 return tuple2() 550 } 551 func tuple2() (int, error) { 552 tuple2called++ 553 return 14, nil 554 } 555 func TestTupleReturnImplicitCast(t *testing.T) { 556 x, _ := tuple1() 557 if x != 14 || tuple2called != 1 { 558 t.Fail() 559 } 560 } 561 562 func TestDeferNamedTupleReturnImplicitCast(t *testing.T) { 563 var ycalled int = 0 564 var zcalled int = 0 565 z := func() { 566 zcalled++ 567 } 568 x := func(fn func() (int, error)) (i interface{}, e error) { 569 defer z() 570 i, e = fn() 571 return 572 } 573 y, _ := x(func() (int, error) { 574 ycalled++ 575 return 14, nil 576 }) 577 if y != 14 || ycalled != 1 || zcalled != 1 { 578 t.Fail() 579 } 580 } 581 582 func TestSliceOfString(t *testing.T) { 583 defer func() { 584 if err := recover(); err == nil || !strings.Contains(err.(error).Error(), "slice bounds out of range") { 585 t.Fail() 586 } 587 }() 588 589 str := "foo" 590 print(str[0:10]) 591 } 592 593 func TestSliceOutOfRange(t *testing.T) { 594 defer func() { 595 if err := recover(); err == nil || !strings.Contains(err.(error).Error(), "slice bounds out of range") { 596 t.Fail() 597 } 598 }() 599 600 a := make([]byte, 4) 601 b := a[8:] 602 _ = b 603 } 604 605 type R struct{ v int } 606 607 func (r R) Val() int { 608 return r.v 609 } 610 611 func TestReceiverCapture(t *testing.T) { 612 r := R{1} 613 f1 := r.Val 614 r = R{2} 615 f2 := r.Val 616 if f1() != 1 || f2() != 2 { 617 t.Fail() 618 } 619 } 620 621 func TestTypeConversion(t *testing.T) { 622 i1, i2, i3 := 4, 2, 2 623 if (i1-i2)/i3 != int(i1-i2)/int(i3) { 624 t.Fail() 625 } 626 f1, f2, f3 := 4.0, 2.0, 2.0 627 if (f1-f2)/f3 != float64(f1-f2)/float64(f3) { 628 t.Fail() 629 } 630 } 631 632 // See https://github.com/gopherjs/gopherjs/issues/851. 633 func TestSlicingNilSlice(t *testing.T) { 634 t.Run("StaysNil", func(t *testing.T) { 635 var s []int 636 s = s[:] 637 if s != nil { 638 t.Errorf("nil slice became non-nil after slicing with s[:]: %#v, want []int(nil)", s) 639 } 640 s = nil 641 s = s[0:0] 642 if s != nil { 643 t.Errorf("nil slice became non-nil after slicing with s[0:0]: %#v, want []int(nil)", s) 644 } 645 s = nil 646 s = s[0:0:0] 647 if s != nil { 648 t.Errorf("nil slice became non-nil after slicing with s[0:0:0]: %#v, want []int(nil)", s) 649 } 650 }) 651 t.Run("Panics", func(t *testing.T) { 652 defer func() { 653 if err := recover(); err == nil || !strings.Contains(err.(error).Error(), "slice bounds out of range") { 654 t.Error("slicing nil slice out of range didn't panic, want panic") 655 } 656 }() 657 var s []int 658 s = s[5:10] 659 }) 660 t.Run("DoesNotBecomeNil", func(t *testing.T) { 661 var s = []int{} 662 s = s[:] 663 if s == nil { 664 t.Errorf("non-nil slice became nil after slicing: %#v, want []int{}", s) 665 } 666 }) 667 } 668 669 // Ensure that doing an interface conversion that fails 670 // produces an expected error type with the right error text. 671 func TestInterfaceConversionRuntimeError(t *testing.T) { 672 defer func() { 673 r := recover() 674 if r == nil { 675 t.Fatal("got no panic, want panic") 676 } 677 re, ok := r.(runtime.Error) 678 if !ok { 679 t.Fatalf("got %T, want runtime.Error", r) 680 } 681 if got, want := re.Error(), "interface conversion: int is not tests.I: missing method Get"; got != want { 682 t.Fatalf("got %q, want %q", got, want) 683 } 684 }() 685 type I interface { 686 Get() int 687 } 688 e := (interface{})(0) 689 _ = e.(I) 690 } 691 692 func TestReflectMapIterationAndDelete(t *testing.T) { 693 m := map[string]int{ 694 "one": 1, 695 "two": 2, 696 "three": 3, 697 } 698 iter := reflect.ValueOf(m).MapRange() 699 for iter.Next() { 700 delete(m, iter.Key().String()) 701 } 702 if got, want := len(m), 0; got != want { 703 t.Fatalf("got %d, want %d", got, want) 704 } 705 }