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