Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"presets": ["@babel/preset-env"]
}
92 changes: 92 additions & 0 deletions __tests__/createController.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import chalk from 'chalk';
import { Command } from 'commander';
import fs from 'fs-extra';
import path from 'path';
import createController from '../commands/createController';

jest.mock('fs-extra');
jest.mock('chalk', () => ({
green: jest.fn((text) => text),
red: jest.fn((text) => text),
cyan: jest.fn((text) => text),
white: jest.fn((text) => text),
}));

describe('add-controller command', () => {
let consoleLogSpy;
let consoleErrorSpy;
let program;
const testDir = path.join(__dirname, '../backend/controllers');
const fileName = 'Test';
const controllerFilePath = path.join(testDir, `${fileName.toLowerCase()}.js`);

beforeAll(() => {
// Ensure test directories are created before tests run
fs.ensureDirSync(testDir);
});

beforeEach(() => {
consoleLogSpy = jest.spyOn(console, 'log').mockImplementation(() => {});
consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
fs.existsSync.mockReset();
fs.mkdirSync.mockReset();
fs.writeFileSync.mockReset();

program = new Command();
createController(program);
});

afterEach(() => {
jest.clearAllMocks();
});

afterAll(() => {
// Clean up test directories after tests complete
fs.removeSync(testDir);
});

it('should create a controller file in controllers directory if it does not exist', () => {
fs.existsSync.mockReturnValue(false);
fs.mkdirSync.mockImplementation(() => {});
fs.writeFileSync.mockImplementation(() => {});

program.parse(['add-controller', fileName], { from: 'user' });

// Check if the directory was created
expect(fs.mkdirSync).toHaveBeenCalledWith(
expect.stringContaining('controllers'),
{ recursive: true }
);

// Check if the controller file was created
expect(fs.writeFileSync).toHaveBeenCalledWith(
expect.stringContaining(controllerFilePath),
expect.any(String)
);

// Verify log output
expect(consoleLogSpy).toHaveBeenCalledWith(
expect.stringContaining('✅ Created controllers directory')
);
expect(consoleLogSpy).toHaveBeenCalledWith(
expect.stringContaining(
`✅ ${fileName} created at controllers/${fileName.toLowerCase()}.js`
)
);
});

it('should log an error if controller file creation fails', () => {
fs.existsSync.mockReturnValue(true);

const errorMessage = 'File system error';
fs.writeFileSync.mockImplementation(() => {
throw new Error(errorMessage);
});

program.parse(['add-controller', fileName], { from: 'user' });

expect(consoleErrorSpy).toHaveBeenCalledWith(
chalk.red(`❌ Failed to write controller file: ${errorMessage}`)
);
});
});
92 changes: 92 additions & 0 deletions __tests__/createRoute.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import chalk from 'chalk';
import { Command } from 'commander';
import fs from 'fs-extra';
import path from 'path';
import createRoute from '../commands/createRoute';

jest.mock('fs-extra');
jest.mock('chalk', () => ({
green: jest.fn((text) => text),
red: jest.fn((text) => text),
cyan: jest.fn((text) => text),
white: jest.fn((text) => text),
}));

describe('add-route command', () => {
let consoleLogSpy;
let consoleErrorSpy;
let program;
const testDir = path.join(__dirname, '../backend/routes');
const fileName = 'Test';
const controllerFilePath = path.join(testDir, `${fileName.toLowerCase()}.js`);

beforeAll(() => {
// Ensure test directories are created before tests run
fs.ensureDirSync(testDir);
});

beforeEach(() => {
consoleLogSpy = jest.spyOn(console, 'log').mockImplementation(() => {});
consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
fs.existsSync.mockReset();
fs.mkdirSync.mockReset();
fs.writeFileSync.mockReset();

program = new Command();
createRoute(program);
});

afterEach(() => {
jest.clearAllMocks();
});

afterAll(() => {
// Clean up test directories after tests complete
fs.removeSync(testDir);
});

it('should create a route file in routes directory if it does not exist', () => {
fs.existsSync.mockReturnValue(false);
fs.mkdirSync.mockImplementation(() => {});
fs.writeFileSync.mockImplementation(() => {});

program.parse(['add-route', fileName], { from: 'user' });

// Check if the directory was created
expect(fs.mkdirSync).toHaveBeenCalledWith(
expect.stringContaining('routes'),
{ recursive: true }
);

// Check if the route file was created
expect(fs.writeFileSync).toHaveBeenCalledWith(
expect.stringContaining(controllerFilePath),
expect.any(String)
);

// Verify log output
expect(consoleLogSpy).toHaveBeenCalledWith(
expect.stringContaining('✅ Created routes directory')
);
expect(consoleLogSpy).toHaveBeenCalledWith(
expect.stringContaining(
`✅ ${fileName} created at routes/${fileName.toLowerCase()}.js`
)
);
});

it('should log an error if route file creation fails', () => {
fs.existsSync.mockReturnValue(true);

const errorMessage = 'File system error';
fs.writeFileSync.mockImplementation(() => {
throw new Error(errorMessage);
});

program.parse(['add-route', fileName], { from: 'user' });

expect(consoleErrorSpy).toHaveBeenCalledWith(
chalk.red(`❌ Failed to write route file: ${errorMessage}`)
);
});
});
92 changes: 92 additions & 0 deletions __tests__/createService.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import chalk from 'chalk';
import { Command } from 'commander';
import fs from 'fs-extra';
import path from 'path';
import createService from '../commands/cerateService';

jest.mock('fs-extra');
jest.mock('chalk', () => ({
green: jest.fn((text) => text),
red: jest.fn((text) => text),
cyan: jest.fn((text) => text),
white: jest.fn((text) => text),
}));

describe('add-service command', () => {
let consoleLogSpy;
let consoleErrorSpy;
let program;
const testDir = path.join(__dirname, '../backend/services');
const fileName = 'Test';
const controllerFilePath = path.join(testDir, `${fileName.toLowerCase()}.js`);

beforeAll(() => {
// Ensure test directories are created before tests run
fs.ensureDirSync(testDir);
});

beforeEach(() => {
consoleLogSpy = jest.spyOn(console, 'log').mockImplementation(() => {});
consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
fs.existsSync.mockReset();
fs.mkdirSync.mockReset();
fs.writeFileSync.mockReset();

program = new Command();
createService(program);
});

afterEach(() => {
jest.clearAllMocks();
});

afterAll(() => {
// Clean up test directories after tests complete
fs.removeSync(testDir);
});

it('should create a service file in services directory if it does not exist', () => {
fs.existsSync.mockReturnValue(false);
fs.mkdirSync.mockImplementation(() => {});
fs.writeFileSync.mockImplementation(() => {});

program.parse(['add-service', fileName], { from: 'user' });

// Check if the directory was created
expect(fs.mkdirSync).toHaveBeenCalledWith(
expect.stringContaining('services'),
{ recursive: true }
);

// Check if the service file was created
expect(fs.writeFileSync).toHaveBeenCalledWith(
expect.stringContaining(controllerFilePath),
expect.any(String)
);

// Verify log output
expect(consoleLogSpy).toHaveBeenCalledWith(
expect.stringContaining('✅ Created services directory')
);
expect(consoleLogSpy).toHaveBeenCalledWith(
expect.stringContaining(
`✅ ${fileName} created at services/${fileName.toLowerCase()}.js`
)
);
});

it('should log an error if service file creation fails', () => {
fs.existsSync.mockReturnValue(true);

const errorMessage = 'File system error';
fs.writeFileSync.mockImplementation(() => {
throw new Error(errorMessage);
});

program.parse(['add-service', fileName], { from: 'user' });

expect(consoleErrorSpy).toHaveBeenCalledWith(
chalk.red(`❌ Failed to write service file: ${errorMessage}`)
);
});
});
76 changes: 76 additions & 0 deletions commands/cerateService.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import chalk from 'chalk';
import fs from 'fs-extra';
import path from 'path';
import { capitalize } from '../utils/capitalize';

export default function createService(program) {
program
.command('add-service <FileName>')
.description('Generate a service')
.action((fileName) => {
const currentDir = process.cwd();
const isInBackend = path.basename(currentDir) === 'backend';

// service dir
const serviceDir = isInBackend
? path.join(currentDir, 'services')
: path.join(currentDir, 'backend', 'services');

// Create the services directory if it doesn't exist
if (!fs.existsSync(serviceDir)) {
try {
fs.mkdirSync(serviceDir, { recursive: true });
console.log(chalk.green('✅ Created services directory'));
} catch (error) {
console.error(
chalk.red(
`❌ Failed to create services directory: ${error.message}`
)
);
return;
}
}

// Service template
const serviceContent = `
// Service for ${capitalize(fileName)}
import ${capitalize(fileName)} from '../models/${capitalize(fileName)}.js';

class ${capitalize(fileName)}Service {
// ${capitalize(fileName)} Services..
}

export default ${capitalize(fileName)}Service;
`;

// Write the service file to the services directory
try {
const serviceFilePath = path.join(
serviceDir,
`${fileName.toLowerCase()}.js`
);
fs.writeFileSync(serviceFilePath, serviceContent);
console.log(
chalk.green(
`✅ ${capitalize(fileName)} created at services/${fileName.toLowerCase()}.js`
)
);
} catch (error) {
console.error(
chalk.red(`❌ Failed to write service file: ${error.message}`)
);
return;
}

// Final success message
console.log(chalk.cyan('\n📝 Next steps:'));
console.log(
chalk.white(
`1. Review your service in services/${fileName.toLowerCase()}.js`
)
);
console.log(
chalk.white('2. Import and use your service in your app as needed')
);
});
}
Loading
Loading