mirror of
https://github.com/larksuite/cli.git
synced 2026-07-06 00:06:28 +08:00
163 lines
3.6 KiB
Go
163 lines
3.6 KiB
Go
// Copyright (c) 2026 Lark Technologies Pte. Ltd.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package output
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
func TestFlattenObjectSimple(t *testing.T) {
|
|
obj := map[string]interface{}{
|
|
"name": "Alice",
|
|
"age": float64(30),
|
|
}
|
|
entries := flattenObject(obj, "", 0)
|
|
m := rowMap(entries)
|
|
|
|
if m["name"] != "Alice" {
|
|
t.Errorf("name = %q, want %q", m["name"], "Alice")
|
|
}
|
|
if m["age"] != "30" {
|
|
t.Errorf("age = %q, want %q", m["age"], "30")
|
|
}
|
|
}
|
|
|
|
func TestFlattenObjectNested(t *testing.T) {
|
|
obj := map[string]interface{}{
|
|
"user": map[string]interface{}{
|
|
"name": "Alice",
|
|
"addr": map[string]interface{}{
|
|
"city": "Beijing",
|
|
},
|
|
},
|
|
}
|
|
entries := flattenObject(obj, "", 0)
|
|
m := rowMap(entries)
|
|
|
|
if m["user.name"] != "Alice" {
|
|
t.Errorf("user.name = %q, want %q", m["user.name"], "Alice")
|
|
}
|
|
if m["user.addr.city"] != "Beijing" {
|
|
t.Errorf("user.addr.city = %q, want %q", m["user.addr.city"], "Beijing")
|
|
}
|
|
}
|
|
|
|
func TestFlattenObjectDeepLimit(t *testing.T) {
|
|
// Create depth=4 nesting — should serialize the innermost object as JSON
|
|
obj := map[string]interface{}{
|
|
"a": map[string]interface{}{
|
|
"b": map[string]interface{}{
|
|
"c": map[string]interface{}{
|
|
"d": "deep",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
entries := flattenObject(obj, "", 0)
|
|
m := rowMap(entries)
|
|
|
|
// depth 0 → a (map), depth 1 → b (map), depth 2 → c (map), depth 3 ≥ maxFlattenDepth → serialize
|
|
if v, ok := m["a.b.c"]; !ok {
|
|
t.Errorf("expected key a.b.c, got keys: %v", m)
|
|
} else if v != `{"d":"deep"}` {
|
|
t.Errorf("a.b.c = %q, want JSON string", v)
|
|
}
|
|
}
|
|
|
|
func TestFlattenObjectArrayLeaf(t *testing.T) {
|
|
obj := map[string]interface{}{
|
|
"tags": []interface{}{"a", "b"},
|
|
}
|
|
entries := flattenObject(obj, "", 0)
|
|
m := rowMap(entries)
|
|
|
|
if m["tags"] != `["a","b"]` {
|
|
t.Errorf("tags = %q, want %q", m["tags"], `["a","b"]`)
|
|
}
|
|
}
|
|
|
|
func TestFlattenObjectNilValue(t *testing.T) {
|
|
obj := map[string]interface{}{
|
|
"empty": nil,
|
|
}
|
|
entries := flattenObject(obj, "", 0)
|
|
m := rowMap(entries)
|
|
|
|
if m["empty"] != "" {
|
|
t.Errorf("empty = %q, want %q", m["empty"], "")
|
|
}
|
|
}
|
|
|
|
func TestCollectColumns(t *testing.T) {
|
|
rows := [][]flatEntry{
|
|
{{Key: "a", Value: "1"}, {Key: "b", Value: "2"}},
|
|
{{Key: "b", Value: "3"}, {Key: "c", Value: "4"}},
|
|
}
|
|
cols := collectColumns(rows)
|
|
|
|
// Should contain a, b, c (union)
|
|
colSet := map[string]bool{}
|
|
for _, c := range cols {
|
|
colSet[c] = true
|
|
}
|
|
for _, expected := range []string{"a", "b", "c"} {
|
|
if !colSet[expected] {
|
|
t.Errorf("missing column %q in %v", expected, cols)
|
|
}
|
|
}
|
|
if len(cols) != 3 {
|
|
t.Errorf("got %d columns, want 3", len(cols))
|
|
}
|
|
}
|
|
|
|
func TestTruncateToWidth(t *testing.T) {
|
|
tests := []struct {
|
|
input string
|
|
maxWidth int
|
|
want string
|
|
}{
|
|
{"hello", 10, "hello"},
|
|
{"hello", 5, "hello"},
|
|
{"hello", 4, "hell…"},
|
|
{"hello", 3, "hel…"},
|
|
{"hello", 1, "h…"},
|
|
{"hello", 0, ""},
|
|
// CJK: each char is width 2
|
|
{"你好世界", 8, "你好世界"},
|
|
{"你好世界", 6, "你好世…"},
|
|
{"你好世界", 4, "你好…"},
|
|
{"你好世界", 3, "你…"},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.input, func(t *testing.T) {
|
|
got := truncateToWidth(tt.input, tt.maxWidth)
|
|
if got != tt.want {
|
|
t.Errorf("truncateToWidth(%q, %d) = %q, want %q", tt.input, tt.maxWidth, got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestStringWidth(t *testing.T) {
|
|
tests := []struct {
|
|
input string
|
|
want int
|
|
}{
|
|
{"hello", 5},
|
|
{"你好", 4},
|
|
{"ab你好cd", 8},
|
|
{"", 0},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.input, func(t *testing.T) {
|
|
got := stringWidth(tt.input)
|
|
if got != tt.want {
|
|
t.Errorf("stringWidth(%q) = %d, want %d", tt.input, got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|