mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-05-16 09:57:38 +08:00
- 新增变更预览能力,支持在提交前查看删除、更新和新增对应的 SQL 语句 - 增加表格密度配置,统一控制默认列宽、行高、字号与单元格内边距 - 优化 DataGrid 编辑状态展示,区分新增、修改和删除行列的视觉反馈 - 调整导出入口与 Wails 前端绑定,补齐变更预览相关调用与测试覆盖
114 lines
3.3 KiB
Go
114 lines
3.3 KiB
Go
package db
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"GoNavi-Wails/internal/connection"
|
|
)
|
|
|
|
func TestGenerateChangePreview_Inserts(t *testing.T) {
|
|
changes := connection.ChangeSet{
|
|
Inserts: []map[string]interface{}{
|
|
{"name": "alice", "age": float64(30)},
|
|
{"name": "bob", "age": nil},
|
|
},
|
|
}
|
|
deletes, updates, inserts := GenerateChangePreview("users", changes, mysqlQuote)
|
|
if len(inserts) != 2 {
|
|
t.Fatalf("expected 2 inserts, got %d", len(inserts))
|
|
}
|
|
expected1 := "INSERT INTO `users` (`age`, `name`) VALUES (30, 'alice');"
|
|
expected2 := "INSERT INTO `users` (`name`) VALUES ('bob');"
|
|
if inserts[0] != expected1 {
|
|
t.Errorf("insert[0]: got %s\nwant %s", inserts[0], expected1)
|
|
}
|
|
if inserts[1] != expected2 {
|
|
t.Errorf("insert[1]: got %s\nwant %s", inserts[1], expected2)
|
|
}
|
|
if len(deletes) != 0 || len(updates) != 0 {
|
|
t.Errorf("expected empty deletes/updates")
|
|
}
|
|
}
|
|
|
|
func TestGenerateChangePreview_Deletes(t *testing.T) {
|
|
changes := connection.ChangeSet{
|
|
Deletes: []map[string]interface{}{
|
|
{"id": float64(1), "name": "alice"},
|
|
{"id": float64(2)},
|
|
},
|
|
}
|
|
deletes, updates, inserts := GenerateChangePreview("users", changes, mysqlQuote)
|
|
if len(deletes) != 2 {
|
|
t.Fatalf("expected 2 deletes, got %d", len(deletes))
|
|
}
|
|
expected1 := "DELETE FROM `users` WHERE `id` = 1 AND `name` = 'alice';"
|
|
if deletes[0] != expected1 {
|
|
t.Errorf("delete[0]: got %s\nwant %s", deletes[0], expected1)
|
|
}
|
|
if len(updates) != 0 || len(inserts) != 0 {
|
|
t.Errorf("expected empty updates/inserts")
|
|
}
|
|
}
|
|
|
|
func TestGenerateChangePreview_Updates(t *testing.T) {
|
|
changes := connection.ChangeSet{
|
|
Updates: []connection.UpdateRow{
|
|
{
|
|
Keys: map[string]interface{}{"id": float64(1)},
|
|
Values: map[string]interface{}{"name": "charlie", "age": float64(25)},
|
|
},
|
|
},
|
|
}
|
|
deletes, updates, inserts := GenerateChangePreview("users", changes, mysqlQuote)
|
|
if len(updates) != 1 {
|
|
t.Fatalf("expected 1 update, got %d", len(updates))
|
|
}
|
|
// SET clause column order is map-iteration-based, so check substring presence
|
|
if !strings.Contains(updates[0], "UPDATE `users` SET") {
|
|
t.Errorf("update: missing UPDATE clause: %s", updates[0])
|
|
}
|
|
if !strings.Contains(updates[0], "WHERE `id` = 1") {
|
|
t.Errorf("update: missing WHERE clause: %s", updates[0])
|
|
}
|
|
if !strings.Contains(updates[0], "`name` = 'charlie'") {
|
|
t.Errorf("update: missing name set: %s", updates[0])
|
|
}
|
|
if !strings.Contains(updates[0], "`age` = 25") {
|
|
t.Errorf("update: missing age set: %s", updates[0])
|
|
}
|
|
if len(deletes) != 0 || len(inserts) != 0 {
|
|
t.Errorf("expected empty deletes/inserts")
|
|
}
|
|
}
|
|
|
|
func TestGenerateChangePreview_EmptyChanges(t *testing.T) {
|
|
deletes, updates, inserts := GenerateChangePreview("t", connection.ChangeSet{}, mysqlQuote)
|
|
if len(deletes) != 0 || len(updates) != 0 || len(inserts) != 0 {
|
|
t.Error("expected all empty for empty changeset")
|
|
}
|
|
}
|
|
|
|
func TestFormatLiteral(t *testing.T) {
|
|
cases := []struct {
|
|
val interface{}
|
|
expected string
|
|
}{
|
|
{nil, "NULL"},
|
|
{"hello", "'hello'"},
|
|
{"it's a test", "'it\\'s a test'"},
|
|
{float64(42), "42"},
|
|
{int64(-1), "-1"},
|
|
{true, "TRUE"},
|
|
{false, "FALSE"},
|
|
}
|
|
for _, c := range cases {
|
|
got := formatLiteral(c.val)
|
|
if got != c.expected {
|
|
t.Errorf("formatLiteral(%v): got %s, want %s", c.val, got, c.expected)
|
|
}
|
|
}
|
|
}
|
|
|
|
func mysqlQuote(s string) string { return "`" + s + "`" }
|