diff options
Diffstat (limited to 'libgo/go/template/template_test.go')
-rw-r--r-- | libgo/go/template/template_test.go | 763 |
1 files changed, 0 insertions, 763 deletions
diff --git a/libgo/go/template/template_test.go b/libgo/go/template/template_test.go deleted file mode 100644 index d21a539..0000000 --- a/libgo/go/template/template_test.go +++ /dev/null @@ -1,763 +0,0 @@ -// 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 template - -import ( - "bytes" - "container/vector" - "fmt" - "io" - "io/ioutil" - "json" - "os" - "strings" - "testing" -) - -type Test struct { - in, out, err string -} - -type T struct { - Item string - Value string -} - -type U struct { - Mp map[string]int -} - -type S struct { - Header string - HeaderPtr *string - Integer int - IntegerPtr *int - NilPtr *int - InnerT T - InnerPointerT *T - Data []T - Pdata []*T - Empty []*T - Emptystring string - Null []*T - Vec *vector.Vector - True bool - False bool - Mp map[string]string - JSON interface{} - Innermap U - Stringmap map[string]string - Ptrmap map[string]*string - Iface interface{} - Ifaceptr interface{} -} - -func (s *S) PointerMethod() string { return "ptrmethod!" } - -func (s S) ValueMethod() string { return "valmethod!" } - -var t1 = T{"ItemNumber1", "ValueNumber1"} -var t2 = T{"ItemNumber2", "ValueNumber2"} - -func uppercase(v interface{}) string { - s := v.(string) - t := "" - for i := 0; i < len(s); i++ { - c := s[i] - if 'a' <= c && c <= 'z' { - c = c + 'A' - 'a' - } - t += string(c) - } - return t -} - -func plus1(v interface{}) string { - i := v.(int) - return fmt.Sprint(i + 1) -} - -func writer(f func(interface{}) string) func(io.Writer, string, ...interface{}) { - return func(w io.Writer, format string, v ...interface{}) { - if len(v) != 1 { - panic("test writer expected one arg") - } - io.WriteString(w, f(v[0])) - } -} - -func multiword(w io.Writer, format string, value ...interface{}) { - for _, v := range value { - fmt.Fprintf(w, "<%v>", v) - } -} - -var formatters = FormatterMap{ - "uppercase": writer(uppercase), - "+1": writer(plus1), - "multiword": multiword, -} - -var tests = []*Test{ - // Simple - &Test{"", "", ""}, - &Test{"abc", "abc", ""}, - &Test{"abc\ndef\n", "abc\ndef\n", ""}, - &Test{" {.meta-left} \n", "{", ""}, - &Test{" {.meta-right} \n", "}", ""}, - &Test{" {.space} \n", " ", ""}, - &Test{" {.tab} \n", "\t", ""}, - &Test{" {#comment} \n", "", ""}, - &Test{"\tSome Text\t\n", "\tSome Text\t\n", ""}, - &Test{" {.meta-right} {.meta-right} {.meta-right} \n", " } } } \n", ""}, - - // Variables at top level - &Test{ - in: "{Header}={Integer}\n", - - out: "Header=77\n", - }, - - &Test{ - in: "Pointers: {*HeaderPtr}={*IntegerPtr}\n", - - out: "Pointers: Header=77\n", - }, - - &Test{ - in: "Stars but not pointers: {*Header}={*Integer}\n", - - out: "Stars but not pointers: Header=77\n", - }, - - &Test{ - in: "nil pointer: {*NilPtr}={*Integer}\n", - - out: "nil pointer: <nil>=77\n", - }, - - // Method at top level - &Test{ - in: "ptrmethod={PointerMethod}\n", - - out: "ptrmethod=ptrmethod!\n", - }, - - &Test{ - in: "valmethod={ValueMethod}\n", - - out: "valmethod=valmethod!\n", - }, - - // Section - &Test{ - in: "{.section Data }\n" + - "some text for the section\n" + - "{.end}\n", - - out: "some text for the section\n", - }, - &Test{ - in: "{.section Data }\n" + - "{Header}={Integer}\n" + - "{.end}\n", - - out: "Header=77\n", - }, - &Test{ - in: "{.section Pdata }\n" + - "{Header}={Integer}\n" + - "{.end}\n", - - out: "Header=77\n", - }, - &Test{ - in: "{.section Pdata }\n" + - "data present\n" + - "{.or}\n" + - "data not present\n" + - "{.end}\n", - - out: "data present\n", - }, - &Test{ - in: "{.section Empty }\n" + - "data present\n" + - "{.or}\n" + - "data not present\n" + - "{.end}\n", - - out: "data not present\n", - }, - &Test{ - in: "{.section Null }\n" + - "data present\n" + - "{.or}\n" + - "data not present\n" + - "{.end}\n", - - out: "data not present\n", - }, - &Test{ - in: "{.section Pdata }\n" + - "{Header}={Integer}\n" + - "{.section @ }\n" + - "{Header}={Integer}\n" + - "{.end}\n" + - "{.end}\n", - - out: "Header=77\n" + - "Header=77\n", - }, - - &Test{ - in: "{.section Data}{.end} {Header}\n", - - out: " Header\n", - }, - - &Test{ - in: "{.section Integer}{@}{.end}", - - out: "77", - }, - - - // Repeated - &Test{ - in: "{.section Pdata }\n" + - "{.repeated section @ }\n" + - "{Item}={Value}\n" + - "{.end}\n" + - "{.end}\n", - - out: "ItemNumber1=ValueNumber1\n" + - "ItemNumber2=ValueNumber2\n", - }, - &Test{ - in: "{.section Pdata }\n" + - "{.repeated section @ }\n" + - "{Item}={Value}\n" + - "{.or}\n" + - "this should not appear\n" + - "{.end}\n" + - "{.end}\n", - - out: "ItemNumber1=ValueNumber1\n" + - "ItemNumber2=ValueNumber2\n", - }, - &Test{ - in: "{.section @ }\n" + - "{.repeated section Empty }\n" + - "{Item}={Value}\n" + - "{.or}\n" + - "this should appear: empty field\n" + - "{.end}\n" + - "{.end}\n", - - out: "this should appear: empty field\n", - }, - &Test{ - in: "{.repeated section Pdata }\n" + - "{Item}\n" + - "{.alternates with}\n" + - "is\nover\nmultiple\nlines\n" + - "{.end}\n", - - out: "ItemNumber1\n" + - "is\nover\nmultiple\nlines\n" + - "ItemNumber2\n", - }, - &Test{ - in: "{.repeated section Pdata }\n" + - "{Item}\n" + - "{.alternates with}\n" + - "is\nover\nmultiple\nlines\n" + - " {.end}\n", - - out: "ItemNumber1\n" + - "is\nover\nmultiple\nlines\n" + - "ItemNumber2\n", - }, - &Test{ - in: "{.section Pdata }\n" + - "{.repeated section @ }\n" + - "{Item}={Value}\n" + - "{.alternates with}DIVIDER\n" + - "{.or}\n" + - "this should not appear\n" + - "{.end}\n" + - "{.end}\n", - - out: "ItemNumber1=ValueNumber1\n" + - "DIVIDER\n" + - "ItemNumber2=ValueNumber2\n", - }, - &Test{ - in: "{.repeated section Vec }\n" + - "{@}\n" + - "{.end}\n", - - out: "elt1\n" + - "elt2\n", - }, - // Same but with a space before {.end}: was a bug. - &Test{ - in: "{.repeated section Vec }\n" + - "{@} {.end}\n", - - out: "elt1 elt2 \n", - }, - &Test{ - in: "{.repeated section Integer}{.end}", - - err: "line 1: .repeated: cannot repeat Integer (type int)", - }, - - // Nested names - &Test{ - in: "{.section @ }\n" + - "{InnerT.Item}={InnerT.Value}\n" + - "{.end}", - - out: "ItemNumber1=ValueNumber1\n", - }, - &Test{ - in: "{.section @ }\n" + - "{InnerT.Item}={.section InnerT}{.section Value}{@}{.end}{.end}\n" + - "{.end}", - - out: "ItemNumber1=ValueNumber1\n", - }, - - &Test{ - in: "{.section Emptystring}emptystring{.end}\n" + - "{.section Header}header{.end}\n", - - out: "\nheader\n", - }, - - &Test{ - in: "{.section True}1{.or}2{.end}\n" + - "{.section False}3{.or}4{.end}\n", - - out: "1\n4\n", - }, - - // Maps - - &Test{ - in: "{Mp.mapkey}\n", - - out: "Ahoy!\n", - }, - &Test{ - in: "{Innermap.Mp.innerkey}\n", - - out: "55\n", - }, - &Test{ - in: "{.section Innermap}{.section Mp}{innerkey}{.end}{.end}\n", - - out: "55\n", - }, - &Test{ - in: "{.section JSON}{.repeated section maps}{a}{b}{.end}{.end}\n", - - out: "1234\n", - }, - &Test{ - in: "{Stringmap.stringkey1}\n", - - out: "stringresult\n", - }, - &Test{ - in: "{.repeated section Stringmap}\n" + - "{@}\n" + - "{.end}", - - out: "stringresult\n" + - "stringresult\n", - }, - &Test{ - in: "{.repeated section Stringmap}\n" + - "\t{@}\n" + - "{.end}", - - out: "\tstringresult\n" + - "\tstringresult\n", - }, - &Test{ - in: "{*Ptrmap.stringkey1}\n", - - out: "pointedToString\n", - }, - &Test{ - in: "{.repeated section Ptrmap}\n" + - "{*@}\n" + - "{.end}", - - out: "pointedToString\n" + - "pointedToString\n", - }, - - - // Interface values - - &Test{ - in: "{Iface}", - - out: "[1 2 3]", - }, - &Test{ - in: "{.repeated section Iface}{@}{.alternates with} {.end}", - - out: "1 2 3", - }, - &Test{ - in: "{.section Iface}{@}{.end}", - - out: "[1 2 3]", - }, - &Test{ - in: "{.section Ifaceptr}{Item} {Value}{.end}", - - out: "Item Value", - }, -} - -func TestAll(t *testing.T) { - // Parse - testAll(t, func(test *Test) (*Template, os.Error) { return Parse(test.in, formatters) }) - // ParseFile - testAll(t, func(test *Test) (*Template, os.Error) { - err := ioutil.WriteFile("_test/test.tmpl", []byte(test.in), 0600) - if err != nil { - t.Error("unexpected write error:", err) - return nil, err - } - return ParseFile("_test/test.tmpl", formatters) - }) - // tmpl.ParseFile - testAll(t, func(test *Test) (*Template, os.Error) { - err := ioutil.WriteFile("_test/test.tmpl", []byte(test.in), 0600) - if err != nil { - t.Error("unexpected write error:", err) - return nil, err - } - tmpl := New(formatters) - return tmpl, tmpl.ParseFile("_test/test.tmpl") - }) -} - -func testAll(t *testing.T, parseFunc func(*Test) (*Template, os.Error)) { - s := new(S) - // initialized by hand for clarity. - s.Header = "Header" - s.HeaderPtr = &s.Header - s.Integer = 77 - s.IntegerPtr = &s.Integer - s.InnerT = t1 - s.Data = []T{t1, t2} - s.Pdata = []*T{&t1, &t2} - s.Empty = []*T{} - s.Null = nil - s.Vec = new(vector.Vector) - s.Vec.Push("elt1") - s.Vec.Push("elt2") - s.True = true - s.False = false - s.Mp = make(map[string]string) - s.Mp["mapkey"] = "Ahoy!" - json.Unmarshal([]byte(`{"maps":[{"a":1,"b":2},{"a":3,"b":4}]}`), &s.JSON) - s.Innermap.Mp = make(map[string]int) - s.Innermap.Mp["innerkey"] = 55 - s.Stringmap = make(map[string]string) - s.Stringmap["stringkey1"] = "stringresult" // the same value so repeated section is order-independent - s.Stringmap["stringkey2"] = "stringresult" - s.Ptrmap = make(map[string]*string) - x := "pointedToString" - s.Ptrmap["stringkey1"] = &x // the same value so repeated section is order-independent - s.Ptrmap["stringkey2"] = &x - s.Iface = []int{1, 2, 3} - s.Ifaceptr = &T{"Item", "Value"} - - var buf bytes.Buffer - for _, test := range tests { - buf.Reset() - tmpl, err := parseFunc(test) - if err != nil { - t.Error("unexpected parse error: ", err) - continue - } - err = tmpl.Execute(&buf, s) - if test.err == "" { - if err != nil { - t.Error("unexpected execute error:", err) - } - } else { - if err == nil { - t.Errorf("expected execute error %q, got nil", test.err) - } else if err.String() != test.err { - t.Errorf("expected execute error %q, got %q", test.err, err.String()) - } - } - if buf.String() != test.out { - t.Errorf("for %q: expected %q got %q", test.in, test.out, buf.String()) - } - } -} - -func TestMapDriverType(t *testing.T) { - mp := map[string]string{"footer": "Ahoy!"} - tmpl, err := Parse("template: {footer}", nil) - if err != nil { - t.Error("unexpected parse error:", err) - } - var b bytes.Buffer - err = tmpl.Execute(&b, mp) - if err != nil { - t.Error("unexpected execute error:", err) - } - s := b.String() - expect := "template: Ahoy!" - if s != expect { - t.Errorf("failed passing string as data: expected %q got %q", expect, s) - } -} - -func TestMapNoEntry(t *testing.T) { - mp := make(map[string]int) - tmpl, err := Parse("template: {notthere}!", nil) - if err != nil { - t.Error("unexpected parse error:", err) - } - var b bytes.Buffer - err = tmpl.Execute(&b, mp) - if err != nil { - t.Error("unexpected execute error:", err) - } - s := b.String() - expect := "template: 0!" - if s != expect { - t.Errorf("failed passing string as data: expected %q got %q", expect, s) - } -} - -func TestStringDriverType(t *testing.T) { - tmpl, err := Parse("template: {@}", nil) - if err != nil { - t.Error("unexpected parse error:", err) - } - var b bytes.Buffer - err = tmpl.Execute(&b, "hello") - if err != nil { - t.Error("unexpected execute error:", err) - } - s := b.String() - expect := "template: hello" - if s != expect { - t.Errorf("failed passing string as data: expected %q got %q", expect, s) - } -} - -func TestTwice(t *testing.T) { - tmpl, err := Parse("template: {@}", nil) - if err != nil { - t.Error("unexpected parse error:", err) - } - var b bytes.Buffer - err = tmpl.Execute(&b, "hello") - if err != nil { - t.Error("unexpected parse error:", err) - } - s := b.String() - expect := "template: hello" - if s != expect { - t.Errorf("failed passing string as data: expected %q got %q", expect, s) - } - err = tmpl.Execute(&b, "hello") - if err != nil { - t.Error("unexpected parse error:", err) - } - s = b.String() - expect += expect - if s != expect { - t.Errorf("failed passing string as data: expected %q got %q", expect, s) - } -} - -func TestCustomDelims(t *testing.T) { - // try various lengths. zero should catch error. - for i := 0; i < 7; i++ { - for j := 0; j < 7; j++ { - tmpl := New(nil) - // first two chars deliberately the same to test equal left and right delims - ldelim := "$!#$%^&"[0:i] - rdelim := "$*&^%$!"[0:j] - tmpl.SetDelims(ldelim, rdelim) - // if braces, this would be template: {@}{.meta-left}{.meta-right} - text := "template: " + - ldelim + "@" + rdelim + - ldelim + ".meta-left" + rdelim + - ldelim + ".meta-right" + rdelim - err := tmpl.Parse(text) - if err != nil { - if i == 0 || j == 0 { // expected - continue - } - t.Error("unexpected parse error:", err) - } else if i == 0 || j == 0 { - t.Errorf("expected parse error for empty delimiter: %d %d %q %q", i, j, ldelim, rdelim) - continue - } - var b bytes.Buffer - err = tmpl.Execute(&b, "hello") - s := b.String() - if s != "template: hello"+ldelim+rdelim { - t.Errorf("failed delim check(%q %q) %q got %q", ldelim, rdelim, text, s) - } - } - } -} - -// Test that a variable evaluates to the field itself and does not further indirection -func TestVarIndirection(t *testing.T) { - s := new(S) - // initialized by hand for clarity. - s.InnerPointerT = &t1 - - var buf bytes.Buffer - input := "{.section @}{InnerPointerT}{.end}" - tmpl, err := Parse(input, nil) - if err != nil { - t.Fatal("unexpected parse error:", err) - } - err = tmpl.Execute(&buf, s) - if err != nil { - t.Fatal("unexpected execute error:", err) - } - expect := fmt.Sprintf("%v", &t1) // output should be hex address of t1 - if buf.String() != expect { - t.Errorf("for %q: expected %q got %q", input, expect, buf.String()) - } -} - -func TestHTMLFormatterWithByte(t *testing.T) { - s := "Test string." - b := []byte(s) - var buf bytes.Buffer - HTMLFormatter(&buf, "", b) - bs := buf.String() - if bs != s { - t.Errorf("munged []byte, expected: %s got: %s", s, bs) - } -} - -type UF struct { - I int - s string -} - -func TestReferenceToUnexported(t *testing.T) { - u := &UF{3, "hello"} - var buf bytes.Buffer - input := "{.section @}{I}{s}{.end}" - tmpl, err := Parse(input, nil) - if err != nil { - t.Fatal("unexpected parse error:", err) - } - err = tmpl.Execute(&buf, u) - if err == nil { - t.Fatal("expected execute error, got none") - } - if strings.Index(err.String(), "not exported") < 0 { - t.Fatal("expected unexported error; got", err) - } -} - -var formatterTests = []Test{ - { - in: "{Header|uppercase}={Integer|+1}\n" + - "{Header|html}={Integer|str}\n", - - out: "HEADER=78\n" + - "Header=77\n", - }, - - { - in: "{Header|uppercase}={Integer Header|multiword}\n" + - "{Header|html}={Header Integer|multiword}\n" + - "{Header|html}={Header Integer}\n", - - out: "HEADER=<77><Header>\n" + - "Header=<Header><77>\n" + - "Header=Header77\n", - }, - { - in: "{Raw}\n" + - "{Raw|html}\n", - - out: "a <&> b\n" + - "a <&> b\n", - }, - { - in: "{Bytes}", - out: "hello", - }, - { - in: "{Raw|uppercase|html|html}", - out: "A &lt;&amp;&gt; B", - }, - { - in: "{Header Integer|multiword|html}", - out: "<Header><77>", - }, - { - in: "{Integer|no_formatter|html}", - err: `unknown formatter: "no_formatter"`, - }, - { - in: "{Integer|||||}", // empty string is a valid formatter - out: "77", - }, -} - -func TestFormatters(t *testing.T) { - data := map[string]interface{}{ - "Header": "Header", - "Integer": 77, - "Raw": "a <&> b", - "Bytes": []byte("hello"), - } - for _, c := range formatterTests { - tmpl, err := Parse(c.in, formatters) - if err != nil { - if c.err == "" { - t.Error("unexpected parse error:", err) - continue - } - if strings.Index(err.String(), c.err) < 0 { - t.Errorf("unexpected error: expected %q, got %q", c.err, err.String()) - continue - } - } else { - if c.err != "" { - t.Errorf("For %q, expected error, got none.", c.in) - continue - } - buf := bytes.NewBuffer(nil) - err = tmpl.Execute(buf, data) - if err != nil { - t.Error("unexpected Execute error: ", err) - continue - } - actual := buf.String() - if actual != c.out { - t.Errorf("for %q: expected %q but got %q.", c.in, c.out, actual) - } - } - } -} |