-
Notifications
You must be signed in to change notification settings - Fork 11
feat(API): Create CLI #7
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
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
fe987df
feat(API): Create CLI
wise-king-sullyman 5ecdd6e
Fix dynamic content types
wise-king-sullyman 9eb9d29
Add CLI building to CI
wise-king-sullyman 6e3c01d
feat(cli): automate setup process
wise-king-sullyman d2ee84b
fix(cli): change config file extension to mjs
wise-king-sullyman eeabf54
fix(CLI): ensure that the config exists before doing a build
wise-king-sullyman File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| __tests__ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| import { createCollectionContent } from '../createCollectionContent' | ||
| import { getConfig } from '../getConfig' | ||
| import { writeFile } from 'fs/promises' | ||
|
|
||
| jest.mock('../getConfig') | ||
| jest.mock('fs/promises') | ||
|
|
||
| // suppress console.log so that it doesn't clutter the test output | ||
| jest.spyOn(console, 'log').mockImplementation(() => {}) | ||
|
|
||
| it('should call getConfig with the passed config file location', async () => { | ||
| await createCollectionContent('/foo/', 'bar', false) | ||
|
|
||
| expect(getConfig).toHaveBeenCalledWith('bar') | ||
| }) | ||
|
|
||
| it('should not proceed if config is not found', async () => { | ||
| ;(getConfig as jest.Mock).mockResolvedValue(undefined) | ||
|
|
||
| await createCollectionContent('/foo/', 'bar', false) | ||
|
|
||
| expect(writeFile).not.toHaveBeenCalled() | ||
| }) | ||
|
|
||
| it('should log error if content is not found in config', async () => { | ||
| ;(getConfig as jest.Mock).mockResolvedValue({ foo: 'bar' }) | ||
|
|
||
| const mockConsoleError = jest.fn() | ||
| jest.spyOn(console, 'error').mockImplementation(mockConsoleError) | ||
|
|
||
| await createCollectionContent('/foo/', 'bar', false) | ||
|
|
||
| expect(mockConsoleError).toHaveBeenCalledWith('No content found in config') | ||
| expect(writeFile).not.toHaveBeenCalled() | ||
| }) | ||
|
|
||
| it('should call writeFile with the expected file location and content without throwing any errors', async () => { | ||
| ;(getConfig as jest.Mock).mockResolvedValue({ content: { key: 'value' } }) | ||
|
|
||
| const mockConsoleError = jest.fn() | ||
| jest.spyOn(console, 'error').mockImplementation(mockConsoleError) | ||
|
|
||
| await createCollectionContent('/foo/', 'bar', false) | ||
|
|
||
| expect(writeFile).toHaveBeenCalledWith( | ||
| '/foo/src/content.ts', | ||
| `export const content = ${JSON.stringify({ key: 'value' })}`, | ||
| ) | ||
| expect(mockConsoleError).not.toHaveBeenCalled() | ||
| }) | ||
|
|
||
| it('should log error if writeFile throws an error', async () => { | ||
| ;(getConfig as jest.Mock).mockResolvedValue({ content: { key: 'value' } }) | ||
|
|
||
| const mockConsoleError = jest.fn() | ||
| jest.spyOn(console, 'error').mockImplementation(mockConsoleError) | ||
|
|
||
| const error = new Error('error') | ||
| ;(writeFile as jest.Mock).mockRejectedValue(error) | ||
|
|
||
| await createCollectionContent('/foo/', 'bar', false) | ||
|
|
||
| expect(mockConsoleError).toHaveBeenCalledWith( | ||
| 'Error writing content file', | ||
| error, | ||
| ) | ||
| }) | ||
|
|
||
| it('should log that content file was created when run in verbose mode', async () => { | ||
| const mockConsoleLog = jest.fn() | ||
| jest.spyOn(console, 'log').mockImplementation(mockConsoleLog) | ||
|
|
||
| await createCollectionContent('/foo/', 'bar', true) | ||
|
|
||
| expect(mockConsoleLog).toHaveBeenCalledWith('Content file created') | ||
| }) | ||
|
|
||
| it('should not log that content file was created when not run in verbose mode', async () => { | ||
| const mockConsoleLog = jest.fn() | ||
| jest.spyOn(console, 'log').mockImplementation(mockConsoleLog) | ||
|
|
||
| await createCollectionContent('/foo/', 'bar', false) | ||
|
|
||
| expect(mockConsoleLog).not.toHaveBeenCalled() | ||
| }) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| /* eslint-disable no-console */ | ||
|
|
||
| import { createConfigFile } from '../createConfigFile.ts' | ||
| import { access, copyFile } from 'fs/promises' | ||
|
|
||
| jest.mock('fs/promises') | ||
|
|
||
| afterEach(() => { | ||
| jest.clearAllMocks() | ||
| }) | ||
|
|
||
| // suppress console calls so that it doesn't clutter the test output | ||
| jest.spyOn(console, 'log').mockImplementation(() => {}) | ||
| jest.spyOn(console, 'error').mockImplementation(() => {}) | ||
|
|
||
| it('should log a message and not call copyFile if the config file already exists', async () => { | ||
| ;(access as jest.Mock).mockResolvedValue(true) | ||
|
|
||
| await createConfigFile('/astro', '/consumer') | ||
|
|
||
| expect(copyFile).not.toHaveBeenCalled() | ||
| expect(console.log).toHaveBeenCalledWith( | ||
| 'pf-docs.config.mjs already exists, proceeding to next setup step', | ||
| ) | ||
| }) | ||
|
|
||
| it('should copy the template file if the config file does not exist', async () => { | ||
| ;(access as jest.Mock).mockRejectedValue(new Error()) | ||
| ;(copyFile as jest.Mock).mockResolvedValue(undefined) | ||
|
|
||
| const from = '/astro/cli/templates/pf-docs.config.mjs' | ||
| const to = '/consumer/pf-docs.config.mjs' | ||
|
|
||
| await createConfigFile('/astro', '/consumer') | ||
|
|
||
| expect(copyFile).toHaveBeenCalledWith(from, to) | ||
| expect(console.log).toHaveBeenCalledWith( | ||
| 'pf-docs.config.mjs has been created in /consumer', | ||
| ) | ||
| }) | ||
|
|
||
| it('should log an error if copyFile fails', async () => { | ||
| ;(access as jest.Mock).mockRejectedValue(new Error()) | ||
| ;(copyFile as jest.Mock).mockRejectedValue(new Error('copy failed')) | ||
|
|
||
| await createConfigFile('/astro', '/consumer') | ||
|
|
||
| expect(console.error).toHaveBeenCalledWith( | ||
| 'Error creating pf-docs.config.mjs in /consumer.', | ||
| ) | ||
| expect(console.error).toHaveBeenCalledWith(new Error('copy failed')) | ||
| }) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| import { getConfig } from '../getConfig' | ||
| import { resolve } from 'path' | ||
|
|
||
| it('should return the config when pf-docs.config.mjs exists', async () => { | ||
| const config = await getConfig(resolve('./cli/testData/good.config.js')) | ||
| expect(config).toEqual({ | ||
| config: { | ||
| content: [ | ||
| { | ||
| base: 'base-path', | ||
| packageName: 'package-name', | ||
| pattern: 'pattern', | ||
| name: 'name', | ||
| }, | ||
| ], | ||
| }, | ||
| }) | ||
| }) | ||
|
|
||
| it('should return undefined and log error when pf-docs.config.mjs does not exist', async () => { | ||
| const consoleErrorMock = jest.fn() | ||
|
|
||
| jest.spyOn(console, 'error').mockImplementation(consoleErrorMock) | ||
|
|
||
| const config = await getConfig('foo') | ||
| expect(config).toBeUndefined() | ||
| expect(consoleErrorMock).toHaveBeenCalledWith( | ||
| 'pf-docs.config.mjs not found, have you created it at the root of your package?', | ||
| ) | ||
| }) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| import { readFile, writeFile } from 'fs/promises' | ||
| import { setFsRootDir } from '../setFsRootDir' | ||
|
|
||
| jest.mock('fs/promises') | ||
|
|
||
| // suppress console.log so that it doesn't clutter the test output | ||
| jest.spyOn(console, 'log').mockImplementation(() => {}) | ||
|
|
||
| it('should attempt to read the astro config file', async () => { | ||
| ;(readFile as jest.Mock).mockResolvedValue("{ fs: { allow: ['/bar/'] } }") | ||
|
|
||
| await setFsRootDir('/foo/', '/bar') | ||
|
|
||
| expect(readFile).toHaveBeenCalledWith('/foo/astro.config.mjs', 'utf8') | ||
| }) | ||
|
|
||
| it('should not modify the file if the default allow list is not present', async () => { | ||
| ;(readFile as jest.Mock).mockResolvedValue("{ fs: { allow: ['/bar/'] } }") | ||
|
|
||
| await setFsRootDir('/foo/', '/bar') | ||
|
|
||
| expect(writeFile).not.toHaveBeenCalled() | ||
| }) | ||
|
|
||
| it('should modify the file if the default allow list is present', async () => { | ||
| ;(readFile as jest.Mock).mockResolvedValue("{ fs: { allow: ['./'] } }") | ||
|
|
||
| await setFsRootDir('/foo/', '/bar') | ||
|
|
||
| expect(writeFile).toHaveBeenCalledWith( | ||
| '/foo/astro.config.mjs', | ||
| "{ fs: { allow: ['/bar/'] } }", | ||
| ) | ||
| }) | ||
|
|
||
| it('should log an error if writing the file fails', async () => { | ||
| ;(readFile as jest.Mock).mockResolvedValue("{ fs: { allow: ['./'] } }") | ||
| ;(writeFile as jest.Mock).mockRejectedValue(new Error('write error')) | ||
| const consoleErrorSpy = jest | ||
| .spyOn(console, 'error') | ||
| .mockImplementation(() => {}) | ||
|
|
||
| await setFsRootDir('/foo/', '/bar') | ||
|
|
||
| expect(consoleErrorSpy).toHaveBeenCalledWith( | ||
| `Error setting the server allow list in /foo/`, | ||
| expect.any(Error), | ||
| ) | ||
| }) | ||
|
|
||
| it('should log a success message after attempting to write the file', async () => { | ||
| ;(readFile as jest.Mock).mockResolvedValue("{ fs: { allow: ['./'] } }") | ||
| const consoleLogSpy = jest.spyOn(console, 'log').mockImplementation(() => {}) | ||
|
|
||
| await setFsRootDir('/foo/', '/bar') | ||
|
|
||
| expect(consoleLogSpy).toHaveBeenCalledWith('fs value set created') | ||
| }) |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.