Refactor, units, tests

This commit is contained in:
Bán Dénes 2021-01-01 00:50:04 +01:00
parent 519c34bc60
commit cd90705ba1
24 changed files with 1221 additions and 1222 deletions

71
src/prepare.js Normal file
View file

@ -0,0 +1,71 @@
const u = require('./utils')
const a = require('./assert')
const unnest = exports.unnest = (config) => {
if (a.type(config)() !== 'object') return config
const result = {}
for (const [key, val] of Object.entries(config)) {
u.deep(result, key, unnest(val))
}
return result
}
const _extend = exports._extend = (to, from) => {
const to_type = a.type(to)()
const from_type = a.type(from)()
if (from === undefined || from === null) return to
if (from === '!!unset') return undefined
if (to_type != from_type) return from
if (from_type == 'object') {
const res = u.deepcopy(to)
for (const key of Object.keys(from)) {
res[key] = _extend(to[key], from[key])
if (res[key] === undefined) delete res[key]
}
return res
} else if (from_type == 'array') {
const res = u.deepcopy(to)
for (const [i, val] of from.entries()) {
res[i] = _extend(res[i], val)
}
return res
} else return from
}
const extend = exports.extend = (...args) => {
let res = args[0]
for (const arg of args) {
if (res == arg) continue
res = _extend(res, arg)
}
return res
}
const _inherit = exports._inherit = (config, root, breadcrumbs) => {
if (a.type(config)() !== 'object') return config
const result = {}
for (const [key, val] of Object.entries(config)) {
breadcrumbs.push(key)
let newval = _inherit(val, root, breadcrumbs)
if (newval && newval.extends !== undefined) {
let candidates = [newval.extends]
const list = [newval]
while (candidates.length) {
const path = candidates.shift()
const other = u.deepcopy(u.deep(root, path))
a.assert(other, `"${path}" (reached from "${breadcrumbs.join('.')}.${key}.extends") does not name a valid target!`)
let parents = other.extends || []
if (a.type(parents)() !== 'array') parents = [parents]
candidates = candidates.concat(parents)
list.unshift(other)
}
newval = extend.apply(this, list)
delete newval.extends
}
result[key] = newval
breadcrumbs.pop()
}
return result
}
const inherit = exports.inherit = (config) => _inherit(config, config, [])