~ubuntu-branches/ubuntu/utopic/golang/utopic

« back to all changes in this revision

Viewing changes to src/pkg/text/template/exec_test.go

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2013-08-20 14:06:23 UTC
  • mfrom: (14.1.23 saucy-proposed)
  • Revision ID: package-import@ubuntu.com-20130820140623-b414jfxi3m0qkmrq
Tags: 2:1.1.2-2ubuntu1
* Merge from Debian unstable (LP: #1211749, #1202027). Remaining changes:
  - 016-armhf-elf-header.patch: Use correct ELF header for armhf binaries.
  - d/control,control.cross: Update Breaks/Replaces for Ubuntu
    versions to ensure smooth upgrades, regenerate control file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
63
63
        BinaryFunc      func(string, string) string
64
64
        VariadicFunc    func(...string) string
65
65
        VariadicFuncInt func(int, ...string) string
 
66
        NilOKFunc       func(*int) bool
66
67
        // Template to test evaluation of templates.
67
68
        Tmpl *Template
 
69
        // Unexported field; cannot be accessed by template.
 
70
        unexported int
68
71
}
69
72
 
70
73
type U struct {
125
128
        BinaryFunc:        func(a, b string) string { return fmt.Sprintf("[%s=%s]", a, b) },
126
129
        VariadicFunc:      func(s ...string) string { return fmt.Sprint("<", strings.Join(s, "+"), ">") },
127
130
        VariadicFuncInt:   func(a int, s ...string) string { return fmt.Sprint(a, "=<", strings.Join(s, "+"), ">") },
 
131
        NilOKFunc:         func(s *int) bool { return s == nil },
128
132
        Tmpl:              Must(New("x").Parse("test template")), // "x" is the value of .X
129
133
}
130
134
 
220
224
        // Trivial cases.
221
225
        {"empty", "", "", nil, true},
222
226
        {"text", "some text", "some text", nil, true},
 
227
        {"nil action", "{{nil}}", "", nil, false},
223
228
 
224
229
        // Ideal constants.
225
230
        {"ideal int", "{{typeOf 3}}", "int", 0, true},
228
233
        {"ideal complex", "{{typeOf 1i}}", "complex128", 0, true},
229
234
        {"ideal int", "{{typeOf " + bigInt + "}}", "int", 0, true},
230
235
        {"ideal too big", "{{typeOf " + bigUint + "}}", "", 0, false},
 
236
        {"ideal nil without type", "{{nil}}", "", 0, false},
231
237
 
232
238
        // Fields of structs.
233
239
        {".X", "-{{.X}}-", "-x-", tVal, true},
234
240
        {".U.V", "-{{.U.V}}-", "-v-", tVal, true},
 
241
        {".unexported", "{{.unexported}}", "", tVal, false},
235
242
 
236
243
        // Fields on maps.
237
244
        {"map .one", "{{.MSI.one}}", "1", tVal, true},
292
299
        {".Method2(3, .X)", "-{{.Method2 3 .X}}-", "-Method2: 3 x-", tVal, true},
293
300
        {".Method2(.U16, `str`)", "-{{.Method2 .U16 `str`}}-", "-Method2: 16 str-", tVal, true},
294
301
        {".Method2(.U16, $x)", "{{if $x := .X}}-{{.Method2 .U16 $x}}{{end}}-", "-Method2: 16 x-", tVal, true},
295
 
        {".Method3(nil)", "-{{.Method3 .MXI.unset}}-", "-Method3: <nil>-", tVal, true},
 
302
        {".Method3(nil constant)", "-{{.Method3 nil}}-", "-Method3: <nil>-", tVal, true},
 
303
        {".Method3(nil value)", "-{{.Method3 .MXI.unset}}-", "-Method3: <nil>-", tVal, true},
296
304
        {"method on var", "{{if $x := .}}-{{$x.Method2 .U16 $x.X}}{{end}}-", "-Method2: 16 x-", tVal, true},
297
305
        {"method on chained var",
298
306
                "{{range .MSIone}}{{if $.U.TrueFalse $.True}}{{$.U.TrueFalse $.True}}{{else}}WRONG{{end}}{{end}}",
303
311
        {"chained method on variable",
304
312
                "{{with $x := .}}{{with .SI}}{{$.GetU.TrueFalse $.True}}{{end}}{{end}}",
305
313
                "true", tVal, true},
 
314
        {".NilOKFunc not nil", "{{call .NilOKFunc .PI}}", "false", tVal, true},
 
315
        {".NilOKFunc nil", "{{call .NilOKFunc nil}}", "true", tVal, true},
306
316
 
307
317
        // Function call builtin.
308
318
        {".BinaryFunc", "{{call .BinaryFunc `1` `2`}}", "[1=2]", tVal, true},
321
331
        {".VariadicFuncBad0", "{{call .VariadicFunc 3}}", "", tVal, false},
322
332
        {".VariadicFuncIntBad0", "{{call .VariadicFuncInt}}", "", tVal, false},
323
333
        {".VariadicFuncIntBad`", "{{call .VariadicFuncInt `x`}}", "", tVal, false},
 
334
        {".VariadicFuncNilBad", "{{call .VariadicFunc nil}}", "", tVal, false},
324
335
 
325
336
        // Pipelines.
326
337
        {"pipeline", "-{{.Method0 | .Method2 .U16}}-", "-Method2: 16 M0-", tVal, true},
327
338
        {"pipeline func", "-{{call .VariadicFunc `llo` | call .VariadicFunc `he` }}-", "-<he+<llo>>-", tVal, true},
328
339
 
 
340
        // Parenthesized expressions
 
341
        {"parens in pipeline", "{{printf `%d %d %d` (1) (2 | add 3) (add 4 (add 5 6))}}", "1 5 15", tVal, true},
 
342
 
 
343
        // Parenthesized expressions with field accesses
 
344
        {"parens: $ in paren", "{{($).X}}", "x", tVal, true},
 
345
        {"parens: $.GetU in paren", "{{($.GetU).V}}", "v", tVal, true},
 
346
        {"parens: $ in paren in pipe", "{{($ | echo).X}}", "x", tVal, true},
 
347
        {"parens: spaces and args", `{{(makemap "up" "down" "left" "right").left}}`, "right", tVal, true},
 
348
 
329
349
        // If.
330
350
        {"if true", "{{if true}}TRUE{{end}}", "TRUE", tVal, true},
331
351
        {"if false", "{{if false}}TRUE{{else}}FALSE{{end}}", "FALSE", tVal, true},
 
352
        {"if nil", "{{if nil}}TRUE{{end}}", "", tVal, false},
332
353
        {"if 1", "{{if 1}}NON-ZERO{{else}}ZERO{{end}}", "NON-ZERO", tVal, true},
333
354
        {"if 0", "{{if 0}}NON-ZERO{{else}}ZERO{{end}}", "ZERO", tVal, true},
334
355
        {"if 1.5", "{{if 1.5}}NON-ZERO{{else}}ZERO{{end}}", "NON-ZERO", tVal, true},
348
369
 
349
370
        // Print etc.
350
371
        {"print", `{{print "hello, print"}}`, "hello, print", tVal, true},
351
 
        {"print", `{{print 1 2 3}}`, "1 2 3", tVal, true},
 
372
        {"print 123", `{{print 1 2 3}}`, "1 2 3", tVal, true},
 
373
        {"print nil", `{{print nil}}`, "<nil>", tVal, true},
352
374
        {"println", `{{println 1 2 3}}`, "1 2 3\n", tVal, true},
353
375
        {"printf int", `{{printf "%04x" 127}}`, "007f", tVal, true},
354
376
        {"printf float", `{{printf "%g" 3.5}}`, "3.5", tVal, true},
387
409
        {"slice[WRONG]", "{{index .SI `hello`}}", "", tVal, false},
388
410
        {"map[one]", "{{index .MSI `one`}}", "1", tVal, true},
389
411
        {"map[two]", "{{index .MSI `two`}}", "2", tVal, true},
390
 
        {"map[NO]", "{{index .MSI `XXX`}}", "", tVal, true},
 
412
        {"map[NO]", "{{index .MSI `XXX`}}", "0", tVal, true},
 
413
        {"map[nil]", "{{index .MSI nil}}", "0", tVal, true},
391
414
        {"map[WRONG]", "{{index .MSI 10}}", "", tVal, false},
392
415
        {"double index", "{{index .SMSI 1 `eleven`}}", "11", tVal, true},
393
416
 
474
497
        // Pipelined arg was not being type-checked.
475
498
        {"bug8a", "{{3|oneArg}}", "", tVal, false},
476
499
        {"bug8b", "{{4|dddArg 3}}", "", tVal, false},
 
500
        // A bug was introduced that broke map lookups for lower-case names.
 
501
        {"bug9", "{{.cause}}", "neglect", map[string]string{"cause": "neglect"}, true},
 
502
        // Field chain starting with function did not work.
 
503
        {"bug10", "{{mapOfThree.three}}-{{(mapOfThree).three}}", "3-3", 0, true},
477
504
}
478
505
 
479
506
func zeroArgs() string {
508
535
        return "vfunc"
509
536
}
510
537
 
 
538
func add(args ...int) int {
 
539
        sum := 0
 
540
        for _, x := range args {
 
541
                sum += x
 
542
        }
 
543
        return sum
 
544
}
 
545
 
 
546
func echo(arg interface{}) interface{} {
 
547
        return arg
 
548
}
 
549
 
 
550
func makemap(arg ...string) map[string]string {
 
551
        if len(arg)%2 != 0 {
 
552
                panic("bad makemap")
 
553
        }
 
554
        m := make(map[string]string)
 
555
        for i := 0; i < len(arg); i += 2 {
 
556
                m[arg[i]] = arg[i+1]
 
557
        }
 
558
        return m
 
559
}
 
560
 
511
561
func stringer(s fmt.Stringer) string {
512
562
        return s.String()
513
563
}
514
564
 
 
565
func mapOfThree() interface{} {
 
566
        return map[string]int{"three": 3}
 
567
}
 
568
 
515
569
func testExecute(execTests []execTest, template *Template, t *testing.T) {
516
570
        b := new(bytes.Buffer)
517
571
        funcs := FuncMap{
518
 
                "count":    count,
519
 
                "dddArg":   dddArg,
520
 
                "oneArg":   oneArg,
521
 
                "typeOf":   typeOf,
522
 
                "vfunc":    vfunc,
523
 
                "zeroArgs": zeroArgs,
524
 
                "stringer": stringer,
 
572
                "add":        add,
 
573
                "count":      count,
 
574
                "dddArg":     dddArg,
 
575
                "echo":       echo,
 
576
                "makemap":    makemap,
 
577
                "mapOfThree": mapOfThree,
 
578
                "oneArg":     oneArg,
 
579
                "stringer":   stringer,
 
580
                "typeOf":     typeOf,
 
581
                "vfunc":      vfunc,
 
582
                "zeroArgs":   zeroArgs,
525
583
        }
526
584
        for _, test := range execTests {
527
585
                var tmpl *Template
624
682
        }
625
683
}
626
684
 
 
685
const execErrorText = `line 1
 
686
line 2
 
687
line 3
 
688
{{template "one" .}}
 
689
{{define "one"}}{{template "two" .}}{{end}}
 
690
{{define "two"}}{{template "three" .}}{{end}}
 
691
{{define "three"}}{{index "hi" $}}{{end}}`
 
692
 
 
693
// Check that an error from a nested template contains all the relevant information.
 
694
func TestExecError(t *testing.T) {
 
695
        tmpl, err := New("top").Parse(execErrorText)
 
696
        if err != nil {
 
697
                t.Fatal("parse error:", err)
 
698
        }
 
699
        var b bytes.Buffer
 
700
        err = tmpl.Execute(&b, 5) // 5 is out of range indexing "hi"
 
701
        if err == nil {
 
702
                t.Fatal("expected error")
 
703
        }
 
704
        const want = `template: top:7:20: executing "three" at <index "hi" $>: error calling index: index out of range: 5`
 
705
        got := err.Error()
 
706
        if got != want {
 
707
                t.Errorf("expected\n%q\ngot\n%q", want, got)
 
708
        }
 
709
}
 
710
 
627
711
func TestJSEscaping(t *testing.T) {
628
712
        testCases := []struct {
629
713
                in, exp string
734
818
                t.Errorf("expected %q got %q", expect, result)
735
819
        }
736
820
}
 
821
 
 
822
func TestExecuteOnNewTemplate(t *testing.T) {
 
823
        // This is issue 3872.
 
824
        _ = New("Name").Templates()
 
825
}
 
826
 
 
827
const testTemplates = `{{define "one"}}one{{end}}{{define "two"}}two{{end}}`
 
828
 
 
829
func TestMessageForExecuteEmpty(t *testing.T) {
 
830
        // Test a truly empty template.
 
831
        tmpl := New("empty")
 
832
        var b bytes.Buffer
 
833
        err := tmpl.Execute(&b, 0)
 
834
        if err == nil {
 
835
                t.Fatal("expected initial error")
 
836
        }
 
837
        got := err.Error()
 
838
        want := `template: empty: "empty" is an incomplete or empty template`
 
839
        if got != want {
 
840
                t.Errorf("expected error %s got %s", want, got)
 
841
        }
 
842
        // Add a non-empty template to check that the error is helpful.
 
843
        tests, err := New("").Parse(testTemplates)
 
844
        if err != nil {
 
845
                t.Fatal(err)
 
846
        }
 
847
        tmpl.AddParseTree("secondary", tests.Tree)
 
848
        err = tmpl.Execute(&b, 0)
 
849
        if err == nil {
 
850
                t.Fatal("expected second error")
 
851
        }
 
852
        got = err.Error()
 
853
        want = `template: empty: "empty" is an incomplete or empty template; defined templates are: "secondary"`
 
854
        if got != want {
 
855
                t.Errorf("expected error %s got %s", want, got)
 
856
        }
 
857
        // Make sure we can execute the secondary.
 
858
        err = tmpl.ExecuteTemplate(&b, "secondary", 0)
 
859
        if err != nil {
 
860
                t.Fatal(err)
 
861
        }
 
862
}