Skip to content

Commit

Permalink
[Feat][Breaking] ResolutionScope and ContainerScope implementation (m…
Browse files Browse the repository at this point in the history
  • Loading branch information
Xapphire13 authored Nov 2, 2019
1 parent d96e0b5 commit 89da698
Show file tree
Hide file tree
Showing 24 changed files with 1,374 additions and 897 deletions.
8 changes: 8 additions & 0 deletions .eslintrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ plugins:
- "prettier"
extends:
- "plugin:@typescript-eslint/recommended"
- "prettier/@typescript-eslint"
- "plugin:prettier/recommended"
globals:
Atomics: readonly
Expand All @@ -26,3 +27,10 @@ rules:
"@typescript-eslint/no-parameter-properties": off
"@typescript-eslint/prefer-interface": off
"@typescript-eslint/indent": off
overrides:
- files:
- "*.test.ts"
- "*.spec.ts"
rules:
"@typescript-eslint/no-empty-function": off
"@typescript-eslint/interface-name-prefix": off
13 changes: 7 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@
"build:types": "tsc -p ./typescript/tsconfig.types.json",
"clean": "rimraf ./dist",
"test": "npm run lint && jest --config test/jest.config.js",
"test:inspect": "npm run lint && node --inspect-brk ./node_modules/jest/bin/jest.js --runInBand --config test/jest.config.js",
"test:coverage": "jest --config test/jest.config.js --coverage",
"lint": "prettier --check \"./src/**/*.ts\" && eslint --ext \".js,.jsx,.ts,.tsx\" \"./src\"",
"lint:fix": "prettier \"./src/**/*.ts\" && eslint --fix --ext \".js,.jsx,.ts,.tsx\" \"./src\""
"lint": "eslint --ext \".js,.jsx,.ts,.tsx\" \"./src\"",
"lint:fix": "eslint --fix --ext \".js,.jsx,.ts,.tsx\" \"./src\""
},
"repository": {
"type": "git",
Expand Down Expand Up @@ -46,14 +47,14 @@
"devDependencies": {
"@types/jest": "^24.0.11",
"@types/node": "^8.10.16",
"@typescript-eslint/eslint-plugin": "^1.6.0",
"@typescript-eslint/parser": "^1.11.0",
"eslint": "^5.16.0",
"@typescript-eslint/eslint-plugin": "^2.5.0",
"@typescript-eslint/parser": "^2.5.0",
"eslint": "^6.5.1",
"eslint-config-prettier": "^6.4.0",
"eslint-plugin-prettier": "^3.1.1",
"husky": "^3.0.0",
"jest": "^24.7.1",
"prettier": "1.17.0",
"prettier": "1.18.2",
"reflect-metadata": "^0.1.12",
"rimraf": "^2.6.2",
"ts-jest": "^24.0.2",
Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/auto-injectable.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ test("@autoInjectable resolves multiple registered dependencies", () => {

@injectable()
class FooBar implements Bar {
str: string = "";
str = "";
}

globalContainer.register<Bar>("Bar", {useClass: FooBar});
Expand Down
11 changes: 11 additions & 0 deletions src/__tests__/child-container.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,14 @@ test("child container resolves all using parent's registration when child contai
expect(myFoo.length).toBe(1);
expect(myFoo[0] instanceof Foo).toBeTruthy();
});

test("isRegistered check parent containers recursively", () => {
class A {}

globalContainer.registerType(A, A);
const child = globalContainer.createChildContainer();

expect(globalContainer.isRegistered(A)).toBeTruthy();
expect(child.isRegistered(A)).toBeFalsy();
expect(child.isRegistered(A, true)).toBeTruthy();
});
48 changes: 27 additions & 21 deletions src/__tests__/global-container.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import {instanceCachingFactory, predicateAwareClassFactory} from "../factories";
import {DependencyContainer} from "../types";
import {instance as globalContainer} from "../dependency-container";
import injectAll from "../decorators/inject-all";
import Lifecycle from "../types/lifecycle";
import {ValueProvider} from "../providers";

interface IBar {
value: string;
Expand Down Expand Up @@ -93,7 +95,11 @@ test("resolves a transient instance when registered by class provider", () => {

test("resolves a singleton instance when class provider registered as singleton", () => {
class Bar {}
globalContainer.register("Bar", {useClass: Bar}, {singleton: true});
globalContainer.register(
"Bar",
{useClass: Bar},
{lifecycle: Lifecycle.Singleton}
);

const myBar = globalContainer.resolve<Bar>("Bar");
const myBar2 = globalContainer.resolve<Bar>("Bar");
Expand All @@ -120,7 +126,7 @@ test("resolves a singleton instance when token alias registered as singleton", (
globalContainer.register(
"SingletonBar",
{useToken: "Bar"},
{singleton: true}
{lifecycle: Lifecycle.Singleton}
);

const myBar = globalContainer.resolve<Bar>("SingletonBar");
Expand Down Expand Up @@ -211,11 +217,11 @@ test("resolves an array of transient instances bound to a single interface", ()
}

class FooOne implements FooInterface {
public bar: string = "foo1";
public bar = "foo1";
}

class FooTwo implements FooInterface {
public bar: string = "foo2";
public bar = "foo2";
}

globalContainer.register<FooInterface>("FooInterface", {useClass: FooOne});
Expand Down Expand Up @@ -245,7 +251,7 @@ test("resolves all transient instances when not registered", () => {
test("returns true for a registered singleton class", () => {
@injectable()
class Bar implements IBar {
public value: string = "";
public value = "";
}

@injectable()
Expand All @@ -260,7 +266,7 @@ test("returns true for a registered singleton class", () => {
test("returns true for a registered class provider", () => {
@injectable()
class Bar implements IBar {
public value: string = "";
public value = "";
}

@injectable()
Expand All @@ -275,22 +281,22 @@ test("returns true for a registered class provider", () => {
test("returns true for a registered value provider", () => {
@injectable()
class Bar implements IBar {
public value: string = "";
public value = "";
}

@injectable()
class Foo {
constructor(public myBar: Bar) {}
}
globalContainer.register(Foo, {useValue: {}});
globalContainer.register(Foo, {useValue: {}} as ValueProvider<any>);

expect(globalContainer.isRegistered(Foo)).toBeTruthy();
});

test("returns true for a registered token provider", () => {
@injectable()
class Bar implements IBar {
public value: string = "";
public value = "";
}

@injectable()
Expand All @@ -307,7 +313,7 @@ test("returns true for a registered token provider", () => {
test("@injectable resolves when not using DI", () => {
@injectable()
class Bar implements IBar {
public value: string = "";
public value = "";
}

@injectable()
Expand All @@ -326,7 +332,7 @@ test("@injectable resolves when not using DI", () => {
test("@injectable resolves when using DI", () => {
@injectable()
class Bar implements IBar {
public value: string = "";
public value = "";
}

@injectable()
Expand All @@ -341,7 +347,7 @@ test("@injectable resolves when using DI", () => {
test("@injectable resolves nested dependencies when using DI", () => {
@injectable()
class Bar implements IBar {
public value: string = "";
public value = "";
}
@injectable()
class Foo {
Expand Down Expand Up @@ -375,7 +381,7 @@ test("@injectable preserves static members", () => {
test("@injectable handles optional params", () => {
@injectable()
class Bar implements IBar {
public value: string = "";
public value = "";
}
@injectable()
class Foo {
Expand Down Expand Up @@ -442,7 +448,7 @@ test("doesn't blow up with empty args", () => {
test("registers by type provider", () => {
@injectable()
class Bar implements IBar {
public value: string = "";
public value = "";
}
@registry([{token: Bar, useClass: Bar}])
class RegisteringFoo {}
Expand All @@ -455,7 +461,7 @@ test("registers by type provider", () => {
test("registers by class provider", () => {
@injectable()
class Bar implements IBar {
public value: string = "";
public value = "";
}
const registration = {
token: "IBar",
Expand Down Expand Up @@ -501,7 +507,7 @@ test("registers by token provider", () => {
test("registers by factory provider", () => {
@injectable()
class Bar implements IBar {
public value: string = "";
public value = "";
}

const registration = {
Expand All @@ -521,7 +527,7 @@ test("registers by factory provider", () => {
test("registers mixed types", () => {
@injectable()
class Bar implements IBar {
public value: string = "";
public value = "";
}
@injectable()
class Foo {
Expand Down Expand Up @@ -563,7 +569,7 @@ test("registers by symbol token provider", () => {
test("allows interfaces to be resolved from the constructor with injection token", () => {
@injectable()
class Bar implements IBar {
public value: string = "";
public value = "";
}

@injectable()
Expand All @@ -580,7 +586,7 @@ test("allows interfaces to be resolved from the constructor with injection token
test("allows interfaces to be resolved from the constructor with just a name", () => {
@injectable()
class Bar implements IBar {
public value: string = "";
public value = "";
}

@injectable()
Expand Down Expand Up @@ -624,11 +630,11 @@ test("injects all dependencies bound to a given interface", () => {
}

class FooImpl1 implements Foo {
public str: string = "foo1";
public str = "foo1";
}

class FooImpl2 implements Foo {
public str: string = "foo2";
public str = "foo2";
}

@injectable()
Expand Down
26 changes: 21 additions & 5 deletions src/__tests__/registry.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Registry from "../registry";
import {Registration} from "../dependency-container";
import Lifecycle from "../types/lifecycle";

let registry: Registry;
beforeEach(() => {
Expand All @@ -8,11 +9,11 @@ beforeEach(() => {

test("getAll returns all registrations of a given key", () => {
const registration1: Registration = {
options: {singleton: false},
options: {lifecycle: Lifecycle.Singleton},
provider: {useValue: "provider"}
};
const registration2: Registration = {
options: {singleton: false},
options: {lifecycle: Lifecycle.Singleton},
provider: {useValue: "provider"}
};

Expand All @@ -30,11 +31,11 @@ test("getAll returns all registrations of a given key", () => {

test("get returns the last registration", () => {
const registration1: Registration = {
options: {singleton: false},
options: {lifecycle: Lifecycle.Singleton},
provider: {useValue: "provider"}
};
const registration2: Registration = {
options: {singleton: false},
options: {lifecycle: Lifecycle.Singleton},
provider: {useValue: "provider"}
};

Expand All @@ -52,7 +53,7 @@ test("get returns null when there is no registration", () => {

test("clear removes all registrations", () => {
const registration: Registration = {
options: {singleton: false},
options: {lifecycle: Lifecycle.Singleton},
provider: {useValue: "provider"}
};

Expand All @@ -62,3 +63,18 @@ test("clear removes all registrations", () => {
registry.clear();
expect(registry.has("Foo")).toBeFalsy();
});

test("setAll replaces everything with new value", () => {
const registration: Registration = {
options: {lifecycle: Lifecycle.Transient},
provider: {useValue: "provider"}
};

expect(registry.has("Foo")).toBeFalsy();

registry.set("Foo", registration);
const fooArray = registry.getAll("Foo");
registry.setAll("Foo", [registration]);

expect(fooArray === registry.getAll("Foo")).toBeFalsy();
});
Loading

0 comments on commit 89da698

Please sign in to comment.