mirror of
https://github.com/jimeh/undent.git
synced 2026-02-19 11:56:39 +00:00
Previously we relied heavily on regexp to filter out and grab all
indentation white space, and then to strip away indentation shared
across all lines. This was reasonably fast. However I wanted to see if I
could make it faster by manually iterating over the input. Turns out
doing so makes is around 20 times faster.
The code is a lot more complicated though, but I'll attempt to break it
down. There's three main phases to it:
1. Iterate over every character of the input to locate all
line-feed (\n) characters, storing their indexes in a integer slice.
2. Iterate over the list of life-feed indexes, and for each line-feed,
scan forward until a non-whitespace character is found, counting how
many whitespace characters we encountered directly after the
life-feed. If the number is lower than our previously lowest number
of leading whitespace characters, store that as the new lowest
number.
3. Now that we know the lowest number of leading whitespace characters
common across every line of the input, we can iterate over the list
of life-feed indexes again. This time to build the final output, but
reading all characters from the life-feed index + whitespace number,
until the next life-feed character, or end of input.
Overall this approach yields a 15-20x speed improvement over the old
method.
Benchmarks, before:
goos: darwin
goarch: amd64
pkg: github.com/jimeh/undent
cpu: Intel(R) Core(TM) i7-1068NG7 CPU @ 2.30GHz
BenchmarkBytes/empty-8 78280611 15.18 ns/op
BenchmarkBytes/single-line-8 2361297 515.1 ns/op
BenchmarkBytes/single-line_indented-8 317440 3618 ns/op
BenchmarkBytes/multi-line-8 630370 1920 ns/op
BenchmarkBytes/multi-line_space_indented-8 156266 7664 ns/op
BenchmarkBytes/multi-line_space_indented_without_any_leading_line-breaks-8 155672 8168 ns/op
BenchmarkBytes/multi-line_space_indented_with_leading_line-breaks-8 144655 8165 ns/op
BenchmarkBytes/multi-line_tab_indented-8 206425 5462 ns/op
BenchmarkBytes/multi-line_tab_indented_without_any_leading_line-breaks-8 223620 5542 ns/op
BenchmarkBytes/multi-line_tab_indented_with_leading_line-breaks-8 208132 5857 ns/op
BenchmarkBytes/multi-line_tab_indented_with_tabs_and_spaces_after_indent-8 199480 5687 ns/op
BenchmarkBytes/multi-line_space_indented_with_blank_lines-8 148402 8072 ns/op
BenchmarkBytes/multi-line_tab_indented_with_blank_lines-8 200929 5691 ns/op
BenchmarkBytes/multi-line_space_indented_with_random_indentation-8 197412 6515 ns/op
BenchmarkBytes/multi-line_tab_indented_with_random_indentation-8 281493 4272 ns/op
BenchmarkBytes/long_block_of_text-8 9894 115752 ns/op
BenchmarkString/empty-8 100000000 12.75 ns/op
BenchmarkString/single-line-8 2224165 529.0 ns/op
BenchmarkString/single-line_indented-8 314088 3784 ns/op
BenchmarkString/multi-line-8 645804 1968 ns/op
BenchmarkString/multi-line_space_indented-8 149310 8103 ns/op
BenchmarkString/multi-line_space_indented_without_any_leading_line-breaks-8 145390 8496 ns/op
BenchmarkString/multi-line_space_indented_with_leading_line-breaks-8 145579 8161 ns/op
BenchmarkString/multi-line_tab_indented-8 223596 5487 ns/op
BenchmarkString/multi-line_tab_indented_without_any_leading_line-breaks-8 214842 5641 ns/op
BenchmarkString/multi-line_tab_indented_with_leading_line-breaks-8 209067 5685 ns/op
BenchmarkString/multi-line_tab_indented_with_tabs_and_spaces_after_indent-8 210307 5584 ns/op
BenchmarkString/multi-line_space_indented_with_blank_lines-8 133948 9280 ns/op
BenchmarkString/multi-line_tab_indented_with_blank_lines-8 178296 5769 ns/op
BenchmarkString/multi-line_space_indented_with_random_indentation-8 206030 6222 ns/op
BenchmarkString/multi-line_tab_indented_with_random_indentation-8 236450 4259 ns/op
BenchmarkString/long_block_of_text-8 10000 113065 ns/op
PASS
ok github.com/jimeh/undent 44.800s
Benchmarks, after:
goos: darwin
goarch: amd64
pkg: github.com/jimeh/undent
cpu: Intel(R) Core(TM) i7-1068NG7 CPU @ 2.30GHz
BenchmarkBytes/empty-8 596493562 2.074 ns/op
BenchmarkBytes/single-line-8 20044598 60.64 ns/op
BenchmarkBytes/single-line_indented-8 12449749 84.43 ns/op
BenchmarkBytes/multi-line-8 5086376 232.3 ns/op
BenchmarkBytes/multi-line_space_indented-8 3077774 400.4 ns/op
BenchmarkBytes/multi-line_space_indented_without_any_leading_line-breaks-8 3011881 386.6 ns/op
BenchmarkBytes/multi-line_space_indented_with_leading_line-breaks-8 3034299 402.9 ns/op
BenchmarkBytes/multi-line_tab_indented-8 4500271 266.2 ns/op
BenchmarkBytes/multi-line_tab_indented_without_any_leading_line-breaks-8 4355886 277.5 ns/op
BenchmarkBytes/multi-line_tab_indented_with_leading_line-breaks-8 3758012 289.5 ns/op
BenchmarkBytes/multi-line_tab_indented_with_tabs_and_spaces_after_indent-8 4425787 271.9 ns/op
BenchmarkBytes/multi-line_space_indented_with_blank_lines-8 3035809 412.2 ns/op
BenchmarkBytes/multi-line_tab_indented_with_blank_lines-8 3771512 334.2 ns/op
BenchmarkBytes/multi-line_space_indented_with_random_indentation-8 4461404 275.6 ns/op
BenchmarkBytes/multi-line_tab_indented_with_random_indentation-8 6960343 174.6 ns/op
BenchmarkBytes/long_block_of_text-8 315788 3776 ns/op
BenchmarkString/empty-8 338024905 3.761 ns/op
BenchmarkString/single-line-8 20067831 59.28 ns/op
BenchmarkString/single-line_indented-8 13826002 88.16 ns/op
BenchmarkString/multi-line-8 4451938 261.6 ns/op
BenchmarkString/multi-line_space_indented-8 2911797 411.1 ns/op
BenchmarkString/multi-line_space_indented_without_any_leading_line-breaks-8 2699631 416.5 ns/op
BenchmarkString/multi-line_space_indented_with_leading_line-breaks-8 2737174 436.3 ns/op
BenchmarkString/multi-line_tab_indented-8 4208000 304.6 ns/op
BenchmarkString/multi-line_tab_indented_without_any_leading_line-breaks-8 4029422 295.8 ns/op
BenchmarkString/multi-line_tab_indented_with_leading_line-breaks-8 3929960 310.3 ns/op
BenchmarkString/multi-line_tab_indented_with_tabs_and_spaces_after_indent-8 3978992 292.5 ns/op
BenchmarkString/multi-line_space_indented_with_blank_lines-8 2829766 428.5 ns/op
BenchmarkString/multi-line_tab_indented_with_blank_lines-8 3788185 304.8 ns/op
BenchmarkString/multi-line_space_indented_with_random_indentation-8 4104337 279.4 ns/op
BenchmarkString/multi-line_tab_indented_with_random_indentation-8 7092417 177.4 ns/op
BenchmarkString/long_block_of_text-8 283140 4398 ns/op
PASS
ok github.com/jimeh/undent 47.252s
791 lines
20 KiB
Go
791 lines
20 KiB
Go
package undent
|
|
|
|
import (
|
|
"bytes"
|
|
"testing"
|
|
|
|
"github.com/rhysd/go-fakeio"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
var stringTestCases = []struct {
|
|
name string
|
|
s string
|
|
want string
|
|
}{
|
|
{
|
|
name: "empty",
|
|
s: "",
|
|
want: "",
|
|
},
|
|
{
|
|
name: "single-line",
|
|
s: "hello world",
|
|
want: "hello world",
|
|
},
|
|
{
|
|
name: "single-line indented",
|
|
s: " hello world",
|
|
want: "hello world",
|
|
},
|
|
{
|
|
name: "multi-line",
|
|
s: `
|
|
{
|
|
"hello": "world",
|
|
"foo": [
|
|
"bar"
|
|
]
|
|
}`,
|
|
want: `{
|
|
"hello": "world",
|
|
"foo": [
|
|
"bar"
|
|
]
|
|
}`,
|
|
},
|
|
{
|
|
name: "multi-line space indented",
|
|
s: `
|
|
{
|
|
"hello": "world",
|
|
"foo": [
|
|
"bar"
|
|
]
|
|
}`,
|
|
want: `{
|
|
"hello": "world",
|
|
"foo": [
|
|
"bar"
|
|
]
|
|
}`,
|
|
},
|
|
{
|
|
name: "multi-line space indented without any leading line-breaks",
|
|
s: ` {
|
|
"hello": "world",
|
|
"foo": [
|
|
"bar"
|
|
]
|
|
}`,
|
|
want: `{
|
|
"hello": "world",
|
|
"foo": [
|
|
"bar"
|
|
]
|
|
}`,
|
|
},
|
|
{
|
|
name: "multi-line space indented with leading line-breaks",
|
|
s: `
|
|
|
|
|
|
{
|
|
"hello": "world",
|
|
"foo": [
|
|
"bar"
|
|
]
|
|
}`,
|
|
want: `
|
|
|
|
{
|
|
"hello": "world",
|
|
"foo": [
|
|
"bar"
|
|
]
|
|
}`,
|
|
},
|
|
{
|
|
name: "multi-line tab indented",
|
|
s: `
|
|
{
|
|
"hello": "world",
|
|
"foo": [
|
|
"bar"
|
|
]
|
|
}`,
|
|
want: `{
|
|
"hello": "world",
|
|
"foo": [
|
|
"bar"
|
|
]
|
|
}`,
|
|
},
|
|
{
|
|
name: "multi-line tab indented without any leading line-breaks",
|
|
s: ` {
|
|
"hello": "world",
|
|
"foo": [
|
|
"bar"
|
|
]
|
|
}`,
|
|
want: `{
|
|
"hello": "world",
|
|
"foo": [
|
|
"bar"
|
|
]
|
|
}`,
|
|
},
|
|
{
|
|
name: "multi-line tab indented with leading line-breaks",
|
|
s: `
|
|
|
|
|
|
{
|
|
"hello": "world",
|
|
"foo": [
|
|
"bar"
|
|
]
|
|
}`,
|
|
want: `
|
|
|
|
{
|
|
"hello": "world",
|
|
"foo": [
|
|
"bar"
|
|
]
|
|
}`,
|
|
},
|
|
{
|
|
name: "multi-line tab indented with tabs and spaces after indent",
|
|
s: `
|
|
{
|
|
"hello": "world",
|
|
"foo": [
|
|
"bar"
|
|
]
|
|
}`,
|
|
want: `{
|
|
"hello": "world",
|
|
"foo": [
|
|
"bar"
|
|
]
|
|
}`,
|
|
},
|
|
{
|
|
name: "multi-line space indented with blank lines",
|
|
s: `
|
|
{
|
|
"hello": "world",
|
|
"foo": [
|
|
|
|
"bar"
|
|
|
|
]
|
|
}`,
|
|
want: `{
|
|
"hello": "world",
|
|
"foo": [
|
|
|
|
"bar"
|
|
|
|
]
|
|
}`,
|
|
},
|
|
{
|
|
name: "multi-line tab indented with blank lines",
|
|
s: `
|
|
{
|
|
"hello": "world",
|
|
"foo": [
|
|
|
|
"bar"
|
|
|
|
]
|
|
}`,
|
|
want: `{
|
|
"hello": "world",
|
|
"foo": [
|
|
|
|
"bar"
|
|
|
|
]
|
|
}`,
|
|
},
|
|
{
|
|
name: "multi-line space indented with random indentation",
|
|
s: `
|
|
hello
|
|
world
|
|
foo
|
|
bar`,
|
|
want: ` hello
|
|
world
|
|
foo
|
|
bar`,
|
|
},
|
|
{
|
|
name: "multi-line tab indented with random indentation",
|
|
s: `
|
|
hello
|
|
world
|
|
foo
|
|
bar`,
|
|
want: ` hello
|
|
world
|
|
foo
|
|
bar`,
|
|
},
|
|
{
|
|
name: "long block of text",
|
|
s: `
|
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc
|
|
ornare, tellus vel luctus tristique, ipsum ante varius mauris, non
|
|
hendrerit tellus urna quis ex. Donec efficitur arcu sed iaculis
|
|
lobortis. Phasellus facilisis vitae mi quis accumsan. Suspendisse
|
|
rhoncus viverra odio ultricies rhoncus. Cras laoreet tortor
|
|
vestibulum pharetra luctus. Vivamus sit amet volutpat elit.
|
|
Suspendisse feugiat lectus id arcu sollicitudin tincidunt. Duis ut
|
|
sem auctor orci sodales varius in ac odio. Nullam finibus odio at
|
|
lacus tristique malesuada.
|
|
|
|
Morbi nisl nulla, euismod eu enim in, tincidunt varius turpis. Morbi
|
|
ullamcorper tortor mi, ut aliquam metus posuere vel. Etiam vel dui
|
|
at quam placerat sollicitudin. Proin aliquam justo vitae mauris
|
|
gravida porta. Praesent hendrerit egestas ligula, faucibus tincidunt
|
|
tortor aliquet at. Ut luctus vehicula arcu eget cursus. Suspendisse
|
|
eget enim mollis, condimentum lacus eu, viverra nulla. Aenean vel
|
|
sapien eget enim convallis accumsan. Donec dictum ullamcorper leo
|
|
placerat sollicitudin. Pellentesque habitant morbi tristique
|
|
senectus et netus et malesuada fames ac turpis egestas. Vestibulum
|
|
volutpat mattis est, a feugiat purus feugiat at. Quisque at velit ut
|
|
mauris convallis sodales a et erat. Mauris condimentum augue sit
|
|
amet arcu sodales, aliquet ultrices ipsum tempor. Donec scelerisque
|
|
mi ligula, vel volutpat velit posuere a. Sed faucibus dui pulvinar
|
|
lorem commodo egestas. In facilisis suscipit lacus non suscipit.
|
|
|
|
Nunc dictum est nulla, a rhoncus mi posuere id. Morbi at tempus
|
|
augue. Quisque ac nibh auctor velit auctor placerat id non eros.
|
|
Nulla condimentum quam id risus suscipit, ut fermentum mauris
|
|
lacinia. Vestibulum suscipit rutrum ex, sed vulputate nisi tempus
|
|
ultricies. Sed id ante pretium, accumsan sapien eget, malesuada
|
|
quam. Phasellus quis commodo enim. Vivamus in purus ac lorem ornare
|
|
posuere non eu quam. Sed arcu tortor, gravida quis fringilla nec,
|
|
ultricies et sem. Pellentesque arcu enim, tempor id nisl at, rhoncus
|
|
efficitur sem. Ut quis placerat quam. Donec maximus a risus sed
|
|
posuere. Curabitur pretium a diam non aliquet.
|
|
|
|
Class aptent taciti sociosqu ad litora torquent per conubia nostra,
|
|
per inceptos himenaeos. Morbi volutpat felis leo, vel ultrices orci
|
|
bibendum ac. Integer eu mattis urna. Donec dictum vehicula
|
|
fermentum. Pellentesque a rutrum ipsum. Donec ultricies elit purus,
|
|
eget viverra tellus tristique sed. In hac habitasse platea dictumst.
|
|
Duis elementum semper elit, sit amet rhoncus lacus dictum ac. Nunc
|
|
pretium enim ac urna efficitur, eget facilisis enim interdum.
|
|
|
|
Vivamus vel lectus lacus. Praesent vestibulum vel ligula eget
|
|
cursus. Quisque eu dignissim erat. Quisque maximus arcu eu turpis
|
|
pulvinar egestas. Nam aliquet neque sed tellus finibus mollis.
|
|
Phasellus consequat nibh nec ornare egestas. Donec at pellentesque
|
|
lorem.`,
|
|
want: `Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc
|
|
ornare, tellus vel luctus tristique, ipsum ante varius mauris, non
|
|
hendrerit tellus urna quis ex. Donec efficitur arcu sed iaculis
|
|
lobortis. Phasellus facilisis vitae mi quis accumsan. Suspendisse
|
|
rhoncus viverra odio ultricies rhoncus. Cras laoreet tortor
|
|
vestibulum pharetra luctus. Vivamus sit amet volutpat elit.
|
|
Suspendisse feugiat lectus id arcu sollicitudin tincidunt. Duis ut
|
|
sem auctor orci sodales varius in ac odio. Nullam finibus odio at
|
|
lacus tristique malesuada.
|
|
|
|
Morbi nisl nulla, euismod eu enim in, tincidunt varius turpis. Morbi
|
|
ullamcorper tortor mi, ut aliquam metus posuere vel. Etiam vel dui
|
|
at quam placerat sollicitudin. Proin aliquam justo vitae mauris
|
|
gravida porta. Praesent hendrerit egestas ligula, faucibus tincidunt
|
|
tortor aliquet at. Ut luctus vehicula arcu eget cursus. Suspendisse
|
|
eget enim mollis, condimentum lacus eu, viverra nulla. Aenean vel
|
|
sapien eget enim convallis accumsan. Donec dictum ullamcorper leo
|
|
placerat sollicitudin. Pellentesque habitant morbi tristique
|
|
senectus et netus et malesuada fames ac turpis egestas. Vestibulum
|
|
volutpat mattis est, a feugiat purus feugiat at. Quisque at velit ut
|
|
mauris convallis sodales a et erat. Mauris condimentum augue sit
|
|
amet arcu sodales, aliquet ultrices ipsum tempor. Donec scelerisque
|
|
mi ligula, vel volutpat velit posuere a. Sed faucibus dui pulvinar
|
|
lorem commodo egestas. In facilisis suscipit lacus non suscipit.
|
|
|
|
Nunc dictum est nulla, a rhoncus mi posuere id. Morbi at tempus
|
|
augue. Quisque ac nibh auctor velit auctor placerat id non eros.
|
|
Nulla condimentum quam id risus suscipit, ut fermentum mauris
|
|
lacinia. Vestibulum suscipit rutrum ex, sed vulputate nisi tempus
|
|
ultricies. Sed id ante pretium, accumsan sapien eget, malesuada
|
|
quam. Phasellus quis commodo enim. Vivamus in purus ac lorem ornare
|
|
posuere non eu quam. Sed arcu tortor, gravida quis fringilla nec,
|
|
ultricies et sem. Pellentesque arcu enim, tempor id nisl at, rhoncus
|
|
efficitur sem. Ut quis placerat quam. Donec maximus a risus sed
|
|
posuere. Curabitur pretium a diam non aliquet.
|
|
|
|
Class aptent taciti sociosqu ad litora torquent per conubia nostra,
|
|
per inceptos himenaeos. Morbi volutpat felis leo, vel ultrices orci
|
|
bibendum ac. Integer eu mattis urna. Donec dictum vehicula
|
|
fermentum. Pellentesque a rutrum ipsum. Donec ultricies elit purus,
|
|
eget viverra tellus tristique sed. In hac habitasse platea dictumst.
|
|
Duis elementum semper elit, sit amet rhoncus lacus dictum ac. Nunc
|
|
pretium enim ac urna efficitur, eget facilisis enim interdum.
|
|
|
|
Vivamus vel lectus lacus. Praesent vestibulum vel ligula eget
|
|
cursus. Quisque eu dignissim erat. Quisque maximus arcu eu turpis
|
|
pulvinar egestas. Nam aliquet neque sed tellus finibus mollis.
|
|
Phasellus consequat nibh nec ornare egestas. Donec at pellentesque
|
|
lorem.`,
|
|
},
|
|
}
|
|
|
|
var stringfTestCases = []struct {
|
|
name string
|
|
s string
|
|
a []interface{}
|
|
want string
|
|
}{
|
|
{
|
|
name: "empty",
|
|
s: "",
|
|
want: "",
|
|
},
|
|
{
|
|
name: "single-line",
|
|
s: "hello %s, %d",
|
|
a: []interface{}{"world", 42},
|
|
want: "hello world, 42",
|
|
},
|
|
{
|
|
name: "single-line indented",
|
|
s: " hello %s, %d",
|
|
a: []interface{}{"world", 42},
|
|
want: "hello world, 42",
|
|
},
|
|
{
|
|
name: "multi-line",
|
|
s: `
|
|
{
|
|
"hello": "%s",
|
|
"foo": [
|
|
%d
|
|
]
|
|
}`,
|
|
a: []interface{}{"world", 42},
|
|
want: `{
|
|
"hello": "world",
|
|
"foo": [
|
|
42
|
|
]
|
|
}`,
|
|
},
|
|
{
|
|
name: "multi-line space indented",
|
|
s: `
|
|
{
|
|
"hello": "%s",
|
|
"foo": [
|
|
%d
|
|
]
|
|
}`,
|
|
a: []interface{}{"world", 42},
|
|
want: `{
|
|
"hello": "world",
|
|
"foo": [
|
|
42
|
|
]
|
|
}`,
|
|
},
|
|
{
|
|
name: "multi-line space indented without any leading line-breaks",
|
|
s: ` {
|
|
"hello": "%s",
|
|
"foo": [
|
|
%d
|
|
]
|
|
}`,
|
|
a: []interface{}{"world", 42},
|
|
want: `{
|
|
"hello": "world",
|
|
"foo": [
|
|
42
|
|
]
|
|
}`,
|
|
},
|
|
{
|
|
name: "multi-line space indented with leading line-breaks",
|
|
s: `
|
|
|
|
|
|
{
|
|
"hello": "%s",
|
|
"foo": [
|
|
%d
|
|
]
|
|
}`,
|
|
a: []interface{}{"world", 42},
|
|
want: `
|
|
|
|
{
|
|
"hello": "world",
|
|
"foo": [
|
|
42
|
|
]
|
|
}`,
|
|
},
|
|
{
|
|
name: "multi-line tab indented",
|
|
s: `
|
|
{
|
|
"hello": "%s",
|
|
"foo": [
|
|
%d
|
|
]
|
|
}`,
|
|
a: []interface{}{"world", 42},
|
|
want: `{
|
|
"hello": "world",
|
|
"foo": [
|
|
42
|
|
]
|
|
}`,
|
|
},
|
|
{
|
|
name: "multi-line tab indented without any leading line-breaks",
|
|
s: ` {
|
|
"hello": "%s",
|
|
"foo": [
|
|
%d
|
|
]
|
|
}`,
|
|
a: []interface{}{"world", 42},
|
|
want: `{
|
|
"hello": "world",
|
|
"foo": [
|
|
42
|
|
]
|
|
}`,
|
|
},
|
|
{
|
|
name: "multi-line tab indented with leading line-breaks",
|
|
s: `
|
|
|
|
|
|
{
|
|
"hello": "%s",
|
|
"foo": [
|
|
%d
|
|
]
|
|
}`,
|
|
a: []interface{}{"world", 42},
|
|
want: `
|
|
|
|
{
|
|
"hello": "world",
|
|
"foo": [
|
|
42
|
|
]
|
|
}`,
|
|
},
|
|
{
|
|
name: "multi-line tab indented with tabs and spaces after indent",
|
|
s: `
|
|
{
|
|
"hello": "%s",
|
|
"foo": [
|
|
%d
|
|
]
|
|
}`,
|
|
a: []interface{}{"world", 42},
|
|
want: `{
|
|
"hello": "world",
|
|
"foo": [
|
|
42
|
|
]
|
|
}`,
|
|
},
|
|
{
|
|
name: "multi-line space indented with blank lines",
|
|
s: `
|
|
{
|
|
"hello": "%s",
|
|
"foo": [
|
|
|
|
%d
|
|
|
|
]
|
|
}`,
|
|
a: []interface{}{"world", 42},
|
|
want: `{
|
|
"hello": "world",
|
|
"foo": [
|
|
|
|
42
|
|
|
|
]
|
|
}`,
|
|
},
|
|
{
|
|
name: "multi-line tab indented with blank lines",
|
|
s: `
|
|
{
|
|
"hello": "%s",
|
|
"foo": [
|
|
|
|
%d
|
|
|
|
]
|
|
}`,
|
|
a: []interface{}{"world", 42},
|
|
want: `{
|
|
"hello": "world",
|
|
"foo": [
|
|
|
|
42
|
|
|
|
]
|
|
}`,
|
|
},
|
|
{
|
|
name: "multi-line space indented with random indentation",
|
|
s: `
|
|
hello
|
|
%s
|
|
foo
|
|
%d`,
|
|
a: []interface{}{"world", 42},
|
|
want: ` hello
|
|
world
|
|
foo
|
|
42`,
|
|
},
|
|
{
|
|
name: "multi-line tab indented with random indentation",
|
|
s: `
|
|
hello
|
|
%s
|
|
foo
|
|
%d`,
|
|
a: []interface{}{"world", 42},
|
|
want: ` hello
|
|
world
|
|
foo
|
|
42`,
|
|
},
|
|
{
|
|
name: "long block of text",
|
|
s: `
|
|
Lorem %s dolor sit amet, consectetur adipiscing elit. Nunc
|
|
ornare, tellus vel luctus tristique, ipsum ante varius mauris, non
|
|
hendrerit tellus urna quis ex. %s efficitur arcu sed iaculis
|
|
lobortis. Phasellus facilisis vitae mi quis accumsan. Suspendisse
|
|
rhoncus viverra odio ultricies rhoncus. Cras laoreet tortor
|
|
vestibulum pharetra luctus. Vivamus sit amet volutpat elit.
|
|
Suspendisse feugiat lectus id arcu sollicitudin tincidunt. Duis ut
|
|
sem auctor orci sodales varius in ac odio. Nullam finibus odio at
|
|
lacus tristique malesuada.
|
|
|
|
Morbi nisl nulla, euismod eu enim in, tincidunt varius turpis. Morbi
|
|
ullamcorper tortor mi, ut aliquam metus posuere vel. Etiam vel dui
|
|
at quam placerat sollicitudin. Proin aliquam justo vitae mauris
|
|
gravida porta. Praesent hendrerit egestas ligula, faucibus tincidunt
|
|
tortor aliquet at. Ut luctus vehicula arcu eget cursus. Suspendisse
|
|
eget enim mollis, condimentum lacus eu, viverra nulla. Aenean vel
|
|
sapien eget enim convallis accumsan. Donec dictum ullamcorper leo
|
|
placerat sollicitudin. Pellentesque habitant morbi tristique
|
|
senectus et netus et malesuada fames ac turpis egestas. Vestibulum
|
|
volutpat mattis est, a feugiat purus feugiat at. Quisque at velit ut
|
|
mauris convallis sodales a et erat. Mauris condimentum augue sit
|
|
amet arcu sodales, aliquet ultrices ipsum tempor. Donec scelerisque
|
|
mi ligula, vel volutpat velit posuere a. Sed faucibus dui pulvinar
|
|
lorem commodo egestas. In facilisis suscipit lacus non suscipit.
|
|
|
|
Nunc dictum est nulla, a rhoncus mi posuere id. Morbi at tempus
|
|
augue. Quisque ac nibh auctor velit auctor placerat id non eros.
|
|
Nulla condimentum quam id risus suscipit, ut fermentum mauris
|
|
lacinia. Vestibulum suscipit rutrum ex, sed vulputate nisi tempus
|
|
ultricies. Sed id ante pretium, accumsan sapien eget, malesuada
|
|
quam. Phasellus quis commodo enim. Vivamus in purus ac lorem ornare
|
|
posuere non eu quam. Sed arcu tortor, gravida quis fringilla nec,
|
|
ultricies et sem. Pellentesque arcu enim, tempor id nisl at, rhoncus
|
|
efficitur sem. Ut quis placerat quam. Donec maximus a risus sed
|
|
posuere. Curabitur pretium a diam non aliquet.
|
|
|
|
Class aptent taciti sociosqu ad litora torquent per conubia nostra,
|
|
per inceptos himenaeos. Morbi volutpat felis leo, vel ultrices orci
|
|
bibendum ac. Integer eu mattis urna. Donec dictum vehicula
|
|
fermentum. Pellentesque a rutrum ipsum. Donec ultricies elit purus,
|
|
eget viverra tellus tristique sed. In hac habitasse platea dictumst.
|
|
Duis elementum semper elit, sit amet rhoncus lacus dictum ac. Nunc
|
|
pretium enim ac urna efficitur, eget facilisis enim interdum.
|
|
|
|
Vivamus vel lectus lacus. Praesent vestibulum vel ligula eget
|
|
cursus. Quisque eu dignissim erat. Quisque maximus arcu eu turpis
|
|
pulvinar egestas. Nam aliquet neque sed tellus finibus mollis.
|
|
Phasellus consequat nibh nec ornare egestas. Donec at pellentesque
|
|
lorem.`,
|
|
a: []interface{}{"ipsum", "Donec"},
|
|
want: `Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc
|
|
ornare, tellus vel luctus tristique, ipsum ante varius mauris, non
|
|
hendrerit tellus urna quis ex. Donec efficitur arcu sed iaculis
|
|
lobortis. Phasellus facilisis vitae mi quis accumsan. Suspendisse
|
|
rhoncus viverra odio ultricies rhoncus. Cras laoreet tortor
|
|
vestibulum pharetra luctus. Vivamus sit amet volutpat elit.
|
|
Suspendisse feugiat lectus id arcu sollicitudin tincidunt. Duis ut
|
|
sem auctor orci sodales varius in ac odio. Nullam finibus odio at
|
|
lacus tristique malesuada.
|
|
|
|
Morbi nisl nulla, euismod eu enim in, tincidunt varius turpis. Morbi
|
|
ullamcorper tortor mi, ut aliquam metus posuere vel. Etiam vel dui
|
|
at quam placerat sollicitudin. Proin aliquam justo vitae mauris
|
|
gravida porta. Praesent hendrerit egestas ligula, faucibus tincidunt
|
|
tortor aliquet at. Ut luctus vehicula arcu eget cursus. Suspendisse
|
|
eget enim mollis, condimentum lacus eu, viverra nulla. Aenean vel
|
|
sapien eget enim convallis accumsan. Donec dictum ullamcorper leo
|
|
placerat sollicitudin. Pellentesque habitant morbi tristique
|
|
senectus et netus et malesuada fames ac turpis egestas. Vestibulum
|
|
volutpat mattis est, a feugiat purus feugiat at. Quisque at velit ut
|
|
mauris convallis sodales a et erat. Mauris condimentum augue sit
|
|
amet arcu sodales, aliquet ultrices ipsum tempor. Donec scelerisque
|
|
mi ligula, vel volutpat velit posuere a. Sed faucibus dui pulvinar
|
|
lorem commodo egestas. In facilisis suscipit lacus non suscipit.
|
|
|
|
Nunc dictum est nulla, a rhoncus mi posuere id. Morbi at tempus
|
|
augue. Quisque ac nibh auctor velit auctor placerat id non eros.
|
|
Nulla condimentum quam id risus suscipit, ut fermentum mauris
|
|
lacinia. Vestibulum suscipit rutrum ex, sed vulputate nisi tempus
|
|
ultricies. Sed id ante pretium, accumsan sapien eget, malesuada
|
|
quam. Phasellus quis commodo enim. Vivamus in purus ac lorem ornare
|
|
posuere non eu quam. Sed arcu tortor, gravida quis fringilla nec,
|
|
ultricies et sem. Pellentesque arcu enim, tempor id nisl at, rhoncus
|
|
efficitur sem. Ut quis placerat quam. Donec maximus a risus sed
|
|
posuere. Curabitur pretium a diam non aliquet.
|
|
|
|
Class aptent taciti sociosqu ad litora torquent per conubia nostra,
|
|
per inceptos himenaeos. Morbi volutpat felis leo, vel ultrices orci
|
|
bibendum ac. Integer eu mattis urna. Donec dictum vehicula
|
|
fermentum. Pellentesque a rutrum ipsum. Donec ultricies elit purus,
|
|
eget viverra tellus tristique sed. In hac habitasse platea dictumst.
|
|
Duis elementum semper elit, sit amet rhoncus lacus dictum ac. Nunc
|
|
pretium enim ac urna efficitur, eget facilisis enim interdum.
|
|
|
|
Vivamus vel lectus lacus. Praesent vestibulum vel ligula eget
|
|
cursus. Quisque eu dignissim erat. Quisque maximus arcu eu turpis
|
|
pulvinar egestas. Nam aliquet neque sed tellus finibus mollis.
|
|
Phasellus consequat nibh nec ornare egestas. Donec at pellentesque
|
|
lorem.`,
|
|
},
|
|
}
|
|
|
|
func TestBytes(t *testing.T) {
|
|
for _, tt := range stringTestCases {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := Bytes(tt.s)
|
|
|
|
assert.IsType(t, []byte{}, got)
|
|
assert.Equal(t, tt.want, string(got))
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestBytesf(t *testing.T) {
|
|
for _, tt := range stringfTestCases {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := Bytesf(tt.s, tt.a...)
|
|
|
|
assert.IsType(t, []byte{}, got)
|
|
assert.Equal(t, tt.want, string(got))
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestString(t *testing.T) {
|
|
for _, tt := range stringTestCases {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := String(tt.s)
|
|
|
|
assert.IsType(t, "", got)
|
|
assert.Equal(t, tt.want, got)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestStringf(t *testing.T) {
|
|
for _, tt := range stringfTestCases {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := Stringf(tt.s, tt.a...)
|
|
|
|
assert.IsType(t, "", got)
|
|
assert.Equal(t, tt.want, got)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestPrint(t *testing.T) {
|
|
for _, tt := range stringTestCases {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got, err := fakeio.Stdout().Do(func() {
|
|
Print(tt.s, 5, tt.s)
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
assert.IsType(t, "", got)
|
|
assert.Equal(t, tt.want+"5"+tt.want, got)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestPrintf(t *testing.T) {
|
|
for _, tt := range stringfTestCases {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got, err := fakeio.Stdout().Do(func() {
|
|
Printf(tt.s, tt.a...)
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
assert.IsType(t, "", got)
|
|
assert.Equal(t, tt.want, got)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestFprint(t *testing.T) {
|
|
for _, tt := range stringTestCases {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
var buf bytes.Buffer
|
|
|
|
Fprint(&buf, tt.s, 5, tt.s)
|
|
got := buf.String()
|
|
|
|
assert.IsType(t, "", got)
|
|
assert.Equal(t, tt.want+"5"+tt.want, got)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestFprintf(t *testing.T) {
|
|
for _, tt := range stringfTestCases {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
var buf bytes.Buffer
|
|
|
|
Fprintf(&buf, tt.s, tt.a...)
|
|
got := buf.String()
|
|
|
|
assert.IsType(t, "", got)
|
|
assert.Equal(t, tt.want, got)
|
|
})
|
|
}
|
|
}
|
|
|
|
func BenchmarkBytes(b *testing.B) {
|
|
for _, tt := range stringTestCases {
|
|
b.Run(tt.name, func(b *testing.B) {
|
|
for i := 0; i < b.N; i++ {
|
|
Bytes(tt.s)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func BenchmarkString(b *testing.B) {
|
|
for _, tt := range stringTestCases {
|
|
b.Run(tt.name, func(b *testing.B) {
|
|
for i := 0; i < b.N; i++ {
|
|
String(tt.s)
|
|
}
|
|
})
|
|
}
|
|
}
|