From b23e0ca8641f53051d0cca4eacee587c61403edc Mon Sep 17 00:00:00 2001 From: Tim Trinidad Date: Tue, 25 Sep 2018 14:51:28 -0400 Subject: [PATCH] Add inRequestScope decorator inversify/InversifyJS/issues/678 --- src/interfaces/interfaces.ts | 1 + src/syntax/provide_in_syntax.ts | 22 ++++---- src/syntax/provide_in_when_on_syntax.ts | 4 ++ test/index.test.ts | 6 ++- test/syntax/provide_in_syntax.test.ts | 69 +++++++++---------------- 5 files changed, 47 insertions(+), 55 deletions(-) diff --git a/src/interfaces/interfaces.ts b/src/interfaces/interfaces.ts index 220eb4f..c67a749 100644 --- a/src/interfaces/interfaces.ts +++ b/src/interfaces/interfaces.ts @@ -15,6 +15,7 @@ namespace interfaces { export interface ProvideInSyntax extends ProvideDoneSyntax { inSingletonScope(): ProvideWhenOnSyntax; + inRequestScope(): ProvideWhenOnSyntax; inTransientScope(): ProvideWhenOnSyntax; } diff --git a/src/syntax/provide_in_syntax.ts b/src/syntax/provide_in_syntax.ts index 08b32ab..0e2a4a0 100644 --- a/src/syntax/provide_in_syntax.ts +++ b/src/syntax/provide_in_syntax.ts @@ -21,25 +21,29 @@ class ProvideInSyntax implements interfaces.ProvideInSyntax { public inSingletonScope(): interfaces.ProvideWhenOnSyntax { let bindingWhenOnSyntax = (bind: inversifyInterfaces.Bind, target: any) => this._bindingInSyntax(bind, target).inSingletonScope(); - let inDoneSyntax = new ProvideDoneSyntax(bindingWhenOnSyntax); - let provideWhenSyntax = new ProvideWhenSyntax(bindingWhenOnSyntax, inDoneSyntax); - let provideOnSyntax = new ProvideOnSyntax(bindingWhenOnSyntax, inDoneSyntax); - return new ProvideWhenOnSyntax(provideWhenSyntax, provideOnSyntax); + return this.provideWhenOnSyntax(bindingWhenOnSyntax); + } + + public inRequestScope(): interfaces.ProvideWhenOnSyntax { + let bindingWhenOnSyntax = (bind: inversifyInterfaces.Bind, target: any) => this._bindingInSyntax(bind, target).inRequestScope(); + return this.provideWhenOnSyntax(bindingWhenOnSyntax); } public inTransientScope(): interfaces.ProvideWhenOnSyntax { let bindingWhenOnSyntax = (bind: inversifyInterfaces.Bind, target: any) => this._bindingInSyntax(bind, target).inTransientScope(); - let inDoneSyntax = new ProvideDoneSyntax(bindingWhenOnSyntax); - - let provideWhenSyntax = new ProvideWhenSyntax(bindingWhenOnSyntax, inDoneSyntax); - let provideOnSyntax = new ProvideOnSyntax(bindingWhenOnSyntax, inDoneSyntax); - return new ProvideWhenOnSyntax(provideWhenSyntax, provideOnSyntax); + return this.provideWhenOnSyntax(bindingWhenOnSyntax); } public done(force?: boolean) { return this._provideDoneSyntax.done(force); } + private provideWhenOnSyntax(bindingWhenOnSyntax: interfaces.BindConstraint) { + let inDoneSyntax = new ProvideDoneSyntax(bindingWhenOnSyntax); + let provideWhenSyntax = new ProvideWhenSyntax(bindingWhenOnSyntax, inDoneSyntax); + let provideOnSyntax = new ProvideOnSyntax(bindingWhenOnSyntax, inDoneSyntax); + return new ProvideWhenOnSyntax(provideWhenSyntax, provideOnSyntax); + } } export default ProvideInSyntax; diff --git a/src/syntax/provide_in_when_on_syntax.ts b/src/syntax/provide_in_when_on_syntax.ts index 84fd226..0b695f8 100644 --- a/src/syntax/provide_in_when_on_syntax.ts +++ b/src/syntax/provide_in_when_on_syntax.ts @@ -81,6 +81,10 @@ class ProvideInWhenOnSyntax implements interfaces.ProvideInWhenOnSyntax { return this._provideInSyntax.inSingletonScope(); } + public inRequestScope(): interfaces.ProvideWhenOnSyntax { + return this._provideInSyntax.inRequestScope(); + } + public inTransientScope(): interfaces.ProvideWhenOnSyntax { return this._provideInSyntax.inTransientScope(); } diff --git a/test/index.test.ts b/test/index.test.ts index 97e7711..adc34c7 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -208,6 +208,10 @@ describe("inversify-binding-decorators", () => { return fluentProvide(identifier).inSingletonScope().done(); }; + let provideRequest = function (identifier: string) { + return fluentProvide(identifier).inRequestScope().done(); + }; + let provideTransient = function (identifier: string) { return fluentProvide(identifier).inTransientScope().done(); }; @@ -244,7 +248,7 @@ describe("inversify-binding-decorators", () => { } } - @provideTransient(TYPE.ThrowableWeapon) + @provideRequest(TYPE.ThrowableWeapon) class Shuriken implements ThrowableWeapon { private _mark: any; public constructor() { diff --git a/test/syntax/provide_in_syntax.test.ts b/test/syntax/provide_in_syntax.test.ts index ec66765..f2cf5f4 100644 --- a/test/syntax/provide_in_syntax.test.ts +++ b/test/syntax/provide_in_syntax.test.ts @@ -19,50 +19,29 @@ describe("ProvideInSyntax", () => { sandbox.restore(); }); - it("Should be able to declare a binding with singleton scope", () => { - - class Ninja { } - let inSingletonScopeExpectation = sinon.expectation.create("inSingletonScope"); - let mockBindingInSyntax = { inSingletonScope: inSingletonScopeExpectation } as any as inversifyInterfaces.BindingInSyntax; - let mockBind = sinon.expectation.create("bind"); - let bindingInSyntaxFunction = - (bind: inversifyInterfaces.Bind, target: any) => { - bind("Ninja"); - return mockBindingInSyntax; - }; - let binding: inversifyInterfaces.Binding = (bindingInSyntaxFunction)._binding; - let provideDoneSyntax = new ProvideDoneSyntax(binding as any); - - let provideInSyntax = new ProvideInSyntax(bindingInSyntaxFunction, provideDoneSyntax); - - provideInSyntax.inSingletonScope().done()(Ninja); - let metadata = Reflect.getMetadata(METADATA_KEY.provide, Reflect)[0]; - metadata.constraint(mockBind); - expect(inSingletonScopeExpectation.calledOnce).to.eql(true, "inSingletonScope was not called exactly once"); - expect(mockBind.calledWith("Ninja")).to.be.eql(true, "mock bind was not called"); - - }); - it("Should be able to declare a binding with transient scope", () => { - - class Ninja { } - let inTransientScopeExpectation = sinon.expectation.create("inTransientScope"); - let mockBindingInSyntax = { inTransientScope: inTransientScopeExpectation } as any as inversifyInterfaces.BindingInSyntax; - let mockBind = sinon.expectation.create("bind"); - let bindingInSyntaxFunction = - (bind: inversifyInterfaces.Bind, target: any) => { - bind("Ninja"); - return mockBindingInSyntax; - }; - let binding: inversifyInterfaces.Binding = (bindingInSyntaxFunction)._binding; - let provideDoneSyntax = new ProvideDoneSyntax(binding as any); - - let provideInSyntax = new ProvideInSyntax(bindingInSyntaxFunction, provideDoneSyntax); - - provideInSyntax.inTransientScope().done()(Ninja); - let metadata = Reflect.getMetadata(METADATA_KEY.provide, Reflect)[0]; - metadata.constraint(mockBind); - expect(inTransientScopeExpectation.calledOnce).to.eql(true, "inTransientScope was not called exactly once"); - expect(mockBind.calledWith("Ninja")).to.be.eql(true, "mock bind was not called"); - + ["inSingletonScope", "inRequestScope", "inTransientScope"].forEach(scope => { + it(`Should be able to declare a binding with ${scope} scope`, () => { + + class Ninja { } + let inScopeExpectation = sinon.expectation.create(scope); + let mockBindingInSyntax = { [scope]: inScopeExpectation } as any as inversifyInterfaces.BindingInSyntax; + let mockBind = sinon.expectation.create("bind"); + let bindingInSyntaxFunction = + (bind: inversifyInterfaces.Bind, target: any) => { + bind("Ninja"); + return mockBindingInSyntax; + }; + let binding: inversifyInterfaces.Binding = (bindingInSyntaxFunction)._binding; + let provideDoneSyntax = new ProvideDoneSyntax(binding as any); + + let provideInSyntax: {[scope: string]: any} = new ProvideInSyntax(bindingInSyntaxFunction, provideDoneSyntax); + + provideInSyntax[scope]().done()(Ninja); + let metadata = Reflect.getMetadata(METADATA_KEY.provide, Reflect)[0]; + metadata.constraint(mockBind); + expect(inScopeExpectation.calledOnce).to.eql(true, `${scope} was not called exactly once`); + expect(mockBind.calledWith("Ninja")).to.be.eql(true, "mock bind was not called"); + + }); }); });