From c5baaab234e6d0fd1c7404d9dd902f8c32524cc6 Mon Sep 17 00:00:00 2001 From: Enoch Riese Date: Sun, 16 Apr 2023 23:59:21 -0400 Subject: [PATCH] refactor (core) move plugin and hook handling to its own class --- packages/core/src/pattern/index.mjs | 164 ++-------------- packages/core/src/pattern/pattern-config.mjs | 12 +- packages/core/src/pattern/pattern-plugins.mjs | 185 ++++++++++++++++++ packages/core/tests/pattern-init.test.mjs | 44 ++--- packages/core/tests/pattern-other.test.mjs | 4 +- 5 files changed, 225 insertions(+), 184 deletions(-) create mode 100644 packages/core/src/pattern/pattern-plugins.mjs diff --git a/packages/core/src/pattern/index.mjs b/packages/core/src/pattern/index.mjs index ef9ebcea89d..6903264c443 100644 --- a/packages/core/src/pattern/index.mjs +++ b/packages/core/src/pattern/index.mjs @@ -11,9 +11,10 @@ import { Store } from '../store.mjs' import { Hooks } from '../hooks.mjs' import { version } from '../../data.mjs' import { __loadPatternDefaults } from '../config.mjs' -import { PatternConfig, getPluginName } from './pattern-config.mjs' +import { PatternConfig } from './pattern-config.mjs' import { PatternDraftQueue } from './pattern-draft-queue.mjs' import { PatternSampler } from './pattern-sampler.mjs' +import { PatternPlugins, getPluginName } from './pattern-plugins.mjs' import cloneDeep from 'lodash.clonedeep' ////////////////////////////////////////////// @@ -35,7 +36,6 @@ export function Pattern(designConfig = {}) { this.setStores = [] // Per-set stores // Non-enumerable properties - __addNonEnumProp(this, 'plugins', {}) __addNonEnumProp(this, 'width', 0) __addNonEnumProp(this, 'height', 0) __addNonEnumProp(this, 'autoLayout', { stacks: {} }) @@ -49,7 +49,8 @@ export function Pattern(designConfig = {}) { __addNonEnumProp(this, '__initialized', false) __addNonEnumProp(this, 'config.parts', {}) __addNonEnumProp(this, 'config.resolvedDependencies', {}) - __addNonEnumProp(this, '__storeMethods', new Set()) + + __addNonEnumProp(this, 'plugins', new PatternPlugins(this)) __addNonEnumProp(this, '__configResolver', new PatternConfig(this)) // handles config resolution during __init() as well as runtime part adding return this @@ -202,7 +203,7 @@ Pattern.prototype.getRenderProps = function () { this.store.log.info('Gathering render props') // Run pre-render hook let svg = new Svg(this) - svg.hooks = this.hooks + svg.hooks = this.plugins.hooks this.__pack() svg.__runHooks('preRender') @@ -294,11 +295,7 @@ Pattern.prototype.sampleOption = function (optionName) { * @return {object} this - The Pattern instance */ Pattern.prototype.on = function (hook, method, data) { - for (const added of this.hooks[hook]) { - // Don't add it twice - if (added.method === method) return this - } - this.hooks[hook].push({ method, data }) + this.plugins.on(hook, method, data) return this } @@ -310,7 +307,7 @@ Pattern.prototype.on = function (hook, method, data) { */ Pattern.prototype.render = function () { this.svg = new Svg(this) - this.svg.hooks = this.hooks + this.svg.hooks = this.plugins.hooks return this.__pack().svg.render() } @@ -323,13 +320,7 @@ Pattern.prototype.render = function () { * @return {object} this - The Pattern instance */ Pattern.prototype.use = function (plugin, data) { - const name = getPluginName(plugin) - if (!this.plugins?.[name]) - return plugin.plugin && plugin.condition - ? this.__useIf(plugin, data) // Conditional plugin - : this.__loadPlugin(plugin, data) // Regular plugin - - this.store.log.info(`Plugin \`${name}\` was requested, but it's already loaded. Skipping.`) + this.plugins.use(plugin, data, this.settings) return this } @@ -347,7 +338,7 @@ Pattern.prototype.use = function (plugin, data) { Pattern.prototype.__createSetStore = function () { const store = new Store() store.set('data', this.store.data) - store.extend([...this.__storeMethods]) + store.extend([...this.plugins.__storeMethods]) return store } @@ -400,15 +391,15 @@ Pattern.prototype.__createPartWithContext = function (name, set) { config: this.config, settings: this.settings[set], store: this.setStores[set], - macros: this.macros, + macros: this.plugins.macros, } if (this.settings[set]?.partClasses) { part.attr('class', this.settings[set].partClasses) } - for (const macro in this.macros) { - part[__macroName(macro)] = this.macros[macro] + for (const macro in this.plugins.macros) { + part[__macroName(macro)] = this.plugins.macros[macro] } return part @@ -457,9 +448,10 @@ Pattern.prototype.__init = function () { */ this.__resolveParts() // Resolves parts .__resolveConfig() // Gets the config from the resolver - .__loadOptionDefaults() // Merges default options with user provided ones - .__loadPlugins() // Loads plugins .__loadConfigData() // Makes config data available in store + .__loadOptionDefaults() // Merges default options with user provided ones + + this.plugins.loadConfigPlugins(this.config, this.settings) // Loads plugins this.store.log.info(`Pattern initialized. Draft order is: ${this.config.draftOrder.join(', ')}`) this.__runHooks('postInit') @@ -577,104 +569,6 @@ Pattern.prototype.__loadOptionDefaults = function () { return this } -/** - * Loads a plugin - * - * @private - * @param {object} plugin - The plugin object, or an object with `plugin` and `condition` keys - * @param {object} data - Any plugin data to load - * @return {Pattern} this - The Pattern instance - */ -Pattern.prototype.__loadPlugin = function (plugin, data) { - this.plugins[plugin.name] = plugin - if (plugin.hooks) this.__loadPluginHooks(plugin, data) - if (plugin.macros) this.__loadPluginMacros(plugin) - if (plugin.store) this.__loadPluginStoreMethods(plugin) - this.store.log.info(`Loaded plugin \`${plugin.name}:${plugin.version}\``) - - return this -} - -/** - * Loads a plugin's hooks - * - * @private - * @param {object} plugin - The plugin object - * @param {object} data - Any plugin data to load - * @return {Pattern} this - The Pattern instance - */ -Pattern.prototype.__loadPluginHooks = function (plugin, data) { - for (let hook of Object.keys(this.hooks)) { - if (typeof plugin.hooks[hook] === 'function') { - this.on(hook, plugin.hooks[hook], data) - } else if (Array.isArray(plugin.hooks[hook])) { - for (let method of plugin.hooks[hook]) { - this.on(hook, method, data) - } - } - } - - return this -} - -/** - * Loads a plugin's macros - * - * @private - * @param {object} plugin - The plugin object - * @return {Pattern} this - The Pattern instance - */ -Pattern.prototype.__loadPluginMacros = function (plugin) { - for (let macro in plugin.macros) { - if (typeof plugin.macros[macro] === 'function') { - this.__macro(macro, plugin.macros[macro]) - } - } -} - -/** - * Loads the plugins that are part of the config - * - * @private - * @return {Pattern} this - The Pattern instance - */ -Pattern.prototype.__loadPlugins = function () { - if (!this.config.plugins) return this - for (const plugin in this.config.plugins) - this.use(this.config.plugins[plugin], this.config.plugins[plugin]?.data) - - return this -} - -/** - * Loads a plugin's store methods - * - * @private - * @param {object} plugin - The plugin object - * @return {Pattern} this - The Pattern instance - */ -Pattern.prototype.__loadPluginStoreMethods = function (plugin) { - if (Array.isArray(plugin.store)) { - for (const method of plugin.store) this.__storeMethods.add(method) - } else this.store.log.warning(`Plugin store methods should be an Array`) - - return this -} - -/** - * Sets a method for a macro - * - * @private - * @param {string} macro - Name of the macro to run - * @param {function} method - The macro method - * @return {object} this - The Pattern instance - */ -Pattern.prototype.__macro = function (key, method) { - this.macros[key] = method - - return this -} - /** * Determines whether a part is needed, depending on the 'only' setting and the configured dependencies * @@ -815,7 +709,7 @@ Pattern.prototype.__resolveParts = function () { */ Pattern.prototype.__runHooks = function (hookName, data = false) { if (data === false) data = this - let hooks = this.hooks[hookName] + let hooks = this.plugins.hooks[hookName] if (hooks.length > 0) { this.store.log.debug(`Running \`${hookName}\` hooks`) for (let hook of hooks) { @@ -863,32 +757,6 @@ Pattern.prototype.__snappedPercentageOption = function (optionName, set) { return abs } -/** - * Loads a conditional plugin - * - * @private - * @param {object} plugin - An object with `plugin` and `condition` keys - * @return {Pattern} this - The Pattern instance - */ -Pattern.prototype.__useIf = function (plugin) { - let load = 0 - for (const set of this.settings) { - if (plugin.condition(set)) load++ - } - if (load > 0) { - this.store.log.info( - `Condition met: Loaded plugin \`${plugin.plugin.name}:${plugin.plugin.version}\`` - ) - this.__loadPlugin(plugin.plugin, plugin.data) - } else { - this.store.log.info( - `Condition not met: Skipped loading plugin \`${plugin.plugin.name}:${plugin.plugin.version}\`` - ) - } - - return this -} - /** * Determines whether a part is wanted, depending on the 'only' setting and the configured dependencies * diff --git a/packages/core/src/pattern/pattern-config.mjs b/packages/core/src/pattern/pattern-config.mjs index 9fddf27759e..69659d62fd0 100644 --- a/packages/core/src/pattern/pattern-config.mjs +++ b/packages/core/src/pattern/pattern-config.mjs @@ -1,4 +1,5 @@ import { __addNonEnumProp } from '../utils.mjs' +import { getPluginName } from './pattern-plugins.mjs' export const hidePresets = { HIDE_ALL: { @@ -13,17 +14,6 @@ export const hidePresets = { }, } -/** - * Get the name of the given plugin config - * - * @param {(Object|Object[])} plugin the plugin to get the name of - * @return {(string|false)} the name, or false if there isn't one - */ -export function getPluginName(plugin) { - const toCheck = Array.isArray(plugin) ? plugin[0] : plugin - return toCheck.name || toCheck.plugin?.name || false -} - ///////////////// // CONSTRUCTOR // ///////////////// diff --git a/packages/core/src/pattern/pattern-plugins.mjs b/packages/core/src/pattern/pattern-plugins.mjs new file mode 100644 index 00000000000..e41d6a5b78d --- /dev/null +++ b/packages/core/src/pattern/pattern-plugins.mjs @@ -0,0 +1,185 @@ +import { Hooks } from '../hooks.mjs' + +/** + * Get the name of the given plugin config + * + * @param {(Object|Object[])} plugin the plugin to get the name of + * @return {(string|false)} the name, or false if there isn't one + */ +export function getPluginName(plugin) { + const toCheck = Array.isArray(plugin) ? plugin[0] : plugin + return toCheck.name || toCheck.plugin?.name || false +} + +export function PatternPlugins(pattern) { + this.store = pattern.store + + this.plugins = {} + this.hooks = new Hooks() + this.macros = {} + this.__storeMethods = new Set() +} + +/** + * Loads a plugin + * + * @param {object} plugin - The plugin to load + * @param {object} data - Any data to pass to the plugin + * @return {object} this - The Pattern instance + */ +PatternPlugins.prototype.use = function (plugin, data, settings = [{}]) { + const name = getPluginName(plugin) + if (!this.plugins?.[name]) + return plugin.plugin && plugin.condition + ? this.__useIf(plugin, data, settings) // Conditional plugin + : this.__loadPlugin(plugin, data) // Regular plugin + + this.store.log.info(`Plugin \`${name}\` was requested, but it's already loaded. Skipping.`) + + return this +} + +/** + * Adds a lifecycle hook method to the pattern + * + * @param {string} hook - Name of the lifecycle hook + * @param {function} method - The method to run + * @param {object} data - Any data to pass to the hook method + * @return {object} this - The Pattern instance + */ +PatternPlugins.prototype.on = function (hook, method, data) { + for (const added of this.hooks[hook]) { + // Don't add it twice + if (added.method === method) return this + } + this.hooks[hook].push({ method, data }) + + return this +} + +/** + * Loads the plugins that are part of the config + * + * @private + * @return {Pattern} this - The Pattern instance + */ +PatternPlugins.prototype.loadConfigPlugins = function (config, settings) { + if (!config.plugins) return this + for (const plugin in config.plugins) + this.use(config.plugins[plugin], config.plugins[plugin]?.data, settings) + return this +} + +/** + * Loads a plugin + * + * @private + * @param {object} plugin - The plugin object, or an object with `plugin` and `condition` keys + * @param {object} data - Any plugin data to load + * @return {Pattern} this - The Pattern instance + */ +PatternPlugins.prototype.__loadPlugin = function (plugin, data) { + const name = getPluginName(plugin) + this.plugins[name] = plugin + if (plugin.hooks) this.__loadPluginHooks(plugin, data) + if (plugin.macros) this.__loadPluginMacros(plugin) + if (plugin.store) this.__loadPluginStoreMethods(plugin) + this.store.log.info(`Loaded plugin \`${plugin.name}:${plugin.version}\``) + + return this +} + +/** + * Loads a plugin's hooks + * + * @private + * @param {object} plugin - The plugin object + * @param {object} data - Any plugin data to load + * @return {Pattern} this - The Pattern instance + */ +PatternPlugins.prototype.__loadPluginHooks = function (plugin, data) { + // console.log('hooks', plugin) + for (let hook of Object.keys(this.hooks)) { + if (typeof plugin.hooks[hook] === 'function') { + this.on(hook, plugin.hooks[hook], data) + } else if (Array.isArray(plugin.hooks[hook])) { + for (let method of plugin.hooks[hook]) { + this.on(hook, method, data) + } + } + } + + return this +} + +/** + * Loads a plugin's macros + * + * @private + * @param {object} plugin - The plugin object + * @return {Pattern} this - The Pattern instance + */ +PatternPlugins.prototype.__loadPluginMacros = function (plugin) { + // console.log('macros', plugin) + for (let macro in plugin.macros) { + if (typeof plugin.macros[macro] === 'function') { + this.__macro(macro, plugin.macros[macro]) + } + } +} + +/** + * Loads a plugin's store methods + * + * @private + * @param {object} plugin - The plugin object + * @return {Pattern} this - The Pattern instance + */ +PatternPlugins.prototype.__loadPluginStoreMethods = function (plugin) { + if (Array.isArray(plugin.store)) { + for (const method of plugin.store) this.__storeMethods.add(method) + } else this.store.log.warning(`Plugin store methods should be an Array`) + + // console.log('store', plugin, this.__storeMethods) + return this +} + +/** + * Sets a method for a macro + * + * @private + * @param {string} macro - Name of the macro to run + * @param {function} method - The macro method + * @return {object} this - The Pattern instance + */ +PatternPlugins.prototype.__macro = function (key, method) { + this.macros[key] = method + + return this +} + +/** + * Loads a conditional plugin + * + * @private + * @param {object} plugin - An object with `plugin` and `condition` keys + * @return {Pattern} this - The Pattern instance + */ +PatternPlugins.prototype.__useIf = function (plugin, settings = [{}]) { + let load = 0 + for (const set of settings) { + if (plugin.condition(set)) load++ + } + if (load > 0) { + this.store.log.info( + `Condition met: Loaded plugin \`${plugin.plugin.name}:${plugin.plugin.version}\`` + ) + this.__loadPlugin(plugin.plugin, plugin.data) + } else { + this.store.log.info( + `Condition not met: Skipped loading plugin \`${plugin.plugin.name}:${plugin.plugin.version}\`` + ) + } + + return this +} diff --git a/packages/core/tests/pattern-init.test.mjs b/packages/core/tests/pattern-init.test.mjs index 743d8bc5ab7..718fa363988 100644 --- a/packages/core/tests/pattern-init.test.mjs +++ b/packages/core/tests/pattern-init.test.mjs @@ -18,7 +18,7 @@ describe('Pattern', () => { expect(Array.isArray(pattern.setStores)).to.equal(true) expect(typeof pattern.store).to.equal('object') expect(typeof pattern.config).to.equal('object') - expect(Object.keys(pattern).length).to.equal(5) + expect(Object.keys(pattern)).to.have.lengthOf(5) }) it('Pattern constructor should add non-enumerable properties', () => { @@ -26,12 +26,10 @@ describe('Pattern', () => { const pattern = new Pattern() expect(typeof pattern.plugins).to.equal('object') expect(typeof pattern.autoLayout).to.equal('object') - expect(typeof pattern.hooks).to.equal('object') expect(typeof pattern.Point).to.equal('function') expect(typeof pattern.Path).to.equal('function') expect(typeof pattern.Snippet).to.equal('function') expect(typeof pattern.Attributes).to.equal('function') - expect(typeof pattern.macros).to.equal('object') // expect(typeof pattern.__designParts).to.equal('object') // expect(typeof pattern.config.inject).to.equal('object') // expect(typeof pattern.config.directDependencies).to.equal('object') @@ -58,7 +56,7 @@ describe('Pattern', () => { absoluteOptions: {}, } for (const [key, value] of Object.entries(dflts)) { - if (typeof value === 'object') expect(Object.keys(value).length).to.equal(0) + if (typeof value === 'object') expect(Object.keys(value)).to.have.lengthOf(0) else expect(pattern.settings[0][key]).to.equal(value) } }) @@ -120,19 +118,19 @@ describe('Pattern', () => { }) it('Pattern.__init() should resolve required measurements', () => { - expect(pattern.config.measurements.length).to.equal(2) + expect(pattern.config.measurements).to.have.lengthOf(2) expect(pattern.config.measurements[0]).to.equal('head') expect(pattern.config.measurements[1]).to.equal('knee') }) it('Pattern.__init() should resolve optional measurements', () => { - expect(pattern.config.optionalMeasurements.length).to.equal(2) + expect(pattern.config.optionalMeasurements).to.have.lengthOf(2) expect(pattern.config.optionalMeasurements[0]).to.equal('chest') expect(pattern.config.optionalMeasurements[1]).to.equal('waist') }) it('Pattern.__init() should resolve options', () => { - expect(Object.keys(pattern.config.options).length).to.equal(3) + expect(Object.keys(pattern.config.options)).to.have.lengthOf(3) for (const [key, value] of Object.entries(partA.options.optA)) { expect(pattern.config.options.optA[key]).to.equal(value) } @@ -149,7 +147,7 @@ describe('Pattern', () => { }) it('Pattern.__init() should resolve plugins', () => { - expect(Object.keys(pattern.config.plugins).length).to.equal(1) + expect(Object.keys(pattern.config.plugins)).to.have.lengthOf(1) }) it('Pattern.__init() should set config data in the store', () => { @@ -160,12 +158,12 @@ describe('Pattern', () => { it('Pattern.__init() should resolve dependencies', () => { expect(typeof pattern.config.resolvedDependencies).to.equal('object') expect(Array.isArray(pattern.config.resolvedDependencies['test.partA'])).to.equal(true) - expect(pattern.config.resolvedDependencies['test.partA'].length).to.equal(0) + expect(pattern.config.resolvedDependencies['test.partA']).to.have.lengthOf(0) expect(Array.isArray(pattern.config.resolvedDependencies['test.partB'])).to.equal(true) - expect(pattern.config.resolvedDependencies['test.partB'].length).to.equal(1) + expect(pattern.config.resolvedDependencies['test.partB']).to.have.lengthOf(1) expect(pattern.config.resolvedDependencies['test.partB'][0]).to.equal('test.partA') expect(Array.isArray(pattern.config.resolvedDependencies['test.partC'])).to.equal(true) - expect(pattern.config.resolvedDependencies['test.partC'].length).to.equal(2) + expect(pattern.config.resolvedDependencies['test.partC']).to.have.lengthOf(2) expect( pattern.config.resolvedDependencies['test.partC'].indexOf('test.partA') !== -1 ).to.equal(true) @@ -325,13 +323,13 @@ describe('Pattern', () => { const design = new Design({ parts: [partC] }) const pattern = new design().addPart(partR).draft() // Measurements - expect(pattern.config.measurements.length).to.equal(4) + expect(pattern.config.measurements).to.have.lengthOf(4) expect(pattern.config.measurements.indexOf('measieA') === -1).to.equal(false) expect(pattern.config.measurements.indexOf('measieB') === -1).to.equal(false) expect(pattern.config.measurements.indexOf('measieC') === -1).to.equal(false) expect(pattern.config.measurements.indexOf('measieR') === -1).to.equal(false) // Optional measurements - expect(pattern.config.optionalMeasurements.length).to.equal(4) + expect(pattern.config.optionalMeasurements).to.have.lengthOf(4) expect(pattern.config.optionalMeasurements.indexOf('optmeasieA') === -1).to.equal(false) expect(pattern.config.optionalMeasurements.indexOf('optmeasieB') === -1).to.equal(false) expect(pattern.config.optionalMeasurements.indexOf('optmeasieC') === -1).to.equal(false) @@ -473,13 +471,13 @@ describe('Pattern', () => { const design = new Design({ parts: [partD] }) const pattern = new design().draft() // Measurements - expect(pattern.config.measurements.length).to.equal(4) + expect(pattern.config.measurements).to.have.lengthOf(4) expect(pattern.config.measurements.indexOf('measieA') === -1).to.equal(false) expect(pattern.config.measurements.indexOf('measieB') === -1).to.equal(false) expect(pattern.config.measurements.indexOf('measieC') === -1).to.equal(false) expect(pattern.config.measurements.indexOf('measieD') === -1).to.equal(false) // Optional measurements - expect(pattern.config.optionalMeasurements.length).to.equal(4) + expect(pattern.config.optionalMeasurements).to.have.lengthOf(4) expect(pattern.config.optionalMeasurements.indexOf('optmeasieA') === -1).to.equal(false) expect(pattern.config.optionalMeasurements.indexOf('optmeasieB') === -1).to.equal(false) expect(pattern.config.optionalMeasurements.indexOf('optmeasieC') === -1).to.equal(false) @@ -578,7 +576,7 @@ describe('Pattern', () => { const design = new Design({ parts: [part] }) const pattern = new design() pattern.draft() - expect(pattern.hooks.preRender.length).to.equal(1) + expect(pattern.plugins.hooks.preRender).to.have.lengthOf(1) }) it('Pattern.__init() should load array of plugins', () => { @@ -608,7 +606,7 @@ describe('Pattern', () => { const design = new Design({ parts: [part] }) const pattern = new design() pattern.__init() - expect(pattern.hooks.preRender.length).to.equal(2) + expect(pattern.plugins.hooks.preRender).to.have.lengthOf(2) }) it('Pattern.__init() should load conditional plugin if condition is met', () => { @@ -629,8 +627,8 @@ describe('Pattern', () => { } const design = new Design({ parts: [part] }) const pattern = new design() - pattern.draft() - expect(pattern.hooks.preRender.length).to.equal(1) + pattern.__init() + expect(pattern.plugins.hooks.preRender).to.have.lengthOf(1) }) it('Pattern.__init() should not load conditional plugin if condition is not mett', () => { @@ -651,7 +649,7 @@ describe('Pattern', () => { } const design = new Design({ parts: [part] }) const pattern = new design() - expect(pattern.hooks.preRender.length).to.equal(0) + expect(pattern.plugins.hooks.preRender).to.have.lengthOf(0) }) it('Pattern.__init() should load multiple conditional plugins', () => { @@ -686,7 +684,7 @@ describe('Pattern', () => { const design = new Design({ parts: [part] }) const pattern = new design() pattern.draft() - expect(pattern.hooks.preRender.length).to.equal(1) + expect(pattern.plugins.hooks.preRender).to.have.lengthOf(1) }) it('Pattern.__init() should load a conditional plugin multiple times with different conditions', () => { @@ -718,7 +716,7 @@ describe('Pattern', () => { expect(pattern.config.plugins).to.be.an('object').that.has.all.keys('example1', 'example1_') expect(pattern.config.plugins.example1.plugin).to.deep.equal(plugin1) expect(pattern.config.plugins.example1_.plugin).to.deep.equal(plugin1) - expect(pattern.hooks.preRender.length).to.equal(1) + expect(pattern.plugins.hooks.preRender).to.have.lengthOf(1) }) it('Load conditional plugins that are also passing data', () => { @@ -757,7 +755,7 @@ describe('Pattern', () => { }) const pattern = new design() pattern.__init() - expect(pattern.hooks.preRender.length).to.equal(2) + expect(pattern.plugins.hooks.preRender).to.have.lengthOf(2) }) it('Pattern.__init() should register a hook via on', () => { diff --git a/packages/core/tests/pattern-other.test.mjs b/packages/core/tests/pattern-other.test.mjs index ba69d58a17d..c15c7ce07fa 100644 --- a/packages/core/tests/pattern-other.test.mjs +++ b/packages/core/tests/pattern-other.test.mjs @@ -90,8 +90,8 @@ describe('Pattern', () => { pattern.use(plugin) pattern.use({ plugin }) pattern.use({ plugin }) - expect(Object.keys(pattern.plugins).length).to.equal(1) - expect(Object.keys(pattern.plugins)[0]).to.equal('test') + expect(Object.keys(pattern.plugins.plugins)).to.have.lengthOf(1) + expect(Object.keys(pattern.plugins.plugins)[0]).to.equal('test') }) it('Should log an error of added parts do not have a draft method', () => {