github.com/maruel/nin@v0.0.0-20220112143044-f35891e3ce7e/lexer_test.go (about) 1 // Copyright 2011 Google Inc. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package nin 16 17 import "testing" 18 19 func newLexer(input string) lexer { 20 l := lexer{} 21 l.Start("input", []byte(input+"\x00")) 22 return l 23 } 24 25 func TestLexer_ReadVarValue(t *testing.T) { 26 lexer := newLexer("plain text $var $VaR ${x}\n") 27 eval, err := lexer.readEvalString(false) 28 if err != nil { 29 t.Fatalf("readEvalString(false) = %v; %s", eval, err) 30 } 31 // The C++ version of EvalString concatenates text to reduce the array slice. 32 // This is slower in Go in practice. 33 // Original: "[plain text ][$var][ ][$VaR][ ][$x]" 34 if got := eval.Serialize(); got != "[plain][ ][text][ ][$var][ ][$VaR][ ][$x]" { 35 t.Fatal(got) 36 } 37 } 38 39 func TestLexer_ReadEvalStringEscapes(t *testing.T) { 40 lexer := newLexer("$ $$ab c$: $\ncde\n") 41 eval, err := lexer.readEvalString(false) 42 if err != nil { 43 t.Fatalf("readEvalString(false) = %v; %s", eval, err) 44 } 45 // The C++ version of EvalString concatenates text to reduce the array slice. 46 // This is slower in Go in practice. 47 // Original: "[ $ab c: cde]" 48 if got := eval.Serialize(); got != "[ ][$][ab][ ][c][:][ ][cde]" { 49 t.Fatal(got) 50 } 51 } 52 53 func TestLexer_ReadIdent(t *testing.T) { 54 lexer := newLexer("foo baR baz_123 foo-bar") 55 if got := lexer.readIdent(); got != "foo" { 56 t.Fatal(got) 57 } 58 if got := lexer.readIdent(); got != "baR" { 59 t.Fatal(got) 60 } 61 if got := lexer.readIdent(); got != "baz_123" { 62 t.Fatal(got) 63 } 64 if got := lexer.readIdent(); got != "foo-bar" { 65 t.Fatal(got) 66 } 67 if got := lexer.readIdent(); got != "" { 68 t.Fatal(got) 69 } 70 } 71 72 func TestLexer_ReadIdentCurlies(t *testing.T) { 73 // Verify that readIdent includes dots in the name, 74 // but in an expansion $bar.dots stops at the dot. 75 lexer := newLexer("foo.dots $bar.dots ${bar.dots}\n") 76 if got := lexer.readIdent(); got != "foo.dots" { 77 t.Fatal(got) 78 } 79 eval, err := lexer.readEvalString(false) 80 if err != nil { 81 t.Fatal(err) 82 } 83 // The C++ version of EvalString concatenates text to reduce the array slice. 84 // This is slower in Go in practice. 85 // Original: "[$bar][.dots ][$bar.dots]" 86 if got := eval.Serialize(); got != "[$bar][.dots][ ][$bar.dots]" { 87 t.Fatal(got) 88 } 89 } 90 91 func TestLexer_Error(t *testing.T) { 92 lexer := newLexer("foo$\nbad $") 93 _, err := lexer.readEvalString(false) 94 if err == nil || err.Error() != "input:2: bad $-escape (literal $ must be written as $$)\nbad $\n ^ near here" { 95 t.Fatal(err) 96 } 97 } 98 99 func TestLexer_CommentEOF(t *testing.T) { 100 // Verify we don't run off the end of the string when the EOF is 101 // mid-comment. 102 lexer := newLexer("# foo") 103 token := lexer.ReadToken() 104 if ERROR != token { 105 t.Fatal(token) 106 } 107 } 108 109 func TestLexer_Tabs(t *testing.T) { 110 // Verify we print a useful error on a disallowed character. 111 lexer := newLexer(" \tfoobar") 112 token := lexer.ReadToken() 113 if INDENT != token { 114 t.Fatal() 115 } 116 token = lexer.ReadToken() 117 if ERROR != token { 118 t.Fatal() 119 } 120 if got := lexer.DescribeLastError(); got != "tabs are not allowed, use spaces" { 121 t.Fatal() 122 } 123 }