UNPKG

bubbles-express-generator

Version:
188 lines (166 loc) 6.11 kB
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; import { execa } from 'execa'; import fs from 'fs-extra'; import path from 'path'; const mockNotify = vi.fn(); vi.mock('update-notifier', () => { return () => ({ notify: mockNotify, }); }); const CLI_PATH = path.resolve(__dirname, '../cli/index.js'); const TEST_PROJECTS_DIR = path.resolve(__dirname, 'test-projects'); const runCLI = async ( args = [], cwd = TEST_PROJECTS_DIR, envOverrides = {}, ) => { return await execa('node', [CLI_PATH, ...args], { cwd, env: { FORCE_COLOR: '0', ...envOverrides }, stdin: 'ignore', }); }; const projectExists = async (dir) => { const fullPath = path.join(TEST_PROJECTS_DIR, dir); try { const stat = await fs.stat(fullPath); return stat.isDirectory(); } catch { return false; } }; describe('bubbles-express CLI', () => { beforeEach(async () => { await fs.ensureDir(TEST_PROJECTS_DIR); }); afterEach(async () => { const files = await fs.readdir(TEST_PROJECTS_DIR); await Promise.all( files.map(async (file) => { if (file !== '.gitkeep') { const fullPath = path.join(TEST_PROJECTS_DIR, file); try { if (await fs.pathExists(fullPath)) { await fs.rm(fullPath, { recursive: true, force: true }); } } catch (err) { console.warn(`⚠️ Could not delete ${fullPath}:`, err.message); } } }), ); }); const templatesRoot = path.resolve(__dirname, '../templates'); let templateDirs = []; try { templateDirs = fs.readdirSync(templatesRoot).filter((dir) => { const fullPath = path.join(templatesRoot, dir); return fs.statSync(fullPath).isDirectory(); }); } catch (err) { templateDirs = []; } const combos = templateDirs .map((dir) => { const match = /^([a-z]+)-([a-z]+)/.exec(dir); if (match) { return { language: match[1], db: match[2] }; } return null; }) .filter(Boolean); combos.forEach(({ language, db }) => { it(`creates project in current directory with "." and no flags [${language}-${db}]`, async () => { const testDirName = `${language}-${db}-dot-no-flags`; const testDir = path.join(TEST_PROJECTS_DIR, testDirName); await fs.ensureDir(testDir); await fs.writeFile(path.join(testDir, 'dummy.txt'), 'placeholder'); const resultOverwrite = await runCLI(['.'], testDir, { NODE_ENV: 'test', MOCK_OVERWRITE: '1', }); expect(resultOverwrite.exitCode).toBe(0); expect(resultOverwrite.stdout).toMatch(/Project created successfully/i); const existsOverwrite = await projectExists(testDirName); expect(existsOverwrite).toBe(true); const renameDir = `${language}-${db}-renamed`; const resultRename = await runCLI(['.'], testDir, { NODE_ENV: 'test', MOCK_OVERWRITE: '0', MOCK_RENAME: renameDir, }); expect(resultRename.stdout).toMatch(/Project created successfully/i); const existsRename = await projectExists( path.join(testDirName, renameDir), ); expect(existsRename).toBe(true); }); it(`creates project with name and no flags [${language}-${db}]`, async () => { const customName = `${language}-${db}-testbackend-no-flags`; const result = await runCLI([customName]); const exists = await projectExists(customName); expect(result.exitCode).toBe(0); expect(result.stdout).toMatch(/Setup complete/i); expect(exists).toBe(true); }); it(`creates project with name and flags [${language}-${db}]`, async () => { const customName = `${language}-${db}-testbackend-flags`; const langFlag = `--${language}`; const dbFlag = db === 'mongo' ? '--mongo' : '--pg'; const result = await runCLI([customName, langFlag, dbFlag]); const exists = await projectExists(customName); expect(result.exitCode).toBe(0); expect(result.stdout).toMatch(/Setup complete/i); expect(exists).toBe(true); }); it(`creates project in current directory with "." and flags [${language}-${db}]`, async () => { const testDirName = `${language}-${db}-dot-flags`; const testDir = path.join(TEST_PROJECTS_DIR, testDirName); await fs.ensureDir(testDir); await fs.writeFile(path.join(testDir, 'dummy.txt'), 'placeholder'); const langFlag = `--${language}`; const dbFlag = db === 'mongo' ? '--mongo' : '--pg'; const resultOverwrite = await runCLI(['.', langFlag, dbFlag], testDir, { NODE_ENV: 'test', MOCK_OVERWRITE: '1', }); expect(resultOverwrite.exitCode).toBe(0); expect(resultOverwrite.stdout).toMatch(/Project created successfully/i); const existsOverwrite = await projectExists(testDirName); expect(existsOverwrite).toBe(true); const renameDir = `${language}-${db}-renamed`; const resultRename = await runCLI(['.', langFlag, dbFlag], testDir, { NODE_ENV: 'test', MOCK_OVERWRITE: '0', MOCK_RENAME: renameDir, }); expect(resultRename.stdout).toMatch(/Project created successfully/i); const existsRename = await projectExists( path.join(testDirName, renameDir), ); expect(existsRename).toBe(true); }); }); it('prompts for overwrite and renames if declined', async () => { const initialDir = 'ts-mongo-dot-no-flags'; const renameDir = 'ts-mongo-renamed'; await fs.ensureDir(path.join(TEST_PROJECTS_DIR, initialDir)); await fs.writeFile( path.join(TEST_PROJECTS_DIR, initialDir, 'dummy.txt'), 'placeholder', ); const result = await runCLI( ['.'], path.join(TEST_PROJECTS_DIR, initialDir), { NODE_ENV: 'test', MOCK_OVERWRITE: '0', MOCK_RENAME: renameDir, }, ); const exists = await projectExists(path.join(initialDir, renameDir)); expect(result.stdout).toMatch(/Project created successfully/i); expect(exists).toBe(true); }); });