diff -Nru golang-pretty-0.0~git20160325.0.add1dbc/debian/changelog golang-pretty-0.1.0/debian/changelog --- golang-pretty-0.0~git20160325.0.add1dbc/debian/changelog 2016-04-29 05:15:37.000000000 +0000 +++ golang-pretty-0.1.0/debian/changelog 2018-12-20 02:51:49.000000000 +0000 @@ -1,3 +1,19 @@ +golang-pretty (0.1.0-1) unstable; urgency=medium + + [ Alexandre Viau ] + * Point Vcs-* urls to salsa.debian.org. + + [ Anthony Fok ] + * New upstream version 0.1.0 + * Add debian/watch + * Apply "cme fix dpkg" fixes to debian/control and debian/copyright, + adding "Testsuite: autopkgtest-pkg-go" field, + setting Priority to optional, bumping Standards-Version to 4.2.1, + and using secure https URL in debian/copyright, etc. + * Build-Depends on golang-any instead of golang-go + + -- Anthony Fok Wed, 19 Dec 2018 19:51:49 -0700 + golang-pretty (0.0~git20160325.0.add1dbc-1) unstable; urgency=medium [ Tonnerre LOMBARD ] diff -Nru golang-pretty-0.0~git20160325.0.add1dbc/debian/compat golang-pretty-0.1.0/debian/compat --- golang-pretty-0.0~git20160325.0.add1dbc/debian/compat 2016-04-29 05:06:01.000000000 +0000 +++ golang-pretty-0.1.0/debian/compat 2018-12-20 02:46:35.000000000 +0000 @@ -1 +1 @@ -9 +11 diff -Nru golang-pretty-0.0~git20160325.0.add1dbc/debian/control golang-pretty-0.1.0/debian/control --- golang-pretty-0.0~git20160325.0.add1dbc/debian/control 2016-04-29 05:14:36.000000000 +0000 +++ golang-pretty-0.1.0/debian/control 2018-12-20 02:49:51.000000000 +0000 @@ -1,23 +1,29 @@ Source: golang-pretty -Section: devel -Priority: extra Maintainer: Debian Go Packaging Team Uploaders: Tonnerre Lombard , - Anthony Fok -Build-Depends: debhelper (>= 9), golang-go, dh-golang, + Anthony Fok , + Tim Potter +Section: devel +Testsuite: autopkgtest-pkg-go +Priority: optional +Build-Depends: debhelper (>= 11~), + golang-any, + dh-golang, golang-github-kr-text-dev -Standards-Version: 3.9.8 +Standards-Version: 4.2.1 +Vcs-Browser: https://salsa.debian.org/go-team/packages/golang-pretty +Vcs-Git: https://salsa.debian.org/go-team/packages/golang-pretty.git Homepage: https://github.com/kr/pretty/ -Vcs-Git: https://anonscm.debian.org/git/pkg-go/packages/golang-pretty.git -Vcs-Browser: https://anonscm.debian.org/cgit/pkg-go/packages/golang-pretty.git XS-Go-Import-Path: github.com/kr/pretty Package: golang-github-kr-pretty-dev Architecture: all -Depends: ${shlibs:Depends}, ${misc:Depends}, golang-github-kr-text-dev -Replaces: golang-pretty-dev (<< 0.0~git20160325.0.add1dbc-1~) +Depends: ${shlibs:Depends}, + ${misc:Depends}, + golang-github-kr-text-dev Breaks: golang-pretty-dev (<< 0.0~git20160325.0.add1dbc-1~) Provides: golang-pretty-dev +Replaces: golang-pretty-dev (<< 0.0~git20160325.0.add1dbc-1~) Description: Pretty printing for Go values Go library package github.com/kr/pretty provides pretty-printing for Go values. This is useful during debugging, to avoid wrapping @@ -28,9 +34,10 @@ for functions in packages fmt and log. Package: golang-pretty-dev -Section: oldlibs Architecture: all -Depends: golang-github-kr-pretty-dev, ${misc:Depends} +Section: oldlibs +Depends: golang-github-kr-pretty-dev, + ${misc:Depends} Description: Transitional package for golang-github-kr-pretty-dev This is a transitional package to ease upgrades to the golang-github-kr-pretty-dev package. It can safely be removed. diff -Nru golang-pretty-0.0~git20160325.0.add1dbc/debian/copyright golang-pretty-0.1.0/debian/copyright --- golang-pretty-0.0~git20160325.0.add1dbc/debian/copyright 2016-04-29 05:09:01.000000000 +0000 +++ golang-pretty-0.1.0/debian/copyright 2018-12-20 02:46:35.000000000 +0000 @@ -1,4 +1,4 @@ -Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: github.com/kr/pretty Source: https://github.com/kr/pretty/ diff -Nru golang-pretty-0.0~git20160325.0.add1dbc/debian/gitlab-ci.yml golang-pretty-0.1.0/debian/gitlab-ci.yml --- golang-pretty-0.0~git20160325.0.add1dbc/debian/gitlab-ci.yml 1970-01-01 00:00:00.000000000 +0000 +++ golang-pretty-0.1.0/debian/gitlab-ci.yml 2018-12-20 02:38:14.000000000 +0000 @@ -0,0 +1,28 @@ + +# auto-generated, DO NOT MODIFY. +# The authoritative copy of this file lives at: +# https://salsa.debian.org/go-team/ci/blob/master/cmd/ci/gitlabciyml.go + +# TODO: publish under debian-go-team/ci +image: stapelberg/ci2 + +test_the_archive: + artifacts: + paths: + - before-applying-commit.json + - after-applying-commit.json + script: + # Create an overlay to discard writes to /srv/gopath/src after the build: + - "rm -rf /cache/overlay/{upper,work}" + - "mkdir -p /cache/overlay/{upper,work}" + - "mount -t overlay overlay -o lowerdir=/srv/gopath/src,upperdir=/cache/overlay/upper,workdir=/cache/overlay/work /srv/gopath/src" + - "export GOPATH=/srv/gopath" + - "export GOCACHE=/cache/go" + # Build the world as-is: + - "ci-build -exemptions=/var/lib/ci-build/exemptions.json > before-applying-commit.json" + # Copy this package into the overlay: + - "GBP_CONF_FILES=:debian/gbp.conf gbp buildpackage --git-no-pristine-tar --git-ignore-branch --git-ignore-new --git-export-dir=/tmp/export --git-no-overlay --git-tarball-dir=/nonexistant --git-cleaner=/bin/true --git-builder='dpkg-buildpackage -S -d --no-sign'" + - "pgt-gopath -dsc /tmp/export/*.dsc" + # Rebuild the world: + - "ci-build -exemptions=/var/lib/ci-build/exemptions.json > after-applying-commit.json" + - "ci-diff before-applying-commit.json after-applying-commit.json" diff -Nru golang-pretty-0.0~git20160325.0.add1dbc/debian/watch golang-pretty-0.1.0/debian/watch --- golang-pretty-0.0~git20160325.0.add1dbc/debian/watch 1970-01-01 00:00:00.000000000 +0000 +++ golang-pretty-0.1.0/debian/watch 2018-12-20 02:46:35.000000000 +0000 @@ -0,0 +1,4 @@ +version=3 +opts=filenamemangle=s/.+\/v?(\d\S*)\.tar\.gz/golang-pretty--\$1\.tar\.gz/,\ +uversionmangle=s/(\d)[_\.\-\+]?(RC|rc|pre|dev|beta|alpha)[.]?(\d*)$/\$1~\$2\$3/ \ + https://github.com/kr/pretty/tags .*/v?(\d\S*)\.tar\.gz diff -Nru golang-pretty-0.0~git20160325.0.add1dbc/diff.go golang-pretty-0.1.0/diff.go --- golang-pretty-0.0~git20160325.0.add1dbc/diff.go 2016-03-25 21:56:24.000000000 +0000 +++ golang-pretty-0.1.0/diff.go 2018-05-06 08:33:45.000000000 +0000 @@ -8,43 +8,81 @@ type sbuf []string -func (s *sbuf) Write(b []byte) (int, error) { - *s = append(*s, string(b)) - return len(b), nil +func (p *sbuf) Printf(format string, a ...interface{}) { + s := fmt.Sprintf(format, a...) + *p = append(*p, s) } // Diff returns a slice where each element describes // a difference between a and b. func Diff(a, b interface{}) (desc []string) { - Fdiff((*sbuf)(&desc), a, b) + Pdiff((*sbuf)(&desc), a, b) return desc } +// wprintfer calls Fprintf on w for each Printf call +// with a trailing newline. +type wprintfer struct{ w io.Writer } + +func (p *wprintfer) Printf(format string, a ...interface{}) { + fmt.Fprintf(p.w, format+"\n", a...) +} + // Fdiff writes to w a description of the differences between a and b. func Fdiff(w io.Writer, a, b interface{}) { - diffWriter{w: w}.diff(reflect.ValueOf(a), reflect.ValueOf(b)) + Pdiff(&wprintfer{w}, a, b) +} + +type Printfer interface { + Printf(format string, a ...interface{}) +} + +// Pdiff prints to p a description of the differences between a and b. +// It calls Printf once for each difference, with no trailing newline. +// The standard library log.Logger is a Printfer. +func Pdiff(p Printfer, a, b interface{}) { + diffPrinter{w: p}.diff(reflect.ValueOf(a), reflect.ValueOf(b)) +} + +type Logfer interface { + Logf(format string, a ...interface{}) } -type diffWriter struct { - w io.Writer +// logprintfer calls Fprintf on w for each Printf call +// with a trailing newline. +type logprintfer struct{ l Logfer } + +func (p *logprintfer) Printf(format string, a ...interface{}) { + p.l.Logf(format, a...) +} + +// Ldiff prints to l a description of the differences between a and b. +// It calls Logf once for each difference, with no trailing newline. +// The standard library testing.T and testing.B are Logfers. +func Ldiff(l Logfer, a, b interface{}) { + Pdiff(&logprintfer{l}, a, b) +} + +type diffPrinter struct { + w Printfer l string // label } -func (w diffWriter) printf(f string, a ...interface{}) { +func (w diffPrinter) printf(f string, a ...interface{}) { var l string if w.l != "" { l = w.l + ": " } - fmt.Fprintf(w.w, l+f, a...) + w.w.Printf(l+f, a...) } -func (w diffWriter) diff(av, bv reflect.Value) { +func (w diffPrinter) diff(av, bv reflect.Value) { if !av.IsValid() && bv.IsValid() { - w.printf("nil != %#v", bv.Interface()) + w.printf("nil != %# v", formatter{v: bv, quote: true}) return } if av.IsValid() && !bv.IsValid() { - w.printf("%#v != nil", av.Interface()) + w.printf("%# v != nil", formatter{v: av, quote: true}) return } if !av.IsValid() && !bv.IsValid() { @@ -58,34 +96,61 @@ return } - // numeric types, including bool - if at.Kind() < reflect.Array { - a, b := av.Interface(), bv.Interface() - if a != b { - w.printf("%#v != %#v", a, b) + switch kind := at.Kind(); kind { + case reflect.Bool: + if a, b := av.Bool(), bv.Bool(); a != b { + w.printf("%v != %v", a, b) + } + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + if a, b := av.Int(), bv.Int(); a != b { + w.printf("%d != %d", a, b) + } + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + if a, b := av.Uint(), bv.Uint(); a != b { + w.printf("%d != %d", a, b) + } + case reflect.Float32, reflect.Float64: + if a, b := av.Float(), bv.Float(); a != b { + w.printf("%v != %v", a, b) + } + case reflect.Complex64, reflect.Complex128: + if a, b := av.Complex(), bv.Complex(); a != b { + w.printf("%v != %v", a, b) + } + case reflect.Array: + n := av.Len() + for i := 0; i < n; i++ { + w.relabel(fmt.Sprintf("[%d]", i)).diff(av.Index(i), bv.Index(i)) } - return - } - - switch at.Kind() { - case reflect.String: - a, b := av.Interface(), bv.Interface() - if a != b { - w.printf("%q != %q", a, b) + case reflect.Chan, reflect.Func, reflect.UnsafePointer: + if a, b := av.Pointer(), bv.Pointer(); a != b { + w.printf("%#x != %#x", a, b) + } + case reflect.Interface: + w.diff(av.Elem(), bv.Elem()) + case reflect.Map: + ak, both, bk := keyDiff(av.MapKeys(), bv.MapKeys()) + for _, k := range ak { + w := w.relabel(fmt.Sprintf("[%#v]", k)) + w.printf("%q != (missing)", av.MapIndex(k)) + } + for _, k := range both { + w := w.relabel(fmt.Sprintf("[%#v]", k)) + w.diff(av.MapIndex(k), bv.MapIndex(k)) + } + for _, k := range bk { + w := w.relabel(fmt.Sprintf("[%#v]", k)) + w.printf("(missing) != %q", bv.MapIndex(k)) } case reflect.Ptr: switch { case av.IsNil() && !bv.IsNil(): - w.printf("nil != %v", bv.Interface()) + w.printf("nil != %# v", formatter{v: bv, quote: true}) case !av.IsNil() && bv.IsNil(): - w.printf("%v != nil", av.Interface()) + w.printf("%# v != nil", formatter{v: av, quote: true}) case !av.IsNil() && !bv.IsNil(): w.diff(av.Elem(), bv.Elem()) } - case reflect.Struct: - for i := 0; i < av.NumField(); i++ { - w.relabel(at.Field(i).Name).diff(av.Field(i), bv.Field(i)) - } case reflect.Slice: lenA := av.Len() lenB := bv.Len() @@ -96,30 +161,20 @@ for i := 0; i < lenA; i++ { w.relabel(fmt.Sprintf("[%d]", i)).diff(av.Index(i), bv.Index(i)) } - case reflect.Map: - ak, both, bk := keyDiff(av.MapKeys(), bv.MapKeys()) - for _, k := range ak { - w := w.relabel(fmt.Sprintf("[%#v]", k.Interface())) - w.printf("%q != (missing)", av.MapIndex(k)) - } - for _, k := range both { - w := w.relabel(fmt.Sprintf("[%#v]", k.Interface())) - w.diff(av.MapIndex(k), bv.MapIndex(k)) + case reflect.String: + if a, b := av.String(), bv.String(); a != b { + w.printf("%q != %q", a, b) } - for _, k := range bk { - w := w.relabel(fmt.Sprintf("[%#v]", k.Interface())) - w.printf("(missing) != %q", bv.MapIndex(k)) + case reflect.Struct: + for i := 0; i < av.NumField(); i++ { + w.relabel(at.Field(i).Name).diff(av.Field(i), bv.Field(i)) } - case reflect.Interface: - w.diff(reflect.ValueOf(av.Interface()), reflect.ValueOf(bv.Interface())) default: - if !reflect.DeepEqual(av.Interface(), bv.Interface()) { - w.printf("%# v != %# v", Formatter(av.Interface()), Formatter(bv.Interface())) - } + panic("unknown reflect Kind: " + kind.String()) } } -func (d diffWriter) relabel(name string) (d1 diffWriter) { +func (d diffPrinter) relabel(name string) (d1 diffPrinter) { d1 = d if d.l != "" && name[0] != '[' { d1.l += "." @@ -128,11 +183,63 @@ return d1 } +// keyEqual compares a and b for equality. +// Both a and b must be valid map keys. +func keyEqual(av, bv reflect.Value) bool { + if !av.IsValid() && !bv.IsValid() { + return true + } + if !av.IsValid() || !bv.IsValid() || av.Type() != bv.Type() { + return false + } + switch kind := av.Kind(); kind { + case reflect.Bool: + a, b := av.Bool(), bv.Bool() + return a == b + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + a, b := av.Int(), bv.Int() + return a == b + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + a, b := av.Uint(), bv.Uint() + return a == b + case reflect.Float32, reflect.Float64: + a, b := av.Float(), bv.Float() + return a == b + case reflect.Complex64, reflect.Complex128: + a, b := av.Complex(), bv.Complex() + return a == b + case reflect.Array: + for i := 0; i < av.Len(); i++ { + if !keyEqual(av.Index(i), bv.Index(i)) { + return false + } + } + return true + case reflect.Chan, reflect.UnsafePointer, reflect.Ptr: + a, b := av.Pointer(), bv.Pointer() + return a == b + case reflect.Interface: + return keyEqual(av.Elem(), bv.Elem()) + case reflect.String: + a, b := av.String(), bv.String() + return a == b + case reflect.Struct: + for i := 0; i < av.NumField(); i++ { + if !keyEqual(av.Field(i), bv.Field(i)) { + return false + } + } + return true + default: + panic("invalid map key type " + av.Type().String()) + } +} + func keyDiff(a, b []reflect.Value) (ak, both, bk []reflect.Value) { for _, av := range a { inBoth := false for _, bv := range b { - if reflect.DeepEqual(av.Interface(), bv.Interface()) { + if keyEqual(av, bv) { inBoth = true both = append(both, av) break @@ -145,7 +252,7 @@ for _, bv := range b { inBoth := false for _, av := range a { - if reflect.DeepEqual(av.Interface(), bv.Interface()) { + if keyEqual(av, bv) { inBoth = true break } diff -Nru golang-pretty-0.0~git20160325.0.add1dbc/diff_test.go golang-pretty-0.1.0/diff_test.go --- golang-pretty-0.0~git20160325.0.add1dbc/diff_test.go 2016-03-25 21:56:24.000000000 +0000 +++ golang-pretty-0.1.0/diff_test.go 2018-05-06 08:33:45.000000000 +0000 @@ -1,7 +1,18 @@ package pretty import ( + "bytes" + "fmt" + "log" + "reflect" "testing" + "unsafe" +) + +var ( + _ Logfer = (*testing.T)(nil) + _ Logfer = (*testing.B)(nil) + _ Printfer = (*log.Logger)(nil) ) type difftest struct { @@ -17,6 +28,20 @@ C []int } +type ( + N struct{ N int } + E interface{} +) + +var ( + c0 = make(chan int) + c1 = make(chan int) + f0 = func() {} + f1 = func() {} + i0 = 0 + i1 = 1 +) + var diffs = []difftest{ {a: nil, b: nil}, {a: S{A: 1}, b: S{A: 1}}, @@ -28,12 +53,79 @@ {S{}, S{A: 1}, []string{`A: 0 != 1`}}, {new(S), &S{A: 1}, []string{`A: 0 != 1`}}, {S{S: new(S)}, S{S: &S{A: 1}}, []string{`S.A: 0 != 1`}}, - {S{}, S{I: 0}, []string{`I: nil != 0`}}, + {S{}, S{I: 0}, []string{`I: nil != int(0)`}}, {S{I: 1}, S{I: "x"}, []string{`I: int != string`}}, {S{}, S{C: []int{1}}, []string{`C: []int[0] != []int[1]`}}, {S{C: []int{}}, S{C: []int{1}}, []string{`C: []int[0] != []int[1]`}}, {S{C: []int{1, 2, 3}}, S{C: []int{1, 2, 4}}, []string{`C[2]: 3 != 4`}}, - {S{}, S{A: 1, S: new(S)}, []string{`A: 0 != 1`, `S: nil != &{0 []}`}}, + {S{}, S{A: 1, S: new(S)}, []string{`A: 0 != 1`, `S: nil != &pretty.S{}`}}, + + // unexported fields of every reflect.Kind (both equal and unequal) + {struct{ x bool }{false}, struct{ x bool }{false}, nil}, + {struct{ x bool }{false}, struct{ x bool }{true}, []string{`x: false != true`}}, + {struct{ x int }{0}, struct{ x int }{0}, nil}, + {struct{ x int }{0}, struct{ x int }{1}, []string{`x: 0 != 1`}}, + {struct{ x int8 }{0}, struct{ x int8 }{0}, nil}, + {struct{ x int8 }{0}, struct{ x int8 }{1}, []string{`x: 0 != 1`}}, + {struct{ x int16 }{0}, struct{ x int16 }{0}, nil}, + {struct{ x int16 }{0}, struct{ x int16 }{1}, []string{`x: 0 != 1`}}, + {struct{ x int32 }{0}, struct{ x int32 }{0}, nil}, + {struct{ x int32 }{0}, struct{ x int32 }{1}, []string{`x: 0 != 1`}}, + {struct{ x int64 }{0}, struct{ x int64 }{0}, nil}, + {struct{ x int64 }{0}, struct{ x int64 }{1}, []string{`x: 0 != 1`}}, + {struct{ x uint }{0}, struct{ x uint }{0}, nil}, + {struct{ x uint }{0}, struct{ x uint }{1}, []string{`x: 0 != 1`}}, + {struct{ x uint8 }{0}, struct{ x uint8 }{0}, nil}, + {struct{ x uint8 }{0}, struct{ x uint8 }{1}, []string{`x: 0 != 1`}}, + {struct{ x uint16 }{0}, struct{ x uint16 }{0}, nil}, + {struct{ x uint16 }{0}, struct{ x uint16 }{1}, []string{`x: 0 != 1`}}, + {struct{ x uint32 }{0}, struct{ x uint32 }{0}, nil}, + {struct{ x uint32 }{0}, struct{ x uint32 }{1}, []string{`x: 0 != 1`}}, + {struct{ x uint64 }{0}, struct{ x uint64 }{0}, nil}, + {struct{ x uint64 }{0}, struct{ x uint64 }{1}, []string{`x: 0 != 1`}}, + {struct{ x uintptr }{0}, struct{ x uintptr }{0}, nil}, + {struct{ x uintptr }{0}, struct{ x uintptr }{1}, []string{`x: 0 != 1`}}, + {struct{ x float32 }{0}, struct{ x float32 }{0}, nil}, + {struct{ x float32 }{0}, struct{ x float32 }{1}, []string{`x: 0 != 1`}}, + {struct{ x float64 }{0}, struct{ x float64 }{0}, nil}, + {struct{ x float64 }{0}, struct{ x float64 }{1}, []string{`x: 0 != 1`}}, + {struct{ x complex64 }{0}, struct{ x complex64 }{0}, nil}, + {struct{ x complex64 }{0}, struct{ x complex64 }{1}, []string{`x: (0+0i) != (1+0i)`}}, + {struct{ x complex128 }{0}, struct{ x complex128 }{0}, nil}, + {struct{ x complex128 }{0}, struct{ x complex128 }{1}, []string{`x: (0+0i) != (1+0i)`}}, + {struct{ x [1]int }{[1]int{0}}, struct{ x [1]int }{[1]int{0}}, nil}, + {struct{ x [1]int }{[1]int{0}}, struct{ x [1]int }{[1]int{1}}, []string{`x[0]: 0 != 1`}}, + {struct{ x chan int }{c0}, struct{ x chan int }{c0}, nil}, + {struct{ x chan int }{c0}, struct{ x chan int }{c1}, []string{fmt.Sprintf("x: %p != %p", c0, c1)}}, + {struct{ x func() }{f0}, struct{ x func() }{f0}, nil}, + {struct{ x func() }{f0}, struct{ x func() }{f1}, []string{fmt.Sprintf("x: %p != %p", f0, f1)}}, + {struct{ x interface{} }{0}, struct{ x interface{} }{0}, nil}, + {struct{ x interface{} }{0}, struct{ x interface{} }{1}, []string{`x: 0 != 1`}}, + {struct{ x interface{} }{0}, struct{ x interface{} }{""}, []string{`x: int != string`}}, + {struct{ x interface{} }{0}, struct{ x interface{} }{nil}, []string{`x: int(0) != nil`}}, + {struct{ x interface{} }{nil}, struct{ x interface{} }{0}, []string{`x: nil != int(0)`}}, + {struct{ x map[int]int }{map[int]int{0: 0}}, struct{ x map[int]int }{map[int]int{0: 0}}, nil}, + {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`}}, + {struct{ x *int }{new(int)}, struct{ x *int }{new(int)}, nil}, + {struct{ x *int }{&i0}, struct{ x *int }{&i1}, []string{`x: 0 != 1`}}, + {struct{ x *int }{nil}, struct{ x *int }{&i0}, []string{`x: nil != &int(0)`}}, + {struct{ x *int }{&i0}, struct{ x *int }{nil}, []string{`x: &int(0) != nil`}}, + {struct{ x []int }{[]int{0}}, struct{ x []int }{[]int{0}}, nil}, + {struct{ x []int }{[]int{0}}, struct{ x []int }{[]int{1}}, []string{`x[0]: 0 != 1`}}, + {struct{ x string }{"a"}, struct{ x string }{"a"}, nil}, + {struct{ x string }{"a"}, struct{ x string }{"b"}, []string{`x: "a" != "b"`}}, + {struct{ x N }{N{0}}, struct{ x N }{N{0}}, nil}, + {struct{ x N }{N{0}}, struct{ x N }{N{1}}, []string{`x.N: 0 != 1`}}, + { + struct{ x unsafe.Pointer }{unsafe.Pointer(uintptr(0))}, + struct{ x unsafe.Pointer }{unsafe.Pointer(uintptr(0))}, + nil, + }, + { + struct{ x unsafe.Pointer }{unsafe.Pointer(uintptr(0))}, + struct{ x unsafe.Pointer }{unsafe.Pointer(uintptr(1))}, + []string{`x: 0x0 != 0x1`}, + }, } func TestDiff(t *testing.T) { @@ -54,6 +146,53 @@ } } +func TestKeyEqual(t *testing.T) { + var emptyInterfaceZero interface{} = 0 + + cases := []interface{}{ + new(bool), + new(int), + new(int8), + new(int16), + new(int32), + new(int64), + new(uint), + new(uint8), + new(uint16), + new(uint32), + new(uint64), + new(uintptr), + new(float32), + new(float64), + new(complex64), + new(complex128), + new([1]int), + new(chan int), + new(unsafe.Pointer), + new(interface{}), + &emptyInterfaceZero, + new(*int), + new(string), + new(struct{ int }), + } + + for _, test := range cases { + rv := reflect.ValueOf(test).Elem() + if !keyEqual(rv, rv) { + t.Errorf("keyEqual(%s, %s) = false want true", rv.Type(), rv.Type()) + } + } +} + +func TestFdiff(t *testing.T) { + var buf bytes.Buffer + Fdiff(&buf, 0, 1) + want := "0 != 1\n" + if got := buf.String(); got != want { + t.Errorf("Fdiff(0, 1) = %q want %q", got, want) + } +} + func diffdiff(t *testing.T, got, exp []string) { minus(t, "unexpected:", got, exp) minus(t, "missing:", exp, got) diff -Nru golang-pretty-0.0~git20160325.0.add1dbc/formatter.go golang-pretty-0.1.0/formatter.go --- golang-pretty-0.0~git20160325.0.add1dbc/formatter.go 2016-03-25 21:56:24.000000000 +0000 +++ golang-pretty-0.1.0/formatter.go 2018-05-06 08:33:45.000000000 +0000 @@ -10,12 +10,8 @@ "github.com/kr/text" ) -const ( - limit = 50 -) - type formatter struct { - x interface{} + v reflect.Value force bool quote bool } @@ -30,11 +26,11 @@ // format x according to the usual rules of package fmt. // In particular, if x satisfies fmt.Formatter, then x.Format will be called. func Formatter(x interface{}) (f fmt.Formatter) { - return formatter{x: x, quote: true} + return formatter{v: reflect.ValueOf(x), quote: true} } func (fo formatter) String() string { - return fmt.Sprint(fo.x) // unwrap it + return fmt.Sprint(fo.v.Interface()) // unwrap it } func (fo formatter) passThrough(f fmt.State, c rune) { @@ -51,14 +47,14 @@ s += fmt.Sprintf(".%d", p) } s += string(c) - fmt.Fprintf(f, s, fo.x) + fmt.Fprintf(f, s, fo.v.Interface()) } func (fo formatter) Format(f fmt.State, c rune) { if fo.force || c == 'v' && f.Flag('#') && f.Flag(' ') { w := tabwriter.NewWriter(f, 4, 4, 1, ' ', 0) p := &printer{tw: w, Writer: w, visited: make(map[visit]int)} - p.printValue(reflect.ValueOf(fo.x), true, fo.quote) + p.printValue(fo.v, true, fo.quote) w.Flush() return } @@ -319,11 +315,6 @@ io.WriteString(p, s) } -func tryDeepEqual(a, b interface{}) bool { - defer func() { recover() }() - return reflect.DeepEqual(a, b) -} - func writeByte(w io.Writer, b byte) { w.Write([]byte{b}) } diff -Nru golang-pretty-0.0~git20160325.0.add1dbc/formatter_test.go golang-pretty-0.1.0/formatter_test.go --- golang-pretty-0.0~git20160325.0.add1dbc/formatter_test.go 2016-03-25 21:56:24.000000000 +0000 +++ golang-pretty-0.1.0/formatter_test.go 2018-05-06 08:33:45.000000000 +0000 @@ -13,6 +13,11 @@ s string } +type passtest struct { + v interface{} + f, s string +} + type LongStructTypeName struct { longFieldName interface{} otherLongFieldName interface{} @@ -33,8 +38,30 @@ fmt.Fprintf(s, "F(%d)", int(f)) } +type Stringer struct { i int } + +func (s *Stringer) String() string { return "foo" } + var long = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" +var passthrough = []passtest{ + {1, "%d", "1"}, + {"a", "%s", "a"}, + {&Stringer{}, "%s", "foo"}, +} + +func TestPassthrough(t *testing.T) { + for _, tt := range passthrough { + s := fmt.Sprintf(tt.f, Formatter(tt.v)) + if tt.s != s { + t.Errorf("expected %q", tt.s) + t.Errorf("got %q", s) + t.Errorf("expraw\n%s", tt.s) + t.Errorf("gotraw\n%s", s) + } + } +} + var gosyntax = []test{ {nil, `nil`}, {"", `""`}, diff -Nru golang-pretty-0.0~git20160325.0.add1dbc/go.mod golang-pretty-0.1.0/go.mod --- golang-pretty-0.0~git20160325.0.add1dbc/go.mod 1970-01-01 00:00:00.000000000 +0000 +++ golang-pretty-0.1.0/go.mod 2018-05-06 08:33:45.000000000 +0000 @@ -0,0 +1,3 @@ +module "github.com/kr/pretty" + +require "github.com/kr/text" v0.1.0 diff -Nru golang-pretty-0.0~git20160325.0.add1dbc/pretty.go golang-pretty-0.1.0/pretty.go --- golang-pretty-0.0~git20160325.0.add1dbc/pretty.go 2016-03-25 21:56:24.000000000 +0000 +++ golang-pretty-0.1.0/pretty.go 2018-05-06 08:33:45.000000000 +0000 @@ -11,6 +11,7 @@ "fmt" "io" "log" + "reflect" ) // Errorf is a convenience wrapper for fmt.Errorf. @@ -101,7 +102,7 @@ func wrap(a []interface{}, force bool) []interface{} { w := make([]interface{}, len(a)) for i, x := range a { - w[i] = formatter{x: x, force: force} + w[i] = formatter{v: reflect.ValueOf(x), force: force} } return w }