...

Source file src/gotest.tools/v3/assert/assert_test.go

Documentation: gotest.tools/v3/assert

     1  package assert
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"testing"
     7  
     8  	gocmp "github.com/google/go-cmp/cmp"
     9  	"gotest.tools/v3/assert/cmp"
    10  )
    11  
    12  type fakeTestingT struct {
    13  	failNowed bool
    14  	failed    bool
    15  	msgs      []string
    16  }
    17  
    18  func (f *fakeTestingT) FailNow() {
    19  	f.failNowed = true
    20  }
    21  
    22  func (f *fakeTestingT) Fail() {
    23  	f.failed = true
    24  }
    25  
    26  func (f *fakeTestingT) Log(args ...interface{}) {
    27  	f.msgs = append(f.msgs, fmt.Sprint(args...))
    28  }
    29  
    30  func (f *fakeTestingT) Helper() {}
    31  
    32  func TestAssert_WithBinaryExpression_Failures(t *testing.T) {
    33  	t.Run("equal", func(t *testing.T) {
    34  		fakeT := &fakeTestingT{}
    35  		Assert(fakeT, 1 == 6)
    36  		expectFailNowed(t, fakeT, "assertion failed: 1 is not 6")
    37  	})
    38  	t.Run("not equal", func(t *testing.T) {
    39  		fakeT := &fakeTestingT{}
    40  		a := 1
    41  		Assert(fakeT, a != 1)
    42  		expectFailNowed(t, fakeT, "assertion failed: a is 1")
    43  	})
    44  	t.Run("greater than", func(t *testing.T) {
    45  		fakeT := &fakeTestingT{}
    46  		Assert(fakeT, 1 > 5)
    47  		expectFailNowed(t, fakeT, "assertion failed: 1 is <= 5")
    48  	})
    49  	t.Run("less than", func(t *testing.T) {
    50  		fakeT := &fakeTestingT{}
    51  		Assert(fakeT, 5 < 1)
    52  		expectFailNowed(t, fakeT, "assertion failed: 5 is >= 1")
    53  	})
    54  	t.Run("greater than or equal", func(t *testing.T) {
    55  		fakeT := &fakeTestingT{}
    56  		Assert(fakeT, 1 >= 5)
    57  		expectFailNowed(t, fakeT, "assertion failed: 1 is less than 5")
    58  	})
    59  	t.Run("less than or equal", func(t *testing.T) {
    60  		fakeT := &fakeTestingT{}
    61  		Assert(fakeT, 6 <= 2)
    62  		expectFailNowed(t, fakeT, "assertion failed: 6 is greater than 2")
    63  	})
    64  }
    65  
    66  func TestAssertWithBoolIdent(t *testing.T) {
    67  	fakeT := &fakeTestingT{}
    68  
    69  	var ok bool
    70  	Assert(fakeT, ok)
    71  	expectFailNowed(t, fakeT, "assertion failed: ok is false")
    72  }
    73  
    74  func TestAssertWithBoolFailureNotEqual(t *testing.T) {
    75  	fakeT := &fakeTestingT{}
    76  
    77  	var err error
    78  	Assert(fakeT, err != nil)
    79  	expectFailNowed(t, fakeT, "assertion failed: err is nil")
    80  }
    81  
    82  func TestAssertWithBoolFailureNotTrue(t *testing.T) {
    83  	fakeT := &fakeTestingT{}
    84  
    85  	badNews := true
    86  	Assert(fakeT, !badNews)
    87  	expectFailNowed(t, fakeT, "assertion failed: badNews is true")
    88  }
    89  
    90  func TestAssertWithBoolFailureAndExtraMessage(t *testing.T) {
    91  	fakeT := &fakeTestingT{}
    92  
    93  	Assert(fakeT, 1 > 5, "sometimes things fail")
    94  	expectFailNowed(t, fakeT, "assertion failed: 1 is <= 5: sometimes things fail")
    95  }
    96  
    97  func TestAssertWithBoolSuccess(t *testing.T) {
    98  	fakeT := &fakeTestingT{}
    99  
   100  	Assert(fakeT, 1 < 5)
   101  	expectSuccess(t, fakeT)
   102  }
   103  
   104  func TestAssertWithBoolMultiLineFailure(t *testing.T) {
   105  	fakeT := &fakeTestingT{}
   106  
   107  	Assert(fakeT, func() bool {
   108  		for i := range []int{1, 2, 3, 4} {
   109  			_ = i
   110  		}
   111  		return false
   112  	}())
   113  	expectFailNowed(t, fakeT, `assertion failed: expression is false: func() bool {
   114  	for i := range []int{1, 2, 3, 4} {
   115  		_ = i
   116  	}
   117  	return false
   118  }()`)
   119  }
   120  
   121  type exampleComparison struct {
   122  	success bool
   123  	message string
   124  }
   125  
   126  func (c exampleComparison) Compare() (bool, string) {
   127  	return c.success, c.message
   128  }
   129  
   130  func TestAssertWithComparisonSuccess(t *testing.T) {
   131  	fakeT := &fakeTestingT{}
   132  
   133  	cmp := exampleComparison{success: true}
   134  	Assert(fakeT, cmp.Compare)
   135  	expectSuccess(t, fakeT)
   136  }
   137  
   138  func TestAssertWithComparisonFailure(t *testing.T) {
   139  	fakeT := &fakeTestingT{}
   140  
   141  	cmp := exampleComparison{message: "oops, not good"}
   142  	Assert(fakeT, cmp.Compare)
   143  	expectFailNowed(t, fakeT, "assertion failed: oops, not good")
   144  }
   145  
   146  func TestAssertWithComparisonAndExtraMessage(t *testing.T) {
   147  	fakeT := &fakeTestingT{}
   148  
   149  	cmp := exampleComparison{message: "oops, not good"}
   150  	Assert(fakeT, cmp.Compare, "extra stuff %v", true)
   151  	expectFailNowed(t, fakeT, "assertion failed: oops, not good: extra stuff true")
   152  }
   153  
   154  type customError struct {
   155  	field bool
   156  }
   157  
   158  func (e *customError) Error() string {
   159  	// access a field of the receiver to simulate the behaviour of most
   160  	// implementations, and test handling of non-nil typed errors.
   161  	e.field = true
   162  	return "custom error"
   163  }
   164  
   165  func TestNilError(t *testing.T) {
   166  	t.Run("nil interface", func(t *testing.T) {
   167  		fakeT := &fakeTestingT{}
   168  		var err error
   169  		NilError(fakeT, err)
   170  		expectSuccess(t, fakeT)
   171  	})
   172  
   173  	t.Run("nil literal", func(t *testing.T) {
   174  		fakeT := &fakeTestingT{}
   175  		NilError(fakeT, nil)
   176  		expectSuccess(t, fakeT)
   177  	})
   178  
   179  	t.Run("interface with non-nil type", func(t *testing.T) {
   180  		fakeT := &fakeTestingT{}
   181  		var customErr *customError
   182  		NilError(fakeT, customErr)
   183  		expected := "assertion failed: error is not nil: error has type *assert.customError"
   184  		expectFailNowed(t, fakeT, expected)
   185  	})
   186  
   187  	t.Run("non-nil error", func(t *testing.T) {
   188  		fakeT := &fakeTestingT{}
   189  		NilError(fakeT, fmt.Errorf("this is the error"))
   190  		expectFailNowed(t, fakeT, "assertion failed: error is not nil: this is the error")
   191  	})
   192  
   193  	t.Run("non-nil error with struct type", func(t *testing.T) {
   194  		fakeT := &fakeTestingT{}
   195  		err := structError{}
   196  		NilError(fakeT, err)
   197  		expectFailNowed(t, fakeT, "assertion failed: error is not nil: this is a struct")
   198  	})
   199  
   200  	t.Run("non-nil error with map type", func(t *testing.T) {
   201  		fakeT := &fakeTestingT{}
   202  		var err mapError
   203  		NilError(fakeT, err)
   204  		expectFailNowed(t, fakeT, "assertion failed: error is not nil: ")
   205  	})
   206  }
   207  
   208  type structError struct{}
   209  
   210  func (structError) Error() string {
   211  	return "this is a struct"
   212  }
   213  
   214  type mapError map[int]string
   215  
   216  func (m mapError) Error() string {
   217  	return m[0]
   218  }
   219  
   220  func TestCheckFailure(t *testing.T) {
   221  	fakeT := &fakeTestingT{}
   222  
   223  	if Check(fakeT, 1 == 2) {
   224  		t.Error("expected check to return false on failure")
   225  	}
   226  	expectFailed(t, fakeT, "assertion failed: 1 is not 2")
   227  }
   228  
   229  func TestCheckSuccess(t *testing.T) {
   230  	fakeT := &fakeTestingT{}
   231  
   232  	if !Check(fakeT, true) {
   233  		t.Error("expected check to return true on success")
   234  	}
   235  	expectSuccess(t, fakeT)
   236  }
   237  
   238  func TestCheckEqualFailure(t *testing.T) {
   239  	fakeT := &fakeTestingT{}
   240  
   241  	actual, expected := 5, 9
   242  	Check(fakeT, cmp.Equal(actual, expected))
   243  	expectFailed(t, fakeT, "assertion failed: 5 (actual int) != 9 (expected int)")
   244  }
   245  
   246  func TestCheck_MultipleFunctionsOnTheSameLine(t *testing.T) {
   247  	fakeT := &fakeTestingT{}
   248  
   249  	f := func(bool) {}
   250  	f(Check(fakeT, false))
   251  	// TODO: update the expected when there is a more correct fix
   252  	expectFailed(t, fakeT,
   253  		"assertion failed: but assert failed to find the expression to print")
   254  }
   255  
   256  func TestEqualSuccess(t *testing.T) {
   257  	fakeT := &fakeTestingT{}
   258  
   259  	Equal(fakeT, 1, 1)
   260  	expectSuccess(t, fakeT)
   261  
   262  	Equal(fakeT, "abcd", "abcd")
   263  	expectSuccess(t, fakeT)
   264  }
   265  
   266  func TestEqualFailure(t *testing.T) {
   267  	fakeT := &fakeTestingT{}
   268  
   269  	actual, expected := 1, 3
   270  	Equal(fakeT, actual, expected)
   271  	expectFailNowed(t, fakeT, "assertion failed: 1 (actual int) != 3 (expected int)")
   272  }
   273  
   274  func TestEqualFailureTypes(t *testing.T) {
   275  	fakeT := &fakeTestingT{}
   276  
   277  	Equal(fakeT, 3, uint(3))
   278  	expectFailNowed(t, fakeT, `assertion failed: 3 (int) != 3 (uint)`)
   279  }
   280  
   281  func TestEqualFailureWithSelectorArgument(t *testing.T) {
   282  	fakeT := &fakeTestingT{}
   283  
   284  	type tc struct {
   285  		expected string
   286  	}
   287  	var testcase = tc{expected: "foo"}
   288  
   289  	Equal(fakeT, "ok", testcase.expected)
   290  	expectFailNowed(t, fakeT,
   291  		"assertion failed: ok (string) != foo (testcase.expected string)")
   292  }
   293  
   294  func TestEqualFailureWithIndexExpr(t *testing.T) {
   295  	fakeT := &fakeTestingT{}
   296  
   297  	expected := map[string]string{"foo": "bar"}
   298  	Equal(fakeT, "ok", expected["foo"])
   299  	expectFailNowed(t, fakeT,
   300  		`assertion failed: ok (string) != bar (expected["foo"] string)`)
   301  }
   302  
   303  func TestEqualFailureWithCallExprArgument(t *testing.T) {
   304  	fakeT := &fakeTestingT{}
   305  	ce := customError{}
   306  	Equal(fakeT, "", ce.Error())
   307  	expectFailNowed(t, fakeT,
   308  		"assertion failed:  (string) != custom error (string)")
   309  }
   310  
   311  func TestAssertFailureWithOfflineComparison(t *testing.T) {
   312  	fakeT := &fakeTestingT{}
   313  	a := 1
   314  	b := 2
   315  	// store comparison in a variable, so ast lookup can't find it
   316  	comparison := cmp.Equal(a, b)
   317  	Assert(fakeT, comparison)
   318  	// expected value wont have variable names
   319  	expectFailNowed(t, fakeT, "assertion failed: 1 (int) != 2 (int)")
   320  }
   321  
   322  type testingT interface {
   323  	Errorf(msg string, args ...interface{})
   324  	Fatalf(msg string, args ...interface{})
   325  }
   326  
   327  func expectFailNowed(t testingT, fakeT *fakeTestingT, expected string) {
   328  	if ht, ok := t.(helperT); ok {
   329  		ht.Helper()
   330  	}
   331  	if fakeT.failed {
   332  		t.Errorf("should not have failed, got messages %s", fakeT.msgs)
   333  	}
   334  	if !fakeT.failNowed {
   335  		t.Fatalf("should have failNowed with message %s", expected)
   336  	}
   337  	if fakeT.msgs[0] != expected {
   338  		t.Fatalf("should have failure message %q, got %q", expected, fakeT.msgs[0])
   339  	}
   340  }
   341  
   342  func expectFailed(t testingT, fakeT *fakeTestingT, expected string) {
   343  	if ht, ok := t.(helperT); ok {
   344  		ht.Helper()
   345  	}
   346  	if fakeT.failNowed {
   347  		t.Errorf("should not have failNowed, got messages %s", fakeT.msgs)
   348  	}
   349  	if !fakeT.failed {
   350  		t.Fatalf("should have failed with message %s", expected)
   351  	}
   352  	if fakeT.msgs[0] != expected {
   353  		t.Fatalf("should have failure message %q, got %q", expected, fakeT.msgs[0])
   354  	}
   355  }
   356  
   357  func expectSuccess(t testingT, fakeT *fakeTestingT) {
   358  	if ht, ok := t.(helperT); ok {
   359  		ht.Helper()
   360  	}
   361  	if fakeT.failNowed {
   362  		t.Errorf("should not have failNowed, got messages %s", fakeT.msgs)
   363  	}
   364  	if fakeT.failed {
   365  		t.Errorf("should not have failed, got messages %s", fakeT.msgs)
   366  	}
   367  }
   368  
   369  type stub struct {
   370  	a string
   371  	b int
   372  }
   373  
   374  func TestDeepEqualSuccess(t *testing.T) {
   375  	actual := stub{"ok", 1}
   376  	expected := stub{"ok", 1}
   377  
   378  	fakeT := &fakeTestingT{}
   379  	DeepEqual(fakeT, actual, expected, gocmp.AllowUnexported(stub{}))
   380  	expectSuccess(t, fakeT)
   381  }
   382  
   383  func TestDeepEqualFailure(t *testing.T) {
   384  	actual := stub{"ok", 1}
   385  	expected := stub{"ok", 2}
   386  
   387  	fakeT := &fakeTestingT{}
   388  	DeepEqual(fakeT, actual, expected, gocmp.AllowUnexported(stub{}))
   389  	if !fakeT.failNowed {
   390  		t.Fatal("should have failNowed")
   391  	}
   392  }
   393  
   394  func TestErrorFailure(t *testing.T) {
   395  	t.Run("nil error", func(t *testing.T) {
   396  		fakeT := &fakeTestingT{}
   397  
   398  		var err error
   399  		Error(fakeT, err, "this error")
   400  		expectFailNowed(t, fakeT, "assertion failed: expected an error, got nil")
   401  	})
   402  	t.Run("different error", func(t *testing.T) {
   403  		fakeT := &fakeTestingT{}
   404  
   405  		err := fmt.Errorf("the actual error")
   406  		Error(fakeT, err, "this error")
   407  		expected := `assertion failed: expected error "this error", got "the actual error"`
   408  		expectFailNowed(t, fakeT, expected)
   409  	})
   410  }
   411  
   412  func TestErrorContainsFailure(t *testing.T) {
   413  	t.Run("nil error", func(t *testing.T) {
   414  		fakeT := &fakeTestingT{}
   415  
   416  		var err error
   417  		ErrorContains(fakeT, err, "this error")
   418  		expectFailNowed(t, fakeT, "assertion failed: expected an error, got nil")
   419  	})
   420  	t.Run("different error", func(t *testing.T) {
   421  		fakeT := &fakeTestingT{}
   422  
   423  		err := fmt.Errorf("the actual error")
   424  		ErrorContains(fakeT, err, "this error")
   425  		expected := `assertion failed: expected error to contain "this error", got "the actual error"`
   426  		expectFailNowed(t, fakeT, expected)
   427  	})
   428  }
   429  
   430  func TestErrorTypeFailure(t *testing.T) {
   431  	t.Run("nil error", func(t *testing.T) {
   432  		fakeT := &fakeTestingT{}
   433  
   434  		var err error
   435  		ErrorType(fakeT, err, os.IsNotExist)
   436  		expectFailNowed(t, fakeT, "assertion failed: error is nil, not os.IsNotExist")
   437  	})
   438  	t.Run("different error", func(t *testing.T) {
   439  		fakeT := &fakeTestingT{}
   440  
   441  		err := fmt.Errorf("the actual error")
   442  		ErrorType(fakeT, err, os.IsNotExist)
   443  		expected := `assertion failed: error is the actual error (*errors.errorString), not os.IsNotExist`
   444  		expectFailNowed(t, fakeT, expected)
   445  	})
   446  }
   447  
   448  func TestErrorIs(t *testing.T) {
   449  	t.Run("nil error", func(t *testing.T) {
   450  		fakeT := &fakeTestingT{}
   451  
   452  		var err error
   453  		ErrorIs(fakeT, err, os.ErrNotExist)
   454  		expected := `assertion failed: error is nil, not "file does not exist" (os.ErrNotExist)`
   455  		expectFailNowed(t, fakeT, expected)
   456  	})
   457  	t.Run("different error", func(t *testing.T) {
   458  		fakeT := &fakeTestingT{}
   459  
   460  		err := fmt.Errorf("the actual error")
   461  		ErrorIs(fakeT, err, os.ErrNotExist)
   462  		expected := `assertion failed: error is "the actual error", not "file does not exist" (os.ErrNotExist)`
   463  		expectFailNowed(t, fakeT, expected)
   464  	})
   465  	t.Run("same error", func(t *testing.T) {
   466  		fakeT := &fakeTestingT{}
   467  
   468  		err := fmt.Errorf("some wrapping: %w", os.ErrNotExist)
   469  		ErrorIs(fakeT, err, os.ErrNotExist)
   470  		expectSuccess(t, fakeT)
   471  	})
   472  }
   473  

View as plain text