-
Notifications
You must be signed in to change notification settings - Fork 384
test: template pack edge cases #3497
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,3 +1,4 @@ | ||||||||||||||
| import {execFileSync} from 'node:child_process'; | ||||||||||||||
| import {cp, readFile, writeFile} from 'node:fs/promises'; | ||||||||||||||
| import {join} from 'node:path'; | ||||||||||||||
| import {describe, expect, it} from 'vitest'; | ||||||||||||||
|
|
@@ -12,6 +13,23 @@ const DEPENDENCY_SECTIONS = [ | |||||||||||||
| 'optionalDependencies', | ||||||||||||||
| ] as const; | ||||||||||||||
|
|
||||||||||||||
| function getCatalogVersion(sourceTemplateDir: string, packageName: string) { | ||||||||||||||
| const catalogVersion = execFileSync( | ||||||||||||||
| 'pnpm', | ||||||||||||||
| ['config', 'get', `catalog.${packageName}`, '--location', 'project'], | ||||||||||||||
| { | ||||||||||||||
| cwd: sourceTemplateDir, | ||||||||||||||
| encoding: 'utf8', | ||||||||||||||
| }, | ||||||||||||||
| ).trim(); | ||||||||||||||
|
|
||||||||||||||
| if (!catalogVersion || catalogVersion === 'undefined') { | ||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: this
Suggested change
non-blocking |
||||||||||||||
| throw new Error(`Expected pnpm catalog entry for ${packageName}.`); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| return catalogVersion; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| describe('replaceWorkspaceProtocolVersions', () => { | ||||||||||||||
| it('replaces workspace protocol versions in copied templates', async () => { | ||||||||||||||
| await inTemporaryDirectory(async (tmpDir) => { | ||||||||||||||
|
|
@@ -21,6 +39,10 @@ describe('replaceWorkspaceProtocolVersions', () => { | |||||||||||||
| await cp(sourceTemplateDir, copiedTemplateDir, {recursive: true}); | ||||||||||||||
|
|
||||||||||||||
| const copiedPackageJsonPath = join(copiedTemplateDir, 'package.json'); | ||||||||||||||
| const expectedReactVersion = getCatalogVersion( | ||||||||||||||
| sourceTemplateDir, | ||||||||||||||
| 'react', | ||||||||||||||
| ); | ||||||||||||||
| const copiedPackageJsonBefore = JSON.parse( | ||||||||||||||
| await readFile(copiedPackageJsonPath, 'utf8'), | ||||||||||||||
| ) as Record<string, Record<string, string> | undefined>; | ||||||||||||||
|
|
@@ -52,6 +74,72 @@ describe('replaceWorkspaceProtocolVersions', () => { | |||||||||||||
| expect(version.startsWith('catalog:')).toBe(false); | ||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (threading) Re: line 52 - I think the comment on the non-blocking |
||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| expect(copiedPackageJson.dependencies?.react).toBe(expectedReactVersion); | ||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the happy-path test should also positively assert a The new I think adding one positive spot-check would close this gap:
Suggested change
non-blocking (but in a "we definitely should do this, but i'm okay if you want to do it as a follow up PR" way)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this sounds sensible yeah |
||||||||||||||
| }); | ||||||||||||||
| }); | ||||||||||||||
|
|
||||||||||||||
| it('throws a clear error when a workspace dependency is missing from the packed manifest', async () => { | ||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: the two error-path tests share ~18 lines of identical scaffolding (copy skeleton, read JSON, inject fake dep, write, assert rejection). At two instances this is at the boundary - I'm fine with keeping them inline since each test reads top-to-bottom as a self-contained story. But if a third error case is added (e.g., testing non-blocking
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. agreed! i also draw the line at 2 hahah |
||||||||||||||
| await inTemporaryDirectory(async (tmpDir) => { | ||||||||||||||
| const sourceTemplateDir = getSkeletonSourceDir(); | ||||||||||||||
| const copiedTemplateDir = join(tmpDir, 'skeleton-copy'); | ||||||||||||||
|
|
||||||||||||||
| await cp(sourceTemplateDir, copiedTemplateDir, {recursive: true}); | ||||||||||||||
|
|
||||||||||||||
| const copiedPackageJsonPath = join(copiedTemplateDir, 'package.json'); | ||||||||||||||
| const copiedPackageJsonBefore = JSON.parse( | ||||||||||||||
| await readFile(copiedPackageJsonPath, 'utf8'), | ||||||||||||||
| ) as Record<string, Record<string, string> | undefined>; | ||||||||||||||
|
|
||||||||||||||
| copiedPackageJsonBefore.dependencies ??= {}; | ||||||||||||||
| copiedPackageJsonBefore.dependencies['@shopify/does-not-exist'] = | ||||||||||||||
| 'workspace:*'; | ||||||||||||||
|
|
||||||||||||||
| await writeFile( | ||||||||||||||
| copiedPackageJsonPath, | ||||||||||||||
| `${JSON.stringify(copiedPackageJsonBefore, null, 2)}\n`, | ||||||||||||||
| ); | ||||||||||||||
|
|
||||||||||||||
| await expect( | ||||||||||||||
| replaceWorkspaceProtocolVersions({ | ||||||||||||||
| sourceTemplateDir, | ||||||||||||||
| targetTemplateDir: copiedTemplateDir, | ||||||||||||||
| }), | ||||||||||||||
| ).rejects.toThrow( | ||||||||||||||
| 'Unable to resolve @shopify/does-not-exist from dependencies in packed template manifest.', | ||||||||||||||
| ); | ||||||||||||||
| }); | ||||||||||||||
| }); | ||||||||||||||
|
|
||||||||||||||
| it('throws a clear error when a catalog dependency is missing from the packed manifest', async () => { | ||||||||||||||
| await inTemporaryDirectory(async (tmpDir) => { | ||||||||||||||
| const sourceTemplateDir = getSkeletonSourceDir(); | ||||||||||||||
| const copiedTemplateDir = join(tmpDir, 'skeleton-copy'); | ||||||||||||||
|
|
||||||||||||||
| await cp(sourceTemplateDir, copiedTemplateDir, {recursive: true}); | ||||||||||||||
|
|
||||||||||||||
| const copiedPackageJsonPath = join(copiedTemplateDir, 'package.json'); | ||||||||||||||
| const copiedPackageJsonBefore = JSON.parse( | ||||||||||||||
| await readFile(copiedPackageJsonPath, 'utf8'), | ||||||||||||||
| ) as Record<string, Record<string, string> | undefined>; | ||||||||||||||
|
|
||||||||||||||
| copiedPackageJsonBefore.dependencies ??= {}; | ||||||||||||||
| copiedPackageJsonBefore.dependencies['@shopify/catalog-does-not-exist'] = | ||||||||||||||
| 'catalog:'; | ||||||||||||||
|
|
||||||||||||||
| await writeFile( | ||||||||||||||
| copiedPackageJsonPath, | ||||||||||||||
| `${JSON.stringify(copiedPackageJsonBefore, null, 2)}\n`, | ||||||||||||||
| ); | ||||||||||||||
|
|
||||||||||||||
| await expect( | ||||||||||||||
| replaceWorkspaceProtocolVersions({ | ||||||||||||||
| sourceTemplateDir, | ||||||||||||||
| targetTemplateDir: copiedTemplateDir, | ||||||||||||||
| }), | ||||||||||||||
| ).rejects.toThrow( | ||||||||||||||
| 'Unable to resolve @shopify/catalog-does-not-exist from dependencies in packed template manifest.', | ||||||||||||||
| ); | ||||||||||||||
| }); | ||||||||||||||
| }); | ||||||||||||||
| }); | ||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TIL you can do this to get configs from pnpm and it will be monorepo aware but scoped to the right project, really cool
i was trying to do this with regexes reading the yaml, considered a yaml parser but this is even better