1
0
Fork 0

chore(core): More unit tests

This commit is contained in:
Joost De Cock 2022-09-19 18:04:47 +02:00
parent 269b1a36f1
commit d5eb2946d3
13 changed files with 662 additions and 809 deletions

View file

@ -34,4 +34,5 @@ export const __loadPatternDefaults = () => ({
debug: false,
options: {},
absoluteOptions: {},
measurements: {}
})

View file

@ -95,7 +95,6 @@ Part.prototype.setHidden = function (hidden = false) {
return this
}
/** Returns an object with shorthand access for pattern design */
/**
* Returns an object that will be passed to draft method to be destructured
*
@ -152,13 +151,13 @@ Part.prototype.shorthand = function () {
shorthand.Snippet.prototype = Object.create(Snippet.prototype)
// Proxy points, paths, snippets, measurements, options, and absoluteOptions
shorthand.points = new Proxy(this.points || {}, pointsProxy(self.points, self.context.store.log))
shorthand.paths = new Proxy(this.paths || {}, pathsProxy(self.paths, self.context.store.log))
shorthand.points = new Proxy(this.points, pointsProxy(self.points, self.context.store.log))
shorthand.paths = new Proxy(this.paths, pathsProxy(self.paths, self.context.store.log))
shorthand.snippets = new Proxy(
this.snippets || {},
this.snippets,
snippetsProxy(self.snippets, self.context.store.log)
)
shorthand.measurements = new Proxy(this.context.settings.measurements || {}, {
shorthand.measurements = new Proxy(this.context.settings.measurements, {
get: function (measurements, name) {
if (typeof measurements[name] === 'undefined')
self.context.store.log.warning(
@ -168,7 +167,7 @@ Part.prototype.shorthand = function () {
},
set: (measurements, name, value) => (self.context.settings.measurements[name] = value),
})
shorthand.options = new Proxy(this.context.settings.options || {}, {
shorthand.options = new Proxy(this.context.settings.options, {
get: function (options, name) {
if (typeof options[name] === 'undefined')
self.context.store.log.warning(
@ -178,7 +177,7 @@ Part.prototype.shorthand = function () {
},
set: (options, name, value) => (self.context.settings.options[name] = value),
})
shorthand.absoluteOptions = new Proxy(this.context.settings.absoluteOptions || {}, {
shorthand.absoluteOptions = new Proxy(this.context.settings.absoluteOptions, {
get: function (absoluteOptions, name) {
if (typeof absoluteOptions[name] === 'undefined')
self.context.store.log.warning(
@ -239,9 +238,6 @@ Part.prototype.__boundary = function () {
}
} catch (err) {
this.context.store.log.error(`Could not calculate boundary of \`paths.${key}\``)
this.context.store.log.debug(
`Since \`paths.${key}\` has no boundary, neither does \`parts.${this.name}\`. Ejecting part`
)
return false
}
}

View file

@ -642,7 +642,7 @@ Path.prototype.shiftAlong = function (distance, stepsPerMm = 10) {
let thisLen = bezier.length()
if (Math.abs(len + thisLen - distance) < 0.1) return op.to
if (len + thisLen > distance)
return shiftAlongBezier(distance - len, bezier, thisLen * stepsPerMm)
return __shiftAlongBezier(distance - len, bezier, thisLen * stepsPerMm)
len += thisLen
}
current = op.to
@ -1266,25 +1266,10 @@ function __pathOffset(path, distance, log) {
* @private
* @param {float} distance - The distance to shift along the cubic Bezier curve
* @param {Bezier} bezier - The BezierJs instance
* @param {int} steps - The numer of steps to walk the Bezier with
* @param {int} steps - The numer of steps per mm to walk the Bezier with
* @return {Point} point - The point at distance along the cubic Bezier curve
*/
function shiftAlongBezier(distance, bezier, steps = false) {
let rlen
if (!steps) {
rlen = new Path()
.move(new Point(...Object.values(bezier.points[0])))
.curve(
new Point(...Object.values(bezier.points[1])),
new Point(...Object.values(bezier.points[2])),
new Point(...Object.values(bezier.points[3]))
)
.roughLength()
if (rlen < 2) steps = 20
else if (rlen < 10) steps = 40
else if (rlen < 100) steps = 100
else steps = 200
}
function __shiftAlongBezier(distance, bezier, steps) {
let previous, next, t, thisLen
let len = 0
for (let i = 0; i <= steps; i++) {

View file

@ -334,7 +334,7 @@ Pattern.prototype.render = function () {
this.svg = new Svg(this)
this.svg.hooks = this.hooks
return this.__pack().svg.render(this)
return this.__pack().svg.render()
}
/**

View file

@ -29,7 +29,7 @@ export function Svg(pattern) {
this.attributes.add('xmlns', 'http://www.w3.org/2000/svg')
this.attributes.add('xmlns:svg', 'http://www.w3.org/2000/svg')
this.attributes.add('xmlns:xlink', 'http://www.w3.org/1999/xlink')
this.attributes.add('xml:lang', pattern.settings.locale)
this.attributes.add('xml:lang', pattern?.settings?.[0]?.locale || 'en')
this.attributes.add('xmlns:freesewing', 'http://freesewing.org/namespaces/freesewing')
this.attributes.add('freesewing', version)
}
@ -44,21 +44,24 @@ export function Svg(pattern) {
* @param {Pattern} pattern - The pattern to render
* @return {string} svg - The rendered SVG output
*/
Svg.prototype.render = function (pattern) {
this.idPrefix = pattern.settings.idPrefix
Svg.prototype.render = function () {
this.idPrefix = this.pattern?.settings?.[0]?.idPrefix || 'fs-'
this.__runHooks('preRender')
pattern.__runHooks('postLayout')
if (!pattern.settings.embed) {
this.attributes.add('width', round(pattern.width) + 'mm')
this.attributes.add('height', round(pattern.height) + 'mm')
this.pattern.__runHooks('postLayout')
if (!this.pattern.settings[0].embed) {
this.attributes.add('width', round(this.pattern.width) + 'mm')
this.attributes.add('height', round(this.pattern.height) + 'mm')
}
this.attributes.add('viewBox', `0 0 ${pattern.width} ${pattern.height}`)
this.attributes.add('viewBox', `0 0 ${round(this.pattern.width)} ${round(this.pattern.height)}`)
this.head = this.__renderHead()
this.tail = this.__renderTail()
this.svg = ''
this.layout = {} // Reset layout
for (let stackId in pattern.stacks) {
const stack = pattern.stacks[stackId]
this.activeStackIndex = 0
for (let stackId in this.pattern.stacks) {
this.activeStack = stackId
this.idPrefix = this.pattern.settings[this.activeStackIndex].idPrefix
const stack = this.pattern.stacks[stackId]
if (!stack.hidden) {
const stackSvg = this.__renderStack(stack)
this.layout[stackId] = {
@ -69,6 +72,7 @@ Svg.prototype.render = function (pattern) {
this.svg += stackSvg
this.svg += this.__closeGroup()
}
this.activeStackIndex++
}
this.svg = this.prefix + this.__renderSvgTag() + this.head + this.svg + this.tail
this.__runHooks('postRender')
@ -137,7 +141,7 @@ Svg.prototype.__indent = function () {
Svg.prototype.__insertText = function (text) {
if (this.hooks.insertText.length > 0) {
for (let hook of this.hooks.insertText)
text = hook.method(this.pattern.settings.locale, text, hook.data)
text = hook.method(this.pattern.settings[this.activeStackIndex].locale || 'en', text, hook.data)
}
return text
@ -223,7 +227,6 @@ Svg.prototype.__renderDefs = function () {
*/
Svg.prototype.__renderHead = function () {
let svg = this.__renderStyle()
svg += this.__renderScript()
svg += this.__renderDefs()
svg += this.__openGroup(this.idPrefix + 'container')
@ -279,8 +282,8 @@ Svg.prototype.__renderPathText = function (path) {
* @param {Part} part - The Part instance to render
* @return {string} svg - The SVG markup for the Part object
*/
Svg.prototype.__renderPart = function (part, partId) {
let svg = this.__openGroup(`${this.idPrefix}part-${partId}`, part.attributes)
Svg.prototype.__renderPart = function (part) {
let svg = this.__openGroup(`${this.idPrefix}stack-${this.activeStack}-part-${part.name}`, part.attributes)
for (let key in part.paths) {
let path = part.paths[key]
if (!path.hidden) svg += this.__renderPath(path)
@ -302,22 +305,6 @@ Svg.prototype.__renderPart = function (part, partId) {
return svg
}
/**
* Returns SVG markup for the script block
*
* @private
* @return {string} svg - The SVG markup for the script block
*/
Svg.prototype.__renderScript = function () {
let svg = '<script type="text/javascript"> <![CDATA['
this.__indent()
svg += this.__nl() + this.script
this.__outdent()
svg += this.__nl() + ']]>' + this.__nl() + '</script>' + this.__nl()
return svg
}
/**
* Returns SVG markup for a snippet
*

View file

@ -725,15 +725,10 @@ export const __addPartPlugins = (part, config, store) => {
store.log.debug(`🔌 __${plugin.name}__ plugin in \`${part.name}\``)
// Do not overwrite an existing plugin with a conditional plugin unless it is also conditional
if (plugin.plugin && plugin.condition) {
if (plugins[plugin.plugin.name]?.condition) {
store.log.info(
`Plugin \`${plugin.plugin.name}\` was re-requested conditionally. Overwriting earlier condition.`
)
plugins[plugin.plugin.name] = plugin
} else
store.log.info(
`Plugin \`${plugin.plugin.name}\` was requested conditionally, but is already loaded explicitly. Not loading.`
)
if (plugins[plugin.plugin.name]?.condition) plugins[plugin.plugin.name] = plugin
else store.log.info(
`Plugin \`${plugin.plugin.name}\` was requested conditionally, but is already loaded explicitly. Not loading.`
)
} else {
plugins[plugin.name] = plugin
}