@codecademy/gamut

71.0.071.0.1-alpha.c0c413.0
bin/__tests__/design.test.mjs
+bin/__tests__/design.test.mjsNew file
+143
Index: package/bin/__tests__/design.test.mjs
===================================================================
--- package/bin/__tests__/design.test.mjs
+++ package/bin/__tests__/design.test.mjs
@@ -0,0 +1,143 @@
+import assert from 'node:assert/strict';
+import { mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
+import { tmpdir } from 'node:os';
+import { join } from 'node:path';
+import { after, before, describe, it } from 'node:test';
+
+import { installDesignMd } from '../lib/design.mjs';
+
+// ---------------------------------------------------------------------------
+// Helpers
+// ---------------------------------------------------------------------------
+
+/**
+ * Create a minimal agent-tools directory with one DESIGN source file.
+ * @param {string} dir
+ * @param {string | null} [pkgVersion]
+ */
+async function makeSourceRoot(dir, pkgVersion = '71.0.0') {
+  const sourceRoot = join(dir, 'agent-tools');
+  await mkdir(sourceRoot);
+
+  // Minimal package.json adjacent to agent-tools
+  if (pkgVersion !== null) {
+    await writeFile(
+      join(dir, 'package.json'),
+      JSON.stringify({ name: '@codecademy/gamut', version: pkgVersion }),
+      'utf8'
+    );
+  }
+
+  // Minimal DESIGN source file
+  await writeFile(
+    join(sourceRoot, 'DESIGN.Codecademy.md'),
+    '---\nversion: alpha\nname: Codecademy\n',
+    'utf8'
+  );
+
+  return sourceRoot;
+}
+
+// ---------------------------------------------------------------------------
+// Tests
+// ---------------------------------------------------------------------------
+
+describe('installDesignMd', () => {
+  /** @type {string} */
+  let tmp;
+
+  before(async () => {
+    tmp = await mkdtemp(join(tmpdir(), 'gamut-design-test-'));
+  });
+
+  after(async () => {
+    await rm(tmp, { recursive: true, force: true });
+  });
+
+  it('stamps the gamut version in an HTML comment at the top of DESIGN.md', async () => {
+    const dir = join(tmp, 'stamp');
+    await mkdir(dir);
+    const sourceRoot = await makeSourceRoot(dir, '99.0.0');
+    const cwd = join(dir, 'app');
+    await mkdir(cwd);
+
+    await installDesignMd(sourceRoot, cwd, 'core');
+
+    const content = await readFile(join(cwd, 'DESIGN.md'), 'utf8');
+    assert.match(content, /^<!-- Generated by @codecademy\/gamut@99\.0\.0\./);
+  });
+
+  it('includes the theme alias in the do-not-edit comment', async () => {
+    const dir = join(tmp, 'theme');
+    await mkdir(dir);
+    const sourceRoot = await makeSourceRoot(dir);
+    const cwd = join(dir, 'app');
+    await mkdir(cwd);
+
+    await installDesignMd(sourceRoot, cwd, 'codecademy');
+
+    const content = await readFile(join(cwd, 'DESIGN.md'), 'utf8');
+    assert.match(content, /--theme codecademy --force/);
+  });
+
+  it('throws when DESIGN.md already exists and --force is not set', async () => {
+    const dir = join(tmp, 'no-force');
+    await mkdir(dir);
+    const sourceRoot = await makeSourceRoot(dir);
+    const cwd = join(dir, 'app');
+    await mkdir(cwd);
+
+    await installDesignMd(sourceRoot, cwd, 'core');
+    await assert.rejects(
+      () => installDesignMd(sourceRoot, cwd, 'core'),
+      /already exists/
+    );
+  });
+
+  it('overwrites DESIGN.md when --force is set', async () => {
+    const dir = join(tmp, 'force');
+    await mkdir(dir);
+    const sourceRoot = await makeSourceRoot(dir);
+    const cwd = join(dir, 'app');
+    await mkdir(cwd);
+
+    await installDesignMd(sourceRoot, cwd, 'core');
+    await assert.doesNotReject(() =>
+      installDesignMd(sourceRoot, cwd, 'core', { force: true })
+    );
+  });
+
+  it('falls back to "unknown" version when package.json is missing', async () => {
+    const dir = join(tmp, 'no-pkg');
+    await mkdir(dir);
+    // Pass null so makeSourceRoot skips writing package.json
+    const sourceRoot = await makeSourceRoot(dir, null);
+    const cwd = join(dir, 'app');
+    await mkdir(cwd);
+
+    await installDesignMd(sourceRoot, cwd, 'core');
+
+    const content = await readFile(join(cwd, 'DESIGN.md'), 'utf8');
+    assert.match(content, /^<!-- Generated by @codecademy\/gamut@unknown\./);
+  });
+
+  it('does not modify the source file', async () => {
+    const dir = join(tmp, 'source-unchanged');
+    await mkdir(dir);
+    const sourceRoot = await makeSourceRoot(dir);
+    const cwd = join(dir, 'app');
+    await mkdir(cwd);
+
+    const sourceBefore = await readFile(
+      join(sourceRoot, 'DESIGN.Codecademy.md'),
+      'utf8'
+    );
+    await installDesignMd(sourceRoot, cwd, 'core');
+    const sourceAfter = await readFile(
+      join(sourceRoot, 'DESIGN.Codecademy.md'),
+      'utf8'
+    );
+
+    assert.equal(sourceAfter, sourceBefore);
+  });
+});