2008-11-20 18:39:41 -07:00
|
|
|
// Copyright 2009 The Go Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
package tabwriter
|
|
|
|
|
|
|
|
import (
|
|
|
|
"io";
|
2009-04-16 21:52:37 -06:00
|
|
|
"os";
|
2008-11-20 18:39:41 -07:00
|
|
|
"tabwriter";
|
|
|
|
"testing";
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2009-01-15 16:10:46 -07:00
|
|
|
type buffer struct {
|
2008-12-18 23:37:22 -07:00
|
|
|
a []byte;
|
2008-11-20 18:39:41 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-01-15 16:10:46 -07:00
|
|
|
func (b *buffer) init(n int) {
|
2009-01-06 16:19:02 -07:00
|
|
|
b.a = make([]byte, n)[0 : 0];
|
2008-11-20 18:39:41 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-01-15 16:10:46 -07:00
|
|
|
func (b *buffer) clear() {
|
2008-12-09 14:03:15 -07:00
|
|
|
b.a = b.a[0 : 0];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-04-17 01:08:24 -06:00
|
|
|
func (b *buffer) Write(buf []byte) (written int, err os.Error) {
|
2008-11-20 18:39:41 -07:00
|
|
|
n := len(b.a);
|
|
|
|
m := len(buf);
|
|
|
|
if n + m <= cap(b.a) {
|
|
|
|
b.a = b.a[0 : n + m];
|
|
|
|
for i := 0; i < m; i++ {
|
|
|
|
b.a[n+i] = buf[i];
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
panicln("buffer too small", n, m, cap(b.a));
|
|
|
|
}
|
|
|
|
return len(buf), nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-01-15 16:10:46 -07:00
|
|
|
func (b *buffer) String() string {
|
2008-11-20 18:39:41 -07:00
|
|
|
return string(b.a);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-01-15 16:10:46 -07:00
|
|
|
func write(t *testing.T, w *tabwriter.Writer, src string) {
|
2008-12-09 14:03:15 -07:00
|
|
|
written, err := io.WriteString(w, src);
|
2008-11-25 15:06:59 -07:00
|
|
|
if err != nil {
|
|
|
|
t.Errorf("--- src:\n%s\n--- write error: %v\n", src, err);
|
|
|
|
}
|
|
|
|
if written != len(src) {
|
|
|
|
t.Errorf("--- src:\n%s\n--- written = %d, len(src) = %d\n", src, written, len(src));
|
|
|
|
}
|
2008-12-09 14:03:15 -07:00
|
|
|
}
|
|
|
|
|
2008-11-25 15:06:59 -07:00
|
|
|
|
2009-01-15 16:10:46 -07:00
|
|
|
func verify(t *testing.T, w *tabwriter.Writer, b *buffer, src, expected string) {
|
2008-12-09 14:03:15 -07:00
|
|
|
err := w.Flush();
|
2008-11-25 15:06:59 -07:00
|
|
|
if err != nil {
|
|
|
|
t.Errorf("--- src:\n%s\n--- flush error: %v\n", src, err);
|
|
|
|
}
|
2008-11-20 18:39:41 -07:00
|
|
|
|
|
|
|
res := b.String();
|
|
|
|
if res != expected {
|
2008-11-21 10:35:49 -07:00
|
|
|
t.Errorf("--- src:\n%s\n--- found:\n%s\n--- expected:\n%s\n", src, res, expected)
|
2008-11-20 18:39:41 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-03-10 17:30:26 -06:00
|
|
|
func check(t *testing.T, tabwidth, padding int, padchar byte, flags uint, src, expected string) {
|
2009-01-15 16:10:46 -07:00
|
|
|
var b buffer;
|
|
|
|
b.init(1000);
|
2008-12-09 14:03:15 -07:00
|
|
|
|
|
|
|
var w tabwriter.Writer;
|
2009-03-10 17:30:26 -06:00
|
|
|
w.Init(&b, tabwidth, padding, padchar, flags);
|
2008-12-09 14:03:15 -07:00
|
|
|
|
|
|
|
// write all at once
|
2009-01-15 16:10:46 -07:00
|
|
|
b.clear();
|
|
|
|
write(t, &w, src);
|
|
|
|
verify(t, &w, &b, src, expected);
|
2008-12-09 14:03:15 -07:00
|
|
|
|
|
|
|
// write byte-by-byte
|
2009-01-15 16:10:46 -07:00
|
|
|
b.clear();
|
2008-12-09 14:03:15 -07:00
|
|
|
for i := 0; i < len(src); i++ {
|
2009-01-15 16:10:46 -07:00
|
|
|
write(t, &w, src[i : i+1]);
|
2008-12-09 14:03:15 -07:00
|
|
|
}
|
2009-01-15 16:10:46 -07:00
|
|
|
verify(t, &w, &b, src, expected);
|
2008-12-09 14:03:15 -07:00
|
|
|
|
|
|
|
// write using Fibonacci slice sizes
|
2009-01-15 16:10:46 -07:00
|
|
|
b.clear();
|
2008-12-09 14:03:15 -07:00
|
|
|
for i, d := 0, 0; i < len(src); {
|
2009-01-15 16:10:46 -07:00
|
|
|
write(t, &w, src[i : i+d]);
|
2008-12-09 14:03:15 -07:00
|
|
|
i, d = i+d, d+1;
|
|
|
|
if i+d > len(src) {
|
|
|
|
d = len(src) - i;
|
|
|
|
}
|
|
|
|
}
|
2009-01-15 16:10:46 -07:00
|
|
|
verify(t, &w, &b, src, expected);
|
2008-12-09 14:03:15 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-06-04 16:47:57 -06:00
|
|
|
type entry struct {
|
|
|
|
tabwidth, padding int;
|
|
|
|
padchar byte;
|
|
|
|
flags uint;
|
|
|
|
src, expected string;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var tests = []entry {
|
|
|
|
entry{
|
|
|
|
8, 1, '.', 0,
|
2008-11-25 15:06:59 -07:00
|
|
|
"",
|
|
|
|
""
|
2009-06-04 16:47:57 -06:00
|
|
|
},
|
2008-11-25 15:06:59 -07:00
|
|
|
|
2009-06-04 16:47:57 -06:00
|
|
|
entry{
|
|
|
|
8, 1, '.', 0,
|
2008-11-25 15:06:59 -07:00
|
|
|
"\n\n\n",
|
|
|
|
"\n\n\n"
|
2009-06-04 16:47:57 -06:00
|
|
|
},
|
2008-11-25 15:06:59 -07:00
|
|
|
|
2009-06-04 16:47:57 -06:00
|
|
|
entry{
|
|
|
|
8, 1, '.', 0,
|
2008-11-25 15:06:59 -07:00
|
|
|
"a\nb\nc",
|
|
|
|
"a\nb\nc"
|
2009-06-04 16:47:57 -06:00
|
|
|
},
|
2008-11-25 15:06:59 -07:00
|
|
|
|
2009-06-04 16:47:57 -06:00
|
|
|
entry{
|
|
|
|
8, 1, '.', 0,
|
2008-11-25 15:06:59 -07:00
|
|
|
"\t", // '\t' terminates an empty cell on last line - nothing to print
|
|
|
|
""
|
2009-06-04 16:47:57 -06:00
|
|
|
},
|
2008-11-25 15:06:59 -07:00
|
|
|
|
2009-06-04 16:47:57 -06:00
|
|
|
entry{
|
|
|
|
8, 1, '.', tabwriter.AlignRight,
|
2008-11-25 15:06:59 -07:00
|
|
|
"\t", // '\t' terminates an empty cell on last line - nothing to print
|
|
|
|
""
|
2009-06-04 16:47:57 -06:00
|
|
|
},
|
2008-11-25 15:06:59 -07:00
|
|
|
|
2009-06-04 16:47:57 -06:00
|
|
|
entry{
|
|
|
|
8, 1, '.', 0,
|
2008-11-25 15:06:59 -07:00
|
|
|
"*\t*",
|
|
|
|
"**"
|
2009-06-04 16:47:57 -06:00
|
|
|
},
|
2008-11-25 15:06:59 -07:00
|
|
|
|
2009-06-04 16:47:57 -06:00
|
|
|
entry{
|
|
|
|
8, 1, '.', 0,
|
2008-11-25 15:06:59 -07:00
|
|
|
"*\t*\n",
|
|
|
|
"*.......*\n"
|
2009-06-04 16:47:57 -06:00
|
|
|
},
|
2008-11-25 15:06:59 -07:00
|
|
|
|
2009-06-04 16:47:57 -06:00
|
|
|
entry{
|
|
|
|
8, 1, '.', 0,
|
2008-11-25 15:06:59 -07:00
|
|
|
"*\t*\t",
|
|
|
|
"*.......*"
|
2009-06-04 16:47:57 -06:00
|
|
|
},
|
2008-11-25 15:06:59 -07:00
|
|
|
|
2009-06-04 16:47:57 -06:00
|
|
|
entry{
|
|
|
|
8, 1, '.', tabwriter.AlignRight,
|
2008-11-25 15:06:59 -07:00
|
|
|
"*\t*\t",
|
|
|
|
".......**"
|
2009-06-04 16:47:57 -06:00
|
|
|
},
|
2008-11-25 15:06:59 -07:00
|
|
|
|
2009-06-04 16:47:57 -06:00
|
|
|
entry{
|
|
|
|
8, 1, '.', 0,
|
2008-11-25 15:06:59 -07:00
|
|
|
"\t\n",
|
|
|
|
"........\n"
|
2009-06-04 16:47:57 -06:00
|
|
|
},
|
2008-11-25 15:06:59 -07:00
|
|
|
|
2009-06-04 16:47:57 -06:00
|
|
|
entry{
|
|
|
|
8, 1, '.', 0,
|
2008-11-25 15:06:59 -07:00
|
|
|
"a) foo",
|
|
|
|
"a) foo"
|
2009-06-04 16:47:57 -06:00
|
|
|
},
|
2008-11-25 15:06:59 -07:00
|
|
|
|
2009-06-04 16:47:57 -06:00
|
|
|
entry{
|
|
|
|
8, 1, ' ', 0,
|
2008-11-25 15:06:59 -07:00
|
|
|
"b) foo\tbar", // "bar" is not in any cell - not formatted, just flushed
|
|
|
|
"b) foobar"
|
2009-06-04 16:47:57 -06:00
|
|
|
},
|
2008-11-25 15:06:59 -07:00
|
|
|
|
2009-06-04 16:47:57 -06:00
|
|
|
entry{
|
|
|
|
8, 1, '.', 0,
|
2008-11-25 15:06:59 -07:00
|
|
|
"c) foo\tbar\t",
|
|
|
|
"c) foo..bar"
|
2009-06-04 16:47:57 -06:00
|
|
|
},
|
2008-11-25 15:06:59 -07:00
|
|
|
|
2009-06-04 16:47:57 -06:00
|
|
|
entry{
|
|
|
|
8, 1, '.', 0,
|
2008-11-25 15:06:59 -07:00
|
|
|
"d) foo\tbar\n",
|
|
|
|
"d) foo..bar\n"
|
2009-06-04 16:47:57 -06:00
|
|
|
},
|
2008-11-25 15:06:59 -07:00
|
|
|
|
2009-06-04 16:47:57 -06:00
|
|
|
entry{
|
|
|
|
8, 1, '.', 0,
|
2008-11-25 15:06:59 -07:00
|
|
|
"e) foo\tbar\t\n",
|
|
|
|
"e) foo..bar.....\n"
|
2009-06-04 16:47:57 -06:00
|
|
|
},
|
2008-11-20 18:39:41 -07:00
|
|
|
|
2009-06-04 16:47:57 -06:00
|
|
|
entry{
|
|
|
|
8, 1, '.', tabwriter.FilterHTML,
|
|
|
|
"f) f<o\t<b>bar</b>\t\n",
|
|
|
|
"f) f<o..<b>bar</b>.....\n"
|
|
|
|
},
|
2008-12-09 14:03:15 -07:00
|
|
|
|
2009-06-04 16:47:57 -06:00
|
|
|
entry{
|
|
|
|
8, 1, '*', 0,
|
2008-11-20 18:39:41 -07:00
|
|
|
"Hello, world!\n",
|
|
|
|
"Hello, world!\n"
|
2009-06-04 16:47:57 -06:00
|
|
|
},
|
2008-11-20 18:39:41 -07:00
|
|
|
|
2009-06-04 16:47:57 -06:00
|
|
|
entry{
|
|
|
|
0, 0, '.', 0,
|
2008-11-21 10:35:49 -07:00
|
|
|
"1\t2\t3\t4\n"
|
2008-11-25 15:06:59 -07:00
|
|
|
"11\t222\t3333\t44444\n",
|
2008-11-21 10:35:49 -07:00
|
|
|
|
|
|
|
"1.2..3...4\n"
|
2008-11-25 15:06:59 -07:00
|
|
|
"11222333344444\n"
|
2009-06-04 16:47:57 -06:00
|
|
|
},
|
2008-11-21 10:35:49 -07:00
|
|
|
|
2009-06-04 16:47:57 -06:00
|
|
|
entry{
|
|
|
|
0, 0, '.', tabwriter.FilterHTML,
|
|
|
|
"1\t2<!---\f--->\t3\t4\n" // \f inside HTML is ignored
|
|
|
|
"11\t222\t3333\t44444\n",
|
|
|
|
|
|
|
|
"1.2<!---\f--->..3...4\n"
|
|
|
|
"11222333344444\n"
|
|
|
|
},
|
|
|
|
|
|
|
|
entry{
|
|
|
|
0, 0, '.', 0,
|
|
|
|
"1\t2\t3\t4\f" // \f causes a newline and flush
|
|
|
|
"11\t222\t3333\t44444\n",
|
|
|
|
|
|
|
|
"1234\n"
|
|
|
|
"11222333344444\n"
|
|
|
|
},
|
|
|
|
|
|
|
|
entry{
|
|
|
|
5, 0, '.', 0,
|
2008-11-25 15:06:59 -07:00
|
|
|
"1\t2\t3\t4\n",
|
|
|
|
"1....2....3....4\n"
|
2009-06-04 16:47:57 -06:00
|
|
|
},
|
2008-11-21 10:35:49 -07:00
|
|
|
|
2009-06-04 16:47:57 -06:00
|
|
|
entry{
|
|
|
|
5, 0, '.', 0,
|
2008-11-25 15:06:59 -07:00
|
|
|
"1\t2\t3\t4\t\n",
|
|
|
|
"1....2....3....4....\n"
|
2009-06-04 16:47:57 -06:00
|
|
|
},
|
2008-11-21 10:35:49 -07:00
|
|
|
|
2009-06-04 16:47:57 -06:00
|
|
|
entry{
|
|
|
|
8, 1, '.', 0,
|
2008-12-05 10:22:13 -07:00
|
|
|
"本\tb\tc\n"
|
|
|
|
"aa\t\u672c\u672c\u672c\tcccc\tddddd\n"
|
2008-11-25 15:06:59 -07:00
|
|
|
"aaa\tbbbb\n",
|
2008-11-21 10:35:49 -07:00
|
|
|
|
2008-12-09 14:03:15 -07:00
|
|
|
"本.......b.......c\n"
|
|
|
|
"aa......本本本.....cccc....ddddd\n"
|
|
|
|
"aaa.....bbbb\n"
|
2009-06-04 16:47:57 -06:00
|
|
|
},
|
2008-11-21 10:35:49 -07:00
|
|
|
|
2009-06-04 16:47:57 -06:00
|
|
|
entry{
|
|
|
|
8, 1, ' ', tabwriter.AlignRight,
|
2008-12-05 10:22:13 -07:00
|
|
|
"a\tè\tc\t\n"
|
|
|
|
"aa\tèèè\tcccc\tddddd\t\n"
|
|
|
|
"aaa\tèèèè\t\n",
|
2008-11-21 10:35:49 -07:00
|
|
|
|
2008-12-05 10:22:13 -07:00
|
|
|
" a è c\n"
|
|
|
|
" aa èèè cccc ddddd\n"
|
|
|
|
" aaa èèèè\n"
|
2009-06-04 16:47:57 -06:00
|
|
|
},
|
2008-11-21 10:35:49 -07:00
|
|
|
|
2009-06-04 16:47:57 -06:00
|
|
|
entry{
|
|
|
|
2, 0, ' ', 0,
|
2008-11-21 10:35:49 -07:00
|
|
|
"a\tb\tc\n"
|
|
|
|
"aa\tbbb\tcccc\n"
|
2008-11-25 15:06:59 -07:00
|
|
|
"aaa\tbbbb\n",
|
2008-11-21 10:35:49 -07:00
|
|
|
|
|
|
|
"a b c\n"
|
|
|
|
"aa bbbcccc\n"
|
2008-11-25 15:06:59 -07:00
|
|
|
"aaabbbb\n"
|
2009-06-04 16:47:57 -06:00
|
|
|
},
|
2008-11-21 10:35:49 -07:00
|
|
|
|
2009-06-04 16:47:57 -06:00
|
|
|
entry{
|
|
|
|
8, 1, '_', 0,
|
2008-11-21 10:35:49 -07:00
|
|
|
"a\tb\tc\n"
|
|
|
|
"aa\tbbb\tcccc\n"
|
2008-11-25 15:06:59 -07:00
|
|
|
"aaa\tbbbb\n",
|
2008-11-21 10:35:49 -07:00
|
|
|
|
|
|
|
"a_______b_______c\n"
|
|
|
|
"aa______bbb_____cccc\n"
|
2008-11-25 15:06:59 -07:00
|
|
|
"aaa_____bbbb\n"
|
2009-06-04 16:47:57 -06:00
|
|
|
},
|
2008-11-21 10:35:49 -07:00
|
|
|
|
2009-06-04 16:47:57 -06:00
|
|
|
entry{
|
|
|
|
4, 1, '-', 0,
|
2008-12-05 10:22:13 -07:00
|
|
|
"4444\t日本語\t22\t1\t333\n"
|
2008-11-21 10:35:49 -07:00
|
|
|
"999999999\t22\n"
|
|
|
|
"7\t22\n"
|
|
|
|
"\t\t\t88888888\n"
|
|
|
|
"\n"
|
|
|
|
"666666\t666666\t666666\t4444\n"
|
2008-11-25 15:06:59 -07:00
|
|
|
"1\t1\t999999999\t0000000000\n",
|
2008-11-21 10:35:49 -07:00
|
|
|
|
2008-12-05 10:22:13 -07:00
|
|
|
"4444------日本語-22--1---333\n"
|
2008-11-21 10:35:49 -07:00
|
|
|
"999999999-22\n"
|
|
|
|
"7---------22\n"
|
|
|
|
"------------------88888888\n"
|
|
|
|
"\n"
|
|
|
|
"666666-666666-666666----4444\n"
|
2008-11-25 15:06:59 -07:00
|
|
|
"1------1------999999999-0000000000\n"
|
2009-06-04 16:47:57 -06:00
|
|
|
},
|
2008-11-21 10:35:49 -07:00
|
|
|
|
2009-06-04 16:47:57 -06:00
|
|
|
entry{
|
|
|
|
4, 3, '.', 0,
|
2008-11-21 10:35:49 -07:00
|
|
|
"4444\t333\t22\t1\t333\n"
|
|
|
|
"999999999\t22\n"
|
|
|
|
"7\t22\n"
|
|
|
|
"\t\t\t88888888\n"
|
|
|
|
"\n"
|
|
|
|
"666666\t666666\t666666\t4444\n"
|
2008-11-25 15:06:59 -07:00
|
|
|
"1\t1\t999999999\t0000000000\n",
|
2008-11-21 10:35:49 -07:00
|
|
|
|
|
|
|
"4444........333...22...1...333\n"
|
|
|
|
"999999999...22\n"
|
|
|
|
"7...........22\n"
|
|
|
|
"....................88888888\n"
|
|
|
|
"\n"
|
|
|
|
"666666...666666...666666......4444\n"
|
2008-11-25 15:06:59 -07:00
|
|
|
"1........1........999999999...0000000000\n"
|
2009-06-04 16:47:57 -06:00
|
|
|
},
|
2008-11-21 10:35:49 -07:00
|
|
|
|
2009-06-04 16:47:57 -06:00
|
|
|
entry{
|
|
|
|
8, 1, '\t', tabwriter.FilterHTML,
|
2008-11-21 10:35:49 -07:00
|
|
|
"4444\t333\t22\t1\t333\n"
|
|
|
|
"999999999\t22\n"
|
|
|
|
"7\t22\n"
|
|
|
|
"\t\t\t88888888\n"
|
|
|
|
"\n"
|
|
|
|
"666666\t666666\t666666\t4444\n"
|
2008-12-09 14:03:15 -07:00
|
|
|
"1\t1\t<font color=red attr=日本語>999999999</font>\t0000000000\n",
|
2008-11-21 10:35:49 -07:00
|
|
|
|
|
|
|
"4444\t\t333\t22\t1\t333\n"
|
|
|
|
"999999999\t22\n"
|
|
|
|
"7\t\t22\n"
|
|
|
|
"\t\t\t\t88888888\n"
|
|
|
|
"\n"
|
|
|
|
"666666\t666666\t666666\t\t4444\n"
|
2008-12-09 14:03:15 -07:00
|
|
|
"1\t1\t<font color=red attr=日本語>999999999</font>\t0000000000\n"
|
2009-06-04 16:47:57 -06:00
|
|
|
},
|
2008-11-21 10:35:49 -07:00
|
|
|
|
2009-06-04 16:47:57 -06:00
|
|
|
entry{
|
|
|
|
0, 2, ' ', tabwriter.AlignRight,
|
2008-11-21 10:35:49 -07:00
|
|
|
".0\t.3\t2.4\t-5.1\t\n"
|
|
|
|
"23.0\t12345678.9\t2.4\t-989.4\t\n"
|
|
|
|
"5.1\t12.0\t2.4\t-7.0\t\n"
|
|
|
|
".0\t0.0\t332.0\t8908.0\t\n"
|
|
|
|
".0\t-.3\t456.4\t22.1\t\n"
|
2008-11-25 15:06:59 -07:00
|
|
|
".0\t1.2\t44.4\t-13.3\t\t",
|
2008-11-21 10:35:49 -07:00
|
|
|
|
|
|
|
" .0 .3 2.4 -5.1\n"
|
|
|
|
" 23.0 12345678.9 2.4 -989.4\n"
|
|
|
|
" 5.1 12.0 2.4 -7.0\n"
|
|
|
|
" .0 0.0 332.0 8908.0\n"
|
|
|
|
" .0 -.3 456.4 22.1\n"
|
2008-11-25 15:06:59 -07:00
|
|
|
" .0 1.2 44.4 -13.3"
|
2009-06-04 16:47:57 -06:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func Test(t *testing.T) {
|
|
|
|
for _, e := range tests {
|
|
|
|
check(t, e.tabwidth, e.padding, e.padchar, e.flags, e.src, e.expected);
|
|
|
|
}
|
2008-11-20 18:39:41 -07:00
|
|
|
}
|