bootstrap-source-flyway.test.mjs
2.57 KB
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
// lib/bootstrap-source-flyway.test.mjs — 纯函数单测(checksum / 迁移名解析)。
// 完整 bootstrap 需真实 mysql2 + DB,不在离线范围;此处只锁定与 Flyway 对齐的关键不变量。
import { test } from 'node:test'
import assert from 'node:assert/strict'
import { flywayChecksum, parseMigrationName } from './bootstrap-source-flyway.mjs'
test('flywayChecksum: deterministic and returns a signed int32', () => {
const a = flywayChecksum('CREATE TABLE t (id INT);\n')
const b = flywayChecksum('CREATE TABLE t (id INT);\n')
assert.equal(a, b)
assert.equal(Number.isInteger(a), true)
assert.ok(a >= -2147483648 && a <= 2147483647, 'signed int32 range')
})
// Flyway 按行读取(剥行终止符)——CRLF 与 LF 的同一内容 checksum 必须相同(跨平台 checkout 稳定)。
test('flywayChecksum: CRLF and LF of the same content match (line-ending normalized)', () => {
const lf = 'line1\nline2\nline3\n'
const crlf = 'line1\r\nline2\r\nline3\r\n'
assert.equal(flywayChecksum(lf), flywayChecksum(crlf))
})
// 尾部有无换行不改变行集合末尾(BufferedReader 不返回"最后的空行")——单个尾换行与无尾换行一致。
test('flywayChecksum: a single trailing newline does not change the checksum', () => {
assert.equal(flywayChecksum('a\nb'), flywayChecksum('a\nb\n'))
})
// 内容不同 → checksum 不同(基本区分性)。
test('flywayChecksum: different content yields different checksum', () => {
assert.notEqual(flywayChecksum('SELECT 1;'), flywayChecksum('SELECT 2;'))
})
// 首行 UTF-8 BOM 被剥离(与 Flyway 一致)——带 BOM 与不带 BOM 的同一内容一致。
test('flywayChecksum: leading UTF-8 BOM is stripped', () => {
assert.equal(flywayChecksum('CREATE TABLE t (id INT);\n'), flywayChecksum('CREATE TABLE t (id INT);\n'))
})
test('parseMigrationName: V1__initial_schema.sql → version 1, description "initial schema"', () => {
assert.deepEqual(parseMigrationName('V1__initial_schema.sql'), { version: '1', description: 'initial schema' })
})
test('parseMigrationName: dotted/underscored versions normalize to dots', () => {
assert.deepEqual(parseMigrationName('V2_1__add_index.sql'), { version: '2.1', description: 'add index' })
assert.deepEqual(parseMigrationName('V10.3__foo.sql'), { version: '10.3', description: 'foo' })
})
test('parseMigrationName: non-migration filenames return null', () => {
assert.equal(parseMigrationName('seed.sql'), null)
assert.equal(parseMigrationName('V1_no_double_underscore.sql'), null)
assert.equal(parseMigrationName('R__repeatable.sql'), null)
})