Call a builder a builder.

Signed-off-by: Eric Peterson <ericpeterson@spotify.com>
This commit is contained in:
Eric Peterson
2021-03-18 10:06:05 +01:00
parent 9d214a88ce
commit 3560405cab
4 changed files with 55 additions and 41 deletions
@@ -20,13 +20,13 @@ import {
RegisterDecoratorParameters,
} from './types';
interface CollatorRegistryEntry {
interface CollatorEnvelope {
collate: DocumentCollator;
refreshInterval: number;
}
export class Registry {
private collators: Record<string, CollatorRegistryEntry>;
export class IndexBuilder {
private collators: Record<string, CollatorEnvelope>;
private decorators: Record<string, DocumentDecorator[]>;
constructor() {
@@ -34,6 +34,10 @@ export class Registry {
this.decorators = {};
}
/**
* Makes the index builder aware of a collator that should be executed at the
* given refresh interval.
*/
addCollator({
type,
collator,
@@ -45,6 +49,11 @@ export class Registry {
};
}
/**
* Makes the index builder aware of a decorator. If no types are provided, it
* will be applied to documents from all known collators, otherwise it will
* only be applied to documents of the given types.
*/
addDecorator({
types = ['*'],
decorator,
@@ -58,8 +67,13 @@ export class Registry {
});
}
// TODO: But like with coordination, timing, error handling, and what have you.
async execute() {
/**
* Starts the process of executing collators and decorators and building the
* search index.
*
* TODO: But like with coordination, timing, error handling, and what have you.
*/
async build() {
return Promise.all(
Object.keys(this.collators).map(async type => {
const decorators: DocumentDecorator[] = (
+32 -32
View File
@@ -19,7 +19,7 @@ import {
DocumentDecorator,
IndexableDocument,
} from '@backstage/search-common';
import { Registry } from './registry';
import { IndexBuilder } from './IndexBuilder';
class TestDocumentCollator implements DocumentCollator {
async execute() {
@@ -33,56 +33,56 @@ class TestDocumentDecorator implements DocumentDecorator {
}
}
describe('search indexer external api', () => {
let testRegistry: Registry;
describe('IndexBuilder', () => {
let testIndexBuilder: IndexBuilder;
let testCollator: DocumentCollator;
let testDecorator: DocumentDecorator;
beforeEach(() => {
testRegistry = new Registry();
testIndexBuilder = new IndexBuilder();
testCollator = new TestDocumentCollator();
testDecorator = new TestDocumentDecorator();
});
describe('registerCollator', () => {
it('registers a collator', async () => {
describe('addCollator', () => {
it('adds a collator', async () => {
const collatorSpy = jest.spyOn(testCollator, 'execute');
// Register a collator.
testRegistry.addCollator({
// Add a collator.
testIndexBuilder.addCollator({
type: 'anything',
defaultRefreshIntervalSeconds: 600,
collator: testCollator,
});
// Execute the registry and ensure the collator was invoked.
await testRegistry.execute();
// Build the index and ensure the collator was invoked.
await testIndexBuilder.build();
expect(collatorSpy).toHaveBeenCalled();
});
});
describe('registerDecorator', () => {
it('registers a decorator', async () => {
describe('addDecorator', () => {
it('adds a decorator', async () => {
const decoratorSpy = jest.spyOn(testDecorator, 'execute');
// Register a collator.
testRegistry.addCollator({
// Add a collator.
testIndexBuilder.addCollator({
type: 'anything',
defaultRefreshIntervalSeconds: 600,
collator: testCollator,
});
// Register a decorator.
testRegistry.addDecorator({
// Add a decorator.
testIndexBuilder.addDecorator({
decorator: testDecorator,
});
// Execute the registry and ensure the decorator was invoked.
await testRegistry.execute();
// Build the index and ensure the decorator was invoked.
await testIndexBuilder.build();
expect(decoratorSpy).toHaveBeenCalled();
});
it('registers a type-specific decorator', async () => {
it('adds a type-specific decorator', async () => {
const expectedType = 'an-expected-type';
const docFixture = {
title: 'Test',
@@ -94,26 +94,26 @@ describe('search indexer external api', () => {
.mockImplementation(async () => [docFixture]);
const decoratorSpy = jest.spyOn(testDecorator, 'execute');
// Register a collator.
testRegistry.addCollator({
// Add a collator.
testIndexBuilder.addCollator({
type: expectedType,
defaultRefreshIntervalSeconds: 600,
collator: testCollator,
});
// Register a decorator for the same type.
testRegistry.addDecorator({
// Add a decorator for the same type.
testIndexBuilder.addDecorator({
types: [expectedType],
decorator: testDecorator,
});
// Execute the registry and ensure the decorator was invoked.
await testRegistry.execute();
// Build the index and ensure the decorator was invoked.
await testIndexBuilder.build();
expect(decoratorSpy).toHaveBeenCalled();
expect(decoratorSpy).toHaveBeenCalledWith([docFixture]);
});
it('registers a type-specific decorator that should not be called', async () => {
it('adds a type-specific decorator that should not be called', async () => {
const expectedType = 'an-expected-type';
const docFixture = {
title: 'Test',
@@ -125,21 +125,21 @@ describe('search indexer external api', () => {
.mockImplementation(async () => [docFixture]);
const decoratorSpy = jest.spyOn(testDecorator, 'execute');
// Register a collator.
testRegistry.addCollator({
// Add a collator.
testIndexBuilder.addCollator({
type: expectedType,
defaultRefreshIntervalSeconds: 600,
collator: testCollator,
});
// Register a decorator for a different type.
testRegistry.addDecorator({
// Add a decorator for a different type.
testIndexBuilder.addDecorator({
types: ['not-the-expected-type'],
decorator: testDecorator,
});
// Execute the registry and ensure the decorator was not invoked.
await testRegistry.execute();
// Build the index and ensure the decorator was not invoked.
await testIndexBuilder.build();
expect(decoratorSpy).not.toHaveBeenCalled();
});
});
+1 -1
View File
@@ -14,4 +14,4 @@
* limitations under the License.
*/
export { Registry } from './registry';
export { IndexBuilder } from './IndexBuilder';