...

Source file src/github.com/go-test/deep/deep_test.go

Documentation: github.com/go-test/deep

     1  package deep_test
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"reflect"
     7  	"sort"
     8  	"testing"
     9  	"time"
    10  	"unsafe"
    11  
    12  	"github.com/go-test/deep"
    13  	v1 "github.com/go-test/deep/test/v1"
    14  	v2 "github.com/go-test/deep/test/v2"
    15  )
    16  
    17  func TestString(t *testing.T) {
    18  	diff := deep.Equal("foo", "foo")
    19  	if len(diff) > 0 {
    20  		t.Error("should be equal:", diff)
    21  	}
    22  
    23  	diff = deep.Equal("foo", "bar")
    24  	if diff == nil {
    25  		t.Fatal("no diff")
    26  	}
    27  	if len(diff) != 1 {
    28  		t.Error("too many diff:", diff)
    29  	}
    30  	if diff[0] != "foo != bar" {
    31  		t.Error("wrong diff:", diff[0])
    32  	}
    33  }
    34  
    35  func TestFloat(t *testing.T) {
    36  	diff := deep.Equal(1.1, 1.1)
    37  	if len(diff) > 0 {
    38  		t.Error("should be equal:", diff)
    39  	}
    40  
    41  	diff = deep.Equal(1.1234561, 1.1234562)
    42  	if diff == nil {
    43  		t.Error("no diff")
    44  	}
    45  
    46  	defaultFloatPrecision := deep.FloatPrecision
    47  	deep.FloatPrecision = 6
    48  	defer func() { deep.FloatPrecision = defaultFloatPrecision }()
    49  
    50  	diff = deep.Equal(1.1234561, 1.1234562)
    51  	if len(diff) > 0 {
    52  		t.Error("should be equal:", diff)
    53  	}
    54  
    55  	diff = deep.Equal(1.123456, 1.123457)
    56  	if diff == nil {
    57  		t.Fatal("no diff")
    58  	}
    59  	if len(diff) != 1 {
    60  		t.Error("too many diff:", diff)
    61  	}
    62  	if diff[0] != "1.123456 != 1.123457" {
    63  		t.Error("wrong diff:", diff[0])
    64  	}
    65  
    66  }
    67  
    68  func TestInt(t *testing.T) {
    69  	diff := deep.Equal(1, 1)
    70  	if len(diff) > 0 {
    71  		t.Error("should be equal:", diff)
    72  	}
    73  
    74  	diff = deep.Equal(1, 2)
    75  	if diff == nil {
    76  		t.Fatal("no diff")
    77  	}
    78  	if len(diff) != 1 {
    79  		t.Error("too many diff:", diff)
    80  	}
    81  	if diff[0] != "1 != 2" {
    82  		t.Error("wrong diff:", diff[0])
    83  	}
    84  }
    85  
    86  func TestUint(t *testing.T) {
    87  	diff := deep.Equal(uint(2), uint(2))
    88  	if len(diff) > 0 {
    89  		t.Error("should be equal:", diff)
    90  	}
    91  
    92  	diff = deep.Equal(uint(2), uint(3))
    93  	if diff == nil {
    94  		t.Fatal("no diff")
    95  	}
    96  	if len(diff) != 1 {
    97  		t.Error("too many diff:", diff)
    98  	}
    99  	if diff[0] != "2 != 3" {
   100  		t.Error("wrong diff:", diff[0])
   101  	}
   102  }
   103  
   104  func TestBool(t *testing.T) {
   105  	diff := deep.Equal(true, true)
   106  	if len(diff) > 0 {
   107  		t.Error("should be equal:", diff)
   108  	}
   109  
   110  	diff = deep.Equal(false, false)
   111  	if len(diff) > 0 {
   112  		t.Error("should be equal:", diff)
   113  	}
   114  
   115  	diff = deep.Equal(true, false)
   116  	if diff == nil {
   117  		t.Fatal("no diff")
   118  	}
   119  	if len(diff) != 1 {
   120  		t.Error("too many diff:", diff)
   121  	}
   122  	if diff[0] != "true != false" { // unless you're fipar
   123  		t.Error("wrong diff:", diff[0])
   124  	}
   125  }
   126  
   127  func TestTypeMismatch(t *testing.T) {
   128  	type T1 int // same type kind (int)
   129  	type T2 int // but different type
   130  	var t1 T1 = 1
   131  	var t2 T2 = 1
   132  	diff := deep.Equal(t1, t2)
   133  	if diff == nil {
   134  		t.Fatal("no diff")
   135  	}
   136  	if len(diff) != 1 {
   137  		t.Error("too many diff:", diff)
   138  	}
   139  	if diff[0] != "deep_test.T1 != deep_test.T2" {
   140  		t.Error("wrong diff:", diff[0])
   141  	}
   142  
   143  	// Same pkg name but differnet full paths
   144  	// https://github.com/go-test/deep/issues/39
   145  	err1 := v1.Error{}
   146  	err2 := v2.Error{}
   147  	diff = deep.Equal(err1, err2)
   148  	if diff == nil {
   149  		t.Fatal("no diff")
   150  	}
   151  	if len(diff) != 1 {
   152  		t.Error("too many diff:", diff)
   153  	}
   154  	if diff[0] != "github.com/go-test/deep/test/v1.Error != github.com/go-test/deep/test/v2.Error" {
   155  		t.Error("wrong diff:", diff[0])
   156  	}
   157  }
   158  
   159  func TestKindMismatch(t *testing.T) {
   160  	deep.LogErrors = true
   161  
   162  	var x int = 100
   163  	var y float64 = 100
   164  	diff := deep.Equal(x, y)
   165  	if diff == nil {
   166  		t.Fatal("no diff")
   167  	}
   168  	if len(diff) != 1 {
   169  		t.Error("too many diff:", diff)
   170  	}
   171  	if diff[0] != "int != float64" {
   172  		t.Error("wrong diff:", diff[0])
   173  	}
   174  
   175  	deep.LogErrors = false
   176  }
   177  
   178  func TestDeepRecursion(t *testing.T) {
   179  	deep.MaxDepth = 2
   180  	defer func() { deep.MaxDepth = 10 }()
   181  
   182  	type s3 struct {
   183  		S int
   184  	}
   185  	type s2 struct {
   186  		S s3
   187  	}
   188  	type s1 struct {
   189  		S s2
   190  	}
   191  	foo := map[string]s1{
   192  		"foo": { // 1
   193  			S: s2{ // 2
   194  				S: s3{ // 3
   195  					S: 42, // 4
   196  				},
   197  			},
   198  		},
   199  	}
   200  	bar := map[string]s1{
   201  		"foo": {
   202  			S: s2{
   203  				S: s3{
   204  					S: 100,
   205  				},
   206  			},
   207  		},
   208  	}
   209  	// No diffs because MaxDepth=2 prevents seeing the diff at 3rd level down
   210  	diff := deep.Equal(foo, bar)
   211  	if diff != nil {
   212  		t.Errorf("got %d diffs, expected none: %v", len(diff), diff)
   213  	}
   214  
   215  	defaultMaxDepth := deep.MaxDepth
   216  	deep.MaxDepth = 4
   217  	defer func() { deep.MaxDepth = defaultMaxDepth }()
   218  
   219  	diff = deep.Equal(foo, bar)
   220  	if diff == nil {
   221  		t.Fatal("no diff")
   222  	}
   223  	if len(diff) != 1 {
   224  		t.Error("too many diff:", diff)
   225  	}
   226  	if diff[0] != "map[foo].S.S.S: 42 != 100" {
   227  		t.Error("wrong diff:", diff[0])
   228  	}
   229  }
   230  
   231  func TestMaxDiff(t *testing.T) {
   232  	a := []int{1, 2, 3, 4, 5, 6, 7}
   233  	b := []int{0, 0, 0, 0, 0, 0, 0}
   234  
   235  	defaultMaxDiff := deep.MaxDiff
   236  	deep.MaxDiff = 3
   237  	defer func() { deep.MaxDiff = defaultMaxDiff }()
   238  
   239  	diff := deep.Equal(a, b)
   240  	if diff == nil {
   241  		t.Fatal("no diffs")
   242  	}
   243  	if len(diff) != deep.MaxDiff {
   244  		t.Errorf("got %d diffs, expected %d", len(diff), deep.MaxDiff)
   245  	}
   246  
   247  	defaultCompareUnexportedFields := deep.CompareUnexportedFields
   248  	deep.CompareUnexportedFields = true
   249  	defer func() { deep.CompareUnexportedFields = defaultCompareUnexportedFields }()
   250  	type fiveFields struct {
   251  		a int // unexported fields require ^
   252  		b int
   253  		c int
   254  		d int
   255  		e int
   256  	}
   257  	t1 := fiveFields{1, 2, 3, 4, 5}
   258  	t2 := fiveFields{0, 0, 0, 0, 0}
   259  	diff = deep.Equal(t1, t2)
   260  	if diff == nil {
   261  		t.Fatal("no diffs")
   262  	}
   263  	if len(diff) != deep.MaxDiff {
   264  		t.Errorf("got %d diffs, expected %d", len(diff), deep.MaxDiff)
   265  	}
   266  
   267  	// Same keys, too many diffs
   268  	m1 := map[int]int{
   269  		1: 1,
   270  		2: 2,
   271  		3: 3,
   272  		4: 4,
   273  		5: 5,
   274  	}
   275  	m2 := map[int]int{
   276  		1: 0,
   277  		2: 0,
   278  		3: 0,
   279  		4: 0,
   280  		5: 0,
   281  	}
   282  	diff = deep.Equal(m1, m2)
   283  	if diff == nil {
   284  		t.Fatal("no diffs")
   285  	}
   286  	if len(diff) != deep.MaxDiff {
   287  		t.Log(diff)
   288  		t.Errorf("got %d diffs, expected %d", len(diff), deep.MaxDiff)
   289  	}
   290  
   291  	// Too many missing keys
   292  	m1 = map[int]int{
   293  		1: 1,
   294  		2: 2,
   295  	}
   296  	m2 = map[int]int{
   297  		1: 1,
   298  		2: 2,
   299  		3: 0,
   300  		4: 0,
   301  		5: 0,
   302  		6: 0,
   303  		7: 0,
   304  	}
   305  	diff = deep.Equal(m1, m2)
   306  	if diff == nil {
   307  		t.Fatal("no diffs")
   308  	}
   309  	if len(diff) != deep.MaxDiff {
   310  		t.Log(diff)
   311  		t.Errorf("got %d diffs, expected %d", len(diff), deep.MaxDiff)
   312  	}
   313  }
   314  
   315  func TestNotHandled(t *testing.T) {
   316  	// UnsafePointer is pretty much the only kind not handled now
   317  	v := []int{1}
   318  	a := unsafe.Pointer(&v)
   319  	b := unsafe.Pointer(&v)
   320  	// UnsafePointer added in Go 1.88. Use these lines once this pkg
   321  	// no longer supports Go 1.17.
   322  	//a := reflect.ValueOf(v).UnsafePointer()
   323  	//b := reflect.ValueOf(v).UnsafePointer()
   324  	diff := deep.Equal(a, b)
   325  	if len(diff) > 0 {
   326  		t.Error("got diffs:", diff)
   327  	}
   328  }
   329  
   330  func TestStruct(t *testing.T) {
   331  	type s1 struct {
   332  		id     int
   333  		Name   string
   334  		Number int
   335  	}
   336  	sa := s1{
   337  		id:     1,
   338  		Name:   "foo",
   339  		Number: 2,
   340  	}
   341  	sb := sa
   342  	diff := deep.Equal(sa, sb)
   343  	if len(diff) > 0 {
   344  		t.Error("should be equal:", diff)
   345  	}
   346  
   347  	sb.Name = "bar"
   348  	diff = deep.Equal(sa, sb)
   349  	if diff == nil {
   350  		t.Fatal("no diff")
   351  	}
   352  	if len(diff) != 1 {
   353  		t.Error("too many diff:", diff)
   354  	}
   355  	if diff[0] != "Name: foo != bar" {
   356  		t.Error("wrong diff:", diff[0])
   357  	}
   358  
   359  	sb.Number = 22
   360  	diff = deep.Equal(sa, sb)
   361  	if diff == nil {
   362  		t.Fatal("no diff")
   363  	}
   364  	if len(diff) != 2 {
   365  		t.Error("too many diff:", diff)
   366  	}
   367  	if diff[0] != "Name: foo != bar" {
   368  		t.Error("wrong diff:", diff[0])
   369  	}
   370  	if diff[1] != "Number: 2 != 22" {
   371  		t.Error("wrong diff:", diff[1])
   372  	}
   373  
   374  	sb.id = 11
   375  	diff = deep.Equal(sa, sb)
   376  	if diff == nil {
   377  		t.Fatal("no diff")
   378  	}
   379  	if len(diff) != 2 {
   380  		t.Error("too many diff:", diff)
   381  	}
   382  	if diff[0] != "Name: foo != bar" {
   383  		t.Error("wrong diff:", diff[0])
   384  	}
   385  	if diff[1] != "Number: 2 != 22" {
   386  		t.Error("wrong diff:", diff[1])
   387  	}
   388  }
   389  
   390  func TestStructWithTags(t *testing.T) {
   391  	type s1 struct {
   392  		same                    int
   393  		modified                int
   394  		sameIgnored             int `deep:"-"`
   395  		modifiedIgnored         int `deep:"-"`
   396  		ExportedSame            int
   397  		ExportedModified        int
   398  		ExportedSameIgnored     int `deep:"-"`
   399  		ExportedModifiedIgnored int `deep:"-"`
   400  	}
   401  	type s2 struct {
   402  		s1
   403  		same                    int
   404  		modified                int
   405  		sameIgnored             int `deep:"-"`
   406  		modifiedIgnored         int `deep:"-"`
   407  		ExportedSame            int
   408  		ExportedModified        int
   409  		ExportedSameIgnored     int `deep:"-"`
   410  		ExportedModifiedIgnored int `deep:"-"`
   411  		recurseInline           s1
   412  		recursePtr              *s2
   413  	}
   414  	sa := s2{
   415  		s1: s1{
   416  			same:                    0,
   417  			modified:                1,
   418  			sameIgnored:             2,
   419  			modifiedIgnored:         3,
   420  			ExportedSame:            4,
   421  			ExportedModified:        5,
   422  			ExportedSameIgnored:     6,
   423  			ExportedModifiedIgnored: 7,
   424  		},
   425  		same:                    0,
   426  		modified:                1,
   427  		sameIgnored:             2,
   428  		modifiedIgnored:         3,
   429  		ExportedSame:            4,
   430  		ExportedModified:        5,
   431  		ExportedSameIgnored:     6,
   432  		ExportedModifiedIgnored: 7,
   433  		recurseInline: s1{
   434  			same:                    0,
   435  			modified:                1,
   436  			sameIgnored:             2,
   437  			modifiedIgnored:         3,
   438  			ExportedSame:            4,
   439  			ExportedModified:        5,
   440  			ExportedSameIgnored:     6,
   441  			ExportedModifiedIgnored: 7,
   442  		},
   443  		recursePtr: &s2{
   444  			same:                    0,
   445  			modified:                1,
   446  			sameIgnored:             2,
   447  			modifiedIgnored:         3,
   448  			ExportedSame:            4,
   449  			ExportedModified:        5,
   450  			ExportedSameIgnored:     6,
   451  			ExportedModifiedIgnored: 7,
   452  		},
   453  	}
   454  	sb := s2{
   455  		s1: s1{
   456  			same:                    0,
   457  			modified:                10,
   458  			sameIgnored:             2,
   459  			modifiedIgnored:         30,
   460  			ExportedSame:            4,
   461  			ExportedModified:        50,
   462  			ExportedSameIgnored:     6,
   463  			ExportedModifiedIgnored: 70,
   464  		},
   465  		same:                    0,
   466  		modified:                10,
   467  		sameIgnored:             2,
   468  		modifiedIgnored:         30,
   469  		ExportedSame:            4,
   470  		ExportedModified:        50,
   471  		ExportedSameIgnored:     6,
   472  		ExportedModifiedIgnored: 70,
   473  		recurseInline: s1{
   474  			same:                    0,
   475  			modified:                10,
   476  			sameIgnored:             2,
   477  			modifiedIgnored:         30,
   478  			ExportedSame:            4,
   479  			ExportedModified:        50,
   480  			ExportedSameIgnored:     6,
   481  			ExportedModifiedIgnored: 70,
   482  		},
   483  		recursePtr: &s2{
   484  			same:                    0,
   485  			modified:                10,
   486  			sameIgnored:             2,
   487  			modifiedIgnored:         30,
   488  			ExportedSame:            4,
   489  			ExportedModified:        50,
   490  			ExportedSameIgnored:     6,
   491  			ExportedModifiedIgnored: 70,
   492  		},
   493  	}
   494  
   495  	orig := deep.CompareUnexportedFields
   496  	deep.CompareUnexportedFields = true
   497  	diff := deep.Equal(sa, sb)
   498  	deep.CompareUnexportedFields = orig
   499  
   500  	want := []string{
   501  		"s1.modified: 1 != 10",
   502  		"s1.ExportedModified: 5 != 50",
   503  		"modified: 1 != 10",
   504  		"ExportedModified: 5 != 50",
   505  		"recurseInline.modified: 1 != 10",
   506  		"recurseInline.ExportedModified: 5 != 50",
   507  		"recursePtr.modified: 1 != 10",
   508  		"recursePtr.ExportedModified: 5 != 50",
   509  	}
   510  	if !reflect.DeepEqual(want, diff) {
   511  		t.Errorf("got %v, want %v", diff, want)
   512  	}
   513  }
   514  
   515  func TestNestedStruct(t *testing.T) {
   516  	type s2 struct {
   517  		Nickname string
   518  	}
   519  	type s1 struct {
   520  		Name  string
   521  		Alias s2
   522  	}
   523  	sa := s1{
   524  		Name:  "Robert",
   525  		Alias: s2{Nickname: "Bob"},
   526  	}
   527  	sb := sa
   528  	diff := deep.Equal(sa, sb)
   529  	if len(diff) > 0 {
   530  		t.Error("should be equal:", diff)
   531  	}
   532  
   533  	sb.Alias.Nickname = "Bobby"
   534  	diff = deep.Equal(sa, sb)
   535  	if diff == nil {
   536  		t.Fatal("no diff")
   537  	}
   538  	if len(diff) != 1 {
   539  		t.Error("too many diff:", diff)
   540  	}
   541  	if diff[0] != "Alias.Nickname: Bob != Bobby" {
   542  		t.Error("wrong diff:", diff[0])
   543  	}
   544  }
   545  
   546  func TestMap(t *testing.T) {
   547  	ma := map[string]int{
   548  		"foo": 1,
   549  		"bar": 2,
   550  	}
   551  	mb := map[string]int{
   552  		"foo": 1,
   553  		"bar": 2,
   554  	}
   555  	diff := deep.Equal(ma, mb)
   556  	if len(diff) > 0 {
   557  		t.Error("should be equal:", diff)
   558  	}
   559  
   560  	diff = deep.Equal(ma, ma)
   561  	if len(diff) > 0 {
   562  		t.Error("should be equal:", diff)
   563  	}
   564  
   565  	mb["foo"] = 111
   566  	diff = deep.Equal(ma, mb)
   567  	if diff == nil {
   568  		t.Fatal("no diff")
   569  	}
   570  	if len(diff) != 1 {
   571  		t.Error("too many diff:", diff)
   572  	}
   573  	if diff[0] != "map[foo]: 1 != 111" {
   574  		t.Error("wrong diff:", diff[0])
   575  	}
   576  
   577  	delete(mb, "foo")
   578  	diff = deep.Equal(ma, mb)
   579  	if diff == nil {
   580  		t.Fatal("no diff")
   581  	}
   582  	if len(diff) != 1 {
   583  		t.Error("too many diff:", diff)
   584  	}
   585  	if diff[0] != "map[foo]: 1 != <does not have key>" {
   586  		t.Error("wrong diff:", diff[0])
   587  	}
   588  
   589  	diff = deep.Equal(mb, ma)
   590  	if diff == nil {
   591  		t.Fatal("no diff")
   592  	}
   593  	if len(diff) != 1 {
   594  		t.Error("too many diff:", diff)
   595  	}
   596  	if diff[0] != "map[foo]: <does not have key> != 1" {
   597  		t.Error("wrong diff:", diff[0])
   598  	}
   599  
   600  	var mc map[string]int
   601  	diff = deep.Equal(ma, mc)
   602  	if diff == nil {
   603  		t.Fatal("no diff")
   604  	}
   605  	if len(diff) != 1 {
   606  		t.Error("too many diff:", diff)
   607  	}
   608  	// handle hash order randomness
   609  	if diff[0] != "map[foo:1 bar:2] != <nil map>" && diff[0] != "map[bar:2 foo:1] != <nil map>" {
   610  		t.Error("wrong diff:", diff[0])
   611  	}
   612  
   613  	diff = deep.Equal(mc, ma)
   614  	if diff == nil {
   615  		t.Fatal("no diff")
   616  	}
   617  	if len(diff) != 1 {
   618  		t.Error("too many diff:", diff)
   619  	}
   620  	if diff[0] != "<nil map> != map[foo:1 bar:2]" && diff[0] != "<nil map> != map[bar:2 foo:1]" {
   621  		t.Error("wrong diff:", diff[0])
   622  	}
   623  }
   624  
   625  func TestArray(t *testing.T) {
   626  	a := [3]int{1, 2, 3}
   627  	b := [3]int{1, 2, 3}
   628  
   629  	diff := deep.Equal(a, b)
   630  	if len(diff) > 0 {
   631  		t.Error("should be equal:", diff)
   632  	}
   633  
   634  	diff = deep.Equal(a, a)
   635  	if len(diff) > 0 {
   636  		t.Error("should be equal:", diff)
   637  	}
   638  
   639  	b[2] = 333
   640  	diff = deep.Equal(a, b)
   641  	if diff == nil {
   642  		t.Fatal("no diff")
   643  	}
   644  	if len(diff) != 1 {
   645  		t.Error("too many diff:", diff)
   646  	}
   647  	if diff[0] != "array[2]: 3 != 333" {
   648  		t.Error("wrong diff:", diff[0])
   649  	}
   650  
   651  	c := [3]int{1, 2, 2}
   652  	diff = deep.Equal(a, c)
   653  	if diff == nil {
   654  		t.Fatal("no diff")
   655  	}
   656  	if len(diff) != 1 {
   657  		t.Error("too many diff:", diff)
   658  	}
   659  	if diff[0] != "array[2]: 3 != 2" {
   660  		t.Error("wrong diff:", diff[0])
   661  	}
   662  
   663  	var d [2]int
   664  	diff = deep.Equal(a, d)
   665  	if diff == nil {
   666  		t.Fatal("no diff")
   667  	}
   668  	if len(diff) != 1 {
   669  		t.Error("too many diff:", diff)
   670  	}
   671  	if diff[0] != "[3]int != [2]int" {
   672  		t.Error("wrong diff:", diff[0])
   673  	}
   674  
   675  	e := [12]int{}
   676  	f := [12]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
   677  	diff = deep.Equal(e, f)
   678  	if diff == nil {
   679  		t.Fatal("no diff")
   680  	}
   681  	if len(diff) != deep.MaxDiff {
   682  		t.Error("not enough diffs:", diff)
   683  	}
   684  	for i := 0; i < deep.MaxDiff; i++ {
   685  		if diff[i] != fmt.Sprintf("array[%d]: 0 != %d", i+1, i+1) {
   686  			t.Error("wrong diff:", diff[i])
   687  		}
   688  	}
   689  }
   690  
   691  func TestSlice(t *testing.T) {
   692  	a := []int{1, 2, 3}
   693  	b := []int{1, 2, 3}
   694  
   695  	diff := deep.Equal(a, b)
   696  	if len(diff) > 0 {
   697  		t.Error("should be equal:", diff)
   698  	}
   699  
   700  	diff = deep.Equal(a, a)
   701  	if len(diff) > 0 {
   702  		t.Error("should be equal:", diff)
   703  	}
   704  
   705  	b[2] = 333
   706  	diff = deep.Equal(a, b)
   707  	if diff == nil {
   708  		t.Fatal("no diff")
   709  	}
   710  	if len(diff) != 1 {
   711  		t.Error("too many diff:", diff)
   712  	}
   713  	if diff[0] != "slice[2]: 3 != 333" {
   714  		t.Error("wrong diff:", diff[0])
   715  	}
   716  
   717  	b = b[0:2]
   718  	diff = deep.Equal(a, b)
   719  	if diff == nil {
   720  		t.Fatal("no diff")
   721  	}
   722  	if len(diff) != 1 {
   723  		t.Error("too many diff:", diff)
   724  	}
   725  	if diff[0] != "slice[2]: 3 != <no value>" {
   726  		t.Error("wrong diff:", diff[0])
   727  	}
   728  
   729  	diff = deep.Equal(b, a)
   730  	if diff == nil {
   731  		t.Fatal("no diff")
   732  	}
   733  	if len(diff) != 1 {
   734  		t.Error("too many diff:", diff)
   735  	}
   736  	if diff[0] != "slice[2]: <no value> != 3" {
   737  		t.Error("wrong diff:", diff[0])
   738  	}
   739  
   740  	var c []int
   741  	diff = deep.Equal(a, c)
   742  	if diff == nil {
   743  		t.Fatal("no diff")
   744  	}
   745  	if len(diff) != 1 {
   746  		t.Error("too many diff:", diff)
   747  	}
   748  	if diff[0] != "[1 2 3] != <nil slice>" {
   749  		t.Error("wrong diff:", diff[0])
   750  	}
   751  
   752  	diff = deep.Equal(c, a)
   753  	if diff == nil {
   754  		t.Fatal("no diff")
   755  	}
   756  	if len(diff) != 1 {
   757  		t.Error("too many diff:", diff)
   758  	}
   759  	if diff[0] != "<nil slice> != [1 2 3]" {
   760  		t.Error("wrong diff:", diff[0])
   761  	}
   762  }
   763  
   764  func TestSiblingSlices(t *testing.T) {
   765  	father := []int{1, 2, 3, 4}
   766  	a := father[0:3]
   767  	b := father[0:3]
   768  
   769  	diff := deep.Equal(a, b)
   770  	if len(diff) > 0 {
   771  		t.Error("should be equal:", diff)
   772  	}
   773  	diff = deep.Equal(b, a)
   774  	if len(diff) > 0 {
   775  		t.Error("should be equal:", diff)
   776  	}
   777  
   778  	a = father[0:3]
   779  	b = father[0:2]
   780  	diff = deep.Equal(a, b)
   781  	if diff == nil {
   782  		t.Fatal("no diff")
   783  	}
   784  	if len(diff) != 1 {
   785  		t.Error("too many diff:", diff)
   786  	}
   787  	if diff[0] != "slice[2]: 3 != <no value>" {
   788  		t.Error("wrong diff:", diff[0])
   789  	}
   790  
   791  	a = father[0:2]
   792  	b = father[0:3]
   793  
   794  	diff = deep.Equal(a, b)
   795  	if diff == nil {
   796  		t.Fatal("no diff")
   797  	}
   798  	if len(diff) != 1 {
   799  		t.Error("too many diff:", diff)
   800  	}
   801  	if diff[0] != "slice[2]: <no value> != 3" {
   802  		t.Error("wrong diff:", diff[0])
   803  	}
   804  
   805  	a = father[0:2]
   806  	b = father[2:4]
   807  
   808  	diff = deep.Equal(a, b)
   809  	if diff == nil {
   810  		t.Fatal("no diff")
   811  	}
   812  	if len(diff) != 2 {
   813  		t.Error("too many diff:", diff)
   814  	}
   815  	if diff[0] != "slice[0]: 1 != 3" {
   816  		t.Error("wrong diff:", diff[0])
   817  	}
   818  	if diff[1] != "slice[1]: 2 != 4" {
   819  		t.Error("wrong diff:", diff[1])
   820  	}
   821  
   822  	a = father[0:0]
   823  	b = father[1:1]
   824  
   825  	diff = deep.Equal(a, b)
   826  	if len(diff) > 0 {
   827  		t.Error("should be equal:", diff)
   828  	}
   829  	diff = deep.Equal(b, a)
   830  	if len(diff) > 0 {
   831  		t.Error("should be equal:", diff)
   832  	}
   833  }
   834  
   835  func TestEmptySlice(t *testing.T) {
   836  	a := []int{1}
   837  	b := []int{}
   838  	var c []int
   839  
   840  	// Non-empty is not equal to empty.
   841  	diff := deep.Equal(a, b)
   842  	if diff == nil {
   843  		t.Fatal("no diff")
   844  	}
   845  	if len(diff) != 1 {
   846  		t.Error("too many diff:", diff)
   847  	}
   848  	if diff[0] != "slice[0]: 1 != <no value>" {
   849  		t.Error("wrong diff:", diff[0])
   850  	}
   851  
   852  	// Empty is not equal to non-empty.
   853  	diff = deep.Equal(b, a)
   854  	if diff == nil {
   855  		t.Fatal("no diff")
   856  	}
   857  	if len(diff) != 1 {
   858  		t.Error("too many diff:", diff)
   859  	}
   860  	if diff[0] != "slice[0]: <no value> != 1" {
   861  		t.Error("wrong diff:", diff[0])
   862  	}
   863  
   864  	// Empty is not equal to nil.
   865  	diff = deep.Equal(b, c)
   866  	if diff == nil {
   867  		t.Fatal("no diff")
   868  	}
   869  	if len(diff) != 1 {
   870  		t.Error("too many diff:", diff)
   871  	}
   872  	if diff[0] != "[] != <nil slice>" {
   873  		t.Error("wrong diff:", diff[0])
   874  	}
   875  
   876  	// Nil is not equal to empty.
   877  	diff = deep.Equal(c, b)
   878  	if diff == nil {
   879  		t.Fatal("no diff")
   880  	}
   881  	if len(diff) != 1 {
   882  		t.Error("too many diff:", diff)
   883  	}
   884  	if diff[0] != "<nil slice> != []" {
   885  		t.Error("wrong diff:", diff[0])
   886  	}
   887  }
   888  
   889  func TestNilSlicesAreEmpty(t *testing.T) {
   890  	defaultNilSlicesAreEmpty := deep.NilSlicesAreEmpty
   891  	deep.NilSlicesAreEmpty = true
   892  	defer func() { deep.NilSlicesAreEmpty = defaultNilSlicesAreEmpty }()
   893  
   894  	a := []int{1}
   895  	b := []int{}
   896  	var c []int
   897  
   898  	// Empty is equal to nil.
   899  	diff := deep.Equal(b, c)
   900  	if len(diff) > 0 {
   901  		t.Error("should be equal:", diff)
   902  	}
   903  
   904  	// Nil is equal to empty.
   905  	diff = deep.Equal(c, b)
   906  	if len(diff) > 0 {
   907  		t.Error("should be equal:", diff)
   908  	}
   909  
   910  	// Non-empty is not equal to nil.
   911  	diff = deep.Equal(a, c)
   912  	if diff == nil {
   913  		t.Fatal("no diff")
   914  	}
   915  	if len(diff) != 1 {
   916  		t.Error("too many diff:", diff)
   917  	}
   918  	if diff[0] != "[1] != <nil slice>" {
   919  		t.Error("wrong diff:", diff[0])
   920  	}
   921  
   922  	// Nil is not equal to non-empty.
   923  	diff = deep.Equal(c, a)
   924  	if diff == nil {
   925  		t.Fatal("no diff")
   926  	}
   927  	if len(diff) != 1 {
   928  		t.Error("too many diff:", diff)
   929  	}
   930  	if diff[0] != "<nil slice> != [1]" {
   931  		t.Error("wrong diff:", diff[0])
   932  	}
   933  
   934  	// Non-empty is not equal to empty.
   935  	diff = deep.Equal(a, b)
   936  	if diff == nil {
   937  		t.Fatal("no diff")
   938  	}
   939  	if len(diff) != 1 {
   940  		t.Error("too many diff:", diff)
   941  	}
   942  	if diff[0] != "slice[0]: 1 != <no value>" {
   943  		t.Error("wrong diff:", diff[0])
   944  	}
   945  
   946  	// Empty is not equal to non-empty.
   947  	diff = deep.Equal(b, a)
   948  	if diff == nil {
   949  		t.Fatal("no diff")
   950  	}
   951  	if len(diff) != 1 {
   952  		t.Error("too many diff:", diff)
   953  	}
   954  	if diff[0] != "slice[0]: <no value> != 1" {
   955  		t.Error("wrong diff:", diff[0])
   956  	}
   957  }
   958  
   959  func TestNilMapsAreEmpty(t *testing.T) {
   960  	defaultNilMapsAreEmpty := deep.NilSlicesAreEmpty
   961  	deep.NilMapsAreEmpty = true
   962  	defer func() { deep.NilSlicesAreEmpty = defaultNilMapsAreEmpty }()
   963  
   964  	a := map[int]int{1: 1}
   965  	b := map[int]int{}
   966  	var c map[int]int
   967  
   968  	// Empty is equal to nil.
   969  	diff := deep.Equal(b, c)
   970  	if len(diff) > 0 {
   971  		t.Error("should be equal:", diff)
   972  	}
   973  
   974  	// Nil is equal to empty.
   975  	diff = deep.Equal(c, b)
   976  	if len(diff) > 0 {
   977  		t.Error("should be equal:", diff)
   978  	}
   979  
   980  	// Non-empty is not equal to nil.
   981  	diff = deep.Equal(a, c)
   982  	if diff == nil {
   983  		t.Fatal("no diff")
   984  	}
   985  	if len(diff) != 1 {
   986  		t.Error("too many diff:", diff)
   987  	}
   988  	if diff[0] != "map[1:1] != <nil map>" {
   989  		t.Error("wrong diff:", diff[0])
   990  	}
   991  
   992  	// Nil is not equal to non-empty.
   993  	diff = deep.Equal(c, a)
   994  	if diff == nil {
   995  		t.Fatal("no diff")
   996  	}
   997  	if len(diff) != 1 {
   998  		t.Error("too many diff:", diff)
   999  	}
  1000  	if diff[0] != "<nil map> != map[1:1]" {
  1001  		t.Error("wrong diff:", diff[0])
  1002  	}
  1003  
  1004  	// Non-empty is not equal to empty.
  1005  	diff = deep.Equal(a, b)
  1006  	if diff == nil {
  1007  		t.Fatal("no diff")
  1008  	}
  1009  	if len(diff) != 1 {
  1010  		t.Error("too many diff:", diff)
  1011  	}
  1012  	if diff[0] != "map[1]: 1 != <does not have key>" {
  1013  		t.Error("wrong diff:", diff[0])
  1014  	}
  1015  
  1016  	// Empty is not equal to non-empty.
  1017  	diff = deep.Equal(b, a)
  1018  	if diff == nil {
  1019  		t.Fatal("no diff")
  1020  	}
  1021  	if len(diff) != 1 {
  1022  		t.Error("too many diff:", diff)
  1023  	}
  1024  	if diff[0] != "map[1]: <does not have key> != 1" {
  1025  		t.Error("wrong diff:", diff[0])
  1026  	}
  1027  }
  1028  
  1029  func TestNilInterface(t *testing.T) {
  1030  	type T struct{ i int }
  1031  
  1032  	a := &T{i: 1}
  1033  	diff := deep.Equal(nil, a)
  1034  	if diff == nil {
  1035  		t.Fatal("no diff")
  1036  	}
  1037  	if len(diff) != 1 {
  1038  		t.Error("too many diff:", diff)
  1039  	}
  1040  	if diff[0] != "<nil pointer> != &{1}" {
  1041  		t.Error("wrong diff:", diff[0])
  1042  	}
  1043  
  1044  	diff = deep.Equal(a, nil)
  1045  	if diff == nil {
  1046  		t.Fatal("no diff")
  1047  	}
  1048  	if len(diff) != 1 {
  1049  		t.Error("too many diff:", diff)
  1050  	}
  1051  	if diff[0] != "&{1} != <nil pointer>" {
  1052  		t.Error("wrong diff:", diff[0])
  1053  	}
  1054  
  1055  	diff = deep.Equal(nil, nil)
  1056  	if len(diff) > 0 {
  1057  		t.Error("should be equal:", diff)
  1058  	}
  1059  }
  1060  
  1061  func TestPointer(t *testing.T) {
  1062  	type T struct{ i int }
  1063  
  1064  	a, b := &T{i: 1}, &T{i: 1}
  1065  	diff := deep.Equal(a, b)
  1066  	if len(diff) > 0 {
  1067  		t.Error("should be equal:", diff)
  1068  	}
  1069  
  1070  	a, b = nil, &T{}
  1071  	diff = deep.Equal(a, b)
  1072  	if diff == nil {
  1073  		t.Fatal("no diff")
  1074  	}
  1075  	if len(diff) != 1 {
  1076  		t.Error("too many diff:", diff)
  1077  	}
  1078  	if diff[0] != "<nil pointer> != deep_test.T" {
  1079  		t.Error("wrong diff:", diff[0])
  1080  	}
  1081  
  1082  	a, b = &T{}, nil
  1083  	diff = deep.Equal(a, b)
  1084  	if diff == nil {
  1085  		t.Fatal("no diff")
  1086  	}
  1087  	if len(diff) != 1 {
  1088  		t.Error("too many diff:", diff)
  1089  	}
  1090  	if diff[0] != "deep_test.T != <nil pointer>" {
  1091  		t.Error("wrong diff:", diff[0])
  1092  	}
  1093  
  1094  	a, b = nil, nil
  1095  	diff = deep.Equal(a, b)
  1096  	if len(diff) > 0 {
  1097  		t.Error("should be equal:", diff)
  1098  	}
  1099  }
  1100  
  1101  func TestTime(t *testing.T) {
  1102  	// In an interable kind (i.e. a struct)
  1103  	type sTime struct {
  1104  		T time.Time
  1105  	}
  1106  	now := time.Now()
  1107  	got := sTime{T: now}
  1108  	expect := sTime{T: now.Add(1 * time.Second)}
  1109  	diff := deep.Equal(got, expect)
  1110  	if len(diff) != 1 {
  1111  		t.Error("expected 1 diff:", diff)
  1112  	}
  1113  
  1114  	// Directly
  1115  	a := now
  1116  	b := now
  1117  	diff = deep.Equal(a, b)
  1118  	if len(diff) > 0 {
  1119  		t.Error("should be equal:", diff)
  1120  	}
  1121  
  1122  	// https://github.com/go-test/deep/issues/15
  1123  	type Time15 struct {
  1124  		time.Time
  1125  	}
  1126  	a15 := Time15{now}
  1127  	b15 := Time15{now}
  1128  	diff = deep.Equal(a15, b15)
  1129  	if len(diff) > 0 {
  1130  		t.Error("should be equal:", diff)
  1131  	}
  1132  
  1133  	later := now.Add(1 * time.Second)
  1134  	b15 = Time15{later}
  1135  	diff = deep.Equal(a15, b15)
  1136  	if len(diff) != 1 {
  1137  		t.Errorf("got %d diffs, expected 1: %s", len(diff), diff)
  1138  	}
  1139  
  1140  	// No diff in Equal should not affect diff of other fields (Foo)
  1141  	type Time17 struct {
  1142  		time.Time
  1143  		Foo int
  1144  	}
  1145  	a17 := Time17{Time: now, Foo: 1}
  1146  	b17 := Time17{Time: now, Foo: 2}
  1147  	diff = deep.Equal(a17, b17)
  1148  	if len(diff) != 1 {
  1149  		t.Errorf("got %d diffs, expected 1: %s", len(diff), diff)
  1150  	}
  1151  }
  1152  
  1153  func TestTimeUnexported(t *testing.T) {
  1154  	// https://github.com/go-test/deep/issues/18
  1155  	// Can't call Call() on exported Value func
  1156  	defaultCompareUnexportedFields := deep.CompareUnexportedFields
  1157  	deep.CompareUnexportedFields = true
  1158  	defer func() { deep.CompareUnexportedFields = defaultCompareUnexportedFields }()
  1159  
  1160  	now := time.Now()
  1161  	type hiddenTime struct {
  1162  		t time.Time
  1163  	}
  1164  	htA := &hiddenTime{t: now}
  1165  	htB := &hiddenTime{t: now}
  1166  	diff := deep.Equal(htA, htB)
  1167  	if len(diff) > 0 {
  1168  		t.Error("should be equal:", diff)
  1169  	}
  1170  
  1171  	// This doesn't call time.Time.Equal(), it compares the unexported fields
  1172  	// in time.Time, causing a diff like:
  1173  	// [t.wall: 13740788835924462040 != 13740788836998203864 t.ext: 1447549 != 1001447549]
  1174  	later := now.Add(1 * time.Second)
  1175  	htC := &hiddenTime{t: later}
  1176  	diff = deep.Equal(htA, htC)
  1177  
  1178  	expected := 1
  1179  	if _, ok := reflect.TypeOf(htA.t).FieldByName("ext"); ok {
  1180  		expected = 2
  1181  	}
  1182  	if len(diff) != expected {
  1183  		t.Errorf("got %d diffs, expected %d: %s", len(diff), expected, diff)
  1184  	}
  1185  }
  1186  
  1187  func TestInterface(t *testing.T) {
  1188  	a := map[string]interface{}{
  1189  		"foo": map[string]string{
  1190  			"bar": "a",
  1191  		},
  1192  	}
  1193  	b := map[string]interface{}{
  1194  		"foo": map[string]string{
  1195  			"bar": "b",
  1196  		},
  1197  	}
  1198  	diff := deep.Equal(a, b)
  1199  	if len(diff) == 0 {
  1200  		t.Fatalf("expected 1 diff, got zero")
  1201  	}
  1202  	if len(diff) != 1 {
  1203  		t.Errorf("expected 1 diff, got %d: %s", len(diff), diff)
  1204  	}
  1205  }
  1206  
  1207  func TestInterface2(t *testing.T) {
  1208  	defer func() {
  1209  		if val := recover(); val != nil {
  1210  			t.Fatalf("panic: %v", val)
  1211  		}
  1212  	}()
  1213  
  1214  	a := map[string]interface{}{
  1215  		"bar": 1,
  1216  	}
  1217  	b := map[string]interface{}{
  1218  		"bar": 1.23,
  1219  	}
  1220  	diff := deep.Equal(a, b)
  1221  	if len(diff) == 0 {
  1222  		t.Fatalf("expected 1 diff, got zero")
  1223  	}
  1224  	if len(diff) != 1 {
  1225  		t.Errorf("expected 1 diff, got %d: %s", len(diff), diff)
  1226  	}
  1227  }
  1228  
  1229  func TestInterface3(t *testing.T) {
  1230  	type Value struct{ int }
  1231  	a := map[string]interface{}{
  1232  		"foo": &Value{},
  1233  	}
  1234  	b := map[string]interface{}{
  1235  		"foo": 1.23,
  1236  	}
  1237  	diff := deep.Equal(a, b)
  1238  	if len(diff) == 0 {
  1239  		t.Fatalf("expected 1 diff, got zero")
  1240  	}
  1241  
  1242  	if len(diff) != 1 {
  1243  		t.Errorf("expected 1 diff, got: %s", diff)
  1244  	}
  1245  }
  1246  
  1247  func TestError(t *testing.T) {
  1248  	a := errors.New("it broke")
  1249  	b := errors.New("it broke")
  1250  
  1251  	diff := deep.Equal(a, b)
  1252  	if len(diff) != 0 {
  1253  		t.Fatalf("expected zero diffs, got %d: %s", len(diff), diff)
  1254  	}
  1255  
  1256  	b = errors.New("it fell apart")
  1257  	diff = deep.Equal(a, b)
  1258  	if len(diff) != 1 {
  1259  		t.Fatalf("expected 1 diff, got %d: %s", len(diff), diff)
  1260  	}
  1261  	if diff[0] != "it broke != it fell apart" {
  1262  		t.Errorf("got '%s', expected 'it broke != it fell apart'", diff[0])
  1263  	}
  1264  
  1265  	// Both errors set
  1266  	type tWithError struct {
  1267  		Error error
  1268  	}
  1269  	t1 := tWithError{
  1270  		Error: a,
  1271  	}
  1272  	t2 := tWithError{
  1273  		Error: b,
  1274  	}
  1275  	diff = deep.Equal(t1, t2)
  1276  	if len(diff) != 1 {
  1277  		t.Fatalf("expected 1 diff, got %d: %s", len(diff), diff)
  1278  	}
  1279  	if diff[0] != "Error: it broke != it fell apart" {
  1280  		t.Errorf("got '%s', expected 'Error: it broke != it fell apart'", diff[0])
  1281  	}
  1282  
  1283  	// Both errors nil
  1284  	t1 = tWithError{
  1285  		Error: nil,
  1286  	}
  1287  	t2 = tWithError{
  1288  		Error: nil,
  1289  	}
  1290  	diff = deep.Equal(t1, t2)
  1291  	if len(diff) != 0 {
  1292  		t.Log(diff)
  1293  		t.Fatalf("expected 0 diff, got %d: %s", len(diff), diff)
  1294  	}
  1295  
  1296  	// One error is nil
  1297  	t1 = tWithError{
  1298  		Error: errors.New("foo"),
  1299  	}
  1300  	t2 = tWithError{
  1301  		Error: nil,
  1302  	}
  1303  	diff = deep.Equal(t1, t2)
  1304  	if len(diff) != 1 {
  1305  		t.Log(diff)
  1306  		t.Fatalf("expected 1 diff, got %d: %s", len(diff), diff)
  1307  	}
  1308  	if diff[0] != "Error: *errors.errorString != <nil pointer>" {
  1309  		t.Errorf("got '%s', expected 'Error: *errors.errorString != <nil pointer>'", diff[0])
  1310  	}
  1311  }
  1312  
  1313  func TestErrorWithOtherFields(t *testing.T) {
  1314  	a := errors.New("it broke")
  1315  	b := errors.New("it fell apart")
  1316  
  1317  	// Both errors set
  1318  	type tWithError struct {
  1319  		Error error
  1320  		Other string
  1321  	}
  1322  	t1 := tWithError{
  1323  		Error: a,
  1324  		Other: "ok",
  1325  	}
  1326  	t2 := tWithError{
  1327  		Error: b,
  1328  		Other: "ok",
  1329  	}
  1330  	diff := deep.Equal(t1, t2)
  1331  	if len(diff) != 1 {
  1332  		t.Fatalf("expected 1 diff, got %d: %s", len(diff), diff)
  1333  	}
  1334  	if diff[0] != "Error: it broke != it fell apart" {
  1335  		t.Errorf("got '%s', expected 'Error: it broke != it fell apart'", diff[0])
  1336  	}
  1337  
  1338  	// Both errors nil
  1339  	t1 = tWithError{
  1340  		Error: nil,
  1341  		Other: "ok",
  1342  	}
  1343  	t2 = tWithError{
  1344  		Error: nil,
  1345  		Other: "ok",
  1346  	}
  1347  	diff = deep.Equal(t1, t2)
  1348  	if len(diff) != 0 {
  1349  		t.Log(diff)
  1350  		t.Fatalf("expected 0 diff, got %d: %s", len(diff), diff)
  1351  	}
  1352  
  1353  	// Different Other value
  1354  	t1 = tWithError{
  1355  		Error: nil,
  1356  		Other: "ok",
  1357  	}
  1358  	t2 = tWithError{
  1359  		Error: nil,
  1360  		Other: "nope",
  1361  	}
  1362  	diff = deep.Equal(t1, t2)
  1363  	if len(diff) != 1 {
  1364  		t.Fatalf("expected 1 diff, got %d: %s", len(diff), diff)
  1365  	}
  1366  	if diff[0] != "Other: ok != nope" {
  1367  		t.Errorf("got '%s', expected 'Other: ok != nope'", diff[0])
  1368  	}
  1369  
  1370  	// Different Other value, same error
  1371  	t1 = tWithError{
  1372  		Error: a,
  1373  		Other: "ok",
  1374  	}
  1375  	t2 = tWithError{
  1376  		Error: a,
  1377  		Other: "nope",
  1378  	}
  1379  	diff = deep.Equal(t1, t2)
  1380  	if len(diff) != 1 {
  1381  		t.Fatalf("expected 1 diff, got %d: %s", len(diff), diff)
  1382  	}
  1383  	if diff[0] != "Other: ok != nope" {
  1384  		t.Errorf("got '%s', expected 'Other: ok != nope'", diff[0])
  1385  	}
  1386  }
  1387  
  1388  type primKindError string
  1389  
  1390  func (e primKindError) Error() string {
  1391  	return string(e)
  1392  }
  1393  
  1394  func TestErrorPrimitiveKind(t *testing.T) {
  1395  	// The primKindError type above is valid and used by Go, e.g.
  1396  	// url.EscapeError and url.InvalidHostError. Before fixing this bug
  1397  	// (https://github.com/go-test/deep/issues/31), we presumed a and b
  1398  	// were ptr or interface (and not nil), so a.Elem() worked. But when
  1399  	// a/b are primitive kinds, Elem() causes a panic.
  1400  	var err1 primKindError = "abc"
  1401  	var err2 primKindError = "abc"
  1402  	diff := deep.Equal(err1, err2)
  1403  	if len(diff) != 0 {
  1404  		t.Fatalf("expected zero diffs, got %d: %s", len(diff), diff)
  1405  	}
  1406  
  1407  	err2 = "def"
  1408  	diff = deep.Equal(err1, err2)
  1409  	if len(diff) != 1 {
  1410  		t.Fatalf("expected 1 diff, got %d: %s", len(diff), diff)
  1411  	}
  1412  }
  1413  
  1414  func TestErrorUnexported(t *testing.T) {
  1415  	// https://github.com/go-test/deep/issues/45
  1416  	type foo struct {
  1417  		bar error
  1418  	}
  1419  	defaultCompareUnexportedFields := deep.CompareUnexportedFields
  1420  	deep.CompareUnexportedFields = true
  1421  	defer func() { deep.CompareUnexportedFields = defaultCompareUnexportedFields }()
  1422  	e1 := foo{bar: fmt.Errorf("error")}
  1423  	e2 := foo{bar: fmt.Errorf("error")}
  1424  	deep.Equal(e1, e2)
  1425  }
  1426  
  1427  func TestNil(t *testing.T) {
  1428  	type student struct {
  1429  		name string
  1430  		age  int
  1431  	}
  1432  
  1433  	mark := student{"mark", 10}
  1434  	var someNilThing interface{} = nil
  1435  	diff := deep.Equal(someNilThing, mark)
  1436  	if diff == nil {
  1437  		t.Error("Nil value to comparison should not be equal")
  1438  	}
  1439  	diff = deep.Equal(mark, someNilThing)
  1440  	if diff == nil {
  1441  		t.Error("Nil value to comparison should not be equal")
  1442  	}
  1443  	diff = deep.Equal(someNilThing, someNilThing)
  1444  	if diff != nil {
  1445  		t.Error("Nil value to comparison should not be equal")
  1446  	}
  1447  }
  1448  
  1449  var testFunc = func() {}
  1450  
  1451  func TestFunc(t *testing.T) {
  1452  	// https://github.com/go-test/deep/issues/46
  1453  	type TestStruct struct {
  1454  		Function func()
  1455  	}
  1456  	t1 := TestStruct{
  1457  		Function: testFunc,
  1458  	}
  1459  	t2 := TestStruct{
  1460  		Function: testFunc,
  1461  	}
  1462  
  1463  	// CompareFunctions is off by default, so this should report no diff:
  1464  	diff := deep.Equal(t1, t2)
  1465  	if len(diff) != 0 {
  1466  		t.Fatalf("expected 0 diff when CompareFunctions=false, got %d: %s", len(diff), diff)
  1467  	}
  1468  
  1469  	deep.CompareFunctions = true
  1470  	defer func() { deep.CompareFunctions = false }()
  1471  
  1472  	// Two funcs are not equal (even if they're the same func)
  1473  	diff = deep.Equal(t1, t2)
  1474  	if len(diff) != 1 {
  1475  		t.Fatalf("expected 1 diff, got %d: %s", len(diff), diff)
  1476  	}
  1477  	if diff[0] != "Function: func != func" {
  1478  		t.Errorf("got '%s', expected 'Function: func != func'", diff[0])
  1479  	}
  1480  
  1481  	// One func nil, the other set: not equal
  1482  	t1.Function = nil
  1483  	diff = deep.Equal(t1, t2)
  1484  	if len(diff) != 1 {
  1485  		t.Fatalf("expected 1 diff, got %d: %s", len(diff), diff)
  1486  	}
  1487  	if diff[0] != "Function: nil func != func" {
  1488  		t.Errorf("got '%s', expected 'Function: nil func != func'", diff[0])
  1489  	}
  1490  
  1491  	// Two nil funcs are equal
  1492  	t1.Function = nil
  1493  	t2.Function = nil
  1494  	diff = deep.Equal(t1, t2)
  1495  	if len(diff) != 0 {
  1496  		t.Errorf("expected 0 diff, got %d: %s", len(diff), diff)
  1497  	}
  1498  }
  1499  
  1500  func TestSliceOrderString(t *testing.T) {
  1501  	// https://github.com/go-test/deep/issues/28
  1502  
  1503  	// These are equal if we ignore order
  1504  	a := []string{"foo", "bar"}
  1505  	b := []string{"bar", "foo"}
  1506  	diff := deep.Equal(a, b, deep.FLAG_IGNORE_SLICE_ORDER)
  1507  	if len(diff) != 0 {
  1508  		t.Fatalf("expected 0 diff, got %d: %s", len(diff), diff)
  1509  	}
  1510  
  1511  	// Equal with dupes
  1512  	a = []string{"foo", "foo", "bar"}
  1513  	b = []string{"bar", "foo", "foo"}
  1514  	diff = deep.Equal(a, b, deep.FLAG_IGNORE_SLICE_ORDER)
  1515  	if len(diff) != 0 {
  1516  		t.Fatalf("expected 0 diff, got %d: %s", len(diff), diff)
  1517  	}
  1518  
  1519  	// NOT equal with dupes
  1520  	a = []string{"foo", "foo", "bar"}
  1521  	b = []string{"bar", "bar", "foo"}
  1522  	diff = deep.Equal(a, b, deep.FLAG_IGNORE_SLICE_ORDER)
  1523  	if len(diff) != 2 {
  1524  		t.Fatalf("expected 2 diff, got %d: %s", len(diff), diff)
  1525  	}
  1526  	m1 := "(unordered) slice[]=foo: value count: 2 != 1"
  1527  	m2 := "(unordered) slice[]=bar: value count: 1 != 2"
  1528  	if diff[0] != m1 && diff[0] != m2 {
  1529  		t.Errorf("got %s, expected '%s' or '%s'", diff[0], m1, m2)
  1530  	}
  1531  	if diff[1] != m1 && diff[1] != m2 {
  1532  		t.Errorf("got %s, expected '%s' or '%s'", diff[1], m1, m2)
  1533  	}
  1534  
  1535  	// NOT equal with one missing
  1536  	a = []string{"foo", "bar"}
  1537  	b = []string{"bar", "foo", "gone"}
  1538  	diff = deep.Equal(a, b, deep.FLAG_IGNORE_SLICE_ORDER)
  1539  	if len(diff) != 1 {
  1540  		t.Fatalf("expected 2 diff, got %d: %s", len(diff), diff)
  1541  	}
  1542  	if diff[0] != "(unordered) slice[]=gone: value count: 0 != 1" {
  1543  		t.Errorf("got %s, expected ''", diff[0])
  1544  	}
  1545  
  1546  	// NOT equal at all
  1547  	a = []string{"foo", "bar"}
  1548  	b = []string{"x"}
  1549  	diff = deep.Equal(a, b, deep.FLAG_IGNORE_SLICE_ORDER)
  1550  	if len(diff) != 3 {
  1551  		t.Fatalf("expected 2 diff, got %d: %s", len(diff), diff)
  1552  	}
  1553  	sort.Strings(diff)
  1554  	if diff[0] != "(unordered) slice[]=bar: value count: 1 != 0" {
  1555  		t.Errorf("got %s, expected '(unordered) slice[]=bar: value count: 1 != 0'", diff[0])
  1556  	}
  1557  	if diff[1] != "(unordered) slice[]=foo: value count: 1 != 0" {
  1558  		t.Errorf("got %s, expected '(unordered) slice[]=foo: value count: 1 != 0", diff[1])
  1559  	}
  1560  	if diff[2] != "(unordered) slice[]=x: value count: 0 != 1" {
  1561  		t.Errorf("got %s, expected '(unordered) slice[]=x: value count: 0 != 1'", diff[2])
  1562  	}
  1563  }
  1564  
  1565  func TestSliceOrderStruct(t *testing.T) {
  1566  	// https://github.com/go-test/deep/issues/28
  1567  	// This is NOT supported but Go is so wonderful that it just happens to work.
  1568  	// But again: not supported. So if this test starts to fail or be a problem,
  1569  	// it can and should be removed becuase the docs say it's not supported.
  1570  	type T struct{ i int }
  1571  	a := []T{
  1572  		{i: 1},
  1573  		{i: 2},
  1574  	}
  1575  	b := []T{
  1576  		{i: 2},
  1577  		{i: 1},
  1578  	}
  1579  	diff := deep.Equal(a, b, deep.FLAG_IGNORE_SLICE_ORDER)
  1580  	if len(diff) != 0 {
  1581  		t.Fatalf("expected 0 diff, got %d: %s", len(diff), diff)
  1582  	}
  1583  }
  1584  

View as plain text