package toml 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{`"basic s\tring"`}}, {"\"\"\"\n basic multi-line\n string value\n\"\"\"", []string{`" basic multi-line\n string value\n"`}}, {`'literal s\tring'`, []string{`"literal s\\tring"`}}, {"'''\n literal multi-line\n string value\n'''", []string{`" literal multi-line\n string value\n"`}}, } { p := newParser() testParseHandler(t, p, p.startString, test) } } func TestBasipString(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{`""`}}, {`"simple string"`, []string{`"simple string"`}}, {`"with\tsome\r\nvalid escapes\b"`, []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{`"A cool UTF8 ƃuıɹʇs"`}}, {`"A string with UTF8 escape \u2318"`, []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 := newParser() testParseHandler(t, p, p.startBasipString, test) } } func TestMultiLineBasipString(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{`""`}}, {"\"\"\"\n\"\"\"", []string{`""`}}, {"\"\"\"\r\n\r\n\"\"\"", []string{`"\n"`}}, {`"""\"\"\"\""""`, []string{`"\"\"\"\""`}}, {"\"\"\"\nThe quick brown \\\n\n\n \t fox jumps over \\\n\t the lazy dog.\\\n \"\"\"", []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{`"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 := newParser() testParseHandler(t, p, p.startMultiLineBasipString, 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{`""`}}, {`'simple'`, []string{`"simple"`}}, {`'C:\Users\nodejs\templates'`, []string{`"C:\\Users\\nodejs\\templates"`}}, {`'\\ServerX\admin$\system32\'`, []string{`"\\\\ServerX\\admin$\\system32\\"`}}, {`'Tom "Dubs" Preston-Werner'`, []string{`"Tom \"Dubs\" Preston-Werner"`}}, {`'<\i\c*\s*>'`, []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{`"Except\tfor\ttabs"`}}, {"'Invalid rune \xcd'", []string{`Error: invalid UTF8 rune at line 1, column 15`}}, } { p := newParser() 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{`""`}}, {"'''\n'''", []string{`""`}}, {`'''I [dw]on't need \d{2} apples'''`, []string{`"I [dw]on't need \\d{2} apples"`}}, {"'''\nThere can\nbe newlines\r\nand \ttabs!\r\n'''", []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 := newParser() testParseHandler(t, p, p.startMultiLineLiteralString, test) } } func TestBasipStringWithUnescapedControlCharacters(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(`"%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}}) } }