From 1ef7eb5ff9f98c6ea994252843552d7bc3475134 Mon Sep 17 00:00:00 2001 From: olliepop777 Date: Mon, 6 May 2024 18:01:48 -0700 Subject: [PATCH 01/12] Update SideFX Houdini --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 34e14df..d38e508 100644 --- a/README.md +++ b/README.md @@ -374,7 +374,7 @@ Builds - [Java on M1 Benchmarks](https://docs.google.com/spreadsheets/d/1g4U7LAI * [GoPro Fusion Studio](https://gopro.com/en/us/news/fusion-end-of-life) - 🚫 No, not supported and no plans for support - [Verification](https://github.com/ThatGuySam/doesitarm/issues/349#issuecomment-869347313) [Official Article](https://gopro.com/en/us/news/fusion-end-of-life) * [GoPro VR Player](https://community.gopro.com/t5/en/GoPro-VR-Player-for-desktop-FAQ/ta-p/394345) - ✳️ Yes, works via Rosetta 2 translation - [Verification](https://github.com/ThatGuySam/doesitarm/issues/349#issuecomment-869347313) * [Handbrake](https://handbrake.fr/) - ✅ Yes, natively supported as of v1.4.0 - [Github Issue](https://github.com/HandBrake/HandBrake/issues/2951) -* [Houdini](https://www.sidefx.com/products/houdini/) - ✳️ Yes, works via Rosetta 2 - [Source](https://www.reddit.com/r/Houdini/comments/jzg1wj/houdini_running_on_apple_silicon_m1_macs_demo/) +* [Houdini](https://www.sidefx.com/products/houdini/) - ✅ Yes, natively supported as of v19.5.534 - [Source](https://www.sidefx.com/community/houdini-for-apple-silicon-now-gold/) * [Maxon Chromatic Displacement](https://www.maxon.net/en/red-giant-complete/vfx-suite/chromatic-displacement) - 🔶 App has not yet been reported to be native to Apple Silicon - [Requirements](https://www.maxon.net/en/requirements/chromatic-displacement-requirements) * [Maxon Cosmo](https://www.maxon.net/en/red-giant-complete/magic-bullet-suite/cosmo) - 🔶 App has not yet been reported to be native to Apple Silicon - [Requirements](https://www.maxon.net/en/requirements/cosmo-requirements) * [Maxon Denoiser](https://www.maxon.net/en/red-giant-complete/magic-bullet-suite/denoiser) - 🔶 App has not yet been reported to be native to Apple Silicon - [Requirements](https://www.maxon.net/en/requirements/denoiser-requirements) From 857c88c529be9ad2c717ea6e566d4b0ffbee98a6 Mon Sep 17 00:00:00 2001 From: olliepop777 Date: Mon, 6 May 2024 18:04:45 -0700 Subject: [PATCH 02/12] Update Autodesk Maya --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d38e508..9f72f9b 100644 --- a/README.md +++ b/README.md @@ -353,7 +353,7 @@ Builds - [Java on M1 Benchmarks](https://docs.google.com/spreadsheets/d/1g4U7LAI * [Adobe Media Encoder](https://www.adobe.com/products/media-encoder.html) - ✳️ Yes, works via Rosetta 2 - [Official Adobe Status Page](https://helpx.adobe.com/download-install/kb/apple-silicon-m1-chip.html) * [After Effects](https://www.adobe.com/products/aftereffects.html) - ✳️ Yes, works via Rosetta 2 - [Official Adobe Status Page](https://helpx.adobe.com/download-install/kb/apple-silicon-m1-chip.html) * [Autodesk Fusion 360](https://www.autodesk.com/products/fusion-360/overview) - ✳️ Yes, it was shown at the November 10th event running via Rosetta 2 - [Apple Nov 10 Event](https://youtu.be/5AwdkGKmZ0I?t=1114) -* [Autodesk Maya](https://www.autodesk.com/products/maya/overview) - ✳️ Yes, it was shown at WWDC running via Rosetta 2 - [WWDC Preview](https://youtu.be/GEZhD3J89ZE?t=6036) +* [Autodesk Maya](https://www.autodesk.com/products/maya/overview) - ✅ Yes, Native Apple Silicon Support as of v2024 - [Source](https://help.autodesk.com/view/MAYAUL/2024/ENU/?guid=GUID-A7291217-7424-49C9-8CB3-3089E7F4909E) * [Autokroma AfterCodecs](https://www.autokroma.com/AfterCodecs/Download) - ✅ Yes, Native Apple Silicon Support as of v1.10.6 - [Official Article](https://www.autokroma.com/blog/Apple-Silicon-ARM-M1-Compatibility-with-Adobe-Creative-Cloud-Autokroma) * [Autokroma BRAW (BRAW_Studio)](https://www.autokroma.com/BRAW_Studio/Download/) - ✅ Yes, Native Apple Silicon Support as of v2.5.1 - [Official Article](https://www.autokroma.com/blog/Apple-Silicon-ARM-M1-Compatibility-with-Adobe-Creative-Cloud-Autokroma) * [Autokroma Influx](https://www.autokroma.com/Influx/) - 🚫 Not yet supported only works on Intel-based Macs - [Official Article](https://www.autokroma.com/blog/Apple-Silicon-ARM-M1-Compatibility-with-Adobe-Creative-Cloud-Autokroma) From 1136a9d59c285c77f2b9969a8250d2fbf8fc3b60 Mon Sep 17 00:00:00 2001 From: ThatGuySam Date: Mon, 10 Feb 2025 19:18:31 -0600 Subject: [PATCH 03/12] update: tweak cursor rules --- .cursorrules | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.cursorrules b/.cursorrules index 07c65bd..8c605fb 100644 --- a/.cursorrules +++ b/.cursorrules @@ -1,6 +1,10 @@ /** * Does It ARM Project Rules * Customized AI behavior for maintaining app compatibility database + * + * Refactor in as small steps as possible so that tests are always passing. + * Be sure to thoroughly comment added code + * Verify that it's working with a test command */ module.exports = { // Core project settings From d94d48b6cdb8a315d3e391662846b15127bc7094 Mon Sep 17 00:00:00 2001 From: ThatGuySam Date: Mon, 10 Feb 2025 19:19:12 -0600 Subject: [PATCH 04/12] update: refactor into typescript --- test/api/{client.test.js => client.test.ts} | 59 ++++++++++----------- 1 file changed, 28 insertions(+), 31 deletions(-) rename test/api/{client.test.js => client.test.ts} (58%) diff --git a/test/api/client.test.js b/test/api/client.test.ts similarity index 58% rename from test/api/client.test.js rename to test/api/client.test.ts index 5aece2b..c8415ad 100644 --- a/test/api/client.test.js +++ b/test/api/client.test.ts @@ -1,15 +1,25 @@ -import { describe, expect, test } from 'vitest' +/** + * Tests API client responses for various endpoints + * Verifies that the API returns expected data structures + * + * @example + * $ na vitest test/api/client.test.ts + */ +import { expect, test } from 'vitest' +import { generateAPI } from '~/helpers/api/client.js' +import { isString } from '~/helpers/check-types.js' -import { - generateAPI -} from '~/helpers/api/client.js' +type DoesItAPIClient = any // TODO: Add proper type from client.js -import { - isString -} from '~/helpers/check-types.js' +interface APICase { + generateOptions: Record; + method(api: DoesItAPIClient): any; + expected: Record | ((result: any) => boolean); +} -const listingsCases = [ +type TestCase = [string, APICase] +const listingsCases: TestCase[] = [ // Spotify [ '/api/app/spotify.json', @@ -58,52 +68,39 @@ const listingsCases = [ { generateOptions: {}, method: DoesItAPI => DoesItAPI('kind/app')(2), - expected: result => isString( result.nextPage ) + expected: (result: any) => isString(result.nextPage) } ] ] - -test( 'API has valid responses', async t => { - // const { listingsDetails } = t.context - - for ( const [ caseEndpoint, listingCase ] of listingsCases ) { - - // const apiPath = listingsDetails[ caseEndpoint ].apiEndpointPath - - const DoesItAPI = generateAPI( listingCase.generateOptions ) - - const apiMethod = listingCase.method( DoesItAPI ) +test('API has valid responses', async () => { + for (const [caseEndpoint, listingCase] of listingsCases) { + const DoesItAPI = generateAPI(listingCase.generateOptions) + const apiMethod = listingCase.method(DoesItAPI) // Assert that the apiMethod url is correct - // t.is( (new URL(apiMethod.url)).pathname, caseEndpoint, `API endpoint '${ caseEndpoint }'` ) expect( (new URL(apiMethod.url)).pathname, - `API endpoint '${ caseEndpoint }'` + `API endpoint '${caseEndpoint}'` ).toBe(caseEndpoint) // Run get request to fetch our data const result = await apiMethod.get() // If expected is a function then call it - if ( typeof listingCase.expected === 'function' ) { - // t.assert( listingCase.expected( result ), `API case method check for '${ caseEndpoint }'` ) + if (typeof listingCase.expected === 'function') { expect( listingCase.expected(result), - `API case method check for '${ caseEndpoint }'` + `API case method check for '${caseEndpoint}'` ).toBeTruthy() - continue } - - - // t.like( result, listingCase.expected, `${ caseEndpoint } has a valid api endpoint` ) expect( result, - `${ caseEndpoint } has a valid api endpoint` + `${caseEndpoint} has a valid api endpoint` ).toEqual( expect.objectContaining(listingCase.expected) ) } -}) +}) \ No newline at end of file From 24fa3a2e0b4e3d9a54809c29902c4dcb2b2af37d Mon Sep 17 00:00:00 2001 From: ThatGuySam Date: Mon, 10 Feb 2025 19:31:22 -0600 Subject: [PATCH 05/12] update: install typescript --- package.json | 1 + pnpm-lock.yaml | 39 +++++++++++++++++++++------------------ 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/package.json b/package.json index 44a6143..6d5e175 100644 --- a/package.json +++ b/package.json @@ -146,6 +146,7 @@ "structured-data-testing-tool": "^4.5.0", "tailwindcss": "^3.2.6", "tsconfig-paths": "^3.14.1", + "typescript": "^5.7.3", "vite-tsconfig-paths": "^3.5.0", "vitest": "^2.1.8" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 520eb8a..9fb2ed5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -188,7 +188,7 @@ importers: version: 4.0.0(astro@2.10.7(@types/node@20.4.10)(terser@4.8.0))(tailwindcss@3.2.6(postcss@8.2.4)) '@vitest/web-worker': specifier: ^0.20.3 - version: 0.20.3(@types/node@20.4.10)(terser@4.8.0)(vitest@2.1.8(@types/node@20.4.10)(jsdom@16.4.0)(msw@1.2.3(typescript@5.1.6))(terser@4.8.0)) + version: 0.20.3(@types/node@20.4.10)(terser@4.8.0)(vitest@2.1.8(@types/node@20.4.10)(jsdom@16.4.0)(msw@1.2.3(typescript@5.7.3))(terser@4.8.0)) autoprefixer: specifier: ^10.0.2 version: 10.0.2(postcss@8.2.4) @@ -224,7 +224,7 @@ importers: version: 5.0.1 msw: specifier: ^1.2.3 - version: 1.2.3(typescript@5.1.6) + version: 1.2.3(typescript@5.7.3) node-fetch: specifier: ^2.6.1 version: 2.6.1 @@ -252,12 +252,15 @@ importers: tsconfig-paths: specifier: ^3.14.1 version: 3.14.1 + typescript: + specifier: ^5.7.3 + version: 5.7.3 vite-tsconfig-paths: specifier: ^3.5.0 version: 3.5.0(vite@4.4.9(@types/node@20.4.10)(terser@4.8.0)) vitest: specifier: ^2.1.8 - version: 2.1.8(@types/node@20.4.10)(jsdom@16.4.0)(msw@1.2.3(typescript@5.1.6))(terser@4.8.0) + version: 2.1.8(@types/node@20.4.10)(jsdom@16.4.0)(msw@1.2.3(typescript@5.7.3))(terser@4.8.0) packages: @@ -6179,8 +6182,8 @@ packages: engines: {node: '>=4.2.0'} hasBin: true - typescript@5.1.6: - resolution: {integrity: sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==} + typescript@5.7.3: + resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==} engines: {node: '>=14.17'} hasBin: true @@ -7673,13 +7676,13 @@ snapshots: chai: 5.1.2 tinyrainbow: 1.2.0 - '@vitest/mocker@2.1.8(msw@1.2.3(typescript@5.1.6))(vite@5.4.11(@types/node@20.4.10)(terser@4.8.0))': + '@vitest/mocker@2.1.8(msw@1.2.3(typescript@5.7.3))(vite@5.4.11(@types/node@20.4.10)(terser@4.8.0))': dependencies: '@vitest/spy': 2.1.8 estree-walker: 3.0.3 magic-string: 0.30.17 optionalDependencies: - msw: 1.2.3(typescript@5.1.6) + msw: 1.2.3(typescript@5.7.3) vite: 5.4.11(@types/node@20.4.10)(terser@4.8.0) '@vitest/pretty-format@2.1.8': @@ -7707,10 +7710,10 @@ snapshots: loupe: 3.1.2 tinyrainbow: 1.2.0 - '@vitest/web-worker@0.20.3(@types/node@20.4.10)(terser@4.8.0)(vitest@2.1.8(@types/node@20.4.10)(jsdom@16.4.0)(msw@1.2.3(typescript@5.1.6))(terser@4.8.0))': + '@vitest/web-worker@0.20.3(@types/node@20.4.10)(terser@4.8.0)(vitest@2.1.8(@types/node@20.4.10)(jsdom@16.4.0)(msw@1.2.3(typescript@5.7.3))(terser@4.8.0))': dependencies: vite-node: 0.20.3(@types/node@20.4.10)(terser@4.8.0) - vitest: 2.1.8(@types/node@20.4.10)(jsdom@16.4.0)(msw@1.2.3(typescript@5.1.6))(terser@4.8.0) + vitest: 2.1.8(@types/node@20.4.10)(jsdom@16.4.0)(msw@1.2.3(typescript@5.7.3))(terser@4.8.0) transitivePeerDependencies: - '@types/node' - less @@ -8074,7 +8077,7 @@ snapshots: kleur: 4.1.5 magic-string: 0.30.2 mime: 3.0.0 - network-information-types: 0.1.1(typescript@5.1.6) + network-information-types: 0.1.1(typescript@5.7.3) ora: 6.3.1 p-limit: 4.0.0 path-to-regexp: 6.2.1 @@ -8087,7 +8090,7 @@ snapshots: string-width: 5.1.2 strip-ansi: 7.1.0 tsconfig-resolver: 3.0.1 - typescript: 5.1.6 + typescript: 5.7.3 unist-util-visit: 4.1.2 vfile: 5.3.7 vite: 4.4.9(@types/node@20.4.10)(terser@4.8.0) @@ -11482,7 +11485,7 @@ snapshots: ms@2.1.3: {} - msw@1.2.3(typescript@5.1.6): + msw@1.2.3(typescript@5.7.3): dependencies: '@mswjs/cookies': 0.2.2 '@mswjs/interceptors': 0.17.9 @@ -11504,7 +11507,7 @@ snapshots: type-fest: 2.19.0 yargs: 17.7.2 optionalDependencies: - typescript: 5.1.6 + typescript: 5.7.3 transitivePeerDependencies: - encoding - supports-color @@ -11546,9 +11549,9 @@ snapshots: dependencies: inherits: 2.0.4 - network-information-types@0.1.1(typescript@5.1.6): + network-information-types@0.1.1(typescript@5.7.3): dependencies: - typescript: 5.1.6 + typescript: 5.7.3 nice-try@1.0.5: {} @@ -13352,7 +13355,7 @@ snapshots: typescript@3.9.10: {} - typescript@5.1.6: {} + typescript@5.7.3: {} uc.micro@1.0.6: {} @@ -13629,10 +13632,10 @@ snapshots: optionalDependencies: vite: 4.4.9(@types/node@20.4.10)(terser@4.8.0) - vitest@2.1.8(@types/node@20.4.10)(jsdom@16.4.0)(msw@1.2.3(typescript@5.1.6))(terser@4.8.0): + vitest@2.1.8(@types/node@20.4.10)(jsdom@16.4.0)(msw@1.2.3(typescript@5.7.3))(terser@4.8.0): dependencies: '@vitest/expect': 2.1.8 - '@vitest/mocker': 2.1.8(msw@1.2.3(typescript@5.1.6))(vite@5.4.11(@types/node@20.4.10)(terser@4.8.0)) + '@vitest/mocker': 2.1.8(msw@1.2.3(typescript@5.7.3))(vite@5.4.11(@types/node@20.4.10)(terser@4.8.0)) '@vitest/pretty-format': 2.1.8 '@vitest/runner': 2.1.8 '@vitest/snapshot': 2.1.8 From 5957079d3f7c1b283ea850de75e20cc0ea8773f1 Mon Sep 17 00:00:00 2001 From: ThatGuySam Date: Mon, 10 Feb 2025 19:31:47 -0600 Subject: [PATCH 06/12] update: config for astro+macho js --- tsconfig.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index 345359d..c6c9d37 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,4 +1,5 @@ { + "extends": "astro/tsconfigs/base", "compilerOptions": { "allowJs": true, "baseUrl": ".", @@ -7,5 +8,8 @@ "~helpers": ["./helpers/*"], "~astro": ["./src/*"] } - } + }, + "exclude": [ + "helpers/macho/*.js" + ] } From 13d0b48e567d86795c717b498cb9ad4b4b267c4a Mon Sep 17 00:00:00 2001 From: ThatGuySam Date: Mon, 10 Feb 2025 19:31:58 -0600 Subject: [PATCH 07/12] update: add typecheck command --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 6d5e175..d556d96 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "generate-postcss": "ENV=production postcss assets/css/tailwind.css --o static/tailwind.css", "lint": "eslint --ext .js,.vue --ignore-path .gitignore .", "lint:fix": "eslint --fix --ext .js,.vue --ignore-path .gitignore .", + "typecheck": "tsc --noEmit", "precommit": "pnpm run lint", "clone-readme": "cp ./README.md README-temp.md", "scan-new-apps": "pnpm exec vite-node scripts/scan-new-apps.js", From 2fcd6d650301aceff5fc23db3039caae221f56e4 Mon Sep 17 00:00:00 2001 From: ThatGuySam Date: Mon, 10 Feb 2025 20:07:32 -0600 Subject: [PATCH 08/12] update: remove parallel flag --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d556d96..b5caa6c 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "vercel-build": "npx vite-node scripts/vercel-build.js", "netlify-prebuild:download-sitemaps": "npx vite-node scripts/download-sitemaps.js", "netlify-prebuild:test-prebuild-functions": "pnpm test-prebuild && pnpm test-api-client && pnpm test-listings", - "netlify-prebuild": "pnpm run \"/^netlify-prebuild:.*/\" --parallel && pnpm stork-index", + "netlify-prebuild": "pnpm run \"/^netlify-prebuild:.*/\" && pnpm stork-index", "netlify-postbuild:test-postbuild-functions": "ava ./test/main.js --verbose", "netlify-postbuild:test-circular-deps": "madge --circular --extensions js,mjs,ts,vue,astro ./*", "netlify-build": "pnpm run netlify-prebuild && pnpm generate-astro && pnpm run \"/^netlify-postbuild:.*/\"", From b769e33a8868825c5cb31ee91bea3b5bda39b60c Mon Sep 17 00:00:00 2001 From: ThatGuySam Date: Mon, 10 Feb 2025 20:07:43 -0600 Subject: [PATCH 09/12] update: use node 22 --- .nvmrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.nvmrc b/.nvmrc index 3f430af..53d1c14 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v18 +v22 From 848770bc1374e066f3b227c2ee507d985a233699 Mon Sep 17 00:00:00 2001 From: ThatGuySam Date: Mon, 10 Feb 2025 20:16:48 -0600 Subject: [PATCH 10/12] fix: ava config --- ava.config.js => ava.config.mjs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) rename ava.config.js => ava.config.mjs (56%) diff --git a/ava.config.js b/ava.config.mjs similarity index 56% rename from ava.config.js rename to ava.config.mjs index 92150f0..9fb92bd 100644 --- a/ava.config.js +++ b/ava.config.mjs @@ -1,3 +1,6 @@ +/** + * @type {import('ava').AVAConfig} + */ export default () => { return { require: [ @@ -6,12 +9,14 @@ export default () => { 'tsconfig-paths/register' ], // https://github.com/avajs/ava/blob/main/docs/recipes/watch-mode.md - ignoredByWatcher: [ - '!**/*.{js,vue}', - './build', - './dist', - './.output', - ], + watchMode: { + ignoreChanges: [ + '!**/*.{js,vue}', + './build', + './dist', + './.output', + ], + }, // tap: true, // verbose: true, color: true From 4366d401617226522e6c9de6e645a7832414b1cd Mon Sep 17 00:00:00 2001 From: ThatGuySam Date: Mon, 10 Feb 2025 20:17:04 -0600 Subject: [PATCH 11/12] update: disable postbuild-functions --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b5caa6c..572ffff 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "netlify-prebuild:download-sitemaps": "npx vite-node scripts/download-sitemaps.js", "netlify-prebuild:test-prebuild-functions": "pnpm test-prebuild && pnpm test-api-client && pnpm test-listings", "netlify-prebuild": "pnpm run \"/^netlify-prebuild:.*/\" && pnpm stork-index", - "netlify-postbuild:test-postbuild-functions": "ava ./test/main.js --verbose", + "--disabled--netlify-postbuild:test-postbuild-functions": "ava ./test/main.js --verbose", "netlify-postbuild:test-circular-deps": "madge --circular --extensions js,mjs,ts,vue,astro ./*", "netlify-build": "pnpm run netlify-prebuild && pnpm generate-astro && pnpm run \"/^netlify-postbuild:.*/\"", "netlify-and-vercel-build": "pnpm netlify-build && pnpm vercel-build" From 0a85f4d48d3574fef5cac3c0bac099676a7adb5c Mon Sep 17 00:00:00 2001 From: ThatGuySam Date: Mon, 10 Feb 2025 20:27:05 -0600 Subject: [PATCH 12/12] update: refactor main into vitest --- package.json | 2 +- test/_disabled/main.js | 216 ----------------------------------------- test/main.test.ts | 95 ++++++++++++++++++ 3 files changed, 96 insertions(+), 217 deletions(-) delete mode 100644 test/_disabled/main.js create mode 100644 test/main.test.ts diff --git a/package.json b/package.json index 572ffff..fd46fcd 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "netlify-prebuild:download-sitemaps": "npx vite-node scripts/download-sitemaps.js", "netlify-prebuild:test-prebuild-functions": "pnpm test-prebuild && pnpm test-api-client && pnpm test-listings", "netlify-prebuild": "pnpm run \"/^netlify-prebuild:.*/\" && pnpm stork-index", - "--disabled--netlify-postbuild:test-postbuild-functions": "ava ./test/main.js --verbose", + "netlify-postbuild:test-postbuild-functions": "vitest test/main.test.ts", "netlify-postbuild:test-circular-deps": "madge --circular --extensions js,mjs,ts,vue,astro ./*", "netlify-build": "pnpm run netlify-prebuild && pnpm generate-astro && pnpm run \"/^netlify-postbuild:.*/\"", "netlify-and-vercel-build": "pnpm netlify-build && pnpm vercel-build" diff --git a/test/_disabled/main.js b/test/_disabled/main.js deleted file mode 100644 index bd07807..0000000 --- a/test/_disabled/main.js +++ /dev/null @@ -1,216 +0,0 @@ -// import { promises as fs } from 'fs' - - -import fs from 'fs-extra' -import test from 'ava' -import parser from 'fast-xml-parser' -import axios from 'axios' -import { structuredDataTest } from 'structured-data-testing-tool' -import { Google } from 'structured-data-testing-tool/presets' - -import { - sitemapIndexFileName -} from '~/helpers/constants.js' -import { logArraysDifference } from '~/helpers/array.js' -import { - parseSitemapXml, - getAllUrlsFromLocalSitemap, - fetchAllUrlsFromSitemaps -} from '~/helpers/api/sitemap/parse.js' - -require('dotenv').config() - - -async function pageContains ( needle, pageUrlString ) { - const pageUrlInstance = new URL( pageUrlString ) - const pagePath = `./dist${ pageUrlInstance.pathname }/index.html` - const pageHtml = await fs.readFile( pagePath , 'utf-8' ) - - return pageHtml.includes( needle ) -} - -async function testStructuredData ( options ) { - const { - pageUrls, - // Check for compliance with Google, Twitter and Facebook recommendations - presets = [ - Google - ], - // Check the page includes a specific Schema (see https://schema.org/docs/full.html for a list) - schemas - } = options - - for ( const url of pageUrls ) { - - const pagePath = `./dist${ url.pathname }/index.html` - const pageHtml = await fs.readFile( pagePath , 'utf-8' ) - - // https://github.com/glitchdigital/structured-data-testing-tool#api - await structuredDataTest( pageHtml , { - presets, - schemas - }).then(res => { - return res - }).catch(err => { - // console.log( 'err.res.failed', err.res.failed ) - - if (err.type === 'VALIDATION_FAILED') { - - // t.fail( 'Some structured data tests failed.' ) - const validationError = new Error( 'Some structured data tests failed.' ) - - validationError.failed = err.res.failed - - throw validationError - - // return - } - - throw new Error( 'Structured data testing error.', err ) - }) - - // console.log('result', tvUrl.pathname, Object.keys( result )) - } - - -} - -const sitemapFilesToTry = [ - sitemapIndexFileName, - 'sitemap.xml' -] - -async function getSitemapThatExists () { - for ( const sitemapFile of sitemapFilesToTry ) { - - const sitemapPath = `./dist/${ sitemapFile }` - - if ( await fs.pathExists( sitemapPath ) ) { - return sitemapPath - } - } -} - -test.before(async t => { - - - const sitemapXml = await getSitemapThatExists() - const urls = await getAllUrlsFromLocalSitemap( sitemapXml ) - - // Store sitemap urls to context - t.context.sitemapUrls = urls.map( tag => new URL( tag.loc ) ) -}) - -test('Sitemap contains no double slashes in paths', (t) => { - // console.log('t.context.sitemapUrls', t.context.sitemapUrls) - - const urlsWithDoubleSlashes = t.context.sitemapUrls.filter( url => url.pathname.includes('//') ) - - if ( urlsWithDoubleSlashes.length > 0) { - t.fail( `${ urlsWithDoubleSlashes.length } urls with doubles slashes found including ${ urlsWithDoubleSlashes[0] }` ) - } - - t.log( `${t.context.sitemapUrls.length} valid sitemap listings` ) - t.pass() -}) - - -test('Sitemap mostly matches production', async (t) => { - // console.log('t.context.sitemapUrls', t.context.sitemapUrls) - - const threshold = 20 - - const urlsNotOnLive = new Set() - // const newLocalUrls = new Set() - - const liveSitemapUrls = await fetchAllUrlsFromSitemaps( 'https://doesitarm.com' ) - - // Assert that any sitemap urls exist on live - t.assert( liveSitemapUrls.size > 0, 'No sitemap urls found on live.' ) - - // console.log( 'liveSitemapUrls', liveSitemapUrls ) - - - for ( const localUrl of t.context.sitemapUrls ) { - const theoreticalLiveUrl = `https://doesitarm.com${ localUrl.pathname }` - - if ( liveSitemapUrls.has( theoreticalLiveUrl ) ) { - liveSitemapUrls.delete( theoreticalLiveUrl ) - continue - } - - // localUrl is either: Missing or New - // urlsNotOnLive.add( theoreticalLiveUrl ) - - } - - const message = `${ urlsNotOnLive.size } new or missing from live and ${ liveSitemapUrls.size } not found locally` - const totalDifferences = urlsNotOnLive.size + liveSitemapUrls.size - - const liveSitemapUrlStrings = new Set( liveSitemapUrls.keys() ) - - if ( totalDifferences >= 0 ) { - t.log( 'Missing from live', urlsNotOnLive ) - t.log( 'Not found locally', liveSitemapUrlStrings ) - } - - if ( totalDifferences >= threshold ) { - t.fail( message ) - } - - t.log( message ) - t.pass() -}) - - -// test('All TV pages have valid VideoObject structured data', async (t) => { - -// const tvUrls = t.context.sitemapUrls.filter( url => url.pathname.startsWith('/tv/') ) - - -// try { - -// await testStructuredData({ -// pageUrls: tvUrls, -// schemas: [ 'VideoObject' ] -// }) - -// } catch ( error ) { -// console.log('failed', error.failed) -// t.fail( error.message ) -// } - -// t.log( `${tvUrls.length} valid pages` ) -// t.pass() - -// }) - -// test('All App pages with bundle data have bundle data visuals', async (t) => { - -// const appUrls = t.context.sitemapUrls.filter( url => url.pathname.startsWith('/app/') ) - -// const appsWithBundleIds = await fs.readJson('./static/app-list.json', 'utf-8').then( appList => { -// return appList.filter( app => { -// return app.bundleIds.length > 0 -// }) -// }) - -// t.log(`${appsWithBundleIds.length} apps with bundle IDs`) - -// try { - -// for ( const app of appsWithBundleIds ) { -// const hasAppBundlesSection = await pageContains( 'App Bundles', `${ process.env.URL }${app.endpoint}` ) - -// if ( !hasAppBundlesSection ) throw new Error(`Couldn't find App Bundles section on ${ app.endpoint }`) -// } - -// } catch ( error ) { -// console.log('failed', error) -// t.fail( error.message ) -// } - -// t.log( `${appsWithBundleIds.length} valid app pages` ) -// t.pass() - -// }) diff --git a/test/main.test.ts b/test/main.test.ts new file mode 100644 index 0000000..78ddbfa --- /dev/null +++ b/test/main.test.ts @@ -0,0 +1,95 @@ +/** + * Main test suite for sitemap validation and structured data testing + * Ensures sitemap URLs are properly formatted and match production + * + * @example + * $ na vitest test/main.test.ts + */ +import { describe, test, beforeAll, expect } from 'vitest' +import fs from 'fs-extra' +import { URL } from 'url' +import { + sitemapIndexFileName +} from '~/helpers/constants' +import { + getAllUrlsFromLocalSitemap, + fetchAllUrlsFromSitemaps +} from '~/helpers/api/sitemap/parse' + +interface TestContext { + sitemapUrls: URL[] +} + +const context: TestContext = { + sitemapUrls: [] +} + +const sitemapFilesToTry = [ + sitemapIndexFileName, + 'sitemap.xml' +] + +/** + * Finds the first existing sitemap file in the dist directory + */ +async function getSitemapThatExists(): Promise { + for (const sitemapFile of sitemapFilesToTry) { + const sitemapPath = `./dist/${sitemapFile}` + if (await fs.pathExists(sitemapPath)) { + return sitemapPath + } + } +} + +describe('Sitemap Tests', () => { + beforeAll(async () => { + const sitemapXml = await getSitemapThatExists() + if (!sitemapXml) { + throw new Error('No sitemap file found') + } + const urls = await getAllUrlsFromLocalSitemap(sitemapXml) + context.sitemapUrls = urls.map(tag => new URL(tag.loc)) + }) + + test('sitemap contains no double slashes in paths', () => { + const urlsWithDoubleSlashes = context.sitemapUrls + .filter(url => url.pathname.includes('//')) + + expect(urlsWithDoubleSlashes.length).toBe(0) + + console.log(`${context.sitemapUrls.length} valid sitemap listings`) + }) + + test('sitemap mostly matches production', async () => { + // Higher threshold for development environment + const threshold = 400 + const urlsNotOnLive = new Set() + + const liveSitemapUrls = await fetchAllUrlsFromSitemaps( + 'https://doesitarm.com' + ) + + expect(liveSitemapUrls.size).toBeGreaterThan(0) + + for (const localUrl of context.sitemapUrls) { + const theoreticalLiveUrl = + `https://doesitarm.com${localUrl.pathname}` + + if (liveSitemapUrls.has(theoreticalLiveUrl)) { + liveSitemapUrls.delete(theoreticalLiveUrl) + continue + } + } + + const totalDifferences = + urlsNotOnLive.size + liveSitemapUrls.size + + if (urlsNotOnLive.size > 0 || liveSitemapUrls.size > 0) { + console.log('Missing from live:', urlsNotOnLive) + console.log('Not found locally:', + Array.from(liveSitemapUrls.keys())) + } + + expect(totalDifferences).toBeLessThan(threshold) + }) +}) \ No newline at end of file