fix line mode wrapping and raw text printing
This commit is contained in:
parent
d46324fe78
commit
67225d3ae5
103
fprint.go
103
fprint.go
@ -1,5 +1,7 @@
|
|||||||
package notation
|
package notation
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
func unwrappable(n node) bool {
|
func unwrappable(n node) bool {
|
||||||
return n.len == n.wrapLen.max &&
|
return n.len == n.wrapLen.max &&
|
||||||
n.len == n.fullWrap.max
|
n.len == n.fullWrap.max
|
||||||
@ -29,6 +31,36 @@ func nodeLen(t int, n node) node {
|
|||||||
n.len += len(part)
|
n.len += len(part)
|
||||||
w += len(part)
|
w += len(part)
|
||||||
f += len(part)
|
f += len(part)
|
||||||
|
case str:
|
||||||
|
// We assume here that an str is always contained by a node that has only a
|
||||||
|
// single str.
|
||||||
|
//
|
||||||
|
// If this changes in the future, then we need to provide tests for the
|
||||||
|
// additional cases. If this doesn't change anytime soon, then we can
|
||||||
|
// refactor this part.
|
||||||
|
//
|
||||||
|
n.len = len(part.val)
|
||||||
|
if part.raw == "" {
|
||||||
|
w = len(part.val)
|
||||||
|
f = len(part.val)
|
||||||
|
} else {
|
||||||
|
lines := strings.Split(part.raw, "\n")
|
||||||
|
part.rawLen.first = len(lines[0])
|
||||||
|
for _, line := range lines {
|
||||||
|
if len(line) > part.rawLen.max {
|
||||||
|
part.rawLen.max = len(line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
part.rawLen.last = len(lines[len(lines)-1])
|
||||||
|
n.parts[i] = part
|
||||||
|
n.wrapLen.first = part.rawLen.first
|
||||||
|
n.fullWrap.first = part.rawLen.first
|
||||||
|
n.wrapLen.max = part.rawLen.max
|
||||||
|
n.fullWrap.max = part.rawLen.max
|
||||||
|
w = part.rawLen.last
|
||||||
|
f = part.rawLen.last
|
||||||
|
}
|
||||||
case node:
|
case node:
|
||||||
part = nodeLen(t, part)
|
part = nodeLen(t, part)
|
||||||
n.parts[i] = part
|
n.parts[i] = part
|
||||||
@ -100,7 +132,7 @@ func nodeLen(t int, n node) node {
|
|||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
func wrapNode(t, c0, c1 int, n node) node {
|
func wrapNode(t, cf0, c0, c1 int, n node) node {
|
||||||
if n.len <= c0 {
|
if n.len <= c0 {
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
@ -120,12 +152,32 @@ func wrapNode(t, c0, c1 int, n node) node {
|
|||||||
for i := 0; i < len(n.parts); i++ {
|
for i := 0; i < len(n.parts); i++ {
|
||||||
p := n.parts[i]
|
p := n.parts[i]
|
||||||
switch part := p.(type) {
|
switch part := p.(type) {
|
||||||
|
case string:
|
||||||
|
cc0 -= len(part)
|
||||||
|
cc1 -= len(part)
|
||||||
|
if !trackBack && cc1 < 0 {
|
||||||
|
cc0 = 0
|
||||||
|
cc1 = 0
|
||||||
|
i = lastWrapperIndex
|
||||||
|
trackBack = true
|
||||||
|
}
|
||||||
|
case str:
|
||||||
|
// We assume here that an str is always contained by a node that has only a
|
||||||
|
// single str. Therefore we don't need to trackback to here, because the
|
||||||
|
// decision on wrapping was already made for the node.
|
||||||
|
//
|
||||||
|
// If this changes in the future, then we need to provide tests for the
|
||||||
|
// additional cases. If this doesn't change anytime soon, then we can
|
||||||
|
// refactor this part.
|
||||||
|
//
|
||||||
|
part.useRaw = part.raw != ""
|
||||||
|
n.parts[i] = part
|
||||||
case node:
|
case node:
|
||||||
part = wrapNode(t, cc0, cc1, part)
|
part = wrapNode(t, cf0, cc0, cc1, part)
|
||||||
n.parts[i] = part
|
n.parts[i] = part
|
||||||
if part.wrap {
|
if part.wrap {
|
||||||
// This is an approximation: sometimes part.fullWrap.first is applied here,
|
// This is an approximation: sometimes part.fullWrap.first should be applied
|
||||||
// but usually those are the same.
|
// here, but usually those are the same.
|
||||||
cc0 -= part.wrapLen.first
|
cc0 -= part.wrapLen.first
|
||||||
cc1 -= part.wrapLen.first
|
cc1 -= part.wrapLen.first
|
||||||
} else {
|
} else {
|
||||||
@ -149,13 +201,13 @@ func wrapNode(t, c0, c1 int, n node) node {
|
|||||||
lastWrapperIndex = i
|
lastWrapperIndex = i
|
||||||
switch part.mode {
|
switch part.mode {
|
||||||
case line:
|
case line:
|
||||||
c0, c1 = c0-t, c1-t
|
cl := cf0 - t
|
||||||
var w int
|
var w int
|
||||||
for j, ni := range part.items {
|
for j, ni := range part.items {
|
||||||
if w > 0 && w+len(part.sep)+ni.len > c0 {
|
if w > 0 && w+len(part.sep)+ni.len > cl {
|
||||||
w = 0
|
w = 0
|
||||||
part.lineWrappers = append(
|
part.lineEnds = append(
|
||||||
part.lineWrappers,
|
part.lineEnds,
|
||||||
j,
|
j,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -167,12 +219,13 @@ func wrapNode(t, c0, c1 int, n node) node {
|
|||||||
w += ni.len
|
w += ni.len
|
||||||
}
|
}
|
||||||
|
|
||||||
|
part.lineEnds = append(part.lineEnds, len(part.items))
|
||||||
n.parts[i] = part
|
n.parts[i] = part
|
||||||
c0, c1 = c0+t, c1+t
|
|
||||||
default:
|
default:
|
||||||
for j := range part.items {
|
for j := range part.items {
|
||||||
part.items[j] = wrapNode(
|
part.items[j] = wrapNode(
|
||||||
t,
|
t,
|
||||||
|
cf0,
|
||||||
c0-t,
|
c0-t,
|
||||||
c1-t,
|
c1-t,
|
||||||
part.items[j],
|
part.items[j],
|
||||||
@ -201,48 +254,50 @@ func fprint(w *writer, t int, n node) {
|
|||||||
|
|
||||||
if !n.wrap {
|
if !n.wrap {
|
||||||
for i, ni := range part.items {
|
for i, ni := range part.items {
|
||||||
fprint(w, t, ni)
|
if i > 0 {
|
||||||
if i < len(part.items)-1 {
|
|
||||||
w.write(part.sep)
|
w.write(part.sep)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fprint(w, t, ni)
|
||||||
}
|
}
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
t++
|
|
||||||
switch part.mode {
|
switch part.mode {
|
||||||
case line:
|
case line:
|
||||||
var (
|
var (
|
||||||
wi int
|
lines [][]node
|
||||||
lineStarted bool
|
last int
|
||||||
)
|
)
|
||||||
|
|
||||||
w.line(t)
|
for _, i := range part.lineEnds {
|
||||||
for i, ni := range part.items {
|
lines = append(lines, part.items[last:i])
|
||||||
if len(part.lineWrappers) > wi &&
|
last = i
|
||||||
i == part.lineWrappers[wi] {
|
|
||||||
wi++
|
|
||||||
w.line(t)
|
|
||||||
lineStarted = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if lineStarted {
|
for _, line := range lines {
|
||||||
|
w.blankLine()
|
||||||
|
w.tabs(1)
|
||||||
|
for i, ni := range line {
|
||||||
|
if i > 0 {
|
||||||
w.write(part.sep)
|
w.write(part.sep)
|
||||||
}
|
}
|
||||||
|
|
||||||
fprint(w, 0, ni)
|
fprint(w, 0, ni)
|
||||||
lineStarted = true
|
}
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
t++
|
||||||
for _, ni := range part.items {
|
for _, ni := range part.items {
|
||||||
w.line(t)
|
w.line(t)
|
||||||
fprint(w, t, ni)
|
fprint(w, t, ni)
|
||||||
w.write(part.suffix)
|
w.write(part.suffix)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
t--
|
t--
|
||||||
|
}
|
||||||
|
|
||||||
w.line(t)
|
w.line(t)
|
||||||
default:
|
default:
|
||||||
w.write(part)
|
w.write(part)
|
||||||
|
@ -110,13 +110,13 @@ func TestFprint(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if n != len(expect) {
|
|
||||||
t.Fatalf("invalid write length; expected: %d, got: %d", len(expect), n)
|
|
||||||
}
|
|
||||||
|
|
||||||
if b.String() != expect {
|
if b.String() != expect {
|
||||||
t.Fatalf("invalid output; expected: %s, got: %s", expect, b.String())
|
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) {
|
t.Run("Fprintt", func(t *testing.T) {
|
31
notation.go
31
notation.go
@ -34,6 +34,13 @@ type node struct {
|
|||||||
parts []interface{}
|
parts []interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type str struct {
|
||||||
|
val string
|
||||||
|
raw string
|
||||||
|
useRaw bool
|
||||||
|
rawLen wrapLen
|
||||||
|
}
|
||||||
|
|
||||||
type wrapMode int
|
type wrapMode int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -45,7 +52,7 @@ type wrapper struct {
|
|||||||
mode wrapMode
|
mode wrapMode
|
||||||
sep, suffix string
|
sep, suffix string
|
||||||
items []node
|
items []node
|
||||||
lineWrappers []int
|
lineEnds []int
|
||||||
}
|
}
|
||||||
|
|
||||||
type writer struct {
|
type writer struct {
|
||||||
@ -61,6 +68,14 @@ func (n node) String() string {
|
|||||||
return b.String()
|
return b.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s str) String() string {
|
||||||
|
if s.useRaw {
|
||||||
|
return s.raw
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.val
|
||||||
|
}
|
||||||
|
|
||||||
func (w *writer) write(o interface{}) {
|
func (w *writer) write(o interface{}) {
|
||||||
if w.err != nil {
|
if w.err != nil {
|
||||||
return
|
return
|
||||||
@ -71,13 +86,21 @@ func (w *writer) write(o interface{}) {
|
|||||||
w.err = err
|
w.err = err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *writer) line(t int) {
|
func (w *writer) blankLine() {
|
||||||
w.write("\n")
|
w.write("\n")
|
||||||
for i := 0; i < t; i++ {
|
}
|
||||||
|
|
||||||
|
func (w *writer) tabs(n int) {
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
w.write("\t")
|
w.write("\t")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *writer) line(t int) {
|
||||||
|
w.blankLine()
|
||||||
|
w.tabs(t)
|
||||||
|
}
|
||||||
|
|
||||||
func nodeOf(parts ...interface{}) node {
|
func nodeOf(parts ...interface{}) node {
|
||||||
return node{parts: parts}
|
return node{parts: parts}
|
||||||
}
|
}
|
||||||
@ -131,7 +154,7 @@ func fprintValues(w io.Writer, o opts, v []interface{}) (int, error) {
|
|||||||
n := reflectValue(o, reflect.ValueOf(vi))
|
n := reflectValue(o, reflect.ValueOf(vi))
|
||||||
if o&wrap != 0 {
|
if o&wrap != 0 {
|
||||||
n = nodeLen(tab, n)
|
n = nodeLen(tab, n)
|
||||||
n = wrapNode(tab, cols0, cols1, n)
|
n = wrapNode(tab, cols0, cols0, cols1, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
fprint(wr, 0, n)
|
fprint(wr, 0, n)
|
||||||
|
18
reflect.go
18
reflect.go
@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func withType(o opts) (opts, bool, bool) {
|
func withType(o opts) (opts, bool, bool) {
|
||||||
@ -140,6 +141,7 @@ func reflectMap(o opts, r reflect.Value) node {
|
|||||||
skeys []string
|
skeys []string
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// TODO: simplify this when no sorting is required
|
||||||
items := wrapper{sep: ", ", suffix: ","}
|
items := wrapper{sep: ", ", suffix: ","}
|
||||||
itemOpts := o | skipTypes
|
itemOpts := o | skipTypes
|
||||||
keys := r.MapKeys()
|
keys := r.MapKeys()
|
||||||
@ -201,7 +203,8 @@ func reflectList(o opts, r reflect.Value) node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func reflectString(o opts, r reflect.Value) node {
|
func reflectString(o opts, r reflect.Value) node {
|
||||||
b := []byte(r.String())
|
sv := r.String()
|
||||||
|
b := []byte(sv)
|
||||||
e := make([]byte, 0, len(b))
|
e := make([]byte, 0, len(b))
|
||||||
for _, c := range b {
|
for _, c := range b {
|
||||||
switch c {
|
switch c {
|
||||||
@ -226,18 +229,23 @@ func reflectString(o opts, r reflect.Value) node {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s := fmt.Sprintf("\"%s\"", string(e))
|
s := str{val: fmt.Sprintf("\"%s\"", string(e))}
|
||||||
|
if !strings.Contains(sv, "`") && strings.Contains(sv, "\n") {
|
||||||
|
s.raw = fmt.Sprintf("`%s`", sv)
|
||||||
|
}
|
||||||
|
|
||||||
|
n := nodeOf(s)
|
||||||
_, t, a := withType(o)
|
_, t, a := withType(o)
|
||||||
if !t {
|
if !t {
|
||||||
return nodeOf(s)
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
tn := reflectType(r.Type())
|
tn := reflectType(r.Type())
|
||||||
if !a && tn.parts[0] == "string" {
|
if !a && tn.parts[0] == "string" {
|
||||||
return nodeOf(s)
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
return nodeOf(tn, "(", wrapper{items: []node{nodeOf(s)}}, ")")
|
return nodeOf(tn, "(", wrapper{items: []node{n}}, ")")
|
||||||
}
|
}
|
||||||
|
|
||||||
func reflectStruct(o opts, r reflect.Value) node {
|
func reflectStruct(o opts, r reflect.Value) node {
|
||||||
|
@ -126,8 +126,8 @@ func defaultSet() tests {
|
|||||||
{"nil custom list", struct{ l myList }{}, "{l: nil}"},
|
{"nil custom list", struct{ l myList }{}, "{l: nil}"},
|
||||||
{"long item", []string{"foobarbazqux"}, "[]{\"foobarbazqux\"}"},
|
{"long item", []string{"foobarbazqux"}, "[]{\"foobarbazqux\"}"},
|
||||||
{"long subitem", []struct{ foo string }{{foo: "foobarbazqux"}}, "[]{{foo: \"foobarbazqux\"}}"},
|
{"long subitem", []struct{ foo string }{{foo: "foobarbazqux"}}, "[]{{foo: \"foobarbazqux\"}}"},
|
||||||
{"string", "\\\"\b\f\n\r\t\vfoo", "\"\\\\\\\"\\b\\f\\n\\r\\t\\vfoo\""},
|
{"string", "\\\"\b\f\r\t\vfoo", "\"\\\\\\\"\\b\\f\\r\\t\\vfoo\""},
|
||||||
{"custom string", myString("\\\"\b\f\n\r\t\vfoo"), "\"\\\\\\\"\\b\\f\\n\\r\\t\\vfoo\""},
|
{"custom string", myString("\\\"\b\f\r\t\vfoo"), "\"\\\\\\\"\\b\\f\\r\\t\\vfoo\""},
|
||||||
{"structure", struct{ foo int }{42}, "{foo: 42}"},
|
{"structure", struct{ foo int }{42}, "{foo: 42}"},
|
||||||
{"custom structure", myStruct{42}, "{field: 42}"},
|
{"custom structure", myStruct{42}, "{field: 42}"},
|
||||||
{"unsafe pointer", unsafe.Pointer(&struct{}{}), "pointer"},
|
{"unsafe pointer", unsafe.Pointer(&struct{}{}), "pointer"},
|
||||||
@ -178,7 +178,7 @@ func (t tests) expectTypes() tests {
|
|||||||
"nil custom list": "struct{l myList}{l: nil}",
|
"nil custom list": "struct{l myList}{l: nil}",
|
||||||
"long item": "[]string{\"foobarbazqux\"}",
|
"long item": "[]string{\"foobarbazqux\"}",
|
||||||
"long subitem": "[]struct{foo string}{{foo: \"foobarbazqux\"}}",
|
"long subitem": "[]struct{foo string}{{foo: \"foobarbazqux\"}}",
|
||||||
"custom string": "myString(\"\\\\\\\"\\b\\f\\n\\r\\t\\vfoo\")",
|
"custom string": "myString(\"\\\\\\\"\\b\\f\\r\\t\\vfoo\")",
|
||||||
"structure": "struct{foo int}{foo: 42}",
|
"structure": "struct{foo int}{foo: 42}",
|
||||||
"custom structure": "myStruct{field: 42}",
|
"custom structure": "myStruct{field: 42}",
|
||||||
"unsafe pointer type": "struct{p Pointer}{p: nil}",
|
"unsafe pointer type": "struct{p Pointer}{p: nil}",
|
||||||
@ -214,7 +214,7 @@ func (t tests) expectVerboseTypes() tests {
|
|||||||
"nil custom list": "struct{l myList}{l: myList(nil)}",
|
"nil custom list": "struct{l myList}{l: myList(nil)}",
|
||||||
"long item": "[]string{string(\"foobarbazqux\")}",
|
"long item": "[]string{string(\"foobarbazqux\")}",
|
||||||
"long subitem": "[]struct{foo string}{struct{foo string}{foo: string(\"foobarbazqux\")}}",
|
"long subitem": "[]struct{foo string}{struct{foo string}{foo: string(\"foobarbazqux\")}}",
|
||||||
"string": "string(\"\\\\\\\"\\b\\f\\n\\r\\t\\vfoo\")",
|
"string": "string(\"\\\\\\\"\\b\\f\\r\\t\\vfoo\")",
|
||||||
"structure": "struct{foo int}{foo: int(42)}",
|
"structure": "struct{foo int}{foo: int(42)}",
|
||||||
"custom structure": "myStruct{field: interface{}(int(42))}",
|
"custom structure": "myStruct{field: interface{}(int(42))}",
|
||||||
"unsafe pointer": "Pointer(pointer)",
|
"unsafe pointer": "Pointer(pointer)",
|
||||||
@ -433,7 +433,7 @@ func (t tests) expectWrapAllWithTypes() tests {
|
|||||||
foo: "foobarbazqux",
|
foo: "foobarbazqux",
|
||||||
},
|
},
|
||||||
}`,
|
}`,
|
||||||
"custom string": "myString(\n\t\"\\\\\\\"\\b\\f\\n\\r\\t\\vfoo\"\n)",
|
"custom string": "myString(\n\t\"\\\\\\\"\\b\\f\\r\\t\\vfoo\"\n)",
|
||||||
"structure": `struct{
|
"structure": `struct{
|
||||||
foo int
|
foo int
|
||||||
}{
|
}{
|
||||||
@ -474,7 +474,16 @@ func (t tests) expectOnlyLongWrappedWithTypes() tests {
|
|||||||
}{
|
}{
|
||||||
i: nil,
|
i: nil,
|
||||||
}`,
|
}`,
|
||||||
"nil map": `struct{m map[int]int}{
|
"function with multiple return args": `func(
|
||||||
|
int,
|
||||||
|
int,
|
||||||
|
) (
|
||||||
|
int,
|
||||||
|
int,
|
||||||
|
)`,
|
||||||
|
"nil map": `struct{
|
||||||
|
m map[int]int
|
||||||
|
}{
|
||||||
m: nil,
|
m: nil,
|
||||||
}`,
|
}`,
|
||||||
"nil custom map": `struct{m myMap}{
|
"nil custom map": `struct{m myMap}{
|
||||||
@ -498,7 +507,7 @@ func (t tests) expectOnlyLongWrappedWithTypes() tests {
|
|||||||
"long subitem": `[]struct{foo string}{
|
"long subitem": `[]struct{foo string}{
|
||||||
{foo: "foobarbazqux"},
|
{foo: "foobarbazqux"},
|
||||||
}`,
|
}`,
|
||||||
"custom string": "myString(\n\t\"\\\\\\\"\\b\\f\\n\\r\\t\\vfoo\"\n)",
|
"custom string": "myString(\n\t\"\\\\\\\"\\b\\f\\r\\t\\vfoo\"\n)",
|
||||||
"structure": `struct{foo int}{
|
"structure": `struct{foo int}{
|
||||||
foo: 42,
|
foo: 42,
|
||||||
}`,
|
}`,
|
||||||
@ -630,8 +639,8 @@ func (t tests) expectWrapAllWithVerboseTypes() tests {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
}`,
|
}`,
|
||||||
"string": "string(\n\t\"\\\\\\\"\\b\\f\\n\\r\\t\\vfoo\"\n)",
|
"string": "string(\n\t\"\\\\\\\"\\b\\f\\r\\t\\vfoo\"\n)",
|
||||||
"custom string": "myString(\n\t\"\\\\\\\"\\b\\f\\n\\r\\t\\vfoo\"\n)",
|
"custom string": "myString(\n\t\"\\\\\\\"\\b\\f\\r\\t\\vfoo\"\n)",
|
||||||
"structure": `struct{
|
"structure": `struct{
|
||||||
foo int
|
foo int
|
||||||
}{
|
}{
|
||||||
@ -941,7 +950,7 @@ func TestBytes(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNonWrapperNodes(t *testing.T) {
|
func TestLongNonWrapperNodes(t *testing.T) {
|
||||||
const expect = `map[struct{
|
const expect = `map[struct{
|
||||||
foo int
|
foo int
|
||||||
bar int
|
bar int
|
||||||
@ -963,3 +972,32 @@ func TestNonWrapperNodes(t *testing.T) {
|
|||||||
t.Fatalf("expected: %s, got: %s", expect, s)
|
t.Fatalf("expected: %s, got: %s", expect, s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSingleLongString(t *testing.T) {
|
||||||
|
t.Run("no line breaks", func(t *testing.T) {
|
||||||
|
const expect = `"foobarbazquxquuxquzquuz"`
|
||||||
|
defer withEnv(t, "TABWIDTH=2", "LINEWIDTH=9", "LINEWIDTH1=12")()
|
||||||
|
s := Sprintwt("foobarbazquxquuxquzquuz")
|
||||||
|
if s != expect {
|
||||||
|
t.Fatalf("expected: %s, got: %s", expect, s)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("line break and backquote", func(t *testing.T) {
|
||||||
|
const expect = "\"foobarbazqux`\\nquuxquzquuz\""
|
||||||
|
defer withEnv(t, "TABWIDTH=2", "LINEWIDTH=9", "LINEWIDTH1=12")()
|
||||||
|
s := Sprintwt("foobarbazqux`\nquuxquzquuz")
|
||||||
|
if s != expect {
|
||||||
|
t.Fatalf("expected: %s, got: %s", expect, s)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("line break and no backquote", func(t *testing.T) {
|
||||||
|
const expect = "`foobarbazqux\nquuxquzquuz`"
|
||||||
|
defer withEnv(t, "TABWIDTH=2", "LINEWIDTH=9", "LINEWIDTH1=12")()
|
||||||
|
s := Sprintwt("foobarbazqux\nquuxquzquuz")
|
||||||
|
if s != expect {
|
||||||
|
t.Fatalf("expected: %s, got: %s", expect, s)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user