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  }