import assert from 'node:assert/strict' import fsp from 'node:fs/promises' import path from 'node:path' import { REPO_ROOT } from './lib.mjs' const filename = path.join(REPO_ROOT, 'build', 'installer.nsh') const source = await fsp.readFile(filename, 'utf8') assert.match(source, /OpenProcess\(i 0x100000, i 0, i R1\) p \.R2 \?e/) assert.match(source, /Pop \$R3/) assert.doesNotMatch(source, /GetLastError\(\)/) assert.match(source, /WaitForSingleObject\(p R2, i 120000\)/) assert.match(source, /ElseIf\} \$R3 != 87/) const waitIndex = source.indexOf('WaitForSingleObject') const imageCheckIndex = source.indexOf('SetEnvironmentVariable(t "YCODE_UPDATE_TARGET_DIR"') assert.ok(waitIndex >= 0 && imageCheckIndex > waitIndex, 'image check must run after waiting for the parent PID') assert.ok(imageCheckIndex > source.indexOf('${ElseIf} $R3 != 87'), 'image check must run after the OpenProcess branch join') assert.ok(source.includes('t "$INSTDIR\\${APP_EXECUTABLE_FILENAME}"')) assert.match(source, /nsExec::ExecToStack/) assert.match(source, /Get-CimInstance Win32_Process/) assert.match(source, /TrimEnd\(\[char\]92\)/) assert.match(source, /AddSeconds\(5\)/) assert.match(source, /Start-Sleep -Milliseconds 500/) assert.match(source, /if \(-not \$\$process\.ExecutablePath\) \{ \$\$found=\$\$true; continue \}/) assert.match(source, /Name -ieq '\$\{APP_EXECUTABLE_FILENAME\}'/) assert.match(source, /StrCmp \$R4 "0" \+3/) assert.doesNotMatch(source, /KillProcess|taskkill|Stop-Process|_CHECK_APP_RUNNING/) assert.doesNotMatch(source, /GetProcessInfo/) assert.doesNotMatch(source, /GetLastError\(\)/) assert.doesNotMatch(source, /Name -ieq 'YCode\.exe'/) console.log('NSIS updater safety checks passed.')