Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1e56150

Browse files
committed
chore(docs): add test command and configuration for vitest
- Introduced a new test command in package.json to run tests using vitest. - Updated CI configuration to include the test command as a dependency. - Modified metadata.js to ensure correct breadcrumb item positioning and generation logic. Signed-off-by: Cory Rylan <[email protected]>
1 parent b931ff5 commit 1e56150

5 files changed

Lines changed: 142 additions & 8 deletions

File tree

pnpm-lock.yaml

Lines changed: 8 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

projects/site/package.json

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,16 @@
1010
"build": "wireit",
1111
"lint": "wireit",
1212
"lint:fix": "wireit",
13+
"test": "wireit",
1314
"test:lighthouse": "wireit",
1415
"preview": "wireit"
1516
},
1617
"wireit": {
1718
"ci": {
1819
"dependencies": [
1920
"lint",
20-
"build"
21+
"build",
22+
"test"
2123
]
2224
},
2325
"dev": {
@@ -187,6 +189,18 @@
187189
"../lint:build"
188190
]
189191
},
192+
"test": {
193+
"command": "vitest run --config=vitest.config.ts",
194+
"files": [
195+
"src/**/*.test.ts",
196+
"src/_11ty/layouts/metadata.js",
197+
"vitest.config.ts"
198+
],
199+
"output": [],
200+
"dependencies": [
201+
"../internals/vite:ci"
202+
]
203+
},
190204
"test:lighthouse": {
191205
"command": "playwright-lock 'vitest run --config=vitest.lighthouse.ts'",
192206
"files": [
@@ -234,6 +248,7 @@
234248
"@nvidia-elements/monaco": "workspace:*",
235249
"@nvidia-elements/styles": "workspace:*",
236250
"@nvidia-elements/themes": "workspace:*",
251+
"@vitest/coverage-istanbul": "catalog:",
237252
"compare-versions": "6.1.1",
238253
"eslint": "catalog:",
239254
"stylelint": "catalog:",

projects/site/src/_11ty/layouts/metadata.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,11 +149,13 @@ export function renderJsonLd(data, meta) {
149149
segments.forEach((seg, i) => {
150150
cumulative += `/${seg}`;
151151
const item = i === segments.length - 1 && !meta.url.endsWith('/') ? meta.url : `${cumulative}/`;
152+
if (!hasGeneratedPage(data, generatedUrls, item)) return;
153+
152154
itemListElement.push({
153155
'@type': 'ListItem',
154-
position: i + 2,
156+
position: itemListElement.length + 1,
155157
name: titleCaseSegment(seg),
156-
...(hasGeneratedPage(data, generatedUrls, item) ? { item: `${SITE_ORIGIN}${PATH_PREFIX}${item}` } : {})
158+
item: `${SITE_ORIGIN}${PATH_PREFIX}${item}`
157159
});
158160
});
159161

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import { afterAll, describe, expect, it, vi } from 'vitest';
2+
3+
vi.stubEnv('ELEMENTS_SITE_URL', 'https://nvidia.github.io');
4+
vi.stubEnv('PAGES_BASE_URL', '/elements/');
5+
6+
afterAll(() => {
7+
vi.unstubAllEnvs();
8+
});
9+
10+
vi.mock('../../index.11tydata.js', () => ({ siteData: { elements: [] } }));
11+
12+
const { renderJsonLd } = await import('./metadata.js');
13+
14+
interface JsonLdListItem {
15+
'@type': 'ListItem';
16+
position: number;
17+
name: string;
18+
item: string;
19+
}
20+
21+
interface BreadcrumbList {
22+
'@type': 'BreadcrumbList';
23+
itemListElement: JsonLdListItem[];
24+
}
25+
26+
function isBreadcrumbList(value: unknown): value is BreadcrumbList {
27+
if (typeof value !== 'object' || value === null) return false;
28+
29+
const candidate = value as Record<string, unknown>;
30+
31+
return candidate['@type'] === 'BreadcrumbList' && Array.isArray(candidate.itemListElement);
32+
}
33+
34+
function getBreadcrumbJsonLd(html: string): BreadcrumbList {
35+
const scripts = [...html.matchAll(/<script type="application\/ld\+json">(.+?)<\/script>/g)].map(
36+
match => JSON.parse(match[1] ?? '{}') as unknown
37+
);
38+
const breadcrumb = scripts.find(isBreadcrumbList);
39+
40+
if (breadcrumb) return breadcrumb;
41+
42+
throw new TypeError('BreadcrumbList JSON-LD was not rendered.');
43+
}
44+
45+
describe('renderJsonLd', () => {
46+
it('should omit non-generated breadcrumb pages from structured data', () => {
47+
const html = renderJsonLd(
48+
{
49+
page: { url: '/docs/api-design/composition/', date: new Date('2026-05-17T00:00:00.000Z') },
50+
collections: {
51+
all: [{ url: '/' }, { url: '/docs/api-design/' }, { url: '/docs/api-design/composition/' }]
52+
}
53+
},
54+
{
55+
title: 'Composition | NVIDIA Elements',
56+
description: 'Composition guidelines for NVIDIA Elements.',
57+
canonicalUrl: 'https://nvidia.github.io/elements/docs/api-design/composition/',
58+
ogImage: 'https://nvidia.github.io/elements/favicon.svg',
59+
url: '/docs/api-design/composition/'
60+
}
61+
);
62+
63+
const breadcrumb = getBreadcrumbJsonLd(html);
64+
65+
expect(breadcrumb.itemListElement).toEqual([
66+
{ '@type': 'ListItem', position: 1, name: 'Home', item: 'https://nvidia.github.io/elements/' },
67+
{
68+
'@type': 'ListItem',
69+
position: 2,
70+
name: 'API Design',
71+
item: 'https://nvidia.github.io/elements/docs/api-design/'
72+
},
73+
{
74+
'@type': 'ListItem',
75+
position: 3,
76+
name: 'Composition',
77+
item: 'https://nvidia.github.io/elements/docs/api-design/composition/'
78+
}
79+
]);
80+
});
81+
82+
it('should include generated breadcrumb section pages', () => {
83+
const html = renderJsonLd(
84+
{
85+
page: { url: '/docs/api-design/composition/', date: new Date('2026-05-17T00:00:00.000Z') },
86+
collections: {
87+
all: [{ url: '/' }, { url: '/docs/' }, { url: '/docs/api-design/' }, { url: '/docs/api-design/composition/' }]
88+
}
89+
},
90+
{
91+
title: 'Composition | NVIDIA Elements',
92+
description: 'Composition guidelines for NVIDIA Elements.',
93+
canonicalUrl: 'https://nvidia.github.io/elements/docs/api-design/composition/',
94+
ogImage: 'https://nvidia.github.io/elements/favicon.svg',
95+
url: '/docs/api-design/composition/'
96+
}
97+
);
98+
99+
const breadcrumb = getBreadcrumbJsonLd(html);
100+
101+
expect(breadcrumb.itemListElement.map(item => item.name)).toEqual(['Home', 'Docs', 'API Design', 'Composition']);
102+
expect(breadcrumb.itemListElement.map(item => item.position)).toEqual([1, 2, 3, 4]);
103+
expect(breadcrumb.itemListElement.every(item => item.item)).toBe(true);
104+
});
105+
});

projects/site/vitest.config.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { mergeConfig } from 'vitest/config';
2+
import { libraryNodeTestConfig } from '@internals/vite/configs/test.node.js';
3+
4+
export default mergeConfig(libraryNodeTestConfig, {
5+
root: import.meta.dirname,
6+
test: {
7+
include: ['./src/**/*.test.ts']
8+
}
9+
});

0 commit comments

Comments
 (0)