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.
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}
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{
39 {"punctuation", "{{,@%}}", []item{
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{
56 {itemNumber, "-7.2i"},
58 {itemNumber, "+1.2e-4"},
60 {itemComplex, "1+2i"},
64 {"characters", `{{'a' '\n' '\'' '\\' '\u00FF' '\xFF' '本'}}`, []item{
66 {itemCharConstant, `'a'`},
67 {itemCharConstant, `'\n'`},
68 {itemCharConstant, `'\''`},
69 {itemCharConstant, `'\\'`},
70 {itemCharConstant, `'\u00FF'`},
71 {itemCharConstant, `'\xFF'`},
72 {itemCharConstant, `'本'`},
76 {"bools", "{{true false}}", []item{
83 {"dot", "{{.}}", []item{
89 {"dots", "{{.x . .2 .x.y}}", []item{
98 {"keywords", "{{range if else end with}}", []item{
100 {itemRange, "range"},
108 {"variables", "{{$c := printf $ $hello $23 $ $var.Field .Method}}", []item{
110 {itemVariable, "$c"},
111 {itemColonEquals, ":="},
112 {itemIdentifier, "printf"},
114 {itemVariable, "$hello"},
115 {itemVariable, "$23"},
117 {itemVariable, "$var.Field"},
118 {itemField, ".Method"},
122 {"pipeline", `intro {{echo hi 1.2 |noargs|args 1 "hi"}} outro`, []item{
123 {itemText, "intro "},
125 {itemIdentifier, "echo"},
126 {itemIdentifier, "hi"},
129 {itemIdentifier, "noargs"},
131 {itemIdentifier, "args"},
133 {itemString, `"hi"`},
135 {itemText, " outro"},
138 {"declaration", "{{$v := 3}}", []item{
140 {itemVariable, "$v"},
141 {itemColonEquals, ":="},
146 {"2 declarations", "{{$v , $w := 3}}", []item{
148 {itemVariable, "$v"},
150 {itemVariable, "$w"},
151 {itemColonEquals, ":="},
157 {"badchar", "#{{\x01}}", []item{
160 {itemError, "unrecognized character in action: U+0001"},
162 {"unclosed action", "{{\n}}", []item{
164 {itemError, "unclosed action"},
166 {"EOF in action", "{{range", []item{
169 {itemError, "unclosed action"},
171 {"unclosed quote", "{{\"\n\"}}", []item{
173 {itemError, "unterminated quoted string"},
175 {"unclosed raw quote", "{{`xx\n`}}", []item{
177 {itemError, "unterminated raw quoted string"},
179 {"unclosed char constant", "{{'\n}}", []item{
181 {itemError, "unterminated character constant"},
183 {"bad number", "{{3k}}", []item{
185 {itemError, `bad number syntax: "3k"`},
189 // Many elements in an action blew the lookahead until
190 // we made lexInsideAction not loop.
191 {"long pipeline deadlock", "{{|||||}}", []item{
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)
208 items = append(items, item)
209 if item.typ == itemEOF || item.typ == itemError {
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)
225 // Some easy cases from above, but with delimiters $$ and @@
226 var lexDelimTests = []lexTest{
227 {"punctuation", "$$,@%{{}}@@", []item{
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}},
246 tLeftDelim = item{itemLeftDelim, "$$"}
247 tRightDelim = item{itemRightDelim, "@@"}
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)