Skip to content

Commit

Permalink
refactor(core): better naming and undefined/null services
Browse files Browse the repository at this point in the history
  • Loading branch information
nfroidure committed Aug 16, 2023
1 parent 9b75715 commit 86a34ca
Show file tree
Hide file tree
Showing 3 changed files with 395 additions and 248 deletions.
8 changes: 4 additions & 4 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ It is designed to have a low footprint on services code.
In fact, the Knifecycle API is aimed to allow to statically
build its services load/unload code once in production.

[See in context](./src/index.ts#L193-L212)
[See in context](./src/index.ts#L192-L211)



Expand All @@ -52,7 +52,7 @@ A service provider is full of state since its concern is
[encapsulate](https://en.wikipedia.org/wiki/Encapsulation_(computer_programming))
your application global states.

[See in context](./src/index.ts#L214-L223)
[See in context](./src/index.ts#L213-L222)



Expand Down Expand Up @@ -121,7 +121,7 @@ Initializers can be of three types:
instanciated once for all for each executions silos using
them (we will cover this topic later on).

[See in context](./src/index.ts#L302-L326)
[See in context](./src/index.ts#L301-L325)



Expand All @@ -137,7 +137,7 @@ Depending on your application design, you could run it
in only one execution silo or into several ones
according to the isolation level your wish to reach.

[See in context](./src/index.ts#L612-L622)
[See in context](./src/index.ts#L613-L623)



Expand Down
196 changes: 168 additions & 28 deletions src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import {
service,
provider,
singleton,
FatalErrorService,
} from './index.js';
import type { Provider, FatalErrorService } from './index.js';
import { ALLOWED_INITIALIZER_TYPES } from './util.js';

describe('Knifecycle', () => {
Expand All @@ -35,6 +35,55 @@ describe('Knifecycle', () => {
};
}

const nullService = service<{ time: any }, null>(
async function nullService({ time }: { time: any }): Promise<null> {
// service run for its side effect only
time();
return null;
},
'nullService',
['time'],
);
const undefinedService = service<{ time: any }, undefined>(
async function undefinedService({
time,
}: {
time: any;
}): Promise<undefined> {
// service run for its side effect only
time();
return undefined;
},
'undefinedService',
['time'],
);
const nullProvider = provider<{ time: any }, null>(
async function nullProvider({
time,
}: {
time: any;
}): Promise<Provider<null>> {
// provider run for its side effect only
time();
return { service: null };
},
'nullProvider',
['time'],
);
const undefinedProvider = provider<{ time: any }, undefined>(
async function undefinedProvider({
time,
}: {
time: any;
}): Promise<Provider<undefined>> {
// service run for its side effect only
time();
return { service: undefined };
},
'undefinedProvider',
['time'],
);

beforeEach(() => {
$ = new Knifecycle();
});
Expand Down Expand Up @@ -485,16 +534,7 @@ describe('Knifecycle', () => {
test('should work with null service dependencies', async () => {
const time = jest.fn();

const nullService = service<{ time: any }, null>(
async function nullService({ time }: { time: any }): Promise<null> {
// service run for its side effect only
time();
return null;
},
'nullService',
['time'],
);
$.register(service(nullService, 'nullService'));
$.register(nullService);
$.register(constant('time', time));

const dependencies = await $.run(['nullService']);
Expand All @@ -505,30 +545,39 @@ describe('Knifecycle', () => {
});
});

test('should work with undefined service dependencies', async () => {
test('should work with null provider dependencies', async () => {
const time = jest.fn();

const undefinedService = service<{ time: any }, undefined>(
async function undefinedService({
time,
}: {
time: any;
}): Promise<undefined> {
// service run for its side effect only
time();
return undefined;
},
'undefinedService',
['time'],
);
$.register(service(undefinedService, 'undefinedService'));
$.register(nullProvider);
$.register(constant('time', time));

const dependencies = await $.run(['undefinedService']);
const dependencies = await $.run(['nullProvider']);

assert.deepEqual(Object.keys(dependencies), ['undefinedService']);
assert.deepEqual(Object.keys(dependencies), ['nullProvider']);
assert.deepEqual(dependencies, {
nullProvider: null,
});
});

test('should work with undefined dependencies', async () => {
const time = jest.fn();

$.register(undefinedService);
$.register(undefinedProvider);
$.register(constant('time', time));

const dependencies = await $.run([
'undefinedService',
'undefinedProvider',
]);

assert.deepEqual(Object.keys(dependencies), [
'undefinedService',
'undefinedProvider',
]);
assert.deepEqual(dependencies, {
undefinedService: undefined,
undefinedProvider: undefined,
});
});

Expand Down Expand Up @@ -915,6 +964,97 @@ describe('Knifecycle', () => {
assert.deepEqual(Object.keys(dependencies), ['hash', 'hash_', 'hash3']);
});

test('should work with null service dependencies', async () => {
const time = jest.fn();

$.register(constant('time', time));

$.register(
initializer(
{
name: '$autoload',
type: 'service',
singleton: true,
},
async () => async (serviceName) => ({
path: `/path/to/${serviceName}`,
initializer: nullService,
}),
),
);

const dependencies = await $.run(['nullService']);

assert.deepEqual(Object.keys(dependencies), ['nullService']);
assert.deepEqual(dependencies, {
nullService: null,
});
});

test('should work with null provider dependencies', async () => {
const time = jest.fn();

$.register(constant('time', time));

$.register(
initializer(
{
name: '$autoload',
type: 'service',
singleton: true,
},
async () => async (serviceName) => ({
path: `/path/to/${serviceName}`,
initializer: nullProvider,
}),
),
);

const dependencies = await $.run(['nullProvider']);

assert.deepEqual(Object.keys(dependencies), ['nullProvider']);
assert.deepEqual(dependencies, {
nullProvider: null,
});
});

test('should work with undefined dependencies', async () => {
const time = jest.fn();

$.register(
initializer(
{
name: '$autoload',
type: 'service',
singleton: true,
},
async () => async (serviceName) => ({
path: `/path/to/${serviceName}`,
initializer:
serviceName === 'undefinedService'
? undefinedService
: undefinedProvider,
}),
),
);

$.register(constant('time', time));

const dependencies = await $.run([
'undefinedService',
'undefinedProvider',
]);

assert.deepEqual(Object.keys(dependencies), [
'undefinedService',
'undefinedProvider',
]);
assert.deepEqual(dependencies, {
undefinedService: undefined,
undefinedProvider: null,
});
});

test('should fail when autoload does not exists', async () => {
try {
await $.run(['test']);
Expand Down
Loading

0 comments on commit 86a34ca

Please sign in to comment.