mirror of
https://github.com/nestjs/nest.git
synced 2026-02-21 23:11:44 +00:00
Merge branch 'middleware-order' of https://github.com/underfin/nest into underfin-middleware-order
This commit is contained in:
60
integration/hello-world/e2e/middleware-execute-order.spec.ts
Normal file
60
integration/hello-world/e2e/middleware-execute-order.spec.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import { INestApplication, MiddlewareConsumer, Module } from '@nestjs/common';
|
||||
import { Test } from '@nestjs/testing';
|
||||
import * as request from 'supertest';
|
||||
|
||||
const RETURN_VALUE_A = 'test_A';
|
||||
const RETURN_VALUE_B = 'test_B';
|
||||
|
||||
@Module({
|
||||
imports: [],
|
||||
})
|
||||
class TestAModule {
|
||||
configure(consumer: MiddlewareConsumer) {
|
||||
consumer
|
||||
.apply((req, res, next) => {
|
||||
res.send(RETURN_VALUE_A);
|
||||
})
|
||||
.forRoutes('hello');
|
||||
}
|
||||
}
|
||||
|
||||
@Module({
|
||||
imports: [TestAModule],
|
||||
})
|
||||
class TestBModule {
|
||||
configure(consumer: MiddlewareConsumer) {
|
||||
consumer
|
||||
.apply((req, res, next) => {
|
||||
res.send(RETURN_VALUE_B);
|
||||
})
|
||||
.forRoutes('hello');
|
||||
}
|
||||
}
|
||||
|
||||
@Module({
|
||||
imports: [TestBModule],
|
||||
})
|
||||
class TestModule {
|
||||
}
|
||||
|
||||
describe('Middleware Execute Order', () => {
|
||||
let app: INestApplication;
|
||||
|
||||
beforeEach(async () => {
|
||||
app = (await Test.createTestingModule({
|
||||
imports: [TestModule],
|
||||
}).compile()).createNestApplication();
|
||||
|
||||
await app.init();
|
||||
});
|
||||
|
||||
it(`Execute middleware of dependent modules first `, () => {
|
||||
return request(app.getHttpServer())
|
||||
.get('/hello')
|
||||
.expect(200, RETURN_VALUE_A);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await app.close();
|
||||
});
|
||||
});
|
||||
@@ -43,6 +43,7 @@ export class Module {
|
||||
InstanceWrapper<Controller>
|
||||
>();
|
||||
private readonly _exports = new Set<string | symbol>();
|
||||
private _distance: number = 0;
|
||||
|
||||
constructor(
|
||||
private readonly _metatype: Type<any>,
|
||||
@@ -114,6 +115,17 @@ export class Module {
|
||||
return this._metatype;
|
||||
}
|
||||
|
||||
get distance(): number {
|
||||
return this._distance;
|
||||
}
|
||||
|
||||
set distance(distance: number){
|
||||
this._distance = distance;
|
||||
Array.from(this._imports)
|
||||
.filter((module) => !module.imports.has(this))
|
||||
.forEach((module) => module.distance = distance + 1);
|
||||
}
|
||||
|
||||
public addCoreProviders(container: NestContainer) {
|
||||
this.addModuleAsProvider();
|
||||
this.addModuleRef();
|
||||
@@ -398,8 +410,9 @@ export class Module {
|
||||
);
|
||||
}
|
||||
|
||||
public addRelatedModule(module: any) {
|
||||
public addRelatedModule(module: Module) {
|
||||
this._imports.add(module);
|
||||
module.distance = this._distance + 1 > module._distance ? this._distance + 1 : module._distance;
|
||||
}
|
||||
|
||||
public replace(toReplace: string | symbol | Type<any>, options: any) {
|
||||
|
||||
@@ -110,7 +110,9 @@ export class MiddlewareModule {
|
||||
});
|
||||
|
||||
await Promise.all(
|
||||
[...configs.entries()].map(async ([module, moduleConfigs]) => {
|
||||
[...configs.entries()].sort(([moduleA, moduleAConfigs], [moduleB, moduleBConfigs]) => {
|
||||
return this.container.getModuleByKey(moduleB).distance - this.container.getModuleByKey(moduleA).distance;
|
||||
}).map(async ([module, moduleConfigs]) => {
|
||||
await Promise.all(registerAllConfigs(module, [...moduleConfigs]));
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -481,4 +481,39 @@ describe('Module', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getter "distance"', () => {
|
||||
@ModuleDecorator({})
|
||||
class ModuleA {}
|
||||
|
||||
@ModuleDecorator({})
|
||||
class ModuleB {}
|
||||
|
||||
@ModuleDecorator({})
|
||||
class ModuleC {}
|
||||
|
||||
let moduleA, moduleB, moduleC;
|
||||
beforeEach(() => {
|
||||
moduleA = new Module(ModuleA as any, [], container);
|
||||
moduleB = new Module(ModuleB as any, [], container);
|
||||
moduleC = new Module(ModuleC as any, [], container);
|
||||
});
|
||||
|
||||
it('should get "distance" correct', () => {
|
||||
moduleA.addRelatedModule(moduleB);
|
||||
moduleC.addRelatedModule(moduleB);
|
||||
moduleA.addRelatedModule(moduleC);
|
||||
|
||||
expect(moduleA.distance).to.be.equal(0);
|
||||
expect(moduleB.distance).to.be.equal(2);
|
||||
expect(moduleC.distance).to.be.equal(1);
|
||||
});
|
||||
|
||||
it('should don`t throw exception when circular dependency', () => {
|
||||
expect(() => {
|
||||
moduleA.addRelatedModule(moduleB);
|
||||
moduleB.addRelatedModule(moduleA);
|
||||
}).to.not.throw;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user