@whook/whook
Version:
Build strong and efficient REST web services.
433 lines (410 loc) • 12.4 kB
text/typescript
/* eslint-disable @typescript-eslint/no-explicit-any */
import { describe, test, beforeEach, jest, expect } from '@jest/globals';
import { YError } from 'yerror';
import initAutoload from './_autoload.js';
import {
type ResolveService,
type ImporterService,
type LogService,
} from 'common-services';
import { SPECIAL_PROPS, type Injector } from 'knifecycle';
import { type WhookAutoloadDependencies } from './_autoload.js';
import {
WHOOK_PROJECT_PLUGIN_NAME,
type WhookResolvedPluginsService,
} from './WHOOK_RESOLVED_PLUGINS.js';
describe('$autoload', () => {
const WHOOK_PLUGINS = [WHOOK_PROJECT_PLUGIN_NAME];
const WHOOK_RESOLVED_PLUGINS: WhookResolvedPluginsService = {
[WHOOK_PROJECT_PLUGIN_NAME]: {
mainURL: 'file:///home/whoiam/project/src/index.ts',
types: ['commands'],
},
};
const log = jest.fn<LogService>();
const importer = jest.fn<ImporterService<any>>();
const $injector = jest.fn<Injector<any>>();
const resolve = jest.fn<ResolveService>();
const access = jest.fn<Required<WhookAutoloadDependencies>['access']>();
beforeEach(() => {
jest.resetModules();
log.mockReset();
importer.mockReset();
$injector.mockReset();
resolve.mockReset();
access.mockReset();
});
test('should fail with no command name', async () => {
importer.mockImplementationOnce(() => {
throw new YError('E_NOT_SUPPOSED_TO_BE_HERE');
});
const $autoload = await initAutoload({
WHOOK_PLUGINS,
WHOOK_RESOLVED_PLUGINS,
args: {
namedArguments: {},
rest: [] as string[],
command: 'whook',
},
importer,
$injector,
resolve,
access,
log,
} as WhookAutoloadDependencies);
try {
await $autoload('commandHandler');
throw new YError('E_UNEXPECTED_SUCCESS');
} catch (err) {
expect({
errorCode: (err as YError).code,
errorDebug: (err as YError).debug,
importerCalls: importer.mock.calls,
injectorCalls: $injector.mock.calls,
resolveCalls: resolve.mock.calls,
logCalls: log.mock.calls.filter(([type]) => !type.endsWith('stack')),
}).toMatchInlineSnapshot(`
{
"errorCode": "E_NO_COMMAND_NAME",
"errorDebug": [],
"importerCalls": [],
"injectorCalls": [],
"logCalls": [
[
"warning",
"🤖 - Initializing the \`$autoload\` service.",
],
[
"warning",
"❌ - No command given in argument.",
],
],
"resolveCalls": [],
}
`);
}
});
test('should warn with not found commands', async () => {
importer.mockImplementationOnce(() => {
throw new YError('E_NO_MODULE');
});
const $autoload = await initAutoload({
WHOOK_PLUGINS,
WHOOK_RESOLVED_PLUGINS,
args: { namedArguments: {}, rest: ['myCommand'], command: 'whook' },
importer,
$injector,
resolve,
access,
log,
} as WhookAutoloadDependencies);
try {
await $autoload('commandHandler');
throw new YError('E_UNEXPECTED_SUCCESS');
} catch (err) {
expect({
errorCode: (err as YError).code,
errorDebug: (err as YError).debug,
importerCalls: importer.mock.calls,
injectorCalls: $injector.mock.calls,
resolveCalls: resolve.mock.calls,
logCalls: log.mock.calls.filter(([type]) => !type.endsWith('stack')),
}).toMatchInlineSnapshot(`
{
"errorCode": "E_BAD_COMMAND_NAME",
"errorDebug": [
"myCommand",
],
"importerCalls": [
[
"file:///home/whoiam/project/src/commands/myCommand.ts",
],
],
"injectorCalls": [],
"logCalls": [
[
"warning",
"🤖 - Initializing the \`$autoload\` service.",
],
[
"debug",
"❌ - Command "myCommand" not found in "file:///home/whoiam/project/src/commands/myCommand.ts".",
],
],
"resolveCalls": [],
}
`);
}
});
test('should work with project commands', async () => {
importer.mockImplementationOnce(async () => ({
default: async () => async () => log('warning', 'Command called!'),
definition: {},
}));
const $autoload = await initAutoload({
WHOOK_PLUGINS,
WHOOK_RESOLVED_PLUGINS,
args: { namedArguments: {}, rest: ['myCommand'], command: 'whook' },
importer,
$injector,
resolve,
access,
log,
} as WhookAutoloadDependencies);
const initializer = await $autoload('commandHandler');
const command = await (initializer as any)();
const result = await command();
expect({
initializer,
location: initializer[SPECIAL_PROPS.LOCATION],
result,
importerCalls: importer.mock.calls,
injectorCalls: $injector.mock.calls,
resolveCalls: resolve.mock.calls,
logCalls: log.mock.calls.filter(([type]) => !type.endsWith('stack')),
}).toMatchInlineSnapshot(`
{
"importerCalls": [
[
"file:///home/whoiam/project/src/commands/myCommand.ts",
],
],
"initializer": [Function],
"injectorCalls": [],
"location": undefined,
"logCalls": [
[
"warning",
"🤖 - Initializing the \`$autoload\` service.",
],
[
"warning",
"Command called!",
],
],
"resolveCalls": [],
"result": undefined,
}
`);
});
test('should work with whook-cli commands', async () => {
importer.mockImplementationOnce(() => {
throw new Error('ENOENT');
});
importer.mockImplementationOnce(async () => ({
default: async () => async () => log('warning', 'Command called!'),
definition: {},
}));
const $autoload = await initAutoload({
WHOOK_PLUGINS: [...WHOOK_PLUGINS, '@whook/cli'],
WHOOK_RESOLVED_PLUGINS: {
...WHOOK_RESOLVED_PLUGINS,
'@whook/cli': {
mainURL: 'file://var/lib/node/node_modules/@whook/cli/dist/index.js',
directory: 'file://var/lib/node/node_modules/@whook/cli/dist',
extension: '.js',
types: ['routes', 'commands', 'services', 'wrappers'],
},
},
args: { namedArguments: {}, rest: ['myCommand'], command: 'whook' },
importer,
$injector,
resolve,
access,
log,
} as WhookAutoloadDependencies);
const initializer = await $autoload('commandHandler');
const command = await (initializer as any)();
const result = await command();
expect({
initializer,
location: initializer[SPECIAL_PROPS.LOCATION],
result,
importerCalls: importer.mock.calls,
injectorCalls: $injector.mock.calls,
resolveCalls: resolve.mock.calls,
logCalls: log.mock.calls.filter(([type]) => !type.endsWith('stack')),
}).toMatchInlineSnapshot(`
{
"importerCalls": [
[
"file:///home/whoiam/project/src/commands/myCommand.ts",
],
[
"file://var/lib/node/node_modules/@whook/cli/dist/commands/myCommand.js",
],
],
"initializer": [Function],
"injectorCalls": [],
"location": undefined,
"logCalls": [
[
"warning",
"🤖 - Initializing the \`$autoload\` service.",
],
[
"debug",
"❌ - Command "myCommand" not found in "file:///home/whoiam/project/src/commands/myCommand.ts".",
],
[
"warning",
"Command called!",
],
],
"resolveCalls": [],
"result": undefined,
}
`);
});
test('should fail with bad commands', async () => {
importer.mockImplementationOnce(() => {
throw new Error('ENOENT');
});
importer.mockImplementationOnce(() => {
throw new Error('ENOENT');
});
const $autoload = await initAutoload({
WHOOK_PLUGINS,
WHOOK_RESOLVED_PLUGINS,
args: { namedArguments: {}, rest: ['myCommand'], command: 'whook' },
importer,
$injector,
resolve,
access,
log,
} as WhookAutoloadDependencies);
try {
await $autoload('commandHandler');
throw new YError('E_UNEXPECTED_SUCCESS');
} catch (err) {
expect({
errorCode: (err as YError).code,
errorDebug: (err as YError).debug,
importerCalls: importer.mock.calls,
injectorCalls: $injector.mock.calls,
resolveCalls: resolve.mock.calls,
logCalls: log.mock.calls.filter(([type]) => !type.endsWith('stack')),
}).toMatchInlineSnapshot(`
{
"errorCode": "E_BAD_COMMAND_NAME",
"errorDebug": [
"myCommand",
],
"importerCalls": [
[
"file:///home/whoiam/project/src/commands/myCommand.ts",
],
],
"injectorCalls": [],
"logCalls": [
[
"warning",
"🤖 - Initializing the \`$autoload\` service.",
],
[
"debug",
"❌ - Command "myCommand" not found in "file:///home/whoiam/project/src/commands/myCommand.ts".",
],
],
"resolveCalls": [],
}
`);
}
});
describe('should fail', () => {
test('with no command handler', async () => {
importer.mockResolvedValueOnce({});
const $autoload = await initAutoload({
WHOOK_PLUGINS,
WHOOK_RESOLVED_PLUGINS,
args: { namedArguments: {}, rest: ['myCommand'], command: 'whook' },
importer,
$injector,
resolve,
access,
log,
} as WhookAutoloadDependencies);
try {
await $autoload('commandHandler');
throw new YError('E_UNEXPECTED_SUCCESS');
} catch (err) {
expect({
errorCode: (err as YError).code,
errorDebug: (err as YError).debug,
importerCalls: importer.mock.calls,
injectorCalls: $injector.mock.calls,
resolveCalls: resolve.mock.calls,
logCalls: log.mock.calls.filter(([type]) => !type.endsWith('stack')),
}).toMatchInlineSnapshot(`
{
"errorCode": "E_NO_COMMAND_HANDLER",
"errorDebug": [
"myCommand",
],
"importerCalls": [
[
"file:///home/whoiam/project/src/commands/myCommand.ts",
],
],
"injectorCalls": [],
"logCalls": [
[
"warning",
"🤖 - Initializing the \`$autoload\` service.",
],
],
"resolveCalls": [],
}
`);
}
});
test('with no command definition', async () => {
importer.mockResolvedValueOnce({
default: async () => undefined,
});
const $autoload = await initAutoload({
WHOOK_PLUGINS,
WHOOK_RESOLVED_PLUGINS,
args: { namedArguments: {}, rest: ['myCommand'], command: 'whook' },
importer,
$injector,
resolve,
access,
log,
} as WhookAutoloadDependencies);
try {
await $autoload('commandHandler');
throw new YError('E_UNEXPECTED_SUCCESS');
} catch (err) {
expect({
errorCode: (err as YError).code,
errorDebug: (err as YError).debug,
importerCalls: importer.mock.calls,
injectorCalls: $injector.mock.calls,
resolveCalls: resolve.mock.calls,
logCalls: log.mock.calls.filter(([type]) => !type.endsWith('stack')),
}).toMatchInlineSnapshot(`
{
"errorCode": "E_NO_COMMAND_DEFINITION",
"errorDebug": [
"myCommand",
],
"importerCalls": [
[
"file:///home/whoiam/project/src/commands/myCommand.ts",
],
],
"injectorCalls": [],
"logCalls": [
[
"warning",
"🤖 - Initializing the \`$autoload\` service.",
],
],
"resolveCalls": [],
}
`);
}
});
});
});