Make type(s) readonly properties of Collator/Decorator classes

Signed-off-by: Eric Peterson <ericpeterson@spotify.com>
This commit is contained in:
Eric Peterson
2021-06-01 11:15:52 +02:00
parent b9b26ec572
commit 455b97b127
6 changed files with 35 additions and 42 deletions
@@ -30,6 +30,7 @@ export interface CatalogEntityDocument extends IndexableDocument {
export class DefaultCatalogCollator implements DocumentCollator {
protected discovery: PluginEndpointDiscovery;
protected locationTemplate: string;
public readonly type: string = 'software-catalog';
constructor({
discovery,
@@ -24,22 +24,33 @@ import { IndexBuilder } from './IndexBuilder';
import { LunrSearchEngine, SearchEngine } from './index';
class TestDocumentCollator implements DocumentCollator {
async execute() {
readonly type: string = 'anything';
async execute(): Promise<IndexableDocument[]> {
return [];
}
}
class TypedDocumentCollator extends TestDocumentCollator {
readonly type = 'an-expected-type';
}
class TestDocumentDecorator implements DocumentDecorator {
async execute(_type: string, documents: IndexableDocument[]) {
async execute(documents: IndexableDocument[]) {
return documents;
}
}
class TypedDocumentDecorator extends TestDocumentDecorator {
readonly types = ['an-expected-type'];
}
class DifferentlyTypedDocumentDecorator extends TestDocumentDecorator {
readonly types = ['not-the-expected-type'];
}
describe('IndexBuilder', () => {
let testSearchEngine: SearchEngine;
let testIndexBuilder: IndexBuilder;
let testCollator: DocumentCollator;
let testDecorator: DocumentDecorator;
beforeEach(() => {
const logger = getVoidLogger();
@@ -48,18 +59,16 @@ describe('IndexBuilder', () => {
logger,
searchEngine: testSearchEngine,
});
testCollator = new TestDocumentCollator();
testDecorator = new TestDocumentDecorator();
});
describe('addCollator', () => {
it('adds a collator', async () => {
jest.useFakeTimers();
const testCollator = new TestDocumentCollator();
const collatorSpy = jest.spyOn(testCollator, 'execute');
// Add a collator.
testIndexBuilder.addCollator({
type: 'anything',
defaultRefreshIntervalSeconds: 6,
collator: testCollator,
});
@@ -75,11 +84,12 @@ describe('IndexBuilder', () => {
describe('addDecorator', () => {
it('adds a decorator', async () => {
jest.useFakeTimers();
const testCollator = new TestDocumentCollator();
const testDecorator = new TestDocumentDecorator();
const decoratorSpy = jest.spyOn(testDecorator, 'execute');
// Add a collator.
testIndexBuilder.addCollator({
type: 'anything',
defaultRefreshIntervalSeconds: 6,
collator: testCollator,
});
@@ -100,7 +110,8 @@ describe('IndexBuilder', () => {
it('adds a type-specific decorator', async () => {
jest.useFakeTimers();
const expectedType = 'an-expected-type';
const testCollator = new TypedDocumentCollator();
const testDecorator = new TypedDocumentDecorator();
const docFixture = {
title: 'Test',
text: 'Test text.',
@@ -113,14 +124,12 @@ describe('IndexBuilder', () => {
// Add a collator.
testIndexBuilder.addCollator({
type: expectedType,
defaultRefreshIntervalSeconds: 6,
collator: testCollator,
});
// Add a decorator for the same type.
testIndexBuilder.addDecorator({
types: [expectedType],
decorator: testDecorator,
});
@@ -131,16 +140,17 @@ describe('IndexBuilder', () => {
// wait for async decorator execution
await Promise.resolve();
expect(decoratorSpy).toHaveBeenCalled();
expect(decoratorSpy).toHaveBeenCalledWith(expectedType, [docFixture]);
expect(decoratorSpy).toHaveBeenCalledWith([docFixture]);
});
it('adds a type-specific decorator that should not be called', async () => {
const expectedType = 'an-expected-type';
const docFixture = {
title: 'Test',
text: 'Test text.',
location: '/test/location',
};
const testCollator = new TestDocumentCollator();
const testDecorator = new DifferentlyTypedDocumentDecorator();
const collatorSpy = jest
.spyOn(testCollator, 'execute')
.mockImplementation(async () => [docFixture]);
@@ -148,14 +158,12 @@ describe('IndexBuilder', () => {
// Add a collator.
testIndexBuilder.addCollator({
type: expectedType,
defaultRefreshIntervalSeconds: 6,
collator: testCollator,
});
// Add a decorator for a different type.
testIndexBuilder.addDecorator({
types: ['not-the-expected-type'],
decorator: testDecorator,
});
@@ -55,28 +55,25 @@ export class IndexBuilder {
* given refresh interval.
*/
addCollator({
type,
collator,
defaultRefreshIntervalSeconds,
}: RegisterCollatorParameters): void {
this.logger.info(
`Added ${collator.constructor.name} collator for type ${type}`,
`Added ${collator.constructor.name} collator for type ${collator.type}`,
);
this.collators[type] = {
this.collators[collator.type] = {
refreshInterval: defaultRefreshIntervalSeconds,
collate: collator,
};
}
/**
* 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.
* Makes the index builder aware of a decorator. If no types are provided on
* the decorator, 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,
}: RegisterDecoratorParameters): void {
addDecorator({ decorator }: RegisterDecoratorParameters): void {
const types = decorator.types || ['*'];
this.logger.info(
`Added decorator ${decorator.constructor.name} to types ${types.join(
', ',
@@ -113,7 +110,7 @@ export class IndexBuilder {
this.logger.debug(
`Decorating ${type} documents via ${decorators[i].constructor.name}`,
);
documents = await decorators[i].execute(type, documents);
documents = await decorators[i].execute(documents);
}
if (!documents || documents.length === 0) {
-11
View File
@@ -26,11 +26,6 @@ import {
* Parameters required to register a collator.
*/
export interface RegisterCollatorParameters {
/**
* The type of document to be indexed (used to name indices, to configure refresh loop, etc).
*/
type: string;
/**
* The default interval (in seconds) that the provided collator will be called (can be overridden in config).
*/
@@ -50,12 +45,6 @@ export interface RegisterDecoratorParameters {
* The decorator class responsible for appending or modifying documents of the given type(s).
*/
decorator: DocumentDecorator;
/**
* (Optional) An array of document types that the given decorator should apply to. If none are provided,
* the decorator will be applied to all types.
*/
types?: string[];
}
/**