go-toml/parse/value_string_test.go

113 lines
5.7 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package parse
import (
"fmt"
"testing"
"git.makaay.nl/mauricem/go-parsekit/parse"
)
func TestStartString(t *testing.T) {
parser := newParser()
wrapper := func(p *parse.API) { parser.parseString(p) }
testParse(t, parser, wrapper, parseTest{"(not a string)", "{}", "unexpected input (expected a string value) at start of file"})
}
func TestString(t *testing.T) {
for _, test := range []parseTest{
{`x=no start quote"`, `{}`, `unexpected input (expected a value) at line 1, column 3`},
{`x="basic s\tring"`, `{"x": "basic s\tring"}`, ``},
{"x=\"\"\"\n basic multi-line\n string value\n\"\"\"", `{"x": " basic multi-line\n string value\n"}`, ``},
{`x='literal s\tring'`, `{"x": "literal s\\tring"}`, ``},
{"x='''\n literal multi-line\n string value\n'''", `{"x": " literal multi-line\n string value\n"}`, ``},
} {
p := newParser()
testParse(t, p, p.startDocument, test)
}
}
func TestBasicString(t *testing.T) {
for _, test := range []parseTest{
{`x="no end quote`, `{}`, `unexpected end of file (expected closing quotation marks) at line 1, column 16`},
{`x=""`, `{"x": ""}`, ``},
{`x="simple string"`, `{"x": "simple string"}`, ``},
{`x="with\tsome\r\nvalid escapes\b"`, `{"x": "with\tsome\r\nvalid escapes\b"}`, ``},
{`x="with an \invalid escape"`, `{}`, `invalid escape sequence at line 1, column 12`},
{`x="A cool UTF8 ƃuıɹʇs"`, `{"x": "A cool UTF8 ƃuıɹʇs"}`, ``},
{`x="A string with UTF8 escape \u2318"`, `{"x": "A string with UTF8 escape ⌘"}`, ``},
{"x=\"Invalid character for UTF \xcd\"", `{}`, `invalid UTF8 rune at line 1, column 30`},
{`x="\uD801 is not a valid rune"`, `{}`, `invalid UTF8 escape '\uD801' at line 1, column 10`},
{`x="\U00D80000 is not a valid rune"`, `{}`, `invalid UTF8 escape '\U00D80000' at line 1, column 14`},
{"x=\"Character that mus\t be escaped\"", `{}`, `invalid character in string value: '\t' (must be escaped) at line 1, column 22`},
{"x=\"Character that must be escaped \u0000\"", `{}`, `invalid character in string value: '\x00' (must be escaped) at line 1, column 35`},
{"x=\"Character that must be escaped \x7f\"", `{}`, `invalid character in string value: '\u007f' (must be escaped) at line 1, column 35`},
{`x="\b\t\n\f\r\"\\\u2318\U00002318" # all escape codes`, `{"x": "\b\t\n\f\r\"\\⌘⌘"}`, ``},
} {
p := newParser()
testParse(t, p, p.startDocument, test)
}
}
func TestMultiLineBasicString(t *testing.T) {
for _, test := range []parseTest{
{`x="""missing close quote""`, `{}`, `unexpected end of file (expected closing three quotation marks) at line 1, column 27`},
{`x=""""""`, `{"x": ""}`, ``},
{"x=\"\"\"\n\"\"\"", `{"x": ""}`, ``},
{"x=\"\"\"\r\n\r\n\"\"\"", `{"x": "\n"}`, ``},
{`x="""\"\"\"\""""`, `{"x": "\"\"\"\""}`, ``},
{"x=\"\"\"\nThe quick brown \\\r\n\r\n\n \t fox jumps over \\\n\t the lazy dog.\\\n \"\"\"", `{"x": "The quick brown fox jumps over the lazy dog."}`, ``},
{"x=\"\"\"\r\nThe quick brown \\\r\n\r\n\n \t\r\n \n\n fox jumps over \\\n\t the lazy dog.\\\n \"\"\"", `{"x": "The quick brown fox jumps over the lazy dog."}`, ``},
{"x=\"\"\"No control chars \f allowed\"\"\"", `{}`, `invalid character in multi-line basic string: '\f' (must be escaped) at line 1, column 23`},
{"x=\"\"\"Escaping control chars\\nis valid\"\"\"", `{"x": "Escaping control chars\nis valid"}`, ``},
{"x=\"\"\"Invalid escaping \\is not allowed\"\"\"", `{}`, `invalid escape sequence at line 1, column 23`},
{"x=\"\"\"Invalid rune \xcd\"\"\"", `{}`, `invalid UTF8 rune at line 1, column 19`},
} {
p := newParser()
testParse(t, p, p.startDocument, test)
}
}
func TestLiteralString(t *testing.T) {
for _, test := range []parseTest{
{`x='missing close quote`, `{}`, `unexpected end of file (expected closing single quote) at line 1, column 23`},
{`x=''`, `{"x": ""}`, ``},
{`x='simple'`, `{"x": "simple"}`, ``},
{`x='C:\Users\nodejs\templates'`, `{"x": "C:\\Users\\nodejs\\templates"}`, ``},
{`x='\\ServerX\admin$\system32\'`, `{"x": "\\\\ServerX\\admin$\\system32\\"}`, ``},
{`x='Tom "Dubs" Preston-Werner'`, `{"x": "Tom \"Dubs\" Preston-Werner"}`, ``},
{`x='<\i\c*\s*>'`, `{"x": "<\\i\\c*\\s*>"}`, ``},
{"x='No cont\rol chars allowed'", `{}`, `invalid character in string value: '\r' (no control chars allowed, except for tab) at line 1, column 11`},
{"x='Except\tfor\ttabs'", `{"x": "Except\tfor\ttabs"}`, ``},
{"x='Invalid rune \xcd'", `{}`, `invalid UTF8 rune at line 1, column 17`},
} {
p := newParser()
testParse(t, p, p.startDocument, test)
}
}
func TestMultiLineLiteralString(t *testing.T) {
for _, test := range []parseTest{
{`x='''missing close quote''`, `{}`, `unexpected end of file (expected closing three single quotes) at line 1, column 27`},
{`x=''''''`, `{"x": ""}`, ``},
{"x='''\n'''", `{"x": ""}`, ``},
{`x='''I [dw]on't need \d{2} apples'''`, `{"x": "I [dw]on't need \\d{2} apples"}`, ``},
{"x='''\nThere can\nbe newlines\r\nand \ttabs!\r\n'''", `{"x": "There can\nbe newlines\nand \ttabs!\n"}`, ``},
{"x='''No other \f control characters'''", `{}`, `invalid character in literal string: '\f' (no control chars allowed, except for tab and newline) at line 1, column 15`},
{"x='''No invalid runes allowed \xcd'''", `{}`, `invalid UTF8 rune at line 1, column 31`},
} {
p := newParser()
testParse(t, p, p.startDocument, 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 := newParser()
input := fmt.Sprintf(`x="%c"`, rune(i))
expected := fmt.Sprintf(`invalid character in string value: %q (must be escaped) at line 1, column 4`, rune(i))
testParse(t, p, p.startDocument, parseTest{input, "{}", expected})
}
}