diff --git a/packages/hmr/package.json b/packages/hmr/package.json index 8c70ece..19223ee 100644 --- a/packages/hmr/package.json +++ b/packages/hmr/package.json @@ -42,6 +42,7 @@ } }, "peerDependencies": { + "@cordisjs/plugin-schema": "^1.0.0-alpha.0", "@cordisjs/plugin-timer": "^1.0.0-alpha.0", "cordis": "^4.0.0-alpha.0" }, diff --git a/packages/loader/src/config/group.ts b/packages/loader/src/config/group.ts index 1e2ac6c..8b91de6 100644 --- a/packages/loader/src/config/group.ts +++ b/packages/loader/src/config/group.ts @@ -7,7 +7,7 @@ export class EntryGroup { public data: EntryOptions[] = [] - constructor(public ctx: C, public tree: EntryTree) { + constructor(public ctx: C, public tree: EntryTree) { const entry = ctx.scope.entry if (entry) entry.subgroup = this } @@ -18,7 +18,7 @@ export class EntryGroup { async create(options: Omit) { const id = this.tree.ensureId(options) - const entry = this.tree.store[id] ??= new Entry(this.ctx.loader) + const entry: Entry = this.tree.store[id] ??= new Entry(this.ctx.loader) // Entry may be moved from another group, // so we need to update the parent reference. entry.parent = this diff --git a/packages/loader/tests/group.spec.ts b/packages/loader/tests/group.spec.ts index d790c6b..f964bd0 100644 --- a/packages/loader/tests/group.spec.ts +++ b/packages/loader/tests/group.spec.ts @@ -1,19 +1,25 @@ -import { mock } from 'node:test' +import { Mock, mock } from 'node:test' import { expect } from 'chai' import { Context } from '@cordisjs/core' import MockLoader from './utils' describe('group management: basic support', () => { const root = new Context() - root.plugin(MockLoader) - const loader = root.loader as unknown as MockLoader - const dispose = mock.fn() - const foo = loader.mock('foo', (ctx: Context) => { - ctx.on('dispose', dispose) - }) - before(() => loader.start()) + let loader!: MockLoader + let foo!: Mock + + before(async () => { + await root.plugin(MockLoader) + loader = root.loader as any + + foo = loader.mock('foo', (ctx: Context) => { + ctx.on('dispose', dispose) + }) + + await loader.start() + }) beforeEach(() => { foo.mock.resetCalls() @@ -40,6 +46,8 @@ describe('group management: basic support', () => { }], }, outer) + await loader.expectScope(outer) + await loader.expectScope(inner) expect(foo.mock.calls).to.have.length(2) expect(dispose.mock.calls).to.have.length(0) expect([...loader.entries()]).to.have.length(4) @@ -72,6 +80,7 @@ describe('group management: basic support', () => { it('enable outer', async () => { await loader.update(outer, { disabled: null }) + await new Promise((resolve) => setTimeout(resolve, 0)) expect(foo.mock.calls).to.have.length(2) expect(dispose.mock.calls).to.have.length(0) expect([...loader.entries()]).to.have.length(4) @@ -80,15 +89,21 @@ describe('group management: basic support', () => { describe('group management: transfer', () => { const root = new Context() - root.plugin(MockLoader) - const loader = root.loader as unknown as MockLoader - const dispose = mock.fn() - const foo = loader.mock('foo', (ctx: Context) => { - ctx.on('dispose', dispose) - }) - before(() => loader.start()) + let loader!: MockLoader + let foo!: Mock + + before(async () => { + await root.plugin(MockLoader) + loader = root.loader as any + + foo = loader.mock('foo', (ctx: Context) => { + ctx.on('dispose', dispose) + }) + + await loader.start() + }) beforeEach(() => { foo.mock.resetCalls() diff --git a/packages/loader/tests/index.spec.ts b/packages/loader/tests/index.spec.ts index 76fa9f3..e7d8af8 100644 --- a/packages/loader/tests/index.spec.ts +++ b/packages/loader/tests/index.spec.ts @@ -1,17 +1,26 @@ import { expect } from 'chai' import { Context } from '@cordisjs/core' import MockLoader from './utils' +import { Mock } from 'node:test' describe('loader: basic support', () => { const root = new Context() - root.plugin(MockLoader) - const loader = root.loader as unknown as MockLoader - const foo = loader.mock('foo', (ctx: Context) => ctx.on('internal/update', () => true)) - const bar = loader.mock('bar', (ctx: Context) => ctx.on('internal/update', () => true)) - const qux = loader.mock('qux', (ctx: Context) => ctx.on('internal/update', () => true)) + let loader!: MockLoader + let foo!: Mock + let bar!: Mock + let qux!: Mock - before(() => loader.start()) + before(async () => { + await root.plugin(MockLoader) + loader = root.loader as any + + foo = loader.mock('foo', (ctx: Context) => ctx.on('internal/update', () => true)) + bar = loader.mock('bar', (ctx: Context) => ctx.on('internal/update', () => true)) + qux = loader.mock('qux', (ctx: Context) => ctx.on('internal/update', () => true)) + + await loader.start() + }) it('loader initiate', async () => { await loader.read([{ diff --git a/packages/loader/tests/isolate.spec.ts b/packages/loader/tests/isolate.spec.ts index 6459363..eb2fc06 100644 --- a/packages/loader/tests/isolate.spec.ts +++ b/packages/loader/tests/isolate.spec.ts @@ -1,30 +1,37 @@ -import { mock } from 'node:test' +import { Mock, mock } from 'node:test' import { expect } from 'chai' import { Context, ScopeStatus, Service } from '@cordisjs/core' import { defineProperty } from 'cosmokit' import MockLoader from './utils' -describe('service isolation: basic', async () => { +describe('service isolation: basic', () => { const root = new Context() - root.plugin(MockLoader) - const loader = root.loader as unknown as MockLoader - const dispose = mock.fn() - const foo = loader.mock('foo', defineProperty((ctx: Context) => { - ctx.on('dispose', dispose) - }, 'inject', ['bar'])) + let loader!: MockLoader + let foo!: Mock + let bar!: Mock - loader.mock('bar', class Bar extends Service { - constructor(ctx: Context) { - super(ctx, 'bar') - } - }) + before(async () => { + await root.plugin(MockLoader) + loader = root.loader as any + + foo = loader.mock('foo', defineProperty((ctx: Context) => { + ctx.on('dispose', dispose) + }, 'inject', ['bar'])) + + bar = loader.mock('bar', class Bar extends Service { + constructor(ctx: Context) { + super(ctx, 'bar') + } + }) - before(() => loader.start()) + await loader.start() + }) beforeEach(() => { foo.mock.resetCalls() + bar.mock.resetCalls() dispose.mock.resetCalls() }) @@ -135,27 +142,34 @@ describe('service isolation: basic', async () => { }) }) -describe('service isolation: realm', async () => { +describe('service isolation: realm', () => { const root = new Context() - root.plugin(MockLoader) - const loader = root.loader as unknown as MockLoader - const dispose = mock.fn() - const foo = Object.assign(loader.mock('foo', (ctx: Context) => { - ctx.on('dispose', dispose) - }), { - inject: ['bar'], - }) + let loader!: MockLoader + let foo!: Mock + let bar!: Mock - const bar = Object.assign(loader.mock('bar', (ctx: Context, config: {}) => { - ctx.set('bar', config) - })) + before(async () => { + await root.plugin(MockLoader) + loader = root.loader as any + + foo = Object.assign(loader.mock('foo', (ctx: Context) => { + ctx.on('dispose', dispose) + }), { + inject: ['bar'], + }) + + bar = Object.assign(loader.mock('bar', (ctx: Context, config = {}) => { + ctx.set('bar', config) + })) - before(() => loader.start()) + await loader.start() + }) beforeEach(() => { foo.mock.resetCalls() + bar.mock.resetCalls() dispose.mock.resetCalls() }) @@ -243,7 +257,7 @@ describe('service isolation: realm', async () => { it('special case: nested realms', async () => { const root = new Context() - root.plugin(MockLoader) + await root.plugin(MockLoader) const loader = root.loader as unknown as MockLoader const dispose = mock.fn() @@ -254,7 +268,7 @@ describe('service isolation: realm', async () => { inject: ['bar'], }) - Object.assign(loader.mock('bar', (ctx: Context, config: {}) => { + Object.assign(loader.mock('bar', (ctx: Context, config = {}) => { ctx.set('bar', config) })) @@ -322,7 +336,7 @@ describe('service isolation: realm', async () => { it('special case: change provider', async () => { const root = new Context() - root.plugin(MockLoader) + await root.plugin(MockLoader) const loader = root.loader as unknown as MockLoader const dispose = mock.fn() @@ -333,7 +347,7 @@ describe('service isolation: realm', async () => { inject: ['bar'], }) - Object.assign(loader.mock('bar', (ctx: Context, config: {}) => { + Object.assign(loader.mock('bar', (ctx: Context, config = {}) => { ctx.set('bar', config) })) @@ -390,7 +404,7 @@ describe('service isolation: realm', async () => { it('special case: change injector', async () => { const root = new Context() - root.plugin(MockLoader) + await root.plugin(MockLoader) const loader = root.loader as unknown as MockLoader const dispose = mock.fn() @@ -401,9 +415,9 @@ describe('service isolation: realm', async () => { inject: ['bar'], }) - Object.assign(loader.mock('bar', (ctx: Context, config: {}) => { + const bar = loader.mock('bar', (ctx: Context, config = {}) => { ctx.set('bar', config) - })) + }) await loader.start() @@ -429,10 +443,11 @@ describe('service isolation: realm', async () => { config: [], }) - await loader.create({ + const inner = await loader.create({ name: 'bar', }, group) + await loader.expectScope(inner) await new Promise((resolve) => setTimeout(resolve, 0)) expect(foo.mock.calls).to.have.length(1) expect(dispose.mock.calls).to.have.length(0) @@ -460,25 +475,32 @@ describe('service isolation: realm', async () => { describe('service isolation: transfer', () => { const root = new Context() - root.plugin(MockLoader) - const loader = root.loader as unknown as MockLoader - const dispose = mock.fn() - const foo = loader.mock('foo', defineProperty((ctx: Context) => { - ctx.on('dispose', dispose) - }, 'inject', ['bar'])) + let loader!: MockLoader + let foo!: Mock + let bar!: Mock - loader.mock('bar', class Bar extends Service { - constructor(ctx: Context) { - super(ctx, 'bar') - } - }) + before(async () => { + await root.plugin(MockLoader) + loader = root.loader as any + + foo = loader.mock('foo', defineProperty((ctx: Context) => { + ctx.on('dispose', dispose) + }, 'inject', ['bar'])) - before(() => loader.start()) + bar = loader.mock('bar', class Bar extends Service { + constructor(ctx: Context) { + super(ctx, 'bar') + } + }) + + await loader.start() + }) beforeEach(() => { foo.mock.resetCalls() + bar.mock.resetCalls() dispose.mock.resetCalls() }) diff --git a/packages/loader/tests/utils.ts b/packages/loader/tests/utils.ts index 85e03d6..69296a0 100644 --- a/packages/loader/tests/utils.ts +++ b/packages/loader/tests/utils.ts @@ -1,10 +1,10 @@ import { Dict } from 'cosmokit' import { Context, EffectScope, Plugin } from '@cordisjs/core' -import { EntryOptions, Group, Loader, LoaderFile } from '../src/index.js' +import { EntryOptions, Group, Loader, LoaderFile } from '../src' import { Mock, mock } from 'node:test' import { expect } from 'chai' -declare module '../src/index.js' { +declare module '../src' { interface Loader { mock(name: string, plugin: F): Mock expectEnable(plugin: any, config?: any): void diff --git a/packages/logger/src/index.ts b/packages/logger/src/index.ts index c320663..03861a3 100644 --- a/packages/logger/src/index.ts +++ b/packages/logger/src/index.ts @@ -35,17 +35,18 @@ export interface LoggerService extends Pick { export class LoggerService extends Service { constructor(ctx: Context) { super(ctx, 'logger') + const self = this ctx.on('internal/info', function (format, ...args) { - this.logger('app').info(format, ...args) + self('app').info(format, ...args) }) ctx.on('internal/error', function (format, ...args) { - this.logger('app').error(format, ...args) + self('app').error(format, ...args) }) ctx.on('internal/warning', function (format, ...args) { - this.logger('app').warn(format, ...args) + self('app').warn(format, ...args) }) }