summaryrefslogtreecommitdiff
path: root/database_test.go
blob: 2f738655b8639768e9c6a9604d77c717c6ebee31 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
package main

import (
	"database/sql"
	"fmt"
	"os"
	"strings"
	"testing"
)

func TestReadMigrations(t *testing.T) {
	n := len(migrations)

	entries, err := os.ReadDir(migrationDir)
	if err != nil {
		t.Fatalf("Failed to determine number of migration files: %v", err)
	}
	nMigrationFiles := len(entries)

	if n != nMigrationFiles {
		t.Fatalf("Expected %d migration files but got %d.", nMigrationFiles, n)
	}

	for i, migration := range migrations {
		path := migrationPath(i)

		expectation := fmt.Sprintf("PRAGMA user_version = %d;", i+1)
		if !strings.HasPrefix(migration, expectation) {
			t.Fatalf("Expected '%s' at start of '%s'.", expectation, path)
		}
	}
}

func TestTransaction(t *testing.T) {
	db, _ := emptyDB(t)

	newVersion := 1
	err := Transaction(db, func(tx *sql.Tx) error {
		// valid statement
		_, err := tx.Exec(fmt.Sprintf("PRAGMA user_version = %d;", newVersion))
		if err != nil {
			return err
		}

		// invalid statement which should roll back the whole transaction
		_, err = tx.Exec("PRAGMA user_version THIS IS SYNTAX ERROR TALKING!!!")
		if err != nil {
			return err
		}
		return nil
	})
	if err == nil {
		t.Fatal("Error was not detected.")
	}

	version, err := UserVersion(db)
	if err != nil {
		t.Fatalf("Failed to get user_version: %v", err)
	}

	if version == newVersion {
		t.Fatal("Valid statement was not rolled back.")
	}

	expectedVersion := 0
	if version != expectedVersion {
		t.Fatalf("Expected user_version %d but got %d", expectedVersion, version)
	}
}

func TestMigrate(t *testing.T) {
	db, _ := emptyDB(t)

	userVersion, err := UserVersion(db)
	if err != nil {
		t.Fatalf("Failed to get initial user_version: %v", err)
	}

	if userVersion != 0 {
		t.Fatalf("Expected user_version 0 but got %d.", userVersion)
	}

	for i := range migrations {
		path := migrationPath(i)

		err := Migrate(db, i)
		if err != nil {
			t.Fatalf("Failed to execute migration %s: %v", path, err)
		}

		userVersion, err = UserVersion(db)
		if err != nil {
			t.Fatalf("Failed to get user_version after migration: %v", err)
		}

		expected := i + 1
		if userVersion != expected {
			t.Fatalf(
				"Expected user_version %d after running %s but got %d.",
				expected,
				path,
				userVersion,
			)
		}
	}
}

func TestUserVersion(t *testing.T) {
	db, _ := emptyDB(t)

	expectedVersion := 42
	err := Transaction(db, func(tx *sql.Tx) error {
		_, err := tx.Exec(fmt.Sprintf("PRAGMA user_version = %d;", expectedVersion))
		if err != nil {
			return err
		}
		return nil
	})
	if err != nil {
		t.Fatalf("Failed to set user expectedVersion: %v", err)
	}

	version, err := UserVersion(db)
	if err != nil {
		t.Fatalf("Could not execute function to test: %v", err)
	}

	if version != expectedVersion {
		t.Fatalf("Expected user_version %d but got %d.", expectedVersion, version)
	}
}

func TestMigrateToLatest(t *testing.T) {
	db, _ := emptyDB(t)

	err := MigrateToLatest(db)
	if err != nil {
		t.Fatalf("Could not execute function to test: %v", err)
	}

	v, err := UserVersion(db)
	if err != nil {
		t.Fatalf("Could not get user_version after migration: %v", err)
	}

	latest := len(migrations)
	if v != latest {
		t.Fatalf("Expected user_version %d but got %d.", latest, v)
	}

	futureUserVersion := 10000
	err = Transaction(db, func(tx *sql.Tx) error {
		_, err := tx.Exec(fmt.Sprintf("PRAGMA user_version = %d;", futureUserVersion))
		if err != nil {
			return err
		}
		return nil
	})

	err = MigrateToLatest(db)
	if err != nil {
		t.Fatalf("Could not execute function to test with future DB: %v", err)
	}

	v, err = UserVersion(db)
	if err != nil {
		t.Fatalf("Could not get user_version after migration with future DB: %v", err)
	}

	if v != futureUserVersion {
		t.Fatalf("Expected user_version %d but got %d.", futureUserVersion, v)
	}
}