Codebase list golang-github-kylelemons-godebug / 3d44244
Import upstream version 1.1.0+git20201106.1.e693023 Debian Janitor 2 years ago
7 changed file(s) with 171 addition(s) and 25 deletion(s). Raw diff Collapse all Expand all
00 language: go
11
22 go:
3 - 1.7
4 - 1.8
5 - tip
3 - "1.14.x"
4 - "1.15.x"
5
6 arch:
7 - amd64
8 - arm64
9 - ppc64le
1515 package diff
1616
1717 import (
18 "bytes"
1918 "fmt"
2019 "strings"
2120 )
4039 func Diff(A, B string) string {
4140 aLines := strings.Split(A, "\n")
4241 bLines := strings.Split(B, "\n")
42 return Render(DiffChunks(aLines, bLines))
43 }
4344
44 chunks := DiffChunks(aLines, bLines)
45
46 buf := new(bytes.Buffer)
45 // Render renders the slice of chunks into a representation that prefixes
46 // the lines with '+', '-', or ' ' depending on whether the line was added,
47 // removed, or equal (respectively).
48 func Render(chunks []Chunk) string {
49 buf := new(strings.Builder)
4750 for _, c := range chunks {
4851 for _, line := range c.Added {
4952 fmt.Fprintf(buf, "+%s\n", line)
134134 }
135135 }
136136
137 func TestRender(t *testing.T) {
138 tests := []struct {
139 desc string
140 chunks []Chunk
141 out string
142 }{
143 {
144 desc: "ordering",
145 chunks: []Chunk{
146 {
147 Added: []string{"1"},
148 Deleted: []string{"2"},
149 Equal: []string{"3"},
150 },
151 {
152 Added: []string{"4"},
153 Deleted: []string{"5"},
154 },
155 },
156 out: strings.TrimSpace(`
157 +1
158 -2
159 3
160 +4
161 -5
162 `),
163 },
164 {
165 desc: "only_added",
166 chunks: []Chunk{
167 {
168 Added: []string{"1"},
169 },
170 },
171 out: strings.TrimSpace(`
172 +1
173 `),
174 },
175 {
176 desc: "only_deleted",
177 chunks: []Chunk{
178 {
179 Deleted: []string{"1"},
180 },
181 },
182 out: strings.TrimSpace(`
183 -1
184 `),
185 },
186 }
187
188 for _, test := range tests {
189 t.Run(test.desc, func(t *testing.T) {
190 if got, want := Render(test.chunks), test.out; got != want {
191 t.Errorf("Render(%q):", test.chunks)
192 t.Errorf("GOT\n%s", got)
193 t.Errorf("WANT\n%s", want)
194 }
195 })
196 }
197 }
198
137199 func ExampleDiff() {
138200 constitution := strings.TrimSpace(`
139201 We the People of the United States, in Order to form a more perfect Union,
1919 //
2020 // See the Reflect and Print examples for what the output looks like.
2121 package pretty
22
23 // TODO:
24 // - Catch cycles
1515
1616 import (
1717 "testing"
18 "time"
1819 )
1920
2021 func TestDiff(t *testing.T) {
125126 }
126127 }
127128 }
129
130 func TestRegressions(t *testing.T) {
131 tests := []struct {
132 issue string
133 config *Config
134 value interface{}
135 want string
136 }{
137 {
138 issue: "kylelemons/godebug#13",
139 config: &Config{
140 PrintStringers: true,
141 },
142 value: struct{ Day *time.Weekday }{},
143 want: "{Day: nil}",
144 },
145 }
146
147 for _, test := range tests {
148 t.Run(test.issue, func(t *testing.T) {
149 if got, want := test.config.Sprint(test.value), test.want; got != want {
150 t.Errorf("%#v.Sprint(%#v) = %q, want %q", test.config, test.value, got, want)
151 }
152 })
153 }
154 }
114114 return n
115115 }
116116
117 func (r *reflector) val2node(val reflect.Value) node {
117 func (r *reflector) val2node(val reflect.Value) (ret node) {
118118 if !val.IsValid() {
119119 return rawVal("nil")
120120 }
121121
122122 if val.CanInterface() {
123 // Detect panics in calling functions on nil pointers.
124 //
125 // We still want to call them, as it's possible that a nil value is
126 // valid for the particular type.
127 //
128 // If we detect a panic, just return raw nil.
129 if val.Kind() == reflect.Ptr && val.IsNil() {
130 defer func() {
131 if r := recover(); r != nil {
132 ret = rawVal("nil")
133 }
134 }()
135 }
136
123137 v := val.Interface()
124138 if formatter, ok := r.Formatter[val.Type()]; ok {
125139 if formatter != nil {
146146 },
147147 },
148148 {
149 desc: "struct w/ IncludeUnexported",
149 desc: "struct with IncludeUnexported",
150150 raw: struct{ Zaphod, Ford, foo string }{"beeblebrox", "prefect", "GOOD"},
151151 cfg: &Config{
152152 IncludeUnexported: true,
166166 },
167167 },
168168 {
169 desc: "time w/ nil Formatter",
169 desc: "time with nil Formatter",
170170 raw: struct{ Date time.Time }{time.Unix(1234567890, 0).UTC()},
171171 cfg: &Config{
172172 PrintStringers: true,
179179 },
180180 },
181181 {
182 desc: "time w/ PrintTextMarshalers",
182 desc: "time with PrintTextMarshalers",
183183 raw: struct{ Date time.Time }{time.Unix(1234567890, 0).UTC()},
184184 cfg: &Config{
185185 PrintTextMarshalers: true,
189189 },
190190 },
191191 {
192 desc: "time w/ PrintStringers",
192 desc: "time with PrintStringers",
193193 raw: struct{ Date time.Time }{time.Unix(1234567890, 0).UTC()},
194194 cfg: &Config{
195195 PrintStringers: true,
196196 },
197197 want: keyvals{
198198 {"Date", stringVal("2009-02-13 23:31:30 +0000 UTC")},
199 },
200 },
201 {
202 desc: "nil with PrintStringers",
203 raw: struct{ Date *time.Time }{},
204 cfg: &Config{
205 PrintStringers: true,
206 },
207 want: keyvals{
208 {"Date", rawVal("nil")},
209 },
210 },
211 {
212 desc: "nilIsFine with PrintStringers",
213 raw: struct{ V *nilIsFine }{},
214 cfg: &Config{
215 PrintStringers: true,
216 },
217 want: keyvals{
218 {"V", stringVal("<nil is fine>")},
219 },
220 },
221 {
222 desc: "nilIsFine non-nil with PrintStringers",
223 raw: struct{ V *nilIsFine }{V: new(nilIsFine)},
224 cfg: &Config{
225 PrintStringers: true,
226 },
227 want: keyvals{
228 {"V", stringVal("<not nil is fine>")},
199229 },
200230 },
201231 {
265295 }
266296
267297 for _, test := range tests {
268 ref := &reflector{
269 Config: test.cfg,
270 }
271 if test.cfg.TrackCycles {
272 ref.pointerTracker = new(pointerTracker)
273 }
274 if got, want := ref.val2node(reflect.ValueOf(test.raw)), test.want; !reflect.DeepEqual(got, want) {
275 t.Run(test.desc, func(t *testing.T) {
298 t.Run(test.desc, func(t *testing.T) {
299 ref := &reflector{
300 Config: test.cfg,
301 }
302 if test.cfg.TrackCycles {
303 ref.pointerTracker = new(pointerTracker)
304 }
305 if got, want := ref.val2node(reflect.ValueOf(test.raw)), test.want; !reflect.DeepEqual(got, want) {
276306 t.Errorf(" got %#v", got)
277307 t.Errorf("want %#v", want)
278308 t.Errorf("Diff: (-got +want)\n%s", Compare(got, want))
279 })
280 }
309 }
310 })
281311 }
282312 }
283313
414444 })
415445 }
416446 }
447
448 type nilIsFine struct{}
449
450 func (n *nilIsFine) String() string {
451 if n == nil {
452 return "<nil is fine>"
453 }
454 return "<not nil is fine>"
455 }