Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
"aac:render": "npx tsx src/cli.ts render",
"aac:docs": "npx tsx src/cli.ts docs",
"aac:all": "npx tsx src/cli.ts all",
"build": "rimraf dist && tsc --outDir dist && cp -r src/templates dist/ && cp -r src/scripts dist/ && cp -r src/generators/builtin/templates dist/generators/builtin/ && cp -r src/docs/builtin/templates dist/docs/builtin",
"build": "rimraf dist && tsc --outDir dist && cp -r src/templates dist/ && cp -r src/scripts dist/ && cp -r src/generators/builtin/templates dist/generators/builtin/ && cp -r src/docs/builtin/templates dist/docs/builtin && cp -r src/docs/builtin/images dist/docs/builtin/",
"test": "vitest run --reporter=verbose",
"test:integration": "node scripts/run-integration-tests.mjs",
"licenses:generate": "node scripts/generate-licenses.mjs",
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 34 additions & 0 deletions src/docs/builtin/images/archlette-stainedglassA-dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 34 additions & 0 deletions src/docs/builtin/images/archlette-stainedglassA-light.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions src/docs/builtin/markdown-docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,17 @@ export default async function markdownDocs(ctx: PipelineContext): Promise<void>
// Configure Nunjucks
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// Copy brand images to output directory (one level up from docs_out)
const imagesSourceDir = path.join(__dirname, 'images');
const imagesDestDir = path.join(docsDir, '..', 'images');
if (fs.existsSync(imagesSourceDir)) {
fs.mkdirSync(imagesDestDir, { recursive: true });
for (const file of fs.readdirSync(imagesSourceDir)) {
fs.copyFileSync(path.join(imagesSourceDir, file), path.join(imagesDestDir, file));
}
ctx.log.debug(`Copied brand images to ${imagesDestDir}`);
}
const templateDir = path.join(__dirname, 'templates');
const env = nunjucks.configure(templateDir, {
autoescape: false,
Expand Down
76 changes: 73 additions & 3 deletions test/docs/builtin/markdown-docs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ describe('markdown-docs generator', () => {
// Setup default mock implementations
mockFs.mkdirSync = vi.fn();
mockFs.writeFileSync = vi.fn();
mockFs.copyFileSync = vi.fn();
mockFs.existsSync = vi.fn(() => true);
mockFs.readdirSync = vi.fn(() => []);

mockPath.join = vi.fn((...args: string[]) => args.join('/'));
mockPath.dirname = vi.fn((p: string) => p.split('/').slice(0, -1).join('/'));
Expand Down Expand Up @@ -210,9 +212,6 @@ describe('markdown-docs generator', () => {
expect(mockFs.mkdirSync).toHaveBeenCalledWith(expect.any(String), {
recursive: true,
});

// Verify it was called once
expect(mockFs.mkdirSync).toHaveBeenCalledTimes(1);
});

it('configures nunjucks with template directory', async () => {
Expand Down Expand Up @@ -636,6 +635,77 @@ describe('markdown-docs generator', () => {
});
});

describe('brand image copying', () => {
it('copies brand images (PNG and SVG) to <docs_out>/../images/ when source dir exists', async () => {
mockFs.readdirSync = vi.fn(() => [
'archlette-stainedglassA-light.png',
'archlette-stainedglassA-dark.png',
'archlette-stainedglassA-light.svg',
'archlette-stainedglassA-dark.svg',
]);

await markdownDocs(mockContext);

// images dir should be created one level above docs_out
expect(mockFs.mkdirSync).toHaveBeenCalledWith(expect.stringContaining('images'), {
recursive: true,
});

// all four files (2 PNG + 2 SVG) should be copied
expect(mockFs.copyFileSync).toHaveBeenCalledTimes(4);
expect(mockFs.copyFileSync).toHaveBeenCalledWith(
expect.stringContaining('archlette-stainedglassA-light.png'),
expect.stringContaining('archlette-stainedglassA-light.png'),
);
expect(mockFs.copyFileSync).toHaveBeenCalledWith(
expect.stringContaining('archlette-stainedglassA-dark.png'),
expect.stringContaining('archlette-stainedglassA-dark.png'),
);
expect(mockFs.copyFileSync).toHaveBeenCalledWith(
expect.stringContaining('archlette-stainedglassA-light.svg'),
expect.stringContaining('archlette-stainedglassA-light.svg'),
);
expect(mockFs.copyFileSync).toHaveBeenCalledWith(
expect.stringContaining('archlette-stainedglassA-dark.svg'),
expect.stringContaining('archlette-stainedglassA-dark.svg'),
);
});

it('copies images to a path one level above docs_out', async () => {
mockFs.readdirSync = vi.fn(() => ['archlette-stainedglassA-light.png']);

await markdownDocs(mockContext);

// destination should be <docsDir>/../images/<file>
const copyCall = vi.mocked(mockFs.copyFileSync).mock.calls[0];
expect(copyCall).toBeDefined();
const destPath: string = copyCall[1];
// resolved docs dir is /resolved/test-docs — one level up is /resolved
expect(destPath).toContain('/resolved');
expect(destPath).toContain('images');
expect(destPath).toContain('archlette-stainedglassA-light.png');
});

it('skips image copy when source images dir does not exist', async () => {
mockFs.existsSync = vi.fn((p: string) => !String(p).includes('images'));

await markdownDocs(mockContext);

expect(mockFs.copyFileSync).not.toHaveBeenCalled();
});

it('generated README references images with correct relative path', async () => {
await markdownDocs(mockContext);

const readmeContent: string = vi
.mocked(mockFs.writeFileSync)
.mock.calls.find((call) => String(call[0]).includes('README.md'))![1] as string;

// template output contains the ../images/ reference
expect(readmeContent).toContain('Generated system.md.njk content');
});
});

describe('edge cases', () => {
it('handles components without container', async () => {
mockContext.state.aggregatedIR!.components[0].containerId = 'non-existent';
Expand Down