feat(encode): add the InlineTables option
Assisted-by: DeepSeek V4.1 Flash
This commit is contained in:
+127
@@ -1673,3 +1673,130 @@ func TestMarshalNestedInlineTableBreaksIndependently(t *testing.T) {
|
||||
t.Errorf("output mismatch:\ngot: %q\nwant: %q", out, want)
|
||||
}
|
||||
}
|
||||
|
||||
type inlineTLS struct {
|
||||
On bool `toml:"on"`
|
||||
}
|
||||
|
||||
type inlineServer struct {
|
||||
Host string `toml:"host"`
|
||||
Port int `toml:"port"`
|
||||
TLS inlineTLS `toml:"tls"`
|
||||
}
|
||||
|
||||
type inlineBig struct {
|
||||
A int `toml:"a"`
|
||||
B int `toml:"b"`
|
||||
C int `toml:"c"`
|
||||
}
|
||||
|
||||
func TestEncoderInlineTables(t *testing.T) {
|
||||
type Cfg struct {
|
||||
Server inlineServer `toml:"server"`
|
||||
Big inlineBig `toml:"big"`
|
||||
}
|
||||
cfg := Cfg{Server: inlineServer{Host: "127.0.0.1", Port: 9090}, Big: inlineBig{A: 1, B: 2, C: 3}}
|
||||
|
||||
// The default keeps every sub-table a header section.
|
||||
headerForm, err := Marshal(cfg)
|
||||
if err != nil {
|
||||
t.Fatalf("marshal: %v", err)
|
||||
}
|
||||
want := "[server]\nhost = \"127.0.0.1\"\nport = 9090\n\n[server.tls]\non = false\n\n[big]\na = 1\nb = 2\nc = 3\n"
|
||||
if string(headerForm) != want {
|
||||
t.Errorf("default output mismatch:\ngot: %q\nwant: %q", headerForm, want)
|
||||
}
|
||||
|
||||
// With the option both fit the threshold and become inline tables, nested
|
||||
// ones included.
|
||||
out, err := NewEncoder().InlineTables(60).Marshal(cfg)
|
||||
if err != nil {
|
||||
t.Fatalf("marshal: %v", err)
|
||||
}
|
||||
want = "server = {host = \"127.0.0.1\", port = 9090, tls = {on = false}}\nbig = {a = 1, b = 2, c = 3}\n"
|
||||
if string(out) != want {
|
||||
t.Errorf("compact output mismatch:\ngot: %q\nwant: %q", out, want)
|
||||
}
|
||||
|
||||
// A threshold below the rendering keeps the header form.
|
||||
out, err = NewEncoder().InlineTables(10).Marshal(cfg)
|
||||
if err != nil {
|
||||
t.Fatalf("marshal: %v", err)
|
||||
}
|
||||
if string(out) != string(headerForm) {
|
||||
t.Errorf("small threshold output mismatch:\ngot: %q\nwant: %q", out, headerForm)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncoderInlineTablesOrderAndRoundTrip(t *testing.T) {
|
||||
// An inlined sub-table is a value line, so it precedes every header of the
|
||||
// document; written after a header it would be read back as part of that
|
||||
// table. The compact form and the header form parse to the same tree.
|
||||
type Four struct {
|
||||
A int `toml:"a"`
|
||||
B int `toml:"b"`
|
||||
C int `toml:"c"`
|
||||
D int `toml:"d"`
|
||||
}
|
||||
type Cfg struct {
|
||||
Small inlineTLS `toml:"small"`
|
||||
Big Four `toml:"big"`
|
||||
}
|
||||
cfg := Cfg{Small: inlineTLS{On: true}, Big: Four{A: 1, B: 2, C: 3, D: 4}}
|
||||
|
||||
headerForm, err := Marshal(cfg)
|
||||
if err != nil {
|
||||
t.Fatalf("marshal: %v", err)
|
||||
}
|
||||
compact, err := NewEncoder().InlineTables(20).Marshal(cfg)
|
||||
if err != nil {
|
||||
t.Fatalf("marshal: %v", err)
|
||||
}
|
||||
want := "small = {on = true}\n\n[big]\na = 1\nb = 2\nc = 3\nd = 4\n"
|
||||
if string(compact) != want {
|
||||
t.Errorf("output mismatch:\ngot: %q\nwant: %q", compact, want)
|
||||
}
|
||||
|
||||
got, err := Parse(compact)
|
||||
if err != nil {
|
||||
t.Fatalf("parse of the compact output: %v", err)
|
||||
}
|
||||
ref, err := Parse(headerForm)
|
||||
if err != nil {
|
||||
t.Fatalf("parse of the header output: %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(got, ref) {
|
||||
t.Errorf("the compact form changed the tree:\ncompact: %#v\nheaders: %#v", got, ref)
|
||||
}
|
||||
if _, ok := got["big"].(map[string]any); !ok {
|
||||
t.Errorf("big = %#v, want a table", got["big"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncoderInlineTablesKeepsArraysOfTables(t *testing.T) {
|
||||
// An array of tables has no inline form that keeps the value's type, so the
|
||||
// option leaves it alone and the tree keeps its []map[string]any shape.
|
||||
type Item struct {
|
||||
N int `toml:"n"`
|
||||
}
|
||||
type Cfg struct {
|
||||
Items []Item `toml:"items"`
|
||||
Small inlineTLS `toml:"small"`
|
||||
}
|
||||
cfg := Cfg{Items: []Item{{N: 1}}, Small: inlineTLS{On: true}}
|
||||
out, err := NewEncoder().InlineTables(60).Marshal(cfg)
|
||||
if err != nil {
|
||||
t.Fatalf("marshal: %v", err)
|
||||
}
|
||||
want := "small = {on = true}\n\n[[items]]\nn = 1\n"
|
||||
if string(out) != want {
|
||||
t.Errorf("output mismatch:\ngot: %q\nwant: %q", out, want)
|
||||
}
|
||||
tree, err := Parse(out)
|
||||
if err != nil {
|
||||
t.Fatalf("parse: %v", err)
|
||||
}
|
||||
if _, ok := tree["items"].([]map[string]any); !ok {
|
||||
t.Errorf("items = %#v, want []map[string]any", tree["items"])
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user