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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [old/] [template/] [template_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 template
6
 
7
import (
8
        "bytes"
9
        "encoding/json"
10
        "fmt"
11
        "io"
12
        "io/ioutil"
13
        "os"
14
        "strings"
15
        "testing"
16
)
17
 
18
type Test struct {
19
        in, out, err string
20
}
21
 
22
type T struct {
23
        Item  string
24
        Value string
25
}
26
 
27
type U struct {
28
        Mp map[string]int
29
}
30
 
31
type S struct {
32
        Header        string
33
        HeaderPtr     *string
34
        Integer       int
35
        IntegerPtr    *int
36
        NilPtr        *int
37
        InnerT        T
38
        InnerPointerT *T
39
        Data          []T
40
        Pdata         []*T
41
        Empty         []*T
42
        Emptystring   string
43
        Null          []*T
44
        Vec           []interface{}
45
        True          bool
46
        False         bool
47
        Mp            map[string]string
48
        JSON          interface{}
49
        Innermap      U
50
        Stringmap     map[string]string
51
        Ptrmap        map[string]*string
52
        Iface         interface{}
53
        Ifaceptr      interface{}
54
}
55
 
56
func (s *S) PointerMethod() string { return "ptrmethod!" }
57
 
58
func (s S) ValueMethod() string { return "valmethod!" }
59
 
60
var t1 = T{"ItemNumber1", "ValueNumber1"}
61
var t2 = T{"ItemNumber2", "ValueNumber2"}
62
 
63
func uppercase(v interface{}) string {
64
        s := v.(string)
65
        t := ""
66
        for i := 0; i < len(s); i++ {
67
                c := s[i]
68
                if 'a' <= c && c <= 'z' {
69
                        c = c + 'A' - 'a'
70
                }
71
                t += string(c)
72
        }
73
        return t
74
}
75
 
76
func plus1(v interface{}) string {
77
        i := v.(int)
78
        return fmt.Sprint(i + 1)
79
}
80
 
81
func writer(f func(interface{}) string) func(io.Writer, string, ...interface{}) {
82
        return func(w io.Writer, format string, v ...interface{}) {
83
                if len(v) != 1 {
84
                        panic("test writer expected one arg")
85
                }
86
                io.WriteString(w, f(v[0]))
87
        }
88
}
89
 
90
func multiword(w io.Writer, format string, value ...interface{}) {
91
        for _, v := range value {
92
                fmt.Fprintf(w, "<%v>", v)
93
        }
94
}
95
 
96
func printf(w io.Writer, format string, v ...interface{}) {
97
        io.WriteString(w, fmt.Sprintf(v[0].(string), v[1:]...))
98
}
99
 
100
var formatters = FormatterMap{
101
        "uppercase": writer(uppercase),
102
        "+1":        writer(plus1),
103
        "multiword": multiword,
104
        "printf":    printf,
105
}
106
 
107
var tests = []*Test{
108
        // Simple
109
        {"", "", ""},
110
        {"abc", "abc", ""},
111
        {"abc\ndef\n", "abc\ndef\n", ""},
112
        {" {.meta-left}   \n", "{", ""},
113
        {" {.meta-right}   \n", "}", ""},
114
        {" {.space}   \n", " ", ""},
115
        {" {.tab}   \n", "\t", ""},
116
        {"     {#comment}   \n", "", ""},
117
        {"\tSome Text\t\n", "\tSome Text\t\n", ""},
118
        {" {.meta-right} {.meta-right} {.meta-right} \n", " } } } \n", ""},
119
 
120
        // Variables at top level
121
        {
122
                in: "{Header}={Integer}\n",
123
 
124
                out: "Header=77\n",
125
        },
126
 
127
        {
128
                in: "Pointers: {*HeaderPtr}={*IntegerPtr}\n",
129
 
130
                out: "Pointers: Header=77\n",
131
        },
132
 
133
        {
134
                in: "Stars but not pointers: {*Header}={*Integer}\n",
135
 
136
                out: "Stars but not pointers: Header=77\n",
137
        },
138
 
139
        {
140
                in: "nil pointer: {*NilPtr}={*Integer}\n",
141
 
142
                out: "nil pointer: =77\n",
143
        },
144
 
145
        {
146
                in: `{"Strings" ":"} {""} {"|"} {"\t\u0123 \x23\\"} {"\"}{\\"}`,
147
 
148
                out: "Strings:  | \t\u0123 \x23\\ \"}{\\",
149
        },
150
 
151
        {
152
                in: "{`Raw strings` `:`} {``} {`|`} {`\\t\\u0123 \\x23\\`} {`}{\\`}",
153
 
154
                out: "Raw strings:  | \\t\\u0123 \\x23\\ }{\\",
155
        },
156
 
157
        {
158
                in: "Characters: {'a'} {'\\u0123'} {' '} {'{'} {'|'} {'}'}",
159
 
160
                out: "Characters: 97 291 32 123 124 125",
161
        },
162
 
163
        {
164
                in: "Integers: {1} {-2} {+42} {0777} {0x0a}",
165
 
166
                out: "Integers: 1 -2 42 511 10",
167
        },
168
 
169
        {
170
                in: "Floats: {.5} {-.5} {1.1} {-2.2} {+42.1} {1e10} {1.2e-3} {1.2e3} {-1.2e3}",
171
 
172
                out: "Floats: 0.5 -0.5 1.1 -2.2 42.1 1e+10 0.0012 1200 -1200",
173
        },
174
 
175
        // Method at top level
176
        {
177
                in: "ptrmethod={PointerMethod}\n",
178
 
179
                out: "ptrmethod=ptrmethod!\n",
180
        },
181
 
182
        {
183
                in: "valmethod={ValueMethod}\n",
184
 
185
                out: "valmethod=valmethod!\n",
186
        },
187
 
188
        // Section
189
        {
190
                in: "{.section Data }\n" +
191
                        "some text for the section\n" +
192
                        "{.end}\n",
193
 
194
                out: "some text for the section\n",
195
        },
196
        {
197
                in: "{.section Data }\n" +
198
                        "{Header}={Integer}\n" +
199
                        "{.end}\n",
200
 
201
                out: "Header=77\n",
202
        },
203
        {
204
                in: "{.section Pdata }\n" +
205
                        "{Header}={Integer}\n" +
206
                        "{.end}\n",
207
 
208
                out: "Header=77\n",
209
        },
210
        {
211
                in: "{.section Pdata }\n" +
212
                        "data present\n" +
213
                        "{.or}\n" +
214
                        "data not present\n" +
215
                        "{.end}\n",
216
 
217
                out: "data present\n",
218
        },
219
        {
220
                in: "{.section Empty }\n" +
221
                        "data present\n" +
222
                        "{.or}\n" +
223
                        "data not present\n" +
224
                        "{.end}\n",
225
 
226
                out: "data not present\n",
227
        },
228
        {
229
                in: "{.section Null }\n" +
230
                        "data present\n" +
231
                        "{.or}\n" +
232
                        "data not present\n" +
233
                        "{.end}\n",
234
 
235
                out: "data not present\n",
236
        },
237
        {
238
                in: "{.section Pdata }\n" +
239
                        "{Header}={Integer}\n" +
240
                        "{.section @ }\n" +
241
                        "{Header}={Integer}\n" +
242
                        "{.end}\n" +
243
                        "{.end}\n",
244
 
245
                out: "Header=77\n" +
246
                        "Header=77\n",
247
        },
248
 
249
        {
250
                in: "{.section Data}{.end} {Header}\n",
251
 
252
                out: " Header\n",
253
        },
254
 
255
        {
256
                in: "{.section Integer}{@}{.end}",
257
 
258
                out: "77",
259
        },
260
 
261
        // Repeated
262
        {
263
                in: "{.section Pdata }\n" +
264
                        "{.repeated section @ }\n" +
265
                        "{Item}={Value}\n" +
266
                        "{.end}\n" +
267
                        "{.end}\n",
268
 
269
                out: "ItemNumber1=ValueNumber1\n" +
270
                        "ItemNumber2=ValueNumber2\n",
271
        },
272
        {
273
                in: "{.section Pdata }\n" +
274
                        "{.repeated section @ }\n" +
275
                        "{Item}={Value}\n" +
276
                        "{.or}\n" +
277
                        "this should not appear\n" +
278
                        "{.end}\n" +
279
                        "{.end}\n",
280
 
281
                out: "ItemNumber1=ValueNumber1\n" +
282
                        "ItemNumber2=ValueNumber2\n",
283
        },
284
        {
285
                in: "{.section @ }\n" +
286
                        "{.repeated section Empty }\n" +
287
                        "{Item}={Value}\n" +
288
                        "{.or}\n" +
289
                        "this should appear: empty field\n" +
290
                        "{.end}\n" +
291
                        "{.end}\n",
292
 
293
                out: "this should appear: empty field\n",
294
        },
295
        {
296
                in: "{.repeated section Pdata }\n" +
297
                        "{Item}\n" +
298
                        "{.alternates with}\n" +
299
                        "is\nover\nmultiple\nlines\n" +
300
                        "{.end}\n",
301
 
302
                out: "ItemNumber1\n" +
303
                        "is\nover\nmultiple\nlines\n" +
304
                        "ItemNumber2\n",
305
        },
306
        {
307
                in: "{.repeated section Pdata }\n" +
308
                        "{Item}\n" +
309
                        "{.alternates with}\n" +
310
                        "is\nover\nmultiple\nlines\n" +
311
                        " {.end}\n",
312
 
313
                out: "ItemNumber1\n" +
314
                        "is\nover\nmultiple\nlines\n" +
315
                        "ItemNumber2\n",
316
        },
317
        {
318
                in: "{.section Pdata }\n" +
319
                        "{.repeated section @ }\n" +
320
                        "{Item}={Value}\n" +
321
                        "{.alternates with}DIVIDER\n" +
322
                        "{.or}\n" +
323
                        "this should not appear\n" +
324
                        "{.end}\n" +
325
                        "{.end}\n",
326
 
327
                out: "ItemNumber1=ValueNumber1\n" +
328
                        "DIVIDER\n" +
329
                        "ItemNumber2=ValueNumber2\n",
330
        },
331
        {
332
                in: "{.repeated section Vec }\n" +
333
                        "{@}\n" +
334
                        "{.end}\n",
335
 
336
                out: "elt1\n" +
337
                        "elt2\n",
338
        },
339
        // Same but with a space before {.end}: was a bug.
340
        {
341
                in: "{.repeated section Vec }\n" +
342
                        "{@} {.end}\n",
343
 
344
                out: "elt1 elt2 \n",
345
        },
346
        {
347
                in: "{.repeated section Integer}{.end}",
348
 
349
                err: "line 1: .repeated: cannot repeat Integer (type int)",
350
        },
351
 
352
        // Nested names
353
        {
354
                in: "{.section @ }\n" +
355
                        "{InnerT.Item}={InnerT.Value}\n" +
356
                        "{.end}",
357
 
358
                out: "ItemNumber1=ValueNumber1\n",
359
        },
360
        {
361
                in: "{.section @ }\n" +
362
                        "{InnerT.Item}={.section InnerT}{.section Value}{@}{.end}{.end}\n" +
363
                        "{.end}",
364
 
365
                out: "ItemNumber1=ValueNumber1\n",
366
        },
367
 
368
        {
369
                in: "{.section Emptystring}emptystring{.end}\n" +
370
                        "{.section Header}header{.end}\n",
371
 
372
                out: "\nheader\n",
373
        },
374
 
375
        {
376
                in: "{.section True}1{.or}2{.end}\n" +
377
                        "{.section False}3{.or}4{.end}\n",
378
 
379
                out: "1\n4\n",
380
        },
381
 
382
        // Maps
383
 
384
        {
385
                in: "{Mp.mapkey}\n",
386
 
387
                out: "Ahoy!\n",
388
        },
389
        {
390
                in: "{Innermap.Mp.innerkey}\n",
391
 
392
                out: "55\n",
393
        },
394
        {
395
                in: "{.section Innermap}{.section Mp}{innerkey}{.end}{.end}\n",
396
 
397
                out: "55\n",
398
        },
399
        {
400
                in: "{.section JSON}{.repeated section maps}{a}{b}{.end}{.end}\n",
401
 
402
                out: "1234\n",
403
        },
404
        {
405
                in: "{Stringmap.stringkey1}\n",
406
 
407
                out: "stringresult\n",
408
        },
409
        {
410
                in: "{.repeated section Stringmap}\n" +
411
                        "{@}\n" +
412
                        "{.end}",
413
 
414
                out: "stringresult\n" +
415
                        "stringresult\n",
416
        },
417
        {
418
                in: "{.repeated section Stringmap}\n" +
419
                        "\t{@}\n" +
420
                        "{.end}",
421
 
422
                out: "\tstringresult\n" +
423
                        "\tstringresult\n",
424
        },
425
        {
426
                in: "{*Ptrmap.stringkey1}\n",
427
 
428
                out: "pointedToString\n",
429
        },
430
        {
431
                in: "{.repeated section Ptrmap}\n" +
432
                        "{*@}\n" +
433
                        "{.end}",
434
 
435
                out: "pointedToString\n" +
436
                        "pointedToString\n",
437
        },
438
 
439
        // Interface values
440
 
441
        {
442
                in: "{Iface}",
443
 
444
                out: "[1 2 3]",
445
        },
446
        {
447
                in: "{.repeated section Iface}{@}{.alternates with} {.end}",
448
 
449
                out: "1 2 3",
450
        },
451
        {
452
                in: "{.section Iface}{@}{.end}",
453
 
454
                out: "[1 2 3]",
455
        },
456
        {
457
                in: "{.section Ifaceptr}{Item} {Value}{.end}",
458
 
459
                out: "Item Value",
460
        },
461
}
462
 
463
func TestAll(t *testing.T) {
464
        // Parse
465
        testAll(t, func(test *Test) (*Template, error) { return Parse(test.in, formatters) })
466
        // ParseFile
467
        f, err := ioutil.TempFile("", "template-test")
468
        if err != nil {
469
                t.Fatal(err)
470
        }
471
        defer func() {
472
                name := f.Name()
473
                f.Close()
474
                os.Remove(name)
475
        }()
476
        testAll(t, func(test *Test) (*Template, error) {
477
                err := ioutil.WriteFile(f.Name(), []byte(test.in), 0600)
478
                if err != nil {
479
                        t.Error("unexpected write error:", err)
480
                        return nil, err
481
                }
482
                return ParseFile(f.Name(), formatters)
483
        })
484
        // tmpl.ParseFile
485
        testAll(t, func(test *Test) (*Template, error) {
486
                err := ioutil.WriteFile(f.Name(), []byte(test.in), 0600)
487
                if err != nil {
488
                        t.Error("unexpected write error:", err)
489
                        return nil, err
490
                }
491
                tmpl := New(formatters)
492
                return tmpl, tmpl.ParseFile(f.Name())
493
        })
494
}
495
 
496
func testAll(t *testing.T, parseFunc func(*Test) (*Template, error)) {
497
        s := new(S)
498
        // initialized by hand for clarity.
499
        s.Header = "Header"
500
        s.HeaderPtr = &s.Header
501
        s.Integer = 77
502
        s.IntegerPtr = &s.Integer
503
        s.InnerT = t1
504
        s.Data = []T{t1, t2}
505
        s.Pdata = []*T{&t1, &t2}
506
        s.Empty = []*T{}
507
        s.Null = nil
508
        s.Vec = []interface{}{"elt1", "elt2"}
509
        s.True = true
510
        s.False = false
511
        s.Mp = make(map[string]string)
512
        s.Mp["mapkey"] = "Ahoy!"
513
        json.Unmarshal([]byte(`{"maps":[{"a":1,"b":2},{"a":3,"b":4}]}`), &s.JSON)
514
        s.Innermap.Mp = make(map[string]int)
515
        s.Innermap.Mp["innerkey"] = 55
516
        s.Stringmap = make(map[string]string)
517
        s.Stringmap["stringkey1"] = "stringresult" // the same value so repeated section is order-independent
518
        s.Stringmap["stringkey2"] = "stringresult"
519
        s.Ptrmap = make(map[string]*string)
520
        x := "pointedToString"
521
        s.Ptrmap["stringkey1"] = &x // the same value so repeated section is order-independent
522
        s.Ptrmap["stringkey2"] = &x
523
        s.Iface = []int{1, 2, 3}
524
        s.Ifaceptr = &T{"Item", "Value"}
525
 
526
        var buf bytes.Buffer
527
        for _, test := range tests {
528
                buf.Reset()
529
                tmpl, err := parseFunc(test)
530
                if err != nil {
531
                        t.Error("unexpected parse error: ", err)
532
                        continue
533
                }
534
                err = tmpl.Execute(&buf, s)
535
                if test.err == "" {
536
                        if err != nil {
537
                                t.Error("unexpected execute error:", err)
538
                        }
539
                } else {
540
                        if err == nil {
541
                                t.Errorf("expected execute error %q, got nil", test.err)
542
                        } else if err.Error() != test.err {
543
                                t.Errorf("expected execute error %q, got %q", test.err, err.Error())
544
                        }
545
                }
546
                if buf.String() != test.out {
547
                        t.Errorf("for %q: expected %q got %q", test.in, test.out, buf.String())
548
                }
549
        }
550
}
551
 
552
func TestMapDriverType(t *testing.T) {
553
        mp := map[string]string{"footer": "Ahoy!"}
554
        tmpl, err := Parse("template: {footer}", nil)
555
        if err != nil {
556
                t.Error("unexpected parse error:", err)
557
        }
558
        var b bytes.Buffer
559
        err = tmpl.Execute(&b, mp)
560
        if err != nil {
561
                t.Error("unexpected execute error:", err)
562
        }
563
        s := b.String()
564
        expect := "template: Ahoy!"
565
        if s != expect {
566
                t.Errorf("failed passing string as data: expected %q got %q", expect, s)
567
        }
568
}
569
 
570
func TestMapNoEntry(t *testing.T) {
571
        mp := make(map[string]int)
572
        tmpl, err := Parse("template: {notthere}!", nil)
573
        if err != nil {
574
                t.Error("unexpected parse error:", err)
575
        }
576
        var b bytes.Buffer
577
        err = tmpl.Execute(&b, mp)
578
        if err != nil {
579
                t.Error("unexpected execute error:", err)
580
        }
581
        s := b.String()
582
        expect := "template: 0!"
583
        if s != expect {
584
                t.Errorf("failed passing string as data: expected %q got %q", expect, s)
585
        }
586
}
587
 
588
func TestStringDriverType(t *testing.T) {
589
        tmpl, err := Parse("template: {@}", nil)
590
        if err != nil {
591
                t.Error("unexpected parse error:", err)
592
        }
593
        var b bytes.Buffer
594
        err = tmpl.Execute(&b, "hello")
595
        if err != nil {
596
                t.Error("unexpected execute error:", err)
597
        }
598
        s := b.String()
599
        expect := "template: hello"
600
        if s != expect {
601
                t.Errorf("failed passing string as data: expected %q got %q", expect, s)
602
        }
603
}
604
 
605
func TestTwice(t *testing.T) {
606
        tmpl, err := Parse("template: {@}", nil)
607
        if err != nil {
608
                t.Error("unexpected parse error:", err)
609
        }
610
        var b bytes.Buffer
611
        err = tmpl.Execute(&b, "hello")
612
        if err != nil {
613
                t.Error("unexpected parse error:", err)
614
        }
615
        s := b.String()
616
        expect := "template: hello"
617
        if s != expect {
618
                t.Errorf("failed passing string as data: expected %q got %q", expect, s)
619
        }
620
        err = tmpl.Execute(&b, "hello")
621
        if err != nil {
622
                t.Error("unexpected parse error:", err)
623
        }
624
        s = b.String()
625
        expect += expect
626
        if s != expect {
627
                t.Errorf("failed passing string as data: expected %q got %q", expect, s)
628
        }
629
}
630
 
631
func TestCustomDelims(t *testing.T) {
632
        // try various lengths.  zero should catch error.
633
        for i := 0; i < 7; i++ {
634
                for j := 0; j < 7; j++ {
635
                        tmpl := New(nil)
636
                        // first two chars deliberately the same to test equal left and right delims
637
                        ldelim := "$!#$%^&"[0:i]
638
                        rdelim := "$*&^%$!"[0:j]
639
                        tmpl.SetDelims(ldelim, rdelim)
640
                        // if braces, this would be template: {@}{.meta-left}{.meta-right}
641
                        text := "template: " +
642
                                ldelim + "@" + rdelim +
643
                                ldelim + ".meta-left" + rdelim +
644
                                ldelim + ".meta-right" + rdelim
645
                        err := tmpl.Parse(text)
646
                        if err != nil {
647
                                if i == 0 || j == 0 { // expected
648
                                        continue
649
                                }
650
                                t.Error("unexpected parse error:", err)
651
                        } else if i == 0 || j == 0 {
652
                                t.Errorf("expected parse error for empty delimiter: %d %d %q %q", i, j, ldelim, rdelim)
653
                                continue
654
                        }
655
                        var b bytes.Buffer
656
                        err = tmpl.Execute(&b, "hello")
657
                        s := b.String()
658
                        if s != "template: hello"+ldelim+rdelim {
659
                                t.Errorf("failed delim check(%q %q) %q got %q", ldelim, rdelim, text, s)
660
                        }
661
                }
662
        }
663
}
664
 
665
// Test that a variable evaluates to the field itself and does not further indirection
666
func TestVarIndirection(t *testing.T) {
667
        s := new(S)
668
        // initialized by hand for clarity.
669
        s.InnerPointerT = &t1
670
 
671
        var buf bytes.Buffer
672
        input := "{.section @}{InnerPointerT}{.end}"
673
        tmpl, err := Parse(input, nil)
674
        if err != nil {
675
                t.Fatal("unexpected parse error:", err)
676
        }
677
        err = tmpl.Execute(&buf, s)
678
        if err != nil {
679
                t.Fatal("unexpected execute error:", err)
680
        }
681
        expect := fmt.Sprintf("%v", &t1) // output should be hex address of t1
682
        if buf.String() != expect {
683
                t.Errorf("for %q: expected %q got %q", input, expect, buf.String())
684
        }
685
}
686
 
687
func TestHTMLFormatterWithByte(t *testing.T) {
688
        s := "Test string."
689
        b := []byte(s)
690
        var buf bytes.Buffer
691
        HTMLFormatter(&buf, "", b)
692
        bs := buf.String()
693
        if bs != s {
694
                t.Errorf("munged []byte, expected: %s got: %s", s, bs)
695
        }
696
}
697
 
698
type UF struct {
699
        I int
700
        s string
701
}
702
 
703
func TestReferenceToUnexported(t *testing.T) {
704
        u := &UF{3, "hello"}
705
        var buf bytes.Buffer
706
        input := "{.section @}{I}{s}{.end}"
707
        tmpl, err := Parse(input, nil)
708
        if err != nil {
709
                t.Fatal("unexpected parse error:", err)
710
        }
711
        err = tmpl.Execute(&buf, u)
712
        if err == nil {
713
                t.Fatal("expected execute error, got none")
714
        }
715
        if strings.Index(err.Error(), "not exported") < 0 {
716
                t.Fatal("expected unexported error; got", err)
717
        }
718
}
719
 
720
var formatterTests = []Test{
721
        {
722
                in: "{Header|uppercase}={Integer|+1}\n" +
723
                        "{Header|html}={Integer|str}\n",
724
 
725
                out: "HEADER=78\n" +
726
                        "Header=77\n",
727
        },
728
 
729
        {
730
                in: "{Header|uppercase}={Integer Header|multiword}\n" +
731
                        "{Header|html}={Header Integer|multiword}\n" +
732
                        "{Header|html}={Header Integer}\n",
733
 
734
                out: "HEADER=<77>
\n" +
735
                        "Header=
<77>\n" +
736
                        "Header=Header77\n",
737
        },
738
        {
739
                in: "{Raw}\n" +
740
                        "{Raw|html}\n",
741
 
742
                out: "a <&> b\n" +
743
                        "a <&> b\n",
744
        },
745
        {
746
                in:  "{Bytes}",
747
                out: "hello",
748
        },
749
        {
750
                in:  "{Raw|uppercase|html|html}",
751
                out: "A &lt;&amp;&gt; B",
752
        },
753
        {
754
                in:  "{Header Integer|multiword|html}",
755
                out: "<Header><77>",
756
        },
757
        {
758
                in:  "{Integer|no_formatter|html}",
759
                err: `unknown formatter: "no_formatter"`,
760
        },
761
        {
762
                in:  "{Integer|||||}", // empty string is a valid formatter
763
                out: "77",
764
        },
765
        {
766
                in:  `{"%.02f 0x%02X" 1.1 10|printf}`,
767
                out: "1.10 0x0A",
768
        },
769
        {
770
                in:  `{""|}{""||}{""|printf}`, // Issue #1896.
771
                out: "",
772
        },
773
}
774
 
775
func TestFormatters(t *testing.T) {
776
        data := map[string]interface{}{
777
                "Header":  "Header",
778
                "Integer": 77,
779
                "Raw":     "a <&> b",
780
                "Bytes":   []byte("hello"),
781
        }
782
        for _, c := range formatterTests {
783
                tmpl, err := Parse(c.in, formatters)
784
                if err != nil {
785
                        if c.err == "" {
786
                                t.Error("unexpected parse error:", err)
787
                                continue
788
                        }
789
                        if strings.Index(err.Error(), c.err) < 0 {
790
                                t.Errorf("unexpected error: expected %q, got %q", c.err, err.Error())
791
                                continue
792
                        }
793
                } else {
794
                        if c.err != "" {
795
                                t.Errorf("For %q, expected error, got none.", c.in)
796
                                continue
797
                        }
798
                        var buf bytes.Buffer
799
                        err = tmpl.Execute(&buf, data)
800
                        if err != nil {
801
                                t.Error("unexpected Execute error: ", err)
802
                                continue
803
                        }
804
                        actual := buf.String()
805
                        if actual != c.out {
806
                                t.Errorf("for %q: expected %q but got %q.", c.in, c.out, actual)
807
                        }
808
                }
809
        }
810
}

powered by: WebSVN 2.1.0

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