chore(core): More unit tests
This commit is contained in:
parent
269b1a36f1
commit
d5eb2946d3
13 changed files with 662 additions and 809 deletions
|
@ -34,4 +34,5 @@ export const __loadPatternDefaults = () => ({
|
|||
debug: false,
|
||||
options: {},
|
||||
absoluteOptions: {},
|
||||
measurements: {}
|
||||
})
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -725,13 +725,8 @@ 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(
|
||||
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 {
|
||||
|
|
376
packages/core/tests/fixtures/render.mjs
vendored
376
packages/core/tests/fixtures/render.mjs
vendored
|
@ -3,366 +3,22 @@ import pkg from '../../package.json' assert { type: 'json' }
|
|||
const { version } = pkg
|
||||
|
||||
var render = {
|
||||
boilerplate: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="0mm" height="0mm" viewBox="0 0 0 0"
|
||||
>
|
||||
<style type="text/css"> <![CDATA[
|
||||
]]>
|
||||
</style>
|
||||
<script type="text/javascript"> <![CDATA[
|
||||
|
||||
]]>
|
||||
</script>
|
||||
<defs>
|
||||
|
||||
</defs>
|
||||
|
||||
|
||||
<!-- Start of group #fs-container -->
|
||||
<g id="fs-container">
|
||||
</g>
|
||||
<!-- end of group #fs-container -->
|
||||
</svg>`,
|
||||
boilerplateNl: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="nl" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="0mm" height="0mm" viewBox="0 0 0 0"
|
||||
>
|
||||
<style type="text/css"> <![CDATA[
|
||||
]]>
|
||||
</style>
|
||||
<script type="text/javascript"> <![CDATA[
|
||||
|
||||
]]>
|
||||
</script>
|
||||
<defs>
|
||||
|
||||
</defs>
|
||||
|
||||
|
||||
<!-- Start of group #fs-container -->
|
||||
<g id="fs-container">
|
||||
</g>
|
||||
<!-- end of group #fs-container -->
|
||||
</svg>`,
|
||||
embed: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" viewBox="0 0 0 0"
|
||||
>
|
||||
<style type="text/css"> <![CDATA[
|
||||
]]>
|
||||
</style>
|
||||
<script type="text/javascript"> <![CDATA[
|
||||
|
||||
]]>
|
||||
</script>
|
||||
<defs>
|
||||
|
||||
</defs>
|
||||
|
||||
|
||||
<!-- Start of group #fs-container -->
|
||||
<g id="fs-container">
|
||||
</g>
|
||||
<!-- end of group #fs-container -->
|
||||
</svg>`,
|
||||
part: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="4mm" height="4mm" viewBox="0 0 4 4"
|
||||
>
|
||||
<style type="text/css"> <![CDATA[
|
||||
]]>
|
||||
</style>
|
||||
<script type="text/javascript"> <![CDATA[
|
||||
|
||||
]]>
|
||||
</script>
|
||||
<defs>
|
||||
|
||||
</defs>
|
||||
|
||||
|
||||
<!-- Start of group #fs-container -->
|
||||
<g id="fs-container">
|
||||
|
||||
<!-- Start of group #fs-part-test -->
|
||||
<g id="fs-part-test" transform="translate(2, 2)">
|
||||
</g>
|
||||
<!-- end of group #fs-part-test -->
|
||||
</g>
|
||||
<!-- end of group #fs-container -->
|
||||
</svg>`,
|
||||
path: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="44mm" height="56.45mm" viewBox="0 0 44 56.451075975520425"
|
||||
>
|
||||
<style type="text/css"> <![CDATA[
|
||||
]]>
|
||||
</style>
|
||||
<script type="text/javascript"> <![CDATA[
|
||||
|
||||
]]>
|
||||
</script>
|
||||
<defs>
|
||||
|
||||
</defs>
|
||||
|
||||
|
||||
<!-- Start of group #fs-container -->
|
||||
<g id="fs-container">
|
||||
|
||||
<!-- Start of group #fs-part-test -->
|
||||
<g id="fs-part-test" transform="translate(2, 2)">
|
||||
<path id="something" class="freesewing" d="M 0,0 L 40,20 C 12,34 56,78 21,32 z" />
|
||||
</g>
|
||||
<!-- end of group #fs-part-test -->
|
||||
</g>
|
||||
<!-- end of group #fs-container -->
|
||||
</svg>`,
|
||||
text: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="4mm" height="4mm" viewBox="0 0 4 4"
|
||||
>
|
||||
<style type="text/css"> <![CDATA[
|
||||
]]>
|
||||
</style>
|
||||
<script type="text/javascript"> <![CDATA[
|
||||
|
||||
]]>
|
||||
</script>
|
||||
<defs>
|
||||
|
||||
</defs>
|
||||
|
||||
|
||||
<!-- Start of group #fs-container -->
|
||||
<g id="fs-container">
|
||||
|
||||
<!-- Start of group #fs-part-test -->
|
||||
<g id="fs-part-test" transform="translate(2, 2)">
|
||||
<text class="text-lg" x="20" y="20"><tspan>This is a test</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<!-- end of group #fs-part-test -->
|
||||
</g>
|
||||
<!-- end of group #fs-container -->
|
||||
</svg>`,
|
||||
circle: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="104mm" height="104mm" viewBox="0 0 104 104"
|
||||
>
|
||||
<style type="text/css"> <![CDATA[
|
||||
]]>
|
||||
</style>
|
||||
<script type="text/javascript"> <![CDATA[
|
||||
|
||||
]]>
|
||||
</script>
|
||||
<defs>
|
||||
|
||||
</defs>
|
||||
|
||||
|
||||
<!-- Start of group #fs-container -->
|
||||
<g id="fs-container">
|
||||
|
||||
<!-- Start of group #fs-part-test -->
|
||||
<g id="fs-part-test" transform="translate(32, 32)"><circle
|
||||
cx="20"
|
||||
cy="20"
|
||||
r="50"
|
||||
|
||||
></circle>
|
||||
</g>
|
||||
<!-- end of group #fs-part-test -->
|
||||
</g>
|
||||
<!-- end of group #fs-container -->
|
||||
</svg>`,
|
||||
multiText: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="4mm" height="4mm" viewBox="0 0 4 4"
|
||||
>
|
||||
<style type="text/css"> <![CDATA[
|
||||
]]>
|
||||
</style>
|
||||
<script type="text/javascript"> <![CDATA[
|
||||
|
||||
]]>
|
||||
</script>
|
||||
<defs>
|
||||
|
||||
</defs>
|
||||
|
||||
|
||||
<!-- Start of group #fs-container -->
|
||||
<g id="fs-container">
|
||||
|
||||
<!-- Start of group #fs-part-test -->
|
||||
<g id="fs-part-test" transform=" translate(2, 2)">
|
||||
<text class="text-lg" x="20" y="20"><tspan>This is a test</tspan><tspan x="20" dy="8">with text on</tspan><tspan x="20" dy="8">multiple lines</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<!-- end of group #fs-part-test -->
|
||||
</g>
|
||||
<!-- end of group #fs-container -->
|
||||
</svg>`,
|
||||
multiTextDflt: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="4mm" height="4mm" viewBox="0 0 4 4"
|
||||
>
|
||||
<style type="text/css"> <![CDATA[
|
||||
]]>
|
||||
</style>
|
||||
<script type="text/javascript"> <![CDATA[
|
||||
|
||||
]]>
|
||||
</script>
|
||||
<defs>
|
||||
|
||||
</defs>
|
||||
|
||||
|
||||
<!-- Start of group #fs-container -->
|
||||
<g id="fs-container">
|
||||
|
||||
<!-- Start of group #fs-part-test -->
|
||||
<g id="fs-part-test" transform=" translate(2, 2)">
|
||||
<text class="text-lg" x="20" y="20"><tspan>This is a test</tspan><tspan x="20" dy="6">with text on</tspan><tspan x="20" dy="6">multiple lines</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<!-- end of group #fs-part-test -->
|
||||
</g>
|
||||
<!-- end of group #fs-container -->
|
||||
</svg>`,
|
||||
textOnPath: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="44mm" height="56.45mm" viewBox="0 0 44 56.451075975520425"
|
||||
>
|
||||
<style type="text/css"> <![CDATA[
|
||||
]]>
|
||||
</style>
|
||||
<script type="text/javascript"> <![CDATA[
|
||||
|
||||
]]>
|
||||
</script>
|
||||
<defs>
|
||||
|
||||
</defs>
|
||||
|
||||
|
||||
<!-- Start of group #fs-container -->
|
||||
<g id="fs-container">
|
||||
|
||||
<!-- Start of group #fs-part-test -->
|
||||
<g id="fs-part-test" transform="translate(2, 2)">
|
||||
<path data-text="This is another test" data-text-class="text-sm" class="freesewing" id="fs-1" d="M 0,0 L 40,20 C 12,34 56,78 21,32 z" />
|
||||
<text><textPath xlink:href="#fs-1" ><tspan class="text-sm">This is another test</tspan></textPath>
|
||||
</text>
|
||||
</g>
|
||||
<!-- end of group #fs-part-test -->
|
||||
</g>
|
||||
<!-- end of group #fs-container -->
|
||||
</svg>`,
|
||||
textOnPathCenter: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="44mm" height="56.45mm" viewBox="0 0 44 56.451075975520425"
|
||||
>
|
||||
<style type="text/css"> <![CDATA[
|
||||
]]>
|
||||
</style>
|
||||
<script type="text/javascript"> <![CDATA[
|
||||
|
||||
]]>
|
||||
</script>
|
||||
<defs>
|
||||
|
||||
</defs>
|
||||
|
||||
|
||||
<!-- Start of group #fs-container -->
|
||||
<g id="fs-container">
|
||||
|
||||
<!-- Start of group #fs-part-test -->
|
||||
<g id="fs-part-test" transform="translate(2, 2)">
|
||||
<path data-text="This is another test" data-text-class="center" class="freesewing" id="fs-1" d="M 0,0 L 40,20 C 12,34 56,78 21,32 z" />
|
||||
<text><textPath xlink:href="#fs-1" startOffset="50%" ><tspan class="center">This is another test</tspan></textPath>
|
||||
</text>
|
||||
</g>
|
||||
<!-- end of group #fs-part-test -->
|
||||
</g>
|
||||
<!-- end of group #fs-container -->
|
||||
</svg>`,
|
||||
textOnPathRight: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="44mm" height="56.45mm" viewBox="0 0 44 56.451075975520425"
|
||||
>
|
||||
<style type="text/css"> <![CDATA[
|
||||
]]>
|
||||
</style>
|
||||
<script type="text/javascript"> <![CDATA[
|
||||
|
||||
]]>
|
||||
</script>
|
||||
<defs>
|
||||
|
||||
</defs>
|
||||
|
||||
|
||||
<!-- Start of group #fs-container -->
|
||||
<g id="fs-container">
|
||||
|
||||
<!-- Start of group #fs-part-test -->
|
||||
<g id="fs-part-test" transform="translate(2, 2)">
|
||||
<path data-text="This is another test" data-text-class="right" class="freesewing" id="fs-1" d="M 0,0 L 40,20 C 12,34 56,78 21,32 z" />
|
||||
<text><textPath xlink:href="#fs-1" startOffset="100%" ><tspan class="right">This is another test</tspan></textPath>
|
||||
</text>
|
||||
</g>
|
||||
<!-- end of group #fs-part-test -->
|
||||
</g>
|
||||
<!-- end of group #fs-container -->
|
||||
</svg>`,
|
||||
snippet: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="4mm" height="4mm" viewBox="0 0 4 4"
|
||||
>
|
||||
<style type="text/css"> <![CDATA[
|
||||
|
||||
]]>
|
||||
</style>
|
||||
<script type="text/javascript"> <![CDATA[
|
||||
|
||||
]]>
|
||||
</script>
|
||||
<defs>
|
||||
|
||||
</defs>
|
||||
|
||||
|
||||
<!-- Start of group #fs-container -->
|
||||
<g id="fs-container">
|
||||
|
||||
<!-- Start of group #fs-part-test -->
|
||||
<g id="fs-part-test" transform="translate(2, 2)">
|
||||
<use x="20" y="20" xlink:href="#test" transform="translate(20, 20) scale(1) translate(-20, -20)"></use>
|
||||
</g>
|
||||
<!-- end of group #fs-part-test -->
|
||||
</g>
|
||||
<!-- end of group #fs-container -->
|
||||
</svg>`,
|
||||
rotatedSnippet: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="4mm" height="4mm" viewBox="0 0 4 4"
|
||||
>
|
||||
<style type="text/css"> <![CDATA[
|
||||
|
||||
]]>
|
||||
</style>
|
||||
<script type="text/javascript"> <![CDATA[
|
||||
|
||||
]]>
|
||||
</script>
|
||||
<defs>
|
||||
|
||||
</defs>
|
||||
|
||||
|
||||
<!-- Start of group #fs-container -->
|
||||
<g id="fs-container">
|
||||
|
||||
<!-- Start of group #fs-part-test -->
|
||||
<g id="fs-part-test" transform="translate(2, 2)">
|
||||
<use x="20" y="20" xlink:href="#test" data-rotate="90" transform="translate(20, 20) scale(1) translate(-20, -20) rotate(90, 20, 20)"></use>
|
||||
</g>
|
||||
<!-- end of group #fs-part-test -->
|
||||
</g>
|
||||
<!-- end of group #fs-container -->
|
||||
</svg>`
|
||||
boilerplate: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svgxmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="3.0.0-alpha.0" width="44mm" height="56.45mm" viewBox="0 0 44 56.45"><style type="text/css"> <![CDATA[]]></style><defs></defs><!-- Start of group #fs-container --><g id="fs-container"><!-- Start of group #fs-stack-test --><g id="fs-stack-test" transform="translate(2, 2)"><!-- Start of group #fs-stack-test-part-test --><g id="fs-stack-test-part-test" ><path id="something" class="freesewing" d="M 0,0 L 40,20 C 12,34 56,78 21,32 z" /></g><!-- end of group #fs-stack-test-part-test --></g><!-- end of group #fs-stack-test --></g><!-- end of group #fs-container --></svg>`,
|
||||
boilerplateNl: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svgxmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="nl" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="3.0.0-alpha.0" width="44mm" height="56.45mm" viewBox="0 0 44 56.45"><style type="text/css"> <![CDATA[]]></style><defs></defs><!-- Start of group #fs-container --><g id="fs-container"><!-- Start of group #fs-stack-test --><g id="fs-stack-test" transform="translate(2, 2)"><!-- Start of group #fs-stack-test-part-test --><g id="fs-stack-test-part-test" ><path id="something" class="freesewing" d="M 0,0 L 40,20 C 12,34 56,78 21,32 z" /></g><!-- end of group #fs-stack-test-part-test --></g><!-- end of group #fs-stack-test --></g><!-- end of group #fs-container --></svg>`,
|
||||
embed: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svgxmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="3.0.0-alpha.0" viewBox="0 0 44 56.45"><style type="text/css"> <![CDATA[]]></style><defs></defs><!-- Start of group #fs-container --><g id="fs-container"><!-- Start of group #fs-stack-test --><g id="fs-stack-test" transform="translate(2, 2)"><!-- Start of group #fs-stack-test-part-test --><g id="fs-stack-test-part-test" ><path id="something" class="freesewing" d="M 0,0 L 40,20 C 12,34 56,78 21,32 z" /></g><!-- end of group #fs-stack-test-part-test --></g><!-- end of group #fs-stack-test --></g><!-- end of group #fs-container --></svg>`,
|
||||
stack: `<!-- Start of group #fs-stack-test-part-test --><g id="fs-stack-test-part-test" ><path id="something" class="freesewing" d="M 0,0 L 40,20 C 12,34 56,78 21,32 z" /></g><!-- end of group #fs-stack-test-part-test -->`,
|
||||
part: `<!-- Start of group #fs-stack-test-part-test --><g id="fs-stack-test-part-test" ><path id="something" class="freesewing" d="M 0,0 L 40,20 C 12,34 56,78 21,32 z" /></g><!-- end of group #fs-stack-test-part-test -->`,
|
||||
path: `<path id="something" class="freesewing" d="M 0,0 L 40,20 C 12,34 56,78 21,32 z" />`,
|
||||
text: `<!-- Start of group #fs-stack-test-part-test --><g id="fs-stack-test-part-test" ><text class="text-lg" x="20" y="20"><tspan>This is a test </tspan></text></g><!-- end of group #fs-stack-test-part-test -->`,
|
||||
multiText: `<!-- Start of group #fs-stack-test-part-test --><g id="fs-stack-test-part-test" ><text class="text-lg" x="20" y="20"><tspan>This is a test</tspan><tspan x="20" dy="6">with text on</tspan><tspan x="20" dy="6">multiple lines </tspan></text></g><!-- end of group #fs-stack-test-part-test -->`,
|
||||
multiTextDflt: `<!-- Start of group #fs-stack-test-part-test --><g id="fs-stack-test-part-test" ><text class="text-lg" x="20" y="20"><tspan>This is a test</tspan><tspan x="20" dy="6">with text on</tspan><tspan x="20" dy="6">multiple lines </tspan></text></g><!-- end of group #fs-stack-test-part-test -->`,
|
||||
textOnPath: `<!-- Start of group #fs-stack-test-part-test --><g id="fs-stack-test-part-test" ><path data-text="This is another test" data-text-class="text-sm" class="freesewing" id="fs-1" d="M 0,0 L 40,20 C 12,34 56,78 21,32 z" /><text><textPath xlink:href="#fs-1" ><tspan class="text-sm">This is another test</tspan></textPath></text></g><!-- end of group #fs-stack-test-part-test -->`,
|
||||
textOnPathCenter: `<!-- Start of group #fs-stack-test-part-test --><g id="fs-stack-test-part-test" ><path data-text="This is another test" data-text-class="center" class="freesewing" id="fs-1" d="" /><text><textPath xlink:href="#fs-1" startOffset="50%" ><tspan class="center">This is another test</tspan></textPath></text></g><!-- end of group #fs-stack-test-part-test -->`,
|
||||
textOnPathRight: `<!-- Start of group #fs-stack-test-part-test --><g id="fs-stack-test-part-test" ><path data-text="This is another test" data-text-class="right" class="freesewing" id="fs-1" d="" /><text><textPath xlink:href="#fs-1" startOffset="100%" ><tspan class="right">This is another test</tspan></textPath></text></g><!-- end of group #fs-stack-test-part-test -->`,
|
||||
circle: `<!-- Start of group #fs-stack-test-part-test --><g id="fs-stack-test-part-test" ><circle cx="20" cy="20" r="50" ></circle></g><!-- end of group #fs-stack-test-part-test -->`,
|
||||
snippet: `<!-- Start of group #fs-stack-test-part-test --><g id="fs-stack-test-part-test" ><use x="20" y="20" xlink:href="#test" transform="translate(20, 20) scale(1) translate(-20, -20) translate(20, 20) scale(1) translate(-20, -20)"></use></g><!-- end of group #fs-stack-test-part-test -->`,
|
||||
rotatedSnippet: `<!-- Start of group #fs-stack-test-part-test --><g id="fs-stack-test-part-test" ><use x="20" y="20" xlink:href="#test" data-rotate="90" transform="translate(20, 20) scale(1) translate(-20, -20) rotate(90, 20, 20) translate(20, 20) scale(1) translate(-20, -20) rotate(90, 20, 20)"></use></g><!-- end of group #fs-stack-test-part-test -->`,
|
||||
scaledSnippet: `<!-- Start of group #fs-stack-test-part-test --><g id="fs-stack-test-part-test" ><use x="20" y="20" xlink:href="#test" data-scale="2" transform="translate(20, 20) scale(2) translate(-20, -20) translate(20, 20) scale(2) translate(-20, -20)"></use></g><!-- end of group #fs-stack-test-part-test -->`,
|
||||
}
|
||||
|
||||
export default render
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import chai from 'chai'
|
||||
import { Design, Part } from '../src/index.mjs'
|
||||
import { Design, Part, pctBasedOn } from '../src/index.mjs'
|
||||
|
||||
const expect = chai.expect
|
||||
|
||||
|
@ -75,6 +75,13 @@ describe('Part', () => {
|
|||
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')
|
||||
|
@ -136,74 +143,27 @@ describe('Part', () => {
|
|||
name: 'test',
|
||||
draft: ({ points, Point, paths, Path, part }) => {
|
||||
points.from = new Point(123, 456)
|
||||
points.to = new Point(19, 76)
|
||||
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()
|
||||
pattern.draft().render()
|
||||
const boundary = pattern.parts[0].test.__boundary()
|
||||
const { topLeft, bottomRight, width, height } = boundary
|
||||
expect(topLeft.x).to.equal(19)
|
||||
expect(topLeft.y).to.equal(76)
|
||||
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(104)
|
||||
expect(height).to.equal(380)
|
||||
expect(width).to.equal(116)
|
||||
expect(height).to.equal(392)
|
||||
})
|
||||
|
||||
/*
|
||||
it('Should stack a part', () => {
|
||||
const part = {
|
||||
name: 'test',
|
||||
draft: (part) => {
|
||||
const { points, Point, paths, Path } = part.shorthand()
|
||||
points.from = new Point(123, 456)
|
||||
points.to = new Point(19, 76)
|
||||
paths.test = new Path().move(points.from).line(points.to)
|
||||
return aprt
|
||||
}
|
||||
}
|
||||
const design = new Design({ parts: [ part ]})
|
||||
const pattern = new design({ paperless: true })
|
||||
pattern.draft()
|
||||
pattern.parts.test.home()
|
||||
console.log(pattern.parts.test.attributes)
|
||||
expect(part.attributes.get('transform')).to.equal('translate(-17, -74)')
|
||||
})
|
||||
|
||||
it('Should only stack a part if needed', () => {
|
||||
let pattern = new Pattern()
|
||||
pattern.settings.mode = 'draft'
|
||||
let part = new pattern.Part()
|
||||
let short = part.shorthand()
|
||||
part.points.from = new short.Point(2, 2)
|
||||
part.points.to = new short.Point(19, 76)
|
||||
part.paths.test = new short.Path().move(part.points.from).line(part.points.to)
|
||||
part.home()
|
||||
expect(part.attributes.get('transform')).to.equal(false)
|
||||
part.home()
|
||||
expect(part.attributes.get('transform')).to.equal(false)
|
||||
})
|
||||
it('Should run hooks', () => {
|
||||
let count = 0
|
||||
const design = new Design()
|
||||
const pattern = new design({ paperless: true })
|
||||
const part = pattern.__createPartWithContext()
|
||||
part.hooks.preDraft = [
|
||||
{
|
||||
method: function () {
|
||||
count++
|
||||
},
|
||||
},
|
||||
]
|
||||
part.runHooks('preDraft')
|
||||
expect(count).to.equal(1)
|
||||
})
|
||||
*/
|
||||
|
||||
it('Units closure should log a warning when passing a non-number', () => {
|
||||
const part = {
|
||||
name: 'test',
|
||||
|
@ -213,79 +173,169 @@ describe('Part', () => {
|
|||
},
|
||||
}
|
||||
const design = new Design({ parts: [part] })
|
||||
const pattern = new design()
|
||||
// Let's also cover the branch where complete is false
|
||||
const pattern = new design({ complete: false} )
|
||||
pattern.draft()
|
||||
expect(pattern.stores[0].logs.warning.length).to.equal(1)
|
||||
expect(pattern.stores[0].logs.warning[0]).to.equal(
|
||||
'Calling `units(value)` but `value` is not a number (`string`)'
|
||||
)
|
||||
})
|
||||
/*
|
||||
describe('isEmpty', () => {
|
||||
it('Should return true if the part has no paths or snippets', () => {
|
||||
const design = new Design()
|
||||
|
||||
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()
|
||||
const part = pattern.__createPartWithContext()
|
||||
expect(part.isEmpty()).to.be.true
|
||||
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('Should return true if the part has paths but they have no length', () => {
|
||||
const design = new Design()
|
||||
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()
|
||||
const part = pattern.__createPartWithContext()
|
||||
const { Path, paths } = part.shorthand()
|
||||
paths.seam = new Path()
|
||||
expect(part.isEmpty()).to.be.true
|
||||
pattern.draft()
|
||||
expect(pattern.settings[0].measurements.head).to.equal(120)
|
||||
})
|
||||
|
||||
it("Should return true if the part has paths but they don't render", () => {
|
||||
const design = new Design()
|
||||
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()
|
||||
const part = pattern.__createPartWithContext()
|
||||
const { Path, paths, Point } = part.shorthand()
|
||||
paths.seam = new Path().move(new Point(0, 0)).line(new Point(2, 3)).setRender(false)
|
||||
expect(part.isEmpty()).to.be.true
|
||||
pattern.draft()
|
||||
expect(pattern.settings[0].options.test).to.equal(120)
|
||||
})
|
||||
|
||||
it('Should return false if the part has a path with length', () => {
|
||||
const design = new Design()
|
||||
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()
|
||||
const part = pattern.__createPartWithContext()
|
||||
const { Path, paths, Point } = part.shorthand()
|
||||
paths.seam = new Path().move(new Point(0, 0)).line(new Point(2, 3))
|
||||
|
||||
expect(part.isEmpty()).to.be.false
|
||||
pattern.draft()
|
||||
expect(pattern.settings[0].absoluteOptions.test).to.equal(120)
|
||||
})
|
||||
|
||||
it('Should return false if the part has a snippet', () => {
|
||||
const design = new Design()
|
||||
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 || true) return part
|
||||
},
|
||||
}
|
||||
const design = new Design({ parts: [part] })
|
||||
const pattern = new design()
|
||||
const part = pattern.__createPartWithContext()
|
||||
const { Point, snippets, Snippet } = part.shorthand()
|
||||
snippets.test = new Snippet('test', new Point(0, 0))
|
||||
|
||||
expect(part.isEmpty()).to.be.false
|
||||
pattern.draft()
|
||||
expect(pattern.stores[0].logs.warning.length).to.equal(1)
|
||||
expect(pattern.stores[0].logs.warning[0]).to.equal('Tried to access `options.test` but it is `undefined`')
|
||||
})
|
||||
|
||||
it('Should return false if the part has a point that has text', () => {
|
||||
const design = new Design()
|
||||
it('Accessing unknown absoluteOption should log a warning', () => {
|
||||
const part = {
|
||||
name: 'test',
|
||||
draft: ({ absoluteOptions, part }) => {
|
||||
if (absoluteOptions.test || true) return part
|
||||
},
|
||||
}
|
||||
const design = new Design({ parts: [part] })
|
||||
const pattern = new design()
|
||||
const part = pattern.__createPartWithContext()
|
||||
const { Point, points } = part.shorthand()
|
||||
points.test = new Point(0, 0)
|
||||
points.test.attributes.set('data-text', 'text')
|
||||
expect(part.isEmpty()).to.be.false
|
||||
pattern.draft()
|
||||
expect(pattern.stores[0].logs.warning.length).to.equal(1)
|
||||
expect(pattern.stores[0].logs.warning[0]).to.equal('Tried to access `absoluteOptions.test` but it is `undefined`')
|
||||
})
|
||||
|
||||
it('Should return false if the part has a point that has a circle', () => {
|
||||
const design = new Design()
|
||||
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()
|
||||
const part = pattern.__createPartWithContext()
|
||||
const { Point, points } = part.shorthand()
|
||||
points.test = new Point(0, 0)
|
||||
points.test.attributes.set('data-circle', 10)
|
||||
expect(part.isEmpty()).to.be.false
|
||||
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)
|
||||
})
|
||||
})
|
||||
*/
|
||||
})
|
||||
|
|
|
@ -57,6 +57,63 @@ describe('Path', () => {
|
|||
expect(round(pattern.parts[0].test.paths.test.ops[2].cp1.y)).to.equal(10)
|
||||
})
|
||||
|
||||
it('Should log a warning when passing a non-Point to smurve()', () => {
|
||||
const part = {
|
||||
name: 'test',
|
||||
draft: ({ Point, points, Path, paths, part }) => {
|
||||
points.from = new Point(10, 20)
|
||||
points.cp1 = new Point(40, 10)
|
||||
points.cp2 = new Point(60, 30)
|
||||
points.to = new Point(90, 20)
|
||||
|
||||
paths.test = new Path()
|
||||
.move(points.from)
|
||||
.curve(points.cp1, points.cp2, points.to)
|
||||
.smurve('hi', 'there')
|
||||
|
||||
return part
|
||||
},
|
||||
}
|
||||
const design = new Design({ parts: [part] })
|
||||
const pattern = new design()
|
||||
pattern.draft()
|
||||
expect(pattern.stores[0].logs.warning.length).to.equal(2)
|
||||
expect(pattern.stores[0].logs.warning[0]).to.equal('Called `Path.smurve(cp2, to)` but `to` is not a `Point` object')
|
||||
})
|
||||
|
||||
it('Should log a warning when passing a non-Point to smurve_()', () => {
|
||||
const part = {
|
||||
name: 'test',
|
||||
draft: ({ Point, Path, paths, part }) => {
|
||||
paths.test = new Path().smurve_('hi')
|
||||
|
||||
return part
|
||||
},
|
||||
}
|
||||
const design = new Design({ parts: [part] })
|
||||
const pattern = new design()
|
||||
pattern.draft()
|
||||
expect(pattern.stores[0].logs.warning.length).to.equal(1)
|
||||
expect(pattern.stores[0].logs.warning[0]).to.equal('Called `Path.smurve_(to)` but `to` is not a `Point` object')
|
||||
})
|
||||
|
||||
it('Should log a warning when passing a non-Path to the paths proxy', () => {
|
||||
const part = {
|
||||
name: 'test',
|
||||
draft: ({ paths, part }) => {
|
||||
paths.test = 'Wriing code can get very lonely sometimes'
|
||||
|
||||
return part
|
||||
},
|
||||
}
|
||||
const design = new Design({ parts: [part] })
|
||||
const pattern = new design()
|
||||
pattern.draft()
|
||||
expect(pattern.stores[0].logs.warning.length).to.equal(2)
|
||||
expect(pattern.stores[0].logs.warning[0]).to.equal('`paths.test` was set with a value that is not a `Path` object')
|
||||
expect(pattern.stores[0].logs.warning[1]).to.equal('Could not set `name` property on `paths.test`')
|
||||
})
|
||||
|
||||
it('Should offset a line', () => {
|
||||
const part = {
|
||||
name: 'test',
|
||||
|
@ -161,13 +218,30 @@ describe('Path', () => {
|
|||
paths.curve = new Path()
|
||||
.move(new Point(0, 0))
|
||||
.curve(new Point(0, 50), new Point(100, 50), new Point(100, 0))
|
||||
.close()
|
||||
return part
|
||||
},
|
||||
}
|
||||
const design = new Design({ parts: [part] })
|
||||
const pattern = new design()
|
||||
pattern.draft().render()
|
||||
expect(round(pattern.parts[0].test.paths.curve.roughLength())).to.equal(200)
|
||||
expect(round(pattern.parts[0].test.paths.curve.roughLength())).to.equal(300)
|
||||
})
|
||||
|
||||
it('Should return the rough length of a line', () => {
|
||||
const part = {
|
||||
name: 'test',
|
||||
draft: ({ paths, Path, Point, part }) => {
|
||||
paths.line = new Path()
|
||||
.move(new Point(0, 0))
|
||||
.line(new Point(0, 50))
|
||||
return part
|
||||
},
|
||||
}
|
||||
const design = new Design({ parts: [part] })
|
||||
const pattern = new design()
|
||||
pattern.draft().render()
|
||||
expect(round(pattern.parts[0].test.paths.line.roughLength())).to.equal(50)
|
||||
})
|
||||
|
||||
it('Should return the path start point', () => {
|
||||
|
@ -615,6 +689,32 @@ describe('Path', () => {
|
|||
expect(round(line.to.y)).to.equal(46.98)
|
||||
})
|
||||
|
||||
it('Should split a path on a line joint', () => {
|
||||
const a = new Point(45, 60)
|
||||
const b = new Point(10, 30)
|
||||
const c = new Point(90, 30)
|
||||
const test = new Path().move(a).line(b).line(c)
|
||||
|
||||
let halves = test.split(b)
|
||||
expect(halves[0].ops[1].to.x).to.equal(10)
|
||||
expect(halves[0].ops[1].to.y).to.equal(30)
|
||||
expect(halves[1].ops[0].to.x).to.equal(10)
|
||||
expect(halves[1].ops[0].to.y).to.equal(30)
|
||||
})
|
||||
|
||||
it('Should split a path on a curve joint', () => {
|
||||
const a = new Point(45, 60)
|
||||
const b = new Point(10, 30)
|
||||
const c = new Point(90, 30)
|
||||
const test = new Path().move(a)._curve(b,b)._curve(c,c)
|
||||
|
||||
let halves = test.split(b)
|
||||
expect(halves[0].ops[1].to.x).to.equal(10)
|
||||
expect(halves[0].ops[1].to.y).to.equal(30)
|
||||
expect(halves[1].ops[0].to.x).to.equal(10)
|
||||
expect(halves[1].ops[0].to.y).to.equal(30)
|
||||
})
|
||||
|
||||
it('Should trim a path when lines overlap', () => {
|
||||
const A = new Point(0, 0)
|
||||
const B = new Point(100, 100)
|
||||
|
@ -684,6 +784,16 @@ describe('Path', () => {
|
|||
expect(test.ops[1].to.y).to.equal(20)
|
||||
})
|
||||
|
||||
it('Calling translate with non-numbers should generate a warning', () => {
|
||||
const log = []
|
||||
const p = new Path()
|
||||
p.log = { warning: msg => log.push(msg) }
|
||||
p.translate('a', 'b')
|
||||
expect(log.length).to.equal(2)
|
||||
expect(log[0]).to.equal('Called `Path.translate(x, y)` but `x` is not a number')
|
||||
expect(log[1]).to.equal('Called `Path.translate(x, y)` but `y` is not a number')
|
||||
})
|
||||
|
||||
it('Should add a path attribute', () => {
|
||||
const line = new Path()
|
||||
.move(new Point(0, 0))
|
||||
|
@ -1039,7 +1149,7 @@ describe('Path', () => {
|
|||
it('Should log a warning when splitting a path on a non-point', () => {
|
||||
const part = {
|
||||
name: 'test',
|
||||
draft: ({ Path, Point, points }) => {
|
||||
draft: ({ Path, Point, points, part}) => {
|
||||
points.a = new Path().move(new Point(0, 0)).line(new Point(0, 40)).split()
|
||||
return part
|
||||
},
|
||||
|
@ -1051,4 +1161,31 @@ describe('Path', () => {
|
|||
'Called `Path.split(point)` but `point` is not a `Point` object'
|
||||
)
|
||||
})
|
||||
|
||||
it('Should add a class', () => {
|
||||
const part = {
|
||||
name: 'test',
|
||||
draft: ({ Path, paths, Point, points, part }) => {
|
||||
paths.line = new Path()
|
||||
.move(new Point(0,0))
|
||||
.line(new Point(10,10))
|
||||
.addClass('fabric banana')
|
||||
return part
|
||||
},
|
||||
}
|
||||
const design = new Design({ parts: [part] })
|
||||
const pattern = new design()
|
||||
pattern.draft()
|
||||
expect(pattern.parts[0].test.paths.line.attributes.get('class')).to.equal('fabric banana')
|
||||
})
|
||||
|
||||
it('Should (un)hide a path with hide()/unhide()', () => {
|
||||
const path = new Path()
|
||||
expect(path.hidden).to.equal(false)
|
||||
path.hide()
|
||||
expect(path.hidden).to.equal(true)
|
||||
path.unhide()
|
||||
expect(path.hidden).to.equal(false)
|
||||
})
|
||||
|
||||
})
|
||||
|
|
|
@ -48,7 +48,7 @@ describe('Pattern', () => {
|
|||
name: 'test.partB',
|
||||
measurements: ['head', 'knee'],
|
||||
optionalMeasurements: ['knee'],
|
||||
after: partA,
|
||||
after: [ partA ],
|
||||
plugins: [
|
||||
{
|
||||
name: 'testPlugin',
|
||||
|
|
|
@ -580,6 +580,51 @@ describe('Pattern', () => {
|
|||
expect(pattern.hooks.preRender.length).to.equal(1)
|
||||
})
|
||||
|
||||
it('Load conditional plugins that are also passing data', () => {
|
||||
const plugin1 = {
|
||||
name: 'example1',
|
||||
version: 1,
|
||||
hooks: {
|
||||
preRender: function (svg) {
|
||||
svg.attributes.add('freesewing:plugin-example1', 1)
|
||||
},
|
||||
},
|
||||
}
|
||||
const plugin2 = {
|
||||
name: 'example2',
|
||||
version: 2,
|
||||
hooks: {
|
||||
preRender: function (svg) {
|
||||
svg.attributes.add('freesewing:plugin-example2', 1)
|
||||
},
|
||||
},
|
||||
}
|
||||
const condition1 = () => true
|
||||
const condition2 = () => false
|
||||
const part1 = {
|
||||
name: 'part1',
|
||||
plugins: [
|
||||
[plugin1, {} ],
|
||||
{ plugin: plugin2, condition: condition1 }
|
||||
],
|
||||
draft: ({ part }) => part
|
||||
}
|
||||
const part2 = {
|
||||
name: 'part2',
|
||||
plugins: [
|
||||
plugin2,
|
||||
{ plugin: plugin2, condition: condition2 },
|
||||
],
|
||||
draft: ({ part }) => part
|
||||
}
|
||||
const design = new Design({
|
||||
parts: [ part1, part2 ]
|
||||
})
|
||||
const pattern = new design()
|
||||
pattern.init()
|
||||
expect(pattern.hooks.preRender.length).to.equal(2)
|
||||
})
|
||||
|
||||
it('Pattern.init() should register a hook via on', () => {
|
||||
const Pattern = new Design()
|
||||
const pattern = new Pattern()
|
||||
|
|
|
@ -1,43 +1,45 @@
|
|||
import chai from 'chai'
|
||||
import chaiString from 'chai-string'
|
||||
//import { Design, Pattern } from '../src/index.mjs'
|
||||
//import pkg from '../package.json' assert { type: 'json' }
|
||||
//import render from './fixtures/render.mjs'
|
||||
import { Svg } from '../src/svg.mjs'
|
||||
import { Design, Pattern, Attributes } from '../src/index.mjs'
|
||||
import { version } from '../data.mjs'
|
||||
import render from './fixtures/render.mjs'
|
||||
|
||||
chai.use(chaiString)
|
||||
const expect = chai.expect
|
||||
//const { version } = pkg
|
||||
|
||||
it('FIXME: Write some tests here', () => {
|
||||
expect(true).to.equal(true)
|
||||
})
|
||||
|
||||
/*
|
||||
describe('Svg', () => {
|
||||
const getPattern = (settings={}, draft=false) => {
|
||||
const part = {
|
||||
name: 'test',
|
||||
draft: part => {
|
||||
const { paths, Path, Point, points } = part.shorthand()
|
||||
points.a = new Path()
|
||||
draft: draft
|
||||
? draft
|
||||
: ({ paths, Path, Point, part }) => {
|
||||
paths.test = new Path()
|
||||
.move(new Point(0, 0))
|
||||
.line(new Point(0, 40))
|
||||
.shiftFractionAlong()
|
||||
.line(new Point(40, 20))
|
||||
.curve(new Point(12, 34), new Point(56, 78), new Point(21, 32))
|
||||
.close()
|
||||
.attr('id', 'something')
|
||||
.attr('class', 'freesewing')
|
||||
return part
|
||||
}
|
||||
}
|
||||
const design = new Design({ parts: [ part ] })
|
||||
const pattern = new design()
|
||||
const Pattern = new Design({ parts: [ part ] })
|
||||
|
||||
return new Pattern(settings)
|
||||
}
|
||||
|
||||
const trim = svg => svg.split("\n").map(line => line.trim()).join('')
|
||||
|
||||
describe('Svg', () => {
|
||||
|
||||
it('Svg constructor should initialize object', () => {
|
||||
pattern.render()
|
||||
let svg = pattern.svg
|
||||
expect(svg.openGroups).to.eql([])
|
||||
const svg = new Svg()
|
||||
expect(svg.attributes instanceof Attributes).to.equal(true)
|
||||
expect(svg.freeId).to.equal(0)
|
||||
expect(svg.body).to.equal('')
|
||||
expect(svg.style).to.equal('')
|
||||
expect(svg.script).to.equal('')
|
||||
expect(svg.defs).to.equal('')
|
||||
expect(svg.pattern).to.eql(pattern)
|
||||
expect(svg.prefix).to.equal('<?xml version="1.0" encoding="UTF-8" standalone="no"?>')
|
||||
expect(svg.attributes.get('xmlns')).to.equal('http://www.w3.org/2000/svg')
|
||||
expect(svg.attributes.get('xmlns:svg')).to.equal('http://www.w3.org/2000/svg')
|
||||
|
@ -48,47 +50,233 @@ describe('Svg', () => {
|
|||
expect(svg.attributes.get('freesewing')).to.equal(version)
|
||||
})
|
||||
|
||||
it('Should render Svg boilerplate', () => {
|
||||
let pattern = new Pattern()
|
||||
expect(pattern.render()).to.equalIgnoreSpaces(render.boilerplate)
|
||||
it('Svg constructor should use the object we pass it as pattern', () => {
|
||||
const obj = {}
|
||||
const svg = new Svg(obj)
|
||||
expect(svg.pattern).to.eql(obj)
|
||||
})
|
||||
|
||||
it('Should render language attribute', () => {
|
||||
let pattern = new Pattern()
|
||||
pattern.settings.locale = 'nl'
|
||||
expect(pattern.render()).to.equalIgnoreSpaces(render.boilerplateNl)
|
||||
|
||||
it('Should render a pattern as SVG', () => {
|
||||
const pattern = getPattern()
|
||||
const svg = pattern.draft().render()
|
||||
expect(trim(svg)).to.equalIgnoreSpaces(render.boilerplate)
|
||||
})
|
||||
|
||||
it('Should render Svg boilerplate for embedding', () => {
|
||||
let pattern = new Pattern()
|
||||
pattern.settings.embed = true
|
||||
expect(pattern.render()).to.equalIgnoreSpaces(render.embed)
|
||||
it('Should render the SVG language attribute', () => {
|
||||
const pattern = getPattern({ locale: 'nl' })
|
||||
const svg = pattern.draft().render()
|
||||
expect(svg).to.equalIgnoreSpaces(render.boilerplateNl)
|
||||
})
|
||||
|
||||
it('Should render Svg part boilerplate', () => {
|
||||
let pattern = new Pattern()
|
||||
pattern.render()
|
||||
pattern.parts.test = new pattern.Part()
|
||||
expect(pattern.render()).to.equalIgnoreSpaces(render.part)
|
||||
pattern.parts.test.render = false
|
||||
expect(pattern.render()).to.equalIgnoreSpaces(render.boilerplate)
|
||||
it('Should render the SVG viewBox attribute for embedding', () => {
|
||||
const pattern = getPattern({ embed: true })
|
||||
const svg = pattern.draft().render()
|
||||
expect(trim(svg)).to.equalIgnoreSpaces(render.embed)
|
||||
})
|
||||
|
||||
it('Should render Svg path', () => {
|
||||
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))
|
||||
it('Should render a stack as SVG', () => {
|
||||
const pattern = getPattern()
|
||||
pattern.draft().render()
|
||||
const svg = pattern.svg.__renderStack(pattern.stacks.test)
|
||||
expect(trim(svg)).to.equalIgnoreSpaces(render.part)
|
||||
})
|
||||
|
||||
it('Should render a part as SVG', () => {
|
||||
const pattern = getPattern()
|
||||
pattern.draft().render()
|
||||
const svg = pattern.svg.__renderPart(pattern.parts[0].test)
|
||||
expect(trim(svg)).to.equalIgnoreSpaces(render.part)
|
||||
})
|
||||
|
||||
it('Should render a path as SVG', () => {
|
||||
const pattern = getPattern()
|
||||
pattern.draft().render()
|
||||
const svg = pattern.svg.__renderPath(pattern.parts[0].test.paths.test)
|
||||
expect(trim(svg)).to.equalIgnoreSpaces(render.path)
|
||||
})
|
||||
|
||||
it('Should render Svg text', () => {
|
||||
const pattern = getPattern({}, ({ points, Point, part }) => {
|
||||
points.test = new Point(20, 20)
|
||||
.attr('data-text', 'This is a test')
|
||||
.attr('data-text-class', 'text-lg')
|
||||
points.other = new Point(10, 10).attr('data-text', '')
|
||||
|
||||
return part
|
||||
})
|
||||
pattern.draft().render()
|
||||
const svg = pattern.svg.__renderPart(pattern.parts[0].test)
|
||||
expect(trim(svg)).to.equalIgnoreSpaces(render.text)
|
||||
})
|
||||
|
||||
it('Should render Svg multi-line text', () => {
|
||||
const pattern = getPattern({}, ({ points, Point, part }) => {
|
||||
points.test = new Point(20, 20)
|
||||
.attr('data-text', 'This is a test\nwith text on\nmultiple lines')
|
||||
.attr('data-text-class', 'text-lg')
|
||||
.attr('data-text-lineheight', 8)
|
||||
|
||||
return part
|
||||
})
|
||||
pattern.draft().render()
|
||||
const svg = pattern.svg.__renderPart(pattern.parts[0].test)
|
||||
expect(trim(svg)).to.equalIgnoreSpaces(render.multiText)
|
||||
})
|
||||
|
||||
it('Should render Svg multi-line text with default lineheight', () => {
|
||||
const pattern = getPattern({}, ({ points, Point, part }) => {
|
||||
points.test = new Point(20, 20)
|
||||
.attr('data-text', 'This is a test\nwith text on\nmultiple lines')
|
||||
.attr('data-text-class', 'text-lg')
|
||||
|
||||
return part
|
||||
})
|
||||
pattern.draft().render()
|
||||
const svg = pattern.svg.__renderPart(pattern.parts[0].test)
|
||||
expect(trim(svg)).to.equalIgnoreSpaces(render.multiTextDflt)
|
||||
})
|
||||
|
||||
|
||||
it('Should render Svg text on path', () => {
|
||||
const pattern = getPattern({}, ({ paths, Path, Point, part }) => {
|
||||
paths.test = new Path()
|
||||
.move(new Point(0, 0))
|
||||
.line(new Point(40, 20))
|
||||
.curve(new Point(12, 34), new Point(56, 78), new Point(21, 32))
|
||||
.close()
|
||||
.attr('id', 'something')
|
||||
.attr('data-text', 'This is another test')
|
||||
.attr('data-text-class', 'text-sm')
|
||||
.attr('class', 'freesewing')
|
||||
expect(pattern.render()).to.equalIgnoreSpaces(render.path)
|
||||
|
||||
return part
|
||||
})
|
||||
it('Should not render Svg path when render property is false', () => {
|
||||
pattern.draft().render()
|
||||
const svg = pattern.svg.__renderPart(pattern.parts[0].test)
|
||||
expect(trim(svg)).to.equalIgnoreSpaces(render.textOnPath)
|
||||
})
|
||||
|
||||
it('Should render Svg text on path, center aligned', () => {
|
||||
const pattern = getPattern({}, ({ paths, Path, Point, part }) => {
|
||||
paths.test = new Path()
|
||||
.attr('data-text', 'This is another test')
|
||||
.attr('data-text-class', 'center')
|
||||
.attr('class', 'freesewing')
|
||||
|
||||
return part
|
||||
})
|
||||
pattern.draft().render()
|
||||
const svg = pattern.svg.__renderPart(pattern.parts[0].test)
|
||||
expect(trim(svg)).to.equalIgnoreSpaces(render.textOnPathCenter)
|
||||
})
|
||||
|
||||
it('Should render Svg text on path, right aligned', () => {
|
||||
const pattern = getPattern({}, ({ paths, Path, Point, part }) => {
|
||||
paths.test = new Path()
|
||||
.attr('data-text', 'This is another test')
|
||||
.attr('data-text-class', 'right')
|
||||
.attr('class', 'freesewing')
|
||||
|
||||
return part
|
||||
})
|
||||
pattern.draft().render()
|
||||
const svg = pattern.svg.__renderPart(pattern.parts[0].test)
|
||||
expect(trim(svg)).to.equalIgnoreSpaces(render.textOnPathRight)
|
||||
})
|
||||
|
||||
it('Should render an Svg circle', () => {
|
||||
const pattern = getPattern({}, ({ points, Point, part }) => {
|
||||
points.test = new Point(20, 20).attr('data-circle', '50')
|
||||
|
||||
return part
|
||||
})
|
||||
pattern.draft().render()
|
||||
const svg = pattern.svg.__renderPart(pattern.parts[0].test)
|
||||
expect(trim(svg)).to.equalIgnoreSpaces(render.circle)
|
||||
})
|
||||
|
||||
it('Should render an Svg snippet', () => {
|
||||
const pattern = getPattern({}, ({ snippets, Snippet, Point, part }) => {
|
||||
snippets.test = new Snippet('test', new Point(20, 20), 'This is a snippet')
|
||||
|
||||
return part
|
||||
})
|
||||
pattern.draft().render()
|
||||
const svg = pattern.svg.__renderPart(pattern.parts[0].test)
|
||||
expect(trim(svg)).to.equalIgnoreSpaces(render.snippet)
|
||||
})
|
||||
|
||||
it('Should render a rotated Svg snippet', () => {
|
||||
const pattern = getPattern({}, ({ snippets, Snippet, Point, part }) => {
|
||||
snippets.test = new Snippet('test', new Point(20, 20), 'This is a snippet')
|
||||
.attr( 'data-rotate', 90)
|
||||
|
||||
return part
|
||||
})
|
||||
pattern.draft().render()
|
||||
const svg = pattern.svg.__renderPart(pattern.parts[0].test)
|
||||
expect(trim(svg)).to.equalIgnoreSpaces(render.rotatedSnippet)
|
||||
})
|
||||
|
||||
it('Should replaced double quotes in Svg text', () => {
|
||||
const svg = new Svg()
|
||||
expect(svg.__escapeText('This is a "test" message')).to.equal(
|
||||
'This is a “test“ message'
|
||||
)
|
||||
})
|
||||
|
||||
it('Should scale an Svg snippet', () => {
|
||||
const pattern = getPattern({}, ({ snippets, Snippet, Point, part }) => {
|
||||
snippets.test = new Snippet('test', new Point(20, 20), 'This is a snippet')
|
||||
.attr( 'data-scale', 2)
|
||||
|
||||
return part
|
||||
})
|
||||
pattern.draft().render()
|
||||
const svg = pattern.svg.__renderPart(pattern.parts[0].test)
|
||||
expect(trim(svg)).to.equalIgnoreSpaces(render.scaledSnippet)
|
||||
})
|
||||
|
||||
it('Should run preRender hook', () => {
|
||||
const pattern = getPattern()
|
||||
pattern.on('preRender', (svg) => {
|
||||
svg.attributes.set('data-hook', 'preRender')
|
||||
})
|
||||
pattern.draft().render()
|
||||
expect(pattern.svg.attributes.get('data-hook')).to.equal('preRender')
|
||||
})
|
||||
|
||||
it('Should run insertText hook', () => {
|
||||
const pattern = getPattern({}, ({ points, Point, part }) => {
|
||||
points.test = new Point(20, 20)
|
||||
.attr('data-text', 'This is a test')
|
||||
.attr('data-text-class', 'text-lg')
|
||||
|
||||
return part
|
||||
})
|
||||
pattern.on('insertText', (locale, text) => {
|
||||
return text.toUpperCase()
|
||||
})
|
||||
pattern.draft()
|
||||
expect(pattern.render()).to.contain('THIS IS A TEST')
|
||||
})
|
||||
|
||||
it('Should run postRender hook', () => {
|
||||
const pattern = getPattern()
|
||||
pattern.on('postRender', (svg) => {
|
||||
svg.svg = 'test'
|
||||
})
|
||||
expect(pattern.render()).to.equal('test')
|
||||
})
|
||||
|
||||
it('Should tab in and out', () => {
|
||||
const svg = new Svg()
|
||||
svg.tabs = 2
|
||||
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()
|
||||
|
@ -103,185 +291,5 @@ describe('Svg', () => {
|
|||
p.paths.test.render = false
|
||||
expect(pattern.render()).to.equalIgnoreSpaces(render.part)
|
||||
})
|
||||
|
||||
it('Should render Svg text', () => {
|
||||
let pattern = new Pattern()
|
||||
pattern.render()
|
||||
pattern.parts.test = new pattern.Part()
|
||||
let p = pattern.parts.test
|
||||
p.points.test = new p.Point(20, 20)
|
||||
.attr('data-text', 'This is a test')
|
||||
.attr('data-text-class', 'text-lg')
|
||||
p.points.other = new p.Point(10, 10).attr('data-text', '')
|
||||
expect(pattern.render()).to.equalIgnoreSpaces(render.text)
|
||||
})
|
||||
|
||||
it('Should render Svg multi-line text', () => {
|
||||
let pattern = new Pattern()
|
||||
pattern.render()
|
||||
pattern.parts.test = new pattern.Part()
|
||||
let p = pattern.parts.test
|
||||
p.points.test = new p.Point(20, 20)
|
||||
.attr('data-text', 'This is a test\nwith text on\nmultiple lines')
|
||||
.attr('data-text-class', 'text-lg')
|
||||
.attr('data-text-lineheight', 8)
|
||||
expect(pattern.render()).to.equalIgnoreSpaces(render.multiText)
|
||||
})
|
||||
|
||||
it('Should render Svg multi-line text with default lineheight', () => {
|
||||
let pattern = new Pattern()
|
||||
pattern.render()
|
||||
pattern.parts.test = new pattern.Part()
|
||||
let p = pattern.parts.test
|
||||
p.points.test = new p.Point(20, 20)
|
||||
.attr('data-text', 'This is a test\nwith text on\nmultiple lines')
|
||||
.attr('data-text-class', 'text-lg')
|
||||
expect(pattern.render()).to.equalIgnoreSpaces(render.multiTextDflt)
|
||||
})
|
||||
|
||||
it('Should not render text when there is none', () => {
|
||||
let pattern = new Pattern()
|
||||
pattern.render()
|
||||
pattern.parts.test = new pattern.Part()
|
||||
let p = pattern.parts.test
|
||||
p.points.test = new p.Point(20, 20)
|
||||
expect(pattern.render()).to.equalIgnoreSpaces(render.part)
|
||||
})
|
||||
|
||||
it('Should render Svg text on path', () => {
|
||||
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('data-text', 'This is another test')
|
||||
.attr('data-text-class', 'text-sm')
|
||||
.attr('class', 'freesewing')
|
||||
expect(pattern.render()).to.equalIgnoreSpaces(render.textOnPath)
|
||||
})
|
||||
|
||||
it('Should render Svg text on path, center aligned', () => {
|
||||
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('data-text', 'This is another test')
|
||||
.attr('data-text-class', 'center')
|
||||
.attr('class', 'freesewing')
|
||||
expect(pattern.render()).to.equalIgnoreSpaces(render.textOnPathCenter)
|
||||
})
|
||||
|
||||
it('Should render Svg text on path, right aligned', () => {
|
||||
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('data-text', 'This is another test')
|
||||
.attr('data-text-class', 'right')
|
||||
.attr('class', 'freesewing')
|
||||
expect(pattern.render()).to.equalIgnoreSpaces(render.textOnPathRight)
|
||||
})
|
||||
|
||||
it('Should render an Svg circle', () => {
|
||||
let pattern = new Pattern()
|
||||
pattern.render()
|
||||
pattern.parts.test = new pattern.Part()
|
||||
let p = pattern.parts.test
|
||||
p.points.test = new p.Point(20, 20).attr('data-circle', '50')
|
||||
expect(pattern.render()).to.equalIgnoreSpaces(render.circle)
|
||||
})
|
||||
|
||||
it('Should render an Svg snippet', () => {
|
||||
let pattern = new Pattern()
|
||||
pattern.render()
|
||||
pattern.parts.test = new pattern.Part()
|
||||
let p = pattern.parts.test
|
||||
p.snippets.test = new p.Snippet('test', new p.Point(20, 20), 'This is a snippet')
|
||||
expect(pattern.render()).to.equalIgnoreSpaces(render.snippet)
|
||||
})
|
||||
|
||||
it('Should render a rotated Svg snippet', () => {
|
||||
let pattern = new Pattern()
|
||||
pattern.render()
|
||||
pattern.parts.test = new pattern.Part()
|
||||
let p = pattern.parts.test
|
||||
p.snippets.test = new p.Snippet('test', new p.Point(20, 20), 'This is a snippet').attr(
|
||||
'data-rotate',
|
||||
90
|
||||
)
|
||||
expect(pattern.render()).to.equalIgnoreSpaces(render.rotatedSnippet)
|
||||
})
|
||||
|
||||
it('Should replaced double quotes in Svg text', () => {
|
||||
const pattern = new Pattern()
|
||||
pattern.render()
|
||||
expect(pattern.svg.escapeText('This is a "test" message')).to.equal(
|
||||
'This is a “test“ message'
|
||||
)
|
||||
})
|
||||
|
||||
it('Should scale an Svg snippet', () => {
|
||||
let pattern = new Pattern()
|
||||
pattern.render()
|
||||
pattern.parts.test = new pattern.Part()
|
||||
let p = pattern.parts.test
|
||||
p.snippets.test = new p.Snippet('test', new p.Point(20, 20), 'This is a snippet').attr(
|
||||
'data-scale',
|
||||
2
|
||||
)
|
||||
expect(pattern.render()).to.contain('scale(2)')
|
||||
})
|
||||
|
||||
it('Should run preRender hook', () => {
|
||||
let pattern = new Pattern()
|
||||
pattern.on('preRender', (svg) => {
|
||||
svg.attributes.set('data-hook', 'preRender')
|
||||
})
|
||||
pattern.render()
|
||||
expect(pattern.svg.attributes.get('data-hook')).to.equal('preRender')
|
||||
})
|
||||
|
||||
it('Should run insertText hook', () => {
|
||||
let pattern = new Pattern()
|
||||
pattern.on('insertText', (locale, text) => {
|
||||
return text.toUpperCase()
|
||||
})
|
||||
pattern.parts.test = new pattern.Part()
|
||||
let p = pattern.parts.test
|
||||
p.points.test = new p.Point(20, 20)
|
||||
.attr('data-text', 'This is a test')
|
||||
.attr('data-text-class', 'text-lg')
|
||||
expect(pattern.render()).to.contain('THIS IS A TEST')
|
||||
})
|
||||
|
||||
it('Should run postRender hook', () => {
|
||||
let pattern = new Pattern()
|
||||
pattern.on('postRender', (svg) => {
|
||||
svg.svg = 'test'
|
||||
})
|
||||
expect(pattern.render()).to.equal('test')
|
||||
})
|
||||
|
||||
it('Should tab in and out', () => {
|
||||
let pattern = new Pattern()
|
||||
pattern.render()
|
||||
const svg = pattern.svg
|
||||
svg.tabs = 2
|
||||
expect(svg.tab()).to.equal(' ')
|
||||
})
|
||||
})
|
||||
*/
|
||||
})
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import chai from 'chai'
|
||||
import {
|
||||
Point,
|
||||
Design,
|
||||
capitalize,
|
||||
beamsIntersect,
|
||||
linesIntersect,
|
||||
|
@ -23,6 +24,7 @@ import {
|
|||
deg2rad,
|
||||
rad2deg,
|
||||
pctBasedOn,
|
||||
generateStackTransform,
|
||||
} from '../src/index.mjs'
|
||||
|
||||
const { expect } = chai
|
||||
|
@ -474,29 +476,20 @@ describe('Utils', () => {
|
|||
expect(result.toAbs(0.0123, { measurements })).to.equal(12.3)
|
||||
expect(result.fromAbs(12.3, { measurements })).to.equal(0.0123)
|
||||
})
|
||||
/*
|
||||
it('Should generate a part transform', () => {
|
||||
const part = {
|
||||
it('Should generate a stack transform', () => {
|
||||
const test = {
|
||||
name: 'test',
|
||||
draft: part => {
|
||||
const { points, Point, paths, Path } = part.shorthand()
|
||||
draft: ({ points, Point, paths, Path, part }) => {
|
||||
points.from = new Point(2, 2)
|
||||
points.to = new Point(19, 76)
|
||||
paths.test = new Path().move(points.from).line(points.to)
|
||||
return part
|
||||
}
|
||||
}
|
||||
const design = new Design({ parts: [ part ]})
|
||||
const design = new Design({ parts: [ test ]})
|
||||
const pattern = new design()
|
||||
pattern.draft().render()
|
||||
const transform = generatePartTransform(30, 60, 90, true, true, pattern.__parts.test)
|
||||
expect(transform.transform).to.equal(
|
||||
`translate(${30 + part.topLeft.x + part.bottomRight.x} ${
|
||||
60 + part.topLeft.y + part.bottomRight.y
|
||||
}) scale(-1 -1) rotate(90 ${part.topLeft.x + part.width / 2} ${
|
||||
part.topLeft.y + part.height / 2
|
||||
})`
|
||||
)
|
||||
const props = pattern.draft().getRenderProps()
|
||||
const transform = generateStackTransform(30, 60, 90, true, true, props.stacks.test)
|
||||
expect(transform.transform).to.equal('translate(51 138) scale(-1 -1) rotate(90 10.5 39)')
|
||||
})
|
||||
*/
|
||||
})
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue