feat: refactoring project
This commit is contained in:
1
src/config/babel.config.js
Normal file
1
src/config/babel.config.js
Normal file
@@ -0,0 +1 @@
|
||||
// Placeholder for babel.config.js
|
||||
1
src/config/webpack.config.js
Normal file
1
src/config/webpack.config.js
Normal file
@@ -0,0 +1 @@
|
||||
// Placeholder for webpack.config.js
|
||||
26
src/setup/dependencies.js
Normal file
26
src/setup/dependencies.js
Normal file
@@ -0,0 +1,26 @@
|
||||
const { execSync } = require('child_process');
|
||||
const ora = require('ora');
|
||||
const { deps } = require('./deps');
|
||||
|
||||
function installDependencies(userInput, options) {
|
||||
const spinner = ora('🔄 Installing dependencies...').start();
|
||||
try {
|
||||
if (userInput.useAntd) {
|
||||
deps.push('antd');
|
||||
}
|
||||
if (userInput.useRedux) {
|
||||
deps.push('@reduxjs/toolkit');
|
||||
deps.push('react-redux');
|
||||
deps.push('redux');
|
||||
}
|
||||
execSync(
|
||||
`npm install ${deps.join(' ')} ${options.verbose ? '--verbose' : ''}`
|
||||
);
|
||||
spinner.succeed('✅ Dependencies installed.');
|
||||
} catch (error) {
|
||||
spinner.fail('❌ Failed to install dependencies.');
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { installDependencies };
|
||||
27
src/setup/deps.js
Normal file
27
src/setup/deps.js
Normal file
@@ -0,0 +1,27 @@
|
||||
const deps = [
|
||||
'react',
|
||||
'react-dom',
|
||||
'@babel/core',
|
||||
'@babel/preset-env',
|
||||
'webpack-cli',
|
||||
'webpack',
|
||||
'web-vitals',
|
||||
'typescript',
|
||||
'style-loader',
|
||||
'react-scripts',
|
||||
'react-dom',
|
||||
'react',
|
||||
'jest',
|
||||
'babel-loader',
|
||||
'ajv',
|
||||
'@types/react-dom',
|
||||
'@types/react',
|
||||
'@types/node',
|
||||
'@types/jest',
|
||||
'@testing-library/user-event',
|
||||
'@testing-library/react',
|
||||
'@testing-library/jest-dom',
|
||||
'@babel/preset-react',
|
||||
];
|
||||
|
||||
module.exports = { deps };
|
||||
18
src/setup/devDependencies.js
Normal file
18
src/setup/devDependencies.js
Normal file
@@ -0,0 +1,18 @@
|
||||
const { execSync } = require('child_process');
|
||||
const ora = require('ora');
|
||||
const { devDeps } = require('./devDeps');
|
||||
|
||||
function installDevDependencies(options){
|
||||
const spinner = ora('🔄 Installing additional dev dependencies...').start();
|
||||
try {
|
||||
execSync(
|
||||
`npm install ${devDeps.join(' ')} ${options.verbose ? '--verbose' : ''}`
|
||||
);
|
||||
spinner.succeed('✅ Additional dev dependencies installed.');
|
||||
} catch (error) {
|
||||
spinner.fail('❌ Failed to install dependencies.');
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { installDevDependencies };
|
||||
16
src/setup/devDeps.js
Normal file
16
src/setup/devDeps.js
Normal file
@@ -0,0 +1,16 @@
|
||||
const devDeps = [
|
||||
'pretty-quick',
|
||||
'webpack-dev-server',
|
||||
'url-loader',
|
||||
'husky',
|
||||
'dotenv-webpack',
|
||||
'dotenv',
|
||||
'@svgr/webpack',
|
||||
'@commitlint/config-conventional',
|
||||
'@commitlint/cli',
|
||||
'prettier',
|
||||
'ora',
|
||||
'@babel/plugin-proposal-private-property-in-object',
|
||||
];
|
||||
|
||||
module.exports = { devDeps };
|
||||
17
src/setup/gitInit.js
Normal file
17
src/setup/gitInit.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Purpose: Initialize a Git repository and run Git commands.
|
||||
const { execSync } = require('child_process');
|
||||
const ora = require('ora');
|
||||
|
||||
async function setupGit(options) {
|
||||
const spinner = ora('🔧 Running Git commands...').start();
|
||||
|
||||
try {
|
||||
execSync(`git init ${options.verbose ? '--verbose' : ''}`);
|
||||
spinner.succeed('✅ Git commands executed successfully.');
|
||||
} catch (error) {
|
||||
spinner.fail('❌ Failed to execute Git commands.');
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { setupGit };
|
||||
15
src/setup/husky.js
Normal file
15
src/setup/husky.js
Normal file
@@ -0,0 +1,15 @@
|
||||
const { execSync } = require('child_process');
|
||||
const ora = require('ora');
|
||||
|
||||
function setupHusky(options) {
|
||||
const spinner = ora('🐶 Setting up Husky...').start();
|
||||
execSync(
|
||||
`npx husky-init && npm install ${options.verbose ? '--verbose' : ''}`
|
||||
);
|
||||
execSync(
|
||||
`npx husky add .husky/pre-commit "npm test" ${options.verbose ? '--verbose' : ''}`
|
||||
);
|
||||
spinner.succeed('🐶 Husky set up.');
|
||||
}
|
||||
|
||||
module.exports = { setupHusky };
|
||||
65
src/setup/init.js
Normal file
65
src/setup/init.js
Normal file
@@ -0,0 +1,65 @@
|
||||
const path = require('path');
|
||||
const { execSync } = require('child_process');
|
||||
const ora = require('ora');
|
||||
const fs = require('fs');
|
||||
const { installDependencies } = require('./dependencies');
|
||||
const { installDevDependencies } = require('./devDependencies');
|
||||
const { setupHusky } = require('./husky');
|
||||
const { setupRedux } = require('./redux');
|
||||
const { setupStyles } = require('./styles');
|
||||
const { setupGit } = require('./gitInit');
|
||||
const { setupTesting } = require('./testing');
|
||||
const { createAtomicStructure } = require('../templates/atomicStructure');
|
||||
const { updatePackageJson } = require('../templates/packageJson');
|
||||
const { askUserWhereToOpen } = require('../utils/logging');
|
||||
const inquirer = require('inquirer');
|
||||
|
||||
async function initProject(projectDirectory, userInput, options) {
|
||||
const root = path.resolve(projectDirectory);
|
||||
const verboseFlag = options.verbose ? '--verbose' : '';
|
||||
|
||||
// Create the project directory
|
||||
fs.mkdirSync(root, { recursive: true });
|
||||
process.chdir(root);
|
||||
|
||||
console.log(`🚀 Creating a new React app in ${root}...`);
|
||||
|
||||
const spinner = ora('Installing base Create React App...').start();
|
||||
|
||||
try {
|
||||
// Initialize CRA with or without TypeScript
|
||||
const template = userInput.language === 'TypeScript' ? '--template typescript' : '';
|
||||
execSync(`npx create-react-app . ${template} ${verboseFlag}`, { stdio: 'inherit' });
|
||||
spinner.succeed('✅ Base React app created successfully.');
|
||||
} catch (error) {
|
||||
spinner.fail('❌ Failed to create base React app.');
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Set up Git
|
||||
setupGit(options);
|
||||
// Install additional dependencies
|
||||
installDependencies(userInput, options);
|
||||
// Install additional dev dependencies
|
||||
installDevDependencies(options);
|
||||
|
||||
// Set up additional features based on user input
|
||||
if (userInput.useHusky) setupHusky(options);
|
||||
if (userInput.useRedux) setupRedux(options);
|
||||
setupStyles(userInput.styling);
|
||||
setupTesting(userInput.testingFramework);
|
||||
|
||||
// Create atomic design structure
|
||||
createAtomicStructure();
|
||||
|
||||
// Update package.json
|
||||
updatePackageJson(userInput);
|
||||
|
||||
console.log('🎉 Project setup complete!');
|
||||
|
||||
// Ask user where to open the project
|
||||
askUserWhereToOpen(root);
|
||||
}
|
||||
|
||||
module.exports = { initProject };
|
||||
29
src/setup/init.test.js
Normal file
29
src/setup/init.test.js
Normal file
@@ -0,0 +1,29 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { initProject } = require('./init');
|
||||
|
||||
jest.mock('fs');
|
||||
jest.mock('ora', () => () => ({
|
||||
start: jest.fn(() => ({ succeed: jest.fn(), fail: jest.fn() })),
|
||||
}));
|
||||
jest.mock('./dependencies', () => ({ installDependencies: jest.fn() }));
|
||||
jest.mock('../utils/prompts', () => ({ askUserWhereToOpen: jest.fn() }));
|
||||
|
||||
describe('initProject', () => {
|
||||
const testDir = 'test-project';
|
||||
|
||||
beforeEach(() => {
|
||||
fs.mkdirSync.mockClear();
|
||||
fs.existsSync.mockReturnValue(false);
|
||||
});
|
||||
|
||||
test('Creates project directory and initializes app', async () => {
|
||||
initProject(testDir, { useHusky: false }, { verbose: false });
|
||||
expect(fs.mkdirSync).toHaveBeenCalledWith(path.resolve(testDir), { recursive: true });
|
||||
});
|
||||
|
||||
test('Fails if directory already exists and not overwritten', () => {
|
||||
fs.existsSync.mockReturnValue(true);
|
||||
expect(() => initProject(testDir, {}, {})).toThrowError();
|
||||
});
|
||||
});
|
||||
60
src/setup/redux.js
Normal file
60
src/setup/redux.js
Normal file
@@ -0,0 +1,60 @@
|
||||
const ora = require('ora');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
function setupRedux(options) {
|
||||
console.log('options...', options);
|
||||
const spinner = ora('🛠️ Setting up Redux...').start();
|
||||
|
||||
const reduxStructure = [
|
||||
'src/store',
|
||||
'src/store/slices',
|
||||
'src/store/middleware',
|
||||
'src/store/selectors',
|
||||
];
|
||||
|
||||
reduxStructure.forEach((dir) => {
|
||||
fs.mkdirSync(dir, { recursive: true });
|
||||
});
|
||||
|
||||
const appFileName = options.language === 'TypeScript' ? 'App.tsx' : 'App.js';
|
||||
const extension = options.language === 'TypeScript' ? '.ts' : '.js';
|
||||
const reactFileType = options.language === 'JavaScript' ? '' : ': React.FC';
|
||||
|
||||
const storeIndex = `
|
||||
import { configureStore } from ‘@reduxjs/toolkit’;
|
||||
|
||||
const store = configureStore({
|
||||
reducer: {
|
||||
// Add your reducers here
|
||||
},
|
||||
middleware: (getDefaultMiddleware) => getDefaultMiddleware(),
|
||||
});
|
||||
|
||||
export default store;
|
||||
`;
|
||||
fs.writeFileSync(path.resolve(`src/store/index${extension}`), storeIndex);
|
||||
|
||||
const appTsxJsPath = path.resolve(`src/${appFileName}`);
|
||||
let appTsxJs = fs.readFileSync(appTsxPath, 'utf8');
|
||||
appTsxJs = `
|
||||
import React from 'react';
|
||||
import { Provider } from 'react-redux';
|
||||
import store from './store';
|
||||
|
||||
const App${reactFileType} = () => {
|
||||
return (
|
||||
<Provider store={store}>
|
||||
${appTsx}
|
||||
</Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
||||
`;
|
||||
fs.writeFileSync(appTsxJsPath, appTsxJs);
|
||||
|
||||
spinner.succeed('🛠️ Redux set up.');
|
||||
}
|
||||
|
||||
module.exports = { setupRedux };
|
||||
52
src/setup/styles.js
Normal file
52
src/setup/styles.js
Normal file
@@ -0,0 +1,52 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const ora = require('ora');
|
||||
const { execSync } = require('child_process');
|
||||
|
||||
function setupStyles(styleChoice) {
|
||||
const spinner = ora('🎨 Setting up styles...').start();
|
||||
|
||||
try {
|
||||
const stylesMap = {
|
||||
CSS: { fileName: 'index.css', dependency: '' },
|
||||
SCSS: { fileName: 'index.scss', dependency: 'sass' },
|
||||
SASS: { fileName: 'index.sass', dependency: 'sass' },
|
||||
LESS: { fileName: 'index.less', dependency: 'less' },
|
||||
};
|
||||
|
||||
// Ensure styleChoice is valid
|
||||
if (!stylesMap[styleChoice]) {
|
||||
spinner.fail(`❌ Unsupported style option: ${styleChoice}`);
|
||||
return;
|
||||
}
|
||||
|
||||
const { fileName, dependency } = stylesMap[styleChoice];
|
||||
const stylePath = path.resolve('src', fileName);
|
||||
|
||||
// Create the style file with a placeholder content
|
||||
fs.writeFileSync(stylePath, `/* Placeholder for ${styleChoice} styles */`);
|
||||
|
||||
// Update index.js or index.tsx to include the style
|
||||
const indexPath = path.resolve('src', 'index.tsx');
|
||||
let indexContent = fs.readFileSync(indexPath, 'utf8');
|
||||
|
||||
// Remove any existing style imports and add the new one
|
||||
indexContent = indexContent.replace(/import\s+['"].*\.(css|scss|sass|less)['"];?/g, '');
|
||||
indexContent = `import './${fileName}';\n${indexContent}`;
|
||||
|
||||
fs.writeFileSync(indexPath, indexContent);
|
||||
|
||||
// Install necessary dependency for the chosen style
|
||||
if (dependency) {
|
||||
spinner.text = `📦 Installing ${dependency}...`;
|
||||
execSync(`npm install ${dependency}`, { stdio: 'inherit' });
|
||||
}
|
||||
|
||||
spinner.succeed(`🎨 ${styleChoice} styles set up successfully.`);
|
||||
} catch (error) {
|
||||
spinner.fail('❌ Failed to set up styles.');
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { setupStyles };
|
||||
23
src/setup/styles.test.js
Normal file
23
src/setup/styles.test.js
Normal file
@@ -0,0 +1,23 @@
|
||||
const fs = require('fs');
|
||||
const { setupStyles } = require('./styles');
|
||||
const { execSync } = require('child_process');
|
||||
|
||||
jest.mock('fs');
|
||||
jest.mock('child_process');
|
||||
|
||||
describe('setupStyles', () => {
|
||||
beforeEach(() => {
|
||||
fs.writeFileSync.mockClear();
|
||||
execSync.mockClear();
|
||||
});
|
||||
|
||||
test('Sets up SCSS styles', () => {
|
||||
setupStyles('SCSS');
|
||||
expect(fs.writeFileSync).toHaveBeenCalledWith(expect.stringContaining('index.scss'), expect.any(String));
|
||||
expect(execSync).toHaveBeenCalledWith('npm install sass', { stdio: 'inherit' });
|
||||
});
|
||||
|
||||
test('Fails for unsupported style options', () => {
|
||||
expect(() => setupStyles('UnknownStyle')).not.toThrow();
|
||||
});
|
||||
});
|
||||
69
src/setup/testing.js
Normal file
69
src/setup/testing.js
Normal file
@@ -0,0 +1,69 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const ora = require('ora');
|
||||
const { execSync } = require('child_process');
|
||||
|
||||
function setupTesting(testingFramework) {
|
||||
const spinner = ora('🧪 Setting up testing framework...').start();
|
||||
|
||||
try {
|
||||
const testingMap = {
|
||||
Jest: {
|
||||
dependency: 'jest @types/jest ts-jest',
|
||||
configFile: 'jest.config.js',
|
||||
},
|
||||
Mocha: {
|
||||
dependency: 'mocha chai @types/mocha',
|
||||
configFile: 'mocha.opts',
|
||||
},
|
||||
};
|
||||
|
||||
// Ensure testingFramework is valid
|
||||
if (!testingMap[testingFramework]) {
|
||||
spinner.fail(`❌ Unsupported testing framework: ${testingFramework}`);
|
||||
return;
|
||||
}
|
||||
|
||||
const { dependency, configFile } = testingMap[testingFramework];
|
||||
|
||||
// Install necessary dependencies for the chosen testing framework
|
||||
spinner.text = `📦 Installing ${testingFramework} and related packages...`;
|
||||
execSync(`npm install --save-dev ${dependency}`, { stdio: 'inherit' });
|
||||
|
||||
// Create a configuration file for the testing framework
|
||||
const configPath = path.resolve(configFile);
|
||||
|
||||
let configContent = '';
|
||||
if (testingFramework === 'Jest') {
|
||||
configContent = `module.exports = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'node',
|
||||
};`;
|
||||
} else if (testingFramework === 'Mocha') {
|
||||
configContent = `--require ts-node/register
|
||||
--recursive
|
||||
`;
|
||||
}
|
||||
|
||||
fs.writeFileSync(configPath, configContent);
|
||||
spinner.succeed(
|
||||
`🧪 ${testingFramework} set up successfully with configuration file: ${configFile}`
|
||||
);
|
||||
|
||||
// Add test script to package.json
|
||||
const packageJsonPath = path.resolve('package.json');
|
||||
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
||||
|
||||
packageJson.scripts = {
|
||||
...packageJson.scripts,
|
||||
test: testingFramework === 'Jest' ? 'jest' : 'mocha',
|
||||
};
|
||||
|
||||
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
||||
} catch (error) {
|
||||
spinner.fail('❌ Failed to set up testing framework.');
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { setupTesting };
|
||||
17
src/templates/atomicStructure.js
Normal file
17
src/templates/atomicStructure.js
Normal file
@@ -0,0 +1,17 @@
|
||||
function createAtomicStructure() {
|
||||
const spinner = ora('🏗️ Creating atomic design structure…').start();
|
||||
const atomicStructure = [
|
||||
'src/components/atoms',
|
||||
'src/components/molecules',
|
||||
'src/components/organisms',
|
||||
'src/components/templates',
|
||||
'src/components/pages',
|
||||
];
|
||||
|
||||
atomicStructure.forEach((dir) => {
|
||||
fs.mkdirSync(dir, { recursive: true });
|
||||
});
|
||||
spinner.succeed('🏗️ Atomic design structure created.');
|
||||
}
|
||||
|
||||
module.exports = { createAtomicStructure };
|
||||
27
src/templates/packageJson.js
Normal file
27
src/templates/packageJson.js
Normal file
@@ -0,0 +1,27 @@
|
||||
// Placeholder for packageJson.js
|
||||
function updatePackageJson() {
|
||||
const spinner = ora(
|
||||
'📝 Updating package.json with custom scripts...'
|
||||
).start();
|
||||
|
||||
const packageJsonPath = path.resolve('package.json');
|
||||
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
||||
|
||||
packageJson.scripts = {
|
||||
start: 'webpack serve --config webpack.config.js --mode development',
|
||||
build: 'webpack --config webpack.config.js --mode production',
|
||||
test: 'echo "Error: no test specified" && exit 0',
|
||||
'test:dev': 'react-scripts test',
|
||||
'pretty-quick': 'pretty-quick',
|
||||
'lint:prettier': 'node check-format.js',
|
||||
prettier: 'prettier --write . --config .prettierrc',
|
||||
'prettier:commit': 'node prettier-commit.js',
|
||||
eject: 'react-scripts eject',
|
||||
prepare: 'husky install',
|
||||
};
|
||||
|
||||
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
||||
spinner.succeed('📝 package.json updated with custom scripts.');
|
||||
}
|
||||
|
||||
module.exports = { updatePackageJson };
|
||||
1
src/templates/reduxTemplate.js
Normal file
1
src/templates/reduxTemplate.js
Normal file
@@ -0,0 +1 @@
|
||||
// Placeholder for reduxTemplate.js
|
||||
1
src/utils/fileUtils.js
Normal file
1
src/utils/fileUtils.js
Normal file
@@ -0,0 +1 @@
|
||||
// Placeholder for fileUtils.js
|
||||
35
src/utils/logging.js
Normal file
35
src/utils/logging.js
Normal file
@@ -0,0 +1,35 @@
|
||||
const chalk = require('chalk');
|
||||
const inquirer = require('inquirer');
|
||||
|
||||
function askUserWhereToOpen(directory) {
|
||||
inquirer
|
||||
.prompt([
|
||||
{
|
||||
type: 'list',
|
||||
name: 'openIn',
|
||||
message: 'Where would you like to open the project?',
|
||||
choices: ['Terminal', 'VSCode', 'Neovim', 'None'],
|
||||
},
|
||||
])
|
||||
.then((answers) => {
|
||||
switch (answers.openIn) {
|
||||
case 'Terminal':
|
||||
openInTerminal(directory);
|
||||
break;
|
||||
case 'VSCode':
|
||||
openInVSCode(directory);
|
||||
break;
|
||||
case 'Neovim':
|
||||
openInNeovim(directory);
|
||||
break;
|
||||
default:
|
||||
console.log(
|
||||
chalk.yellow(
|
||||
'Project setup complete. You can manually open the project if needed.'
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = { askUserWhereToOpen };
|
||||
28
src/utils/overWriteFolder.js
Normal file
28
src/utils/overWriteFolder.js
Normal file
@@ -0,0 +1,28 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const inquirer = require('inquirer');
|
||||
|
||||
async function overWriteFolder(root) {
|
||||
// Check if directory exists
|
||||
if (fs.existsSync(root)) {
|
||||
const { overwrite } = await inquirer.prompt([
|
||||
{
|
||||
type: 'confirm',
|
||||
name: 'overwrite',
|
||||
message: `⚠️ The directory ${root} already exists. Do you want to overwrite it?`,
|
||||
default: false,
|
||||
},
|
||||
]);
|
||||
|
||||
if (!overwrite) {
|
||||
console.error(`❌ Exiting setup as the directory ${root} already exists.`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log(`🗑️ Removing existing directory: ${root}`);
|
||||
fs.rmSync(root, { recursive: true, force: true });
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
module.exports = { overWriteFolder };
|
||||
39
src/utils/overWriteProject.test.js
Normal file
39
src/utils/overWriteProject.test.js
Normal file
@@ -0,0 +1,39 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { overWrite } = require('./overWriteProject');
|
||||
|
||||
jest.mock('fs');
|
||||
jest.mock('inquirer', () => ({
|
||||
prompt: jest.fn(() => Promise.resolve({ overwrite: true })),
|
||||
}));
|
||||
|
||||
describe('overWrite Function', () => {
|
||||
const testDir = path.resolve('test-dir');
|
||||
|
||||
beforeEach(() => {
|
||||
fs.existsSync.mockClear();
|
||||
fs.rmSync.mockClear();
|
||||
});
|
||||
|
||||
test('Removes directory if overwrite is confirmed', async () => {
|
||||
fs.existsSync.mockReturnValue(true);
|
||||
const result = await overWrite(testDir);
|
||||
expect(fs.rmSync).toHaveBeenCalledWith(testDir, { recursive: true, force: true });
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
test('Exits if overwrite is declined', async () => {
|
||||
require('inquirer').prompt.mockResolvedValueOnce({ overwrite: false });
|
||||
fs.existsSync.mockReturnValue(true);
|
||||
const result = await overWrite(testDir);
|
||||
expect(fs.rmSync).not.toHaveBeenCalled();
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
test('Proceeds if directory does not exist', async () => {
|
||||
fs.existsSync.mockReturnValue(false);
|
||||
const result = await overWrite(testDir);
|
||||
expect(fs.rmSync).not.toHaveBeenCalled();
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
});
|
||||
17
src/utils/prompts.js
Normal file
17
src/utils/prompts.js
Normal file
@@ -0,0 +1,17 @@
|
||||
const inquirer = require('inquirer');
|
||||
|
||||
async function askProjectDetails() {
|
||||
return inquirer.prompt([
|
||||
{ type: 'confirm', name: 'useHusky', message: 'Install Husky?' },
|
||||
{ type: 'confirm', name: 'useAntd', message: 'Install Antd?' },
|
||||
{ type: 'confirm', name: 'useRedux', message: 'Use Redux?' },
|
||||
|
||||
{ type: 'confirm', name: 'useModuleFederation', message: 'Use Module Federation Plugin?' },
|
||||
{ type: 'list', name: 'language', message: 'Choose language:', choices: ['JavaScript', 'TypeScript'] },
|
||||
{ type: 'list', name: 'testingFramework', message: 'Choose testing framework:', choices: ['Jest', 'Mocha'] },
|
||||
{ type: 'list', name: 'styling', message: 'Choose styling option:', choices: ['CSS', 'SCSS', 'SASS', 'LESS'] },
|
||||
{ type: 'list', name: 'modules', message: 'Use CSS Modules, styled-components, or emotion?', choices: ['Modules', 'styled-components', 'emotion'] },
|
||||
]);
|
||||
}
|
||||
|
||||
module.exports = { askProjectDetails };
|
||||
Reference in New Issue
Block a user