Added a scripts execution ability
This commit is contained in:
375
pkg/readers/sqldir/reader_test.go
Normal file
375
pkg/readers/sqldir/reader_test.go
Normal file
@@ -0,0 +1,375 @@
|
||||
package sqldir
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"git.warky.dev/wdevs/relspecgo/pkg/readers"
|
||||
)
|
||||
|
||||
func TestReader_ReadDatabase(t *testing.T) {
|
||||
// Create temporary test directory
|
||||
tempDir, err := os.MkdirTemp("", "sqldir-test-*")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create temp directory: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
// Create test SQL files with both underscore and hyphen separators
|
||||
testFiles := map[string]string{
|
||||
"1_001_create_users.sql": "CREATE TABLE users (id SERIAL PRIMARY KEY, name TEXT);",
|
||||
"1_002_create_posts.sql": "CREATE TABLE posts (id SERIAL PRIMARY KEY, user_id INT);",
|
||||
"2_001_add_indexes.sql": "CREATE INDEX idx_posts_user_id ON posts(user_id);",
|
||||
"1_003_seed_data.pgsql": "INSERT INTO users (name) VALUES ('Alice'), ('Bob');",
|
||||
"10-10-create-newid.pgsql": "CREATE TABLE newid (id SERIAL PRIMARY KEY);",
|
||||
"2-005-add-column.sql": "ALTER TABLE users ADD COLUMN email TEXT;",
|
||||
}
|
||||
|
||||
for filename, content := range testFiles {
|
||||
filePath := filepath.Join(tempDir, filename)
|
||||
if err := os.WriteFile(filePath, []byte(content), 0644); err != nil {
|
||||
t.Fatalf("Failed to create test file %s: %v", filename, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Create subdirectory with additional script
|
||||
subDir := filepath.Join(tempDir, "migrations")
|
||||
if err := os.MkdirAll(subDir, 0755); err != nil {
|
||||
t.Fatalf("Failed to create subdirectory: %v", err)
|
||||
}
|
||||
subFile := filepath.Join(subDir, "3_001_add_column.sql")
|
||||
if err := os.WriteFile(subFile, []byte("ALTER TABLE users ADD COLUMN email TEXT;"), 0644); err != nil {
|
||||
t.Fatalf("Failed to create subdirectory file: %v", err)
|
||||
}
|
||||
|
||||
// Create reader
|
||||
reader := NewReader(&readers.ReaderOptions{
|
||||
FilePath: tempDir,
|
||||
Metadata: map[string]any{
|
||||
"schema_name": "test_schema",
|
||||
"database_name": "test_db",
|
||||
},
|
||||
})
|
||||
|
||||
// Read database
|
||||
db, err := reader.ReadDatabase()
|
||||
if err != nil {
|
||||
t.Fatalf("ReadDatabase failed: %v", err)
|
||||
}
|
||||
|
||||
// Verify database
|
||||
if db.Name != "test_db" {
|
||||
t.Errorf("Expected database name 'test_db', got '%s'", db.Name)
|
||||
}
|
||||
|
||||
if len(db.Schemas) != 1 {
|
||||
t.Fatalf("Expected 1 schema, got %d", len(db.Schemas))
|
||||
}
|
||||
|
||||
schema := db.Schemas[0]
|
||||
if schema.Name != "test_schema" {
|
||||
t.Errorf("Expected schema name 'test_schema', got '%s'", schema.Name)
|
||||
}
|
||||
|
||||
// Verify scripts (should be 7 total: 4 underscore + 2 hyphen + 1 subdirectory)
|
||||
if len(schema.Scripts) != 7 {
|
||||
t.Fatalf("Expected 7 scripts, got %d", len(schema.Scripts))
|
||||
}
|
||||
|
||||
// Verify script details
|
||||
expectedScripts := []struct {
|
||||
name string
|
||||
priority int
|
||||
sequence uint
|
||||
}{
|
||||
{"create_users", 1, 1},
|
||||
{"create_posts", 1, 2},
|
||||
{"seed_data", 1, 3},
|
||||
{"add_indexes", 2, 1},
|
||||
{"add-column", 2, 5},
|
||||
{"add_column", 3, 1},
|
||||
{"create-newid", 10, 10},
|
||||
}
|
||||
|
||||
scriptMap := make(map[string]*struct {
|
||||
priority int
|
||||
sequence uint
|
||||
sql string
|
||||
})
|
||||
for _, script := range schema.Scripts {
|
||||
scriptMap[script.Name] = &struct {
|
||||
priority int
|
||||
sequence uint
|
||||
sql string
|
||||
}{
|
||||
priority: script.Priority,
|
||||
sequence: script.Sequence,
|
||||
sql: script.SQL,
|
||||
}
|
||||
}
|
||||
|
||||
for _, expected := range expectedScripts {
|
||||
script, exists := scriptMap[expected.name]
|
||||
if !exists {
|
||||
t.Errorf("Expected script '%s' not found", expected.name)
|
||||
continue
|
||||
}
|
||||
if script.priority != expected.priority {
|
||||
t.Errorf("Script '%s': expected priority %d, got %d",
|
||||
expected.name, expected.priority, script.priority)
|
||||
}
|
||||
if script.sequence != expected.sequence {
|
||||
t.Errorf("Script '%s': expected sequence %d, got %d",
|
||||
expected.name, expected.sequence, script.sequence)
|
||||
}
|
||||
if script.sql == "" {
|
||||
t.Errorf("Script '%s': SQL content is empty", expected.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestReader_ReadSchema(t *testing.T) {
|
||||
// Create temporary test directory
|
||||
tempDir, err := os.MkdirTemp("", "sqldir-test-*")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create temp directory: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
// Create test SQL file
|
||||
testFile := filepath.Join(tempDir, "1_001_test.sql")
|
||||
if err := os.WriteFile(testFile, []byte("SELECT 1;"), 0644); err != nil {
|
||||
t.Fatalf("Failed to create test file: %v", err)
|
||||
}
|
||||
|
||||
// Create reader
|
||||
reader := NewReader(&readers.ReaderOptions{
|
||||
FilePath: tempDir,
|
||||
})
|
||||
|
||||
// Read schema
|
||||
schema, err := reader.ReadSchema()
|
||||
if err != nil {
|
||||
t.Fatalf("ReadSchema failed: %v", err)
|
||||
}
|
||||
|
||||
// Verify schema
|
||||
if schema.Name != "public" {
|
||||
t.Errorf("Expected default schema name 'public', got '%s'", schema.Name)
|
||||
}
|
||||
|
||||
if len(schema.Scripts) != 1 {
|
||||
t.Fatalf("Expected 1 script, got %d", len(schema.Scripts))
|
||||
}
|
||||
}
|
||||
|
||||
func TestReader_InvalidDirectory(t *testing.T) {
|
||||
reader := NewReader(&readers.ReaderOptions{
|
||||
FilePath: "/nonexistent/directory",
|
||||
})
|
||||
|
||||
_, err := reader.ReadDatabase()
|
||||
if err == nil {
|
||||
t.Error("Expected error for nonexistent directory, got nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestReader_EmptyDirectory(t *testing.T) {
|
||||
// Create temporary empty directory
|
||||
tempDir, err := os.MkdirTemp("", "sqldir-test-*")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create temp directory: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
reader := NewReader(&readers.ReaderOptions{
|
||||
FilePath: tempDir,
|
||||
})
|
||||
|
||||
db, err := reader.ReadDatabase()
|
||||
if err != nil {
|
||||
t.Fatalf("ReadDatabase failed: %v", err)
|
||||
}
|
||||
|
||||
if len(db.Schemas[0].Scripts) != 0 {
|
||||
t.Errorf("Expected 0 scripts in empty directory, got %d", len(db.Schemas[0].Scripts))
|
||||
}
|
||||
}
|
||||
|
||||
func TestReader_InvalidFilename(t *testing.T) {
|
||||
// Create temporary test directory
|
||||
tempDir, err := os.MkdirTemp("", "sqldir-test-*")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create temp directory: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
// Create files with various invalid patterns
|
||||
invalidFiles := []string{
|
||||
"invalid.sql", // No priority/sequence
|
||||
"1_test.sql", // Missing sequence
|
||||
"test_1_2.sql", // Wrong order
|
||||
"a_001_test.sql", // Non-numeric priority
|
||||
"1_abc_test.sql", // Non-numeric sequence
|
||||
"1_001_test.txt", // Wrong extension
|
||||
"1_001_test.sql.backup", // Wrong extension
|
||||
}
|
||||
|
||||
for _, filename := range invalidFiles {
|
||||
filePath := filepath.Join(tempDir, filename)
|
||||
if err := os.WriteFile(filePath, []byte("SELECT 1;"), 0644); err != nil {
|
||||
t.Fatalf("Failed to create test file %s: %v", filename, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Create one valid file
|
||||
validFile := filepath.Join(tempDir, "1_001_valid.sql")
|
||||
if err := os.WriteFile(validFile, []byte("SELECT 1;"), 0644); err != nil {
|
||||
t.Fatalf("Failed to create valid file: %v", err)
|
||||
}
|
||||
|
||||
reader := NewReader(&readers.ReaderOptions{
|
||||
FilePath: tempDir,
|
||||
})
|
||||
|
||||
db, err := reader.ReadDatabase()
|
||||
if err != nil {
|
||||
t.Fatalf("ReadDatabase failed: %v", err)
|
||||
}
|
||||
|
||||
// Should only have the valid file
|
||||
if len(db.Schemas[0].Scripts) != 1 {
|
||||
t.Errorf("Expected 1 script (invalid files should be skipped), got %d", len(db.Schemas[0].Scripts))
|
||||
}
|
||||
|
||||
if db.Schemas[0].Scripts[0].Name != "valid" {
|
||||
t.Errorf("Expected script name 'valid', got '%s'", db.Schemas[0].Scripts[0].Name)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReader_ReadTable(t *testing.T) {
|
||||
reader := NewReader(&readers.ReaderOptions{})
|
||||
|
||||
_, err := reader.ReadTable()
|
||||
if err == nil {
|
||||
t.Error("Expected error for ReadTable (not supported), got nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestReader_HyphenFormat(t *testing.T) {
|
||||
// Create temporary test directory
|
||||
tempDir, err := os.MkdirTemp("", "sqldir-test-hyphen-*")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create temp directory: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
// Create test files with hyphen separators
|
||||
testFiles := map[string]string{
|
||||
"1-001-create-table.sql": "CREATE TABLE test (id INT);",
|
||||
"1-002-insert-data.pgsql": "INSERT INTO test VALUES (1);",
|
||||
"10-10-create-newid.pgsql": "CREATE TABLE newid (id SERIAL);",
|
||||
"2-005-add-index.sql": "CREATE INDEX idx_test ON test(id);",
|
||||
}
|
||||
|
||||
for filename, content := range testFiles {
|
||||
filePath := filepath.Join(tempDir, filename)
|
||||
if err := os.WriteFile(filePath, []byte(content), 0644); err != nil {
|
||||
t.Fatalf("Failed to create test file %s: %v", filename, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Create reader
|
||||
reader := NewReader(&readers.ReaderOptions{
|
||||
FilePath: tempDir,
|
||||
})
|
||||
|
||||
// Read database
|
||||
db, err := reader.ReadDatabase()
|
||||
if err != nil {
|
||||
t.Fatalf("ReadDatabase failed: %v", err)
|
||||
}
|
||||
|
||||
schema := db.Schemas[0]
|
||||
if len(schema.Scripts) != 4 {
|
||||
t.Fatalf("Expected 4 scripts, got %d", len(schema.Scripts))
|
||||
}
|
||||
|
||||
// Verify specific hyphen-formatted scripts
|
||||
expectedScripts := map[string]struct {
|
||||
priority int
|
||||
sequence uint
|
||||
}{
|
||||
"create-table": {1, 1},
|
||||
"insert-data": {1, 2},
|
||||
"add-index": {2, 5},
|
||||
"create-newid": {10, 10},
|
||||
}
|
||||
|
||||
for _, script := range schema.Scripts {
|
||||
expected, exists := expectedScripts[script.Name]
|
||||
if !exists {
|
||||
t.Errorf("Unexpected script: %s", script.Name)
|
||||
continue
|
||||
}
|
||||
if script.Priority != expected.priority {
|
||||
t.Errorf("Script '%s': expected priority %d, got %d",
|
||||
script.Name, expected.priority, script.Priority)
|
||||
}
|
||||
if script.Sequence != expected.sequence {
|
||||
t.Errorf("Script '%s': expected sequence %d, got %d",
|
||||
script.Name, expected.sequence, script.Sequence)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestReader_MixedFormat(t *testing.T) {
|
||||
// Test that both underscore and hyphen formats can be mixed
|
||||
tempDir, err := os.MkdirTemp("", "sqldir-test-mixed-*")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create temp directory: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
testFiles := map[string]string{
|
||||
"1_001_underscore.sql": "SELECT 1;",
|
||||
"1-002-hyphen.sql": "SELECT 2;",
|
||||
"2_003_underscore.sql": "SELECT 3;",
|
||||
"2-004-hyphen.sql": "SELECT 4;",
|
||||
}
|
||||
|
||||
for filename, content := range testFiles {
|
||||
filePath := filepath.Join(tempDir, filename)
|
||||
if err := os.WriteFile(filePath, []byte(content), 0644); err != nil {
|
||||
t.Fatalf("Failed to create test file %s: %v", filename, err)
|
||||
}
|
||||
}
|
||||
|
||||
reader := NewReader(&readers.ReaderOptions{
|
||||
FilePath: tempDir,
|
||||
})
|
||||
|
||||
db, err := reader.ReadDatabase()
|
||||
if err != nil {
|
||||
t.Fatalf("ReadDatabase failed: %v", err)
|
||||
}
|
||||
|
||||
schema := db.Schemas[0]
|
||||
if len(schema.Scripts) != 4 {
|
||||
t.Fatalf("Expected 4 scripts (mixed format), got %d", len(schema.Scripts))
|
||||
}
|
||||
|
||||
// Verify both formats are parsed correctly
|
||||
names := make(map[string]bool)
|
||||
for _, script := range schema.Scripts {
|
||||
names[script.Name] = true
|
||||
}
|
||||
|
||||
expectedNames := []string{"underscore", "hyphen", "underscore", "hyphen"}
|
||||
for _, name := range expectedNames {
|
||||
if !names[name] {
|
||||
t.Errorf("Expected script name '%s' not found", name)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user