OSDN Git Service

Update Go library to last weekly.
[pf3gnuchains/gcc-fork.git] / libgo / go / template / parse / lex_test.go
1 // Copyright 2011 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 parse
6
7 import (
8         "reflect"
9         "testing"
10 )
11
12 type lexTest struct {
13         name  string
14         input string
15         items []item
16 }
17
18 var (
19         tEOF      = item{itemEOF, ""}
20         tLeft     = item{itemLeftDelim, "{{"}
21         tRight    = item{itemRightDelim, "}}"}
22         tRange    = item{itemRange, "range"}
23         tPipe     = item{itemPipe, "|"}
24         tFor      = item{itemIdentifier, "for"}
25         tQuote    = item{itemString, `"abc \n\t\" "`}
26         raw       = "`" + `abc\n\t\" ` + "`"
27         tRawQuote = item{itemRawString, raw}
28 )
29
30 var lexTests = []lexTest{
31         {"empty", "", []item{tEOF}},
32         {"spaces", " \t\n", []item{{itemText, " \t\n"}, tEOF}},
33         {"text", `now is the time`, []item{{itemText, "now is the time"}, tEOF}},
34         {"text with comment", "hello-{{/* this is a comment */}}-world", []item{
35                 {itemText, "hello-"},
36                 {itemText, "-world"},
37                 tEOF,
38         }},
39         {"punctuation", "{{,@%}}", []item{
40                 tLeft,
41                 {itemChar, ","},
42                 {itemChar, "@"},
43                 {itemChar, "%"},
44                 tRight,
45                 tEOF,
46         }},
47         {"empty action", `{{}}`, []item{tLeft, tRight, tEOF}},
48         {"for", `{{for }}`, []item{tLeft, tFor, tRight, tEOF}},
49         {"quote", `{{"abc \n\t\" "}}`, []item{tLeft, tQuote, tRight, tEOF}},
50         {"raw quote", "{{" + raw + "}}", []item{tLeft, tRawQuote, tRight, tEOF}},
51         {"numbers", "{{1 02 0x14 -7.2i 1e3 +1.2e-4 4.2i 1+2i}}", []item{
52                 tLeft,
53                 {itemNumber, "1"},
54                 {itemNumber, "02"},
55                 {itemNumber, "0x14"},
56                 {itemNumber, "-7.2i"},
57                 {itemNumber, "1e3"},
58                 {itemNumber, "+1.2e-4"},
59                 {itemNumber, "4.2i"},
60                 {itemComplex, "1+2i"},
61                 tRight,
62                 tEOF,
63         }},
64         {"characters", `{{'a' '\n' '\'' '\\' '\u00FF' '\xFF' '本'}}`, []item{
65                 tLeft,
66                 {itemCharConstant, `'a'`},
67                 {itemCharConstant, `'\n'`},
68                 {itemCharConstant, `'\''`},
69                 {itemCharConstant, `'\\'`},
70                 {itemCharConstant, `'\u00FF'`},
71                 {itemCharConstant, `'\xFF'`},
72                 {itemCharConstant, `'本'`},
73                 tRight,
74                 tEOF,
75         }},
76         {"bools", "{{true false}}", []item{
77                 tLeft,
78                 {itemBool, "true"},
79                 {itemBool, "false"},
80                 tRight,
81                 tEOF,
82         }},
83         {"dot", "{{.}}", []item{
84                 tLeft,
85                 {itemDot, "."},
86                 tRight,
87                 tEOF,
88         }},
89         {"dots", "{{.x . .2 .x.y}}", []item{
90                 tLeft,
91                 {itemField, ".x"},
92                 {itemDot, "."},
93                 {itemNumber, ".2"},
94                 {itemField, ".x.y"},
95                 tRight,
96                 tEOF,
97         }},
98         {"keywords", "{{range if else end with}}", []item{
99                 tLeft,
100                 {itemRange, "range"},
101                 {itemIf, "if"},
102                 {itemElse, "else"},
103                 {itemEnd, "end"},
104                 {itemWith, "with"},
105                 tRight,
106                 tEOF,
107         }},
108         {"variables", "{{$c := printf $ $hello $23 $ $var.Field .Method}}", []item{
109                 tLeft,
110                 {itemVariable, "$c"},
111                 {itemColonEquals, ":="},
112                 {itemIdentifier, "printf"},
113                 {itemVariable, "$"},
114                 {itemVariable, "$hello"},
115                 {itemVariable, "$23"},
116                 {itemVariable, "$"},
117                 {itemVariable, "$var.Field"},
118                 {itemField, ".Method"},
119                 tRight,
120                 tEOF,
121         }},
122         {"pipeline", `intro {{echo hi 1.2 |noargs|args 1 "hi"}} outro`, []item{
123                 {itemText, "intro "},
124                 tLeft,
125                 {itemIdentifier, "echo"},
126                 {itemIdentifier, "hi"},
127                 {itemNumber, "1.2"},
128                 tPipe,
129                 {itemIdentifier, "noargs"},
130                 tPipe,
131                 {itemIdentifier, "args"},
132                 {itemNumber, "1"},
133                 {itemString, `"hi"`},
134                 tRight,
135                 {itemText, " outro"},
136                 tEOF,
137         }},
138         {"declaration", "{{$v := 3}}", []item{
139                 tLeft,
140                 {itemVariable, "$v"},
141                 {itemColonEquals, ":="},
142                 {itemNumber, "3"},
143                 tRight,
144                 tEOF,
145         }},
146         {"2 declarations", "{{$v , $w := 3}}", []item{
147                 tLeft,
148                 {itemVariable, "$v"},
149                 {itemChar, ","},
150                 {itemVariable, "$w"},
151                 {itemColonEquals, ":="},
152                 {itemNumber, "3"},
153                 tRight,
154                 tEOF,
155         }},
156         // errors
157         {"badchar", "#{{\x01}}", []item{
158                 {itemText, "#"},
159                 tLeft,
160                 {itemError, "unrecognized character in action: U+0001"},
161         }},
162         {"unclosed action", "{{\n}}", []item{
163                 tLeft,
164                 {itemError, "unclosed action"},
165         }},
166         {"EOF in action", "{{range", []item{
167                 tLeft,
168                 tRange,
169                 {itemError, "unclosed action"},
170         }},
171         {"unclosed quote", "{{\"\n\"}}", []item{
172                 tLeft,
173                 {itemError, "unterminated quoted string"},
174         }},
175         {"unclosed raw quote", "{{`xx\n`}}", []item{
176                 tLeft,
177                 {itemError, "unterminated raw quoted string"},
178         }},
179         {"unclosed char constant", "{{'\n}}", []item{
180                 tLeft,
181                 {itemError, "unterminated character constant"},
182         }},
183         {"bad number", "{{3k}}", []item{
184                 tLeft,
185                 {itemError, `bad number syntax: "3k"`},
186         }},
187
188         // Fixed bugs
189         // Many elements in an action blew the lookahead until
190         // we made lexInsideAction not loop.
191         {"long pipeline deadlock", "{{|||||}}", []item{
192                 tLeft,
193                 tPipe,
194                 tPipe,
195                 tPipe,
196                 tPipe,
197                 tPipe,
198                 tRight,
199                 tEOF,
200         }},
201 }
202
203 // collect gathers the emitted items into a slice.
204 func collect(t *lexTest, left, right string) (items []item) {
205         l := lex(t.name, t.input, left, right)
206         for {
207                 item := l.nextItem()
208                 items = append(items, item)
209                 if item.typ == itemEOF || item.typ == itemError {
210                         break
211                 }
212         }
213         return
214 }
215
216 func TestLex(t *testing.T) {
217         for _, test := range lexTests {
218                 items := collect(&test, "", "")
219                 if !reflect.DeepEqual(items, test.items) {
220                         t.Errorf("%s: got\n\t%v\nexpected\n\t%v", test.name, items, test.items)
221                 }
222         }
223 }
224
225 // Some easy cases from above, but with delimiters $$ and @@
226 var lexDelimTests = []lexTest{
227         {"punctuation", "$$,@%{{}}@@", []item{
228                 tLeftDelim,
229                 {itemChar, ","},
230                 {itemChar, "@"},
231                 {itemChar, "%"},
232                 {itemChar, "{"},
233                 {itemChar, "{"},
234                 {itemChar, "}"},
235                 {itemChar, "}"},
236                 tRightDelim,
237                 tEOF,
238         }},
239         {"empty action", `$$@@`, []item{tLeftDelim, tRightDelim, tEOF}},
240         {"for", `$$for @@`, []item{tLeftDelim, tFor, tRightDelim, tEOF}},
241         {"quote", `$$"abc \n\t\" "@@`, []item{tLeftDelim, tQuote, tRightDelim, tEOF}},
242         {"raw quote", "$$" + raw + "@@", []item{tLeftDelim, tRawQuote, tRightDelim, tEOF}},
243 }
244
245 var (
246         tLeftDelim  = item{itemLeftDelim, "$$"}
247         tRightDelim = item{itemRightDelim, "@@"}
248 )
249
250 func TestDelims(t *testing.T) {
251         for _, test := range lexDelimTests {
252                 items := collect(&test, "$$", "@@")
253                 if !reflect.DeepEqual(items, test.items) {
254                         t.Errorf("%s: got\n\t%v\nexpected\n\t%v", test.name, items, test.items)
255                 }
256         }
257 }