apply-ddl.test.mjs 3.03 KB
import { test } from 'node:test'
import assert from 'node:assert/strict'
import { parseEnv, resolveDbConfig } from './apply-ddl.mjs'

test('parseEnv ignores comments, trims, keeps special chars literally', () => {
  const env = parseEnv('# c\nDB_PASS=p@ss$word!\nDB_NAME = erp \n')
  assert.equal(env.DB_PASS, 'p@ss$word!')
  assert.equal(env.DB_NAME, 'erp')
})

test('parseEnv does NOT expand variables', () => {
  const env = parseEnv('A=1\nB=${A}\nC=$A\nD=$(whoami)\nE=`id`\n')
  assert.equal(env.B, '${A}')
  assert.equal(env.C, '$A')
  assert.equal(env.D, '$(whoami)')
  assert.equal(env.E, '`id`')
})

test('parseEnv skips blank lines and comment lines', () => {
  const env = parseEnv('\n  \n# comment\nK=v\n   # indented comment\n')
  assert.deepEqual(Object.keys(env), ['K'])
  assert.equal(env.K, 'v')
})

test('parseEnv strips one layer of matching quotes', () => {
  const env = parseEnv(`Q1="hello world"\nQ2='a=b=c'\nQ3="$keep"\n`)
  assert.equal(env.Q1, 'hello world')
  assert.equal(env.Q2, 'a=b=c')
  assert.equal(env.Q3, '$keep')
})

test('parseEnv keeps = signs inside the value', () => {
  const env = parseEnv('URL=mysql://u:p@h:3306/db?x=1&y=2\n')
  assert.equal(env.URL, 'mysql://u:p@h:3306/db?x=1&y=2')
})

test('parseEnv strips an optional leading export', () => {
  const env = parseEnv('export DB_USER=root\n')
  assert.equal(env.DB_USER, 'root')
})

test('parseEnv tolerates CRLF line endings', () => {
  const env = parseEnv('A=1\r\nB=2\r\n')
  assert.equal(env.A, '1')
  assert.equal(env.B, '2')
})

test('parseEnv ignores lines without an = sign', () => {
  const env = parseEnv('NOEQUALS\nK=v\n')
  assert.deepEqual(Object.keys(env), ['K'])
})

test('parseEnv on empty / non-string input returns empty object', () => {
  assert.deepEqual(parseEnv(''), {})
  assert.deepEqual(parseEnv(undefined), {})
  assert.deepEqual(parseEnv(null), {})
})

// ── resolveDbConfig(M1:DB_SCHEMA 是插件契约的 schema 键)─────────
test('resolveDbConfig maps DB_SCHEMA to database (plugin canonical key)', () => {
  const c = resolveDbConfig({ DB_SCHEMA: 'erp_test', DB_USER: 'u', DB_PASS: 'p', DB_HOST: 'db.local', DB_PORT: '3307' })
  assert.equal(c.database, 'erp_test')
  assert.equal(c.host, 'db.local')
  assert.equal(c.port, 3307)
  assert.equal(c.user, 'u')
  assert.equal(c.password, 'p')
})

test('resolveDbConfig honors DB_NAME / MYSQL_DATABASE aliases', () => {
  assert.equal(resolveDbConfig({ DB_NAME: 'a' }).database, 'a')
  assert.equal(resolveDbConfig({ MYSQL_DATABASE: 'b' }).database, 'b')
  // DB_SCHEMA wins over aliases
  assert.equal(resolveDbConfig({ DB_SCHEMA: 's', DB_NAME: 'a' }).database, 's')
})

test('resolveDbConfig fails closed when no schema key is present (M1)', () => {
  assert.throws(() => resolveDbConfig({ DB_USER: 'root' }, '.env.local'), /DB_SCHEMA/)
})

test('resolveDbConfig applies sane defaults for host/port/user/password', () => {
  const c = resolveDbConfig({ DB_SCHEMA: 's' })
  assert.equal(c.host, '127.0.0.1')
  assert.equal(c.port, 3306)
  assert.equal(c.user, 'root')
  assert.equal(c.password, '')
})