1package messagediff 2 3import ( 4 "testing" 5 "time" 6 7 "github.com/d4l3k/messagediff/testdata" 8) 9 10type testStruct struct { 11 A, b int 12 C []int 13 D [3]int 14} 15 16type RecursiveStruct struct { 17 Key int 18 Child *RecursiveStruct 19} 20 21func newRecursiveStruct(key int) *RecursiveStruct { 22 a := &RecursiveStruct{ 23 Key: key, 24 } 25 b := &RecursiveStruct{ 26 Key: key, 27 Child: a, 28 } 29 a.Child = b 30 return a 31} 32 33type testCase struct { 34 a, b interface{} 35 diff string 36 equal bool 37} 38 39func checkTestCases(t *testing.T, testData []testCase) { 40 for i, td := range testData { 41 diff, equal := PrettyDiff(td.a, td.b) 42 if diff != td.diff { 43 t.Errorf("%d. PrettyDiff(%#v, %#v) diff = %#v; not %#v", i, td.a, td.b, diff, td.diff) 44 } 45 if equal != td.equal { 46 t.Errorf("%d. PrettyDiff(%#v, %#v) equal = %#v; not %#v", i, td.a, td.b, equal, td.equal) 47 } 48 } 49} 50 51func TestPrettyDiff(t *testing.T) { 52 testData := []testCase{ 53 { 54 true, 55 false, 56 "modified: = false\n", 57 false, 58 }, 59 { 60 true, 61 0, 62 "modified: = 0\n", 63 false, 64 }, 65 { 66 []int{0, 1, 2}, 67 []int{0, 1, 2, 3}, 68 "added: [3] = 3\n", 69 false, 70 }, 71 { 72 []int{0, 1, 2, 3}, 73 []int{0, 1, 2}, 74 "removed: [3] = 3\n", 75 false, 76 }, 77 { 78 []int{0}, 79 []int{1}, 80 "modified: [0] = 1\n", 81 false, 82 }, 83 { 84 &[]int{0}, 85 &[]int{1}, 86 "modified: [0] = 1\n", 87 false, 88 }, 89 { 90 map[string]int{"a": 1, "b": 2}, 91 map[string]int{"b": 4, "c": 3}, 92 "added: [\"c\"] = 3\nmodified: [\"b\"] = 4\nremoved: [\"a\"] = 1\n", 93 false, 94 }, 95 { 96 testStruct{1, 2, []int{1}, [3]int{4, 5, 6}}, 97 testStruct{1, 3, []int{1, 2}, [3]int{4, 5, 6}}, 98 "added: .C[1] = 2\nmodified: .b = 3\n", 99 false, 100 }, 101 { 102 nil, 103 nil, 104 "", 105 true, 106 }, 107 { 108 &struct{}{}, 109 nil, 110 "modified: = <nil>\n", 111 false, 112 }, 113 { 114 nil, 115 &struct{}{}, 116 "modified: = &struct {}{}\n", 117 false, 118 }, 119 { 120 time.Time{}, 121 time.Time{}, 122 "", 123 true, 124 }, 125 { 126 testdata.MakeTest(10, "duck"), 127 testdata.MakeTest(20, "foo"), 128 "modified: .a = 20\nmodified: .b = \"foo\"\n", 129 false, 130 }, 131 } 132 checkTestCases(t, testData) 133} 134 135func TestPrettyDiffRecursive(t *testing.T) { 136 testData := []testCase{ 137 { 138 newRecursiveStruct(1), 139 newRecursiveStruct(1), 140 "", 141 true, 142 }, 143 { 144 newRecursiveStruct(1), 145 newRecursiveStruct(2), 146 "modified: .Child.Key = 2\nmodified: .Key = 2\n", 147 false, 148 }, 149 } 150 checkTestCases(t, testData) 151} 152 153func TestPathString(t *testing.T) { 154 testData := []struct { 155 in Path 156 want string 157 }{{ 158 Path{StructField("test"), SliceIndex(1), MapKey{"blue"}, MapKey{12.3}}, 159 ".test[1][\"blue\"][12.3]", 160 }} 161 for i, td := range testData { 162 if out := td.in.String(); out != td.want { 163 t.Errorf("%d. %#v.String() = %#v; not %#v", i, td.in, out, td.want) 164 } 165 } 166} 167 168type ignoreStruct struct { 169 A int `testdiff:"ignore"` 170 a int 171 B [3]int `testdiff:"ignore"` 172 b [3]int 173} 174 175func TestIgnoreTag(t *testing.T) { 176 s1 := ignoreStruct{1, 1, [3]int{1, 2, 3}, [3]int{4, 5, 6}} 177 s2 := ignoreStruct{2, 1, [3]int{1, 8, 3}, [3]int{4, 5, 6}} 178 179 diff, equal := PrettyDiff(s1, s2) 180 if !equal { 181 t.Errorf("Expected structs to be equal. Diff:\n%s", diff) 182 } 183 184 s2 = ignoreStruct{2, 2, [3]int{1, 8, 3}, [3]int{4, 9, 6}} 185 diff, equal = PrettyDiff(s1, s2) 186 if equal { 187 t.Errorf("Expected structs NOT to be equal.") 188 } 189 expect := "modified: .a = 2\nmodified: .b[1] = 9\n" 190 if diff != expect { 191 t.Errorf("Expected diff to be:\n%v\nbut got:\n%v", expect, diff) 192 } 193} 194