test: cover viewDefinitionSurvivesReopenAfterCheckpointAndStaysLiveOv...

This commit is contained in:
dualfroz committed 2026-09-09 18:25:23 +02:00
1 parent d882371038
commit 9c87f22cbb
1 file changed
+173
+173
View File
@@ -199,4 +199,177 @@ class PersistenceTest {
assertContains(output.toString(), "1")
assertContains(output.toString(), "2")
}
@Test
fun viewDefinitionSurvivesReopenAfterCheckpointAndStaysLiveOverNewData() {
val dir = tempDir()
runScript(
dir,
"""
CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT NOT NULL, age INTEGER);
INSERT INTO users VALUES (1, 'ada', 36), (2, 'linus', 54);
CREATE VIEW adults AS SELECT id, name FROM users WHERE age >= 40;
.exit
""".trimIndent()
)
val afterCheckpoint = runScript(
dir,
"""
SELECT name FROM adults ORDER BY id ASC;
INSERT INTO users VALUES (3, 'grace', 85);
.exit
""".trimIndent()
)
assertContains(afterCheckpoint, "linus")
assertTrue(!afterCheckpoint.contains("ada"), "view predicate must exclude rows under the age threshold")
val afterInsert = runScript(dir, "SELECT name FROM adults ORDER BY id ASC;\n.views\n.exit\n")
assertContains(afterInsert, "grace")
assertContains(afterInsert, "adults")
}
@Test
fun dropViewSurvivesReopenWithoutACheckpoint() {
val dir = tempDir()
val persistence = Persistence(dir)
persistence.appendWal(
listOf(
"CREATE TABLE t (id INTEGER);",
"CREATE VIEW v AS SELECT id FROM t;",
"DROP VIEW v;"
)
)
val output = StringBuilder()
Repl(output, output, Persistence(dir)).run(".views\n.exit\n".reader().buffered())
assertContains(output.toString(), "no views")
}
@Test
fun updatesUsingScalarFunctionsAndPredicatesSurviveReopen() {
val dir = tempDir()
runScript(
dir,
"""
CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT NOT NULL, bio TEXT);
INSERT INTO users VALUES (1, 'ada', 'mathematician'), (2, 'linus', NULL), (3, 'grace', 'admiral');
UPDATE users SET name = UPPER(name) WHERE bio IS NOT NULL;
DELETE FROM users WHERE name IN ('linus') OR bio LIKE '%admiral';
.exit
""".trimIndent()
)
val reopened = runScript(dir, "SELECT name FROM users ORDER BY id ASC;\n.exit\n")
assertContains(reopened, "ADA")
assertTrue(!reopened.contains("linus"), "row matching NOT IN predicate must stay deleted")
assertTrue(!reopened.contains("grace") && !reopened.contains("GRACE"), "row matching LIKE predicate must stay deleted")
}
@Test
fun decimalAndDateColumnsSurviveReopenAfterCheckpoint() {
val dir = tempDir()
runScript(
dir,
"""
CREATE TABLE orders (id INTEGER PRIMARY KEY, amount DECIMAL(10, 2), placed DATE);
INSERT INTO orders VALUES (1, 19.9, CAST('2024-03-01' AS DATE));
.exit
""".trimIndent()
)
val reopened = runScript(dir, "SELECT amount, placed FROM orders;\n.exit\n")
assertContains(reopened, "19.90")
assertContains(reopened, "2024-03-01")
}
@Test
fun decimalAndDateColumnsSurviveReopenWithoutACheckpointViaWalReplay() {
val dir = tempDir()
val persistence = Persistence(dir)
persistence.appendWal(
listOf(
"CREATE TABLE orders (id INTEGER PRIMARY KEY, amount DECIMAL(10, 2), placed DATE);",
"INSERT INTO orders VALUES (1, CAST('42.5' AS DECIMAL(10, 2)), CAST('2024-03-01' AS DATE));"
)
)
val output = StringBuilder()
Repl(output, output, Persistence(dir)).run("SELECT amount, placed FROM orders;\n.exit\n".reader().buffered())
assertContains(output.toString(), "42.50")
assertContains(output.toString(), "2024-03-01")
}
@Test
fun foreignKeyAndCheckConstraintsSurviveReopenAfterCheckpoint() {
val dir = tempDir()
runScript(
dir,
"""
CREATE TABLE departments (id INTEGER PRIMARY KEY, name TEXT);
CREATE TABLE employees (id INTEGER PRIMARY KEY, dept_id INTEGER REFERENCES departments(id) ON DELETE CASCADE, age INTEGER CHECK (age > 0));
INSERT INTO departments VALUES (1, 'eng');
INSERT INTO employees VALUES (1, 1, 30);
.exit
""".trimIndent()
)
val afterConstraintChecks = runScript(
dir,
"""
INSERT INTO employees VALUES (2, 99, 30);
.exit
""".trimIndent()
)
assertContains(afterConstraintChecks, "Error")
assertContains(afterConstraintChecks, "FOREIGN KEY")
val afterCascade = runScript(
dir,
"""
DELETE FROM departments WHERE id = 1;
SELECT * FROM employees;
.exit
""".trimIndent()
)
assertContains(afterCascade, "0 rows")
}
@Test
fun uniqueConstraintsSurviveReopenAfterCheckpoint() {
val dir = tempDir()
runScript(
dir,
"""
CREATE TABLE users (id INTEGER PRIMARY KEY, email TEXT UNIQUE, a INTEGER, b INTEGER, UNIQUE (a, b));
INSERT INTO users VALUES (1, 'ada@example.com', 1, 1);
.exit
""".trimIndent()
)
val afterReopen = runScript(
dir,
"""
INSERT INTO users VALUES (2, 'ada@example.com', 2, 2);
.exit
""".trimIndent()
)
assertContains(afterReopen, "Error")
assertContains(afterReopen, "UNIQUE constraint")
val afterCompositeViolation = runScript(
dir,
"""
INSERT INTO users VALUES (3, 'grace@example.com', 1, 1);
.exit
""".trimIndent()
)
assertContains(afterCompositeViolation, "Error")
assertContains(afterCompositeViolation, "UNIQUE constraint")
}
@Test
fun uniqueIndexSurvivesReopenAfterCheckpointAndKeepsEnforcingAndAccelerating() {
val dir = tempDir()
runScript(
dir,
"""
CREATE TABLE users (id INTEGER PRIMARY KEY, email TEXT);
INSERT INTO users VALUES (1, 'ada@example.com');
CREATE UNIQUE INDEX idx_email ON users (email);
.exit
""".trimIndent()
}