github.com/tetratelabs/wazero@v1.7.3-0.20240513003603-48f702e154b5/internal/testing/require/require_test.go (about)

     1  package require
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"io"
     7  	"testing"
     8  )
     9  
    10  func TestCapturePanic(t *testing.T) {
    11  	tests := []struct {
    12  		name        string
    13  		panics      func()
    14  		expectedErr string
    15  	}{
    16  		{
    17  			name:        "doesn't panic",
    18  			panics:      func() {},
    19  			expectedErr: "",
    20  		},
    21  		{
    22  			name:        "panics with error",
    23  			panics:      func() { panic(errors.New("error")) },
    24  			expectedErr: "error",
    25  		},
    26  		{
    27  			name:        "panics with string",
    28  			panics:      func() { panic("crash") },
    29  			expectedErr: "crash",
    30  		},
    31  		{
    32  			name:        "panics with object",
    33  			panics:      func() { panic(struct{}{}) },
    34  			expectedErr: "{}",
    35  		},
    36  	}
    37  
    38  	for _, tt := range tests {
    39  		tc := tt
    40  
    41  		t.Run(tc.name, func(t *testing.T) {
    42  			captured := CapturePanic(tc.panics)
    43  			if tc.expectedErr == "" {
    44  				if captured != nil {
    45  					t.Fatalf("expected no error, but found %v", captured)
    46  				}
    47  			} else {
    48  				if captured.Error() != tc.expectedErr {
    49  					t.Fatalf("expected %s, but found %s", tc.expectedErr, captured.Error())
    50  				}
    51  			}
    52  		})
    53  	}
    54  }
    55  
    56  func TestFail(t *testing.T) {
    57  	tests := []struct {
    58  		name           string
    59  		formatWithArgs []interface{}
    60  		expectedLog    string
    61  	}{
    62  		{
    63  			name:        "message no formatWithArgs",
    64  			expectedLog: "failed",
    65  		},
    66  		{
    67  			name:           "message formatWithArgs =: string",
    68  			formatWithArgs: []interface{}{"because"},
    69  			expectedLog:    "failed: because",
    70  		},
    71  		{
    72  			name:           "message formatWithArgs = [number]",
    73  			formatWithArgs: []interface{}{1},
    74  			expectedLog:    "failed: 1",
    75  		},
    76  		{
    77  			name:           "message formatWithArgs = [struct]",
    78  			formatWithArgs: []interface{}{struct{}{}},
    79  			expectedLog:    "failed: {}",
    80  		},
    81  		{
    82  			name:           "message formatWithArgs = [string, string]",
    83  			formatWithArgs: []interface{}{"because", "this"},
    84  			expectedLog:    "failed: because this",
    85  		},
    86  		{
    87  			name:           "message formatWithArgs = [format, string]",
    88  			formatWithArgs: []interface{}{"because %s", "this"},
    89  			expectedLog:    "failed: because this",
    90  		},
    91  		{
    92  			name:           "message formatWithArgs = [format, struct]",
    93  			formatWithArgs: []interface{}{"because %s", struct{}{}},
    94  			expectedLog:    "failed: because {}",
    95  		},
    96  	}
    97  
    98  	for _, tt := range tests {
    99  		tc := tt
   100  
   101  		t.Run(tc.name, func(t *testing.T) {
   102  			m := &mockT{t: t}
   103  			fail(m, "failed", "", tc.formatWithArgs...)
   104  			m.require(tc.expectedLog)
   105  		})
   106  	}
   107  }
   108  
   109  type testStruct struct {
   110  	name string
   111  }
   112  
   113  func TestRequire(t *testing.T) {
   114  	zero := uint64(0)
   115  	struct1 := &testStruct{"hello"}
   116  	struct2 := &testStruct{"hello"}
   117  
   118  	tests := []struct {
   119  		name        string
   120  		require     func(TestingT)
   121  		expectedLog string
   122  	}{
   123  		{
   124  			name: "Contains passes on contains",
   125  			require: func(t TestingT) {
   126  				Contains(t, "hello cat", "cat")
   127  			},
   128  		},
   129  		{
   130  			name: "Contains fails on empty",
   131  			require: func(t TestingT) {
   132  				Contains(t, "", "dog")
   133  			},
   134  			expectedLog: `expected "" to contain "dog"`,
   135  		},
   136  		{
   137  			name: "Contains fails on not contains",
   138  			require: func(t TestingT) {
   139  				Contains(t, "hello cat", "dog")
   140  			},
   141  			expectedLog: `expected "hello cat" to contain "dog"`,
   142  		},
   143  		{
   144  			name: "Contains fails on not contains with format",
   145  			require: func(t TestingT) {
   146  				Contains(t, "hello cat", "dog", "pay me %d", 5)
   147  			},
   148  			expectedLog: `expected "hello cat" to contain "dog": pay me 5`,
   149  		},
   150  		{
   151  			name: "Equal passes on equal: string",
   152  			require: func(t TestingT) {
   153  				Equal(t, "wazero", "wazero")
   154  			},
   155  		},
   156  		{
   157  			name: "Equal passes on equal: []byte",
   158  			require: func(t TestingT) {
   159  				Equal(t, []byte{1, 2, 3, 4}, []byte{1, 2, 3, 4})
   160  			},
   161  		},
   162  		{
   163  			name: "Equal passes on equal: struct",
   164  			require: func(t TestingT) {
   165  				Equal(t, &testStruct{name: "takeshi"}, &testStruct{name: "takeshi"})
   166  			},
   167  		},
   168  		{
   169  			name: "Equal fails on nil: string",
   170  			require: func(t TestingT) {
   171  				Equal(t, "wazero", nil)
   172  			},
   173  			expectedLog: `expected "wazero", but was nil`,
   174  		},
   175  		{
   176  			name: "Equal fails on nil: []byte",
   177  			require: func(t TestingT) {
   178  				Equal(t, []byte{1, 2, 3, 4}, nil)
   179  			},
   180  			expectedLog: `expected []byte{0x1, 0x2, 0x3, 0x4}, but was nil`,
   181  		},
   182  		{
   183  			name: "Equal fails on nil: struct",
   184  			require: func(t TestingT) {
   185  				Equal(t, &testStruct{name: "takeshi"}, nil)
   186  			},
   187  			expectedLog: `expected &require.testStruct{name:"takeshi"}, but was nil`,
   188  		},
   189  
   190  		{
   191  			name: "Equal fails on not same type: string",
   192  			require: func(t TestingT) {
   193  				Equal(t, "wazero", uint32(1))
   194  			},
   195  			expectedLog: `expected "wazero", but was uint32(1)`,
   196  		},
   197  		{
   198  			name: "Equal fails on not same type: []byte",
   199  			require: func(t TestingT) {
   200  				Equal(t, []byte{1, 2, 3, 4}, "wazero")
   201  			},
   202  			expectedLog: `expected []uint8([1 2 3 4]), but was string(wazero)`,
   203  		},
   204  		{
   205  			name: "Equal fails on not same type: struct",
   206  			require: func(t TestingT) {
   207  				Equal(t, &testStruct{name: "takeshi"}, "wazero")
   208  			},
   209  			expectedLog: `expected *require.testStruct(&{takeshi}), but was string(wazero)`,
   210  		},
   211  		{
   212  			name: "Equal fails on not equal: string",
   213  			require: func(t TestingT) {
   214  				Equal(t, "wazero", "walero")
   215  			},
   216  			expectedLog: `expected "wazero", but was "walero"`,
   217  		},
   218  		{
   219  			name: "Equal fails on not equal: uint64", // ensure we don't use multi-line output!
   220  			require: func(t TestingT) {
   221  				Equal(t, uint64(12), uint64(13))
   222  			},
   223  			expectedLog: `expected 12, but was 13`,
   224  		},
   225  		{
   226  			name: "Equal fails on not equal: []byte",
   227  			require: func(t TestingT) {
   228  				Equal(t, []byte{1, 2, 3, 4}, []byte{1, 2, 4})
   229  			},
   230  			expectedLog: `unexpected value
   231  expected:
   232  	[]byte{0x1, 0x2, 0x3, 0x4}
   233  was:
   234  	[]byte{0x1, 0x2, 0x4}
   235  `,
   236  		},
   237  		{
   238  			name: "Equal fails on not equal: struct",
   239  			require: func(t TestingT) {
   240  				Equal(t, &testStruct{name: "takeshi"}, &testStruct{name: "adrian"})
   241  			},
   242  			expectedLog: `unexpected value
   243  expected:
   244  	&require.testStruct{name:"takeshi"}
   245  was:
   246  	&require.testStruct{name:"adrian"}
   247  `,
   248  		},
   249  		{
   250  			name: "Equal fails on not equal: struct with format",
   251  			require: func(t TestingT) {
   252  				Equal(t, &testStruct{name: "takeshi"}, &testStruct{name: "adrian"}, "pay me %d", 5)
   253  			},
   254  			expectedLog: `unexpected value: pay me 5
   255  expected:
   256  	&require.testStruct{name:"takeshi"}
   257  was:
   258  	&require.testStruct{name:"adrian"}
   259  `,
   260  		},
   261  		{
   262  			name: "EqualError passes on equal",
   263  			require: func(t TestingT) {
   264  				EqualError(t, io.EOF, io.EOF.Error())
   265  			},
   266  		},
   267  		{
   268  			name: "EqualError fails on nil",
   269  			require: func(t TestingT) {
   270  				EqualError(t, nil, "crash")
   271  			},
   272  			expectedLog: "expected an error, but was nil",
   273  		},
   274  		{
   275  			name: "EqualError fails on not equal",
   276  			require: func(t TestingT) {
   277  				EqualError(t, io.EOF, "crash")
   278  			},
   279  			expectedLog: `expected error "crash", but was "EOF"`,
   280  		},
   281  		{
   282  			name: "EqualError fails on not equal with format",
   283  			require: func(t TestingT) {
   284  				EqualError(t, io.EOF, "crash", "pay me %d", 5)
   285  			},
   286  			expectedLog: `expected error "crash", but was "EOF": pay me 5`,
   287  		},
   288  		{
   289  			name: "Error passes on not nil",
   290  			require: func(t TestingT) {
   291  				Error(t, io.EOF)
   292  			},
   293  		},
   294  		{
   295  			name: "Error fails on nil",
   296  			require: func(t TestingT) {
   297  				Error(t, nil)
   298  			},
   299  			expectedLog: "expected an error, but was nil",
   300  		},
   301  		{
   302  			name: "Error fails on nil with format",
   303  			require: func(t TestingT) {
   304  				Error(t, nil, "pay me %d", 5)
   305  			},
   306  			expectedLog: `expected an error, but was nil: pay me 5`,
   307  		},
   308  		{
   309  			name: "ErrorIs passes on same",
   310  			require: func(t TestingT) {
   311  				ErrorIs(t, io.EOF, io.EOF)
   312  			},
   313  		},
   314  		{
   315  			name: "ErrorIs passes on wrapped",
   316  			require: func(t TestingT) {
   317  				ErrorIs(t, fmt.Errorf("cause: %w", io.EOF), io.EOF)
   318  			},
   319  		},
   320  		{
   321  			name: "ErrorIs fails on not equal",
   322  			require: func(t TestingT) {
   323  				ErrorIs(t, io.EOF, io.ErrUnexpectedEOF)
   324  			},
   325  			expectedLog: "expected errors.Is(EOF, unexpected EOF), but it wasn't",
   326  		},
   327  		{
   328  			name: "ErrorIs fails on not equal with format",
   329  			require: func(t TestingT) {
   330  				ErrorIs(t, io.EOF, io.ErrUnexpectedEOF, "pay me %d", 5)
   331  			},
   332  			expectedLog: `expected errors.Is(EOF, unexpected EOF), but it wasn't: pay me 5`,
   333  		},
   334  		{
   335  			name: "Nil passes on nil",
   336  			require: func(t TestingT) {
   337  				Nil(t, nil)
   338  			},
   339  		},
   340  		{
   341  			name: "Nil fails on not nil",
   342  			require: func(t TestingT) {
   343  				Nil(t, io.EOF)
   344  			},
   345  			expectedLog: "expected nil, but was EOF",
   346  		},
   347  		{
   348  			name: "Nil fails on not nil with format",
   349  			require: func(t TestingT) {
   350  				Nil(t, io.EOF, "pay me %d", 5)
   351  			},
   352  			expectedLog: `expected nil, but was EOF: pay me 5`,
   353  		},
   354  		{
   355  			name: "NoError passes on nil",
   356  			require: func(t TestingT) {
   357  				NoError(t, nil)
   358  			},
   359  		},
   360  		{
   361  			name: "NoError fails on not nil",
   362  			require: func(t TestingT) {
   363  				NoError(t, io.EOF)
   364  			},
   365  			expectedLog: "expected no error, but was EOF",
   366  		},
   367  		{
   368  			name: "NoError fails on not nil with format",
   369  			require: func(t TestingT) {
   370  				NoError(t, io.EOF, "pay me %d", 5)
   371  			},
   372  			expectedLog: `expected no error, but was EOF: pay me 5`,
   373  		},
   374  		{
   375  			name: "NotNil passes on not nil",
   376  			require: func(t TestingT) {
   377  				NotNil(t, io.EOF)
   378  			},
   379  		},
   380  		{
   381  			name: "NotNil fails on nil",
   382  			require: func(t TestingT) {
   383  				NotNil(t, nil)
   384  			},
   385  			expectedLog: "expected to not be nil",
   386  		},
   387  		{
   388  			name: "NotNil fails on nil with format",
   389  			require: func(t TestingT) {
   390  				NotNil(t, nil, "pay me %d", 5)
   391  			},
   392  			expectedLog: `expected to not be nil: pay me 5`,
   393  		},
   394  		{
   395  			name: "False passes on false",
   396  			require: func(t TestingT) {
   397  				False(t, false)
   398  			},
   399  		},
   400  		{
   401  			name: "False fails on true",
   402  			require: func(t TestingT) {
   403  				False(t, true)
   404  			},
   405  			expectedLog: "expected false, but was true",
   406  		},
   407  		{
   408  			name: "False fails on true with format",
   409  			require: func(t TestingT) {
   410  				False(t, true, "pay me %d", 5)
   411  			},
   412  			expectedLog: "expected false, but was true: pay me 5",
   413  		},
   414  		{
   415  			name: "Equal passes on equal: string",
   416  			require: func(t TestingT) {
   417  				Equal(t, "wazero", "wazero")
   418  			},
   419  		},
   420  		{
   421  			name: "Equal passes on equal: []byte",
   422  			require: func(t TestingT) {
   423  				Equal(t, []byte{1, 2, 3, 4}, []byte{1, 2, 3, 4})
   424  			},
   425  		},
   426  		{
   427  			name: "Equal passes on equal: struct",
   428  			require: func(t TestingT) {
   429  				Equal(t, &testStruct{name: "takeshi"}, &testStruct{name: "takeshi"})
   430  			},
   431  		},
   432  		{
   433  			name: "Equal fails on nil: string",
   434  			require: func(t TestingT) {
   435  				Equal(t, "wazero", nil)
   436  			},
   437  			expectedLog: `expected "wazero", but was nil`,
   438  		},
   439  		{
   440  			name: "Equal fails on nil: []byte",
   441  			require: func(t TestingT) {
   442  				Equal(t, []byte{1, 2, 3, 4}, nil)
   443  			},
   444  			expectedLog: `expected []byte{0x1, 0x2, 0x3, 0x4}, but was nil`,
   445  		},
   446  		{
   447  			name: "Equal fails on nil: struct",
   448  			require: func(t TestingT) {
   449  				Equal(t, &testStruct{name: "takeshi"}, nil)
   450  			},
   451  			expectedLog: `expected &require.testStruct{name:"takeshi"}, but was nil`,
   452  		},
   453  		{
   454  			name: "NotEqual passes on not equal",
   455  			require: func(t TestingT) {
   456  				NotEqual(t, uint32(1), uint32(2))
   457  			},
   458  		},
   459  		{
   460  			name: "NotEqual fails on equal: nil",
   461  			require: func(t TestingT) {
   462  				NotEqual(t, nil, nil)
   463  			},
   464  			expectedLog: `expected to not equal <nil>`,
   465  		},
   466  		{
   467  			name: "NotEqual fails on equal: string",
   468  			require: func(t TestingT) {
   469  				NotEqual(t, "wazero", "wazero")
   470  			},
   471  			expectedLog: `expected to not equal "wazero"`,
   472  		},
   473  		{
   474  			name: "NotEqual fails on equal: []byte",
   475  			require: func(t TestingT) {
   476  				NotEqual(t, []byte{1, 2, 3, 4}, []byte{1, 2, 3, 4})
   477  			},
   478  			expectedLog: `expected to not equal []byte{0x1, 0x2, 0x3, 0x4}`,
   479  		},
   480  		{
   481  			name: "NotEqual fails on equal: struct",
   482  			require: func(t TestingT) {
   483  				NotEqual(t, &testStruct{name: "takeshi"}, &testStruct{name: "takeshi"})
   484  			},
   485  			expectedLog: `expected to not equal &require.testStruct{name:"takeshi"}`,
   486  		},
   487  		{
   488  			name: "NotEqual fails on equal: struct with format",
   489  			require: func(t TestingT) {
   490  				NotEqual(t, &testStruct{name: "takeshi"}, &testStruct{name: "takeshi"}, "pay me %d", 5)
   491  			},
   492  			expectedLog: `expected to not equal &require.testStruct{name:"takeshi"}: pay me 5`,
   493  		},
   494  		{
   495  			name: "NotSame passes on not same",
   496  			require: func(t TestingT) {
   497  				NotSame(t, struct1, struct2)
   498  			},
   499  		},
   500  		{
   501  			name: "NotSame passes on different types",
   502  			require: func(t TestingT) {
   503  				NotSame(t, struct1, &zero)
   504  			},
   505  		},
   506  		{
   507  			name: "NotSame fails on same pointers",
   508  			require: func(t TestingT) {
   509  				NotSame(t, struct1, struct1)
   510  			},
   511  			expectedLog: "expected &{hello} to point to a different object",
   512  		},
   513  		{
   514  			name: "NotSame fails on same pointers with format",
   515  			require: func(t TestingT) {
   516  				NotSame(t, struct1, struct1, "pay me %d", 5)
   517  			},
   518  			expectedLog: "expected &{hello} to point to a different object: pay me 5",
   519  		},
   520  		{
   521  			name: "Same passes on same",
   522  			require: func(t TestingT) {
   523  				Same(t, struct1, struct1)
   524  			},
   525  		},
   526  		{
   527  			name: "Same fails on different types",
   528  			require: func(t TestingT) {
   529  				Same(t, struct1, &zero)
   530  			},
   531  			expectedLog: fmt.Sprintf("expected %v to point to the same object as &{hello}", &zero),
   532  		},
   533  		{
   534  			name: "Same fails on different pointers",
   535  			require: func(t TestingT) {
   536  				Same(t, struct1, struct2)
   537  			},
   538  			expectedLog: "expected &{hello} to point to the same object as &{hello}",
   539  		},
   540  		{
   541  			name: "Same fails on different pointers with format",
   542  			require: func(t TestingT) {
   543  				Same(t, struct1, struct2, "pay me %d", 5)
   544  			},
   545  			expectedLog: "expected &{hello} to point to the same object as &{hello}: pay me 5",
   546  		},
   547  		{
   548  			name: "True passes on true",
   549  			require: func(t TestingT) {
   550  				True(t, true)
   551  			},
   552  		},
   553  		{
   554  			name: "True fails on false",
   555  			require: func(t TestingT) {
   556  				True(t, false)
   557  			},
   558  			expectedLog: "expected true, but was false",
   559  		},
   560  		{
   561  			name: "True fails on false with format",
   562  			require: func(t TestingT) {
   563  				True(t, false, "pay me %d", 5)
   564  			},
   565  			expectedLog: "expected true, but was false: pay me 5",
   566  		},
   567  		{
   568  			name: "Zero passes on float32(0)",
   569  			require: func(t TestingT) {
   570  				Zero(t, float32(0))
   571  			},
   572  		},
   573  		{
   574  			name: "Zero passes on float64(0)",
   575  			require: func(t TestingT) {
   576  				Zero(t, float64(0))
   577  			},
   578  		},
   579  		{
   580  			name: "Zero passes on int(0)",
   581  			require: func(t TestingT) {
   582  				Zero(t, int(0))
   583  			},
   584  		},
   585  		{
   586  			name: "Zero passes on uint32(0)",
   587  			require: func(t TestingT) {
   588  				Zero(t, uint32(0))
   589  			},
   590  		},
   591  		{
   592  			name: "Zero passes on uint64(0)",
   593  			require: func(t TestingT) {
   594  				Zero(t, uint64(0))
   595  			},
   596  		},
   597  		{
   598  			name: "Zero fails on float32(1)",
   599  			require: func(t TestingT) {
   600  				Zero(t, float32(1))
   601  			},
   602  			expectedLog: "expected zero, but was 1",
   603  		},
   604  		{
   605  			name: "Zero fails on float64(1)",
   606  			require: func(t TestingT) {
   607  				Zero(t, float64(1))
   608  			},
   609  			expectedLog: "expected zero, but was 1",
   610  		},
   611  		{
   612  			name: "Zero fails on int(1)",
   613  			require: func(t TestingT) {
   614  				Zero(t, int(1))
   615  			},
   616  			expectedLog: "expected zero, but was 1",
   617  		},
   618  		{
   619  			name: "Zero fails on uint32(1)",
   620  			require: func(t TestingT) {
   621  				Zero(t, uint32(1))
   622  			},
   623  			expectedLog: "expected zero, but was 1",
   624  		},
   625  		{
   626  			name: "Zero fails on uint64(1)",
   627  			require: func(t TestingT) {
   628  				Zero(t, uint64(1))
   629  			},
   630  			expectedLog: "expected zero, but was 1",
   631  		},
   632  		{
   633  			name: "Zero fails on uint64(1) with format",
   634  			require: func(t TestingT) {
   635  				Zero(t, uint64(1), "pay me %d", 5)
   636  			},
   637  			expectedLog: "expected zero, but was 1: pay me 5",
   638  		},
   639  	}
   640  
   641  	for _, tt := range tests {
   642  		tc := tt
   643  		t.Run(tc.name, func(t *testing.T) {
   644  			m := &mockT{t: t}
   645  			tc.require(m)
   646  			m.require(tc.expectedLog)
   647  		})
   648  	}
   649  }
   650  
   651  // compile-time check to ensure mockT implements TestingT
   652  var _ TestingT = &mockT{}
   653  
   654  type mockT struct {
   655  	t   *testing.T
   656  	log string
   657  }
   658  
   659  // Fatal implements TestingT.Fatal
   660  func (t *mockT) Fatal(args ...interface{}) {
   661  	if t.log != "" {
   662  		t.t.Fatal("already called Fatal(")
   663  	}
   664  	t.log = fmt.Sprint(args...)
   665  }
   666  
   667  func (t *mockT) require(expectedLog string) {
   668  	if expectedLog != t.log {
   669  		t.t.Fatalf("expected log=%q, but found %q", expectedLog, t.log)
   670  	}
   671  }