drop-test-db-template.test.mjs
3.2 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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
// lib/drop-test-db-template.test.mjs — 校验生成模板 scripts/drop-test-db.mjs 的"只删副本、硬拒删源库"逻辑。
// 跑真实模板产物:复制到临时 scripts/、写 ../config-vars.yaml、再 node 执行。host/port 指向 127.0.0.1:1(必拒连)。
import { test } from 'node:test'
import assert from 'node:assert/strict'
import { spawnSync } from 'node:child_process'
import { mkdtempSync, mkdirSync, copyFileSync, writeFileSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { fileURLToPath } from 'node:url'
const TEMPLATE = fileURLToPath(new URL('../skills/plan/skeleton-gen/templates/scripts-drop-test-db-template.mjs', import.meta.url))
function runWithDb({ host = '127.0.0.1', port = '1', user = 'root', password = 'x', schemaLine = 'schema: erp_dev', env = {}, laneMarker = null } = {}) {
const dir = mkdtempSync(join(tmpdir(), 'erp-drtb-'))
mkdirSync(join(dir, 'scripts'))
copyFileSync(TEMPLATE, join(dir, 'scripts', 'drop-test-db.mjs'))
writeFileSync(
join(dir, 'config-vars.yaml'),
['database:', ` host: ${host}`, ` port: ${port}`, ` user: ${user}`, ` password: ${password}`, ' ' + schemaLine, ''].join('\n'),
)
if (laneMarker !== null) {
mkdirSync(join(dir, '.tmp'))
writeFileSync(join(dir, '.tmp', 'erp-lane-db'), laneMarker)
}
const childEnv = { ...process.env, ...env }
if (!('ERP_TEST_DB_SCHEMA' in env)) delete childEnv.ERP_TEST_DB_SCHEMA
return spawnSync('node', [join(dir, 'scripts', 'drop-test-db.mjs')], { encoding: 'utf8', env: childEnv })
}
test('drop-test-db: unfilled placeholders fail before mysql', () => {
const r = runWithDb({ schemaLine: 'schema: 【人工填写:schema 名】' })
assert.equal(r.status, 1)
assert.match(r.stderr, /仍是占位/, 'stderr: ' + r.stderr)
})
test('drop-test-db: empty source schema fails before mysql', () => {
const r = runWithDb({ schemaLine: 'schema:' })
assert.equal(r.status, 1)
assert.match(r.stderr, /database\.schema/, 'stderr: ' + r.stderr)
})
// **安全红线**:待删副本 = 源库 → 拒绝(绝不删源库)。守卫先于任何 mysql 调用。
test('drop-test-db: refuses to drop when copy name equals source (protects source)', () => {
const r = runWithDb({ env: { ERP_TEST_DB_SCHEMA: 'erp_dev' } })
assert.equal(r.status, 1)
assert.match(r.stderr, /待删副本名与源库名相同/, 'stderr: ' + r.stderr)
assert.doesNotMatch(r.stdout, /删除一次性副本/, '拒绝应先于 DROP — stdout: ' + r.stdout)
})
test('drop-test-db: serial default targets <source>__test copy', () => {
const r = runWithDb()
assert.match(r.stdout, /删除一次性副本 erp_dev__test/, 'stdout: ' + r.stdout)
assert.notEqual(r.status, 0, '应在连库阶段失败(127.0.0.1:1)')
})
test('drop-test-db: ERP_TEST_DB_SCHEMA env names the copy to drop', () => {
const r = runWithDb({ env: { ERP_TEST_DB_SCHEMA: 'erp_dev_lane2' } })
assert.match(r.stdout, /删除一次性副本 erp_dev_lane2/, 'stdout: ' + r.stdout)
})
test('drop-test-db: .tmp/erp-lane-db marker names the copy when env absent', () => {
const r = runWithDb({ laneMarker: 'erp_dev_lane3\n' })
assert.match(r.stdout, /删除一次性副本 erp_dev_lane3/, 'stdout: ' + r.stdout)
})