Repository: k1LoW/tbls
Pull request #410 (2023-01-20 13:23:00)

Fix test


Patch:
diff --git a/config/config.go b/config/config.go
index a639c73..afcfb7a 100644
--- a/config/config.go
+++ b/config/config.go
@@ -206,7 +206,7 @@ func Exclude(e []string) Option {
 	}
 }
 
-// IncludeLabels return Option set Config.IncludeLabels
+// IncludeLabels return Option set Config.includeLabels
 func IncludeLabels(l []string) Option {
 	return func(c *Config) error {
 		if len(l) > 0 {
@@ -226,7 +226,7 @@ func New() (*Config, error) {
 	return &c, nil
 }
 
-// Load load config with all method
+// Load config with all method
 func (c *Config) Load(configPath string, options ...Option) error {
 	if err := c.LoadConfigFile(configPath); err != nil {
 		return err
diff --git a/docker-compose.yml b/docker-compose.yml
index 0689ad2..cb8af72 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -67,6 +67,6 @@ services:
       - MONGO_INITDB_ROOT_PASSWORD=secret
       - MONGO_INITDB_DATABASE=test
     volumes:
-      - ./testdata/ddl/mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro
+      - ./testdata/ddl/mongo:/docker-entrypoint-initdb.d
     ports:
       - "27017:27017"
diff --git a/go.mod b/go.mod
index 7295bd1..8424382 100644
--- a/go.mod
+++ b/go.mod
@@ -28,6 +28,7 @@ require (
 	github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2
 	github.com/snowflakedb/gosnowflake v1.6.16
 	github.com/spf13/cobra v1.6.1
+	github.com/tenntenn/golden v0.4.0
 	github.com/xo/dburl v0.13.0
 	gitlab.com/golang-commonmark/mdurl v0.0.0-20191124015652-932350d1cb84
 	go.mongodb.org/mongo-driver v1.11.1
@@ -86,6 +87,8 @@ require (
 	github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect
 	github.com/inconshreveable/mousetrap v1.0.1 // indirect
 	github.com/jmespath/go-jmespath v0.4.0 // indirect
+	github.com/josharian/mapfs v0.0.0-20210615234106-095c008854e6 // indirect
+	github.com/josharian/txtarfs v0.0.0-20210615234325-77aca6df5bca // indirect
 	github.com/k1LoW/fontdir v0.1.0 // indirect
 	github.com/klauspost/compress v1.15.11 // indirect
 	github.com/mattn/go-colorable v0.1.13 // indirect
@@ -110,6 +113,7 @@ require (
 	golang.org/x/sys v0.4.0 // indirect
 	golang.org/x/term v0.4.0 // indirect
 	golang.org/x/text v0.6.0 // indirect
+	golang.org/x/tools v0.1.12 // indirect
 	golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
 	google.golang.org/appengine v1.6.7 // indirect
 	google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef // indirect
diff --git a/go.sum b/go.sum
index b7cfaf8..9e9f3ab 100644
--- a/go.sum
+++ b/go.sum
@@ -248,6 +248,10 @@ github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9Y
 github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
 github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
 github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
+github.com/josharian/mapfs v0.0.0-20210615234106-095c008854e6 h1:c+ctPFdISggaSNCfU1IueNBAsqetJSvMcpQlT+0OVdY=
+github.com/josharian/mapfs v0.0.0-20210615234106-095c008854e6/go.mod h1:Rv/momJI8DgrWnBZip+SgagpcgORIZQE5SERlxNb8LY=
+github.com/josharian/txtarfs v0.0.0-20210615234325-77aca6df5bca h1:a8xeK4GsWLE4LYo5VI4u1Cn7ZvT1NtXouXR3DdKLB8Q=
+github.com/josharian/txtarfs v0.0.0-20210615234325-77aca6df5bca/go.mod h1:UbC32ft9G/jG+sZI8wLbIBNIrYr7vp/yqMDa9SxVBNA=
 github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
 github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
 github.com/k1LoW/duration v1.2.0 h1:qq1gWtPh7YROFyerBufVP+ATR11mOOHDInrcC/Xe/6A=
@@ -361,6 +365,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
 github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
 github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
 github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/tenntenn/golden v0.4.0 h1:ghZvhG1A3zp3JKBBywTt4GRJ4ieCtZi6Xw20kt8fpy0=
+github.com/tenntenn/golden v0.4.0/go.mod h1:0xI/4lpoHR65AUTmd1RKR9S1Uv0JR3yR2Q1Ob2bKqQA=
 github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
 github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
 github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
@@ -376,6 +382,7 @@ github.com/xo/dburl v0.13.0 h1:kq+oD1j/m8DnJ/p6G/LQXRosVchs8q5/AszEUKkvYfo=
 github.com/xo/dburl v0.13.0/go.mod h1:K6rSPgbVqP3ZFT0RHkdg/M3M5KhLeV2MaS/ZqaLd1kA=
 github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA=
 github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
+github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 gitlab.com/golang-commonmark/mdurl v0.0.0-20191124015652-932350d1cb84 h1:qqjvoVXdWIcZCLPMlzgA7P9FZWdPGPvP/l3ef8GzV6o=
@@ -424,6 +431,7 @@ golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPI
 golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
 golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
 golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -459,6 +467,7 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
@@ -521,7 +530,9 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn
 golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
 golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
+golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
 golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/schema/schema.go b/schema/schema.go
index 698b3c7..b6d5650 100644
--- a/schema/schema.go
+++ b/schema/schema.go
@@ -167,7 +167,7 @@ func (s *Schema) FindTableByName(name string) (*Table, error) {
 	return nil, errors.Errorf("not found table '%s'", name)
 }
 
-// FindRelation ...
+// FindRelation find relation by columns and parent colums
 func (s *Schema) FindRelation(cs, pcs []*Column) (*Relation, error) {
 L:
 	for _, r := range s.Relations {


Test patch:
diff --git a/config/config_test.go b/config/config_test.go
index e049dd2..0efa8e1 100644
--- a/config/config_test.go
+++ b/config/config_test.go
@@ -10,6 +10,7 @@ import (
 	"testing"
 
 	"github.com/k1LoW/tbls/schema"
+	"github.com/tenntenn/golden"
 )
 
 func TestLoadDefault(t *testing.T) {
@@ -179,10 +180,6 @@ func TestFilterTables(t *testing.T) {
 	if err != nil {
 		t.Error(err)
 	}
-	err = c.LoadConfigFile(filepath.Join(testdataDir(), "config_test_tbls.yml"))
-	if err != nil {
-		t.Error(err)
-	}
 	tests := []struct {
 		include       []string
 		exclude       []string
@@ -222,8 +219,8 @@ func TestFilterTables(t *testing.T) {
 		{[]string{"users"}, []string{}, []string{"private"}, 0, 2, 1},
 	}
 	for i, tt := range tests {
-		t.Run(fmt.Sprintf("%d.%v%v", i, tt.include, tt.exclude), func(t *testing.T) {
-			s := newSchemaForTestFilterTables(t)
+		t.Run(fmt.Sprintf("%d.%v%v%v", i, tt.include, tt.exclude, tt.labels), func(t *testing.T) {
+			s := newTestSchemaViaJSON(t)
 			c.Include = tt.include
 			c.Exclude = tt.exclude
 			c.includeLabels = tt.labels
@@ -243,100 +240,46 @@ func TestFilterTables(t *testing.T) {
 }
 
 func TestModifySchema(t *testing.T) {
-	s := schema.Schema{
-		Name: "testschema",
-		Tables: []*schema.Table{
-			&schema.Table{
-				Name:    "users",
-				Comment: "users comment",
-				Columns: []*schema.Column{
-					&schema.Column{
-						Name: "id",
-						Type: "serial",
-					},
-					&schema.Column{
-						Name: "username",
-						Type: "text",
-					},
-				},
-				Indexes: []*schema.Index{
-					&schema.Index{
-						Name: "user_index",
-					},
-				},
-				Constraints: []*schema.Constraint{
-					&schema.Constraint{
-						Name: "PRIMARY",
-					},
-				},
-			},
-			&schema.Table{
-				Name:    "posts",
-				Comment: "posts comment",
-				Columns: []*schema.Column{
-					&schema.Column{
-						Name: "id",
-						Type: "serial",
-					},
-					&schema.Column{
-						Name: "user_id",
-						Type: "int",
-					},
-					&schema.Column{
-						Name: "title",
-						Type: "text",
-					},
-				},
-				Triggers: []*schema.Trigger{
-					&schema.Trigger{
-						Name: "update_posts_title",
-					},
-				},
-			},
-			&schema.Table{
-				Name: "migrations",
-				Columns: []*schema.Column{
-					&schema.Column{
-						Name: "id",
-						Type: "serial",
-					},
-					&schema.Column{
-						Name: "name",
-						Type: "text",
-					},
-				},
-			},
-		},
-	}
 	c, err := New()
 	if err != nil {
 		t.Error(err)
 	}
-	err = c.LoadConfigFile(filepath.Join(testdataDir(), "config_test_tbls.yml"))
-	if err != nil {
-		t.Error(err)
-	}
-	err = c.ModifySchema(&s)
-	if err != nil {
-		t.Error(err)
+	tests := []struct {
+		name      string
+		desc      string
+		labels    []string
+		comments  []AdditionalComment
+		relations []AdditionalRelation
+	}{
+		{"", "", []string{}, nil, nil},
+		{"mod_name_and_desc", "this is test schema", []string{}, nil, nil},
 	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			c.Name = tt.name
+			c.Desc = tt.desc
+			c.Labels = tt.labels
+			c.Comments = tt.comments
+			c.Relations = tt.relations
+			s := newTestSchemaViaJSON(t)
+			err = c.ModifySchema(s)
+			if err != nil {
+				t.Error(err)
+			}
 
-	if want := 1; len(s.Relations) != want {
-		t.Errorf("got %v\nwant %v", len(s.Relations), want)
-	}
-	posts, _ := s.FindTableByName("posts")
-	title, _ := posts.FindColumnByName("title")
-	if want := "post title"; title.Comment != want {
-		t.Errorf("got %v\nwant %v", title.Comment, want)
-	}
-	if want := 2; len(title.Labels) != want {
-		t.Errorf("got %v\nwant %v", len(title.Labels), want)
-	}
-	if want := 2; len(s.Tables) != want {
-		t.Errorf("got %v\nwant %v", len(s.Tables), want)
-	}
-	if want := "mydatabase"; s.Name != want {
-		t.Errorf("got %v\nwant %v", s.Name, want)
+			got, err := json.MarshalIndent(s, "", "  ")
+			if err != nil {
+				t.Error(err)
+			}
+			f := fmt.Sprintf("modify_schema_%s", tt.name)
+			if os.Getenv("UPDATE_GOLDEN") != "" {
+				golden.Update(t, testdataDir(), f, got)
+				return
+			}
+			if diff := golden.Diff(t, testdataDir(), f, got); diff != "" {
+				t.Error(diff)
+			}
+		})
 	}
 }
 
@@ -559,10 +502,10 @@ func TestCheckVersion(t *testing.T) {
 	}
 }
 
-func newSchemaForTestFilterTables(t *testing.T) *schema.Schema {
+func newTestSchemaViaJSON(t *testing.T) *schema.Schema {
 	t.Helper()
 	s := &schema.Schema{}
-	file, err := os.Open(filepath.Join(testdataDir(), "filter_tables.json"))
+	file, err := os.Open(filepath.Join(testdataDir(), "test_schema.json"))
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/testdata/ddl/mongo-init.js b/testdata/ddl/mongo/init.js
similarity index 100%
rename from testdata/ddl/mongo-init.js
rename to testdata/ddl/mongo/init.js
diff --git a/testdata/ddl/filter_tables.sql b/testdata/ddl/test_schema.sql
similarity index 82%
rename from testdata/ddl/filter_tables.sql
rename to testdata/ddl/test_schema.sql
index b53e2ad..3f7a178 100644
--- a/testdata/ddl/filter_tables.sql
+++ b/testdata/ddl/test_schema.sql
@@ -1,3 +1,4 @@
+DROP TRIGGER IF EXISTS update_posts_updated;
 DROP TABLE IF EXISTS schema_migrations;
 DROP TABLE IF EXISTS user_options;
 DROP TABLE IF EXISTS posts;
@@ -22,6 +23,7 @@ CREATE TABLE posts (
   CONSTRAINT posts_user_id_fk FOREIGN KEY(user_id) REFERENCES users(id) MATCH NONE ON UPDATE NO ACTION ON DELETE CASCADE,
   CONSTRAINT posts_category_id_fk FOREIGN KEY(category_id) REFERENCES categories(id) MATCH NONE ON UPDATE NO ACTION ON DELETE CASCADE
 );
+CREATE INDEX posts_user_id_idx ON posts(user_id);
 
 CREATE TABLE user_options (
   id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -34,3 +36,8 @@ CREATE TABLE schema_migrations (
   id INTEGER PRIMARY KEY AUTOINCREMENT,
   name TEXT NOT NULL
 );
+
+CREATE TRIGGER update_posts_updated AFTER UPDATE ON posts FOR EACH ROW
+BEGIN
+  UPDATE posts SET updated = current_timestamp WHERE id = OLD.id;
+END;
diff --git a/testdata/modify_schema_.golden b/testdata/modify_schema_.golden
new file mode 100644
index 0000000..d1af918
--- /dev/null
+++ b/testdata/modify_schema_.golden
@@ -0,0 +1,407 @@
+{
+  "name": "testdb.sqlite3",
+  "desc": "",
+  "tables": [
+    {
+      "name": "users",
+      "type": "table",
+      "comment": "users comment",
+      "columns": [
+        {
+          "name": "id",
+          "type": "INTEGER",
+          "nullable": true,
+          "default": null,
+          "comment": ""
+        },
+        {
+          "name": "username",
+          "type": "TEXT",
+          "nullable": false,
+          "default": null,
+          "comment": ""
+        }
+      ],
+      "indexes": [
+        {
+          "name": "sqlite_autoindex_users_1",
+          "def": "UNIQUE (username)",
+          "table": "users",
+          "columns": [
+            "username"
+          ],
+          "comment": ""
+        }
+      ],
+      "constraints": [
+        {
+          "name": "id",
+          "type": "PRIMARY KEY",
+          "def": "PRIMARY KEY (id)",
+          "table": "users",
+          "referenced_table": null,
+          "columns": [
+            "id"
+          ],
+          "referenced_columns": null,
+          "comment": ""
+        },
+        {
+          "name": "sqlite_autoindex_users_1",
+          "type": "UNIQUE",
+          "def": "UNIQUE (username)",
+          "table": "users",
+          "referenced_table": null,
+          "columns": [
+            "username"
+          ],
+          "referenced_columns": null,
+          "comment": ""
+        },
+        {
+          "name": "-",
+          "type": "CHECK",
+          "def": "CHECK(length(username) \u003e 4)",
+          "table": "users",
+          "referenced_table": null,
+          "columns": [
+            "username"
+          ],
+          "referenced_columns": null,
+          "comment": ""
+        }
+      ],
+      "triggers": [],
+      "def": "CREATE TABLE users (\n  id INTEGER PRIMARY KEY AUTOINCREMENT,\n  username TEXT UNIQUE NOT NULL CHECK(length(username) \u003e 4)\n)",
+      "labels": [
+        {
+          "Name": "private",
+          "Virtual": true
+        }
+      ]
+    },
+    {
+      "name": "categories",
+      "type": "table",
+      "comment": "",
+      "columns": [
+        {
+          "name": "id",
+          "type": "INTEGER",
+          "nullable": true,
+          "default": null,
+          "comment": ""
+        },
+        {
+          "name": "name",
+          "type": "TEXT",
+          "nullable": false,
+          "default": null,
+          "comment": ""
+        }
+      ],
+      "indexes": [
+        {
+          "name": "sqlite_autoindex_categories_1",
+          "def": "UNIQUE (name)",
+          "table": "categories",
+          "columns": [
+            "name"
+          ],
+          "comment": ""
+        }
+      ],
+      "constraints": [
+        {
+          "name": "id",
+          "type": "PRIMARY KEY",
+          "def": "PRIMARY KEY (id)",
+          "table": "categories",
+          "referenced_table": null,
+          "columns": [
+            "id"
+          ],
+          "referenced_columns": null,
+          "comment": ""
+        },
+        {
+          "name": "sqlite_autoindex_categories_1",
+          "type": "UNIQUE",
+          "def": "UNIQUE (name)",
+          "table": "categories",
+          "referenced_table": null,
+          "columns": [
+            "name"
+          ],
+          "referenced_columns": null,
+          "comment": ""
+        }
+      ],
+      "triggers": [],
+      "def": "CREATE TABLE categories (\n  id INTEGER PRIMARY KEY AUTOINCREMENT,\n  name TEXT UNIQUE NOT NULL\n)",
+      "labels": [
+        {
+          "Name": "public",
+          "Virtual": true
+        },
+        {
+          "Name": "option",
+          "Virtual": true
+        }
+      ]
+    },
+    {
+      "name": "posts",
+      "type": "table",
+      "comment": "",
+      "columns": [
+        {
+          "name": "id",
+          "type": "INTEGER",
+          "nullable": true,
+          "default": null,
+          "comment": ""
+        },
+        {
+          "name": "user_id",
+          "type": "INTEGER",
+          "nullable": false,
+          "default": null,
+          "comment": ""
+        },
+        {
+          "name": "category_id",
+          "type": "INTEGER",
+          "nullable": false,
+          "default": null,
+          "comment": ""
+        },
+        {
+          "name": "title",
+          "type": "TEXT",
+          "nullable": false,
+          "default": null,
+          "comment": ""
+        }
+      ],
+      "indexes": [
+        {
+          "name": "posts_user_id_idx",
+          "def": "CREATE INDEX posts_user_id_idx ON posts(user_id)",
+          "table": "posts",
+          "columns": [
+            "user_id"
+          ],
+          "comment": ""
+        }
+      ],
+      "constraints": [
+        {
+          "name": "id",
+          "type": "PRIMARY KEY",
+          "def": "PRIMARY KEY (id)",
+          "table": "posts",
+          "referenced_table": null,
+          "columns": [
+            "id"
+          ],
+          "referenced_columns": null,
+          "comment": ""
+        },
+        {
+          "name": "- (Foreign key ID: 0)",
+          "type": "FOREIGN KEY",
+          "def": "FOREIGN KEY (category_id) REFERENCES categories (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE",
+          "table": "posts",
+          "referenced_table": "categories",
+          "columns": [
+            "category_id"
+          ],
+          "referenced_columns": [
+            "id"
+          ],
+          "comment": ""
+        },
+        {
+          "name": "- (Foreign key ID: 1)",
+          "type": "FOREIGN KEY",
+          "def": "FOREIGN KEY (user_id) REFERENCES users (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE",
+          "table": "posts",
+          "referenced_table": "users",
+          "columns": [
+            "user_id"
+          ],
+          "referenced_columns": [
+            "id"
+          ],
+          "comment": ""
+        }
+      ],
+      "triggers": [
+        {
+          "name": "update_posts_updated",
+          "def": "CREATE TRIGGER update_posts_updated AFTER UPDATE ON posts FOR EACH ROW\nBEGIN\n  UPDATE posts SET updated = current_timestamp WHERE id = OLD.id;\nEND",
+          "comment": ""
+        }
+      ],
+      "def": "CREATE TABLE posts (\n  id INTEGER PRIMARY KEY AUTOINCREMENT,\n  user_id INTEGER NOT NULL,\n  category_id INTEGER NOT NULL,\n  title TEXT NOT NULL,\n  CONSTRAINT posts_user_id_fk FOREIGN KEY(user_id) REFERENCES users(id) MATCH NONE ON UPDATE NO ACTION ON DELETE CASCADE,\n  CONSTRAINT posts_category_id_fk FOREIGN KEY(category_id) REFERENCES categories(id) MATCH NONE ON UPDATE NO ACTION ON DELETE CASCADE\n)",
+      "labels": [
+        {
+          "Name": "public",
+          "Virtual": true
+        }
+      ]
+    },
+    {
+      "name": "user_options",
+      "type": "table",
+      "comment": "",
+      "columns": [
+        {
+          "name": "id",
+          "type": "INTEGER",
+          "nullable": true,
+          "default": null,
+          "comment": ""
+        },
+        {
+          "name": "user_id",
+          "type": "INTEGER",
+          "nullable": false,
+          "default": null,
+          "comment": ""
+        },
+        {
+          "name": "email",
+          "type": "TEXT",
+          "nullable": false,
+          "default": null,
+          "comment": ""
+        }
+      ],
+      "indexes": [],
+      "constraints": [
+        {
+          "name": "id",
+          "type": "PRIMARY KEY",
+          "def": "PRIMARY KEY (id)",
+          "table": "user_options",
+          "referenced_table": null,
+          "columns": [
+            "id"
+          ],
+          "referenced_columns": null,
+          "comment": ""
+        },
+        {
+          "name": "- (Foreign key ID: 0)",
+          "type": "FOREIGN KEY",
+          "def": "FOREIGN KEY (user_id) REFERENCES users (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE",
+          "table": "user_options",
+          "referenced_table": "users",
+          "columns": [
+            "user_id"
+          ],
+          "referenced_columns": [
+            "id"
+          ],
+          "comment": ""
+        }
+      ],
+      "triggers": [],
+      "def": "CREATE TABLE user_options (\n  id INTEGER PRIMARY KEY AUTOINCREMENT,\n  user_id INTEGER NOT NULL,\n  email TEXT NOT NULL,\n  CONSTRAINT user_options_user_id_fk FOREIGN KEY(user_id) REFERENCES users(id) MATCH NONE ON UPDATE NO ACTION ON DELETE CASCADE\n)",
+      "labels": [
+        {
+          "Name": "private",
+          "Virtual": true
+        },
+        {
+          "Name": "option",
+          "Virtual": true
+        }
+      ]
+    },
+    {
+      "name": "schema_migrations",
+      "type": "table",
+      "comment": "",
+      "columns": [
+        {
+          "name": "id",
+          "type": "INTEGER",
+          "nullable": true,
+          "default": null,
+          "comment": ""
+        },
+        {
+          "name": "name",
+          "type": "TEXT",
+          "nullable": false,
+          "default": null,
+          "comment": ""
+        }
+      ],
+      "indexes": [],
+      "constraints": [
+        {
+          "name": "id",
+          "type": "PRIMARY KEY",
+          "def": "PRIMARY KEY (id)",
+          "table": "schema_migrations",
+          "referenced_table": null,
+          "columns": [
+            "id"
+          ],
+          "referenced_columns": null,
+          "comment": ""
+        }
+      ],
+      "triggers": [],
+      "def": "CREATE TABLE schema_migrations (\n  id INTEGER PRIMARY KEY AUTOINCREMENT,\n  name TEXT NOT NULL\n)"
+    }
+  ],
+  "relations": [
+    {
+      "table": "posts",
+      "columns": [
+        "category_id"
+      ],
+      "parent_table": "categories",
+      "parent_columns": [
+        "id"
+      ],
+      "def": "FOREIGN KEY (category_id) REFERENCES categories (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE",
+      "virtual": false
+    },
+    {
+      "table": "posts",
+      "columns": [
+        "user_id"
+      ],
+      "parent_table": "users",
+      "parent_columns": [
+        "id"
+      ],
+      "def": "FOREIGN KEY (user_id) REFERENCES users (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE",
+      "virtual": false
+    },
+    {
+      "table": "user_options",
+      "columns": [
+        "user_id"
+      ],
+      "parent_table": "users",
+      "parent_columns": [
+        "id"
+      ],
+      "def": "FOREIGN KEY (user_id) REFERENCES users (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE",
+      "virtual": false
+    }
+  ],
+  "functions": null,
+  "driver": {
+    "name": "sqlite",
+    "database_version": "3.39.4",
+    "meta": {}
+  }
+}
\ No newline at end of file
diff --git a/testdata/modify_schema_mod_name_and_desc.golden b/testdata/modify_schema_mod_name_and_desc.golden
new file mode 100644
index 0000000..c103e02
--- /dev/null
+++ b/testdata/modify_schema_mod_name_and_desc.golden
@@ -0,0 +1,407 @@
+{
+  "name": "mod_name_and_desc",
+  "desc": "this is test schema",
+  "tables": [
+    {
+      "name": "users",
+      "type": "table",
+      "comment": "users comment",
+      "columns": [
+        {
+          "name": "id",
+          "type": "INTEGER",
+          "nullable": true,
+          "default": null,
+          "comment": ""
+        },
+        {
+          "name": "username",
+          "type": "TEXT",
+          "nullable": false,
+          "default": null,
+          "comment": ""
+        }
+      ],
+      "indexes": [
+        {
+          "name": "sqlite_autoindex_users_1",
+          "def": "UNIQUE (username)",
+          "table": "users",
+          "columns": [
+            "username"
+          ],
+          "comment": ""
+        }
+      ],
+      "constraints": [
+        {
+          "name": "id",
+          "type": "PRIMARY KEY",
+          "def": "PRIMARY KEY (id)",
+          "table": "users",
+          "referenced_table": null,
+          "columns": [
+            "id"
+          ],
+          "referenced_columns": null,
+          "comment": ""
+        },
+        {
+          "name": "sqlite_autoindex_users_1",
+          "type": "UNIQUE",
+          "def": "UNIQUE (username)",
+          "table": "users",
+          "referenced_table": null,
+          "columns": [
+            "username"
+          ],
+          "referenced_columns": null,
+          "comment": ""
+        },
+        {
+          "name": "-",
+          "type": "CHECK",
+          "def": "CHECK(length(username) \u003e 4)",
+          "table": "users",
+          "referenced_table": null,
+          "columns": [
+            "username"
+          ],
+          "referenced_columns": null,
+          "comment": ""
+        }
+      ],
+      "triggers": [],
+      "def": "CREATE TABLE users (\n  id INTEGER PRIMARY KEY AUTOINCREMENT,\n  username TEXT UNIQUE NOT NULL CHECK(length(username) \u003e 4)\n)",
+      "labels": [
+        {
+          "Name": "private",
+          "Virtual": true
+        }
+      ]
+    },
+    {
+      "name": "categories",
+      "type": "table",
+      "comment": "",
+      "columns": [
+        {
+          "name": "id",
+          "type": "INTEGER",
+          "nullable": true,
+          "default": null,
+          "comment": ""
+        },
+        {
+          "name": "name",
+          "type": "TEXT",
+          "nullable": false,
+          "default": null,
+          "comment": ""
+        }
+      ],
+      "indexes": [
+        {
+          "name": "sqlite_autoindex_categories_1",
+          "def": "UNIQUE (name)",
+          "table": "categories",
+          "columns": [
+            "name"
+          ],
+          "comment": ""
+        }
+      ],
+      "constraints": [
+        {
+          "name": "id",
+          "type": "PRIMARY KEY",
+          "def": "PRIMARY KEY (id)",
+          "table": "categories",
+          "referenced_table": null,
+          "columns": [
+            "id"
+          ],
+          "referenced_columns": null,
+          "comment": ""
+        },
+        {
+          "name": "sqlite_autoindex_categories_1",
+          "type": "UNIQUE",
+          "def": "UNIQUE (name)",
+          "table": "categories",
+          "referenced_table": null,
+          "columns": [
+            "name"
+          ],
+          "referenced_columns": null,
+          "comment": ""
+        }
+      ],
+      "triggers": [],
+      "def": "CREATE TABLE categories (\n  id INTEGER PRIMARY KEY AUTOINCREMENT,\n  name TEXT UNIQUE NOT NULL\n)",
+      "labels": [
+        {
+          "Name": "public",
+          "Virtual": true
+        },
+        {
+          "Name": "option",
+          "Virtual": true
+        }
+      ]
+    },
+    {
+      "name": "posts",
+      "type": "table",
+      "comment": "",
+      "columns": [
+        {
+          "name": "id",
+          "type": "INTEGER",
+          "nullable": true,
+          "default": null,
+          "comment": ""
+        },
+        {
+          "name": "user_id",
+          "type": "INTEGER",
+          "nullable": false,
+          "default": null,
+          "comment": ""
+        },
+        {
+          "name": "category_id",
+          "type": "INTEGER",
+          "nullable": false,
+          "default": null,
+          "comment": ""
+        },
+        {
+          "name": "title",
+          "type": "TEXT",
+          "nullable": false,
+          "default": null,
+          "comment": ""
+        }
+      ],
+      "indexes": [
+        {
+          "name": "posts_user_id_idx",
+          "def": "CREATE INDEX posts_user_id_idx ON posts(user_id)",
+          "table": "posts",
+          "columns": [
+            "user_id"
+          ],
+          "comment": ""
+        }
+      ],
+      "constraints": [
+        {
+          "name": "id",
+          "type": "PRIMARY KEY",
+          "def": "PRIMARY KEY (id)",
+          "table": "posts",
+          "referenced_table": null,
+          "columns": [
+            "id"
+          ],
+          "referenced_columns": null,
+          "comment": ""
+        },
+        {
+          "name": "- (Foreign key ID: 0)",
+          "type": "FOREIGN KEY",
+          "def": "FOREIGN KEY (category_id) REFERENCES categories (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE",
+          "table": "posts",
+          "referenced_table": "categories",
+          "columns": [
+            "category_id"
+          ],
+          "referenced_columns": [
+            "id"
+          ],
+          "comment": ""
+        },
+        {
+          "name": "- (Foreign key ID: 1)",
+          "type": "FOREIGN KEY",
+          "def": "FOREIGN KEY (user_id) REFERENCES users (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE",
+          "table": "posts",
+          "referenced_table": "users",
+          "columns": [
+            "user_id"
+          ],
+          "referenced_columns": [
+            "id"
+          ],
+          "comment": ""
+        }
+      ],
+      "triggers": [
+        {
+          "name": "update_posts_updated",
+          "def": "CREATE TRIGGER update_posts_updated AFTER UPDATE ON posts FOR EACH ROW\nBEGIN\n  UPDATE posts SET updated = current_timestamp WHERE id = OLD.id;\nEND",
+          "comment": ""
+        }
+      ],
+      "def": "CREATE TABLE posts (\n  id INTEGER PRIMARY KEY AUTOINCREMENT,\n  user_id INTEGER NOT NULL,\n  category_id INTEGER NOT NULL,\n  title TEXT NOT NULL,\n  CONSTRAINT posts_user_id_fk FOREIGN KEY(user_id) REFERENCES users(id) MATCH NONE ON UPDATE NO ACTION ON DELETE CASCADE,\n  CONSTRAINT posts_category_id_fk FOREIGN KEY(category_id) REFERENCES categories(id) MATCH NONE ON UPDATE NO ACTION ON DELETE CASCADE\n)",
+      "labels": [
+        {
+          "Name": "public",
+          "Virtual": true
+        }
+      ]
+    },
+    {
+      "name": "user_options",
+      "type": "table",
+      "comment": "",
+      "columns": [
+        {
+          "name": "id",
+          "type": "INTEGER",
+          "nullable": true,
+          "default": null,
+          "comment": ""
+        },
+        {
+          "name": "user_id",
+          "type": "INTEGER",
+          "nullable": false,
+          "default": null,
+          "comment": ""
+        },
+        {
+          "name": "email",
+          "type": "TEXT",
+          "nullable": false,
+          "default": null,
+          "comment": ""
+        }
+      ],
+      "indexes": [],
+      "constraints": [
+        {
+          "name": "id",
+          "type": "PRIMARY KEY",
+          "def": "PRIMARY KEY (id)",
+          "table": "user_options",
+          "referenced_table": null,
+          "columns": [
+            "id"
+          ],
+          "referenced_columns": null,
+          "comment": ""
+        },
+        {
+          "name": "- (Foreign key ID: 0)",
+          "type": "FOREIGN KEY",
+          "def": "FOREIGN KEY (user_id) REFERENCES users (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE",
+          "table": "user_options",
+          "referenced_table": "users",
+          "columns": [
+            "user_id"
+          ],
+          "referenced_columns": [
+            "id"
+          ],
+          "comment": ""
+        }
+      ],
+      "triggers": [],
+      "def": "CREATE TABLE user_options (\n  id INTEGER PRIMARY KEY AUTOINCREMENT,\n  user_id INTEGER NOT NULL,\n  email TEXT NOT NULL,\n  CONSTRAINT user_options_user_id_fk FOREIGN KEY(user_id) REFERENCES users(id) MATCH NONE ON UPDATE NO ACTION ON DELETE CASCADE\n)",
+      "labels": [
+        {
+          "Name": "private",
+          "Virtual": true
+        },
+        {
+          "Name": "option",
+          "Virtual": true
+        }
+      ]
+    },
+    {
+      "name": "schema_migrations",
+      "type": "table",
+      "comment": "",
+      "columns": [
+        {
+          "name": "id",
+          "type": "INTEGER",
+          "nullable": true,
+          "default": null,
+          "comment": ""
+        },
+        {
+          "name": "name",
+          "type": "TEXT",
+          "nullable": false,
+          "default": null,
+          "comment": ""
+        }
+      ],
+      "indexes": [],
+      "constraints": [
+        {
+          "name": "id",
+          "type": "PRIMARY KEY",
+          "def": "PRIMARY KEY (id)",
+          "table": "schema_migrations",
+          "referenced_table": null,
+          "columns": [
+            "id"
+          ],
+          "referenced_columns": null,
+          "comment": ""
+        }
+      ],
+      "triggers": [],
+      "def": "CREATE TABLE schema_migrations (\n  id INTEGER PRIMARY KEY AUTOINCREMENT,\n  name TEXT NOT NULL\n)"
+    }
+  ],
+  "relations": [
+    {
+      "table": "posts",
+      "columns": [
+        "category_id"
+      ],
+      "parent_table": "categories",
+      "parent_columns": [
+        "id"
+      ],
+      "def": "FOREIGN KEY (category_id) REFERENCES categories (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE",
+      "virtual": false
+    },
+    {
+      "table": "posts",
+      "columns": [
+        "user_id"
+      ],
+      "parent_table": "users",
+      "parent_columns": [
+        "id"
+      ],
+      "def": "FOREIGN KEY (user_id) REFERENCES users (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE",
+      "virtual": false
+    },
+    {
+      "table": "user_options",
+      "columns": [
+        "user_id"
+      ],
+      "parent_table": "users",
+      "parent_columns": [
+        "id"
+      ],
+      "def": "FOREIGN KEY (user_id) REFERENCES users (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE",
+      "virtual": false
+    }
+  ],
+  "functions": null,
+  "driver": {
+    "name": "sqlite",
+    "database_version": "3.39.4",
+    "meta": {}
+  }
+}
\ No newline at end of file
diff --git a/testdata/filter_tables.json b/testdata/test_schema.json
similarity index 93%
rename from testdata/filter_tables.json
rename to testdata/test_schema.json
index 92f54a5..dffd883 100644
--- a/testdata/filter_tables.json
+++ b/testdata/test_schema.json
@@ -1,11 +1,11 @@
 {
-  "name": "filter_tables.sqlite3",
+  "name": "testdb.sqlite3",
   "desc": "",
   "tables": [
     {
       "name": "users",
       "type": "table",
-      "comment": "",
+      "comment": "users comment",
       "columns": [
         {
           "name": "id",
@@ -170,7 +170,17 @@
           "comment": ""
         }
       ],
-      "indexes": [],
+      "indexes": [
+        {
+          "name": "posts_user_id_idx",
+          "def": "CREATE INDEX posts_user_id_idx ON posts(user_id)",
+          "table": "posts",
+          "columns": [
+            "user_id"
+          ],
+          "comment": ""
+        }
+      ],
       "constraints": [
         {
           "name": "id",
@@ -213,7 +223,13 @@
           "comment": ""
         }
       ],
-      "triggers": [],
+      "triggers": [
+        {
+          "name": "update_posts_updated",
+          "def": "CREATE TRIGGER update_posts_updated AFTER UPDATE ON posts FOR EACH ROW\nBEGIN\n  UPDATE posts SET updated = current_timestamp WHERE id = OLD.id;\nEND",
+          "comment": ""
+        }
+      ],
       "def": "CREATE TABLE posts (\n  id INTEGER PRIMARY KEY AUTOINCREMENT,\n  user_id INTEGER NOT NULL,\n  category_id INTEGER NOT NULL,\n  title TEXT NOT NULL,\n  CONSTRAINT posts_user_id_fk FOREIGN KEY(user_id) REFERENCES users(id) MATCH NONE ON UPDATE NO ACTION ON DELETE CASCADE,\n  CONSTRAINT posts_category_id_fk FOREIGN KEY(category_id) REFERENCES categories(id) MATCH NONE ON UPDATE NO ACTION ON DELETE CASCADE\n)",
       "labels": [{"name":"public", "virtual": true}]
     },