Skip to content

Commit

Permalink
feat(core): add support for optional dependencies (#244)
Browse files Browse the repository at this point in the history
  • Loading branch information
fahrradflucht authored and clebert committed Jan 11, 2019
1 parent 2d1933c commit 4e3c896
Show file tree
Hide file tree
Showing 3 changed files with 286 additions and 65 deletions.
189 changes: 185 additions & 4 deletions packages/core/src/__tests__/feature-service-registry.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ describe('FeatureServiceRegistry', () => {

providerDefinitionB = {
id: 'b',
dependencies: {a: '^1.0'},
optionalDependencies: {a: '^1.0'},
create: jest.fn(() => ({'1.0': binderB}))
};

Expand Down Expand Up @@ -194,19 +194,43 @@ describe('FeatureServiceRegistry', () => {
]);
});

it('fails to register the Feature Service "b" due to the lack of dependency "a"', () => {
it('fails to register the Feature Service "c" due to the lack of dependency "a"', () => {
expect(() =>
featureServiceRegistry.registerFeatureServices(
[providerDefinitionB],
[providerDefinitionC],
'test'
)
).toThrowError(
new Error(
'The required Feature Service "a" is not registered and therefore could not be bound to consumer "b".'
'The required Feature Service "a" is not registered and therefore could not be bound to consumer "c".'
)
);
});

it('doesnt fail to register the Feature Service "b" due to the lack of optional dependency "a"', () => {
providerDefinitionB = {
id: 'b',
optionalDependencies: {a: '^1.0'},
create: jest.fn(() => ({'1.0': jest.fn()}))
};

expect(() =>
featureServiceRegistry.registerFeatureServices(
[providerDefinitionB],
'test'
)
).not.toThrow();

expect(spyConsoleInfo.mock.calls).toEqual([
[
'The optional Feature Service "a" is not registered and therefore could not be bound to consumer "b".'
],
[
'The Feature Service "b" has been successfully registered by consumer "test".'
]
]);
});

it('fails to register the Feature Service "d" due to an unsupported dependency version', () => {
const stateProviderD = {
id: 'd',
Expand All @@ -226,6 +250,33 @@ describe('FeatureServiceRegistry', () => {
);
});

it('does not fail to register the Feature Service "d" due to an unsupported optional dependency version', () => {
const stateProviderD = {
id: 'd',
optionalDependencies: {a: '1.0'},
create: jest.fn()
};

expect(() =>
featureServiceRegistry.registerFeatureServices(
[providerDefinitionA, stateProviderD],
'test'
)
).not.toThrow();

expect(spyConsoleInfo.mock.calls).toEqual([
[
'The Feature Service "a" has been successfully registered by consumer "test".'
],
[
'The optional Feature Service "a" in the unsupported version "1.0" could not be bound to consumer "d". The supported versions are ["1.1"].'
],
[
'The Feature Service "d" has been successfully registered by consumer "test".'
]
]);
});

it('fails to register the Feature Service "d" due to an invalid dependency version', () => {
const stateProviderDefinitionD = {
id: 'd',
Expand All @@ -245,6 +296,33 @@ describe('FeatureServiceRegistry', () => {
);
});

it('does not fail to register the Feature Service "d" due to an invalid optional dependency version', () => {
const stateProviderDefinitionD = {
id: 'd',
optionalDependencies: {a: ''},
create: jest.fn()
};

expect(() =>
featureServiceRegistry.registerFeatureServices(
[providerDefinitionA, stateProviderDefinitionD],
'test'
)
).not.toThrow();

expect(spyConsoleInfo.mock.calls).toEqual([
[
'The Feature Service "a" has been successfully registered by consumer "test".'
],
[
'The optional Feature Service "a" in an invalid version could not be bound to consumer "d".'
],
[
'The Feature Service "d" has been successfully registered by consumer "test".'
]
]);
});

it('fails to register the Feature Service "e" due to a dependency with an invalid version', () => {
const stateProviderDefinitionD = {
id: 'd',
Expand Down Expand Up @@ -308,6 +386,109 @@ describe('FeatureServiceRegistry', () => {
});
});

describe('for a Feature Service consumer without an id specifier and dependencies', () => {
it('creates a bindings object with Feature Services', () => {
featureServiceRegistry = new FeatureServiceRegistry();

featureServiceRegistry.registerFeatureServices(
[providerDefinitionA],
'test'
);

expect(binderA.mock.calls).toEqual([]);

expect(
featureServiceRegistry.bindFeatureServices({
id: 'foo',
dependencies: {a: '1.1'}
})
).toEqual({
featureServices: {a: featureServiceA},
unbind: expect.any(Function)
});

expect(binderA.mock.calls).toEqual([['foo']]);
});
});

describe('for a Feature Service consumer and two optional dependencies', () => {
describe('with the first dependency missing', () => {
it('creates a bindings object with Feature Services', () => {
featureServiceRegistry = new FeatureServiceRegistry();

featureServiceRegistry.registerFeatureServices(
[providerDefinitionA],
'test'
);

expect(binderA.mock.calls).toEqual([]);

expect(
featureServiceRegistry.bindFeatureServices({
id: 'foo',
optionalDependencies: {b: '1.0', a: '1.1'}
})
).toEqual({
featureServices: {a: featureServiceA},
unbind: expect.any(Function)
});

expect(binderA.mock.calls).toEqual([['foo']]);
});
});

describe('with the second dependency missing', () => {
it('creates a bindings object with Feature Services', () => {
featureServiceRegistry = new FeatureServiceRegistry();

featureServiceRegistry.registerFeatureServices(
[providerDefinitionA],
'test'
);

expect(binderA.mock.calls).toEqual([]);

expect(
featureServiceRegistry.bindFeatureServices({
id: 'foo',
optionalDependencies: {a: '1.1', b: '1.0'}
})
).toEqual({
featureServices: {a: featureServiceA},
unbind: expect.any(Function)
});

expect(binderA.mock.calls).toEqual([['foo']]);
});
});

describe('with no dependency missing', () => {
it('creates a bindings object with Feature Services', () => {
featureServiceRegistry = new FeatureServiceRegistry();

featureServiceRegistry.registerFeatureServices(
[providerDefinitionA, providerDefinitionB],
'test'
);

expect(binderA.mock.calls).toEqual([['b']]);

expect(
featureServiceRegistry.bindFeatureServices({
id: 'foo',
optionalDependencies: {a: '1.1', b: '^1.0'}
})
).toEqual({
featureServices: {a: featureServiceA, b: featureServiceB},
unbind: expect.any(Function)
});

expect(binderA.mock.calls).toEqual([['b'], ['foo']]);
expect(binderB.mock.calls).toEqual([['foo']]);
});
});
});

it('fails to create a bindings object for an consumer which is already bound', () => {
featureServiceRegistry.bindFeatureServices({id: 'foo'});
featureServiceRegistry.bindFeatureServices({id: 'foo'}, 'bar');
Expand Down

0 comments on commit 4e3c896

Please sign in to comment.