-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Plugins helpers #4274
Plugins helpers #4274
Changes from 12 commits
caaa9c0
5d27f20
fcc87b4
65b8b88
596f9c0
624da6f
b35525c
906bdf8
f0495f3
0fe173e
0b5305b
5c10a01
5435b6c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
const pluginSets = new Map(); | ||
const pluginsRequested = new Set(); | ||
|
||
export function getPlugins(setKey) { | ||
if (!pluginsRequested.has(setKey)) pluginsRequested.add(setKey); | ||
const pluginSet = pluginSets.get(setKey); | ||
if (!pluginSet) return []; | ||
dbatiste marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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) { | ||
if (pluginsRequested.has(setKey)) { | ||
throw new Error(`Plugin Set "${setKey}" has already been requested. Additional plugin registrations would result in stale consumer plugins.`); | ||
} | ||
|
||
let pluginSet = pluginSets.get(setKey); | ||
if (!pluginSet) { | ||
pluginSet = { plugins: [], requiresSorting: false }; | ||
dbatiste marked this conversation as resolved.
Show resolved
Hide resolved
|
||
pluginSets.set(setKey, pluginSet); | ||
} 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}".`); | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: not sure if this is better or not, but another option that's 1 less line! if (!pluginSets.has(setKey)) {
pluginSets.set({ plugins: [], requiresSorting: false });
}
const pluginSet = pluginSets.get(setKey); There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh yeah... I think I might had that initially, but then switched it to only do the single look-up. The difference is probably negligible for the number of plugin sets we'll have though. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should be |
||
|
||
pluginSet.plugins.push({ plugin, options: Object.assign({ key: undefined, sort: 0 }, options) }); | ||
pluginSet.requiresSorting = pluginSet.requiresSorting || (options?.sort !== undefined); | ||
dlockhart marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
// Do not import! Testing only!! | ||
export function resetPlugins() { | ||
pluginSets.clear(); | ||
pluginsRequested.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; | ||
} |
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(); | ||
}); | ||
dlockhart marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
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(); | ||
}); | ||
|
||
}); | ||
dlockhart marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another option would be to set something like a
requested = true
on the set, similar torequiresSorting
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I originally considered that but felt wrong because
getPlugins
would need to add to thepluginSets
for the case where there are no registrations. But now that I think about it more, tracking the bit separately isn't really saving anything, whether the plugin Set key is valid or not. I think I will switch it.