Skip to content

Commit

Permalink
feat: Container.hasToken() for checking token presence.
Browse files Browse the repository at this point in the history
  • Loading branch information
mnasyrov committed Apr 17, 2021
1 parent d4a41e8 commit 1c4cb87
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 1 deletion.
4 changes: 4 additions & 0 deletions packages/ditox/lib/index.d.ts
Expand Up @@ -72,6 +72,10 @@ declare type Container = {
* Binds a factory for the token.
*/
bindFactory<T>(token: Token<T>, factory: (container: Container) => T, options?: FactoryOptions<T>): void;
/**
* Checks if the token is registered in the container hierarchy.
*/
hasToken(token: Token<unknown>): boolean;
/**
* Returns a resolved value by the token, or returns `undefined` in case the token is not found.
*/
Expand Down
6 changes: 6 additions & 0 deletions packages/ditox/lib/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/ditox/lib/index.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions packages/ditox/src/ditox.js.flow
Expand Up @@ -95,10 +95,16 @@ export type Container = {
options?: FactoryOptions<T>,
): void,

/**
* Checks if the token is registered in the container hierarchy.
*/
hasToken(token: Token<*>): boolean;

/**
* Returns a resolved value by the token, or returns `undefined` in case the token is not found.
*/
get<T>(token: Token<T>): T | void,

/**
* Returns a resolved value by the token, or throws `ResolverError` in case the token is not found.
*/
Expand All @@ -108,6 +114,7 @@ export type Container = {
* Removes a binding for the token.
*/
remove<T>(token: Token<T>): void,

/**
* Removes all bindings in the container.
*/
Expand Down
29 changes: 29 additions & 0 deletions packages/ditox/src/ditox.test.ts
Expand Up @@ -390,6 +390,35 @@ describe('Container', () => {
});
});

describe('hasToken()', () => {
it('should check if a container hierarchy has the token', () => {
const factory = jest.fn();

const token1 = token();
const token2 = token();
const token3 = token();

const parent = createContainer();
parent.bindValue(token1, 1);
parent.bindFactory(token2, factory);

expect(parent.hasToken(token1)).toBe(true);
expect(parent.hasToken(token2)).toBe(true);
expect(parent.hasToken(token3)).toBe(false);

const child = createContainer(parent);
expect(child.hasToken(token1)).toBe(true);
expect(child.hasToken(token2)).toBe(true);
expect(child.hasToken(token3)).toBe(false);

child.bindValue(token3, 2);
expect(parent.hasToken(token3)).toBe(false);
expect(child.hasToken(token3)).toBe(true);

expect(factory).toHaveBeenCalledTimes(0);
});
});

describe('get()', () => {
it('should return a provided value', () => {
const container = createContainer();
Expand Down
13 changes: 13 additions & 0 deletions packages/ditox/src/ditox.ts
Expand Up @@ -107,6 +107,11 @@ export type Container = {
options?: FactoryOptions<T>,
): void;

/**
* Checks if the token is registered in the container hierarchy.
*/
hasToken(token: Token<unknown>): boolean;

/**
* Returns a resolved value by the token, or returns `undefined` in case the token is not found.
*/
Expand Down Expand Up @@ -247,6 +252,14 @@ export function createContainer(parentContainer?: Container): Container {
bindInternalTokens();
},

hasToken(token: Token<unknown>): boolean {
return (
values.has(token.symbol) ||
factories.has(token.symbol) ||
(parentContainer?.hasToken(token) ?? false)
);
},

get<T>(token: Token<T>): T | undefined {
const value = resolver(token, container);
if (value !== NOT_FOUND) {
Expand Down
29 changes: 29 additions & 0 deletions packages/ditox/test-flow/ditox.test.js
Expand Up @@ -270,6 +270,35 @@ describe('Container', () => {
});
});

describe('hasToken()', () => {
it('should check if a container hierarchy has the token', () => {
const factory = jest.fn();

const token1 = token();
const token2 = token();
const token3 = token();

const parent = createContainer();
parent.bindValue(token1, 1);
parent.bindFactory(token2, factory);

expect(parent.hasToken(token1)).toBe(true);
expect(parent.hasToken(token2)).toBe(true);
expect(parent.hasToken(token3)).toBe(false);

const child = createContainer(parent);
expect(child.hasToken(token1)).toBe(true);
expect(child.hasToken(token2)).toBe(true);
expect(child.hasToken(token3)).toBe(false);

child.bindValue(token3, 2);
expect(parent.hasToken(token3)).toBe(false);
expect(child.hasToken(token3)).toBe(true);

expect(factory).toHaveBeenCalledTimes(0);
});
});

describe('get()', () => {
it('should return a provided value', () => {
const container = createContainer();
Expand Down

0 comments on commit 1c4cb87

Please sign in to comment.