From 64ec6c34e42761add69f16b29302799856bf5443 Mon Sep 17 00:00:00 2001 From: Arpad Ryszka Date: Thu, 26 Nov 2020 18:05:14 +0100 Subject: [PATCH] linting --- README.md | 1 + fprint.go | 166 +++++++++++++++++++++++++-------------------- fprintmore_test.go | 165 +++++++++++++------------------------------- notation.go | 10 +-- sprint_test.go | 40 +++++------ 5 files changed, 168 insertions(+), 214 deletions(-) diff --git a/README.md b/README.md index ace34fb..f310998 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Notation - print Go objects +[![Go Report Card](https://goreportcard.com/badge/github.com/aryszka/notation)](https://goreportcard.com/report/github.com/aryszka/notation) [![codecov](https://codecov.io/gh/aryszka/notation/branch/master/graph/badge.svg?token=7M18MEAVQW)](https://codecov.io/gh/aryszka/notation) This package can be used to print (or sprint) Go objects for debugging purposes, with optional wrapping diff --git a/fprint.go b/fprint.go index b9cebff..76c75d4 100644 --- a/fprint.go +++ b/fprint.go @@ -40,32 +40,28 @@ func strLen(s str) str { return s } -func nodeLen(t int, n node) node { - // We assume here that an str is always contained - // by a node that has only a single str. - // - if s, ok := n.parts[0].(str); ok { - s = strLen(s) - n.parts[0] = s - n.len = len(s.val) - if s.raw == "" { - wl := wrapLen{ - first: len(s.val), - max: len(s.val), - last: len(s.val), - } - - n.wrapLen = wl - n.fullWrap = wl - return n +func stringNodeLen(n node) node { + s := strLen(n.parts[0].(str)) + n.parts[0] = s + n.len = len(s.val) + if s.raw == "" { + wl := wrapLen{ + first: len(s.val), + max: len(s.val), + last: len(s.val), } - n.wrapLen = s.rawLen - n.fullWrap = s.rawLen + n.wrapLen = wl + n.fullWrap = wl return n } - // measure all parts: + n.wrapLen = s.rawLen + n.fullWrap = s.rawLen + return n +} + +func measureParts(t int, n node) node { for i := range n.parts { switch pt := n.parts[i].(type) { case node: @@ -77,7 +73,10 @@ func nodeLen(t int, n node) node { } } - // measure the unwrapped length: + return n +} + +func measureUnwrapped(n node) node { for _, p := range n.parts { switch pt := p.(type) { case node: @@ -96,7 +95,10 @@ func nodeLen(t int, n node) node { } } - // measure the wrapped and the fully wrapped length: + return n +} + +func measureWrapped(t int, n node) node { var w, f int for _, p := range n.parts { switch pt := p.(type) { @@ -186,6 +188,20 @@ func nodeLen(t int, n node) node { return n } +func nodeLen(t int, n node) node { + // We assume here that an str is always contained + // by a node that has only a single str. + // + if _, ok := n.parts[0].(str); ok { + return stringNodeLen(n) + } + + n = measureParts(t, n) + n = measureUnwrapped(n) + n = measureWrapped(t, n) + return n +} + func wrapNode(t, cf0, c0, c1 int, n node) node { // fits: if n.len <= c0 { @@ -319,6 +335,59 @@ func wrapNode(t, cf0, c0, c1 int, n node) node { return n } +func fprintWrapper(w *writer, t int, wrap bool, wr wrapper) { + if len(wr.items) == 0 { + return + } + + if !wrap { + for i, ni := range wr.items { + if i > 0 { + w.write(wr.sep) + } + + fprint(w, t, ni) + } + + return + } + + switch wr.mode { + case line: + var ( + lines [][]node + last int + ) + + for _, i := range wr.lineEnds { + lines = append(lines, wr.items[last:i]) + last = i + } + + for _, line := range lines { + w.line(1) + for i, ni := range line { + if i > 0 { + w.write(wr.sep) + } + + fprint(w, 0, ni) + } + } + default: + t++ + for _, ni := range wr.items { + w.line(t) + fprint(w, t, ni) + w.write(wr.suffix) + } + + t-- + } + + w.line(t) +} + func fprint(w *writer, t int, n node) { // handle write errors at a single place: if w.err != nil { @@ -330,56 +399,7 @@ func fprint(w *writer, t int, n node) { case node: fprint(w, t, part) case wrapper: - if len(part.items) == 0 { - continue - } - - if !n.wrap { - for i, ni := range part.items { - if i > 0 { - w.write(part.sep) - } - - fprint(w, t, ni) - } - - continue - } - - switch part.mode { - case line: - var ( - lines [][]node - last int - ) - - for _, i := range part.lineEnds { - lines = append(lines, part.items[last:i]) - last = i - } - - for _, line := range lines { - w.line(1) - for i, ni := range line { - if i > 0 { - w.write(part.sep) - } - - fprint(w, 0, ni) - } - } - default: - t++ - for _, ni := range part.items { - w.line(t) - fprint(w, t, ni) - w.write(part.suffix) - } - - t-- - } - - w.line(t) + fprintWrapper(w, t, n.wrap, part) default: w.write(part) } diff --git a/fprintmore_test.go b/fprintmore_test.go index 59b1ed6..263abce 100644 --- a/fprintmore_test.go +++ b/fprintmore_test.go @@ -3,6 +3,7 @@ package notation import ( "bytes" "errors" + "io" "testing" ) @@ -78,129 +79,61 @@ func TestFailingWriter(t *testing.T) { } func TestFprint(t *testing.T) { - t.Run("Fprint", func(t *testing.T) { - const expect = `{fooBarBaz: 42}` - var b bytes.Buffer - o := struct{ fooBarBaz int }{42} - defer withEnv(t, "TABWIDTH=0", "LINEWIDTH=0", "LINEWIDTH1=0")() - n, err := Fprint(&b, o) - if err != nil { - t.Fatal(err) - } - - if n != len(expect) { - t.Fatalf("invalid write length; expected: %d, got: %d", len(expect), n) - } - - if b.String() != expect { - t.Fatalf("invalid output; expected: %s, got: %s", expect, b.String()) - } - }) - - t.Run("Fprintw", func(t *testing.T) { - const expect = `{ + defer withEnv(t, "TABWIDTH=0", "LINEWIDTH=0", "LINEWIDTH1=0")() + o := struct{ fooBarBaz int }{42} + for _, test := range []struct { + name string + fn func(io.Writer, ...interface{}) (int, error) + expect string + }{{ + name: "Fprint", + fn: Fprint, + expect: `{fooBarBaz: 42}`, + }, { + name: "Fprintw", + fn: Fprintw, + expect: `{ fooBarBaz: 42, -}` - - var b bytes.Buffer - o := struct{ fooBarBaz int }{42} - defer withEnv(t, "TABWIDTH=0", "LINEWIDTH=0", "LINEWIDTH1=0")() - n, err := Fprintw(&b, o) - if err != nil { - t.Fatal(err) - } - - if b.String() != expect { - t.Fatalf("invalid output; expected: %s, got: %s", expect, b.String()) - } - - if n != len(expect) { - t.Fatalf("invalid write length; expected: %d, got: %d", len(expect), n) - } - }) - - t.Run("Fprintt", func(t *testing.T) { - const expect = `struct{fooBarBaz int}{fooBarBaz: 42}` - var b bytes.Buffer - o := struct{ fooBarBaz int }{42} - defer withEnv(t, "TABWIDTH=0", "LINEWIDTH=0", "LINEWIDTH1=0")() - n, err := Fprintt(&b, o) - if err != nil { - t.Fatal(err) - } - - if n != len(expect) { - t.Fatalf("invalid write length; expected: %d, got: %d", len(expect), n) - } - - if b.String() != expect { - t.Fatalf("invalid output; expected: %s, got: %s", expect, b.String()) - } - }) - - t.Run("Fprintwt", func(t *testing.T) { - const expect = `struct{ +}`, + }, { + name: "Fprintt", + fn: Fprintt, + expect: `struct{fooBarBaz int}{fooBarBaz: 42}`, + }, { + name: "Fprintwt", + fn: Fprintwt, + expect: `struct{ fooBarBaz int }{ fooBarBaz: 42, -}` - - var b bytes.Buffer - o := struct{ fooBarBaz int }{42} - defer withEnv(t, "TABWIDTH=0", "LINEWIDTH=0", "LINEWIDTH1=0")() - n, err := Fprintwt(&b, o) - if err != nil { - t.Fatal(err) - } - - if n != len(expect) { - t.Fatalf("invalid write length; expected: %d, got: %d", len(expect), n) - } - - if b.String() != expect { - t.Fatalf("invalid output; expected: %s, got: %s", expect, b.String()) - } - }) - - t.Run("Fprintv", func(t *testing.T) { - const expect = `struct{fooBarBaz int}{fooBarBaz: int(42)}` - var b bytes.Buffer - o := struct{ fooBarBaz int }{42} - defer withEnv(t, "TABWIDTH=0", "LINEWIDTH=0", "LINEWIDTH1=0")() - n, err := Fprintv(&b, o) - if err != nil { - t.Fatal(err) - } - - if n != len(expect) { - t.Fatalf("invalid write length; expected: %d, got: %d", len(expect), n) - } - - if b.String() != expect { - t.Fatalf("invalid output; expected: %s, got: %s", expect, b.String()) - } - }) - - t.Run("Fprintv", func(t *testing.T) { - const expect = `struct{ +}`, + }, { + name: "Fprintv", + fn: Fprintv, + expect: `struct{fooBarBaz int}{fooBarBaz: int(42)}`, + }, { + name: "Fprintwv", + fn: Fprintwv, + expect: `struct{ fooBarBaz int }{ fooBarBaz: int(42), -}` - var b bytes.Buffer - o := struct{ fooBarBaz int }{42} - defer withEnv(t, "TABWIDTH=0", "LINEWIDTH=0", "LINEWIDTH1=0")() - n, err := Fprintwv(&b, o) - if err != nil { - t.Fatal(err) - } +}`, + }} { + t.Run(test.name, func(t *testing.T) { + var b bytes.Buffer + n, err := test.fn(&b, o) + if err != nil { + t.Fatal(err) + } - if n != len(expect) { - t.Fatalf("invalid write length; expected: %d, got: %d", len(expect), n) - } + if n != len(test.expect) { + t.Fatalf("invalid write length; expected %d, got: %d", len(test.expect), n) + } - if b.String() != expect { - t.Fatalf("invalid output; expected: %s, got: %s", expect, b.String()) - } - }) + if b.String() != test.expect { + t.Fatalf("invalid output; expected: %s, got: %s", test.expect, b.String()) + } + }) + } } diff --git a/notation.go b/notation.go index eb88b20..e8d7433 100644 --- a/notation.go +++ b/notation.go @@ -316,31 +316,31 @@ func Sprint(v ...interface{}) string { return sprintValues(none, v) } -// Sprint returns the string representation of the Go objects, with wrapping (and indentation) where necessary. +// Sprintw returns the string representation of the Go objects, with wrapping (and indentation) where necessary. // When multiple objects are provided, they'll be seprated by a newline. func Sprintw(v ...interface{}) string { return sprintValues(wrap, v) } -// Sprint returns the string representation of the Go objects, with moderate type information. When multiple +// Sprintt returns the string representation of the Go objects, with moderate type information. When multiple // objects are provided, they'll be seprated by a space. func Sprintt(v ...interface{}) string { return sprintValues(types, v) } -// Sprint returns the string representation of the Go objects, with wrapping (and indentation) where necessary, +// Sprintwt returns the string representation of the Go objects, with wrapping (and indentation) where necessary, // and with moderate type information. When multiple objects are provided, they'll be seprated by a newline. func Sprintwt(v ...interface{}) string { return sprintValues(wrap|types, v) } -// Sprint returns the string representation of the Go objects, with verbose type information. When multiple +// Sprintv returns the string representation of the Go objects, with verbose type information. When multiple // objects are provided, they'll be seprated by a space. func Sprintv(v ...interface{}) string { return sprintValues(allTypes, v) } -// Sprint returns the string representation of the Go objects, with wrapping (and indentation) where necessary, +// Sprintwv returns the string representation of the Go objects, with wrapping (and indentation) where necessary, // and with verbose type information. When multiple objects are provided, they'll be seprated by a newline. func Sprintwv(v ...interface{}) string { return sprintValues(wrap|allTypes, v) diff --git a/sprint_test.go b/sprint_test.go index 9c943c9..3ef80d8 100644 --- a/sprint_test.go +++ b/sprint_test.go @@ -40,7 +40,7 @@ func (test test) run(t *testing.T, sprint func(...interface{}) string) { }) } -func (tests tests) run(t *testing.T, sprint func(...interface{}) string) { +func (ts tests) run(t *testing.T, sprint func(...interface{}) string) { logEnv := func(name string, dflt int) { t.Logf("%s=%d", name, config(name, dflt)) } @@ -49,14 +49,14 @@ func (tests tests) run(t *testing.T, sprint func(...interface{}) string) { logEnv("LINEWIDTH", 80-8) logEnv("LINEWIDTH1", 80*3/2-8) - for _, ti := range tests { + for _, ti := range ts { ti.run(t, sprint) } } -func (t tests) expect(expect map[string]string) tests { +func (ts tests) expect(expect map[string]string) tests { var set tests - for _, test := range t { + for _, test := range ts { if expect, doSet := expect[test.title]; doSet { test.expect = expect } @@ -136,8 +136,8 @@ func defaultSet() tests { } } -func (t tests) expectTypes() tests { - return t.expect(map[string]string{ +func (ts tests) expectTypes() tests { + return ts.expect(map[string]string{ "custom false": "myBool(false)", "custom true": "myBool(true)", "custom int": "myInt(42)", @@ -185,8 +185,8 @@ func (t tests) expectTypes() tests { }) } -func (t tests) expectVerboseTypes() tests { - return t.expectTypes().expect(map[string]string{ +func (ts tests) expectVerboseTypes() tests { + return ts.expectTypes().expect(map[string]string{ "false": "bool(false)", "true": "bool(true)", "int": "int(42)", @@ -223,8 +223,8 @@ func (t tests) expectVerboseTypes() tests { }) } -func (t tests) expectWrapAll() tests { - return t.expect(map[string]string{ +func (ts tests) expectWrapAll() tests { + return ts.expect(map[string]string{ "array": `[3]{ 1, 2, @@ -308,8 +308,8 @@ func (t tests) expectWrapAll() tests { }) } -func (t tests) expectOnlyLongWrapped() tests { - return t.expect(map[string]string{ +func (ts tests) expectOnlyLongWrapped() tests { + return ts.expect(map[string]string{ "long item": `[]{ "foobarbazqux", }`, @@ -319,8 +319,8 @@ func (t tests) expectOnlyLongWrapped() tests { }) } -func (t tests) expectWrapAllWithTypes() tests { - return t.expectTypes().expect(map[string]string{ +func (ts tests) expectWrapAllWithTypes() tests { + return ts.expectTypes().expect(map[string]string{ "array": `[3]int{ 1, 2, @@ -450,8 +450,8 @@ func (t tests) expectWrapAllWithTypes() tests { }) } -func (t tests) expectOnlyLongWrappedWithTypes() tests { - return t.expectTypes().expect(map[string]string{ +func (ts tests) expectOnlyLongWrappedWithTypes() tests { + return ts.expectTypes().expect(map[string]string{ "nil channel": `struct{c chan int}{ c: nil, }`, @@ -517,8 +517,8 @@ func (t tests) expectOnlyLongWrappedWithTypes() tests { }) } -func (t tests) expectWrapAllWithVerboseTypes() tests { - return t.expectVerboseTypes().expect(map[string]string{ +func (ts tests) expectWrapAllWithVerboseTypes() tests { + return ts.expectVerboseTypes().expect(map[string]string{ "array": `[3]int{ int(1), int(2), @@ -659,8 +659,8 @@ func (t tests) expectWrapAllWithVerboseTypes() tests { }) } -func (t tests) expectOnlyLongWrappedWithVerboseTypes() tests { - return t.expectVerboseTypes().expect(map[string]string{ +func (ts tests) expectOnlyLongWrappedWithVerboseTypes() tests { + return ts.expectVerboseTypes().expect(map[string]string{ "nil channel": `struct{c chan int}{ c: (chan int)(nil), }`,