test-project-context.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. import fs from 'fs/promises';
  2. import os from 'os';
  3. import path from 'path';
  4. import { VLProjectContext } from './src/vl/project-context.js';
  5. let passed = 0;
  6. let failed = 0;
  7. function test(name, fn) {
  8. return Promise.resolve()
  9. .then(fn)
  10. .then(() => {
  11. console.log(` ✓ ${name}`);
  12. passed++;
  13. })
  14. .catch((err) => {
  15. console.log(` ✗ ${name}: ${err.message}`);
  16. failed++;
  17. });
  18. }
  19. function assertEqual(actual, expected, msg) {
  20. if (actual !== expected) {
  21. throw new Error(msg || `Expected ${JSON.stringify(expected)}, got ${JSON.stringify(actual)}`);
  22. }
  23. }
  24. function assert(cond, msg) {
  25. if (!cond) throw new Error(msg || 'Assertion failed');
  26. }
  27. console.log('\n── Project Context Regression ──');
  28. const tmpRoot = await fs.mkdtemp(path.join(os.tmpdir(), 'vlcode-project-context-'));
  29. const populatedDir = path.join(tmpRoot, 'PopulatedProject');
  30. const emptyDir = path.join(tmpRoot, 'EmptyProject');
  31. await fs.mkdir(path.join(populatedDir, 'Apps'), { recursive: true });
  32. await fs.mkdir(path.join(populatedDir, '.vl-code', 'rules'), { recursive: true });
  33. await fs.mkdir(path.join(emptyDir, 'Theme'), { recursive: true });
  34. await fs.mkdir(path.join(emptyDir, '.vl-code'), { recursive: true });
  35. await fs.writeFile(
  36. path.join(populatedDir, 'Apps', 'OrdersApp.vx'),
  37. '// VL_VERSION:3.5\n<App_OrdersApp>\n',
  38. 'utf8'
  39. );
  40. await fs.writeFile(
  41. path.join(populatedDir, '.vl-code', 'rules', 'naming.md'),
  42. '# naming rule\n',
  43. 'utf8'
  44. );
  45. await fs.writeFile(
  46. path.join(emptyDir, 'Theme', 'Theme.vth'),
  47. '// VL_VERSION:3.5\n<Theme_Enterprise>\n',
  48. 'utf8'
  49. );
  50. await fs.writeFile(
  51. path.join(emptyDir, '.vl-code', 'ProjectMeta.json'),
  52. JSON.stringify({ projectName: 'EmptyProject' }, null, 2),
  53. 'utf8'
  54. );
  55. await test('load resets stale project identity when switching workspaces', async () => {
  56. const ctx = new VLProjectContext(populatedDir);
  57. await ctx.load();
  58. assertEqual(ctx.getSummary()?.projectName, 'Orders');
  59. assert(ctx.getRules().length > 0, 'expected rules from populated project');
  60. ctx.workDir = emptyDir;
  61. await ctx.load();
  62. assertEqual(ctx.getSummary()?.projectName, null, 'projectName should reset when new workspace has no app/db');
  63. assertEqual(ctx.getRules().length, 0, 'rules should reset when switching workspaces');
  64. assertEqual(ctx.getAllFiles().some((f) => f.path === 'Apps/OrdersApp.vx'), false, 'previous files should not persist');
  65. });
  66. await test('ProjectMeta projectName overrides generic database file names', async () => {
  67. const metaNamedDir = path.join(tmpRoot, 'MetaNamedProject');
  68. await fs.mkdir(path.join(metaNamedDir, 'Apps'), { recursive: true });
  69. await fs.mkdir(path.join(metaNamedDir, 'Database'), { recursive: true });
  70. await fs.mkdir(path.join(metaNamedDir, '.vl-code'), { recursive: true });
  71. await fs.writeFile(
  72. path.join(metaNamedDir, 'Apps', 'TodoApp.vx'),
  73. '// VL_VERSION:3.5\n<App_TodoApp>\n',
  74. 'utf8'
  75. );
  76. await fs.writeFile(
  77. path.join(metaNamedDir, 'Database', 'main.vdb'),
  78. '// VL_VERSION:3.5\n<Database_Main>\n',
  79. 'utf8'
  80. );
  81. await fs.writeFile(
  82. path.join(metaNamedDir, '.vl-code', 'ProjectMeta.json'),
  83. JSON.stringify({
  84. projectName: 'TodoTest',
  85. apps: [{ name: 'TodoApp', filePath: 'Apps/TodoApp.vx' }],
  86. }, null, 2),
  87. 'utf8'
  88. );
  89. const ctx = new VLProjectContext(metaNamedDir);
  90. await ctx.load();
  91. assertEqual(ctx.getSummary()?.projectName, 'TodoTest');
  92. });
  93. console.log(`\n── Results ──\n\n ${passed} passed, ${failed} failed\n`);
  94. process.exit(failed > 0 ? 1 : 0);