diff --git a/.github/workflows/autofix.yml b/.github/workflows/autofix.yml index 8c62cd4eaa..3f8a287e3a 100644 --- a/.github/workflows/autofix.yml +++ b/.github/workflows/autofix.yml @@ -20,26 +20,21 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + - uses: voidzero-dev/setup-vp@a03302daa50cf2f017c8c7345730c2740df207d6 # v1 with: node-version: lts/* - - - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # 5e1c8eafbd745f64b1ef30a7d7ed7965034c486c - name: ๐ง Install pnpm - - - name: ๐ฆ Install dependencies - run: pnpm install + cache: true - name: ๐จ Check for non-RTL/non-a11y CSS classes - run: pnpm vp run lint:css + run: vp run lint:css - name: ๐ Compare translations - run: pnpm vp run i18n:check + run: vp run i18n:check - name: ๐ Update lunaria data - run: pnpm vp run build:lunaria + run: vp run build:lunaria - name: ๐ Fix lint errors - run: pnpm vp run lint:fix + run: vp run lint:fix - uses: autofix-ci/action@635ffb0c9798bd160680f18fd73371e355b85f27 # 635ffb0c9798bd160680f18fd73371e355b85f27 diff --git a/.github/workflows/chromatic.yml b/.github/workflows/chromatic.yml index 0a4860dc5f..5adb687647 100644 --- a/.github/workflows/chromatic.yml +++ b/.github/workflows/chromatic.yml @@ -26,15 +26,13 @@ jobs: repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }} ref: ${{ github.event.pull_request.head.sha || github.sha }} - - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + - uses: voidzero-dev/setup-vp@a03302daa50cf2f017c8c7345730c2740df207d6 # v1 with: node-version: lts/* + cache: true - - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # 5e1c8eafbd745f64b1ef30a7d7ed7965034c486c - name: ๐ง Install pnpm - - - name: ๐ฆ Install dependencies - run: pnpm install + - name: ๐ง Install pnpm globally + run: vp install -g pnpm - name: ๐งช Run Chromatic Visual and Accessibility Tests uses: chromaui/action@f191a0224b10e1a38b2091cefb7b7a2337009116 # v16.0.0 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b26e2a37b3..f4c414458b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,18 +28,16 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + - uses: voidzero-dev/setup-vp@a03302daa50cf2f017c8c7345730c2740df207d6 # v1 with: node-version: lts/* - - - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # 5e1c8eafbd745f64b1ef30a7d7ed7965034c486c - name: ๐ง Install pnpm + run-install: false - name: ๐ฆ Install dependencies (root only, no scripts) - run: pnpm install --filter . --ignore-scripts + run: vp install --filter . --ignore-scripts - name: ๐ Lint project - run: pnpm vp run lint + run: vp run lint types: name: ๐ช Type check @@ -48,18 +46,13 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + - uses: voidzero-dev/setup-vp@a03302daa50cf2f017c8c7345730c2740df207d6 # v1 with: node-version: lts/* - - - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # 5e1c8eafbd745f64b1ef30a7d7ed7965034c486c - name: ๐ง Install pnpm - - - name: ๐ฆ Install dependencies - run: pnpm install + cache: true - name: ๐ช Type check - run: pnpm vp run test:types + run: vp run test:types unit: name: ๐งช Unit tests @@ -68,18 +61,13 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + - uses: voidzero-dev/setup-vp@a03302daa50cf2f017c8c7345730c2740df207d6 # v1 with: node-version: lts/* - - - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # 5e1c8eafbd745f64b1ef30a7d7ed7965034c486c - name: ๐ง Install pnpm - - - name: ๐ฆ Install dependencies - run: pnpm install + cache: true - name: ๐งช Unit tests - run: pnpm vp test --project unit --coverage --reporter=default --reporter=junit --outputFile=test-report.junit.xml + run: vp test --project unit --coverage --reporter=default --reporter=junit --outputFile=test-report.junit.xml - name: โฌ๏ธ Upload test results to Codecov if: ${{ !cancelled() }} @@ -94,21 +82,16 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + - uses: voidzero-dev/setup-vp@a03302daa50cf2f017c8c7345730c2740df207d6 # v1 with: node-version: lts/* - - - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # 5e1c8eafbd745f64b1ef30a7d7ed7965034c486c - name: ๐ง Install pnpm - - - name: ๐ฆ Install dependencies - run: pnpm install + cache: true - name: ๐ Install browser - run: pnpm vp exec playwright install chromium-headless-shell + run: vp exec playwright install chromium-headless-shell - name: ๐งช Component tests - run: pnpm vp test --project nuxt --coverage --reporter=default --reporter=junit --outputFile=test-report.junit.xml + run: vp test --project nuxt --coverage --reporter=default --reporter=junit --outputFile=test-report.junit.xml - name: โฌ๏ธ Upload coverage reports to Codecov uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6 @@ -131,23 +114,18 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + - uses: voidzero-dev/setup-vp@a03302daa50cf2f017c8c7345730c2740df207d6 # v1 with: node-version: lts/* - - - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # 5e1c8eafbd745f64b1ef30a7d7ed7965034c486c - name: ๐ง Install pnpm - - - name: ๐ฆ Install dependencies - run: pnpm install + cache: true - name: ๐๏ธ Build project - run: pnpm vp run build:test + run: vp run build:test env: VALIDATE_HTML: true - name: ๐ฅ๏ธ Test project (browser) - run: pnpm vp run test:browser:prebuilt + run: vp run test:browser:prebuilt a11y: name: โฟ Accessibility audit @@ -159,21 +137,16 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + - uses: voidzero-dev/setup-vp@a03302daa50cf2f017c8c7345730c2740df207d6 # v1 with: node-version: lts/* - - - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # 5e1c8eafbd745f64b1ef30a7d7ed7965034c486c - name: ๐ง Install pnpm - - - name: ๐ฆ Install dependencies - run: pnpm install + cache: true - name: ๐๏ธ Build project - run: pnpm vp run build:test + run: vp run build:test - name: โฟ Accessibility audit (Lighthouse - ${{ matrix.mode }} mode) - run: pnpm vp run test:a11y:prebuilt + run: vp run test:a11y:prebuilt env: LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }} LIGHTHOUSE_COLOR_MODE: ${{ matrix.mode }} @@ -185,18 +158,13 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + - uses: voidzero-dev/setup-vp@a03302daa50cf2f017c8c7345730c2740df207d6 # v1 with: node-version: lts/* - - - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # 5e1c8eafbd745f64b1ef30a7d7ed7965034c486c - name: ๐ง Install pnpm - - - name: ๐ฆ Install dependencies - run: pnpm install + cache: true - name: ๐งน Check for unused code - run: pnpm vp run knip + run: vp run knip i18n: name: ๐ i18n validation @@ -205,20 +173,18 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + - uses: voidzero-dev/setup-vp@a03302daa50cf2f017c8c7345730c2740df207d6 # v1 with: node-version: lts/* - - - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # 5e1c8eafbd745f64b1ef30a7d7ed7965034c486c - name: ๐ง Install pnpm + run-install: false - name: ๐ฆ Install dependencies (root only, no scripts) - run: pnpm install --filter . --ignore-scripts + run: vp install --filter . --ignore-scripts - name: ๐ Check for missing or dynamic i18n keys - run: pnpm vp run i18n:report + run: vp run i18n:report - name: ๐ Check i18n schema is up to date run: | - pnpm vp run i18n:schema + vp run i18n:schema git diff --exit-code i18n/schema.json diff --git a/.github/workflows/lunaria.yml b/.github/workflows/lunaria.yml index b2bc818360..4e1cf26604 100644 --- a/.github/workflows/lunaria.yml +++ b/.github/workflows/lunaria.yml @@ -28,15 +28,10 @@ jobs: # Makes the action clone the entire git history fetch-depth: 0 - - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + - uses: voidzero-dev/setup-vp@a03302daa50cf2f017c8c7345730c2740df207d6 # v1 with: node-version: lts/* - - - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # 5e1c8eafbd745f64b1ef30a7d7ed7965034c486c - name: ๐ง Install pnpm - - - name: ๐ฆ Install dependencies - run: pnpm install + cache: true - name: Generate Lunaria Overview uses: lunariajs/action@4911ad0736d1e3b20af4cb70f5079aea2327ed8e # v1-prerelease diff --git a/.github/workflows/release-pr.yml b/.github/workflows/release-pr.yml index fc244db18e..bb8d7cc779 100644 --- a/.github/workflows/release-pr.yml +++ b/.github/workflows/release-pr.yml @@ -20,9 +20,10 @@ jobs: with: fetch-depth: 0 - - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + - uses: voidzero-dev/setup-vp@a03302daa50cf2f017c8c7345730c2740df207d6 # v1 with: node-version: lts/* + run-install: false - name: ๐ Check for unreleased commits id: check diff --git a/.github/workflows/release-tag.yml b/.github/workflows/release-tag.yml index 331540e6d9..5e318171f9 100644 --- a/.github/workflows/release-tag.yml +++ b/.github/workflows/release-tag.yml @@ -23,9 +23,10 @@ jobs: with: fetch-depth: 0 - - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + - uses: voidzero-dev/setup-vp@a03302daa50cf2f017c8c7345730c2740df207d6 # v1 with: node-version: lts/* + run-install: false - name: ๐ข Determine next version id: version @@ -58,13 +59,9 @@ jobs: git tag -a "$VERSION" -m "Release $VERSION" git push origin "$VERSION" - - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # 5e1c8eafbd745f64b1ef30a7d7ed7965034c486c - if: steps.check.outputs.skip == 'false' - name: ๐ง Install pnpm - - name: ๐ฆ Install dependencies if: steps.check.outputs.skip == 'false' - run: pnpm vp install --filter . --ignore-scripts + run: vp install --filter . --ignore-scripts - name: ๐ Generate release notes if: steps.check.outputs.skip == 'false' @@ -98,18 +95,14 @@ jobs: with: ref: release - - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + - uses: voidzero-dev/setup-vp@a03302daa50cf2f017c8c7345730c2740df207d6 # v1 with: node-version: lts/* registry-url: https://registry.npmjs.org - - - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # 5e1c8eafbd745f64b1ef30a7d7ed7965034c486c - name: ๐ง Install pnpm - with: - cache: false + run-install: false - name: ๐ฆ Install dependencies - run: pnpm install --filter npmx-connector... + run: vp install --filter npmx-connector... - name: ๐ข Set connector version env: @@ -122,7 +115,7 @@ jobs: echo "Publishing npmx-connector@${PKG_VERSION}" - name: ๐๏ธ Build connector - run: pnpm --filter npmx-connector build + run: vp run --filter npmx-connector build - name: ๐ค Publish to npm with provenance # Uses OIDC trusted publishing โ no NPM_TOKEN needed. diff --git a/.storybook/decorators.ts b/.storybook/decorators.ts new file mode 100644 index 0000000000..270cdec3a5 --- /dev/null +++ b/.storybook/decorators.ts @@ -0,0 +1,20 @@ +import AppFooter from '~/components/AppFooter.vue' +import AppHeader from '~/components/AppHeader.vue' + +/** + * Wraps a page story with the standard site chrome: AppHeader, main content + * area, and AppFooter. Use this for any full-page story so the layout stays + * consistent and changes only need to be made in one place. + */ +export const pageDecorator = () => ({ + components: { AppHeader, AppFooter }, + template: ` +
-
-### Code Blocks
-
-Pre-formatted code blocks are used for writing about programming or
-markup source code. Rather than forming normal paragraphs, the lines
-of a code block are interpreted literally. Markdown wraps a code block
-in both `` and `` tags.
-
-To produce a code block in Markdown, simply indent every line of the
-block by at least 4 spaces or 1 tab.
-
-This is a normal paragraph:
-
- This is a code block.
-
-Here is an example of AppleScript:
-
- tell application "Foo"
- beep
- end tell
-
-A code block continues until it reaches a line that is not indented
-(or the end of the article).
-
-Within a code block, ampersands (`&`) and angle brackets (`<` and `>`)
-are automatically converted into HTML entities. This makes it very
-easy to include example HTML source code using Markdown -- just paste
-it and indent it, and Markdown will handle the hassle of encoding the
-ampersands and angle brackets. For example, this:
-
-
-
-Regular Markdown syntax is not processed within code blocks. E.g.,
-asterisks are just literal asterisks within a code block. This means
-it's also easy to use Markdown to write about Markdown's own syntax.
-
-```
-tell application "Foo"
- beep
-end tell
-```
-
-## Span Elements
-
-### Links
-
-Markdown supports two style of links: _inline_ and _reference_.
-
-In both styles, the link text is delimited by [square brackets].
-
-To create an inline link, use a set of regular parentheses immediately
-after the link text's closing square bracket. Inside the parentheses,
-put the URL where you want the link to point, along with an _optional_
-title for the link, surrounded in quotes. For example:
-
-This is [an example](http://example.com/) inline link.
-
-[This link](http://example.net/) has no title attribute.
-
-### Emphasis
-
-Markdown treats asterisks (`*`) and underscores (`_`) as indicators of
-emphasis. Text wrapped with one `*` or `_` will be wrapped with an
-HTML `` tag; double `*`'s or `_`'s will be wrapped with an HTML
-`` tag. E.g., this input:
-
-_single asterisks_
-
-_single underscores_
-
-**double asterisks**
-
-**double underscores**
-
-### Code
-
-To indicate a span of code, wrap it with backtick quotes (`` ` ``).
-Unlike a pre-formatted code block, a code span indicates code within a
-normal paragraph. For example:
-
-Use the `printf()` function.
-
-
diff --git a/app/pages/index.vue b/app/pages/index.vue
index 7cc3981569..48c5575b00 100644
--- a/app/pages/index.vue
+++ b/app/pages/index.vue
@@ -8,8 +8,6 @@ async function search() {
startSearch()
}
-const { env } = useAppConfig().buildInfo
-
useSeoMeta({
title: () => $t('seo.home.title'),
ogTitle: () => $t('seo.home.title'),
@@ -32,25 +30,7 @@ defineOgImageComponent('Default', {
-
-
-
-
-
-
+
+// Maximum file size we'll try to load (500KB) - must match server
+const MAX_FILE_SIZE = 500 * 1024
+
definePageMeta({
name: 'code',
path: '/package-code/:org?/:packageName/v/:version/:filePath(.*)?',
@@ -12,6 +15,10 @@ definePageMeta({
const route = useRoute('code')
+const mobileFileTreeRef = useTemplateRef('mobileFileTreeRef')
+
+const { codeContainerFull } = useCodeContainer()
+
// Parse package name, version, and file path from URL
// Patterns:
// /code/nuxt/v/4.2.0 โ packageName: "nuxt", version: "4.2.0", filePath: null (show tree)
@@ -95,25 +102,26 @@ const currentNode = computed(() => {
return lastFound
})
-const isViewingFile = computed(() => currentNode.value?.type === 'file')
-
-// Maximum file size we'll try to load (500KB) - must match server
-const MAX_FILE_SIZE = 500 * 1024
+const isViewingFile = computed(() => currentNode.value?.type === 'file')
// Estimate binary file based on mime type
-const isBinaryFile = computed(() => {
+const isBinaryFile = computed(() => {
+ if (!isViewingFile.value) return false
+
const contentType = fileContent.value?.contentType
if (!contentType) return false
return isBinaryContentType(contentType)
})
-const isFileTooLarge = computed(() => {
+const isFileTooLarge = computed(() => {
+ if (!isViewingFile.value) return false
+
const size = currentNode.value?.size
return size !== undefined && size > MAX_FILE_SIZE
})
// Fetch file content when a file is selected (and not too large)
-const fileContentUrl = computed(() => {
+const fileContentUrl = computed(() => {
// Don't fetch if no file path, file tree not loaded, file is too large, or it's a directory
if (!filePath.value || !fileTree.value || isFileTooLarge.value || !isViewingFile.value) {
return null
@@ -127,6 +135,19 @@ const {
execute: fetchFileContent,
} = useFetch(() => fileContentUrl.value!, { immediate: false })
+// Loading skeleton state
+const isLoading = computed(() => {
+ if (!isViewingFile.value) {
+ return treeStatus.value !== 'success' && treeStatus.value !== 'error'
+ }
+
+ return !fileStatus.value || fileStatus.value === 'pending' || fileStatus.value === 'idle'
+})
+
+function toggleMobileTreeDrawer(): void {
+ mobileFileTreeRef.value?.toggle()
+}
+
watch(
fileContentUrl,
url => {
@@ -185,24 +206,6 @@ watch(fileContent, () => {
nextTick(scrollToLine)
})
-// Build breadcrumb path segments
-const breadcrumbs = computed(() => {
- const parts = filePath.value?.split('/').filter(Boolean) ?? []
- const result: { name: string; path: string }[] = []
-
- for (let i = 0; i < parts.length; i++) {
- const part = parts[i]
- if (part) {
- result.push({
- name: part,
- path: parts.slice(0, i + 1).join('/'),
- })
- }
- }
-
- return result
-})
-
// Navigation helper - build URL for a path
function getCurrentCodeUrlWithPath(path?: string): string {
return getCodeUrl({
@@ -236,36 +239,10 @@ function handleLineClick(lineNum: number, event: MouseEvent) {
currentHash.value = newHash
}
-// Copy link to current line(s)
-const { copied: permalinkCopied, copy: copyPermalink } = useClipboard({ copiedDuring: 2000 })
-function copyPermalinkUrl() {
- const url = new URL(window.location.href)
- copyPermalink(url.toString())
-}
-
-const { copied: fileContentCopied, copy: copyFileContent } = useClipboard({
- source: () => fileContent.value?.content || '',
- copiedDuring: 2000,
-})
-
// Canonical URL for this code page
const canonicalUrl = computed(() => `https://npmx.dev${getCodeUrl(route.params)}`)
-// Toggle markdown view mode
-const markdownViewModes = [
- {
- key: 'preview',
- label: $t('code.markdown_view_mode.preview'),
- icon: 'i-lucide:eye',
- },
- {
- key: 'code',
- label: $t('code.markdown_view_mode.code'),
- icon: 'i-lucide:code',
- },
-] as const
-
-const markdownViewMode = shallowRef<(typeof markdownViewModes)[number]['key']>('preview')
+const markdownViewMode = shallowRef<'preview' | 'code'>('preview')
const bytesFormatter = useBytesFormatter()
@@ -310,6 +287,15 @@ defineOgImageComponent('Default', {
description: () => pkg.value?.license ?? '',
primaryColor: '#60a5fa',
})
+
+onPrehydrate(el => {
+ const settingsSaved = JSON.parse(localStorage.getItem('npmx-settings') || '{}')
+ const container = el.querySelector('#code-page-container')
+
+ if (settingsSaved?.codeContainerFull === true && container) {
+ container.classList.add('container-full')
+ }
+})
@@ -346,113 +332,51 @@ defineOgImageComponent('Default', {
{{ $t('code.binary_file') }}
@@ -496,7 +422,7 @@ defineOgImageComponent('Default', {
{{ $t('code.file_too_large') }}
@@ -512,44 +438,6 @@ defineOgImageComponent('Default', {
const x = 1;',
+ lines: 1,
+ },
+ markdownViewMode: 'preview',
+ selectedLines: null,
+ getCodeUrlWithPath: (path = '') => `/package-code/vite/v/1.0.0/${path}`,
+ packageName: 'vite',
+ version: '1.0.0',
+ },
+ })
+ const results = await runAxe(component)
+ expect(results.violations).toEqual([])
+ })
+ })
+
+ describe('CodeSkeletonLoader', () => {
+ it('should have no accessibility violations', async () => {
+ const component = await mountSuspended(CodeSkeletonLoader)
+ const results = await runAxe(component)
+ expect(results.violations).toEqual([])
+ })
+ })
+
describe('CodeViewer', () => {
it('should have no accessibility violations', async () => {
const component = await mountSuspended(CodeViewer, {
@@ -2252,23 +2300,6 @@ describe('component accessibility audits', () => {
})
})
- describe('ChartPatternSlot', () => {
- it('should have no accessibility violations', async () => {
- const component = await mountSuspended(ChartPatternSlot, {
- props: {
- id: 'perennius',
- seed: 1,
- foregroundColor: 'black',
- fallbackColor: 'transparent',
- maxSize: 24,
- minSize: 16,
- },
- })
- const results = await runAxe(component)
- expect(results.violations).toEqual([])
- })
- })
-
describe('CopyToClipboardButton', () => {
it('should have no accessibility violations in default state', async () => {
const component = await mountSuspended(CopyToClipboardButton, {
diff --git a/test/unit/a11y-component-coverage.spec.ts b/test/unit/a11y-component-coverage.spec.ts
index a73b58dd6d..6100cc04dc 100644
--- a/test/unit/a11y-component-coverage.spec.ts
+++ b/test/unit/a11y-component-coverage.spec.ts
@@ -11,7 +11,6 @@
import fs from 'node:fs'
import path from 'node:path'
import { assert, describe, it } from 'vitest'
-import { fileURLToPath } from 'node:url'
/**
* Components explicitly skipped from a11y testing with reasons.
@@ -152,9 +151,9 @@ function getTestedComponents(
}
describe('a11y component test coverage', () => {
- const componentsDir = fileURLToPath(new URL('../../app/components', import.meta.url))
- const componentsDtsPath = fileURLToPath(new URL('../../.nuxt/components.d.ts', import.meta.url))
- const testFilePath = fileURLToPath(new URL('../nuxt/a11y.spec.ts', import.meta.url))
+ const componentsDir = path.join(import.meta.dirname, '../../app/components')
+ const componentsDtsPath = path.join(import.meta.dirname, '../../.nuxt/components.d.ts')
+ const testFilePath = path.join(import.meta.dirname, '../nuxt/a11y.spec.ts')
it('should have accessibility tests for all components (or be explicitly skipped)', () => {
// Get all Vue components
diff --git a/test/unit/app/utils/charts.spec.ts b/test/unit/app/utils/charts.spec.ts
index 6a82d7e82a..72c3d6c998 100644
--- a/test/unit/app/utils/charts.spec.ts
+++ b/test/unit/app/utils/charts.spec.ts
@@ -15,9 +15,6 @@ import {
sanitise,
insertLineBreaks,
applyEllipsis,
- createSeedNumber,
- createSeededSvgPattern,
- createChartPatternSlotMarkup,
type TrendLineConfig,
type TrendLineDataset,
type VersionsBarConfig,
@@ -1402,252 +1399,3 @@ describe('applyEllipsis', () => {
expect(applyEllipsis('you need to touch grass', 13)).toBe('you need to t...')
})
})
-
-describe('createSeedNumber', () => {
- it('returns the same hash for the same input', () => {
- expect(createSeedNumber('react')).toBe(createSeedNumber('react'))
- expect(createSeedNumber('vue')).toBe(createSeedNumber('vue'))
- })
-
- it('returns different hashes for different inputs', () => {
- expect(createSeedNumber('react')).not.toBe(createSeedNumber('vue'))
- expect(createSeedNumber('svelte')).not.toBe(createSeedNumber('solid'))
- })
-
- it('returns a 32 bit unsigned integer', () => {
- const result = createSeedNumber('react')
- expect(Number.isInteger(result)).toBe(true)
- expect(result).toBeGreaterThanOrEqual(0)
- expect(result).toBeLessThanOrEqual(4294967295)
- })
-
- it('handles an empty string', () => {
- const result = createSeedNumber('')
- expect(Number.isInteger(result)).toBe(true)
- expect(result).toBeGreaterThanOrEqual(0)
- expect(result).toBeLessThanOrEqual(4294967295)
- })
-
- it('is case sensitive', () => {
- expect(createSeedNumber('react')).not.toBe(createSeedNumber('React'))
- })
-})
-
-describe('createSeededSvgPattern', () => {
- it('returns deterministic output for the same seed', () => {
- const first = createSeededSvgPattern('react')
- const second = createSeededSvgPattern('react')
- expect(first).toEqual(second)
- })
-
- it('returns different output for different seeds', () => {
- const first = createSeededSvgPattern('react')
- const second = createSeededSvgPattern('vue')
- expect(second).not.toEqual(first)
- })
-
- it('returns a valid pattern object shape', () => {
- const result = createSeededSvgPattern('react')
- expect(typeof result.width).toBe('number')
- expect(typeof result.height).toBe('number')
- expect(typeof result.rotation).toBe('number')
- expect(typeof result.patternType).toBe('string')
- expect(typeof result.contentMarkup).toBe('string')
- })
-
- it('uses default options when none are provided', () => {
- const result = createSeededSvgPattern('react')
- expect(result.width).toBeGreaterThanOrEqual(8)
- expect(result.width).toBeLessThanOrEqual(20)
- expect(result.height).toBe(result.width)
- expect(result.contentMarkup.length).toBeGreaterThan(0)
- })
-
- it('uses the provided foreground and background colors', () => {
- const result = createSeededSvgPattern('react', {
- foregroundColor: '#ff0000',
- backgroundColor: '#00ff00',
- })
- expect(result.contentMarkup).toContain('#ff0000')
- expect(result.contentMarkup).toContain('#00ff00')
- expect(result.contentMarkup).toContain('