export-proof-gap-software-form-smoke.js 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. #!/usr/bin/env node
  2. const fs = require('fs');
  3. const os = require('os');
  4. const path = require('path');
  5. const { spawnSync } = require('child_process');
  6. const { SOFTWARE_HEADER } = require('./export-proof-gap-software-form');
  7. const root = path.resolve(__dirname, '..');
  8. function main() {
  9. const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'tihao-proof-gap-form-'));
  10. const outputDir = path.join(tmp, 'form-latest');
  11. const result = spawnSync(process.execPath, [
  12. path.join(root, 'scripts', 'export-proof-gap-software-form.js'),
  13. '--output',
  14. outputDir,
  15. '--strict'
  16. ], { cwd: root, encoding: 'utf8' });
  17. if (result.status !== 0) {
  18. process.stderr.write(result.stderr || result.stdout || '');
  19. throw new Error('proof-gap software form export should pass');
  20. }
  21. const csvPath = path.join(outputDir, 'tihao-proof-gap-software-form.csv');
  22. const mdPath = path.join(outputDir, 'tihao-proof-gap-software-form.md');
  23. const summaryPath = path.join(outputDir, 'tihao-proof-gap-software-form-summary.json');
  24. assert(fs.existsSync(csvPath), 'csv should exist');
  25. assert(fs.existsSync(mdPath), 'markdown should exist');
  26. assert(fs.existsSync(summaryPath), 'summary should exist');
  27. const summary = JSON.parse(fs.readFileSync(summaryPath, 'utf8'));
  28. const csv = fs.readFileSync(csvPath, 'utf8');
  29. const md = fs.readFileSync(mdPath, 'utf8').replace(/^\uFEFF/, '');
  30. const lines = csv.replace(/^\uFEFF/, '').split(/\r?\n/).filter(Boolean);
  31. assert(csv.charCodeAt(0) === 0xFEFF, 'csv should have UTF-8 BOM');
  32. assert(summary.passed === true, 'summary should pass');
  33. assert(summary.headerMatches === true, 'header should match software header');
  34. assert(summary.rowWidthOk === true, 'all rows should have software header width');
  35. assert(summary.rowCount === 5, 'row count should be 5');
  36. assert(summary.duplicateIdCount === 0, 'duplicate ids should be 0');
  37. assert(lines[0] === SOFTWARE_HEADER.join(','), 'csv header should match software header');
  38. assert(lines.filter(line => /^GAP-\d{3},/.test(line)).length === 5, 'csv should include 5 GAP rows');
  39. for (const title of summary.expectedTitles) {
  40. assert(csv.includes(title), `csv should include ${title}`);
  41. assert(md.includes(title), `markdown should include ${title}`);
  42. }
  43. assert(md.includes('最新提号补证表单'), 'markdown should be Chinese');
  44. assert(md.includes('不能把 sample、smoke'), 'markdown should keep proof boundary');
  45. assert(!/sk-[A-Za-z0-9_-]{10,}/.test(csv + md), 'form should not contain model token patterns');
  46. assert(!/r:[A-Za-z0-9]{20,}/.test(csv + md), 'form should not contain Parse sessionToken patterns');
  47. console.log(JSON.stringify({
  48. ok: true,
  49. outputDir,
  50. rowCount: summary.rowCount,
  51. duplicateIdCount: summary.duplicateIdCount
  52. }, null, 2));
  53. }
  54. function assert(condition, message) {
  55. if (!condition) throw new Error(message);
  56. }
  57. main();