diff --git a/packages/core/src/pattern.mjs b/packages/core/src/pattern.mjs index 4d0b30cf606..3bd340deff1 100644 --- a/packages/core/src/pattern.mjs +++ b/packages/core/src/pattern.mjs @@ -130,15 +130,8 @@ Pattern.prototype.draft = function () { this.stores[set].log.error([`Unable to draft part \`${partName}\` (set ${set})`, err]) } } else this.stores[set].log.error(`Unable to draft pattern. Part.draft() is not callable`) - try { - this.parts[set][partName].hidden = - this.parts[set][partName].hidden === true ? true : !this.__wants(partName, set) - } catch (err) { - this.stores[set].log.error([ - `Unable to set \`hidden\` property on part \`${partName}\``, - err, - ]) - } + this.parts[set][partName].hidden = + this.parts[set][partName].hidden === true ? true : !this.__wants(partName, set) } else { this.stores[set].log.debug( `Part \`${partName}\` is not needed. Skipping draft and setting hidden to \`true\`` @@ -253,11 +246,12 @@ Pattern.prototype.init = function () { * @return {object} this - The Pattern instance */ Pattern.prototype.sample = function () { + this.init() if (this.settings[0].sample.type === 'option') { return this.sampleOption(this.settings[0].sample.option) } else if (this.settings[0].sample.type === 'measurement') { return this.sampleMeasurement(this.settings[0].sample.measurement) - } else if (this.settings.sample.type === 'models') { + } else if (this.settings[0].sample.type === 'models') { return this.sampleModels(this.settings[0].sample.models, this.settings[0].sample.focus || false) } } @@ -268,7 +262,7 @@ Pattern.prototype.sample = function () { * @return {object} this - The Pattern instance */ Pattern.prototype.sampleMeasurement = function (measurementName) { - this.store.log.debug(`Sampling measurement \`${measurementName}\``) + this.stores[0].log.debug(`Sampling measurement \`${measurementName}\``) this.__runHooks('preSample') this.__applySettings(this.__measurementSets(measurementName)) this.init() @@ -283,7 +277,7 @@ Pattern.prototype.sampleMeasurement = function (measurementName) { * @return {object} this - The Pattern instance */ Pattern.prototype.sampleModels = function (models, focus = false) { - this.store.log.debug(`Sampling models \`${Object.keys(models).join(', ')}\``) + this.stores[0].log.debug(`Sampling models \`${Object.keys(models).join(', ')}\``) this.__runHooks('preSample') this.__applySettings(this.__modelSets(models, focus)) this.init() @@ -345,15 +339,7 @@ Pattern.prototype.render = function () { * @return {object} this - The Pattern instance */ Pattern.prototype.use = function (plugin, data) { - if (this.plugins?.[plugin.name]?.condition && !plugin.condition) { - // Plugin was first loaded conditionally, and is now loaded explicitly - this.stores[0].log.info( - `Plugin \`${plugin.plugin.name} was loaded conditionally earlier, but is now loaded explicitly.` - ) - return this.__loadPlugin(plugin, data) - } - // New plugin - else if (!this.plugins?.[plugin.name]) + if (!this.plugins?.[plugin.name]) return plugin.plugin && plugin.condition ? this.__useIf(plugin, data) // Conditional plugin : this.__loadPlugin(plugin, data) // Regular plugin @@ -482,8 +468,8 @@ Pattern.prototype.__filterOptionalMeasurements = function () { * @return {bool} hidden - true if the part is hidden, or false if not */ Pattern.prototype.__isPartHidden = function (partName) { - if (Array.isArray(this.settings.only)) { - if (this.settings.only.includes(partName)) return false + if (Array.isArray(this.settings[this.activeSet || 0].only)) { + if (this.settings[this.activeSet || 0].only.includes(partName)) return false } if (this.__parts?.[partName]?.hide) return true if (this.__parts?.[partName]?.hideAll) return true @@ -501,9 +487,9 @@ Pattern.prototype.__isPartHidden = function (partName) { Pattern.prototype.__isStackHidden = function (stackName) { if (!this.stacks[stackName]) return true const parts = this.stacks[stackName].getPartNames() - if (Array.isArray(this.settings.only)) { + if (Array.isArray(this.settings[this.activeStack || 0].only)) { for (const partName of parts) { - if (this.settings.only.includes(partName)) return false + if (this.settings[this.activeStack || 0].only.includes(partName)) return false } } for (const partName of parts) { @@ -694,7 +680,7 @@ Pattern.prototype.__loadPlugins = function () { */ Pattern.prototype.__loadPluginStoreMethods = function (plugin) { if (Array.isArray(plugin.store)) { - for (const store of this.stores) store.extend(...plugin.store) + for (const store of this.stores) store.extend(plugin.store) } else this.stores[0].log.warning(`Plugin store methods should be an Array`) } @@ -722,7 +708,7 @@ Pattern.prototype.__macro = function (key, method) { Pattern.prototype.__measurementSets = function (measurementName) { let val = this.settings[0].measurements[measurementName] if (val === undefined) - this.stores.log.error( + this.stores[0].log.error( `Cannot sample measurement \`${measurementName}\` because it's \`undefined\`` ) let step = val / 50 @@ -826,7 +812,7 @@ Pattern.prototype.__needs = function (partName, set = 0) { */ Pattern.prototype.__optionSets = function (optionName) { let option = this.config.options[optionName] - if (typeof option.list === 'object') return this.__listOptionSets(optionName) + if (typeof option?.list === 'object') return this.__listOptionSets(optionName) const sets = [] let factor = 1 let step, val @@ -917,7 +903,7 @@ Pattern.prototype.__pack = function () { for (let stackId of Object.keys(this.settings[0].layout.stacks)) { // Some parts are added by late-stage plugins if (this.stacks[stackId]) { - let transforms = this.settings.layout.stacks[stackId] + let transforms = this.settings[this.activeStack || 0].layout.stacks[stackId] this.stacks[stackId].generateTransform(transforms) } } diff --git a/packages/core/src/stack.mjs b/packages/core/src/stack.mjs index fd92d2aa25c..96e8ad27d32 100644 --- a/packages/core/src/stack.mjs +++ b/packages/core/src/stack.mjs @@ -117,31 +117,11 @@ Stack.prototype.attr = function (name, value, overwrite = false) { /** Generates the transform for a stack */ Stack.prototype.generateTransform = function (transforms) { const { move, rotate, flipX, flipY } = transforms - const generated = utils.generateStackTransform(move.x, move.y, rotate, flipX, flipY, this) + const generated = utils.generateStackTransform( move?.x, move?.y, rotate, flipX, flipY, this) for (var t in generated) { this.attr(t, generated[t], true) } } -/** Homes the stack so that its top left corner is in (0,0) */ -//Stack.prototype.home = function () { -// const parts = this.getPartList() -// if (parts.length < 1) return this -// for (const part of this.getPartList()) { -// part.home() -// } -// -// if (parts.length === 1) { -// this.topLeft = part.topLeft -// this.bottomRigth = part.bottomRight -// this.width = part.width -// this.height = part.height -// -// return this -// } -// -// return this.boundary() -//} - export default Stack diff --git a/packages/core/src/store.mjs b/packages/core/src/store.mjs index d39fe002cea..db0bfbffeee 100644 --- a/packages/core/src/store.mjs +++ b/packages/core/src/store.mjs @@ -43,10 +43,10 @@ export function Store(methods = []) { } this.logs = logs - for (const method of methods) { - if (avoid.indexOf(method[0]) !== -1) { - this.logs.warning(`You cannot squat ${method[0]} in the store`) - } else set(this, ...method) + for (const [path, method] of methods) { + if (avoid.indexOf(path) !== -1) { + this.log.warning(`You cannot overwrite store.${path}()`) + } else set(this, path, method) } return this @@ -62,10 +62,10 @@ export function Store(methods = []) { * @param {function} method - Method to add to the store (variadic) * @return {Store} this - The Store instance */ -Store.prototype.extend = function (...methods) { +Store.prototype.extend = function (methods) { for (const [path, method] of methods) { - if (avoid.indexOf(method[0]) !== -1) { - this.log.warning(`You can't squat ${method[0]}in the store`) + if (avoid.indexOf(path) !== -1) { + this.log.warning(`You cannot overwrite store.${path}()`) } else { this.log.info(`Extending store with ${path}`) set(this, path, (...args) => method(this, ...args)) diff --git a/packages/core/src/svg.mjs b/packages/core/src/svg.mjs index 7e25df2bb80..5443d1fbbd1 100644 --- a/packages/core/src/svg.mjs +++ b/packages/core/src/svg.mjs @@ -60,7 +60,7 @@ Svg.prototype.render = function () { this.activeStackIndex = 0 for (let stackId in this.pattern.stacks) { this.activeStack = stackId - this.idPrefix = this.pattern.settings[this.activeStackIndex].idPrefix + this.idPrefix = this.pattern.settings[this.activeStackIndex]?.idPrefix || 'fs-' const stack = this.pattern.stacks[stackId] if (!stack.hidden) { const stackSvg = this.__renderStack(stack) diff --git a/packages/core/src/utils.mjs b/packages/core/src/utils.mjs index 2d3535da39a..4c4429fae09 100644 --- a/packages/core/src/utils.mjs +++ b/packages/core/src/utils.mjs @@ -288,7 +288,7 @@ export function deg2rad(degrees) { * @param {Stack} stack - The Stack instance * @return {string} transform - The SVG transform value */ -export const generateStackTransform = (x, y, rotate, flipX, flipY, stack) => { +export const generateStackTransform = (x=0, y=0, rotate=0, flipX=false, flipY=false, stack) => { const transforms = [] let xTotal = x || 0 let yTotal = y || 0 diff --git a/packages/core/tests/pattern-other.test.mjs b/packages/core/tests/pattern-other.test.mjs new file mode 100644 index 00000000000..c289b298480 --- /dev/null +++ b/packages/core/tests/pattern-other.test.mjs @@ -0,0 +1,198 @@ +import chai from 'chai' +import { Design } from '../src/index.mjs' + +const expect = chai.expect + +describe('Pattern', () => { + + it('Should log an error when a part does not have a name', () => { + const part = { draft: ({ part }) => part } + const design = new Design() + const pattern = new design() + pattern.addPart(part) + expect(pattern.stores[0].logs.error.length).to.equal(1) + expect(pattern.stores[0].logs.error[0]).to.equal('Part must have a name') + }) + + it('Should log an error when a part does not have a draft method', () => { + const from = { + name: 'test', + draft: ({ points, part }) => { + points.test = false + return part + } + } + const to = { + name: 'testTo', + from, + draft: ({ points, part }) => { + return part + } + } + const design = new Design({ parts: [ to ]}) + const pattern = new design() + pattern.draft() + expect(pattern.stores[0].logs.error.length).to.equal(2) + expect(pattern.stores[0].logs.error[0][0]).to.equal('Unable to draft part `test` (set 0)') + expect(pattern.stores[0].logs.error[1][0]).to.equal('Could not inject part `test` into part `testTo`') + }) + + it('Not returning the part from the draft method should log an error', () => { + const test = { + name: 'test', + draft: ({ points, part }) => {} + } + const design = new Design({ parts: [ test ]}) + const pattern = new design() + pattern.draft() + expect(pattern.stores[0].logs.error.length).to.equal(1) + expect(pattern.stores[0].logs.error[0]).to.equal('Result of drafting part test was undefined. Did you forget to return the part?') + }) + + it('Should skip unneeded parts', () => { + const test = { + name: 'test', + draft: ({ points, part }) => part + } + const design = new Design({ parts: [ test ]}) + const pattern = new design({ only: ['you'] }) + pattern.draft() + expect(pattern.stores[0].logs.debug.length).to.equal(3) + expect(pattern.stores[0].logs.debug[2]).to.equal('Part `test` is not needed. Skipping draft and setting hidden to `true`') + }) + + it('Should return the initialized config', () => { + const test = { + name: 'test', + draft: ({ points, part }) => part + } + const design = new Design({ parts: [ test ]}) + const pattern = new design({ only: ['you'] }) + const config = pattern.getConfig() + expect(config.parts[0]).to.equal(test) + }) + + it('Should skip a plugin that is loaded twice', () => { + const test = { + name: 'test', + draft: ({ points, part }) => part + } + const plugin = { name: 'test' } + const design = new Design({ parts: [ test ]}) + const pattern = new design({ only: ['you'] }) + pattern.use(plugin) + pattern.use(plugin) + pattern.use({ plugin }) + pattern.use({ plugin }) + expect(pattern.stores[0].logs.info[1]).to.equal("Plugin `test` was requested, but it's already loaded. Skipping.") + expect(pattern.stores[0].logs.info[3]).to.equal("Plugin `test` was requested, but it's already loaded. Skipping.") + }) + + it('Should log an error of added parts do not have a draft method', () => { + const design = new Design() + const pattern = new design() + pattern.addPart({}) + expect(pattern.stores[0].logs.error.length).to.equal(1) + expect(pattern.stores[0].logs.error[0]).to.equal('Part must have a draft() method') + }) + + it('Parts in only are never hidden', () => { + const test = { + name: 'test', + hidden: true, + draft: ({ points, part }) => part + } + const design = new Design() + const pattern = new design({ only: ['test']}) + pattern.init() + expect(pattern.__isPartHidden('test')).to.equal(false) + }) + + it('Stacks with parts in only are never hidden', () => { + const part = { + name: 'test', + draft: ({ points, Point, paths, Path, part }) => { + points.test = new Point(3, 3) + + return part + }, + } + const design = new Design({ parts: [part] }) + const pattern = new design({ only: [ 'test' ] }) + pattern.draft().render() + expect(pattern.__isStackHidden('test')).to.equal(false) + }) + + it('Stacks with parts in only are never hidden', () => { + const part = { + name: 'test', + draft: ({ points, Point, paths, Path, part }) => { + points.test = new Point(3, 3) + + return part + }, + } + const design = new Design({ parts: [part] }) + const pattern = new design({ only: [ 'test' ] }) + pattern.draft().render() + expect(pattern.__isStackHidden('test')).to.equal(false) + }) + + it('Stacks with hidden dependencies should set hidden', () => { + const part1 = { + name: 'test1', + draft: ({ points, Point, paths, Path, part }) => { + points.test = new Point(3, 3) + + return part + }, + } + const part2 = { + name: 'test2', + from: part1, + hideDependencies: true, + draft: ({ points, Point, paths, Path, part }) => { + points.test = new Point(3, 3) + + return part + }, + } + const design = new Design({ parts: [part2] }) + const pattern = new design() + const config = pattern.getConfig() + expect(config.parts[1].hideAll).to.equal(true) + }) + + it('Drafts with errors should not get packed', () => { + const part= { + name: 'test', + draft: ({ points, Point, paths, Path, part }) => { + points.test = new Point(3, 3) + joints.foo = 'bar' + + return part + }, + } + const design = new Design({ parts: [part] }) + const pattern = new design() + pattern.draft().render() + expect(pattern.stores[0].logs.error.length).to.equal(1) + expect(pattern.stores[0].logs.error[0][0]).to.equal('Unable to draft part `test` (set 0)') + }) + + it('Handle layout object', () => { + const part = { + name: 'test', + draft: ({ points, Point, paths, Path, part }) => { + points.test = new Point(3, 3) + + return part + }, + } + const design = new Design({ parts: [part] }) + const pattern = new design({ layout: { stacks: { test: { flipX: true } } } }) + const props = pattern.draft().getRenderProps() + // FIXME: Add assertions here + //expect(pattern.__isStackHidden('test')).to.equal(false) + }) +}) diff --git a/packages/core/tests/pattern-sample.test.mjs b/packages/core/tests/pattern-sample.test.mjs index 219a6e55c66..b79f0384d82 100644 --- a/packages/core/tests/pattern-sample.test.mjs +++ b/packages/core/tests/pattern-sample.test.mjs @@ -1,42 +1,191 @@ import chai from 'chai' -//import { round, Pattern, Design, pctBasedOn } from '../src/index.mjs' +import { round, Pattern, Design, pctBasedOn } from '../src/index.mjs' const expect = chai.expect describe('Pattern', () => { describe('Pattern.sample()', () => { - it('FIXME: Write some tests here', () => { - expect(true).to.equal(true) + + it('Should sample an option', () => { + const part = { + name: 'test', + measurements: ['head'], + options: { + size: { pct: 50, min: 20, max: 80 }, + }, + draft: ({ Point, paths, Path, measurements, options, part }) => { + paths.test = new Path() + .move(new Point(0,0)) + .line(new Point(0, measurements.head * options.size)) + + return part + }, + } + const Pattern = new Design({ parts: [part] }) + const pattern = new Pattern({ + measurements: { head: 400 }, + sample: { + type: 'option', + option: 'size' + } + }) + pattern.sample() + expect(pattern.stores.length).to.equal(10) + expect(pattern.settings.length).to.equal(10) + expect(pattern.parts[9].test.paths.test.ops[1].to.y).to.equal(320) + }) + + it('Should sample a static option', () => { + const part = { + name: 'test', + measurements: ['head'], + options: { + size: 0.05, + }, + draft: ({ Point, paths, Path, measurements, options, part }) => { + paths.test = new Path() + .move(new Point(0,0)) + .line(new Point(0, measurements.head * options.size)) + + return part + }, + } + const Pattern = new Design({ parts: [part] }) + const pattern = new Pattern({ + measurements: { head: 400 }, + sample: { + type: 'option', + option: 'size' + } + }) + pattern.sample() + expect(pattern.stores.length).to.equal(10) + expect(pattern.settings.length).to.equal(10) + expect(round(pattern.parts[9].test.paths.test.ops[1].to.y)).to.equal(22) + }) + + it('Should sample a list option', () => { + const part = { + name: 'test', + measurements: ['head'], + options: { + size: { dflt: 5, list: [1, 2, 3, 4, 5 ,6 ,7, 8, 9, 10] }, + }, + draft: ({ Point, paths, Path, measurements, options, part }) => { + paths.test = new Path() + .move(new Point(0,0)) + .line(new Point(0, measurements.head * options.size/10)) + + return part + }, + } + const Pattern = new Design({ parts: [part] }) + const pattern = new Pattern({ + measurements: { head: 400 }, + sample: { + type: 'option', + option: 'size' + } + }) + pattern.sample() + expect(pattern.stores.length).to.equal(10) + expect(pattern.settings.length).to.equal(10) + expect(pattern.parts[9].test.paths.test.ops[1].to.y).to.equal(400) + }) + + it('Should sample a measurement', () => { + const part = { + name: 'test', + measurements: ['head'], + options: { + size: { pct: 50, min: 20, max: 80 }, + }, + draft: ({ Point, paths, Path, measurements, options, part }) => { + paths.test = new Path() + .move(new Point(0,0)) + .line(new Point(0, measurements.head * options.size)) + + return part + }, + } + const Pattern = new Design({ parts: [part] }) + const pattern = new Pattern({ + measurements: { head: 400 }, + sample: { + type: 'measurement', + measurement: 'head' + } + }) + pattern.sample() + expect(pattern.stores.length).to.equal(10) + expect(pattern.settings.length).to.equal(10) + expect(pattern.parts[9].test.paths.test.ops[1].to.y).to.equal(216) + }) + + it('Should log an error when sampling an undefined measurement', () => { + const part = { + name: 'test', + measurements: ['head'], + options: { + size: { pct: 50, min: 20, max: 80 }, + }, + draft: ({ Point, paths, Path, measurements, options, part }) => { + paths.test = new Path() + .move(new Point(0,0)) + .line(new Point(0, measurements.head * options.size)) + + return part + }, + } + const Pattern = new Design({ parts: [part] }) + const pattern = new Pattern({ + measurements: { }, + sample: { + type: 'measurement', + measurement: 'head' + } + }) + pattern.sample() + expect(pattern.stores[0].logs.error.length).to.equal(1) + expect(pattern.stores[0].logs.error[0]).to.equal("Cannot sample measurement `head` because it's `undefined`") + }) + + it('Should sample models', () => { + const part = { + name: 'test', + measurements: ['head'], + options: { + size: { pct: 50, min: 20, max: 80 }, + }, + draft: ({ Point, paths, Path, measurements, options, part }) => { + paths.test = new Path() + .move(new Point(0,0)) + .line(new Point(0, measurements.head * options.size)) + + return part + }, + } + const Pattern = new Design({ parts: [part] }) + const pattern = new Pattern({ + measurements: { head: 400 }, + sample: { + type: 'models', + models: { + a: { head: 100 }, + b: { head: 200 }, + c: { head: 300 }, + d: { head: 400 }, + }, + focus: 'c' + } + }) + pattern.sample() + expect(pattern.stores.length).to.equal(4) + expect(pattern.settings.length).to.equal(4) + expect(pattern.parts[3].test.paths.test.ops[1].to.y).to.equal(200) }) /* - it('Should sample an option', () => { - let pattern = new Pattern({ - options: { - len: { pct: 30, min: 10 }, - bonus: 10, - }, - }) - pattern.draft = function () { - pattern.parts.a = new pattern.Part() - pattern.parts.b = new pattern.Part() - let a = pattern.parts.a - a.points.from = new a.Point(0, 0) - a.points.to = new a.Point( - 100 * a.context.settings.options.len, - a.context.settings.options.bonus - ) - a.paths.test = new a.Path().move(a.points.from).line(a.points.to) - pattern.parts.b.inject(a) - } - pattern.settings.sample = { - type: 'option', - option: 'len', - } - pattern.sample() - expect(pattern.parts.a.paths.test_1.render).to.equal(true) - expect(pattern.parts.b.paths.test_10.ops[1].to.y).to.equal(10) - }) it("Should sample a list option", () => { const front = { name: 'front', diff --git a/packages/core/tests/snippet.test.mjs b/packages/core/tests/snippet.test.mjs index 4bd3a46c335..d6de391b53c 100644 --- a/packages/core/tests/snippet.test.mjs +++ b/packages/core/tests/snippet.test.mjs @@ -1,5 +1,5 @@ import chai from 'chai' -import { Snippet, Point } from '../src/index.mjs' +import { Design, Snippet, Point } from '../src/index.mjs' const expect = chai.expect @@ -26,4 +26,22 @@ describe('Snippet', () => { s.attr('class', 'less', true) expect(s.attributes.get('class')).to.equal('less') }) + + it('Should get a snippet via the snippets proxy', () => { + let result + const part = { + name: 'test', + draft: ({ snippets, part }) => { + snippets.test = ':)' + result = snippets.test + + return part + }, + } + const design = new Design({ parts: [part] }) + const pattern = new design() + pattern.draft() + expect(result).to.equal(':)') + }) + }) diff --git a/packages/core/tests/stacks.test.mjs b/packages/core/tests/stacks.test.mjs index 33545c67c55..cc3871ef54d 100644 --- a/packages/core/tests/stacks.test.mjs +++ b/packages/core/tests/stacks.test.mjs @@ -4,6 +4,7 @@ import { Design } from '../src/index.mjs' const expect = chai.expect describe('Stacks', () => { + describe('Pattern.init()', () => { const partA = { name: 'test.partA', @@ -52,7 +53,6 @@ describe('Stacks', () => { paths.line = new Path().move(points.from).line(points.to) return part }, - // stack: 'box', } const Pattern = new Design({ @@ -68,8 +68,6 @@ describe('Stacks', () => { }, }) pattern.draft() - //console.log(pattern.parts) - //pattern.render() it('Pattern.init() should resolve dependencies', () => { expect(typeof pattern.config.resolvedDependencies).to.equal('object') @@ -104,6 +102,7 @@ describe('Stacks', () => { pattern.draft().render() expect(pattern.stacks.test.topLeft.x).to.equal(17) expect(pattern.stacks.test.topLeft.y).to.equal(74) + pattern.render() expect(pattern.stacks.test.bottomRight.x).to.equal(125) expect(pattern.stacks.test.bottomRight.y).to.equal(458) expect(pattern.stacks.test.width).to.equal(108) @@ -149,7 +148,8 @@ describe('Stacks', () => { expect(pattern.stacks.test.topLeft.x).to.equal(9) expect(pattern.stacks.test.topLeft.y).to.equal(66) }) - it('Should generate the part transforms', () => { + + it('Should generate the stack transforms', () => { const part = { name: 'test', draft: ({ points, Point, paths, Path, part }) => { @@ -173,4 +173,57 @@ describe('Stacks', () => { expect(pattern.stacks.test.attributes.list.transform[0]).to.equal('translate(10 20)') }) }) + + it('Should get the anchor for the stack', () => { + const part = { + name: 'test', + draft: ({ points, Point, paths, Path, part }) => { + points.anchor = new Point(2, 2) + + return part + }, + } + const design = new Design({ parts: [part] }) + const pattern = new design() + pattern.draft().render() + const anchor = pattern.stacks.test.getAnchor() + expect(anchor.name).to.equal('anchor') + expect(anchor.x).to.equal(2) + expect(anchor.y).to.equal(2) + }) + + it('Should get the gridAnchor for the stack', () => { + const part = { + name: 'test', + draft: ({ points, Point, paths, Path, part }) => { + points.gridAnchor = new Point(3, 3) + + return part + }, + } + const design = new Design({ parts: [part] }) + const pattern = new design() + pattern.draft().render() + const anchor = pattern.stacks.test.getAnchor() + expect(anchor.name).to.equal('gridAnchor') + expect(anchor.x).to.equal(3) + expect(anchor.y).to.equal(3) + }) + + it('Should get the default aAnchor for the stack', () => { + const part = { + name: 'test', + draft: ({ points, Point, paths, Path, part }) => { + points.test = new Point(3, 3) + + return part + }, + } + const design = new Design({ parts: [part] }) + const pattern = new design() + pattern.draft().render() + const anchor = pattern.stacks.test.getAnchor() + expect(anchor.x).to.equal(0) + expect(anchor.y).to.equal(0) + }) }) diff --git a/packages/core/tests/store.test.mjs b/packages/core/tests/store.test.mjs index 1926c710af7..4d1e65e3b6b 100644 --- a/packages/core/tests/store.test.mjs +++ b/packages/core/tests/store.test.mjs @@ -106,4 +106,52 @@ describe('Store', () => { expect(pattern.stores[0].get('test.example_part.a')).to.equal('hello A') expect(pattern.stores[0].get('test.example_part.b')).to.equal('hello B') }) + + it('Should log a warning when trying to extend a protected method via the constructor', () => { + const store = new Store([['get', () => false]]) + expect(store.logs.warning.length).to.equal(1) + expect(store.logs.warning[0]).to.equal('You cannot overwrite store.get()') + }) + + it('Should log a warning when trying to extend a protected method via the extend', () => { + const store = new Store() + store.extend([['get', () => false]]) + expect(store.logs.warning.length).to.equal(1) + expect(store.logs.warning[0]).to.equal('You cannot overwrite store.get()') + }) + + it('Should extend the store with a new method via the constructor', () => { + const store = new Store([['test', () => true]]) + expect(store.test()).to.equal(true) + }) + + it('Should log a warning when pushing to a non-array key', () => { + const store = new Store() + store.push('test',1) + expect(store.logs.warning.length).to.equal(1) + expect(store.logs.warning[0]).to.equal('Store.push(value) on key `test`, but key does not hold an array') + }) + + it('Should log a warning when setting an undefined value with set()', () => { + const store = new Store() + store.set('test') + expect(store.logs.warning.length).to.equal(1) + expect(store.logs.warning[0]).to.equal('Store.set(value) on key `test`, but value is undefined') + }) + + it('Should log a warning when setting an undefined value with setIfUnset()', () => { + const store = new Store() + store.setIfUnset('test') + expect(store.logs.warning.length).to.equal(1) + expect(store.logs.warning[0]).to.equal('Store.setIfUnset(value) on key `test`, but value is undefined') + }) + + it('Should unset a value', () => { + const store = new Store() + store.set('test', 1980) + expect(store.get('test')).to.equal(1980) + store.unset('test') + expect(typeof store.get('test')).to.equal('undefined') + }) + }) diff --git a/packages/core/tests/svg.test.mjs b/packages/core/tests/svg.test.mjs index d44992df897..c5237210579 100644 --- a/packages/core/tests/svg.test.mjs +++ b/packages/core/tests/svg.test.mjs @@ -275,21 +275,4 @@ describe('Svg', () => { expect(svg.__tab()).to.equal(' ') }) - /* - it('Should not render an Svg path when render property is false', () => { - let pattern = new Pattern() - pattern.render() - pattern.parts.test = new pattern.Part() - let p = pattern.parts.test - p.paths.test = new p.Path() - .move(new p.Point(0, 0)) - .line(new p.Point(40, 20)) - .curve(new p.Point(12, 34), new p.Point(56, 78), new p.Point(21, 32)) - .close() - .attr('id', 'something') - .attr('class', 'freesewing') - p.paths.test.render = false - expect(pattern.render()).to.equalIgnoreSpaces(render.part) - }) -*/ })