Skip to content

Commit

Permalink
chore(context): rename group to phase for sorting
Browse files Browse the repository at this point in the history
  • Loading branch information
raymondfeng committed May 10, 2019
1 parent 48b41e9 commit cb6d0b7
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@

import {expect} from '@loopback/testlab';
import {
compareBindingsByTag,
Context,
ContextView,
filterByTag,
Getter,
inject,
compareBindingsByGroup,
} from '../..';

let app: Context;
Expand Down Expand Up @@ -39,7 +39,7 @@ describe('@inject.* to receive multiple values matching a filter', async () => {
it('injects as getter with bindingComparator', async () => {
class MyControllerWithGetter {
@inject.getter(workloadMonitorFilter, {
bindingComparator: compareBindingsByGroup('name'),
bindingComparator: compareBindingsByTag('name'),
})
getter: Getter<number[]>;
}
Expand Down Expand Up @@ -80,7 +80,7 @@ describe('@inject.* to receive multiple values matching a filter', async () => {
class MyControllerWithBindingSorter {
constructor(
@inject(workloadMonitorFilter, {
bindingComparator: compareBindingsByGroup('name'),
bindingComparator: compareBindingsByTag('name'),
})
public values: number[],
) {}
Expand All @@ -99,7 +99,7 @@ describe('@inject.* to receive multiple values matching a filter', async () => {
class ControllerWithInvalidInject {
constructor(
@inject('my-key', {
bindingComparator: compareBindingsByGroup('name'),
bindingComparator: compareBindingsByTag('name'),
})
public values: number[],
) {}
Expand Down Expand Up @@ -129,7 +129,7 @@ describe('@inject.* to receive multiple values matching a filter', async () => {
it('injects as a view with bindingComparator', async () => {
class MyControllerWithView {
@inject.view(workloadMonitorFilter, {
bindingComparator: compareBindingsByGroup('name'),
bindingComparator: compareBindingsByTag('name'),
})
view: ContextView<number[]>;
}
Expand Down
44 changes: 22 additions & 22 deletions packages/context/src/__tests__/unit/binding-sorter.unit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,58 +4,58 @@
// License text available at https://opensource.org/licenses/MIT

import {expect} from '@loopback/testlab';
import {Binding, compareByOrder, sortBindingsByGroup} from '../..';
import {Binding, compareByOrder, sortBindingsByPhase} from '../..';

describe('BindingComparator', () => {
const FINAL = Symbol('final');
const orderedGroups = ['log', 'auth', FINAL];
const groupTagName = 'group';
const orderOfPhases = ['log', 'auth', FINAL];
const phaseTagName = 'phase';
let bindings: Binding<unknown>[];
let sortedBindingKeys: string[];

beforeEach(givenBindings);
beforeEach(sortBindings);

it('sorts by group', () => {
it('sorts by phase', () => {
/**
* Groups
* Phases
* - 'log': logger1, logger2
* - 'auth': auth1, auth2
*/
assertOrder('logger1', 'logger2', 'auth1', 'auth2');
});

it('sorts by group - unknown group comes before known ones', () => {
it('sorts by phase - unknown phase comes before known ones', () => {
/**
* Groups
* Phases
* - 'metrics': metrics // not part of ['log', 'auth']
* - 'log': logger1
*/
assertOrder('metrics', 'logger1');
});

it('sorts by group alphabetically without ordered group', () => {
it('sorts by phase alphabetically without orderOf phase', () => {
/**
* Groups
* Phases
* - 'metrics': metrics // not part of ['log', 'auth']
* - 'rateLimit': rateLimit // not part of ['log', 'auth']
*/
assertOrder('metrics', 'rateLimit');
});

it('sorts by binding order without group tags', () => {
it('sorts by binding order without phase tags', () => {
/**
* Groups
* Phases
* - '': validator1, validator2 // not part of ['log', 'auth']
* - 'metrics': metrics // not part of ['log', 'auth']
* - 'log': logger1
*/
assertOrder('validator1', 'validator2', 'metrics', 'logger1');
});

it('sorts by binding order without group tags', () => {
it('sorts by binding order without phase tags', () => {
/**
* Groups
* Phases
* - '': validator1 // not part of ['log', 'auth']
* - 'metrics': metrics // not part of ['log', 'auth']
* - 'log': logger1
Expand All @@ -65,7 +65,7 @@ describe('BindingComparator', () => {
});

/**
* The sorted bindings by group:
* The sorted bindings by phase:
* - '': validator1, validator2 // not part of ['log', 'auth']
* - 'metrics': metrics // not part of ['log', 'auth']
* - 'rateLimit': rateLimit // not part of ['log', 'auth']
Expand All @@ -74,20 +74,20 @@ describe('BindingComparator', () => {
*/
function givenBindings() {
bindings = [
Binding.bind('logger1').tag({[groupTagName]: 'log'}),
Binding.bind('auth1').tag({[groupTagName]: 'auth'}),
Binding.bind('auth2').tag({[groupTagName]: 'auth'}),
Binding.bind('logger2').tag({[groupTagName]: 'log'}),
Binding.bind('metrics').tag({[groupTagName]: 'metrics'}),
Binding.bind('rateLimit').tag({[groupTagName]: 'rateLimit'}),
Binding.bind('logger1').tag({[phaseTagName]: 'log'}),
Binding.bind('auth1').tag({[phaseTagName]: 'auth'}),
Binding.bind('auth2').tag({[phaseTagName]: 'auth'}),
Binding.bind('logger2').tag({[phaseTagName]: 'log'}),
Binding.bind('metrics').tag({[phaseTagName]: 'metrics'}),
Binding.bind('rateLimit').tag({[phaseTagName]: 'rateLimit'}),
Binding.bind('validator1'),
Binding.bind('validator2'),
Binding.bind('final').tag({[groupTagName]: FINAL}),
Binding.bind('final').tag({[phaseTagName]: FINAL}),
];
}

function sortBindings() {
sortBindingsByGroup(bindings, groupTagName, orderedGroups);
sortBindingsByPhase(bindings, phaseTagName, orderOfPhases);
sortedBindingKeys = bindings.map(b => b.key);
}

Expand Down
8 changes: 4 additions & 4 deletions packages/context/src/__tests__/unit/context-view.unit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {expect} from '@loopback/testlab';
import {
Binding,
BindingScope,
compareBindingsByGroup,
compareBindingsByTag,
Context,
ContextView,
createViewGetter,
Expand All @@ -31,7 +31,7 @@ describe('ContextView', () => {
const view = new ContextView(
server,
filterByTag('foo'),
compareBindingsByGroup('group', ['b', 'a']),
compareBindingsByTag('phase', ['b', 'a']),
);
expect(view.bindings).to.eql([bindings[1], bindings[0]]);
});
Expand Down Expand Up @@ -195,14 +195,14 @@ describe('ContextView', () => {
server
.bind('bar')
.toDynamicValue(() => Promise.resolve('BAR'))
.tag('foo', 'bar', {group: 'a'})
.tag('foo', 'bar', {phase: 'a'})
.inScope(BindingScope.SINGLETON),
);
bindings.push(
app
.bind('foo')
.to('FOO')
.tag('foo', 'bar', {group: 'b'}),
.tag('foo', 'bar', {phase: 'b'}),
);
}
});
50 changes: 25 additions & 25 deletions packages/context/src/binding-sorter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,33 +31,33 @@ export interface BindingComparator {
}

/**
* Creates a binding compare function to sort bindings by tagged group name.
* Creates a binding compare function to sort bindings by tagged phase name.
*
* @remarks
* Two bindings are compared as follows:
*
* 1. Get values for the given tag as `group` for bindings, if the tag is not
* present, default `group` to `''`.
* 2. If both bindings have `group` value in `orderedGroups`, honor the order
* specified by `orderedGroups`.
* 3. If a binding's `group` does not exist in `orderedGroups`, it comes before
* the one with `group` exists in `orderedGroups`.
* 4. If both bindings have `group` value outside of `orderedGroups`, they are
* ordered by group names alphabetically and symbol values come before string
* 1. Get values for the given tag as `phase` for bindings, if the tag is not
* present, default `phase` to `''`.
* 2. If both bindings have `phase` value in `orderOfPhases`, honor the order
* specified by `orderOfPhases`.
* 3. If a binding's `phase` does not exist in `orderOfPhases`, it comes before
* the one with `phase` exists in `orderOfPhases`.
* 4. If both bindings have `phase` value outside of `orderOfPhases`, they are
* ordered by phase names alphabetically and symbol values come before string
* values.
*
* @param groupTagName Name of the binding tag for group
* @param orderedGroups An array of group names as the predefined order
* @param phaseTagName Name of the binding tag for phase
* @param orderOfPhases An array of phase names as the predefined order
*/
export function compareBindingsByGroup(
groupTagName: string = 'group',
orderedGroups: (string | symbol)[] = [],
export function compareBindingsByTag(
phaseTagName: string = 'phase',
orderOfPhases: (string | symbol)[] = [],
): BindingComparator {
return (a: Readonly<Binding<unknown>>, b: Readonly<Binding<unknown>>) => {
return compareByOrder(
a.tagMap[groupTagName],
b.tagMap[groupTagName],
orderedGroups,
a.tagMap[phaseTagName],
b.tagMap[phaseTagName],
orderOfPhases,
);
};
}
Expand Down Expand Up @@ -107,18 +107,18 @@ export function compareByOrder(
}

/**
* Sort bindings by group names denoted by a tag and the predefined order
* Sort bindings by phase names denoted by a tag and the predefined order
*
* @param bindings An array of bindings
* @param groupTagName Tag name for group, for example, we can use the value
* `'a'` of tag `order` as the group name for `binding.tag({order: 'a'})`.
* @param phaseTagName Tag name for phase, for example, we can use the value
* `'a'` of tag `order` as the phase name for `binding.tag({order: 'a'})`.
*
* @param orderedGroups An array of group names as the predefined order
* @param orderOfPhases An array of phase names as the predefined order
*/
export function sortBindingsByGroup(
export function sortBindingsByPhase(
bindings: Readonly<Binding<unknown>>[],
groupTagName?: string,
orderedGroups?: (string | symbol)[],
phaseTagName?: string,
orderOfPhases?: (string | symbol)[],
) {
return bindings.sort(compareBindingsByGroup(groupTagName, orderedGroups));
return bindings.sort(compareBindingsByTag(phaseTagName, orderOfPhases));
}

0 comments on commit cb6d0b7

Please sign in to comment.