-
Notifications
You must be signed in to change notification settings - Fork 1
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
Enhance Frontend CI with Testing #81
Changes from all commits
86a3fd3
a2fa9c5
805f42c
8c43185
f9146cd
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 |
---|---|---|
|
@@ -8,7 +8,8 @@ | |
"lint:turbo": "turbo lint", | ||
"lint:packageVersion": "syncpack list-mismatches", | ||
"fmt:turbo": "turbo fmt", | ||
"gen:turbo": "turbo gen" | ||
"gen:turbo": "turbo gen", | ||
"test:turbo": "turbo test" | ||
}, | ||
"packageManager": "[email protected]+sha512.0a203ffaed5a3f63242cd064c8fb5892366c103e328079318f78062f24ea8c9d50bc6a47aa3567cabefd824d170e78fa2745ed1f16b132e16436146b7688f19b", | ||
"devDependencies": { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,107 +1,3 @@ | ||
import fs from 'node:fs' | ||
import path from 'node:path' | ||
import { fileURLToPath } from 'node:url' | ||
import { Command } from 'commander' | ||
import { build, createServer, preview } from 'vite' | ||
import { program } from '../src/index.js' | ||
|
||
const __filename = fileURLToPath(import.meta.url) | ||
const __dirname = path.dirname(__filename) | ||
const root = path.resolve(__dirname, '../..') | ||
const publicDir = path.join(process.cwd(), 'public') | ||
const outDir = path.join(process.cwd(), 'dist') | ||
|
||
function runPreprocess(inputPath: string | null) { | ||
if (inputPath && !fs.existsSync(inputPath)) { | ||
throw new Error('Invalid input path. Please provide a valid .sql file.') | ||
} | ||
|
||
const sqlContent = inputPath ? fs.readFileSync(inputPath, 'utf8') : '{}' | ||
const filePath = path.join(publicDir, 'schema.json') | ||
|
||
if (!fs.existsSync(publicDir)) { | ||
fs.mkdirSync(publicDir, { recursive: true }) | ||
} | ||
|
||
try { | ||
const jsonContent = JSON.stringify({ sql: sqlContent }, null, 2) | ||
fs.writeFileSync(filePath, jsonContent, 'utf8') | ||
return filePath | ||
} catch (error) { | ||
console.error( | ||
`Error during preprocessing: ${error instanceof Error ? error.message : 'Unknown error'}`, | ||
) | ||
return null | ||
} | ||
} | ||
|
||
const program = new Command() | ||
|
||
program.name('liam').description('CLI tool for Liam').version('0.0.0') | ||
|
||
const erdCommand = new Command('erd').description('ERD commands') | ||
|
||
program.addCommand(erdCommand) | ||
|
||
erdCommand | ||
.command('build') | ||
.description('Run Vite build') | ||
.option('--input <path>', 'Path to the .sql file') | ||
.action(async (options) => { | ||
try { | ||
const inputPath = options.input | ||
runPreprocess(inputPath) | ||
await build({ | ||
publicDir, | ||
root, | ||
build: { | ||
outDir, | ||
emptyOutDir: false, | ||
}, | ||
}) | ||
} catch (error) { | ||
console.error('Build failed:', error) | ||
process.exit(1) | ||
} | ||
}) | ||
|
||
erdCommand | ||
.command('dev') | ||
.description('Run Vite dev server') | ||
.option('--input <path>', 'Path to the .sql file') | ||
.action(async (options) => { | ||
try { | ||
const inputPath = options.input | ||
runPreprocess(inputPath) | ||
const server = await createServer({ publicDir, root }) | ||
const address = server.httpServer?.address() | ||
const port = typeof address === 'object' && address ? address.port : 5173 | ||
console.info(`Dev server is running at http://localhost:${port}`) | ||
await server.listen() | ||
} catch (error) { | ||
console.error('Failed to start dev server:', error) | ||
process.exit(1) | ||
} | ||
}) | ||
|
||
erdCommand | ||
.command('preview') | ||
.description('Preview the production build') | ||
.action(async () => { | ||
try { | ||
const previewServer = await preview({ | ||
publicDir, | ||
root, | ||
build: { | ||
outDir, | ||
emptyOutDir: false, | ||
}, | ||
}) | ||
const address = previewServer.httpServer?.address() | ||
const port = typeof address === 'object' && address ? address.port : 4173 | ||
console.info(`Preview server is running at http://localhost:${port}`) | ||
} catch (error) { | ||
console.error('Failed to start preview server:', error) | ||
process.exit(1) | ||
} | ||
}) | ||
program.parse(process.argv) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { build } from 'vite' | ||
import { runPreprocess } from '../runPreprocess.js' | ||
|
||
export const buildCommand = async ( | ||
inputPath: string, | ||
publicDir: string, | ||
root: string, | ||
outDir: string, | ||
) => { | ||
runPreprocess(inputPath, publicDir) | ||
await build({ | ||
publicDir, | ||
root, | ||
build: { | ||
outDir, | ||
emptyOutDir: false, | ||
}, | ||
}) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { createServer } from 'vite' | ||
import { runPreprocess } from '../runPreprocess.js' | ||
|
||
export const devCommand = async ( | ||
inputPath: string, | ||
publicDir: string, | ||
root: string, | ||
) => { | ||
runPreprocess(inputPath, publicDir) | ||
const server = await createServer({ publicDir, root }) | ||
const address = server.httpServer?.address() | ||
const port = typeof address === 'object' && address ? address.port : 5173 | ||
console.info(`Dev server is running at http://localhost:${port}`) | ||
await server.listen() | ||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,4 @@ | ||||||||||||||||
import { buildCommand } from './buildCommand.js' | ||||||||||||||||
import { devCommand } from './devCommand.js' | ||||||||||||||||
import { previewCommand } from './previewCommand.js' | ||||||||||||||||
export { buildCommand, devCommand, previewCommand } | ||||||||||||||||
Comment on lines
+1
to
+4
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. [nits]
Suggested change
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. That's actually been a bit of a headache for me since yesterday! At the moment, removing the error
So, I can only confirm that it functions properly in its current state, with the To explain a bit further, if I change I’m hoping to get some help with this issue from someone else in the future. Also, since this is a rather fragile part of the setup, I’m considering adding a smoke test to ensure the CLI continues to work properly. Hope that gives some clarity, and thank you for the suggestion! |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { preview } from 'vite' | ||
|
||
export const previewCommand = async ( | ||
publicDir: string, | ||
root: string, | ||
outDir: string, | ||
) => { | ||
const previewServer = await preview({ | ||
publicDir, | ||
root, | ||
build: { | ||
outDir, | ||
emptyOutDir: false, | ||
}, | ||
}) | ||
const address = previewServer.httpServer?.address() | ||
const port = typeof address === 'object' && address ? address.port : 4173 | ||
console.info(`Preview server is running at http://localhost:${port}`) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
import type { Command } from 'commander' | ||
import { describe, expect, it, vi } from 'vitest' | ||
import { program } from '.' | ||
import { buildCommand, devCommand, previewCommand } from './commands' | ||
|
||
// Function to set up mocks | ||
function setupMocks() { | ||
vi.mock('./commands/buildCommand', () => ({ | ||
buildCommand: vi.fn(), | ||
})) | ||
vi.mock('./commands/devCommand', () => ({ | ||
devCommand: vi.fn(), | ||
})) | ||
vi.mock('./commands/previewCommand', () => ({ | ||
previewCommand: vi.fn(), | ||
})) | ||
} | ||
|
||
// Utility function to find a subcommand | ||
function findSubCommand(erdCommand: Command | undefined, name: string) { | ||
return erdCommand?.commands.find((cmd: Command) => cmd.name() === name) | ||
} | ||
|
||
setupMocks() | ||
|
||
describe('program', () => { | ||
it('should have the correct name and description', () => { | ||
expect(program.name()).toBe('liam') | ||
expect(program.description()).toBe('CLI tool for Liam') | ||
}) | ||
|
||
it('should have an "erd" command with subcommands', () => { | ||
const erdCommand = program.commands.find((cmd) => cmd.name() === 'erd') | ||
expect(erdCommand).toBeDefined() | ||
expect(erdCommand?.description()).toBe('ERD commands') | ||
|
||
// Verify subcommands | ||
const buildSubCommand = findSubCommand(erdCommand, 'build') | ||
expect(buildSubCommand).toBeDefined() | ||
expect(buildSubCommand?.description()).toBe('Run Vite build') | ||
|
||
const devSubCommand = findSubCommand(erdCommand, 'dev') | ||
expect(devSubCommand).toBeDefined() | ||
expect(devSubCommand?.description()).toBe('Run Vite dev server') | ||
|
||
const previewSubCommand = findSubCommand(erdCommand, 'preview') | ||
expect(previewSubCommand).toBeDefined() | ||
expect(previewSubCommand?.description()).toBe( | ||
'Preview the production build', | ||
) | ||
}) | ||
|
||
describe('commands', () => { | ||
it('should call buildCommand when "build" command is executed', () => { | ||
program.parse(['erd', 'build', '--input', 'path/to/file.sql'], { | ||
from: 'user', | ||
}) | ||
expect(buildCommand).toHaveBeenCalledWith( | ||
'path/to/file.sql', | ||
expect.stringMatching(/\/public$/), | ||
expect.any(String), | ||
expect.stringMatching(/\/dist$/), | ||
) | ||
}) | ||
|
||
it('should call devCommand when "dev" command is executed', () => { | ||
program.parse(['erd', 'dev', '--input', 'path/to/file.sql'], { | ||
from: 'user', | ||
}) | ||
expect(devCommand).toHaveBeenCalledWith( | ||
'path/to/file.sql', | ||
expect.stringMatching(/\/public$/), | ||
expect.any(String), | ||
) | ||
}) | ||
|
||
it('should call previewCommand when "preview" command is executed', () => { | ||
program.parse(['erd', 'preview'], { from: 'user' }) | ||
expect(previewCommand).toHaveBeenCalledWith( | ||
expect.stringMatching(/\/public$/), | ||
expect.any(String), | ||
expect.stringMatching(/\/dist$/), | ||
) | ||
}) | ||
}) | ||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import path from 'node:path' | ||
import { fileURLToPath } from 'node:url' | ||
import { Command } from 'commander' | ||
import { buildCommand, devCommand, previewCommand } from './commands/index.js' | ||
|
||
const __filename = fileURLToPath(import.meta.url) | ||
const __dirname = path.dirname(__filename) | ||
const root = path.resolve(__dirname, '../../..') | ||
const publicDir = path.join(process.cwd(), 'public') | ||
const outDir = path.join(process.cwd(), 'dist') | ||
|
||
const program = new Command() | ||
|
||
program.name('liam').description('CLI tool for Liam').version('0.0.0') | ||
|
||
const erdCommand = new Command('erd').description('ERD commands') | ||
program.addCommand(erdCommand) | ||
|
||
erdCommand | ||
.command('build') | ||
.description('Run Vite build') | ||
.option('--input <path>', 'Path to the .sql file') | ||
.action((options) => buildCommand(options.input, publicDir, root, outDir)) | ||
|
||
erdCommand | ||
.command('dev') | ||
.description('Run Vite dev server') | ||
.option('--input <path>', 'Path to the .sql file') | ||
.action((options) => devCommand(options.input, publicDir, root)) | ||
|
||
erdCommand | ||
.command('preview') | ||
.description('Preview the production build') | ||
.action(() => previewCommand(publicDir, root, outDir)) | ||
|
||
export { program } |
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.
[nits]
Could we write it like this to make it more concise?