diff options
Diffstat (limited to 'caddyconfig/caddyfile/lexer_test.go')
-rw-r--r-- | caddyconfig/caddyfile/lexer_test.go | 227 |
1 files changed, 217 insertions, 10 deletions
diff --git a/caddyconfig/caddyfile/lexer_test.go b/caddyconfig/caddyfile/lexer_test.go index 30ee0f6..92acc4d 100644 --- a/caddyconfig/caddyfile/lexer_test.go +++ b/caddyconfig/caddyfile/lexer_test.go @@ -18,13 +18,13 @@ import ( "testing" ) -type lexerTestCase struct { - input []byte - expected []Token -} - func TestLexer(t *testing.T) { - testCases := []lexerTestCase{ + testCases := []struct { + input []byte + expected []Token + expectErr bool + errorMessage string + }{ { input: []byte(`host:123`), expected: []Token{ @@ -249,12 +249,219 @@ func TestLexer(t *testing.T) { {Line: 1, Text: `quotes`}, }, }, + { + input: []byte(`heredoc <<EOF +content +EOF same-line-arg + `), + expected: []Token{ + {Line: 1, Text: `heredoc`}, + {Line: 1, Text: "content"}, + {Line: 3, Text: `same-line-arg`}, + }, + }, + { + input: []byte(`heredoc <<VERY-LONG-MARKER +content +VERY-LONG-MARKER same-line-arg + `), + expected: []Token{ + {Line: 1, Text: `heredoc`}, + {Line: 1, Text: "content"}, + {Line: 3, Text: `same-line-arg`}, + }, + }, + { + input: []byte(`heredoc <<EOF +extra-newline + +EOF same-line-arg + `), + expected: []Token{ + {Line: 1, Text: `heredoc`}, + {Line: 1, Text: "extra-newline\n"}, + {Line: 4, Text: `same-line-arg`}, + }, + }, + { + input: []byte(`heredoc <<EOF + EOF same-line-arg + `), + expected: []Token{ + {Line: 1, Text: `heredoc`}, + {Line: 1, Text: ""}, + {Line: 2, Text: `same-line-arg`}, + }, + }, + { + input: []byte(`heredoc <<EOF + content + EOF same-line-arg + `), + expected: []Token{ + {Line: 1, Text: `heredoc`}, + {Line: 1, Text: "content"}, + {Line: 3, Text: `same-line-arg`}, + }, + }, + { + input: []byte(`prev-line + heredoc <<EOF + multi + line + content + EOF same-line-arg + next-line + `), + expected: []Token{ + {Line: 1, Text: `prev-line`}, + {Line: 2, Text: `heredoc`}, + {Line: 2, Text: "\tmulti\n\tline\n\tcontent"}, + {Line: 6, Text: `same-line-arg`}, + {Line: 7, Text: `next-line`}, + }, + }, + { + input: []byte(`escaped-heredoc \<< >>`), + expected: []Token{ + {Line: 1, Text: `escaped-heredoc`}, + {Line: 1, Text: `<<`}, + {Line: 1, Text: `>>`}, + }, + }, + { + input: []byte(`not-a-heredoc <EOF + content + `), + expected: []Token{ + {Line: 1, Text: `not-a-heredoc`}, + {Line: 1, Text: `<EOF`}, + {Line: 2, Text: `content`}, + }, + }, + { + input: []byte(`not-a-heredoc <<<EOF content`), + expected: []Token{ + {Line: 1, Text: `not-a-heredoc`}, + {Line: 1, Text: `<<<EOF`}, + {Line: 1, Text: `content`}, + }, + }, + { + input: []byte(`not-a-heredoc "<<" ">>"`), + expected: []Token{ + {Line: 1, Text: `not-a-heredoc`}, + {Line: 1, Text: `<<`}, + {Line: 1, Text: `>>`}, + }, + }, + { + input: []byte(`not-a-heredoc << >>`), + expected: []Token{ + {Line: 1, Text: `not-a-heredoc`}, + {Line: 1, Text: `<<`}, + {Line: 1, Text: `>>`}, + }, + }, + { + input: []byte(`not-a-heredoc <<HERE SAME LINE + content + HERE same-line-arg + `), + expected: []Token{ + {Line: 1, Text: `not-a-heredoc`}, + {Line: 1, Text: `<<HERE`}, + {Line: 1, Text: `SAME`}, + {Line: 1, Text: `LINE`}, + {Line: 2, Text: `content`}, + {Line: 3, Text: `HERE`}, + {Line: 3, Text: `same-line-arg`}, + }, + }, + { + input: []byte(`heredoc <<s + � + s + `), + expected: []Token{ + {Line: 1, Text: `heredoc`}, + {Line: 1, Text: "�"}, + }, + }, + { + input: []byte("\u000Aheredoc \u003C\u003C\u0073\u0073\u000A\u00BF\u0057\u0001\u0000\u00FF\u00FF\u00FF\u00FF\u00FF\u00FF\u00FF\u003D\u001F\u000A\u0073\u0073\u000A\u00BF\u0057\u0001\u0000\u00FF\u00FF\u00FF\u00FF\u00FF\u00FF\u00FF\u003D\u001F\u000A\u00BF\u00BF\u0057\u0001\u0000\u00FF\u00FF\u00FF\u00FF\u00FF\u00FF\u00FF\u003D\u001F"), + expected: []Token{ + { + Line: 2, + Text: "heredoc", + }, + { + Line: 2, + Text: "\u00BF\u0057\u0001\u0000\u00FF\u00FF\u00FF\u00FF\u00FF\u00FF\u00FF\u003D\u001F", + }, + { + Line: 5, + Text: "\u00BF\u0057\u0001\u0000\u00FF\u00FF\u00FF\u00FF\u00FF\u00FF\u00FF\u003D\u001F", + }, + { + Line: 6, + Text: "\u00BF\u00BF\u0057\u0001\u0000\u00FF\u00FF\u00FF\u00FF\u00FF\u00FF\u00FF\u003D\u001F", + }, + }, + }, + { + input: []byte("not-a-heredoc <<\n"), + expectErr: true, + errorMessage: "missing opening heredoc marker on line #1; must contain only alpha-numeric characters, dashes and underscores; got empty string", + }, + { + input: []byte(`heredoc <<<EOF + content + EOF same-line-arg + `), + expectErr: true, + errorMessage: "too many '<' for heredoc on line #1; only use two, for example <<END", + }, + { + input: []byte(`heredoc <<EOF + content + `), + expectErr: true, + errorMessage: "incomplete heredoc <<EOF on line #3, expected ending marker EOF", + }, + { + input: []byte(`heredoc <<EOF + content + EOF + `), + expectErr: true, + errorMessage: "mismatched leading whitespace in heredoc <<EOF on line #2 [\tcontent], expected whitespace [\t\t] to match the closing marker", + }, + { + input: []byte(`heredoc <<EOF + content + EOF + `), + expectErr: true, + errorMessage: "mismatched leading whitespace in heredoc <<EOF on line #2 [ content], expected whitespace [\t\t] to match the closing marker", + }, } for i, testCase := range testCases { actual, err := Tokenize(testCase.input, "") + if testCase.expectErr { + if err == nil { + t.Fatalf("expected error, got actual: %v", actual) + continue + } + if err.Error() != testCase.errorMessage { + t.Fatalf("expected error '%v', got: %v", testCase.errorMessage, err) + } + continue + } + if err != nil { - t.Errorf("%v", err) + t.Fatalf("%v", err) } lexerCompare(t, i, testCase.expected, actual) } @@ -262,17 +469,17 @@ func TestLexer(t *testing.T) { func lexerCompare(t *testing.T, n int, expected, actual []Token) { if len(expected) != len(actual) { - t.Errorf("Test case %d: expected %d token(s) but got %d", n, len(expected), len(actual)) + t.Fatalf("Test case %d: expected %d token(s) but got %d", n, len(expected), len(actual)) } for i := 0; i < len(actual) && i < len(expected); i++ { if actual[i].Line != expected[i].Line { - t.Errorf("Test case %d token %d ('%s'): expected line %d but was line %d", + t.Fatalf("Test case %d token %d ('%s'): expected line %d but was line %d", n, i, expected[i].Text, expected[i].Line, actual[i].Line) break } if actual[i].Text != expected[i].Text { - t.Errorf("Test case %d token %d: expected text '%s' but was '%s'", + t.Fatalf("Test case %d token %d: expected text '%s' but was '%s'", n, i, expected[i].Text, actual[i].Text) break } |