github.com/chunqian/pretty@v0.0.0-20200305075802-e57086a8d0c4/diff_test.go (about)

     1  package pretty
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"log"
     7  	"reflect"
     8  	"testing"
     9  	"unsafe"
    10  )
    11  
    12  var (
    13  	_ Logfer   = (*testing.T)(nil)
    14  	_ Logfer   = (*testing.B)(nil)
    15  	_ Printfer = (*log.Logger)(nil)
    16  )
    17  
    18  type difftest struct {
    19  	a   interface{}
    20  	b   interface{}
    21  	exp []string
    22  }
    23  
    24  type S struct {
    25  	A int
    26  	S *S
    27  	I interface{}
    28  	C []int
    29  }
    30  
    31  type (
    32  	N struct{ N int }
    33  	E interface{}
    34  )
    35  
    36  var (
    37  	c0 = make(chan int)
    38  	c1 = make(chan int)
    39  	f0 = func() {}
    40  	f1 = func() {}
    41  	i0 = 0
    42  	i1 = 1
    43  )
    44  
    45  var diffs = []difftest{
    46  	{a: nil, b: nil},
    47  	{a: S{A: 1}, b: S{A: 1}},
    48  
    49  	{0, "", []string{`int != string`}},
    50  	{0, 1, []string{`0 != 1`}},
    51  	{S{}, new(S), []string{`pretty.S != *pretty.S`}},
    52  	{"a", "b", []string{`"a" != "b"`}},
    53  	{S{}, S{A: 1}, []string{`A: 0 != 1`}},
    54  	{new(S), &S{A: 1}, []string{`A: 0 != 1`}},
    55  	{S{S: new(S)}, S{S: &S{A: 1}}, []string{`S.A: 0 != 1`}},
    56  	{S{}, S{I: 0}, []string{`I: nil != int(0)`}},
    57  	{S{I: 1}, S{I: "x"}, []string{`I: int != string`}},
    58  	{S{}, S{C: []int{1}}, []string{`C: []int[0] != []int[1]`}},
    59  	{S{C: []int{}}, S{C: []int{1}}, []string{`C: []int[0] != []int[1]`}},
    60  	{S{C: []int{1, 2, 3}}, S{C: []int{1, 2, 4}}, []string{`C[2]: 3 != 4`}},
    61  	{S{}, S{A: 1, S: new(S)}, []string{`A: 0 != 1`, `S: nil != &pretty.S{}`}},
    62  
    63  	// unexported fields of every reflect.Kind (both equal and unequal)
    64  	{struct{ x bool }{false}, struct{ x bool }{false}, nil},
    65  	{struct{ x bool }{false}, struct{ x bool }{true}, []string{`x: false != true`}},
    66  	{struct{ x int }{0}, struct{ x int }{0}, nil},
    67  	{struct{ x int }{0}, struct{ x int }{1}, []string{`x: 0 != 1`}},
    68  	{struct{ x int8 }{0}, struct{ x int8 }{0}, nil},
    69  	{struct{ x int8 }{0}, struct{ x int8 }{1}, []string{`x: 0 != 1`}},
    70  	{struct{ x int16 }{0}, struct{ x int16 }{0}, nil},
    71  	{struct{ x int16 }{0}, struct{ x int16 }{1}, []string{`x: 0 != 1`}},
    72  	{struct{ x int32 }{0}, struct{ x int32 }{0}, nil},
    73  	{struct{ x int32 }{0}, struct{ x int32 }{1}, []string{`x: 0 != 1`}},
    74  	{struct{ x int64 }{0}, struct{ x int64 }{0}, nil},
    75  	{struct{ x int64 }{0}, struct{ x int64 }{1}, []string{`x: 0 != 1`}},
    76  	{struct{ x uint }{0}, struct{ x uint }{0}, nil},
    77  	{struct{ x uint }{0}, struct{ x uint }{1}, []string{`x: 0 != 1`}},
    78  	{struct{ x uint8 }{0}, struct{ x uint8 }{0}, nil},
    79  	{struct{ x uint8 }{0}, struct{ x uint8 }{1}, []string{`x: 0 != 1`}},
    80  	{struct{ x uint16 }{0}, struct{ x uint16 }{0}, nil},
    81  	{struct{ x uint16 }{0}, struct{ x uint16 }{1}, []string{`x: 0 != 1`}},
    82  	{struct{ x uint32 }{0}, struct{ x uint32 }{0}, nil},
    83  	{struct{ x uint32 }{0}, struct{ x uint32 }{1}, []string{`x: 0 != 1`}},
    84  	{struct{ x uint64 }{0}, struct{ x uint64 }{0}, nil},
    85  	{struct{ x uint64 }{0}, struct{ x uint64 }{1}, []string{`x: 0 != 1`}},
    86  	{struct{ x uintptr }{0}, struct{ x uintptr }{0}, nil},
    87  	{struct{ x uintptr }{0}, struct{ x uintptr }{1}, []string{`x: 0 != 1`}},
    88  	{struct{ x float32 }{0}, struct{ x float32 }{0}, nil},
    89  	{struct{ x float32 }{0}, struct{ x float32 }{1}, []string{`x: 0 != 1`}},
    90  	{struct{ x float64 }{0}, struct{ x float64 }{0}, nil},
    91  	{struct{ x float64 }{0}, struct{ x float64 }{1}, []string{`x: 0 != 1`}},
    92  	{struct{ x complex64 }{0}, struct{ x complex64 }{0}, nil},
    93  	{struct{ x complex64 }{0}, struct{ x complex64 }{1}, []string{`x: (0+0i) != (1+0i)`}},
    94  	{struct{ x complex128 }{0}, struct{ x complex128 }{0}, nil},
    95  	{struct{ x complex128 }{0}, struct{ x complex128 }{1}, []string{`x: (0+0i) != (1+0i)`}},
    96  	{struct{ x [1]int }{[1]int{0}}, struct{ x [1]int }{[1]int{0}}, nil},
    97  	{struct{ x [1]int }{[1]int{0}}, struct{ x [1]int }{[1]int{1}}, []string{`x[0]: 0 != 1`}},
    98  	{struct{ x chan int }{c0}, struct{ x chan int }{c0}, nil},
    99  	{struct{ x chan int }{c0}, struct{ x chan int }{c1}, []string{fmt.Sprintf("x: %p != %p", c0, c1)}},
   100  	{struct{ x func() }{f0}, struct{ x func() }{f0}, nil},
   101  	{struct{ x func() }{f0}, struct{ x func() }{f1}, []string{fmt.Sprintf("x: %p != %p", f0, f1)}},
   102  	{struct{ x interface{} }{0}, struct{ x interface{} }{0}, nil},
   103  	{struct{ x interface{} }{0}, struct{ x interface{} }{1}, []string{`x: 0 != 1`}},
   104  	{struct{ x interface{} }{0}, struct{ x interface{} }{""}, []string{`x: int != string`}},
   105  	{struct{ x interface{} }{0}, struct{ x interface{} }{nil}, []string{`x: int(0) != nil`}},
   106  	{struct{ x interface{} }{nil}, struct{ x interface{} }{0}, []string{`x: nil != int(0)`}},
   107  	{struct{ x map[int]int }{map[int]int{0: 0}}, struct{ x map[int]int }{map[int]int{0: 0}}, nil},
   108  	{struct{ x map[int]int }{map[int]int{0: 0}}, struct{ x map[int]int }{map[int]int{0: 1}}, []string{`x[0]: 0 != 1`}},
   109  	{struct{ x *int }{new(int)}, struct{ x *int }{new(int)}, nil},
   110  	{struct{ x *int }{&i0}, struct{ x *int }{&i1}, []string{`x: 0 != 1`}},
   111  	{struct{ x *int }{nil}, struct{ x *int }{&i0}, []string{`x: nil != &int(0)`}},
   112  	{struct{ x *int }{&i0}, struct{ x *int }{nil}, []string{`x: &int(0) != nil`}},
   113  	{struct{ x []int }{[]int{0}}, struct{ x []int }{[]int{0}}, nil},
   114  	{struct{ x []int }{[]int{0}}, struct{ x []int }{[]int{1}}, []string{`x[0]: 0 != 1`}},
   115  	{struct{ x string }{"a"}, struct{ x string }{"a"}, nil},
   116  	{struct{ x string }{"a"}, struct{ x string }{"b"}, []string{`x: "a" != "b"`}},
   117  	{struct{ x N }{N{0}}, struct{ x N }{N{0}}, nil},
   118  	{struct{ x N }{N{0}}, struct{ x N }{N{1}}, []string{`x.N: 0 != 1`}},
   119  	{
   120  		struct{ x unsafe.Pointer }{unsafe.Pointer(uintptr(0))},
   121  		struct{ x unsafe.Pointer }{unsafe.Pointer(uintptr(0))},
   122  		nil,
   123  	},
   124  	{
   125  		struct{ x unsafe.Pointer }{unsafe.Pointer(uintptr(0))},
   126  		struct{ x unsafe.Pointer }{unsafe.Pointer(uintptr(1))},
   127  		[]string{`x: 0x0 != 0x1`},
   128  	},
   129  }
   130  
   131  func TestDiff(t *testing.T) {
   132  	for _, tt := range diffs {
   133  		got := Diff(tt.a, tt.b)
   134  		eq := len(got) == len(tt.exp)
   135  		if eq {
   136  			for i := range got {
   137  				eq = eq && got[i] == tt.exp[i]
   138  			}
   139  		}
   140  		if !eq {
   141  			t.Errorf("diffing % #v", tt.a)
   142  			t.Errorf("with    % #v", tt.b)
   143  			diffdiff(t, got, tt.exp)
   144  			continue
   145  		}
   146  	}
   147  }
   148  
   149  func TestKeyEqual(t *testing.T) {
   150  	var emptyInterfaceZero interface{} = 0
   151  
   152  	cases := []interface{}{
   153  		new(bool),
   154  		new(int),
   155  		new(int8),
   156  		new(int16),
   157  		new(int32),
   158  		new(int64),
   159  		new(uint),
   160  		new(uint8),
   161  		new(uint16),
   162  		new(uint32),
   163  		new(uint64),
   164  		new(uintptr),
   165  		new(float32),
   166  		new(float64),
   167  		new(complex64),
   168  		new(complex128),
   169  		new([1]int),
   170  		new(chan int),
   171  		new(unsafe.Pointer),
   172  		new(interface{}),
   173  		&emptyInterfaceZero,
   174  		new(*int),
   175  		new(string),
   176  		new(struct{ int }),
   177  	}
   178  
   179  	for _, test := range cases {
   180  		rv := reflect.ValueOf(test).Elem()
   181  		if !keyEqual(rv, rv) {
   182  			t.Errorf("keyEqual(%s, %s) = false want true", rv.Type(), rv.Type())
   183  		}
   184  	}
   185  }
   186  
   187  func TestFdiff(t *testing.T) {
   188  	var buf bytes.Buffer
   189  	Fdiff(&buf, 0, 1)
   190  	want := "0 != 1\n"
   191  	if got := buf.String(); got != want {
   192  		t.Errorf("Fdiff(0, 1) = %q want %q", got, want)
   193  	}
   194  }
   195  
   196  func diffdiff(t *testing.T, got, exp []string) {
   197  	minus(t, "unexpected:", got, exp)
   198  	minus(t, "missing:", exp, got)
   199  }
   200  
   201  func minus(t *testing.T, s string, a, b []string) {
   202  	var i, j int
   203  	for i = 0; i < len(a); i++ {
   204  		for j = 0; j < len(b); j++ {
   205  			if a[i] == b[j] {
   206  				break
   207  			}
   208  		}
   209  		if j == len(b) {
   210  			t.Error(s, a[i])
   211  		}
   212  	}
   213  }