mirror of
https://github.com/sern-handler/handler
synced 2026-06-06 01:16:55 +00:00
add more tests, polish up ioc
This commit is contained in:
@@ -17,6 +17,7 @@ export interface Disposable {
|
||||
dispose(): unknown;
|
||||
}
|
||||
|
||||
|
||||
export interface Emitter {
|
||||
addListener(eventName: string | symbol, listener: AnyFunction): this;
|
||||
removeListener(eventName: string | symbol, listener: AnyFunction): this;
|
||||
|
||||
@@ -13,7 +13,7 @@ export function disposeAll(logger: Logging|undefined) {
|
||||
|
||||
|
||||
type Insertable =
|
||||
| ((container: UnpackedDependencies) => unknown)
|
||||
| ((container: UnpackedDependencies) => object)
|
||||
| object
|
||||
const dependencyBuilder = (container: Container, excluded: string[] ) => {
|
||||
return {
|
||||
@@ -25,9 +25,7 @@ const dependencyBuilder = (container: Container, excluded: string[] ) => {
|
||||
if(typeof v !== 'function') {
|
||||
container.addSingleton(key, v)
|
||||
} else {
|
||||
//TODO fixme
|
||||
//@ts-ignore
|
||||
container.addWiredSingleton(key, (cntr: UnpackedDependencies) => v(cntr))
|
||||
container.addWiredSingleton(key, (cntr) => v(cntr as UnpackedDependencies))
|
||||
}
|
||||
},
|
||||
/**
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import * as __Services from '../structures/default-services';
|
||||
import type { UnpackedDependencies } from '../../types/utility';
|
||||
|
||||
/**
|
||||
* A semi-generic container that provides error handling, emitter, and module store.
|
||||
@@ -46,8 +46,8 @@ export class Container {
|
||||
return false;
|
||||
}
|
||||
|
||||
addWiredSingleton(key: string, fn: (c: Container) => object) {
|
||||
const insert = fn(this);
|
||||
addWiredSingleton(key: string, fn: (c: Record<string,unknown>) => object) {
|
||||
const insert = fn(this.deps());
|
||||
return this.addSingleton(key, insert);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ export async function importModule<T>(absPath: string) {
|
||||
|
||||
let commandModule: Module = fileModule.default;
|
||||
|
||||
assert(commandModule , `No export @ ${absPath}. Forgot to ignore with "!"? (!${path.basename(absPath)})?`);
|
||||
assert(commandModule , `No default export @ ${absPath}`);
|
||||
if ('default' in commandModule) {
|
||||
commandModule = commandModule.default as Module;
|
||||
}
|
||||
@@ -56,10 +56,15 @@ export async function importModule<T>(absPath: string) {
|
||||
|
||||
|
||||
export async function* readRecursive(dir: string): AsyncGenerator<string> {
|
||||
const files = await readdir(dir, { recursive: true, withFileTypes: true });
|
||||
const files = await readdir(dir, { withFileTypes: true });
|
||||
|
||||
for (const file of files) {
|
||||
const fullPath = path.join(file.parentPath, file.name);
|
||||
if(!file.name.startsWith('!') && !file.isDirectory()) {
|
||||
const fullPath = path.join(dir, file.name);
|
||||
if (file.isDirectory()) {
|
||||
if (!file.name.startsWith('!')) {
|
||||
yield* readRecursive(fullPath);
|
||||
}
|
||||
} else if (!file.name.startsWith('!')) {
|
||||
yield fullPath;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ import { PayloadType, SernError } from '../core/structures/enums'
|
||||
import { Err, Ok, Result } from 'ts-results-es';
|
||||
import type { Awaitable, UnpackedDependencies } from '../types/utility';
|
||||
import type { ControlPlugin } from '../types/core-plugin';
|
||||
import type { CommandMeta, CommandModule, Module, Processed } from '../types/core-modules';
|
||||
import type { CommandModule, Module, Processed } from '../types/core-modules';
|
||||
import { EventEmitter } from 'node:events';
|
||||
import * as assert from 'node:assert';
|
||||
import { Context } from '../core/structures/context';
|
||||
@@ -32,13 +32,13 @@ import { inspect } from 'node:util'
|
||||
import { disposeAll } from '../core/ioc/base';
|
||||
import { arrayifySource, callPlugin, everyPluginOk, filterMapTo, handleError } from '../core/operators';
|
||||
|
||||
import { resultPayload, isAutocomplete, treeSearch } from '../core/functions'
|
||||
|
||||
function contextArgs(wrappable: Message | BaseInteraction, messageArgs?: string[]) {
|
||||
const ctx = Context.wrap(wrappable);
|
||||
const args = ctx.isMessage() ? ['text', messageArgs!] : ['slash', ctx.options];
|
||||
return [ctx, args] as [Context, Args];
|
||||
}
|
||||
import { resultPayload, isAutocomplete, treeSearch } from '../core/functions'
|
||||
|
||||
function intoPayload(module: Processed<Module>, ) {
|
||||
return pipe(map(arrayifySource),
|
||||
|
||||
@@ -16,8 +16,8 @@ export default async function(dir: string, deps : UnpackedDependencies) {
|
||||
log?.info({ message: "Client signaled ready, registering modules" });
|
||||
for await (const path of Files.readRecursive(dir)) {
|
||||
const { module } = await Files.importModule<Module>(path);
|
||||
const validModuleType = module.type >= 0 && module.type <= 1 << 10;
|
||||
if(!validModuleType) {
|
||||
const validType = module.type >= 0 && module.type <= 1 << 10;
|
||||
if(!validType) {
|
||||
throw Error(`Found ${module.name} at ${module.meta.absPath}, which has an incorrect \`type\``);
|
||||
}
|
||||
for(const plugin of module.plugins) {
|
||||
|
||||
@@ -21,12 +21,6 @@ import { AnyCommandPlugin, AnyEventPlugin, ControlPlugin, InitPlugin } from './c
|
||||
import { Awaitable, Args, SlashOptions, SernEventsMapping } from './utility';
|
||||
|
||||
|
||||
export interface CommandMeta {
|
||||
fullPath: string;
|
||||
id: string;
|
||||
isClass: boolean;
|
||||
}
|
||||
|
||||
export type Processed<T> = T & { name: string; description: string };
|
||||
|
||||
export interface Module {
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import { faker } from '@faker-js/faker'
|
||||
import path from 'node:path'
|
||||
import * as Files from '../../src/core/module-loading'
|
||||
import { Module } from '../../src/types/core-modules'
|
||||
import { AssertionError } from 'node:assert'
|
||||
describe('module-loading', () => {
|
||||
it('should properly extract filename from file, nested once', () => {
|
||||
const extension = faker.system.fileExt()
|
||||
const name = faker.system.fileName({ extensionCount: 0 })
|
||||
const filename = Files.fmtFileName(name+'.'+extension);
|
||||
expect(filename).toBe(name)
|
||||
})
|
||||
it('should get the filename of the commandmodule (linux, esm)', () => {
|
||||
const fname = "///home/pooba/Projects/sern/halibu/dist/commands/ping.js"
|
||||
const callsiteinfo = Files.parseCallsite(fname)
|
||||
@@ -23,5 +19,32 @@ describe('module-loading', () => {
|
||||
const callsiteinfo = Files.parseCallsite(fname)
|
||||
expect(callsiteinfo.name).toEqual("ping");
|
||||
})
|
||||
|
||||
|
||||
it('should import a commandModule properly', async () => {
|
||||
const { module } = await Files.importModule<Module>(path.resolve("test", 'mockules', "module.ts"));
|
||||
expect(module.name).toBe('module')
|
||||
})
|
||||
it('should throw when failed commandModule import', async () => {
|
||||
try {
|
||||
await Files.importModule(path.resolve('test', 'mockules', 'failed.ts'))
|
||||
} catch(e) {
|
||||
expect(e instanceof AssertionError)
|
||||
}
|
||||
})
|
||||
it('should throw when failed commandModule import', async () => {
|
||||
try {
|
||||
await Files.importModule(path.resolve('test', 'mockules', 'failed.ts'))
|
||||
} catch(e) {
|
||||
expect(e instanceof AssertionError)
|
||||
}
|
||||
})
|
||||
|
||||
it('reads all modules in mockules', async () => {
|
||||
const ps = [] as string[]
|
||||
for await (const fpath of Files.readRecursive(path.resolve('test', 'mockules'))) {
|
||||
ps.push(fpath)
|
||||
}
|
||||
expect(ps.length === 4)
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
0
test/mockules/!ignd.ts
Normal file
0
test/mockules/!ignd.ts
Normal file
0
test/mockules/!ignored/ignored.ts
Normal file
0
test/mockules/!ignored/ignored.ts
Normal file
0
test/mockules/failed.ts
Normal file
0
test/mockules/failed.ts
Normal file
6
test/mockules/module.ts
Normal file
6
test/mockules/module.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { CommandType, commandModule } from '../../src/'
|
||||
export default commandModule({
|
||||
type: CommandType.Both,
|
||||
description: "",
|
||||
execute: (Ctx, args) => {}
|
||||
})
|
||||
6
test/mockules/ug/pass.ts
Normal file
6
test/mockules/ug/pass.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { CommandType, commandModule } from '../../../src/'
|
||||
export default commandModule({
|
||||
type: CommandType.Both,
|
||||
description: "",
|
||||
execute: (Ctx, args) => {}
|
||||
})
|
||||
Reference in New Issue
Block a user