OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [fmt/] [fmt_test.go] - Blame information for rev 774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 747 jeremybenn
// Copyright 2009 The Go Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
4
 
5
package fmt_test
6
 
7
import (
8
        "bytes"
9
        . "fmt"
10
        "io"
11
        "math"
12
        "runtime" // for the malloc count test only
13
        "strings"
14
        "testing"
15
        "time"
16
)
17
 
18
type (
19
        renamedBool       bool
20
        renamedInt        int
21
        renamedInt8       int8
22
        renamedInt16      int16
23
        renamedInt32      int32
24
        renamedInt64      int64
25
        renamedUint       uint
26
        renamedUint8      uint8
27
        renamedUint16     uint16
28
        renamedUint32     uint32
29
        renamedUint64     uint64
30
        renamedUintptr    uintptr
31
        renamedString     string
32
        renamedBytes      []byte
33
        renamedFloat32    float32
34
        renamedFloat64    float64
35
        renamedComplex64  complex64
36
        renamedComplex128 complex128
37
)
38
 
39
func TestFmtInterface(t *testing.T) {
40
        var i1 interface{}
41
        i1 = "abc"
42
        s := Sprintf("%s", i1)
43
        if s != "abc" {
44
                t.Errorf(`Sprintf("%%s", empty("abc")) = %q want %q`, s, "abc")
45
        }
46
}
47
 
48
const b32 uint32 = 1<<32 - 1
49
const b64 uint64 = 1<<64 - 1
50
 
51
var array = [5]int{1, 2, 3, 4, 5}
52
var iarray = [4]interface{}{1, "hello", 2.5, nil}
53
var slice = array[:]
54
var islice = iarray[:]
55
 
56
type A struct {
57
        i int
58
        j uint
59
        s string
60
        x []int
61
}
62
 
63
type I int
64
 
65
func (i I) String() string { return Sprintf("<%d>", int(i)) }
66
 
67
type B struct {
68
        I I
69
        j int
70
}
71
 
72
type C struct {
73
        i int
74
        B
75
}
76
 
77
type F int
78
 
79
func (f F) Format(s State, c rune) {
80
        Fprintf(s, "<%c=F(%d)>", c, int(f))
81
}
82
 
83
type G int
84
 
85
func (g G) GoString() string {
86
        return Sprintf("GoString(%d)", int(g))
87
}
88
 
89
type S struct {
90
        F F // a struct field that Formats
91
        G G // a struct field that GoStrings
92
}
93
 
94
type SI struct {
95
        I interface{}
96
}
97
 
98
// A type with a String method with pointer receiver for testing %p
99
type P int
100
 
101
var pValue P
102
 
103
func (p *P) String() string {
104
        return "String(p)"
105
}
106
 
107
var b byte
108
 
109
var fmttests = []struct {
110
        fmt string
111
        val interface{}
112
        out string
113
}{
114
        {"%d", 12345, "12345"},
115
        {"%v", 12345, "12345"},
116
        {"%t", true, "true"},
117
 
118
        // basic string
119
        {"%s", "abc", "abc"},
120
        {"%x", "abc", "616263"},
121
        {"%x", "xyz", "78797a"},
122
        {"%X", "xyz", "78797A"},
123
        {"%q", "abc", `"abc"`},
124
 
125
        // basic bytes
126
        {"%s", []byte("abc"), "abc"},
127
        {"%x", []byte("abc"), "616263"},
128
        {"% x", []byte("abc\xff"), "61 62 63 ff"},
129
        {"% X", []byte("abc\xff"), "61 62 63 FF"},
130
        {"%x", []byte("xyz"), "78797a"},
131
        {"%X", []byte("xyz"), "78797A"},
132
        {"%q", []byte("abc"), `"abc"`},
133
 
134
        // escaped strings
135
        {"%#q", `abc`, "`abc`"},
136
        {"%#q", `"`, "`\"`"},
137
        {"1 %#q", `\n`, "1 `\\n`"},
138
        {"2 %#q", "\n", `2 "\n"`},
139
        {"%q", `"`, `"\""`},
140
        {"%q", "\a\b\f\r\n\t\v", `"\a\b\f\r\n\t\v"`},
141
        {"%q", "abc\xffdef", `"abc\xffdef"`},
142
        {"%q", "\u263a", `"☺"`},
143
        {"%+q", "\u263a", `"\u263a"`},
144
        {"%q", "\U0010ffff", `"\U0010ffff"`},
145
 
146
        // escaped characters
147
        {"%q", 'x', `'x'`},
148
        {"%q", 0, `'\x00'`},
149
        {"%q", '\n', `'\n'`},
150
        {"%q", '\u0e00', `'\u0e00'`},         // not a printable rune.
151
        {"%q", '\U000c2345', `'\U000c2345'`}, // not a printable rune.
152
        {"%q", int64(0x7FFFFFFF), `%!q(int64=2147483647)`},
153
        {"%q", uint64(0xFFFFFFFF), `%!q(uint64=4294967295)`},
154
        {"%q", '"', `'"'`},
155
        {"%q", '\'', `'\''`},
156
        {"%q", "\u263a", `"☺"`},
157
        {"%+q", "\u263a", `"\u263a"`},
158
 
159
        // width
160
        {"%5s", "abc", "  abc"},
161
        {"%2s", "\u263a", " ☺"},
162
        {"%-5s", "abc", "abc  "},
163
        {"%-8q", "abc", `"abc"   `},
164
        {"%05s", "abc", "00abc"},
165
        {"%08q", "abc", `000"abc"`},
166
        {"%5s", "abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz"},
167
        {"%.5s", "abcdefghijklmnopqrstuvwxyz", "abcde"},
168
        {"%.5s", "日本語日本語", "日本語日本"},
169
        {"%.5s", []byte("日本語日本語"), "日本語日本"},
170
        {"%.5q", "abcdefghijklmnopqrstuvwxyz", `"abcde"`},
171
        {"%.3q", "日本語日本語", `"日本語"`},
172
        {"%.3q", []byte("日本語日本語"), `"日本語"`},
173
        {"%10.1q", "日本語日本語", `       "日"`},
174
 
175
        // integers
176
        {"%d", 12345, "12345"},
177
        {"%d", -12345, "-12345"},
178
        {"%10d", 12345, "     12345"},
179
        {"%10d", -12345, "    -12345"},
180
        {"%+10d", 12345, "    +12345"},
181
        {"%010d", 12345, "0000012345"},
182
        {"%010d", -12345, "-000012345"},
183
        {"%-10d", 12345, "12345     "},
184
        {"%010.3d", 1, "       001"},
185
        {"%010.3d", -1, "      -001"},
186
        {"%+d", 12345, "+12345"},
187
        {"%+d", -12345, "-12345"},
188
        {"%+d", 0, "+0"},
189
        {"% d", 0, " 0"},
190
        {"% d", 12345, " 12345"},
191
        {"%.0d", 0, ""},
192
        {"%.d", 0, ""},
193
 
194
        // unicode format
195
        {"%U", 0x1, "U+0001"},
196
        {"%U", uint(0x1), "U+0001"},
197
        {"%.8U", 0x2, "U+00000002"},
198
        {"%U", 0x1234, "U+1234"},
199
        {"%U", 0x12345, "U+12345"},
200
        {"%10.6U", 0xABC, "  U+000ABC"},
201
        {"%-10.6U", 0xABC, "U+000ABC  "},
202
        {"%U", '\n', `U+000A`},
203
        {"%#U", '\n', `U+000A`},
204
        {"%U", 'x', `U+0078`},
205
        {"%#U", 'x', `U+0078 'x'`},
206
        {"%U", '\u263a', `U+263A`},
207
        {"%#U", '\u263a', `U+263A '☺'`},
208
 
209
        // floats
210
        {"%+.3e", 0.0, "+0.000e+00"},
211
        {"%+.3e", 1.0, "+1.000e+00"},
212
        {"%+.3f", -1.0, "-1.000"},
213
        {"% .3E", -1.0, "-1.000E+00"},
214
        {"% .3e", 1.0, " 1.000e+00"},
215
        {"%+.3g", 0.0, "+0"},
216
        {"%+.3g", 1.0, "+1"},
217
        {"%+.3g", -1.0, "-1"},
218
        {"% .3g", -1.0, "-1"},
219
        {"% .3g", 1.0, " 1"},
220
 
221
        // complex values
222
        {"%+.3e", 0i, "(+0.000e+00+0.000e+00i)"},
223
        {"%+.3f", 0i, "(+0.000+0.000i)"},
224
        {"%+.3g", 0i, "(+0+0i)"},
225
        {"%+.3e", 1 + 2i, "(+1.000e+00+2.000e+00i)"},
226
        {"%+.3f", 1 + 2i, "(+1.000+2.000i)"},
227
        {"%+.3g", 1 + 2i, "(+1+2i)"},
228
        {"%.3e", 0i, "(0.000e+00+0.000e+00i)"},
229
        {"%.3f", 0i, "(0.000+0.000i)"},
230
        {"%.3g", 0i, "(0+0i)"},
231
        {"%.3e", 1 + 2i, "(1.000e+00+2.000e+00i)"},
232
        {"%.3f", 1 + 2i, "(1.000+2.000i)"},
233
        {"%.3g", 1 + 2i, "(1+2i)"},
234
        {"%.3e", -1 - 2i, "(-1.000e+00-2.000e+00i)"},
235
        {"%.3f", -1 - 2i, "(-1.000-2.000i)"},
236
        {"%.3g", -1 - 2i, "(-1-2i)"},
237
        {"% .3E", -1 - 2i, "(-1.000E+00-2.000E+00i)"},
238
        {"%+.3g", complex64(1 + 2i), "(+1+2i)"},
239
        {"%+.3g", complex128(1 + 2i), "(+1+2i)"},
240
 
241
        // erroneous formats
242
        {"", 2, "%!(EXTRA int=2)"},
243
        {"%d", "hello", "%!d(string=hello)"},
244
 
245
        // old test/fmt_test.go
246
        {"%d", 1234, "1234"},
247
        {"%d", -1234, "-1234"},
248
        {"%d", uint(1234), "1234"},
249
        {"%d", uint32(b32), "4294967295"},
250
        {"%d", uint64(b64), "18446744073709551615"},
251
        {"%o", 01234, "1234"},
252
        {"%#o", 01234, "01234"},
253
        {"%o", uint32(b32), "37777777777"},
254
        {"%o", uint64(b64), "1777777777777777777777"},
255
        {"%x", 0x1234abcd, "1234abcd"},
256
        {"%#x", 0x1234abcd, "0x1234abcd"},
257
        {"%x", b32 - 0x1234567, "fedcba98"},
258
        {"%X", 0x1234abcd, "1234ABCD"},
259
        {"%X", b32 - 0x1234567, "FEDCBA98"},
260
        {"%#X", 0, "0X0"},
261
        {"%x", b64, "ffffffffffffffff"},
262
        {"%b", 7, "111"},
263
        {"%b", b64, "1111111111111111111111111111111111111111111111111111111111111111"},
264
        {"%b", -6, "-110"},
265
        {"%e", 1.0, "1.000000e+00"},
266
        {"%e", 1234.5678e3, "1.234568e+06"},
267
        {"%e", 1234.5678e-8, "1.234568e-05"},
268
        {"%e", -7.0, "-7.000000e+00"},
269
        {"%e", -1e-9, "-1.000000e-09"},
270
        {"%f", 1234.5678e3, "1234567.800000"},
271
        {"%f", 1234.5678e-8, "0.000012"},
272
        {"%f", -7.0, "-7.000000"},
273
        {"%f", -1e-9, "-0.000000"},
274
        {"%g", 1234.5678e3, "1.2345678e+06"},
275
        {"%g", float32(1234.5678e3), "1.2345678e+06"},
276
        {"%g", 1234.5678e-8, "1.2345678e-05"},
277
        {"%g", -7.0, "-7"},
278
        {"%g", -1e-9, "-1e-09"},
279
        {"%g", float32(-1e-9), "-1e-09"},
280
        {"%E", 1.0, "1.000000E+00"},
281
        {"%E", 1234.5678e3, "1.234568E+06"},
282
        {"%E", 1234.5678e-8, "1.234568E-05"},
283
        {"%E", -7.0, "-7.000000E+00"},
284
        {"%E", -1e-9, "-1.000000E-09"},
285
        {"%G", 1234.5678e3, "1.2345678E+06"},
286
        {"%G", float32(1234.5678e3), "1.2345678E+06"},
287
        {"%G", 1234.5678e-8, "1.2345678E-05"},
288
        {"%G", -7.0, "-7"},
289
        {"%G", -1e-9, "-1E-09"},
290
        {"%G", float32(-1e-9), "-1E-09"},
291
        {"%c", 'x', "x"},
292
        {"%c", 0xe4, "ä"},
293
        {"%c", 0x672c, "本"},
294
        {"%c", 'æ—¥', "æ—¥"},
295
        {"%20.8d", 1234, "            00001234"},
296
        {"%20.8d", -1234, "           -00001234"},
297
        {"%20d", 1234, "                1234"},
298
        {"%-20.8d", 1234, "00001234            "},
299
        {"%-20.8d", -1234, "-00001234           "},
300
        {"%-#20.8x", 0x1234abc, "0x01234abc          "},
301
        {"%-#20.8X", 0x1234abc, "0X01234ABC          "},
302
        {"%-#20.8o", 01234, "00001234            "},
303
        {"%.20b", 7, "00000000000000000111"},
304
        {"%20.5s", "qwertyuiop", "               qwert"},
305
        {"%.5s", "qwertyuiop", "qwert"},
306
        {"%-20.5s", "qwertyuiop", "qwert               "},
307
        {"%20c", 'x', "                   x"},
308
        {"%-20c", 'x', "x                   "},
309
        {"%20.6e", 1.2345e3, "        1.234500e+03"},
310
        {"%20.6e", 1.2345e-3, "        1.234500e-03"},
311
        {"%20e", 1.2345e3, "        1.234500e+03"},
312
        {"%20e", 1.2345e-3, "        1.234500e-03"},
313
        {"%20.8e", 1.2345e3, "      1.23450000e+03"},
314
        {"%20f", 1.23456789e3, "         1234.567890"},
315
        {"%20f", 1.23456789e-3, "            0.001235"},
316
        {"%20f", 12345678901.23456789, "  12345678901.234568"},
317
        {"%-20f", 1.23456789e3, "1234.567890         "},
318
        {"%20.8f", 1.23456789e3, "       1234.56789000"},
319
        {"%20.8f", 1.23456789e-3, "          0.00123457"},
320
        {"%g", 1.23456789e3, "1234.56789"},
321
        {"%g", 1.23456789e-3, "0.00123456789"},
322
        {"%g", 1.23456789e20, "1.23456789e+20"},
323
        {"%20e", math.Inf(1), "                +Inf"},
324
        {"%-20f", math.Inf(-1), "-Inf                "},
325
        {"%20g", math.NaN(), "                 NaN"},
326
 
327
        // arrays
328
        {"%v", array, "[1 2 3 4 5]"},
329
        {"%v", iarray, "[1 hello 2.5 ]"},
330
        {"%v", &array, "&[1 2 3 4 5]"},
331
        {"%v", &iarray, "&[1 hello 2.5 ]"},
332
 
333
        // slices
334
        {"%v", slice, "[1 2 3 4 5]"},
335
        {"%v", islice, "[1 hello 2.5 ]"},
336
        {"%v", &slice, "&[1 2 3 4 5]"},
337
        {"%v", &islice, "&[1 hello 2.5 ]"},
338
 
339
        // complexes with %v
340
        {"%v", 1 + 2i, "(1+2i)"},
341
        {"%v", complex64(1 + 2i), "(1+2i)"},
342
        {"%v", complex128(1 + 2i), "(1+2i)"},
343
 
344
        // structs
345
        {"%v", A{1, 2, "a", []int{1, 2}}, `{1 2 a [1 2]}`},
346
        {"%+v", A{1, 2, "a", []int{1, 2}}, `{i:1 j:2 s:a x:[1 2]}`},
347
 
348
        // +v on structs with Stringable items
349
        {"%+v", B{1, 2}, `{I:<1> j:2}`},
350
        {"%+v", C{1, B{2, 3}}, `{i:1 B:{I:<2> j:3}}`},
351
 
352
        // q on Stringable items
353
        {"%s", I(23), `<23>`},
354
        {"%q", I(23), `"<23>"`},
355
        {"%x", I(23), `3c32333e`},
356
        {"%d", I(23), `23`}, // Stringer applies only to string formats.
357
 
358
        // go syntax
359
        {"%#v", A{1, 2, "a", []int{1, 2}}, `fmt_test.A{i:1, j:0x2, s:"a", x:[]int{1, 2}}`},
360
        {"%#v", &b, "(*uint8)(0xPTR)"},
361
        {"%#v", TestFmtInterface, "(func(*testing.T))(0xPTR)"},
362
        {"%#v", make(chan int), "(chan int)(0xPTR)"},
363
        {"%#v", uint64(1<<64 - 1), "0xffffffffffffffff"},
364
        {"%#v", 1000000000, "1000000000"},
365
        {"%#v", map[string]int{"a": 1}, `map[string]int{"a":1}`},
366
        {"%#v", map[string]B{"a": {1, 2}}, `map[string]fmt_test.B{"a":fmt_test.B{I:1, j:2}}`},
367
        {"%#v", []string{"a", "b"}, `[]string{"a", "b"}`},
368
        {"%#v", SI{}, `fmt_test.SI{I:interface {}(nil)}`},
369
        {"%#v", []int(nil), `[]int(nil)`},
370
        {"%#v", []int{}, `[]int{}`},
371
        {"%#v", array, `[5]int{1, 2, 3, 4, 5}`},
372
        {"%#v", &array, `&[5]int{1, 2, 3, 4, 5}`},
373
        {"%#v", iarray, `[4]interface {}{1, "hello", 2.5, interface {}(nil)}`},
374
        {"%#v", &iarray, `&[4]interface {}{1, "hello", 2.5, interface {}(nil)}`},
375
        {"%#v", map[int]byte(nil), `map[int]uint8(nil)`},
376
        {"%#v", map[int]byte{}, `map[int]uint8{}`},
377
 
378
        // slices with other formats
379
        {"%#x", []int{1, 2, 15}, `[0x1 0x2 0xf]`},
380
        {"%x", []int{1, 2, 15}, `[1 2 f]`},
381
        {"%d", []int{1, 2, 15}, `[1 2 15]`},
382
        {"%d", []byte{1, 2, 15}, `[1 2 15]`},
383
        {"%q", []string{"a", "b"}, `["a" "b"]`},
384
 
385
        // renamings
386
        {"%v", renamedBool(true), "true"},
387
        {"%d", renamedBool(true), "%!d(fmt_test.renamedBool=true)"},
388
        {"%o", renamedInt(8), "10"},
389
        {"%d", renamedInt8(-9), "-9"},
390
        {"%v", renamedInt16(10), "10"},
391
        {"%v", renamedInt32(-11), "-11"},
392
        {"%X", renamedInt64(255), "FF"},
393
        {"%v", renamedUint(13), "13"},
394
        {"%o", renamedUint8(14), "16"},
395
        {"%X", renamedUint16(15), "F"},
396
        {"%d", renamedUint32(16), "16"},
397
        {"%X", renamedUint64(17), "11"},
398
        {"%o", renamedUintptr(18), "22"},
399
        {"%x", renamedString("thing"), "7468696e67"},
400
        {"%d", renamedBytes([]byte{1, 2, 15}), `[1 2 15]`},
401
        {"%q", renamedBytes([]byte("hello")), `"hello"`},
402
        {"%v", renamedFloat32(22), "22"},
403
        {"%v", renamedFloat64(33), "33"},
404
        {"%v", renamedComplex64(3 + 4i), "(3+4i)"},
405
        {"%v", renamedComplex128(4 - 3i), "(4-3i)"},
406
 
407
        // Formatter
408
        {"%x", F(1), ""},
409
        {"%x", G(2), "2"},
410
        {"%+v", S{F(4), G(5)}, "{F: G:5}"},
411
 
412
        // GoStringer
413
        {"%#v", G(6), "GoString(6)"},
414
        {"%#v", S{F(7), G(8)}, "fmt_test.S{F:, G:GoString(8)}"},
415
 
416
        // %T
417
        {"%T", (4 - 3i), "complex128"},
418
        {"%T", renamedComplex128(4 - 3i), "fmt_test.renamedComplex128"},
419
        {"%T", intVal, "int"},
420
        {"%6T", &intVal, "  *int"},
421
 
422
        // %p
423
        {"p0=%p", new(int), "p0=0xPTR"},
424
        {"p1=%s", &pValue, "p1=String(p)"}, // String method...
425
        {"p2=%p", &pValue, "p2=0xPTR"},     // ... not called with %p
426
        {"p4=%#p", new(int), "p4=PTR"},
427
 
428
        // %p on non-pointers
429
        {"%p", make(chan int), "0xPTR"},
430
        {"%p", make(map[int]int), "0xPTR"},
431
        {"%p", make([]int, 1), "0xPTR"},
432
        {"%p", 27, "%!p(int=27)"}, // not a pointer at all
433
 
434
        // %d on Stringer should give integer if possible
435
        {"%s", time.Time{}.Month(), "January"},
436
        {"%d", time.Time{}.Month(), "1"},
437
 
438
        // erroneous things
439
        {"%s %", "hello", "hello %!(NOVERB)"},
440
        {"%s %.2", "hello", "hello %!(NOVERB)"},
441
        {"%d", "hello", "%!d(string=hello)"},
442
        {"no args", "hello", "no args%!(EXTRA string=hello)"},
443
        {"%s", nil, "%!s()"},
444
        {"%T", nil, ""},
445
        {"%-1", 100, "%!(NOVERB)%!(EXTRA int=100)"},
446
 
447
        // The "" show up because maps are printed by
448
        // first obtaining a list of keys and then looking up
449
        // each key.  Since NaNs can be map keys but cannot
450
        // be fetched directly, the lookup fails and returns a
451
        // zero reflect.Value, which formats as .
452
        // This test is just to check that it shows the two NaNs at all.
453
        {"%v", map[float64]int{math.NaN(): 1, math.NaN(): 2}, "map[NaN: NaN:]"},
454
}
455
 
456
func TestSprintf(t *testing.T) {
457
        for _, tt := range fmttests {
458
                s := Sprintf(tt.fmt, tt.val)
459
                if i := strings.Index(tt.out, "PTR"); i >= 0 {
460
                        j := i
461
                        for ; j < len(s); j++ {
462
                                c := s[j]
463
                                if (c < '0' || c > '9') && (c < 'a' || c > 'f') && (c < 'A' || c > 'F') {
464
                                        break
465
                                }
466
                        }
467
                        s = s[0:i] + "PTR" + s[j:]
468
                }
469
                if s != tt.out {
470
                        if _, ok := tt.val.(string); ok {
471
                                // Don't requote the already-quoted strings.
472
                                // It's too confusing to read the errors.
473
                                t.Errorf("Sprintf(%q, %q) = <%s> want <%s>", tt.fmt, tt.val, s, tt.out)
474
                        } else {
475
                                t.Errorf("Sprintf(%q, %v) = %q want %q", tt.fmt, tt.val, s, tt.out)
476
                        }
477
                }
478
        }
479
}
480
 
481
func BenchmarkSprintfEmpty(b *testing.B) {
482
        for i := 0; i < b.N; i++ {
483
                Sprintf("")
484
        }
485
}
486
 
487
func BenchmarkSprintfString(b *testing.B) {
488
        for i := 0; i < b.N; i++ {
489
                Sprintf("%s", "hello")
490
        }
491
}
492
 
493
func BenchmarkSprintfInt(b *testing.B) {
494
        for i := 0; i < b.N; i++ {
495
                Sprintf("%d", 5)
496
        }
497
}
498
 
499
func BenchmarkSprintfIntInt(b *testing.B) {
500
        for i := 0; i < b.N; i++ {
501
                Sprintf("%d %d", 5, 6)
502
        }
503
}
504
 
505
func BenchmarkSprintfPrefixedInt(b *testing.B) {
506
        for i := 0; i < b.N; i++ {
507
                Sprintf("This is some meaningless prefix text that needs to be scanned %d", 6)
508
        }
509
}
510
 
511
func BenchmarkSprintfFloat(b *testing.B) {
512
        for i := 0; i < b.N; i++ {
513
                Sprintf("%g", 5.23184)
514
        }
515
}
516
 
517
var mallocBuf bytes.Buffer
518
 
519
// gccgo numbers are different because gccgo does not have escape
520
// analysis yet.
521
var mallocTest = []struct {
522
        count int
523
        desc  string
524
        fn    func()
525
}{
526
        {5, `Sprintf("")`, func() { Sprintf("") }},
527
        {5, `Sprintf("xxx")`, func() { Sprintf("xxx") }},
528
        {5, `Sprintf("%x")`, func() { Sprintf("%x", 7) }},
529
        {5, `Sprintf("%s")`, func() { Sprintf("%s", "hello") }},
530
        {5, `Sprintf("%x %x")`, func() { Sprintf("%x %x", 7, 112) }},
531
        // For %g we use a float32, not float64, to guarantee passing the argument
532
        // does not need to allocate memory to store the result in a pointer-sized word.
533
        {20, `Sprintf("%g")`, func() { Sprintf("%g", float32(3.14159)) }},
534
        {5, `Fprintf(buf, "%x %x %x")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%x %x %x", 7, 8, 9) }},
535
        {5, `Fprintf(buf, "%s")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%s", "hello") }},
536
}
537
 
538
var _ bytes.Buffer
539
 
540
func TestCountMallocs(t *testing.T) {
541
        for _, mt := range mallocTest {
542
                const N = 100
543
                memstats := new(runtime.MemStats)
544
                runtime.ReadMemStats(memstats)
545
                mallocs := 0 - memstats.Mallocs
546
                for i := 0; i < N; i++ {
547
                        mt.fn()
548
                }
549
                runtime.ReadMemStats(memstats)
550
                mallocs += memstats.Mallocs
551
                if mallocs/N > uint64(mt.count) {
552
                        t.Errorf("%s: expected %d mallocs, got %d", mt.desc, mt.count, mallocs/N)
553
                }
554
        }
555
}
556
 
557
type flagPrinter struct{}
558
 
559
func (*flagPrinter) Format(f State, c rune) {
560
        s := "%"
561
        for i := 0; i < 128; i++ {
562
                if f.Flag(i) {
563
                        s += string(i)
564
                }
565
        }
566
        if w, ok := f.Width(); ok {
567
                s += Sprintf("%d", w)
568
        }
569
        if p, ok := f.Precision(); ok {
570
                s += Sprintf(".%d", p)
571
        }
572
        s += string(c)
573
        io.WriteString(f, "["+s+"]")
574
}
575
 
576
var flagtests = []struct {
577
        in  string
578
        out string
579
}{
580
        {"%a", "[%a]"},
581
        {"%-a", "[%-a]"},
582
        {"%+a", "[%+a]"},
583
        {"%#a", "[%#a]"},
584
        {"% a", "[% a]"},
585
        {"%0a", "[%0a]"},
586
        {"%1.2a", "[%1.2a]"},
587
        {"%-1.2a", "[%-1.2a]"},
588
        {"%+1.2a", "[%+1.2a]"},
589
        {"%-+1.2a", "[%+-1.2a]"},
590
        {"%-+1.2abc", "[%+-1.2a]bc"},
591
        {"%-1.2abc", "[%-1.2a]bc"},
592
}
593
 
594
func TestFlagParser(t *testing.T) {
595
        var flagprinter flagPrinter
596
        for _, tt := range flagtests {
597
                s := Sprintf(tt.in, &flagprinter)
598
                if s != tt.out {
599
                        t.Errorf("Sprintf(%q, &flagprinter) => %q, want %q", tt.in, s, tt.out)
600
                }
601
        }
602
}
603
 
604
func TestStructPrinter(t *testing.T) {
605
        var s struct {
606
                a string
607
                b string
608
                c int
609
        }
610
        s.a = "abc"
611
        s.b = "def"
612
        s.c = 123
613
        var tests = []struct {
614
                fmt string
615
                out string
616
        }{
617
                {"%v", "{abc def 123}"},
618
                {"%+v", "{a:abc b:def c:123}"},
619
        }
620
        for _, tt := range tests {
621
                out := Sprintf(tt.fmt, s)
622
                if out != tt.out {
623
                        t.Errorf("Sprintf(%q, &s) = %q, want %q", tt.fmt, out, tt.out)
624
                }
625
        }
626
}
627
 
628
// Check map printing using substrings so we don't depend on the print order.
629
func presentInMap(s string, a []string, t *testing.T) {
630
        for i := 0; i < len(a); i++ {
631
                loc := strings.Index(s, a[i])
632
                if loc < 0 {
633
                        t.Errorf("map print: expected to find %q in %q", a[i], s)
634
                }
635
                // make sure the match ends here
636
                loc += len(a[i])
637
                if loc >= len(s) || (s[loc] != ' ' && s[loc] != ']') {
638
                        t.Errorf("map print: %q not properly terminated in %q", a[i], s)
639
                }
640
        }
641
}
642
 
643
func TestMapPrinter(t *testing.T) {
644
        m0 := make(map[int]string)
645
        s := Sprint(m0)
646
        if s != "map[]" {
647
                t.Errorf("empty map printed as %q not %q", s, "map[]")
648
        }
649
        m1 := map[int]string{1: "one", 2: "two", 3: "three"}
650
        a := []string{"1:one", "2:two", "3:three"}
651
        presentInMap(Sprintf("%v", m1), a, t)
652
        presentInMap(Sprint(m1), a, t)
653
}
654
 
655
func TestEmptyMap(t *testing.T) {
656
        const emptyMapStr = "map[]"
657
        var m map[string]int
658
        s := Sprint(m)
659
        if s != emptyMapStr {
660
                t.Errorf("nil map printed as %q not %q", s, emptyMapStr)
661
        }
662
        m = make(map[string]int)
663
        s = Sprint(m)
664
        if s != emptyMapStr {
665
                t.Errorf("empty map printed as %q not %q", s, emptyMapStr)
666
        }
667
}
668
 
669
// Check that Sprint (and hence Print, Fprint) puts spaces in the right places,
670
// that is, between arg pairs in which neither is a string.
671
func TestBlank(t *testing.T) {
672
        got := Sprint("<", 1, ">:", 1, 2, 3, "!")
673
        expect := "<1>:1 2 3!"
674
        if got != expect {
675
                t.Errorf("got %q expected %q", got, expect)
676
        }
677
}
678
 
679
// Check that Sprintln (and hence Println, Fprintln) puts spaces in the right places,
680
// that is, between all arg pairs.
681
func TestBlankln(t *testing.T) {
682
        got := Sprintln("<", 1, ">:", 1, 2, 3, "!")
683
        expect := "< 1 >: 1 2 3 !\n"
684
        if got != expect {
685
                t.Errorf("got %q expected %q", got, expect)
686
        }
687
}
688
 
689
// Check Formatter with Sprint, Sprintln, Sprintf
690
func TestFormatterPrintln(t *testing.T) {
691
        f := F(1)
692
        expect := "\n"
693
        s := Sprint(f, "\n")
694
        if s != expect {
695
                t.Errorf("Sprint wrong with Formatter: expected %q got %q", expect, s)
696
        }
697
        s = Sprintln(f)
698
        if s != expect {
699
                t.Errorf("Sprintln wrong with Formatter: expected %q got %q", expect, s)
700
        }
701
        s = Sprintf("%v\n", f)
702
        if s != expect {
703
                t.Errorf("Sprintf wrong with Formatter: expected %q got %q", expect, s)
704
        }
705
}
706
 
707
func args(a ...interface{}) []interface{} { return a }
708
 
709
var startests = []struct {
710
        fmt string
711
        in  []interface{}
712
        out string
713
}{
714
        {"%*d", args(4, 42), "  42"},
715
        {"%.*d", args(4, 42), "0042"},
716
        {"%*.*d", args(8, 4, 42), "    0042"},
717
        {"%0*d", args(4, 42), "0042"},
718
        {"%-*d", args(4, 42), "42  "},
719
 
720
        // erroneous
721
        {"%*d", args(nil, 42), "%!(BADWIDTH)42"},
722
        {"%.*d", args(nil, 42), "%!(BADPREC)42"},
723
        {"%*d", args(5, "foo"), "%!d(string=  foo)"},
724
        {"%*% %d", args(20, 5), "% 5"},
725
        {"%*", args(4), "%!(NOVERB)"},
726
        {"%*d", args(int32(4), 42), "%!(BADWIDTH)42"},
727
}
728
 
729
func TestWidthAndPrecision(t *testing.T) {
730
        for _, tt := range startests {
731
                s := Sprintf(tt.fmt, tt.in...)
732
                if s != tt.out {
733
                        t.Errorf("%q: got %q expected %q", tt.fmt, s, tt.out)
734
                }
735
        }
736
}
737
 
738
// A type that panics in String.
739
type Panic struct {
740
        message interface{}
741
}
742
 
743
// Value receiver.
744
func (p Panic) GoString() string {
745
        panic(p.message)
746
}
747
 
748
// Value receiver.
749
func (p Panic) String() string {
750
        panic(p.message)
751
}
752
 
753
// A type that panics in Format.
754
type PanicF struct {
755
        message interface{}
756
}
757
 
758
// Value receiver.
759
func (p PanicF) Format(f State, c rune) {
760
        panic(p.message)
761
}
762
 
763
var panictests = []struct {
764
        fmt string
765
        in  interface{}
766
        out string
767
}{
768
        // String
769
        {"%s", (*Panic)(nil), ""}, // nil pointer special case
770
        {"%s", Panic{io.ErrUnexpectedEOF}, "%s(PANIC=unexpected EOF)"},
771
        {"%s", Panic{3}, "%s(PANIC=3)"},
772
        // GoString
773
        {"%#v", (*Panic)(nil), ""}, // nil pointer special case
774
        {"%#v", Panic{io.ErrUnexpectedEOF}, "%v(PANIC=unexpected EOF)"},
775
        {"%#v", Panic{3}, "%v(PANIC=3)"},
776
        // Format
777
        {"%s", (*PanicF)(nil), ""}, // nil pointer special case
778
        {"%s", PanicF{io.ErrUnexpectedEOF}, "%s(PANIC=unexpected EOF)"},
779
        {"%s", PanicF{3}, "%s(PANIC=3)"},
780
}
781
 
782
func TestPanics(t *testing.T) {
783
        for _, tt := range panictests {
784
                s := Sprintf(tt.fmt, tt.in)
785
                if s != tt.out {
786
                        t.Errorf("%q: got %q expected %q", tt.fmt, s, tt.out)
787
                }
788
        }
789
}
790
 
791
// Test that erroneous String routine doesn't cause fatal recursion.
792
var recurCount = 0
793
 
794
type Recur struct {
795
        i      int
796
        failed *bool
797
}
798
 
799
func (r Recur) String() string {
800
        if recurCount++; recurCount > 10 {
801
                *r.failed = true
802
                return "FAIL"
803
        }
804
        // This will call badVerb. Before the fix, that would cause us to recur into
805
        // this routine to print %!p(value). Now we don't call the user's method
806
        // during an error.
807
        return Sprintf("recur@%p value: %d", r, r.i)
808
}
809
 
810
func TestBadVerbRecursion(t *testing.T) {
811
        failed := false
812
        r := Recur{3, &failed}
813
        Sprintf("recur@%p value: %d\n", &r, r.i)
814
        if failed {
815
                t.Error("fail with pointer")
816
        }
817
        failed = false
818
        r = Recur{4, &failed}
819
        Sprintf("recur@%p, value: %d\n", r, r.i)
820
        if failed {
821
                t.Error("fail with value")
822
        }
823
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.