Skip to content
Open
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
257 changes: 257 additions & 0 deletions src/commands/__tests__/generate.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,264 @@
import { generateCommand } from '../generate';
import { GenerateService } from '../../services/generate.service';
import { AuthGeneratorService } from '../../services/auth-generator.service';
import { Schematic, AuthFeature } from '../../constants/enums';

jest.mock('chalk', () => ({
red: jest.fn((str: string) => str),
green: jest.fn((str: string) => str),
cyan: jest.fn((str: string) => str),
white: jest.fn((str: string) => str),
yellow: jest.fn((str: string) => str),
gray: jest.fn((str: string) => str),
}));

jest.mock('../../services/generate.service');
jest.mock('../../services/auth-generator.service');
jest.mock('inquirer');

import inquirer from 'inquirer';

describe('generateCommand', () => {
let consoleSpy: jest.SpyInstance;
let processExitSpy: jest.SpyInstance;
let mockPrompt: jest.Mock;

beforeEach(() => {
consoleSpy = jest.spyOn(console, 'log').mockImplementation();
jest.spyOn(console, 'error').mockImplementation();
processExitSpy = jest
.spyOn(process, 'exit')
.mockImplementation(() => undefined as never);
mockPrompt = inquirer.prompt as unknown as jest.Mock;
jest.clearAllMocks();
});

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

it('should be defined', () => {
expect(generateCommand).toBeDefined();
});

it('should exit with error for unknown schematic', async () => {
await generateCommand('unknown', 'test', {
skipSpec: false,
flat: false,
dryRun: false,
});

expect(processExitSpy).toHaveBeenCalledWith(1);
});

it('should resolve "mo" alias to module schematic', async () => {
(GenerateService.generate as jest.Mock).mockReturnValue([
{ filePath: '/src/test/test.module.ts', content: '' },
]);

await generateCommand('mo', 'test', {
skipSpec: false,
flat: false,
dryRun: false,
});

expect(GenerateService.generate).toHaveBeenCalledWith(
expect.objectContaining({ schematic: Schematic.MODULE }),
);
});

it('should resolve "co" alias to controller schematic', async () => {
(GenerateService.generate as jest.Mock).mockReturnValue([
{ filePath: '/src/test/test.controller.ts', content: '' },
]);

await generateCommand('co', 'users', {
skipSpec: false,
flat: false,
dryRun: false,
});

expect(GenerateService.generate).toHaveBeenCalledWith(
expect.objectContaining({ schematic: Schematic.CONTROLLER }),
);
});

it('should resolve "s" alias to service schematic', async () => {
(GenerateService.generate as jest.Mock).mockReturnValue([
{ filePath: '/src/test/test.service.ts', content: '' },
]);

await generateCommand('s', 'users', {
skipSpec: false,
flat: false,
dryRun: false,
});

expect(GenerateService.generate).toHaveBeenCalledWith(
expect.objectContaining({ schematic: Schematic.SERVICE }),
);
});

it('should resolve "gu" alias to guard schematic', async () => {
(GenerateService.generate as jest.Mock).mockReturnValue([
{ filePath: '/src/common/guards/auth.guard.ts', content: '' },
]);

await generateCommand('gu', 'auth', {
skipSpec: false,
flat: false,
dryRun: false,
});

expect(GenerateService.generate).toHaveBeenCalledWith(
expect.objectContaining({ schematic: Schematic.GUARD }),
);
});

it('should resolve "i" alias to interceptor schematic', async () => {
(GenerateService.generate as jest.Mock).mockReturnValue([
{ filePath: '/src/common/interceptors/logging.interceptor.ts', content: '' },
]);

await generateCommand('i', 'logging', {
skipSpec: false,
flat: false,
dryRun: false,
});

expect(GenerateService.generate).toHaveBeenCalledWith(
expect.objectContaining({ schematic: Schematic.INTERCEPTOR }),
);
});

it('should resolve "p" alias to pipe schematic', async () => {
(GenerateService.generate as jest.Mock).mockReturnValue([
{ filePath: '/src/common/pipes/validation.pipe.ts', content: '' },
]);

await generateCommand('p', 'validation', {
skipSpec: false,
flat: false,
dryRun: false,
});

expect(GenerateService.generate).toHaveBeenCalledWith(
expect.objectContaining({ schematic: Schematic.PIPE }),
);
});

it('should pass skipSpec option correctly', async () => {
(GenerateService.generate as jest.Mock).mockReturnValue([
{ filePath: '/src/test/test.service.ts', content: '' },
]);

await generateCommand('service', 'test', {
skipSpec: true,
flat: false,
dryRun: false,
});

expect(GenerateService.generate).toHaveBeenCalledWith(
expect.objectContaining({
options: expect.objectContaining({ skipSpec: true }),
}),
);
});

it('should pass flat option correctly', async () => {
(GenerateService.generate as jest.Mock).mockReturnValue([
{ filePath: '/src/test.service.ts', content: '' },
]);

await generateCommand('service', 'test', {
skipSpec: false,
flat: true,
dryRun: false,
});

expect(GenerateService.generate).toHaveBeenCalledWith(
expect.objectContaining({
options: expect.objectContaining({ flat: true }),
}),
);
});

it('should handle dry-run mode', async () => {
(GenerateService.generate as jest.Mock).mockReturnValue([
{ filePath: '/src/test/test.service.ts', content: '' },
{ filePath: '/src/test/test.service.spec.ts', content: '' },
]);

await generateCommand('service', 'test', {
skipSpec: false,
flat: false,
dryRun: true,
});

expect(GenerateService.generate).toHaveBeenCalledWith(
expect.objectContaining({
options: expect.objectContaining({ dryRun: true }),
}),
);
});

it('should handle errors gracefully', async () => {
(GenerateService.generate as jest.Mock).mockImplementation(() => {
throw new Error('File system error');
});

await generateCommand('service', 'test', {
skipSpec: false,
flat: false,
dryRun: false,
});

expect(processExitSpy).toHaveBeenCalledWith(1);
});

describe('auth schematic', () => {
it('should prompt for auth features when schematic is "auth"', async () => {
mockPrompt.mockResolvedValue({
authFeatures: [AuthFeature.JWT],
});
(AuthGeneratorService.generate as jest.Mock).mockReturnValue([
{ filePath: '/src/auth/auth.module.ts', content: '' },
]);

await generateCommand('auth', '', {
skipSpec: false,
flat: false,
dryRun: false,
});

expect(mockPrompt).toHaveBeenCalled();
expect(AuthGeneratorService.generate).toHaveBeenCalledWith(
expect.objectContaining({
features: [AuthFeature.JWT],
}),
);
});

it('should handle auth dry-run mode', async () => {
mockPrompt.mockResolvedValue({
authFeatures: [AuthFeature.JWT, AuthFeature.RBAC],
});
(AuthGeneratorService.generate as jest.Mock).mockReturnValue([
{ filePath: '/src/auth/auth.module.ts', content: '' },
{ filePath: '/src/auth/guards/roles.guard.ts', content: '' },
]);

await generateCommand('auth', '', {
skipSpec: false,
flat: false,
dryRun: true,
});

expect(AuthGeneratorService.generate).toHaveBeenCalledWith(
expect.objectContaining({
options: expect.objectContaining({ dryRun: true }),
}),
);
});
});
});
Loading