1
0
Fork 0
freesewing/packages/core/tests/part.test.mjs
joostdecock 26e282f5b7 fix: Fix tests after major chai upgrade
Note that the tests for Lumina are failing, but that's not related to
the chai upgrade, rather it seems these tests fail because of issues in
the design that we'll tackle later (it's a brand new design yet to be
released).
2024-02-04 12:14:42 +01:00

432 lines
13 KiB
JavaScript

import { expect } from 'chai'
import { Design, Part, pctBasedOn } from '../src/index.mjs'
describe('Part', () => {
it('Shorthand should contain the part itself', () => {
let dp
const part = {
name: 'test',
draft: ({ part }) => {
dp = part
return part
},
}
const design = new Design({ parts: [part] })
const pattern = new design()
pattern.draft()
expect(typeof dp).to.equal('object')
expect(typeof dp.context).to.equal('object')
})
it('Should return a function from __macroClosure', () => {
const part = new Part()
expect(typeof part.__macroClosure()).to.equal('function')
})
it('Should not run an unknown macro', () => {
const part = new Part()
const macro = part.__macroClosure()
expect(macro('unknown')).to.equal(undefined)
})
it('Should return a valid ID with Part.getId()', () => {
const part = new Part()
const id = part.getId()
const prefixed = part.getId('orange')
expect(id).to.equal('1')
expect(prefixed).to.equal('orange2')
})
it('Should register and run a macro', () => {
const plugin = {
name: 'test',
version: '0.1-test',
macros: {
test: function (so) {
let points = this.points
points.macro = new this.Point(so.x, so.y)
},
},
}
const part = {
name: 'test',
draft: ({ part, Point, points, macro }) => {
points.example = new Point(12, 34)
macro('test', { x: 123, y: 456 })
return part
},
plugins: plugin,
}
const design = new Design({ parts: [part] })
const pattern = new design()
pattern.draft()
expect(pattern.parts[0].test.points.macro.x).to.equal(123)
expect(pattern.parts[0].test.points.macro.y).to.equal(456)
})
it('Should return a free ID in draft method', () => {
let id = null
const part = {
name: 'test',
draft: ({ getId, part }) => {
id = getId()
id = getId()
id = getId()
return part
},
}
const design = new Design({ parts: [part] })
new design().draft()
expect(id).to.equal('3')
})
it('Should return a function from __unitsClosure', () => {
const part = new Part()
expect(typeof part.__unitsClosure()).to.equal('function')
})
it('Should convert units', () => {
const part = new Part()
part.context = { settings: { units: 'metric' } }
const units = part.__unitsClosure()
expect(units(123.456)).to.equal('12.35cm')
expect(units(123.456)).to.equal('12.35cm')
})
it('Should convert units directly', () => {
const part = new Part()
part.context = { settings: { units: 'metric' } }
expect(part.units(123.456)).to.equal('12.35cm')
expect(part.units(123.456)).to.equal('12.35cm')
})
it('Should set part attributes', () => {
const part = new Part()
part.attr('foo', 'bar')
expect(part.attributes.get('foo')).to.equal('bar')
part.attr('foo', 'baz')
expect(part.attributes.get('foo')).to.equal('bar baz')
part.attr('foo', 'schmoo', true)
expect(part.attributes.get('foo')).to.equal('schmoo')
})
it('Should log a warning when setting a non-Point value in points', () => {
const part = {
name: 'test',
draft: ({ points, part }) => {
points.a = 'banana'
return part
},
}
const design = new Design({ parts: [part] })
const pattern = new design()
pattern.draft()
expect(pattern.setStores[0].logs.warn.length).to.equal(4)
expect(pattern.setStores[0].logs.warn[0]).to.equal(
'`points.a` was set with a value that is not a `Point` object'
)
expect(pattern.setStores[0].logs.warn[1]).to.equal(
'`points.a` was set with a `x` parameter that is not a `number`'
)
expect(pattern.setStores[0].logs.warn[2]).to.equal(
'`points.a` was set with a `y` parameter that is not a `number`'
)
})
it('Should log a warning when setting a non-Snippet value in snippets', () => {
const part = {
name: 'test',
draft: ({ snippets, part }) => {
snippets.a = 'banana'
return part
},
}
const design = new Design({ parts: [part] })
const pattern = new design()
pattern.draft()
expect(pattern.setStores[0].logs.warn.length).to.equal(4)
expect(pattern.setStores[0].logs.warn[0]).to.equal(
'`snippets.a` was set with a value that is not a `Snippet` object'
)
expect(pattern.setStores[0].logs.warn[1]).to.equal(
'`snippets.a` was set with a `def` parameter that is not a `string`'
)
expect(pattern.setStores[0].logs.warn[2]).to.equal(
'`snippets.a` was set with an `anchor` parameter that is not a `Point`'
)
})
it('Should calculate the part boundary', () => {
const part = {
name: 'test',
draft: ({ points, Point, paths, Path, part }) => {
points.from = new Point(123, 456)
points.to = new Point(19, 76).attr('data-circle', 12)
paths.test = new Path().move(points.from).line(points.to)
return part
},
}
const design = new Design({ parts: [part] })
const pattern = new design()
pattern.draft().render()
const boundary = pattern.parts[0].test.__boundary()
const { topLeft, bottomRight, width, height } = boundary
expect(topLeft.x).to.equal(7)
expect(topLeft.y).to.equal(64)
// Cover the cached branch
pattern.parts[0].test.__boundary()
expect(bottomRight.x).to.equal(123)
expect(bottomRight.y).to.equal(456)
expect(width).to.equal(116)
expect(height).to.equal(392)
})
it('Units closure should log a warning when passing a non-number', () => {
const part = {
name: 'test',
draft: ({ units, part }) => {
units('a')
return part
},
}
const design = new Design({ parts: [part] })
// Let's also cover the branch where complete is false
const pattern = new design({ complete: false })
pattern.draft()
expect(pattern.setStores[0].logs.warn.length).to.equal(1)
expect(pattern.setStores[0].logs.warn[0]).to.equal(
'Calling `units(value)` but `value` is not a number (`string`)'
)
})
it('Should (un)hide a part with hide()/unhide()', () => {
const part = new Part()
expect(part.hidden).to.equal(false)
part.hide()
expect(part.hidden).to.equal(true)
part.unhide()
expect(part.hidden).to.equal(false)
})
it('Should (un)hide a part with setHidden()', () => {
const part = new Part()
expect(part.hidden).to.equal(false)
part.setHidden(true)
expect(part.hidden).to.equal(true)
part.setHidden(false)
expect(part.hidden).to.equal(false)
})
it('Draft method should receive the Snippet constructor', () => {
let method
const part = {
name: 'test',
draft: ({ Point, snippets, Snippet, part }) => {
method = Snippet
snippets.test = new Snippet('notch', new Point(19, 80))
return part
},
}
const design = new Design({ parts: [part] })
const pattern = new design()
pattern.draft()
expect(typeof method).to.equal('function')
expect(pattern.parts[0].test.snippets.test.def).to.equal('notch')
expect(pattern.parts[0].test.snippets.test.name).to.equal('test')
expect(pattern.parts[0].test.snippets.test.anchor.x).to.equal(19)
expect(pattern.parts[0].test.snippets.test.anchor.y).to.equal(80)
})
it('Measurments proxy should allow setting a measurement', () => {
const part = {
name: 'test',
draft: ({ measurements, part }) => {
measurements.head = 120
return part
},
}
const design = new Design({ parts: [part] })
const pattern = new design()
pattern.draft()
expect(pattern.settings[0].measurements.head).to.equal(120)
})
it('Options proxy should allow setting an option', () => {
const part = {
name: 'test',
draft: ({ options, part }) => {
options.test = 120
return part
},
}
const design = new Design({ parts: [part] })
const pattern = new design()
pattern.draft()
expect(pattern.settings[0].options.test).to.equal(120)
})
it('AbsoluteOptions proxy should allow setting an absoluteOption', () => {
const part = {
name: 'test',
draft: ({ absoluteOptions, part }) => {
absoluteOptions.test = 120
return part
},
}
const design = new Design({ parts: [part] })
const pattern = new design()
pattern.draft()
expect(pattern.settings[0].absoluteOptions.test).to.equal(120)
})
it('Snapped percentage options should be available to the draft method', () => {
const part = {
name: 'test',
options: {
test: { pct: 10, min: 5, max: 25, snap: 5, ...pctBasedOn('head') },
},
draft: ({ paths, Path, Point, absoluteOptions, part }) => {
paths.test = new Path().move(new Point(0, 0)).line(new Point(absoluteOptions.test, 0))
return part
},
}
const design = new Design({ parts: [part] })
const pattern = new design({ measurements: { head: 200 } })
pattern.draft()
expect(pattern.parts[0].test.paths.test.ops[1].to.x).to.equal(20)
})
it('Accessing unknown option should log a warning', () => {
const part = {
name: 'test',
draft: ({ options, part }) => {
if (options.test === 'This should never match') return null
else return part
},
}
const design = new Design({ parts: [part] })
const pattern = new design()
pattern.draft()
expect(pattern.setStores[0].logs.warn.length).to.equal(1)
expect(pattern.setStores[0].logs.warn[0]).to.equal(
'Tried to access `options.test` but it is `undefined`'
)
})
it('Accessing unknown absoluteOption should log a warning', () => {
const part = {
name: 'test',
draft: ({ absoluteOptions, part }) => {
if (absoluteOptions.test === 'this check should always fail') return null
else return part
},
}
const design = new Design({ parts: [part] })
const pattern = new design()
pattern.draft()
expect(pattern.setStores[0].logs.warn.length).to.equal(1)
expect(pattern.setStores[0].logs.warn[0]).to.equal(
'Tried to access `absoluteOptions.test` but it is `undefined`'
)
})
it('Injecting a part should contain all data', () => {
const from = {
name: 'from',
draft: ({ points, Point, paths, Path, snippets, Snippet, part }) => {
points.from = new Point(0, 0)
points.to = new Point(19, 80)
points.start = new Point(100, 100)
points.cp1 = new Point(100, 200)
points.cp2 = new Point(200, 100)
points.end = new Point(200, 200)
paths.line = new Path().move(points.from).line(points.to)
paths.curve = new Path().move(points.start).curve(points.cp1, points.cp2, points.end)
snippets.test = new Snippet('notch', points.end)
return part
},
}
const to = {
from,
name: 'to',
draft: ({ part }) => part,
}
const design = new Design({ parts: [from, to] })
const pattern = new design()
pattern.draft()
expect(pattern.parts[0].to.points.to.x).to.equal(19)
expect(pattern.parts[0].to.points.to.y).to.equal(80)
expect(typeof pattern.parts[0].to.paths.line).to.equal('object')
expect(pattern.parts[0].to.paths.curve.ops[1].cp2.x).to.equal(200)
})
it('Should set/unset the name of the active macro', () => {
const activeMacro = []
const plugin = {
name: 'testplugin',
version: '0.0.1',
macros: {
macro1: (config, { part, store }) => {
activeMacro.push(store.activeMacro)
return part
},
},
}
const part = {
name: 'test',
draft: ({ macro, part }) => {
activeMacro.push(part.activeMacro)
macro('macro1')
activeMacro.push(part.activeMacro)
return part
},
}
const design = new Design({ parts: [part], plugins: [plugin] })
const pattern = new design()
pattern.draft()
expect(activeMacro[0]).to.equal(undefined)
expect(activeMacro[1]).to.equal('macro1')
expect(activeMacro[2]).to.equal(undefined)
})
it('Should set/unset the name of the active macro in a nested macro', () => {
const activeMacro = []
const plugin = {
name: 'testplugin',
version: '0.0.1',
macros: {
macro1: (config, { macro, part, store }) => {
activeMacro.push(store.activeMacro)
macro('macro2')
activeMacro.push(store.activeMacro)
return part
},
macro2: (config, { part, store }) => {
activeMacro.push(store.activeMacro)
return part
},
},
}
const part = {
name: 'test',
draft: ({ macro, part }) => {
activeMacro.push(part.activeMacro)
macro('macro1')
activeMacro.push(part.activeMacro)
return part
},
}
const design = new Design({ parts: [part], plugins: [plugin] })
const pattern = new design()
pattern.draft()
expect(activeMacro[0]).to.equal(undefined)
expect(activeMacro[1]).to.equal('macro1')
expect(activeMacro[2]).to.equal('macro2')
expect(activeMacro[3]).to.equal('macro1')
expect(activeMacro[4]).to.equal(undefined)
})
})