wip(core): Ensure imutable design parts and options
This commit is contained in:
parent
485492e452
commit
12c5c6a3f8
11 changed files with 298 additions and 233 deletions
|
@ -44,6 +44,24 @@ export function Part() {
|
||||||
// PUBLIC METHODS //
|
// PUBLIC METHODS //
|
||||||
//////////////////////////////////////////////
|
//////////////////////////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a part as an object suitable for inclusion in renderprops
|
||||||
|
*
|
||||||
|
* @return {object} part - A plain object representing the part
|
||||||
|
*/
|
||||||
|
Part.prototype.asProps = function () {
|
||||||
|
return {
|
||||||
|
paths: this.paths,
|
||||||
|
points: this.points,
|
||||||
|
snippets: this.snippets,
|
||||||
|
attributes: this.attributes,
|
||||||
|
height: this.height,
|
||||||
|
width: this.width,
|
||||||
|
bottomRight: this.bottomRight,
|
||||||
|
topLeft: this.topLeft,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an attribute in a chainable way
|
* Adds an attribute in a chainable way
|
||||||
*
|
*
|
||||||
|
@ -106,6 +124,7 @@ Part.prototype.shorthand = function () {
|
||||||
const sa = this.context.settings?.complete ? this.context.settings?.sa || 0 : 0
|
const sa = this.context.settings?.complete ? this.context.settings?.sa || 0 : 0
|
||||||
const shorthand = {
|
const shorthand = {
|
||||||
complete,
|
complete,
|
||||||
|
context: this.context,
|
||||||
getId: this.getId,
|
getId: this.getId,
|
||||||
hide: this.hide,
|
hide: this.hide,
|
||||||
log: this.context.store.log,
|
log: this.context.store.log,
|
||||||
|
|
|
@ -26,7 +26,6 @@ import { __loadPatternDefaults } from './config.mjs'
|
||||||
export function Pattern(designConfig) {
|
export function Pattern(designConfig) {
|
||||||
// Non-enumerable properties
|
// Non-enumerable properties
|
||||||
__addNonEnumProp(this, 'plugins', {})
|
__addNonEnumProp(this, 'plugins', {})
|
||||||
__addNonEnumProp(this, 'parts', [{}])
|
|
||||||
__addNonEnumProp(this, 'width', 0)
|
__addNonEnumProp(this, 'width', 0)
|
||||||
__addNonEnumProp(this, 'height', 0)
|
__addNonEnumProp(this, 'height', 0)
|
||||||
__addNonEnumProp(this, 'autoLayout', { stacks: {} })
|
__addNonEnumProp(this, 'autoLayout', { stacks: {} })
|
||||||
|
@ -37,17 +36,24 @@ export function Pattern(designConfig) {
|
||||||
__addNonEnumProp(this, 'Snippet', Snippet)
|
__addNonEnumProp(this, 'Snippet', Snippet)
|
||||||
__addNonEnumProp(this, 'Attributes', Attributes)
|
__addNonEnumProp(this, 'Attributes', Attributes)
|
||||||
__addNonEnumProp(this, 'macros', {})
|
__addNonEnumProp(this, 'macros', {})
|
||||||
__addNonEnumProp(this, '__parts', {})
|
__addNonEnumProp(this, '__designParts', {})
|
||||||
__addNonEnumProp(this, '__inject', {})
|
__addNonEnumProp(this, '__inject', {})
|
||||||
__addNonEnumProp(this, '__dependencies', {})
|
__addNonEnumProp(this, '__dependencies', {})
|
||||||
__addNonEnumProp(this, '__resolvedDependencies', {})
|
__addNonEnumProp(this, '__resolvedDependencies', {})
|
||||||
|
__addNonEnumProp(this, '__resolvedParts', [])
|
||||||
|
__addNonEnumProp(this, '__storeMethods', new Set())
|
||||||
|
__addNonEnumProp(this, '__mutated', {
|
||||||
|
optionDistance: {},
|
||||||
|
partDistance: {},
|
||||||
|
partHide: {},
|
||||||
|
partHideAll: {},
|
||||||
|
})
|
||||||
__addNonEnumProp(this, '__draftOrder', [])
|
__addNonEnumProp(this, '__draftOrder', [])
|
||||||
__addNonEnumProp(this, '__hide', {})
|
__addNonEnumProp(this, '__hide', {})
|
||||||
|
|
||||||
// Enumerable properties
|
// Enumerable properties
|
||||||
this.designConfig = designConfig // The design configuration (unresolved)
|
this.designConfig = designConfig // The design configuration (unresolved)
|
||||||
this.config = {} // Will hold the resolved pattern after calling __init()
|
this.config = {} // Will hold the resolved pattern after calling __init()
|
||||||
this.stacks = {} // Drafted stacks container
|
|
||||||
this.store = new Store() // Pattern-wide store
|
this.store = new Store() // Pattern-wide store
|
||||||
this.setStores = [] // Per-set stores
|
this.setStores = [] // Per-set stores
|
||||||
|
|
||||||
|
@ -81,10 +87,13 @@ Pattern.prototype.addPart = function (part) {
|
||||||
Pattern.prototype.draft = function () {
|
Pattern.prototype.draft = function () {
|
||||||
this.__init()
|
this.__init()
|
||||||
this.__runHooks('preDraft')
|
this.__runHooks('preDraft')
|
||||||
|
// Keep container for drafted parts fresh
|
||||||
|
this.parts = []
|
||||||
|
|
||||||
// Iterate over the provided sets of settings (typically just one)
|
// Iterate over the provided sets of settings (typically just one)
|
||||||
for (const set in this.settings) {
|
for (const set in this.settings) {
|
||||||
this.activeSet = set
|
this.activeSet = set
|
||||||
|
this.setStores[set] = this.__createSetStore()
|
||||||
this.setStores[set].log.debug(`Initialized store for set ${set}`)
|
this.setStores[set].log.debug(`Initialized store for set ${set}`)
|
||||||
this.__runHooks('preSetDraft')
|
this.__runHooks('preSetDraft')
|
||||||
this.setStores[set].log.debug(`📐 Drafting pattern for set ${set}`)
|
this.setStores[set].log.debug(`📐 Drafting pattern for set ${set}`)
|
||||||
|
@ -99,6 +108,7 @@ Pattern.prototype.draft = function () {
|
||||||
// Create parts
|
// Create parts
|
||||||
this.setStores[set].log.debug(`📦 Creating part \`${partName}\` (set ${set})`)
|
this.setStores[set].log.debug(`📦 Creating part \`${partName}\` (set ${set})`)
|
||||||
this.parts[set][partName] = this.__createPartWithContext(partName, set)
|
this.parts[set][partName] = this.__createPartWithContext(partName, set)
|
||||||
|
|
||||||
// Handle inject/inheritance
|
// Handle inject/inheritance
|
||||||
if (typeof this.__inject[partName] === 'string') {
|
if (typeof this.__inject[partName] === 'string') {
|
||||||
this.setStores[set].log.debug(
|
this.setStores[set].log.debug(
|
||||||
|
@ -115,11 +125,11 @@ Pattern.prototype.draft = function () {
|
||||||
}
|
}
|
||||||
if (this.__needs(partName, set)) {
|
if (this.__needs(partName, set)) {
|
||||||
// Draft part
|
// Draft part
|
||||||
if (typeof this.__parts?.[partName]?.draft === 'function') {
|
if (typeof this.__designParts?.[partName]?.draft === 'function') {
|
||||||
this.activePart = partName
|
this.activePart = partName
|
||||||
try {
|
try {
|
||||||
this.__runHooks('prePartDraft')
|
this.__runHooks('prePartDraft')
|
||||||
const result = this.__parts[partName].draft(this.parts[set][partName].shorthand())
|
const result = this.__designParts[partName].draft(this.parts[set][partName].shorthand())
|
||||||
this.__runHooks('postPartDraft')
|
this.__runHooks('postPartDraft')
|
||||||
if (typeof result === 'undefined') {
|
if (typeof result === 'undefined') {
|
||||||
this.setStores[set].log.error(
|
this.setStores[set].log.error(
|
||||||
|
@ -129,7 +139,7 @@ Pattern.prototype.draft = function () {
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.setStores[set].log.error([`Unable to draft part \`${partName}\` (set ${set})`, err])
|
this.setStores[set].log.error([`Unable to draft part \`${partName}\` (set ${set})`, err])
|
||||||
}
|
}
|
||||||
} else this.setStores[set].log.error(`Unable to draft pattern. Part.draft() is not callable`)
|
} else this.setStores[set].log.error(`Unable to draft pattern part __${partName}__. Part.draft() is not callable`)
|
||||||
this.parts[set][partName].hidden =
|
this.parts[set][partName].hidden =
|
||||||
this.parts[set][partName].hidden === true ? true : !this.__wants(partName, set)
|
this.parts[set][partName].hidden === true ? true : !this.__wants(partName, set)
|
||||||
} else {
|
} else {
|
||||||
|
@ -183,26 +193,23 @@ Pattern.prototype.getRenderProps = function () {
|
||||||
warning: store.logs.warning,
|
warning: store.logs.warning,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
props.parts = {}
|
props.parts = []
|
||||||
for (let p in this.parts) {
|
for (const set of this.parts) {
|
||||||
if (!this.parts[p].hidden) {
|
const setParts = {}
|
||||||
props.parts[p] = {
|
for (let p in set) {
|
||||||
paths: this.parts[p].paths,
|
if (!set[p].hidden) {
|
||||||
points: this.parts[p].points,
|
setParts[p] = {
|
||||||
snippets: this.parts[p].snippets,
|
...set[p].asProps(),
|
||||||
attributes: this.parts[p].attributes,
|
store: this.setStores[set[p].set],
|
||||||
height: this.parts[p].height,
|
}
|
||||||
width: this.parts[p].width,
|
|
||||||
bottomRight: this.parts[p].bottomRight,
|
|
||||||
topLeft: this.parts[p].topLeft,
|
|
||||||
store: this.setStores[this.parts[p].set],
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
props.parts.push(setParts)
|
||||||
}
|
}
|
||||||
props.stacks = {}
|
props.stacks = {}
|
||||||
for (let s in this.stacks) {
|
for (let s in this.stacks) {
|
||||||
if (!this.__isStackHidden(s)) {
|
if (!this.__isStackHidden(s)) {
|
||||||
props.stacks[s] = this.stacks[s]
|
props.stacks[s] = this.stacks[s].asProps()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,12 +315,8 @@ Pattern.prototype.render = function () {
|
||||||
* @return {object} this - The Pattern instance
|
* @return {object} this - The Pattern instance
|
||||||
*/
|
*/
|
||||||
Pattern.prototype.use = function (plugin, data) {
|
Pattern.prototype.use = function (plugin, data) {
|
||||||
const name = plugin.plugin
|
const name = getPluginName(plugin)
|
||||||
? plugin.plugin.name
|
if (!this.plugins?.[name]) return (plugin.plugin && plugin.condition)
|
||||||
: plugin.name
|
|
||||||
console.log('@@@@@@@@@ in use', name, plugin, data)
|
|
||||||
if (!this.plugins?.[name])
|
|
||||||
return (plugin.plugin && plugin.condition)
|
|
||||||
? this.__useIf(plugin, data) // Conditional plugin
|
? this.__useIf(plugin, data) // Conditional plugin
|
||||||
: this.__loadPlugin(plugin, data) // Regular plugin
|
: this.__loadPlugin(plugin, data) // Regular plugin
|
||||||
|
|
||||||
|
@ -339,8 +342,8 @@ Pattern.prototype.use = function (plugin, data) {
|
||||||
*/
|
*/
|
||||||
Pattern.prototype.__addDependency = function (name, part, dep) {
|
Pattern.prototype.__addDependency = function (name, part, dep) {
|
||||||
this.__dependencies[name] = mergeDependencies(dep.name, this.__dependencies[name])
|
this.__dependencies[name] = mergeDependencies(dep.name, this.__dependencies[name])
|
||||||
if (typeof this.__parts[dep.name] === 'undefined') {
|
if (typeof this.__designParts[dep.name] === 'undefined') {
|
||||||
this.config = this.__addPartConfig(this.__parts[dep.name])
|
this.config = this.__addPartConfig(this.__designParts[dep.name])
|
||||||
}
|
}
|
||||||
|
|
||||||
return this
|
return this
|
||||||
|
@ -356,9 +359,10 @@ Pattern.prototype.__addDependency = function (name, part, dep) {
|
||||||
* @return {object} config - The mutated global config
|
* @return {object} config - The mutated global config
|
||||||
*/
|
*/
|
||||||
Pattern.prototype.__addPartConfig = function (part) {
|
Pattern.prototype.__addPartConfig = function (part) {
|
||||||
if (this.__parts[part.name].resolved) return config
|
|
||||||
|
if (this.__resolvedParts.includes(part.name)) return this
|
||||||
|
|
||||||
// Add parts, using set to keep them unique in the array
|
// Add parts, using set to keep them unique in the array
|
||||||
this.__parts[part.name].resolved = true
|
|
||||||
this.designConfig.parts = [...new Set(this.designConfig.parts).add(part)]
|
this.designConfig.parts = [...new Set(this.designConfig.parts).add(part)]
|
||||||
|
|
||||||
return this.__addPartOptions(part)
|
return this.__addPartOptions(part)
|
||||||
|
@ -442,15 +446,15 @@ Pattern.prototype.__addPartOptionalMeasurements = function (part, list=false) {
|
||||||
* @return {Pattern} this - The Pattern instance
|
* @return {Pattern} this - The Pattern instance
|
||||||
*/
|
*/
|
||||||
Pattern.prototype.__addPartOptions = function (part) {
|
Pattern.prototype.__addPartOptions = function (part) {
|
||||||
if (!this.config.optionDistance) this.config.optionDistance = {}
|
|
||||||
if (!this.config.options) this.config.options = {}
|
if (!this.config.options) this.config.options = {}
|
||||||
if (part.options) {
|
if (part.options) {
|
||||||
for (const optionName in part.options) {
|
for (const optionName in part.options) {
|
||||||
if (!this.config.optionDistance[optionName]) {
|
if (!this.__mutated.optionDistance[optionName]) {
|
||||||
this.config.optionDistance[optionName] = part.distance
|
this.__mutated.optionDistance[optionName] = this.__mutated.partDistance?.[part.name] || 0
|
||||||
this.config.options[optionName] = part.options[optionName]
|
// Keep design parts immutable in the pattern or risk subtle bugs
|
||||||
|
this.config.options[optionName] = Object.freeze(part.options[optionName])
|
||||||
this.store.log.debug(`🔵 __${optionName}__ option loaded from \`${part.name}\``)
|
this.store.log.debug(`🔵 __${optionName}__ option loaded from \`${part.name}\``)
|
||||||
} else if (this.config.optionDistance[optionName] > part.distance) {
|
} else if (this.__mutated.optionDistance[optionName] > this.__mutated.partDistance[part.name]) {
|
||||||
this.config.options[optionName] = part.options[optionName]
|
this.config.options[optionName] = part.options[optionName]
|
||||||
this.store.log.debug(`🟣 __${optionName}__ option overwritten by \`${part.name}\``)
|
this.store.log.debug(`🟣 __${optionName}__ option overwritten by \`${part.name}\``)
|
||||||
}
|
}
|
||||||
|
@ -466,6 +470,18 @@ Pattern.prototype.__addPartOptions = function (part) {
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getPluginName(plugin) {
|
||||||
|
if (Array.isArray(plugin)) {
|
||||||
|
if (plugin[0].name) return plugin[0].name
|
||||||
|
if (plugin[0].plugin.name) return plugin[0].plugin.name
|
||||||
|
} else {
|
||||||
|
if (plugin.name) return plugin.name
|
||||||
|
if (plugin.plugin.name) return plugin.plugin.name
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolves/Adds a part's configured plugins to the global config
|
* Resolves/Adds a part's configured plugins to the global config
|
||||||
*
|
*
|
||||||
|
@ -474,44 +490,63 @@ Pattern.prototype.__addPartOptions = function (part) {
|
||||||
* @return {Pattern} this - The Pattern instance
|
* @return {Pattern} this - The Pattern instance
|
||||||
*/
|
*/
|
||||||
Pattern.prototype.__addPartPlugins = function (part) {
|
Pattern.prototype.__addPartPlugins = function (part) {
|
||||||
if (!this.config.plugins) this.config.plugins = []
|
if (!this.config.plugins) this.config.plugins = {}
|
||||||
const plugins = {}
|
const plugins = { ...this.config.plugins }
|
||||||
if (!part.plugins) return this
|
if (!part.plugins) return this
|
||||||
for (const plugin of part.plugins) plugins[plugin.name] = plugin
|
// Side-step immutability of the part object to ensure plugins is an array
|
||||||
if (!Array.isArray(part.plugins)) part.plugins = [part.plugins]
|
let partPlugins = part.plugins
|
||||||
for (let plugin of part.plugins) {
|
if (!Array.isArray(partPlugins)) partPlugins = [partPlugins]
|
||||||
|
for (const plugin of partPlugins) plugins[getPluginName(plugin)] = plugin
|
||||||
|
for (let plugin of partPlugins) {
|
||||||
|
const name = getPluginName(plugin)
|
||||||
// Handle [plugin, data] scenario
|
// Handle [plugin, data] scenario
|
||||||
if (Array.isArray(plugin)) {
|
if (Array.isArray(plugin)) {
|
||||||
const pluginObj = { ...plugin[0], data: plugin[1] }
|
const pluginObj = { ...plugin[0], data: plugin[1] }
|
||||||
plugin = pluginObj
|
plugin = pluginObj
|
||||||
}
|
}
|
||||||
if (plugin.plugin) this.store.log.debug(`🔌 Resolved __${plugin.plugin.name}__ conditional plugin in \`${part.name}\``)
|
if (plugin.plugin) this.store.log.debug(`🔌 Resolved __${name}__ conditional plugin in \`${part.name}\``)
|
||||||
else this.store.log.debug(`🔌 Resolved __${plugin.name}__ plugin in \`${part.name}\``)
|
else this.store.log.debug(`🔌 Resolved __${name}__ plugin in \`${part.name}\``)
|
||||||
// Do not overwrite an existing plugin with a conditional plugin unless it is also conditional
|
// Do not overwrite an existing plugin with a conditional plugin unless it is also conditional
|
||||||
if (plugin.plugin && plugin.condition) {
|
if (plugin.plugin && plugin.condition) {
|
||||||
if (!plugins[plugin.plugin.name]) {
|
if (!plugins[name]) {
|
||||||
plugins[plugin.plugin.name] = plugin
|
plugins[name] = plugin
|
||||||
this.store.log.info(`Plugin \`${plugin.plugin.name}\` was conditionally added.`)
|
this.store.log.info(`Plugin \`${name}\` was conditionally added.`)
|
||||||
}
|
}
|
||||||
else if (plugins[plugin.plugin.name]?.condition) {
|
else if (plugins[name]?.condition) {
|
||||||
plugins[plugin.plugin.name+'_'] = plugin
|
plugins[name+'_'] = plugin
|
||||||
this.store.log.info(`Plugin \`${plugin.plugin.name}\` was conditionally added again. Renaming to ${plugin.plugin.name}_.`)
|
this.store.log.info(`Plugin \`${name}\` was conditionally added again. Renaming to ${name}_.`)
|
||||||
}
|
}
|
||||||
else this.store.log.info(
|
else this.store.log.info(
|
||||||
`Plugin \`${plugin.plugin.name}\` was requested conditionally, but is already added explicitly. Not loading.`
|
`Plugin \`${name}\` was requested conditionally, but is already added explicitly. Not loading.`
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
plugins[plugin.name] = plugin
|
plugins[name] = plugin
|
||||||
this.store.log.info(`Plugin \`${plugin.name}\` was added.`)
|
this.store.log.info(`Plugin \`${name}\` was added.`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Weed out doubles
|
this.config.plugins = {...plugins }
|
||||||
this.config.plugins = [...new Set(Object.values(plugins))]
|
|
||||||
|
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a store for a set (of settings)
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @return {Store} store - A new store populated with relevant data/methods
|
||||||
|
*/
|
||||||
|
Pattern.prototype.__createSetStore = function () {
|
||||||
|
const store = new Store()
|
||||||
|
store.set('data', this.store.data)
|
||||||
|
for (const method of [...this.__storeMethods]) {
|
||||||
|
store.set(method[0], (...args) => method[1](store, ...args))
|
||||||
|
}
|
||||||
|
|
||||||
|
return store
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Merges (sets of) settings with the default settings
|
* Merges (sets of) settings with the default settings
|
||||||
*
|
*
|
||||||
|
@ -525,7 +560,6 @@ Pattern.prototype.__applySettings = function (sets) {
|
||||||
this.settings = []
|
this.settings = []
|
||||||
for (const set in sets) {
|
for (const set in sets) {
|
||||||
this.settings.push({ ...__loadPatternDefaults(), ...sets[set] })
|
this.settings.push({ ...__loadPatternDefaults(), ...sets[set] })
|
||||||
this.setStores.push(new Store())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return this
|
return this
|
||||||
|
@ -544,7 +578,7 @@ Pattern.prototype.__createPartWithContext = function (name, set) {
|
||||||
const part = new Part()
|
const part = new Part()
|
||||||
part.name = name
|
part.name = name
|
||||||
part.set = set
|
part.set = set
|
||||||
part.stack = this.__parts[name]?.stack || name
|
part.stack = this.__designParts[name]?.stack || name
|
||||||
part.context = {
|
part.context = {
|
||||||
parts: this.parts[set],
|
parts: this.parts[set],
|
||||||
config: this.config,
|
config: this.config,
|
||||||
|
@ -552,6 +586,7 @@ Pattern.prototype.__createPartWithContext = function (name, set) {
|
||||||
store: this.setStores[set],
|
store: this.setStores[set],
|
||||||
macros: this.macros,
|
macros: this.macros,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.settings[set]?.partClasses) {
|
if (this.settings[set]?.partClasses) {
|
||||||
part.attr('class', this.settings[set].partClasses)
|
part.attr('class', this.settings[set].partClasses)
|
||||||
}
|
}
|
||||||
|
@ -617,8 +652,8 @@ Pattern.prototype.__init = function () {
|
||||||
.__resolveDependencies() // Resolves dependencies
|
.__resolveDependencies() // Resolves dependencies
|
||||||
.__resolveDraftOrder() // Resolves draft order
|
.__resolveDraftOrder() // Resolves draft order
|
||||||
.__loadPlugins() // Loads plugins
|
.__loadPlugins() // Loads plugins
|
||||||
.__filterOptionalMeasurements() // Removes required m's from optional list
|
|
||||||
.__loadConfigData() // Makes config data available in store
|
.__loadConfigData() // Makes config data available in store
|
||||||
|
.__filterOptionalMeasurements() // Removes required m's from optional list
|
||||||
.__loadOptionDefaults() // Merges default options with user provided ones
|
.__loadOptionDefaults() // Merges default options with user provided ones
|
||||||
|
|
||||||
// Say hello
|
// Say hello
|
||||||
|
@ -646,8 +681,8 @@ Pattern.prototype.__isPartHidden = function (partName) {
|
||||||
if (Array.isArray(this.settings[this.activeSet || 0].only)) {
|
if (Array.isArray(this.settings[this.activeSet || 0].only)) {
|
||||||
if (this.settings[this.activeSet || 0].only.includes(partName)) return false
|
if (this.settings[this.activeSet || 0].only.includes(partName)) return false
|
||||||
}
|
}
|
||||||
if (this.__parts?.[partName]?.hide) return true
|
if (this.__designParts?.[partName]?.hide) return true
|
||||||
if (this.__parts?.[partName]?.hideAll) return true
|
if (this.__designParts?.[partName]?.hideAll) return true
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -669,8 +704,8 @@ Pattern.prototype.__isStackHidden = function (stackName) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
for (const partName of parts) {
|
for (const partName of parts) {
|
||||||
if (this.__parts?.[partName]?.hide) return true
|
if (this.__designParts?.[partName]?.hide) return true
|
||||||
if (this.__parts?.[partName]?.hideAll) return true
|
if (this.__designParts?.[partName]?.hideAll) return true
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
|
@ -740,9 +775,7 @@ Pattern.prototype.__loadAbsoluteOptionsSet = function (set) {
|
||||||
* @return {Pattern} this - The Pattern instance
|
* @return {Pattern} this - The Pattern instance
|
||||||
*/
|
*/
|
||||||
Pattern.prototype.__loadConfigData = function () {
|
Pattern.prototype.__loadConfigData = function () {
|
||||||
if (this.designConfig.data) {
|
if (this.designConfig.data) this.store.set('data', this.designConfig.data)
|
||||||
for (const i in this.settings) this.setStores[i].set('data', this.designConfig.data)
|
|
||||||
}
|
|
||||||
|
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
@ -844,7 +877,10 @@ Pattern.prototype.__loadPluginMacros = function (plugin) {
|
||||||
*/
|
*/
|
||||||
Pattern.prototype.__loadPlugins = function () {
|
Pattern.prototype.__loadPlugins = function () {
|
||||||
if (!this.config.plugins) return this
|
if (!this.config.plugins) return this
|
||||||
for (const plugin of this.config.plugins) this.use(plugin, plugin.data)
|
for (const plugin in this.config.plugins) this.use(
|
||||||
|
this.config.plugins[plugin],
|
||||||
|
this.config.plugins[plugin]?.data,
|
||||||
|
)
|
||||||
|
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
@ -858,8 +894,11 @@ Pattern.prototype.__loadPlugins = function () {
|
||||||
*/
|
*/
|
||||||
Pattern.prototype.__loadPluginStoreMethods = function (plugin) {
|
Pattern.prototype.__loadPluginStoreMethods = function (plugin) {
|
||||||
if (Array.isArray(plugin.store)) {
|
if (Array.isArray(plugin.store)) {
|
||||||
for (const store of this.setStores) store.extend(plugin.store)
|
for (const method of plugin.store) this.__storeMethods.add(method)
|
||||||
} else this.store.log.warning(`Plugin store methods should be an Array`)
|
}
|
||||||
|
else this.store.log.warning(`Plugin store methods should be an Array`)
|
||||||
|
|
||||||
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1143,7 +1182,7 @@ Pattern.prototype.__resolveDraftOrder = function (graph = this.__resolvedDepende
|
||||||
})
|
})
|
||||||
|
|
||||||
// Don't forget about parts without dependencies
|
// Don't forget about parts without dependencies
|
||||||
for (const part in this.__parts) {
|
for (const part in this.__designParts) {
|
||||||
if (sorted.indexOf(part) === -1) sorted.push(part)
|
if (sorted.indexOf(part) === -1) sorted.push(part)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1164,49 +1203,53 @@ Pattern.prototype.__resolveDraftOrder = function (graph = this.__resolvedDepende
|
||||||
Pattern.prototype.__resolveParts = function (count = 0, distance = 0) {
|
Pattern.prototype.__resolveParts = function (count = 0, distance = 0) {
|
||||||
if (count === 0) {
|
if (count === 0) {
|
||||||
for (const part of this.designConfig.parts) {
|
for (const part of this.designConfig.parts) {
|
||||||
part.distance = distance
|
// Keep design parts immutable in the pattern or risk subtle bugs
|
||||||
this.__parts[part.name] = part
|
this.__designParts[part.name] = Object.freeze(part)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
distance++
|
distance++
|
||||||
for (const part of this.designConfig.parts) {
|
for (const part of this.designConfig.parts) {
|
||||||
if (typeof part.distance === 'undefined') part.distance = distance
|
if (typeof this.__mutated.partDistance[part.name] === 'undefined') this.__mutated.partDistance[part.name] = distance
|
||||||
}
|
}
|
||||||
for (const [name, part] of Object.entries(this.__parts)) {
|
for (const [name, part] of Object.entries(this.__designParts)) {
|
||||||
// Hide when hideAll is set
|
// Hide when hideAll is set
|
||||||
if (part.hideAll) part.hide = true
|
if (part.hideAll) part.hide = true
|
||||||
// Inject (from)
|
// Inject (from)
|
||||||
if (part.from) {
|
if (part.from) {
|
||||||
if (part.hideDependencies || part.hideAll) {
|
if (part.hideDependencies || part.hideAll) {
|
||||||
part.from.hide = true
|
// Don't mutate the part, keep this info in the pattern object
|
||||||
part.from.hideAll = true
|
this.__mutated.partHide[from.name] = true
|
||||||
part.from.distance = distance
|
this.__mutated.partHideAll[from.name] = true
|
||||||
|
this.__mutated.partDistance = distance
|
||||||
}
|
}
|
||||||
this.__parts[part.from.name] = part.from
|
this.__designParts[part.from.name] = part.from
|
||||||
this.__inject[name] = part.from.name
|
this.__inject[name] = part.from.name
|
||||||
}
|
}
|
||||||
// Simple dependency (after)
|
// Simple dependency (after)
|
||||||
if (part.after) {
|
if (part.after) {
|
||||||
if (Array.isArray(part.after)) {
|
if (Array.isArray(part.after)) {
|
||||||
for (const dep of part.after) {
|
for (const dep of part.after) {
|
||||||
dep.distance = distance
|
// Don't mutate the part, keep this info in the pattern object
|
||||||
this.__parts[dep.name] = dep
|
this.__mutated.partDistance[dep.name] = distance
|
||||||
|
this.__designParts[dep.name] = dep
|
||||||
this.__addDependency(name, part, dep)
|
this.__addDependency(name, part, dep)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (part.hideDependencies) part.after.hide = true
|
if (part.hideDependencies) {
|
||||||
part.after.distance = distance
|
this.__mutated.partHide[part.after.name] = true
|
||||||
this.__parts[part.after.name] = part.after
|
}
|
||||||
|
this.__mutated.partDistance[part.after.name] = distance
|
||||||
|
this.__designParts[part.after.name] = part.after
|
||||||
this.__addDependency(name, part, part.after)
|
this.__addDependency(name, part, part.after)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Did we discover any new dependencies?
|
// Did we discover any new dependencies?
|
||||||
const len = Object.keys(this.__parts).length
|
const len = Object.keys(this.__designParts).length
|
||||||
// If so, resolve recursively
|
// If so, resolve recursively
|
||||||
if (len > count) return this.__resolveParts(len, distance)
|
if (len > count) return this.__resolveParts(len, distance)
|
||||||
|
|
||||||
for (const part of Object.values(this.__parts)) this.__addPartConfig(part)
|
for (const part of Object.values(this.__designParts)) this.__addPartConfig(part)
|
||||||
|
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
@ -1291,20 +1334,21 @@ Pattern.prototype.__setBase = function () {
|
||||||
Pattern.prototype.__snappedPercentageOption = function (optionName, set) {
|
Pattern.prototype.__snappedPercentageOption = function (optionName, set) {
|
||||||
const conf = this.config.options[optionName]
|
const conf = this.config.options[optionName]
|
||||||
const abs = conf.toAbs(this.settings[set].options[optionName], this.settings[set])
|
const abs = conf.toAbs(this.settings[set].options[optionName], this.settings[set])
|
||||||
// Handle units-specific config
|
// Handle units-specific config - Side-step immutability for the snap conf
|
||||||
if (!Array.isArray(conf.snap) && conf.snap.metric && conf.snap.imperial)
|
let snapConf = conf.snap
|
||||||
conf.snap = conf.snap[this.settings[set].units]
|
if (!Array.isArray(snapConf) && snapConf.metric && snapConf.imperial)
|
||||||
|
snapConf = snapConf[this.settings[set].units]
|
||||||
// Simple steps
|
// Simple steps
|
||||||
if (typeof conf.snap === 'number') return Math.ceil(abs / conf.snap) * conf.snap
|
if (typeof snapConf === 'number') return Math.ceil(abs / snapConf) * snapConf
|
||||||
// List of snaps
|
// List of snaps
|
||||||
if (Array.isArray(conf.snap) && conf.snap.length > 1) {
|
if (Array.isArray(snapConf) && snapConf.length > 1) {
|
||||||
for (const snap of conf.snap
|
for (const snap of snapConf
|
||||||
.sort((a, b) => a - b)
|
.sort((a, b) => a - b)
|
||||||
.map((snap, i) => {
|
.map((snap, i) => {
|
||||||
const margin =
|
const margin =
|
||||||
i < conf.snap.length - 1
|
i < snapConf.length - 1
|
||||||
? (conf.snap[Number(i) + 1] - snap) / 2 // Look forward
|
? (snapConf[Number(i) + 1] - snap) / 2 // Look forward
|
||||||
: (snap - conf.snap[i - 1]) / 2 // Final snap, look backward
|
: (snap - snapConf[i - 1]) / 2 // Final snap, look backward
|
||||||
|
|
||||||
return {
|
return {
|
||||||
min: snap - margin,
|
min: snap - margin,
|
||||||
|
@ -1326,7 +1370,6 @@ Pattern.prototype.__snappedPercentageOption = function (optionName, set) {
|
||||||
* @return {Pattern} this - The Pattern instance
|
* @return {Pattern} this - The Pattern instance
|
||||||
*/
|
*/
|
||||||
Pattern.prototype.__useIf = function (plugin) {
|
Pattern.prototype.__useIf = function (plugin) {
|
||||||
console.log(')_________', plugin)
|
|
||||||
let load = 0
|
let load = 0
|
||||||
for (const set of this.settings) {
|
for (const set of this.settings) {
|
||||||
if (plugin.condition(set)) load++
|
if (plugin.condition(set)) load++
|
||||||
|
|
|
@ -26,6 +26,15 @@ Stack.prototype.addPart = function (part) {
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns a stack object suitbale for renderprops */
|
||||||
|
Stack.prototype.asProps = function (part) {
|
||||||
|
return {
|
||||||
|
...this,
|
||||||
|
parts: [...this.parts]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Returns a list of parts in this stack */
|
/* Returns a list of parts in this stack */
|
||||||
Stack.prototype.getPartList = function () {
|
Stack.prototype.getPartList = function () {
|
||||||
return [...this.parts]
|
return [...this.parts]
|
||||||
|
|
|
@ -3,8 +3,6 @@ import { Design } from '../src/index.mjs'
|
||||||
|
|
||||||
const expect = chai.expect
|
const expect = chai.expect
|
||||||
|
|
||||||
if (!expect) console.log('shut up eslint REMOVE')
|
|
||||||
|
|
||||||
describe('Multisets', () => {
|
describe('Multisets', () => {
|
||||||
describe('FIXME', () => {
|
describe('FIXME', () => {
|
||||||
const partA = {
|
const partA = {
|
||||||
|
|
|
@ -32,13 +32,6 @@ describe('Part', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should register and run a macro', () => {
|
it('Should register and run a macro', () => {
|
||||||
const part = {
|
|
||||||
name: 'test',
|
|
||||||
draft: ({ part, macro }) => {
|
|
||||||
macro('test', { x: 123, y: 456 })
|
|
||||||
return part
|
|
||||||
},
|
|
||||||
}
|
|
||||||
const plugin = {
|
const plugin = {
|
||||||
name: 'test',
|
name: 'test',
|
||||||
version: '0.1-test',
|
version: '0.1-test',
|
||||||
|
@ -49,7 +42,16 @@ describe('Part', () => {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
const design = new Design({ parts: [part], plugins: [plugin] })
|
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()
|
const pattern = new design()
|
||||||
pattern.draft()
|
pattern.draft()
|
||||||
expect(pattern.parts[0].test.points.macro.x).to.equal(123)
|
expect(pattern.parts[0].test.points.macro.x).to.equal(123)
|
||||||
|
@ -92,7 +94,7 @@ describe('Part', () => {
|
||||||
expect(part.attributes.get('foo')).to.equal('schmoo')
|
expect(part.attributes.get('foo')).to.equal('schmoo')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should raise a warning when setting a non-Point value in points', () => {
|
it('Should log a warning when setting a non-Point value in points', () => {
|
||||||
const part = {
|
const part = {
|
||||||
name: 'test',
|
name: 'test',
|
||||||
draft: ({ points, part }) => {
|
draft: ({ points, part }) => {
|
||||||
|
@ -103,19 +105,19 @@ describe('Part', () => {
|
||||||
const design = new Design({ parts: [part] })
|
const design = new Design({ parts: [part] })
|
||||||
const pattern = new design()
|
const pattern = new design()
|
||||||
pattern.draft()
|
pattern.draft()
|
||||||
expect(pattern.stores[0].logs.warning.length).to.equal(4)
|
expect(pattern.setStores[0].logs.warning.length).to.equal(4)
|
||||||
expect(pattern.stores[0].logs.warning[0]).to.equal(
|
expect(pattern.setStores[0].logs.warning[0]).to.equal(
|
||||||
'`points.a` was set with a value that is not a `Point` object'
|
'`points.a` was set with a value that is not a `Point` object'
|
||||||
)
|
)
|
||||||
expect(pattern.stores[0].logs.warning[1]).to.equal(
|
expect(pattern.setStores[0].logs.warning[1]).to.equal(
|
||||||
'`points.a` was set with a `x` parameter that is not a `number`'
|
'`points.a` was set with a `x` parameter that is not a `number`'
|
||||||
)
|
)
|
||||||
expect(pattern.stores[0].logs.warning[2]).to.equal(
|
expect(pattern.setStores[0].logs.warning[2]).to.equal(
|
||||||
'`points.a` was set with a `y` parameter that is not a `number`'
|
'`points.a` was set with a `y` parameter that is not a `number`'
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should raise a warning when setting a non-Snippet value in snippets', () => {
|
it('Should log a warning when setting a non-Snippet value in snippets', () => {
|
||||||
const part = {
|
const part = {
|
||||||
name: 'test',
|
name: 'test',
|
||||||
draft: ({ snippets, part }) => {
|
draft: ({ snippets, part }) => {
|
||||||
|
@ -126,14 +128,14 @@ describe('Part', () => {
|
||||||
const design = new Design({ parts: [part] })
|
const design = new Design({ parts: [part] })
|
||||||
const pattern = new design()
|
const pattern = new design()
|
||||||
pattern.draft()
|
pattern.draft()
|
||||||
expect(pattern.stores[0].logs.warning.length).to.equal(4)
|
expect(pattern.setStores[0].logs.warning.length).to.equal(4)
|
||||||
expect(pattern.stores[0].logs.warning[0]).to.equal(
|
expect(pattern.setStores[0].logs.warning[0]).to.equal(
|
||||||
'`snippets.a` was set with a value that is not a `Snippet` object'
|
'`snippets.a` was set with a value that is not a `Snippet` object'
|
||||||
)
|
)
|
||||||
expect(pattern.stores[0].logs.warning[1]).to.equal(
|
expect(pattern.setStores[0].logs.warning[1]).to.equal(
|
||||||
'`snippets.a` was set with a `def` parameter that is not a `string`'
|
'`snippets.a` was set with a `def` parameter that is not a `string`'
|
||||||
)
|
)
|
||||||
expect(pattern.stores[0].logs.warning[2]).to.equal(
|
expect(pattern.setStores[0].logs.warning[2]).to.equal(
|
||||||
'`snippets.a` was set with an `anchor` parameter that is not a `Point`'
|
'`snippets.a` was set with an `anchor` parameter that is not a `Point`'
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -176,8 +178,8 @@ describe('Part', () => {
|
||||||
// Let's also cover the branch where complete is false
|
// Let's also cover the branch where complete is false
|
||||||
const pattern = new design({ complete: false} )
|
const pattern = new design({ complete: false} )
|
||||||
pattern.draft()
|
pattern.draft()
|
||||||
expect(pattern.stores[0].logs.warning.length).to.equal(1)
|
expect(pattern.setStores[0].logs.warning.length).to.equal(1)
|
||||||
expect(pattern.stores[0].logs.warning[0]).to.equal(
|
expect(pattern.setStores[0].logs.warning[0]).to.equal(
|
||||||
'Calling `units(value)` but `value` is not a number (`string`)'
|
'Calling `units(value)` but `value` is not a number (`string`)'
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -291,8 +293,8 @@ describe('Part', () => {
|
||||||
const design = new Design({ parts: [part] })
|
const design = new Design({ parts: [part] })
|
||||||
const pattern = new design()
|
const pattern = new design()
|
||||||
pattern.draft()
|
pattern.draft()
|
||||||
expect(pattern.stores[0].logs.warning.length).to.equal(1)
|
expect(pattern.setStores[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`')
|
expect(pattern.setStores[0].logs.warning[0]).to.equal('Tried to access `options.test` but it is `undefined`')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Accessing unknown absoluteOption should log a warning', () => {
|
it('Accessing unknown absoluteOption should log a warning', () => {
|
||||||
|
@ -305,8 +307,8 @@ describe('Part', () => {
|
||||||
const design = new Design({ parts: [part] })
|
const design = new Design({ parts: [part] })
|
||||||
const pattern = new design()
|
const pattern = new design()
|
||||||
pattern.draft()
|
pattern.draft()
|
||||||
expect(pattern.stores[0].logs.warning.length).to.equal(1)
|
expect(pattern.setStores[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`')
|
expect(pattern.setStores[0].logs.warning[0]).to.equal('Tried to access `absoluteOptions.test` but it is `undefined`')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Injecting a part should contain all data', () => {
|
it('Injecting a part should contain all data', () => {
|
||||||
|
|
|
@ -77,8 +77,8 @@ describe('Path', () => {
|
||||||
const design = new Design({ parts: [part] })
|
const design = new Design({ parts: [part] })
|
||||||
const pattern = new design()
|
const pattern = new design()
|
||||||
pattern.draft()
|
pattern.draft()
|
||||||
expect(pattern.stores[0].logs.warning.length).to.equal(2)
|
expect(pattern.setStores[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')
|
expect(pattern.setStores[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_()', () => {
|
it('Should log a warning when passing a non-Point to smurve_()', () => {
|
||||||
|
@ -93,8 +93,8 @@ describe('Path', () => {
|
||||||
const design = new Design({ parts: [part] })
|
const design = new Design({ parts: [part] })
|
||||||
const pattern = new design()
|
const pattern = new design()
|
||||||
pattern.draft()
|
pattern.draft()
|
||||||
expect(pattern.stores[0].logs.warning.length).to.equal(1)
|
expect(pattern.setStores[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')
|
expect(pattern.setStores[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', () => {
|
it('Should log a warning when passing a non-Path to the paths proxy', () => {
|
||||||
|
@ -109,9 +109,9 @@ describe('Path', () => {
|
||||||
const design = new Design({ parts: [part] })
|
const design = new Design({ parts: [part] })
|
||||||
const pattern = new design()
|
const pattern = new design()
|
||||||
pattern.draft()
|
pattern.draft()
|
||||||
expect(pattern.stores[0].logs.warning.length).to.equal(2)
|
expect(pattern.setStores[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.setStores[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`')
|
expect(pattern.setStores[0].logs.warning[1]).to.equal('Could not set `name` property on `paths.test`')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should offset a line', () => {
|
it('Should offset a line', () => {
|
||||||
|
@ -1074,8 +1074,8 @@ describe('Path', () => {
|
||||||
const design = new Design({ parts: [part] })
|
const design = new Design({ parts: [part] })
|
||||||
const pattern = new design()
|
const pattern = new design()
|
||||||
pattern.draft()
|
pattern.draft()
|
||||||
expect(pattern.stores[0].logs.error.length).to.equal(2)
|
expect(pattern.setStores[0].logs.error.length).to.equal(2)
|
||||||
expect(pattern.stores[0].logs.error[0]).to.equal(
|
expect(pattern.setStores[0].logs.error[0]).to.equal(
|
||||||
'Called `Path.offset(distance)` but `distance` is not a number'
|
'Called `Path.offset(distance)` but `distance` is not a number'
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -1092,8 +1092,8 @@ describe('Path', () => {
|
||||||
const design = new Design({ parts: [part] })
|
const design = new Design({ parts: [part] })
|
||||||
const pattern = new design()
|
const pattern = new design()
|
||||||
pattern.draft()
|
pattern.draft()
|
||||||
expect(pattern.stores[0].logs.error.length).to.equal(2)
|
expect(pattern.setStores[0].logs.error.length).to.equal(2)
|
||||||
expect(pattern.stores[0].logs.error[0]).to.equal(
|
expect(pattern.setStores[0].logs.error[0]).to.equal(
|
||||||
'Called `Path.join(that)` but `that` is not a `Path` object'
|
'Called `Path.join(that)` but `that` is not a `Path` object'
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -1141,7 +1141,7 @@ describe('Path', () => {
|
||||||
const design = new Design({ parts: [part] })
|
const design = new Design({ parts: [part] })
|
||||||
const pattern = new design()
|
const pattern = new design()
|
||||||
pattern.draft()
|
pattern.draft()
|
||||||
expect(pattern.stores[0].logs.error[0]).to.equal(
|
expect(pattern.setStores[0].logs.error[0]).to.equal(
|
||||||
'Called `Path.shiftFractionAlong(fraction)` but `fraction` is not a number'
|
'Called `Path.shiftFractionAlong(fraction)` but `fraction` is not a number'
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -1157,7 +1157,7 @@ describe('Path', () => {
|
||||||
const design = new Design({ parts: [part] })
|
const design = new Design({ parts: [part] })
|
||||||
const pattern = new design()
|
const pattern = new design()
|
||||||
pattern.draft()
|
pattern.draft()
|
||||||
expect(pattern.stores[0].logs.error[0]).to.equal(
|
expect(pattern.setStores[0].logs.error[0]).to.equal(
|
||||||
'Called `Path.split(point)` but `point` is not a `Point` object'
|
'Called `Path.split(point)` but `point` is not a `Point` object'
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
|
@ -5,7 +5,6 @@ const expect = chai.expect
|
||||||
|
|
||||||
describe('Pattern', () => {
|
describe('Pattern', () => {
|
||||||
describe('Pattern.constructor()', () => {
|
describe('Pattern.constructor()', () => {
|
||||||
/*
|
|
||||||
|
|
||||||
it('Pattern constructor should return pattern object', () => {
|
it('Pattern constructor should return pattern object', () => {
|
||||||
const Pattern = new Design()
|
const Pattern = new Design()
|
||||||
|
@ -20,7 +19,7 @@ describe('Pattern', () => {
|
||||||
expect(Array.isArray(pattern.setStores)).to.equal(true)
|
expect(Array.isArray(pattern.setStores)).to.equal(true)
|
||||||
expect(typeof pattern.store).to.equal('object')
|
expect(typeof pattern.store).to.equal('object')
|
||||||
expect(typeof pattern.config).to.equal('object')
|
expect(typeof pattern.config).to.equal('object')
|
||||||
expect(Object.keys(pattern).length).to.equal(6)
|
expect(Object.keys(pattern).length).to.equal(5)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Pattern constructor should add non-enumerable properties', () => {
|
it('Pattern constructor should add non-enumerable properties', () => {
|
||||||
|
@ -34,7 +33,7 @@ describe('Pattern', () => {
|
||||||
expect(typeof pattern.Snippet).to.equal('function')
|
expect(typeof pattern.Snippet).to.equal('function')
|
||||||
expect(typeof pattern.Attributes).to.equal('function')
|
expect(typeof pattern.Attributes).to.equal('function')
|
||||||
expect(typeof pattern.macros).to.equal('object')
|
expect(typeof pattern.macros).to.equal('object')
|
||||||
expect(typeof pattern.__parts).to.equal('object')
|
expect(typeof pattern.__designParts).to.equal('object')
|
||||||
expect(typeof pattern.__inject).to.equal('object')
|
expect(typeof pattern.__inject).to.equal('object')
|
||||||
expect(typeof pattern.__dependencies).to.equal('object')
|
expect(typeof pattern.__dependencies).to.equal('object')
|
||||||
expect(typeof pattern.__resolvedDependencies).to.equal('object')
|
expect(typeof pattern.__resolvedDependencies).to.equal('object')
|
||||||
|
@ -75,7 +74,7 @@ describe('Pattern', () => {
|
||||||
options: {
|
options: {
|
||||||
optA: { pct: 40, min: 20, max: 80 },
|
optA: { pct: 40, min: 20, max: 80 },
|
||||||
},
|
},
|
||||||
draft: () => {},
|
draft: ({ part }) => part,
|
||||||
}
|
}
|
||||||
const partB = {
|
const partB = {
|
||||||
name: 'test.partB',
|
name: 'test.partB',
|
||||||
|
@ -93,7 +92,7 @@ describe('Pattern', () => {
|
||||||
options: {
|
options: {
|
||||||
optB: { deg: 40, min: 20, max: 80 },
|
optB: { deg: 40, min: 20, max: 80 },
|
||||||
},
|
},
|
||||||
draft: () => {},
|
draft: ({ part }) => part,
|
||||||
}
|
}
|
||||||
const partC = {
|
const partC = {
|
||||||
name: 'test.partC',
|
name: 'test.partC',
|
||||||
|
@ -103,7 +102,7 @@ describe('Pattern', () => {
|
||||||
options: {
|
options: {
|
||||||
optC: { pct: 20, min: 10, max: 30 },
|
optC: { pct: 20, min: 10, max: 30 },
|
||||||
},
|
},
|
||||||
draft: () => {},
|
draft: ({ part }) => part,
|
||||||
}
|
}
|
||||||
|
|
||||||
const Pattern = new Design({
|
const Pattern = new Design({
|
||||||
|
@ -114,7 +113,7 @@ describe('Pattern', () => {
|
||||||
parts: [partC],
|
parts: [partC],
|
||||||
})
|
})
|
||||||
const pattern = new Pattern()
|
const pattern = new Pattern()
|
||||||
pattern.__init()
|
pattern.draft()
|
||||||
|
|
||||||
it('Pattern.__init() should resolve all measurements', () => {
|
it('Pattern.__init() should resolve all measurements', () => {
|
||||||
expect(
|
expect(
|
||||||
|
@ -152,7 +151,7 @@ describe('Pattern', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Pattern.__init() should resolve plugins', () => {
|
it('Pattern.__init() should resolve plugins', () => {
|
||||||
expect(pattern.config.plugins.length).to.equal(1)
|
expect(Object.keys(pattern.config.plugins).length).to.equal(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Pattern.__init() should set config data in the store', () => {
|
it('Pattern.__init() should set config data in the store', () => {
|
||||||
|
@ -497,7 +496,7 @@ describe('Pattern', () => {
|
||||||
}
|
}
|
||||||
const design = new Design({ parts: [part] })
|
const design = new Design({ parts: [part] })
|
||||||
const pattern = new design()
|
const pattern = new design()
|
||||||
pattern.__init()
|
pattern.draft()
|
||||||
expect(pattern.hooks.preRender.length).to.equal(1)
|
expect(pattern.hooks.preRender.length).to.equal(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -573,9 +572,10 @@ describe('Pattern', () => {
|
||||||
const pattern = new design()
|
const pattern = new design()
|
||||||
expect(pattern.hooks.preRender.length).to.equal(0)
|
expect(pattern.hooks.preRender.length).to.equal(0)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Pattern.__init() should load multiple conditional plugins', () => {
|
it('Pattern.__init() should load multiple conditional plugins', () => {
|
||||||
const plugin = {
|
const plugin1 = {
|
||||||
name: 'example',
|
name: 'example1',
|
||||||
version: 1,
|
version: 1,
|
||||||
hooks: {
|
hooks: {
|
||||||
preRender: function (svg) {
|
preRender: function (svg) {
|
||||||
|
@ -583,22 +583,30 @@ describe('Pattern', () => {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
const plugin2 = {
|
||||||
|
name: 'example2',
|
||||||
|
version: 2,
|
||||||
|
hooks: {
|
||||||
|
preRender: function (svg) {
|
||||||
|
svg.attributes.add('freesewing:plugin-example', 2)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
const condition1 = () => true
|
const condition1 = () => true
|
||||||
const condition2 = () => false
|
const condition2 = () => false
|
||||||
const part = {
|
const part = {
|
||||||
name: 'test.part',
|
name: 'test.part',
|
||||||
plugins: [
|
plugins: [
|
||||||
{ plugin, condition: condition1 },
|
{ plugin: plugin1, condition: condition1 },
|
||||||
{ plugin, condition: condition2 },
|
{ plugin: plugin2, condition: condition2 },
|
||||||
],
|
],
|
||||||
draft: (part) => part,
|
draft: (part) => part,
|
||||||
}
|
}
|
||||||
const design = new Design({ parts: [ part ] })
|
const design = new Design({ parts: [ part ] })
|
||||||
const pattern = new design()
|
const pattern = new design()
|
||||||
pattern.__init()
|
pattern.draft()
|
||||||
expect(pattern.hooks.preRender.length).to.equal(1)
|
expect(pattern.hooks.preRender.length).to.equal(1)
|
||||||
})
|
})
|
||||||
*/
|
|
||||||
|
|
||||||
it('Load conditional plugins that are also passing data', () => {
|
it('Load conditional plugins that are also passing data', () => {
|
||||||
const plugin1 = {
|
const plugin1 = {
|
||||||
|
@ -638,17 +646,13 @@ describe('Pattern', () => {
|
||||||
draft: ({ part }) => part
|
draft: ({ part }) => part
|
||||||
}
|
}
|
||||||
const design = new Design({
|
const design = new Design({
|
||||||
parts: [ part1 ]
|
parts: [ part1, part2 ]
|
||||||
})
|
})
|
||||||
const pattern = new design()
|
const pattern = new design()
|
||||||
pattern.__init()
|
pattern.__init()
|
||||||
//console.log(pattern.store.logs)
|
|
||||||
console.log(pattern.config)
|
|
||||||
//console.log(pattern.hooks)
|
|
||||||
expect(pattern.hooks.preRender.length).to.equal(2)
|
expect(pattern.hooks.preRender.length).to.equal(2)
|
||||||
})
|
})
|
||||||
|
|
||||||
/*
|
|
||||||
it('Pattern.__init() should register a hook via on', () => {
|
it('Pattern.__init() should register a hook via on', () => {
|
||||||
const Pattern = new Design()
|
const Pattern = new Design()
|
||||||
const pattern = new Pattern()
|
const pattern = new Pattern()
|
||||||
|
@ -704,35 +708,44 @@ describe('Pattern', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should check whether created parts get the pattern context', () => {
|
it('Should check whether created parts get the pattern context', () => {
|
||||||
|
let partContext
|
||||||
const part = {
|
const part = {
|
||||||
name: 'test',
|
name: 'test',
|
||||||
draft: ({ part }) => part,
|
draft: ({ Point, paths, Path, part, context }) => {
|
||||||
|
paths.test = new Path()
|
||||||
|
.move(new Point(0,0))
|
||||||
|
.line(new Point(100,0))
|
||||||
|
partContext = context
|
||||||
|
|
||||||
|
return part
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const Pattern = new Design({ parts: [part] })
|
const Pattern = new Design({ parts: [part], data: { name: 'test', version: '1' }})
|
||||||
const pattern = new Pattern()
|
const pattern = new Pattern()
|
||||||
pattern.draft()
|
pattern.draft()
|
||||||
const context = pattern.parts[0].test.context
|
expect(typeof partContext).to.equal('object')
|
||||||
expect(typeof context).to.equal('object')
|
expect(typeof partContext.parts).to.equal('object')
|
||||||
expect(typeof context.parts).to.equal('object')
|
expect(typeof partContext.config).to.equal('object')
|
||||||
expect(typeof context.config).to.equal('object')
|
expect(typeof partContext.config.options).to.equal('object')
|
||||||
expect(typeof context.config.options).to.equal('object')
|
expect(typeof partContext.store.data).to.equal('object')
|
||||||
expect(typeof pattern.parts[0].test.context.config.data).to.equal('object')
|
expect(partContext.store.data.name).to.equal('test')
|
||||||
expect(Array.isArray(context.config.measurements)).to.equal(true)
|
expect(partContext.store.get('data.name')).to.equal('test')
|
||||||
expect(Array.isArray(context.config.optionalMeasurements)).to.equal(true)
|
expect(Array.isArray(partContext.config.measurements)).to.equal(true)
|
||||||
expect(Array.isArray(context.config.parts)).to.equal(true)
|
expect(Array.isArray(partContext.config.optionalMeasurements)).to.equal(true)
|
||||||
expect(Array.isArray(context.config.plugins)).to.equal(true)
|
expect(typeof partContext.config.plugins).to.equal('object')
|
||||||
expect(context.settings).to.equal(pattern.settings[0])
|
expect(typeof partContext.parts).to.equal('object')
|
||||||
expect(typeof context.store).to.equal('object')
|
expect(partContext.settings).to.equal(pattern.settings[0])
|
||||||
expect(typeof context.store.log).to.equal('object')
|
expect(typeof partContext.store).to.equal('object')
|
||||||
expect(typeof context.store.log.debug).to.equal('function')
|
expect(typeof partContext.store.log).to.equal('object')
|
||||||
expect(typeof context.store.log.info).to.equal('function')
|
expect(typeof partContext.store.log.debug).to.equal('function')
|
||||||
expect(typeof context.store.log.warning).to.equal('function')
|
expect(typeof partContext.store.log.info).to.equal('function')
|
||||||
expect(typeof context.store.log.error).to.equal('function')
|
expect(typeof partContext.store.log.warning).to.equal('function')
|
||||||
expect(typeof context.store.logs).to.equal('object')
|
expect(typeof partContext.store.log.error).to.equal('function')
|
||||||
expect(Array.isArray(context.store.logs.debug)).to.equal(true)
|
expect(typeof partContext.store.logs).to.equal('object')
|
||||||
expect(Array.isArray(context.store.logs.info)).to.equal(true)
|
expect(Array.isArray(partContext.store.logs.debug)).to.equal(true)
|
||||||
expect(Array.isArray(context.store.logs.warning)).to.equal(true)
|
expect(Array.isArray(partContext.store.logs.info)).to.equal(true)
|
||||||
expect(Array.isArray(context.store.logs.error)).to.equal(true)
|
expect(Array.isArray(partContext.store.logs.warning)).to.equal(true)
|
||||||
|
expect(Array.isArray(partContext.store.logs.error)).to.equal(true)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -800,6 +813,5 @@ describe('Pattern', () => {
|
||||||
const pattern = new Pattern()
|
const pattern = new Pattern()
|
||||||
expect(() => pattern.__init()).to.throw()
|
expect(() => pattern.__init()).to.throw()
|
||||||
})
|
})
|
||||||
*/
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -10,14 +10,14 @@ describe('Pattern', () => {
|
||||||
const design = new Design()
|
const design = new Design()
|
||||||
const pattern = new design()
|
const pattern = new design()
|
||||||
pattern.addPart(part)
|
pattern.addPart(part)
|
||||||
expect(pattern.stores[0].logs.error.length).to.equal(1)
|
expect(pattern.store.logs.error.length).to.equal(1)
|
||||||
expect(pattern.stores[0].logs.error[0]).to.equal('Part must have a name')
|
expect(pattern.store.logs.error[0]).to.equal('Part must have a name')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should log an error when a part does not have a draft method', () => {
|
it('Should log an error when a part does not have a draft method', () => {
|
||||||
const from = {
|
const from = {
|
||||||
name: 'test',
|
name: 'test',
|
||||||
draft: ({ points, part }) => {
|
noDraft: ({ points, part }) => {
|
||||||
points.test = false
|
points.test = false
|
||||||
return part
|
return part
|
||||||
}
|
}
|
||||||
|
@ -32,9 +32,8 @@ describe('Pattern', () => {
|
||||||
const design = new Design({ parts: [ to ]})
|
const design = new Design({ parts: [ to ]})
|
||||||
const pattern = new design()
|
const pattern = new design()
|
||||||
pattern.draft()
|
pattern.draft()
|
||||||
expect(pattern.stores[0].logs.error.length).to.equal(2)
|
expect(pattern.setStores[0].logs.error.length).to.equal(1)
|
||||||
expect(pattern.stores[0].logs.error[0][0]).to.equal('Unable to draft part `test` (set 0)')
|
expect(pattern.setStores[0].logs.error[0]).to.equal('Unable to draft pattern part __test__. Part.draft() is not callable')
|
||||||
expect(pattern.stores[0].logs.error[1][0]).to.equal('Could not inject part `test` into part `testTo`')
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Not returning the part from the draft method should log an error', () => {
|
it('Not returning the part from the draft method should log an error', () => {
|
||||||
|
@ -45,8 +44,8 @@ describe('Pattern', () => {
|
||||||
const design = new Design({ parts: [ test ]})
|
const design = new Design({ parts: [ test ]})
|
||||||
const pattern = new design()
|
const pattern = new design()
|
||||||
pattern.draft()
|
pattern.draft()
|
||||||
expect(pattern.stores[0].logs.error.length).to.equal(1)
|
expect(pattern.setStores[0].logs.error.length).to.equal(1)
|
||||||
expect(pattern.stores[0].logs.error[0]).to.equal('Result of drafting part test was undefined. Did you forget to return the part?')
|
expect(pattern.setStores[0].logs.error[0]).to.equal('Result of drafting part test was undefined. Did you forget to return the part?')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should skip unneeded parts', () => {
|
it('Should skip unneeded parts', () => {
|
||||||
|
@ -57,8 +56,8 @@ describe('Pattern', () => {
|
||||||
const design = new Design({ parts: [ test ]})
|
const design = new Design({ parts: [ test ]})
|
||||||
const pattern = new design({ only: ['you'] })
|
const pattern = new design({ only: ['you'] })
|
||||||
pattern.draft()
|
pattern.draft()
|
||||||
expect(pattern.stores[0].logs.debug.length).to.equal(3)
|
expect(pattern.setStores[0].logs.debug.length).to.equal(4)
|
||||||
expect(pattern.stores[0].logs.debug[2]).to.equal('Part `test` is not needed. Skipping draft and setting hidden to `true`')
|
expect(pattern.setStores[0].logs.debug[3]).to.equal('Part `test` is not needed. Skipping draft and setting hidden to `true`')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should return the initialized config', () => {
|
it('Should return the initialized config', () => {
|
||||||
|
@ -69,7 +68,8 @@ describe('Pattern', () => {
|
||||||
const design = new Design({ parts: [ test ]})
|
const design = new Design({ parts: [ test ]})
|
||||||
const pattern = new design({ only: ['you'] })
|
const pattern = new design({ only: ['you'] })
|
||||||
const config = pattern.getConfig()
|
const config = pattern.getConfig()
|
||||||
expect(config.parts[0]).to.equal(test)
|
expect(config.draftOrder.length).to.equal(1)
|
||||||
|
expect(config.draftOrder[0]).to.equal('test')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should skip a plugin that is loaded twice', () => {
|
it('Should skip a plugin that is loaded twice', () => {
|
||||||
|
@ -84,16 +84,16 @@ describe('Pattern', () => {
|
||||||
pattern.use(plugin)
|
pattern.use(plugin)
|
||||||
pattern.use({ plugin })
|
pattern.use({ plugin })
|
||||||
pattern.use({ plugin })
|
pattern.use({ plugin })
|
||||||
expect(pattern.stores[0].logs.info[1]).to.equal("Plugin `test` was requested, but it's already loaded. Skipping.")
|
expect(Object.keys(pattern.plugins).length).to.equal(1)
|
||||||
expect(pattern.stores[0].logs.info[3]).to.equal("Plugin `test` was requested, but it's already loaded. Skipping.")
|
expect(Object.keys(pattern.plugins)[0]).to.equal('test')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should log an error of added parts do not have a draft method', () => {
|
it('Should log an error of added parts do not have a draft method', () => {
|
||||||
const design = new Design()
|
const design = new Design()
|
||||||
const pattern = new design()
|
const pattern = new design()
|
||||||
pattern.addPart({})
|
pattern.addPart({})
|
||||||
expect(pattern.stores[0].logs.error.length).to.equal(1)
|
expect(pattern.store.logs.error.length).to.equal(1)
|
||||||
expect(pattern.stores[0].logs.error[0]).to.equal('Part must have a draft() method')
|
expect(pattern.store.logs.error[0]).to.equal('Part must have a draft() method')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Parts in only are never hidden', () => {
|
it('Parts in only are never hidden', () => {
|
||||||
|
@ -138,31 +138,6 @@ describe('Pattern', () => {
|
||||||
expect(pattern.__isStackHidden('test')).to.equal(false)
|
expect(pattern.__isStackHidden('test')).to.equal(false)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Stacks with hidden dependencies should set hidden', () => {
|
|
||||||
const part1 = {
|
|
||||||
name: 'test1',
|
|
||||||
draft: ({ points, Point, paths, Path, part }) => {
|
|
||||||
points.test = new Point(3, 3)
|
|
||||||
|
|
||||||
return part
|
|
||||||
},
|
|
||||||
}
|
|
||||||
const part2 = {
|
|
||||||
name: 'test2',
|
|
||||||
from: part1,
|
|
||||||
hideDependencies: true,
|
|
||||||
draft: ({ points, Point, paths, Path, part }) => {
|
|
||||||
points.test = new Point(3, 3)
|
|
||||||
|
|
||||||
return part
|
|
||||||
},
|
|
||||||
}
|
|
||||||
const design = new Design({ parts: [part2] })
|
|
||||||
const pattern = new design()
|
|
||||||
const config = pattern.getConfig()
|
|
||||||
expect(config.parts[1].hideAll).to.equal(true)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Drafts with errors should not get packed', () => {
|
it('Drafts with errors should not get packed', () => {
|
||||||
const part= {
|
const part= {
|
||||||
name: 'test',
|
name: 'test',
|
||||||
|
@ -176,8 +151,8 @@ describe('Pattern', () => {
|
||||||
const design = new Design({ parts: [part] })
|
const design = new Design({ parts: [part] })
|
||||||
const pattern = new design()
|
const pattern = new design()
|
||||||
pattern.draft().render()
|
pattern.draft().render()
|
||||||
expect(pattern.stores[0].logs.error.length).to.equal(1)
|
expect(pattern.setStores[0].logs.error.length).to.equal(1)
|
||||||
expect(pattern.stores[0].logs.error[0][0]).to.equal('Unable to draft part `test` (set 0)')
|
expect(pattern.setStores[0].logs.error[0][0]).to.equal('Unable to draft part `test` (set 0)')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Handle layout object', () => {
|
it('Handle layout object', () => {
|
||||||
|
|
|
@ -30,7 +30,7 @@ describe('Pattern', () => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
pattern.sample()
|
pattern.sample()
|
||||||
expect(pattern.stores.length).to.equal(10)
|
expect(pattern.setStores.length).to.equal(10)
|
||||||
expect(pattern.settings.length).to.equal(10)
|
expect(pattern.settings.length).to.equal(10)
|
||||||
expect(pattern.parts[9].test.paths.test.ops[1].to.y).to.equal(320)
|
expect(pattern.parts[9].test.paths.test.ops[1].to.y).to.equal(320)
|
||||||
})
|
})
|
||||||
|
@ -59,7 +59,7 @@ describe('Pattern', () => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
pattern.sample()
|
pattern.sample()
|
||||||
expect(pattern.stores.length).to.equal(10)
|
expect(pattern.setStores.length).to.equal(10)
|
||||||
expect(pattern.settings.length).to.equal(10)
|
expect(pattern.settings.length).to.equal(10)
|
||||||
expect(round(pattern.parts[9].test.paths.test.ops[1].to.y)).to.equal(22)
|
expect(round(pattern.parts[9].test.paths.test.ops[1].to.y)).to.equal(22)
|
||||||
})
|
})
|
||||||
|
@ -88,7 +88,7 @@ describe('Pattern', () => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
pattern.sample()
|
pattern.sample()
|
||||||
expect(pattern.stores.length).to.equal(10)
|
expect(pattern.setStores.length).to.equal(10)
|
||||||
expect(pattern.settings.length).to.equal(10)
|
expect(pattern.settings.length).to.equal(10)
|
||||||
expect(pattern.parts[9].test.paths.test.ops[1].to.y).to.equal(400)
|
expect(pattern.parts[9].test.paths.test.ops[1].to.y).to.equal(400)
|
||||||
})
|
})
|
||||||
|
@ -117,7 +117,7 @@ describe('Pattern', () => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
pattern.sample()
|
pattern.sample()
|
||||||
expect(pattern.stores.length).to.equal(10)
|
expect(pattern.setStores.length).to.equal(10)
|
||||||
expect(pattern.settings.length).to.equal(10)
|
expect(pattern.settings.length).to.equal(10)
|
||||||
expect(pattern.parts[9].test.paths.test.ops[1].to.y).to.equal(216)
|
expect(pattern.parts[9].test.paths.test.ops[1].to.y).to.equal(216)
|
||||||
})
|
})
|
||||||
|
@ -146,8 +146,8 @@ describe('Pattern', () => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
pattern.sample()
|
pattern.sample()
|
||||||
expect(pattern.stores[0].logs.error.length).to.equal(1)
|
expect(pattern.store.logs.error.length).to.equal(1)
|
||||||
expect(pattern.stores[0].logs.error[0]).to.equal("Cannot sample measurement `head` because it's `undefined`")
|
expect(pattern.store.logs.error[0]).to.equal("Cannot sample measurement `head` because it's `undefined`")
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should sample models', () => {
|
it('Should sample models', () => {
|
||||||
|
@ -180,7 +180,7 @@ describe('Pattern', () => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
pattern.sample()
|
pattern.sample()
|
||||||
expect(pattern.stores.length).to.equal(4)
|
expect(pattern.setStores.length).to.equal(4)
|
||||||
expect(pattern.settings.length).to.equal(4)
|
expect(pattern.settings.length).to.equal(4)
|
||||||
expect(pattern.parts[3].test.paths.test.ops[1].to.y).to.equal(200)
|
expect(pattern.parts[3].test.paths.test.ops[1].to.y).to.equal(200)
|
||||||
})
|
})
|
||||||
|
@ -217,7 +217,6 @@ describe('Pattern', () => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
pattern.sample();
|
pattern.sample();
|
||||||
console.log(pattern.parts)
|
|
||||||
expect(pattern.parts.front.paths.line_1.ops[1].to.x).to.equal(100);
|
expect(pattern.parts.front.paths.line_1.ops[1].to.x).to.equal(100);
|
||||||
expect(pattern.parts.front.paths.line_2.ops[1].to.x).to.equal(200);
|
expect(pattern.parts.front.paths.line_2.ops[1].to.x).to.equal(200);
|
||||||
expect(pattern.parts.front.paths.line_3.ops[1].to.x).to.equal(300);
|
expect(pattern.parts.front.paths.line_3.ops[1].to.x).to.equal(300);
|
||||||
|
|
|
@ -7,20 +7,28 @@ const measurements = { head: 400 }
|
||||||
const toAbs = (val, { measurements }) => measurements.head * val
|
const toAbs = (val, { measurements }) => measurements.head * val
|
||||||
|
|
||||||
describe('Snapped options', () => {
|
describe('Snapped options', () => {
|
||||||
it('Should snap a percentage options to equal steps', () => {
|
it('Should snap a percentage option to equal steps', () => {
|
||||||
|
let abs
|
||||||
const part = {
|
const part = {
|
||||||
name: 'test',
|
name: 'test',
|
||||||
measurements: ['head'],
|
measurements: ['head'],
|
||||||
options: {
|
options: {
|
||||||
test: { pct: 30, min: 0, max: 100, snap: 12, toAbs },
|
test: { pct: 30, min: 0, max: 100, snap: 12, toAbs },
|
||||||
},
|
},
|
||||||
|
draft: ({ part, absoluteOptions }) => {
|
||||||
|
abs = absoluteOptions
|
||||||
|
return part
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const design = new Design({ parts: [part] })
|
const design = new Design({ parts: [ part] })
|
||||||
const patternA = new design({ options: { test: 0.13 }, measurements }).draft()
|
new design({ options: { test: 0.13 }, measurements, idPrefix: 'A' }).draft()
|
||||||
const patternB = new design({ options: { test: 0.27 }, measurements }).draft()
|
expect(abs.test).to.equal(60)
|
||||||
expect(patternA.settings[0].absoluteOptions.test).to.equal(60)
|
new design({ options: { test: 0.27 }, measurements, idPrefix: 'B' }).draft()
|
||||||
expect(patternB.settings[0].absoluteOptions.test).to.equal(108)
|
expect(abs.test).to.equal(108)
|
||||||
|
new design({ options: { test: 0.71 }, measurements, idPrefix: 'C' }).draft()
|
||||||
|
expect(abs.test).to.equal(288)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should snap a percentage options to the Fibonacci sequence', () => {
|
it('Should snap a percentage options to the Fibonacci sequence', () => {
|
||||||
const part = {
|
const part = {
|
||||||
name: 'test',
|
name: 'test',
|
||||||
|
|
|
@ -266,7 +266,7 @@ describe('Svg', () => {
|
||||||
pattern.on('postRender', (svg) => {
|
pattern.on('postRender', (svg) => {
|
||||||
svg.svg = 'test'
|
svg.svg = 'test'
|
||||||
})
|
})
|
||||||
expect(pattern.render()).to.equal('test')
|
expect(pattern.draft().render()).to.equal('test')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should tab in and out', () => {
|
it('Should tab in and out', () => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue