Published
Edited
Aug 11, 2020
Importers
Insert cell
md`# Adapters`
Insert cell
class Adapters {

constructor() {
this.index = {};
}

set(from, to, adapter) {
const adapters = this.index[from] = this.index[from] || {};
adapters[to] = adapter;
return () => this.remove(from, to);
}

get(from, to, fromExact = false, toExact = false) {
return this._find(from, fromExact, (f) => {
const adapters = this.index[f];
if (!adapters) return ;
return this._find(to, toExact, (t) => adapters[t]);
})
}

getAll(from, to, fromExact = false, toExact = false) {
let result = [];
this._find(from, fromExact, (f) => {
const adapters = this.index[f];
if (adapters) {
this._find(to, toExact, (t) => {
const adapter = adapters[t];
if (adapter) {
result.push(adapter);
}
})
}
})
return result;
}

remove(from, to) {
const adapters = this.index[from];
if (!adapters) return ;
let result = adapters[to];
delete adapters[to];
if (!Object.keys(adapters).length) delete this.index[from];
return result;
}

_find(path, exact, action) {
let result;
path = path.split('.');
while (path.length) {
result = action(path.join('.'));
if (result || exact) break;
path.pop();
}
return result;
}

}

Insert cell
Insert cell

describe('Adapters', async () => {

it(`should be able to register and retrieve and remove exact adapter`, async () => {
const a = new Adapters();
a.set('a', 'b', 'FOOBAR');
expect(a.get('a', 'b')).toEqual('FOOBAR');
expect(a.remove('a', 'b')).toEqual('FOOBAR');
expect(a.get('a', 'b')).toBe(undefined);
expect(a.remove('a', 'b')).toBe(undefined);
});

it(`should be able to retrieve adapters by parent target keys`, async () => {
const a = new Adapters();
a.set('menu', 'file', 'File menu');
expect(a.get('menu', 'file.text')).toEqual('File menu');
expect(a.get('menu', 'file.text.markdown')).toEqual('File menu');
expect(a.getAll('menu', 'file.text.markdown')).toEqual(['File menu']);

a.set('menu', 'file.text', 'Menu for text files');
expect(a.get('menu', 'file.text')).toEqual('Menu for text files');
expect(a.get('menu', 'file.text.markdown')).toEqual('Menu for text files');
expect(a.getAll('menu', 'file.text.markdown')).toEqual(['Menu for text files', 'File menu']);
});

it(`should be able to retrieve adapters by parent source keys`, async () => {
const a = new Adapters();
a.set('menu', 'file', 'Show files in menus');
expect(a.get('menu.context', 'file')).toEqual('Show files in menus');
expect(a.get('menu.context.editor', 'file')).toEqual('Show files in menus');
expect(a.get('menu.context.editor.code', 'file')).toEqual('Show files in menus');

a.set('menu.context.editor', 'file', 'Show files in context EDITOR menu');
expect(a.get('menu.context', 'file')).toEqual('Show files in menus');
expect(a.get('menu.context.editor', 'file')).toEqual('Show files in context EDITOR menu');
expect(a.get('menu.context.editor.code', 'file')).toEqual('Show files in context EDITOR menu');

expect(a.getAll('menu.context.editor.code', 'file')).toEqual(['Show files in context EDITOR menu', 'Show files in menus']);
});

it(`should be able to retrieve adapters by parent and source keys`, async () => {
const a = new Adapters();
a.set('menu', 'file', 'Show files in menus');
expect(a.get('menu.context', 'file.text.javascript')).toEqual('Show files in menus');
expect(a.get('menu.context.editor', 'file.text.javascript')).toEqual('Show files in menus');
expect(a.get('menu.context.editor.code', 'file.text.javascript')).toEqual('Show files in menus');

a.set('menu.context.editor', 'file.text', 'Show TEXT files in context EDITOR menu');
a.set('menu.context.editor', 'file.text.java', 'Show Java source files in context EDITOR menu');
expect(a.get('menu.context', 'file.text')).toEqual('Show files in menus');
expect(a.get('menu.context.editor', 'file')).toEqual('Show files in menus');
expect(a.get('menu.context.editor', 'file.text')).toEqual('Show TEXT files in context EDITOR menu');
expect(a.get('menu.context.editor.code', 'file.text.javascript')).toEqual('Show TEXT files in context EDITOR menu');
expect(a.get('menu.context.editor.code', 'file.text.java')).toEqual('Show Java source files in context EDITOR menu');

expect(a.getAll('menu.context.editor.code', 'file.text.java')).toEqual([
'Show Java source files in context EDITOR menu',
'Show TEXT files in context EDITOR menu',
'Show files in menus'
]);
});


})

Insert cell
import { it, describe, expect } from '@kotelnikov/unit-tests-in-notebooks'
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more