-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
188 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
const pluginSets = new Map(); | ||
|
||
function getPluginSet(setKey) { | ||
let pluginSet = pluginSets.get(setKey); | ||
if (pluginSet) return pluginSet; | ||
|
||
pluginSet = { plugins: [], requested: false, requiresSorting: false }; | ||
pluginSets.set(setKey, pluginSet); | ||
return pluginSet; | ||
} | ||
|
||
export function getPlugins(setKey) { | ||
const pluginSet = getPluginSet(setKey); | ||
pluginSet.requested = true; | ||
if (pluginSet.requiresSorting) { | ||
pluginSet.plugins.sort((item1, item2) => item1.options.sort - item2.options.sort); | ||
pluginSet.requiresSorting = false; | ||
} | ||
return pluginSet.plugins.map(item => item.plugin); | ||
} | ||
|
||
export function registerPlugin(setKey, plugin, options) { | ||
const pluginSet = getPluginSet(setKey); | ||
|
||
if (pluginSet.requested) { | ||
throw new Error(`Plugin Set "${setKey}" has already been requested. Additional plugin registrations would result in stale consumer plugins.`); | ||
} else if (options?.key !== undefined) { | ||
if (pluginSet.plugins.find(registeredPlugin => registeredPlugin.options.key === options?.key)) { | ||
throw new Error(`Plugin Set "${setKey}" already has a plugin with the key "${options.key}".`); | ||
} | ||
} | ||
|
||
pluginSet.plugins.push({ plugin, options: Object.assign({ key: undefined, sort: 0 }, options) }); | ||
pluginSet.requiresSorting = pluginSet.requiresSorting || (options?.sort !== undefined); | ||
} | ||
|
||
// Do not import! Testing only!! | ||
export function resetPlugins() { | ||
pluginSets.clear(); | ||
} | ||
|
||
export function tryGetPluginByKey(setKey, pluginKey) { | ||
const pluginSet = pluginSets.get(setKey); | ||
const plugin = pluginSet?.plugins.find(plugin => plugin.options.key === pluginKey)?.plugin; | ||
return plugin || null; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
import { getPlugins, registerPlugin, resetPlugins, tryGetPluginByKey } from '../plugins.js'; | ||
import { expect } from '@brightspace-ui/testing'; | ||
|
||
describe('plugins', () => { | ||
|
||
afterEach(() => { | ||
resetPlugins(); | ||
}); | ||
|
||
describe('default', () => { | ||
|
||
beforeEach(() => { | ||
registerPlugin('test-plugins', { prop1: 'beer' }); | ||
registerPlugin('test-plugins', { prop1: 'donuts' }); | ||
}); | ||
|
||
it('getPlugins should return empty array for invalid plugin set key', () => { | ||
const plugins = getPlugins('invalid-plugin-set-key'); | ||
expect(plugins.length).to.equal(0); | ||
}); | ||
|
||
it('getPlugins should return array of plugins in registration order', () => { | ||
const plugins = getPlugins('test-plugins'); | ||
expect(plugins.length).to.equal(2); | ||
expect(plugins[0].prop1).to.equal('beer'); | ||
expect(plugins[1].prop1).to.equal('donuts'); | ||
}); | ||
|
||
it('getPlugins should return copy of the array for each consumer', () => { | ||
const plugins1 = getPlugins('test-plugins'); | ||
const plugins2 = getPlugins('test-plugins'); | ||
expect(plugins1).not.to.equal(plugins2); | ||
}); | ||
|
||
it('registerPlugin should throw when called after a consumer has called getPlugins for the same Set key', () => { | ||
getPlugins('test-plugins'); | ||
expect(() => { | ||
registerPlugin('test-plugins', { prop1: 'candy apple' }); | ||
}).to.throw(); | ||
}); | ||
|
||
it('registerPlugin should not throw when called after a consumer has called getPlugins for a different Set key', () => { | ||
getPlugins('test-plugins'); | ||
expect(() => { | ||
registerPlugin('test-plugins-other', { prop1: 'candy apple' }); | ||
}).to.not.throw(); | ||
}); | ||
|
||
}); | ||
|
||
describe('sorted', () => { | ||
|
||
beforeEach(() => { | ||
registerPlugin('test-plugins', { prop1: 'beer' }, { sort: 3 }); | ||
registerPlugin('test-plugins', { prop1: 'donuts' }, { sort: 1 }); | ||
}); | ||
|
||
it('getPlugins should return array of plugins in sort order', () => { | ||
const plugins = getPlugins('test-plugins'); | ||
expect(plugins.length).to.equal(2); | ||
expect(plugins[0].prop1).to.equal('donuts'); | ||
expect(plugins[1].prop1).to.equal('beer'); | ||
}); | ||
|
||
}); | ||
|
||
describe('keyed', () => { | ||
|
||
beforeEach(() => { | ||
registerPlugin('test-plugins', { prop1: 'beer' }, { key: 'plugin1' }); | ||
registerPlugin('test-plugins', { prop1: 'donuts' }, { key: 'plugin2' }); | ||
}); | ||
|
||
it('getPlugin should return undefined for invalid plugin set key', () => { | ||
const plugin = tryGetPluginByKey('invalid-plugin-set-key', 'plugin1'); | ||
expect(plugin).to.be.null; | ||
}); | ||
|
||
it('getPlugin should return undefined for invalid plugin key', () => { | ||
const plugin = tryGetPluginByKey('test-plugins', 'pluginx'); | ||
expect(plugin).to.be.null; | ||
}); | ||
|
||
it('getPlugin should return plugin for specified keys', () => { | ||
const plugin = tryGetPluginByKey('test-plugins', 'plugin1'); | ||
expect(plugin.prop1).to.equal('beer'); | ||
}); | ||
|
||
it('registerPlugin should not throw when adding a plugin with key not used within the set', () => { | ||
expect(() => { | ||
registerPlugin('test-plugins-other', { prop1: 'candy apple' }, { key: 'plugin1' }); | ||
}).to.not.throw(); | ||
}); | ||
|
||
it('registerPlugin should throw when adding a plugin with key already used within the set', () => { | ||
expect(() => { | ||
registerPlugin('test-plugins', { prop1: 'candy apple' }, { key: 'plugin1' }); | ||
}).to.throw(); | ||
}); | ||
|
||
}); | ||
|
||
}); |