mirror of
https://github.com/therootcompany/golib.git
synced 2026-11-04 15:05:00 +00:00
146 lines
3.4 KiB
Go
146 lines
3.4 KiB
Go
package csvdb
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"testing"
|
|
|
|
"github.com/therootcompany/golib/database/csvx"
|
|
)
|
|
|
|
func TestFileRoundtrip(t *testing.T) {
|
|
root, err := os.OpenRoot(t.TempDir())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer func() { _ = root.Close() }()
|
|
f := &Store[testRuleRow]{Root: root, Name: "test.tsv", Format: "tsv"}
|
|
ctx := context.Background()
|
|
|
|
if _, err := f.Init(ctx); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
rows := []testRuleRow{
|
|
{Email: "a@example.com"},
|
|
{Email: "b@example.com"},
|
|
}
|
|
if err := f.WriteAll(ctx, rows); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
got, err := f.Fetch(ctx)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(got) != 2 {
|
|
t.Fatalf("got %d rows, want 2", len(got))
|
|
}
|
|
if got[0].Email != "a@example.com" || got[1].Email != "b@example.com" {
|
|
t.Fatalf("unexpected rows: %v", got)
|
|
}
|
|
}
|
|
|
|
func TestFileNormalizeHook(t *testing.T) {
|
|
root, err := os.OpenRoot(t.TempDir())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer func() { _ = root.Close() }()
|
|
f := &Store[identityRow]{
|
|
Root: root,
|
|
Name: "identities.tsv",
|
|
Format: "tsv",
|
|
Normalize: func(rows []identityRow) {
|
|
for i := range rows {
|
|
if rows[i].Email.Valid {
|
|
rows[i].Email.String = csvx.NormalizeEmail(rows[i].Email.String)
|
|
}
|
|
if rows[i].Phone.Valid {
|
|
rows[i].Phone.String = csvx.NormalizePhone(rows[i].Phone.String)
|
|
}
|
|
}
|
|
},
|
|
}
|
|
ctx := context.Background()
|
|
rows := []identityRow{{
|
|
Email: csvx.Text{String: " USER@Example.COM ", Valid: true},
|
|
Phone: csvx.Text{String: "+1 (415) 555-0123", Valid: true},
|
|
}}
|
|
if err := f.WriteAll(ctx, rows); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
got, err := f.Fetch(ctx)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(got) != 1 || got[0].Email.String != "user@example.com" || got[0].Phone.String != "(415) 555-0123" {
|
|
t.Fatalf("contacts = %#v", got)
|
|
}
|
|
}
|
|
|
|
func TestFileFetchSkipsComments(t *testing.T) {
|
|
root, err := os.OpenRoot(t.TempDir())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer func() { _ = root.Close() }()
|
|
content := "# beginner note\nemail\trevoked_at\texpires_at\nuser@example.com\t\t\n"
|
|
if err := root.WriteFile("comments.tsv", []byte(content), 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
f := &Store[testRuleRow]{Root: root, Name: "comments.tsv", Format: "tsv"}
|
|
got, err := f.Fetch(context.Background())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(got) != 1 || got[0].Email != "user@example.com" {
|
|
t.Fatalf("got %#v, want one parsed row", got)
|
|
}
|
|
}
|
|
|
|
func TestFileFetchMissing(t *testing.T) {
|
|
root, err := os.OpenRoot(t.TempDir())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer func() { _ = root.Close() }()
|
|
f := &Store[testRuleRow]{Root: root, Name: "missing.tsv", Format: "tsv"}
|
|
got, err := f.Fetch(context.Background())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(got) != 0 {
|
|
t.Fatalf("got %d rows, want 0", len(got))
|
|
}
|
|
}
|
|
|
|
func TestFileAtomicWrite(t *testing.T) {
|
|
dir := t.TempDir()
|
|
root, err := os.OpenRoot(dir)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer func() { _ = root.Close() }()
|
|
f := &Store[testRuleRow]{Root: root, Name: "test.tsv", Format: "tsv"}
|
|
ctx := context.Background()
|
|
if _, err := f.Init(ctx); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
rows := []testRuleRow{{Email: "x@example.com"}}
|
|
for range 5 {
|
|
if err := f.WriteAll(ctx, rows); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
info, err := root.Stat("test.tsv")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if info.Size() == 0 {
|
|
t.Fatal("file is empty after writes")
|
|
}
|
|
entries, _ := os.ReadDir(dir)
|
|
if len(entries) != 1 {
|
|
t.Fatalf("expected 1 file in dir, got %d (temp files not cleaned up?)", len(entries))
|
|
}
|
|
}
|