107 lines
5.9 KiB
Go
107 lines
5.9 KiB
Go
package parser
|
||
|
||
import (
|
||
"fmt"
|
||
"testing"
|
||
)
|
||
|
||
func TestString(t *testing.T) {
|
||
for _, test := range []parseTest{
|
||
{``, []string{`Error: unexpected end of file (expected a string value) at start of file`}},
|
||
{`no start quote"`, []string{`Error: unexpected input (expected a string value) at start of file`}},
|
||
{`"basic s\tring"`, []string{`string("basic s\tring")`}},
|
||
{"\"\"\"\n basic multi-line\n string value\n\"\"\"", []string{`string(" basic multi-line\n string value\n")`}},
|
||
{`'literal s\tring'`, []string{`string("literal s\\tring")`}},
|
||
{"'''\n literal multi-line\n string value\n'''", []string{`string(" literal multi-line\n string value\n")`}},
|
||
} {
|
||
p := &parser{}
|
||
testParseHandler(t, p, p.startString, test)
|
||
}
|
||
}
|
||
|
||
func TestBasicString(t *testing.T) {
|
||
for _, test := range []parseTest{
|
||
{``, []string{`Error: unexpected end of file (expected opening quotation marks) at start of file`}},
|
||
{`no start quote"`, []string{`Error: unexpected input (expected opening quotation marks) at start of file`}},
|
||
{`"no end quote`, []string{`Error: unexpected end of file (expected closing quotation marks) at line 1, column 14`}},
|
||
{`""`, []string{`string("")`}},
|
||
{`"simple string"`, []string{`string("simple string")`}},
|
||
{`"with\tsome\r\nvalid escapes\b"`, []string{`string("with\tsome\r\nvalid escapes\b")`}},
|
||
{`"with an \invalid escape"`, []string{`Error: invalid escape sequence at line 1, column 10`}},
|
||
{`"A cool UTF8 ƃuıɹʇs"`, []string{`string("A cool UTF8 ƃuıɹʇs")`}},
|
||
{`"A string with UTF8 escape \u2318"`, []string{`string("A string with UTF8 escape ⌘")`}},
|
||
{"\"Invalid character for UTF \xcd\"", []string{`Error: invalid UTF8 rune at line 1, column 28`}},
|
||
{"\"Character that mus\t be escaped\"", []string{`Error: invalid character in basic string: '\t' (must be escaped) at line 1, column 20`}},
|
||
{"\"Character that must be escaped \u0000\"", []string{`Error: invalid character in basic string: '\x00' (must be escaped) at line 1, column 33`}},
|
||
{"\"Character that must be escaped \x7f\"", []string{`Error: invalid character in basic string: '\u007f' (must be escaped) at line 1, column 33`}},
|
||
} {
|
||
p := &parser{}
|
||
testParseHandler(t, p, p.startBasicString, test)
|
||
}
|
||
}
|
||
|
||
func TestMultiLineBasicString(t *testing.T) {
|
||
for _, test := range []parseTest{
|
||
{``, []string{`Error: unexpected end of file (expected opening three quotation marks) at start of file`}},
|
||
{`"""missing close quote""`, []string{`Error: unexpected end of file (expected closing three quotation marks) at line 1, column 25`}},
|
||
{`""""""`, []string{`string("")`}},
|
||
{"\"\"\"\n\"\"\"", []string{`string("")`}},
|
||
{"\"\"\"\r\n\r\n\"\"\"", []string{`string("\n")`}},
|
||
{`"""\"\"\"\""""`, []string{`string("\"\"\"\"")`}},
|
||
{"\"\"\"\nThe quick brown \\\n\n\n \t fox jumps over \\\n\t the lazy dog.\\\n \"\"\"", []string{`string("The quick brown fox jumps over the lazy dog.")`}},
|
||
{"\"\"\"No control chars \f allowed\"\"\"", []string{`Error: invalid character in multi-line basic string: '\f' (must be escaped) at line 1, column 21`}},
|
||
{"\"\"\"Escaping control chars\\nis valid\"\"\"", []string{`string("Escaping control chars\nis valid")`}},
|
||
{"\"\"\"Invalid escaping \\is not allowed\"\"\"", []string{`Error: invalid escape sequence at line 1, column 21`}},
|
||
{"\"\"\"Invalid rune \xcd\"\"\"", []string{`Error: invalid UTF8 rune at line 1, column 17`}},
|
||
} {
|
||
p := &parser{}
|
||
testParseHandler(t, p, p.startMultiLineBasicString, test)
|
||
}
|
||
}
|
||
|
||
func TestLiteralString(t *testing.T) {
|
||
for _, test := range []parseTest{
|
||
{``, []string{`Error: unexpected end of file (expected opening single quote) at start of file`}},
|
||
{`'missing close quote`, []string{`Error: unexpected end of file (expected closing single quote) at line 1, column 21`}},
|
||
{`''`, []string{`string("")`}},
|
||
{`'simple'`, []string{`string("simple")`}},
|
||
{`'C:\Users\nodejs\templates'`, []string{`string("C:\\Users\\nodejs\\templates")`}},
|
||
{`'\\ServerX\admin$\system32\'`, []string{`string("\\\\ServerX\\admin$\\system32\\")`}},
|
||
{`'Tom "Dubs" Preston-Werner'`, []string{`string("Tom \"Dubs\" Preston-Werner")`}},
|
||
{`'<\i\c*\s*>'`, []string{`string("<\\i\\c*\\s*>")`}},
|
||
{"'No cont\rol chars allowed'", []string{`Error: invalid character in literal string: '\r' (no control chars allowed, except for tab) at line 1, column 9`}},
|
||
{"'Except\tfor\ttabs'", []string{`string("Except\tfor\ttabs")`}},
|
||
{"'Invalid rune \xcd'", []string{`Error: invalid UTF8 rune at line 1, column 15`}},
|
||
} {
|
||
p := &parser{}
|
||
testParseHandler(t, p, p.startLiteralString, test)
|
||
}
|
||
}
|
||
|
||
func TestMultiLineLiteralString(t *testing.T) {
|
||
for _, test := range []parseTest{
|
||
{``, []string{`Error: unexpected end of file (expected opening three single quotes) at start of file`}},
|
||
{`'''missing close quote''`, []string{`Error: unexpected end of file (expected closing three single quotes) at line 1, column 25`}},
|
||
{`''''''`, []string{`string("")`}},
|
||
{"'''\n'''", []string{`string("")`}},
|
||
{`'''I [dw]on't need \d{2} apples'''`, []string{`string("I [dw]on't need \\d{2} apples")`}},
|
||
{"'''\nThere can\nbe newlines\r\nand \ttabs!\r\n'''", []string{`string("There can\nbe newlines\nand \ttabs!\n")`}},
|
||
{"'''No other \f control characters'''", []string{`Error: invalid character in literal string: '\f' (no control chars allowed, except for tab and newline) at line 1, column 13`}},
|
||
{"'''No invalid runes allowed \xcd'''", []string{"Error: invalid UTF8 rune at line 1, column 29"}},
|
||
} {
|
||
p := &parser{}
|
||
testParseHandler(t, p, p.startMultiLineLiteralString, test)
|
||
}
|
||
}
|
||
|
||
func TestBasicStringWithUnescapedControlCharacters(t *testing.T) {
|
||
// A quick check for almost all characters that must be escaped.
|
||
// The missing one (\x7f) is covered in the previous test.
|
||
for i := 0x00; i <= 0x1F; i++ {
|
||
p := &parser{}
|
||
input := fmt.Sprintf(`"%c"`, rune(i))
|
||
expected := fmt.Sprintf(`Error: invalid character in basic string: %q (must be escaped) at line 1, column 2`, rune(i))
|
||
testParseHandler(t, p, p.startString, parseTest{input, []string{expected}})
|
||
}
|
||
}
|