Assisted-by: GLM 5.3 Flash
This commit is contained in:
+104
-1
@@ -503,7 +503,8 @@ func TestRejectsSpecInvalid(t *testing.T) {
|
||||
"dotted over header": "[a.b]\nx = 1\n[a]\nb.y = 2\n",
|
||||
"table over array": "[[t]]\n[t]\n",
|
||||
"truncated datetime": "a = 2026-01-02T\n",
|
||||
"datetime no seconds": "a = 2026-01-02T07:32\n",
|
||||
// "datetime no seconds" moved to the acceptance tests: TOML 1.1
|
||||
// makes the seconds optional.
|
||||
}
|
||||
for name, doc := range cases {
|
||||
if _, err := Parse([]byte(doc)); err == nil {
|
||||
@@ -540,3 +541,105 @@ host = "h2"
|
||||
t.Errorf("forms[1].smtp.host = %v", h)
|
||||
}
|
||||
}
|
||||
|
||||
// --- TOML 1.1 --------------------------------------------------------------
|
||||
|
||||
func TestParseAcceptsNoSecondsDatetimes(t *testing.T) {
|
||||
tree, err := Parse([]byte(`t = 13:37
|
||||
dt = 1979-05-27T07:32
|
||||
odt1 = 1979-05-27 07:32Z
|
||||
odt2 = 1979-05-27 07:32-07:00
|
||||
`))
|
||||
if err != nil {
|
||||
t.Fatalf("parse: %v", err)
|
||||
}
|
||||
if got := tree["t"].(LocalTime).String(); got != "13:37:00" {
|
||||
t.Errorf("t = %q, want %q", got, "13:37:00")
|
||||
}
|
||||
if got := tree["dt"].(LocalDateTime).String(); got != "1979-05-27T07:32:00" {
|
||||
t.Errorf("dt = %q, want %q", got, "1979-05-27T07:32:00")
|
||||
}
|
||||
if got := tree["odt1"].(time.Time).Format(time.RFC3339Nano); got != "1979-05-27T07:32:00Z" {
|
||||
t.Errorf("odt1 = %q", got)
|
||||
}
|
||||
if got := tree["odt2"].(time.Time).Format(time.RFC3339Nano); got != "1979-05-27T07:32:00-07:00" {
|
||||
t.Errorf("odt2 = %q", got)
|
||||
}
|
||||
// The fraction still requires the seconds it belongs to.
|
||||
if _, err := Parse([]byte("a = 07:32.5\n")); err == nil {
|
||||
t.Error("07:32.5: expected an error, got none")
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseAcceptsEscapeAndHexEscapes(t *testing.T) {
|
||||
tree, err := Parse([]byte(`esc = "\e"
|
||||
hex = "\x20\x7f\xf8"
|
||||
nul = "\x00"
|
||||
multi = """\x68\x65"""
|
||||
lit = '\x20'
|
||||
`))
|
||||
if err != nil {
|
||||
t.Fatalf("parse: %v", err)
|
||||
}
|
||||
if got := tree["esc"].(string); got != "\x1b" {
|
||||
t.Errorf("esc = %q, want the escape character", got)
|
||||
}
|
||||
if got := tree["hex"].(string); got != " \x7f\u00f8" {
|
||||
t.Errorf("hex = %q", got)
|
||||
}
|
||||
if got := tree["nul"].(string); got != "\x00" {
|
||||
t.Errorf("nul = %q", got)
|
||||
}
|
||||
if got := tree["multi"].(string); got != "he" {
|
||||
t.Errorf("multi = %q", got)
|
||||
}
|
||||
// A literal string carries the sequence verbatim.
|
||||
if got := tree["lit"].(string); got != `\x20` {
|
||||
t.Errorf("lit = %q, want the verbatim sequence", got)
|
||||
}
|
||||
// Two digits exactly; a short or non-hex escape is an error.
|
||||
for _, doc := range []string{`a = "\x4"`, `a = "\x"`, `a = "\xgg"`} {
|
||||
if _, err := Parse([]byte(doc)); err == nil {
|
||||
t.Errorf("%s: expected an error, got none", doc)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseAcceptsMultilineInlineTables(t *testing.T) {
|
||||
tree, err := Parse([]byte("tbl = {\n\thello = \"world\",\n\tarr = [1,\n\t\t2,\n\t],\n\tsub = {\n\t\tk = 1,\n\t},\n\tbare = 2}\n"))
|
||||
if err != nil {
|
||||
t.Fatalf("parse: %v", err)
|
||||
}
|
||||
tbl := tree["tbl"].(map[string]any)
|
||||
if tbl["hello"] != "world" || tbl["bare"] != int64(2) {
|
||||
t.Fatalf("tbl = %#v", tbl)
|
||||
}
|
||||
if arr := tbl["arr"].([]any); len(arr) != 2 {
|
||||
t.Errorf("arr = %#v", tbl["arr"])
|
||||
}
|
||||
if sub := tbl["sub"].(map[string]any); sub["k"] != int64(1) {
|
||||
t.Errorf("sub = %#v", tbl["sub"])
|
||||
}
|
||||
// Comments inside the table, and a trailing comma at both depths.
|
||||
tree, err = Parse([]byte("m = { # one\n\t# two\n\ta = 1, # three\n\t# four\n}\n"))
|
||||
if err != nil {
|
||||
t.Fatalf("parse with comments: %v", err)
|
||||
}
|
||||
if m := tree["m"].(map[string]any); m["a"] != int64(1) {
|
||||
t.Errorf("m = %#v", m)
|
||||
}
|
||||
// The old single-line shapes keep working, with and without the comma.
|
||||
if _, err := Parse([]byte("a = { b = 1, c = 2 }\n")); err != nil {
|
||||
t.Errorf("single line: %v", err)
|
||||
}
|
||||
// Still rejected: two commas, a missing value, and an unclosed table.
|
||||
for name, doc := range map[string]string{
|
||||
"double comma": "a = { b = 1,, c = 2 }\n",
|
||||
"missing value": "a = {\n\tb =\n}\n",
|
||||
"unterminated": "a = { b = 1,\n",
|
||||
} {
|
||||
if _, err := Parse([]byte(doc)); err == nil {
|
||||
t.Errorf("%s: expected an error, got none", name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user