Getting coverage to 100%
This commit is contained in:
parent
b27e10374e
commit
c45523f38a
25 changed files with 2393 additions and 2282 deletions
2993
package-lock.json
generated
2993
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -32,7 +32,8 @@
|
|||
"glob": "^8.1.0",
|
||||
"mocha": "^10.2.0",
|
||||
"nyc": "^15.1.0",
|
||||
"rollup": "^3.10.1"
|
||||
"rollup": "^3.10.1",
|
||||
"sinon": "^15.0.1"
|
||||
},
|
||||
"nyc": {
|
||||
"all": true,
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
### Minor
|
||||
|
||||
- Add full anchor support to individual points (via `adjust`, probably)
|
||||
- Allow footprints to access raw array/object fields from points with templating
|
||||
- Include raw kicad footprint integrations
|
||||
- pull torik's script to be able to convert raw kicad footprints into positionable ergogen ones
|
||||
- have a `dummy` footprint which can just be updated from schematic
|
||||
|
|
|
@ -136,20 +136,15 @@ const whats = {
|
|||
outline
|
||||
}
|
||||
|
||||
const expand_shorthand = (config, units) => {
|
||||
const expand_shorthand = (config, name, units) => {
|
||||
if (a.type(config.expand)(units) == 'string') {
|
||||
const prefix = config.expand.slice(0, -1)
|
||||
const suffix = config.expand.slice(-1)
|
||||
let expand = prefix
|
||||
let joints = 0
|
||||
|
||||
if (suffix == ')') ; // noop
|
||||
else if (suffix == '>') joints = 1
|
||||
else if (suffix == ']') joints = 2
|
||||
else expand = config.expand
|
||||
|
||||
config.expand = parseFloat(expand)
|
||||
config.joints = config.joints || joints
|
||||
const valid_suffixes = [')', '>', ']']
|
||||
a.assert(valid_suffixes.includes(suffix), `If field "${name}" is a string, ` +
|
||||
`it should end with one of [${valid_suffixes.map(s => `'${s}'`).join(', ')}]!`)
|
||||
config.expand = prefix
|
||||
config.joints = config.joints || valid_suffixes.indexOf(suffix)
|
||||
}
|
||||
|
||||
if (a.type(config.joints)(units) == 'string') {
|
||||
|
@ -159,7 +154,7 @@ const expand_shorthand = (config, units) => {
|
|||
}
|
||||
}
|
||||
|
||||
exports.parse = (config = {}, points = {}, units = {}) => {
|
||||
exports.parse = (config, points, units) => {
|
||||
|
||||
// output outlines will be collected here
|
||||
const outlines = {}
|
||||
|
@ -201,7 +196,7 @@ exports.parse = (config = {}, points = {}, units = {}) => {
|
|||
const original_adjust = part.adjust // same as above
|
||||
const adjust = start => anchor(original_adjust || {}, `${name}.adjust`, points, start)(units)
|
||||
const fillet = a.sane(part.fillet || 0, `${name}.fillet`, 'number')(units)
|
||||
expand_shorthand(part, units)
|
||||
expand_shorthand(part, `${name}.expand`, units)
|
||||
const expand = a.sane(part.expand || 0, `${name}.expand`, 'number')(units)
|
||||
const joints = a.in(a.sane(part.joints || 0, `${name}.joints`, 'number')(units), `${name}.joints`, [0, 1, 2])
|
||||
const scale = a.sane(part.scale || 1, `${name}.scale`, 'number')(units)
|
||||
|
|
36
src/pcbs.js
36
src/pcbs.js
|
@ -115,7 +115,7 @@ const kicad_netclass = `
|
|||
)
|
||||
`
|
||||
|
||||
const makerjs2kicad = exports._makerjs2kicad = (model, layer='Edge.Cuts') => {
|
||||
const makerjs2kicad = exports._makerjs2kicad = (model, layer) => {
|
||||
const grs = []
|
||||
const xy = val => `${val[0]} ${-val[1]}`
|
||||
m.model.walk(model, {
|
||||
|
@ -185,30 +185,40 @@ const footprint = exports._footprint = (points, net_indexer, component_indexer,
|
|||
parsed_def = {type: 'boolean', value: param_def}
|
||||
} else if (def_type == 'array') {
|
||||
parsed_def = {type: 'array', value: param_def}
|
||||
} else if (def_type == 'undefined') {
|
||||
} else if (def_type == 'object') {
|
||||
// parsed param definitions also expand to an object
|
||||
// so to detect whether this is an arbitrary object,
|
||||
// we first have to make sure it's not an expanded param def
|
||||
// (this has to be a heuristic, but should be pretty reliable)
|
||||
const defarr = Object.keys(param_def)
|
||||
const already_expanded = defarr.length == 2 && defarr.includes('type') && defarr.includes('value')
|
||||
if (!already_expanded) {
|
||||
parsed_def = {type: 'object', value: param_def}
|
||||
}
|
||||
} else {
|
||||
parsed_def = {type: 'net', value: undefined}
|
||||
}
|
||||
|
||||
// combine default value with potential user override
|
||||
let value = prep.extend(parsed_def.value, params[param_name])
|
||||
let type = parsed_def.type
|
||||
let value = params[param_name] !== undefined ? params[param_name] : parsed_def.value
|
||||
const type = parsed_def.type
|
||||
a.in(type, `${name}.params.${param_name}.type`, [
|
||||
'string', 'number', 'boolean', 'array', 'object', 'net', 'anchor'
|
||||
])
|
||||
|
||||
// templating support, with conversion back to raw datatypes
|
||||
const converters = {
|
||||
string: v => v,
|
||||
number: v => a.sane(v, `${name}.params.${param_name}`, 'number')(units),
|
||||
boolean: v => v === 'true',
|
||||
net: v => v,
|
||||
anchor: v => v,
|
||||
array: v => v
|
||||
boolean: v => v === 'true'
|
||||
}
|
||||
if (a.type(value)() == 'string') {
|
||||
if (a.type(value)() == 'string' && Object.keys(converters).includes(type)) {
|
||||
value = u.template(value, point.meta)
|
||||
value = converters[type](value)
|
||||
}
|
||||
|
||||
// type-specific processing
|
||||
if (['string', 'number', 'boolean', 'array'].includes(type)) {
|
||||
if (['string', 'number', 'boolean', 'array', 'object'].includes(type)) {
|
||||
parsed_params[param_name] = value
|
||||
} else if (type == 'net') {
|
||||
const net = a.sane(value, `${name}.params.${param_name}`, 'string')(units)
|
||||
|
@ -218,8 +228,8 @@ const footprint = exports._footprint = (points, net_indexer, component_indexer,
|
|||
index: index,
|
||||
str: `(net ${index} "${net}")`
|
||||
}
|
||||
} else if (type == 'anchor') {
|
||||
let parsed_anchor = anchor(value || {}, `${name}.params.${param_name}`, points, point)(units)
|
||||
} else { // anchor
|
||||
let parsed_anchor = anchor(value, `${name}.params.${param_name}`, points, point)(units)
|
||||
parsed_anchor.y = -parsed_anchor.y // kicad mirror, as per usual
|
||||
parsed_params[param_name] = parsed_anchor
|
||||
}
|
||||
|
@ -236,7 +246,7 @@ const footprint = exports._footprint = (points, net_indexer, component_indexer,
|
|||
const sign = point.meta.mirrored ? -1 : 1
|
||||
return `${sign * x} ${y}`
|
||||
}
|
||||
const xyfunc = (x, y, resist=true) => {
|
||||
const xyfunc = (x, y, resist) => {
|
||||
const new_anchor = anchor({
|
||||
shift: [x, -y],
|
||||
resist: resist
|
||||
|
|
|
@ -244,7 +244,7 @@ const render_zone = exports._render_zone = (zone_name, zone, anchor, global_key,
|
|||
|
||||
const parse_axis = exports._parse_axis = (config, name, points, units) => {
|
||||
if (!['number', 'undefined'].includes(a.type(config)(units))) {
|
||||
const mirror_obj = a.sane(config || {}, name, 'object')()
|
||||
const mirror_obj = a.sane(config, name, 'object')()
|
||||
const distance = a.sane(mirror_obj.distance || 0, `${name}.distance`, 'number')(units)
|
||||
delete mirror_obj.distance
|
||||
let axis = anchor_lib.parse(mirror_obj, name, points)(units).x
|
||||
|
@ -254,21 +254,18 @@ const parse_axis = exports._parse_axis = (config, name, points, units) => {
|
|||
}
|
||||
|
||||
const perform_mirror = exports._perform_mirror = (point, axis) => {
|
||||
if (axis !== undefined) {
|
||||
point.meta.mirrored = false
|
||||
if (point.meta.asym == 'source') return ['', null]
|
||||
const mp = point.clone().mirror(axis)
|
||||
const mirrored_name = `mirror_${point.meta.name}`
|
||||
mp.meta = prep.extend(mp.meta, mp.meta.mirror || {})
|
||||
mp.meta.name = mirrored_name
|
||||
mp.meta.colrow = `mirror_${mp.meta.colrow}`
|
||||
mp.meta.mirrored = true
|
||||
if (point.meta.asym == 'clone') {
|
||||
point.meta.skip = true
|
||||
}
|
||||
return [mirrored_name, mp]
|
||||
point.meta.mirrored = false
|
||||
if (point.meta.asym == 'source') return ['', null]
|
||||
const mp = point.clone().mirror(axis)
|
||||
const mirrored_name = `mirror_${point.meta.name}`
|
||||
mp.meta = prep.extend(mp.meta, mp.meta.mirror || {})
|
||||
mp.meta.name = mirrored_name
|
||||
mp.meta.colrow = `mirror_${mp.meta.colrow}`
|
||||
mp.meta.mirrored = true
|
||||
if (point.meta.asym == 'clone') {
|
||||
point.meta.skip = true
|
||||
}
|
||||
return ['', null]
|
||||
return [mirrored_name, mp]
|
||||
}
|
||||
|
||||
exports.parse = (config, units) => {
|
||||
|
@ -300,13 +297,11 @@ exports.parse = (config, units) => {
|
|||
|
||||
// simplifying the names in individual point "zones" and single-key columns
|
||||
while (Object.keys(new_points).some(k => k.endsWith('_default'))) {
|
||||
for (const key of Object.keys(new_points)) {
|
||||
if (key.endsWith('_default')) {
|
||||
const new_key = key.slice(0, -8)
|
||||
new_points[new_key] = new_points[key]
|
||||
new_points[new_key].meta.name = new_key
|
||||
delete new_points[key]
|
||||
}
|
||||
for (const key of Object.keys(new_points).filter(k => k.endsWith('_default'))) {
|
||||
const new_key = key.slice(0, -8)
|
||||
new_points[new_key] = new_points[key]
|
||||
new_points[new_key].meta.name = new_key
|
||||
delete new_points[key]
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -352,7 +347,7 @@ exports.parse = (config, units) => {
|
|||
const global_axis = parse_axis(global_mirror, `points.mirror`, points, units)
|
||||
const global_mirrored_points = {}
|
||||
for (const point of Object.values(points)) {
|
||||
if (global_axis !== undefined && point.mirrored === undefined) {
|
||||
if (global_axis !== undefined && point.meta.mirrored === undefined) {
|
||||
const [mname, mp] = perform_mirror(point, global_axis)
|
||||
if (mp) {
|
||||
global_mirrored_points[mname] = mp
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
(page A3)
|
||||
(title_block
|
||||
(title _export)
|
||||
(rev v1.0.0)
|
||||
(company Unknown)
|
||||
(rev v3.14)
|
||||
(company MrZealot)
|
||||
)
|
||||
|
||||
(general
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
(page A3)
|
||||
(title_block
|
||||
(title export)
|
||||
(rev v1.0.0)
|
||||
(company Unknown)
|
||||
(rev v3.14)
|
||||
(company MrZealot)
|
||||
)
|
||||
|
||||
(general
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
meta:
|
||||
author: MrZealot
|
||||
version: v3.14
|
||||
units:
|
||||
a: 28 + u
|
||||
points:
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
meta:
|
||||
author: MrZealot
|
||||
version: v3.14
|
||||
units:
|
||||
a: 28 + u
|
||||
points.zones.matrix:
|
||||
|
|
3
test/fixtures/big.yaml
vendored
3
test/fixtures/big.yaml
vendored
|
@ -1,3 +1,6 @@
|
|||
meta:
|
||||
author: MrZealot
|
||||
version: v3.14
|
||||
units:
|
||||
a: 28 + u
|
||||
points.zones.matrix:
|
||||
|
|
|
@ -107,6 +107,32 @@ exports.inject = (ergogen) => {
|
|||
}
|
||||
})
|
||||
|
||||
ergogen.inject('footprint', 'arrobj_test', {
|
||||
params: {
|
||||
designator: 'T',
|
||||
side: 'F',
|
||||
start: {x: 0, y: 0},
|
||||
end: [[1, 0], [0, 1]]
|
||||
},
|
||||
body: p => {
|
||||
lines = ''
|
||||
for (const item of p.end) {
|
||||
lines += `(fp_line (start ${p.start.x} ${p.start.y}) (end ${item[0]} ${item[1]}) (layer Dwgs.User) (width 0.05))\n`
|
||||
}
|
||||
return `
|
||||
|
||||
(module arrobj_test (layer ${p.side}.Cu) (tedit 5CF31DEF)
|
||||
|
||||
${p.at /* parametric position */}
|
||||
|
||||
${lines}
|
||||
|
||||
)
|
||||
|
||||
`
|
||||
}
|
||||
})
|
||||
|
||||
ergogen.inject('references_test', {
|
||||
params: {},
|
||||
body: p => {
|
||||
|
|
|
@ -1,4 +1,12 @@
|
|||
global.chai = require('chai')
|
||||
global.chai.use(require('chai-as-promised'))
|
||||
global.expect = global.chai.expect
|
||||
global.should = global.chai.should()
|
||||
global.should = global.chai.should()
|
||||
global.sinon = require('sinon')
|
||||
|
||||
// Restore the default sandbox after every test
|
||||
exports.mochaHooks = {
|
||||
afterEach() {
|
||||
sinon.restore()
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@ require('./helpers/mock_footprints').inject(ergogen)
|
|||
|
||||
let what = process.env.npm_config_what
|
||||
const dump = process.env.npm_config_dump
|
||||
const lineends = /(?:\r\n|\r|\n)/g
|
||||
|
||||
|
||||
|
||||
|
@ -30,6 +31,19 @@ for (const unit of glob.sync(path.join(__dirname, 'unit', '*.js'))) {
|
|||
// as well as individual tests using slash-notation (like `points/default`)
|
||||
// the --dump switch can output the new results, overriding the old reference
|
||||
|
||||
const dump_structure = (obj, depth=-1, prefix='', breadcrumbs=[]) => {
|
||||
if (a.type(obj)() != 'object') {
|
||||
console.log(prefix + breadcrumbs.join('_'))
|
||||
return
|
||||
}
|
||||
if (depth == 0) return
|
||||
for (const [key, val] of Object.entries(obj)) {
|
||||
breadcrumbs.push(key)
|
||||
dump_structure(val, depth-1, prefix, breadcrumbs)
|
||||
breadcrumbs.pop()
|
||||
}
|
||||
}
|
||||
|
||||
const cap = s => s.charAt(0).toUpperCase() + s.slice(1)
|
||||
|
||||
const test = function(input_path) {
|
||||
|
@ -37,33 +51,52 @@ const test = function(input_path) {
|
|||
this.slow(120000)
|
||||
title = path.basename(input_path, '.yaml').split('_').join(' ')
|
||||
it(title, async function() {
|
||||
|
||||
const input = yaml.load(fs.readFileSync(input_path).toString())
|
||||
const base = path.join(path.dirname(input_path), path.basename(input_path, '.yaml'))
|
||||
const references = glob.sync(base + '___*')
|
||||
|
||||
// handle deliberately wrong inputs
|
||||
const exception = base + '___EXCEPTION.txt'
|
||||
if (fs.existsSync(exception)) {
|
||||
const exception_snippet = fs.readFileSync(exception).toString()
|
||||
return await ergogen.process(input, true).should.be.rejectedWith(exception_snippet)
|
||||
}
|
||||
|
||||
const output = await ergogen.process(input, true)
|
||||
|
||||
// compare output vs. reference
|
||||
const base = path.join(path.dirname(input_path), path.basename(input_path, '.yaml'))
|
||||
for (const expected_path of glob.sync(base + '___*')) {
|
||||
let expected = fs.readFileSync(expected_path).toString()
|
||||
if (expected_path.endsWith('.json')) {
|
||||
expected = JSON.parse(expected)
|
||||
}
|
||||
const comp_path = expected_path.split('___')[1].split('.')[0].split('_').join('.')
|
||||
const output_part = u.deep(output, comp_path)
|
||||
if (dump) {
|
||||
if (a.type(output_part)() == 'string') {
|
||||
fs.writeFileSync(expected_path, output_part)
|
||||
} else {
|
||||
fs.writeJSONSync(expected_path, output_part, {spaces: 4})
|
||||
if (references.length) {
|
||||
for (const expected_path of references) {
|
||||
let expected = fs.readFileSync(expected_path).toString()
|
||||
if (expected_path.endsWith('.json')) {
|
||||
expected = JSON.parse(expected)
|
||||
}
|
||||
} else {
|
||||
if (a.type(output_part)() == 'string') {
|
||||
const parse_out = output_part.replace(/(?:\r\n|\r|\n)/g,"\n")
|
||||
const parse_exp = expected.replace(/(?:\r\n|\r|\n)/g,"\n")
|
||||
parse_out.should.deep.equal(parse_exp)
|
||||
const comp_path = expected_path.split('___')[1].split('.')[0].split('_').join('.')
|
||||
const output_part = u.deep(output, comp_path)
|
||||
if (dump) {
|
||||
if (a.type(output_part)() == 'string') {
|
||||
fs.writeFileSync(expected_path, output_part)
|
||||
} else {
|
||||
fs.writeJSONSync(expected_path, output_part, {spaces: 4})
|
||||
}
|
||||
} else {
|
||||
output_part.should.deep.equal(expected)
|
||||
if (a.type(output_part)() == 'string') {
|
||||
const parse_out = output_part.replace(lineends, '\n')
|
||||
const parse_exp = expected.replace(lineends, '\n')
|
||||
parse_out.should.deep.equal(parse_exp)
|
||||
} else {
|
||||
// JSON can hide negative zeroes, for example, so we canonical-ize first
|
||||
const canonical_part = JSON.parse(JSON.stringify(output_part))
|
||||
canonical_part.should.deep.equal(expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// explicit dump-ing above only works, if there are already files with the right name
|
||||
// if there aren't, dump now outputs a list of candidates that could be referenced
|
||||
} else if (dump) {
|
||||
dump_structure(output, 3, base + '___')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -140,17 +173,17 @@ for (let w of cli_what) {
|
|||
}
|
||||
const comp_res = dircompare.compareSync(output_path, ref_path, {
|
||||
compareContent: true,
|
||||
ignoreLineEnding: true,
|
||||
compareFileSync: dircompare.fileCompareHandlers.lineBasedFileCompare.compareSync,
|
||||
compareFileAsync: dircompare.fileCompareHandlers.lineBasedFileCompare.compareAsync,
|
||||
ignoreLineEnding: true
|
||||
compareFileAsync: dircompare.fileCompareHandlers.lineBasedFileCompare.compareAsync
|
||||
})
|
||||
if (dump) {
|
||||
fs.moveSync(output_path, ref_path, {overwrite: true})
|
||||
} else {
|
||||
fs.removeSync(output_path)
|
||||
}
|
||||
const parse_act_log = actual_log.replace(/(?:\r\n|\r|\n)/g,"\n")
|
||||
const parse_ref_log = ref_log.replace(/(?:\r\n|\r|\n)/g,"\n")
|
||||
const parse_act_log = actual_log.replace(lineends, '\n')
|
||||
const parse_ref_log = ref_log.replace(lineends, '\n')
|
||||
parse_act_log.should.equal(parse_ref_log)
|
||||
comp_res.same.should.be.true
|
||||
// deliberately incorrect execution
|
||||
|
|
|
@ -39,3 +39,8 @@ pcbs:
|
|||
what: anchor_test
|
||||
params:
|
||||
end: matrix
|
||||
arrobj:
|
||||
what: arrobj_test
|
||||
params:
|
||||
start: {x: 5, y: 5}
|
||||
end: [[6, 6], [7, 7]]
|
||||
|
|
|
@ -242,6 +242,19 @@
|
|||
)
|
||||
|
||||
|
||||
|
||||
|
||||
(module arrobj_test (layer F.Cu) (tedit 5CF31DEF)
|
||||
|
||||
(at 0 0 0)
|
||||
|
||||
(fp_line (start 5 5) (end 6 6) (layer Dwgs.User) (width 0.05))
|
||||
(fp_line (start 5 5) (end 7 7) (layer Dwgs.User) (width 0.05))
|
||||
|
||||
|
||||
)
|
||||
|
||||
|
||||
(gr_line (start -9.5 9.5) (end 9.5 9.5) (angle 90) (layer Edge.Cuts) (width 0.15))
|
||||
(gr_line (start 9.5 9.5) (end 9.5 -9.5) (angle 90) (layer Edge.Cuts) (width 0.15))
|
||||
(gr_line (start 9.5 -9.5) (end -9.5 -9.5) (angle 90) (layer Edge.Cuts) (width 0.15))
|
||||
|
|
24
test/points/autobind.yaml
Normal file
24
test/points/autobind.yaml
Normal file
|
@ -0,0 +1,24 @@
|
|||
points.zones:
|
||||
none:
|
||||
key:
|
||||
autobind: 0
|
||||
columns:
|
||||
a:
|
||||
b:
|
||||
some:
|
||||
key:
|
||||
autobind: 1
|
||||
columns:
|
||||
a:
|
||||
b:
|
||||
outlines:
|
||||
none:
|
||||
- what: rectangle
|
||||
where: /none_.*/
|
||||
size: 5
|
||||
bound: true
|
||||
some:
|
||||
- what: rectangle
|
||||
where: /some_.*/
|
||||
size: 5
|
||||
bound: true
|
146
test/points/autobind___outlines_none_dxf.dxf
Normal file
146
test/points/autobind___outlines_none_dxf.dxf
Normal file
|
@ -0,0 +1,146 @@
|
|||
0
|
||||
SECTION
|
||||
2
|
||||
HEADER
|
||||
9
|
||||
$INSUNITS
|
||||
70
|
||||
4
|
||||
0
|
||||
ENDSEC
|
||||
0
|
||||
SECTION
|
||||
2
|
||||
TABLES
|
||||
0
|
||||
TABLE
|
||||
2
|
||||
LTYPE
|
||||
0
|
||||
LTYPE
|
||||
72
|
||||
65
|
||||
70
|
||||
64
|
||||
2
|
||||
CONTINUOUS
|
||||
3
|
||||
______
|
||||
73
|
||||
0
|
||||
40
|
||||
0
|
||||
0
|
||||
ENDTAB
|
||||
0
|
||||
TABLE
|
||||
2
|
||||
LAYER
|
||||
0
|
||||
ENDTAB
|
||||
0
|
||||
ENDSEC
|
||||
0
|
||||
SECTION
|
||||
2
|
||||
ENTITIES
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
-2.5
|
||||
20
|
||||
-2.5
|
||||
11
|
||||
2.5
|
||||
21
|
||||
-2.5
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
2.5
|
||||
20
|
||||
-2.5
|
||||
11
|
||||
2.5
|
||||
21
|
||||
2.5
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
2.5
|
||||
20
|
||||
2.5
|
||||
11
|
||||
-2.5
|
||||
21
|
||||
2.5
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
-2.5
|
||||
20
|
||||
2.5
|
||||
11
|
||||
-2.5
|
||||
21
|
||||
-2.5
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
16.5
|
||||
20
|
||||
-2.5
|
||||
11
|
||||
21.5
|
||||
21
|
||||
-2.5
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
21.5
|
||||
20
|
||||
-2.5
|
||||
11
|
||||
21.5
|
||||
21
|
||||
2.5
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
21.5
|
||||
20
|
||||
2.5
|
||||
11
|
||||
16.5
|
||||
21
|
||||
2.5
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
16.5
|
||||
20
|
||||
2.5
|
||||
11
|
||||
16.5
|
||||
21
|
||||
-2.5
|
||||
0
|
||||
ENDSEC
|
||||
0
|
||||
EOF
|
146
test/points/autobind___outlines_some_dxf.dxf
Normal file
146
test/points/autobind___outlines_some_dxf.dxf
Normal file
|
@ -0,0 +1,146 @@
|
|||
0
|
||||
SECTION
|
||||
2
|
||||
HEADER
|
||||
9
|
||||
$INSUNITS
|
||||
70
|
||||
4
|
||||
0
|
||||
ENDSEC
|
||||
0
|
||||
SECTION
|
||||
2
|
||||
TABLES
|
||||
0
|
||||
TABLE
|
||||
2
|
||||
LTYPE
|
||||
0
|
||||
LTYPE
|
||||
72
|
||||
65
|
||||
70
|
||||
64
|
||||
2
|
||||
CONTINUOUS
|
||||
3
|
||||
______
|
||||
73
|
||||
0
|
||||
40
|
||||
0
|
||||
0
|
||||
ENDTAB
|
||||
0
|
||||
TABLE
|
||||
2
|
||||
LAYER
|
||||
0
|
||||
ENDTAB
|
||||
0
|
||||
ENDSEC
|
||||
0
|
||||
SECTION
|
||||
2
|
||||
ENTITIES
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
-2.5
|
||||
20
|
||||
-2.5
|
||||
11
|
||||
3.5
|
||||
21
|
||||
-2.5
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
-2.5
|
||||
20
|
||||
2.5
|
||||
11
|
||||
3.5
|
||||
21
|
||||
2.5
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
-2.5
|
||||
20
|
||||
2.5
|
||||
11
|
||||
-2.5
|
||||
21
|
||||
-2.5
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
3.5
|
||||
20
|
||||
-2.5
|
||||
11
|
||||
3.5
|
||||
21
|
||||
2.5
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
15.5
|
||||
20
|
||||
-2.5
|
||||
11
|
||||
21.5
|
||||
21
|
||||
-2.5
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
21.5
|
||||
20
|
||||
-2.5
|
||||
11
|
||||
21.5
|
||||
21
|
||||
2.5
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
15.5
|
||||
20
|
||||
2.5
|
||||
11
|
||||
21.5
|
||||
21
|
||||
2.5
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
15.5
|
||||
20
|
||||
-2.5
|
||||
11
|
||||
15.5
|
||||
21
|
||||
2.5
|
||||
0
|
||||
ENDSEC
|
||||
0
|
||||
EOF
|
|
@ -13,3 +13,18 @@ points:
|
|||
rows:
|
||||
bottom:
|
||||
top:
|
||||
other:
|
||||
anchor:
|
||||
ref: matrix_right_top
|
||||
shift: [100, 100]
|
||||
# default mirror object, ref = [0, 0], distance = 0
|
||||
mirror: {}
|
||||
columns:
|
||||
left:
|
||||
rows:
|
||||
bottom.asym: source
|
||||
top.asym: clone
|
||||
right:
|
||||
rows:
|
||||
bottom:
|
||||
top:
|
||||
|
|
|
@ -193,6 +193,294 @@ LINE
|
|||
8
|
||||
0
|
||||
10
|
||||
110
|
||||
20
|
||||
128
|
||||
11
|
||||
128
|
||||
21
|
||||
128
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
128
|
||||
20
|
||||
128
|
||||
11
|
||||
128
|
||||
21
|
||||
110
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
128
|
||||
20
|
||||
110
|
||||
11
|
||||
110
|
||||
21
|
||||
110
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
110
|
||||
20
|
||||
110
|
||||
11
|
||||
110
|
||||
21
|
||||
128
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
129
|
||||
20
|
||||
128
|
||||
11
|
||||
147
|
||||
21
|
||||
128
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
147
|
||||
20
|
||||
128
|
||||
11
|
||||
147
|
||||
21
|
||||
110
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
147
|
||||
20
|
||||
110
|
||||
11
|
||||
129
|
||||
21
|
||||
110
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
129
|
||||
20
|
||||
110
|
||||
11
|
||||
129
|
||||
21
|
||||
128
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
129
|
||||
20
|
||||
147
|
||||
11
|
||||
147
|
||||
21
|
||||
147
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
147
|
||||
20
|
||||
147
|
||||
11
|
||||
147
|
||||
21
|
||||
129
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
147
|
||||
20
|
||||
129
|
||||
11
|
||||
129
|
||||
21
|
||||
129
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
129
|
||||
20
|
||||
129
|
||||
11
|
||||
129
|
||||
21
|
||||
147
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
-128
|
||||
20
|
||||
147
|
||||
11
|
||||
-110
|
||||
21
|
||||
147
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
-110
|
||||
20
|
||||
147
|
||||
11
|
||||
-110
|
||||
21
|
||||
129
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
-110
|
||||
20
|
||||
129
|
||||
11
|
||||
-128
|
||||
21
|
||||
129
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
-128
|
||||
20
|
||||
129
|
||||
11
|
||||
-128
|
||||
21
|
||||
147
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
-147
|
||||
20
|
||||
128
|
||||
11
|
||||
-129
|
||||
21
|
||||
128
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
-129
|
||||
20
|
||||
128
|
||||
11
|
||||
-129
|
||||
21
|
||||
110
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
-129
|
||||
20
|
||||
110
|
||||
11
|
||||
-147
|
||||
21
|
||||
110
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
-147
|
||||
20
|
||||
110
|
||||
11
|
||||
-147
|
||||
21
|
||||
128
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
-147
|
||||
20
|
||||
147
|
||||
11
|
||||
-129
|
||||
21
|
||||
147
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
-129
|
||||
20
|
||||
147
|
||||
11
|
||||
-129
|
||||
21
|
||||
129
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
-129
|
||||
20
|
||||
129
|
||||
11
|
||||
-147
|
||||
21
|
||||
129
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
-147
|
||||
20
|
||||
129
|
||||
11
|
||||
-147
|
||||
21
|
||||
147
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
48.05
|
||||
20
|
||||
28
|
||||
|
|
786
test/points/mirrors___points.json
Normal file
786
test/points/mirrors___points.json
Normal file
|
@ -0,0 +1,786 @@
|
|||
{
|
||||
"matrix_left_bottom": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"r": 0,
|
||||
"meta": {
|
||||
"stagger": 0,
|
||||
"spread": 19,
|
||||
"splay": 0,
|
||||
"origin": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"orient": 0,
|
||||
"shift": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"rotate": 0,
|
||||
"width": 18,
|
||||
"height": 18,
|
||||
"padding": 19,
|
||||
"autobind": 10,
|
||||
"skip": false,
|
||||
"asym": "source",
|
||||
"colrow": "left_bottom",
|
||||
"name": "matrix_left_bottom",
|
||||
"zone": {
|
||||
"columns": {
|
||||
"left": {
|
||||
"rows": {
|
||||
"bottom": {
|
||||
"asym": "source"
|
||||
},
|
||||
"top": {
|
||||
"asym": "clone"
|
||||
}
|
||||
},
|
||||
"key": {},
|
||||
"name": "left"
|
||||
},
|
||||
"right": null
|
||||
},
|
||||
"rows": {
|
||||
"bottom": {},
|
||||
"top": {}
|
||||
},
|
||||
"name": "matrix"
|
||||
},
|
||||
"col": {
|
||||
"rows": {
|
||||
"bottom": {
|
||||
"asym": "source"
|
||||
},
|
||||
"top": {
|
||||
"asym": "clone"
|
||||
}
|
||||
},
|
||||
"key": {},
|
||||
"name": "left"
|
||||
},
|
||||
"row": "bottom",
|
||||
"bind": [
|
||||
10,
|
||||
10,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"mirrored": false
|
||||
}
|
||||
},
|
||||
"matrix_right_bottom": {
|
||||
"x": 19,
|
||||
"y": 0,
|
||||
"r": 0,
|
||||
"meta": {
|
||||
"stagger": 0,
|
||||
"spread": 19,
|
||||
"splay": 0,
|
||||
"origin": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"orient": 0,
|
||||
"shift": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"rotate": 0,
|
||||
"width": 18,
|
||||
"height": 18,
|
||||
"padding": 19,
|
||||
"autobind": 10,
|
||||
"skip": false,
|
||||
"asym": "both",
|
||||
"colrow": "right_bottom",
|
||||
"name": "matrix_right_bottom",
|
||||
"zone": {
|
||||
"columns": {
|
||||
"left": {
|
||||
"rows": {
|
||||
"bottom": {
|
||||
"asym": "source"
|
||||
},
|
||||
"top": {
|
||||
"asym": "clone"
|
||||
}
|
||||
},
|
||||
"key": {},
|
||||
"name": "left"
|
||||
},
|
||||
"right": null
|
||||
},
|
||||
"rows": {
|
||||
"bottom": {},
|
||||
"top": {}
|
||||
},
|
||||
"name": "matrix"
|
||||
},
|
||||
"col": {
|
||||
"rows": {},
|
||||
"key": {},
|
||||
"name": "right"
|
||||
},
|
||||
"row": "bottom",
|
||||
"bind": [
|
||||
10,
|
||||
0,
|
||||
0,
|
||||
10
|
||||
],
|
||||
"mirrored": false
|
||||
}
|
||||
},
|
||||
"matrix_right_top": {
|
||||
"x": 19,
|
||||
"y": 19,
|
||||
"r": 0,
|
||||
"meta": {
|
||||
"stagger": 0,
|
||||
"spread": 19,
|
||||
"splay": 0,
|
||||
"origin": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"orient": 0,
|
||||
"shift": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"rotate": 0,
|
||||
"width": 18,
|
||||
"height": 18,
|
||||
"padding": 19,
|
||||
"autobind": 10,
|
||||
"skip": false,
|
||||
"asym": "both",
|
||||
"colrow": "right_top",
|
||||
"name": "matrix_right_top",
|
||||
"zone": {
|
||||
"columns": {
|
||||
"left": {
|
||||
"rows": {
|
||||
"bottom": {
|
||||
"asym": "source"
|
||||
},
|
||||
"top": {
|
||||
"asym": "clone"
|
||||
}
|
||||
},
|
||||
"key": {},
|
||||
"name": "left"
|
||||
},
|
||||
"right": null
|
||||
},
|
||||
"rows": {
|
||||
"bottom": {},
|
||||
"top": {}
|
||||
},
|
||||
"name": "matrix"
|
||||
},
|
||||
"col": {
|
||||
"rows": {},
|
||||
"key": {},
|
||||
"name": "right"
|
||||
},
|
||||
"row": "top",
|
||||
"bind": [
|
||||
0,
|
||||
0,
|
||||
10,
|
||||
10
|
||||
],
|
||||
"mirrored": false
|
||||
}
|
||||
},
|
||||
"other_left_bottom": {
|
||||
"x": 119,
|
||||
"y": 119,
|
||||
"r": 0,
|
||||
"meta": {
|
||||
"stagger": 0,
|
||||
"spread": 19,
|
||||
"splay": 0,
|
||||
"origin": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"orient": 0,
|
||||
"shift": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"rotate": 0,
|
||||
"width": 18,
|
||||
"height": 18,
|
||||
"padding": 19,
|
||||
"autobind": 10,
|
||||
"skip": false,
|
||||
"asym": "source",
|
||||
"colrow": "left_bottom",
|
||||
"name": "other_left_bottom",
|
||||
"zone": {
|
||||
"columns": {
|
||||
"left": {
|
||||
"rows": {
|
||||
"bottom": {
|
||||
"asym": "source"
|
||||
},
|
||||
"top": {
|
||||
"asym": "clone"
|
||||
}
|
||||
},
|
||||
"key": {},
|
||||
"name": "left"
|
||||
},
|
||||
"right": null
|
||||
},
|
||||
"rows": {
|
||||
"bottom": {},
|
||||
"top": {}
|
||||
},
|
||||
"name": "other"
|
||||
},
|
||||
"col": {
|
||||
"rows": {
|
||||
"bottom": {
|
||||
"asym": "source"
|
||||
},
|
||||
"top": {
|
||||
"asym": "clone"
|
||||
}
|
||||
},
|
||||
"key": {},
|
||||
"name": "left"
|
||||
},
|
||||
"row": "bottom",
|
||||
"bind": [
|
||||
10,
|
||||
10,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"mirrored": false
|
||||
}
|
||||
},
|
||||
"other_right_bottom": {
|
||||
"x": 138,
|
||||
"y": 119,
|
||||
"r": 0,
|
||||
"meta": {
|
||||
"stagger": 0,
|
||||
"spread": 19,
|
||||
"splay": 0,
|
||||
"origin": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"orient": 0,
|
||||
"shift": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"rotate": 0,
|
||||
"width": 18,
|
||||
"height": 18,
|
||||
"padding": 19,
|
||||
"autobind": 10,
|
||||
"skip": false,
|
||||
"asym": "both",
|
||||
"colrow": "right_bottom",
|
||||
"name": "other_right_bottom",
|
||||
"zone": {
|
||||
"columns": {
|
||||
"left": {
|
||||
"rows": {
|
||||
"bottom": {
|
||||
"asym": "source"
|
||||
},
|
||||
"top": {
|
||||
"asym": "clone"
|
||||
}
|
||||
},
|
||||
"key": {},
|
||||
"name": "left"
|
||||
},
|
||||
"right": null
|
||||
},
|
||||
"rows": {
|
||||
"bottom": {},
|
||||
"top": {}
|
||||
},
|
||||
"name": "other"
|
||||
},
|
||||
"col": {
|
||||
"rows": {},
|
||||
"key": {},
|
||||
"name": "right"
|
||||
},
|
||||
"row": "bottom",
|
||||
"bind": [
|
||||
10,
|
||||
0,
|
||||
0,
|
||||
10
|
||||
],
|
||||
"mirrored": false
|
||||
}
|
||||
},
|
||||
"other_right_top": {
|
||||
"x": 138,
|
||||
"y": 138,
|
||||
"r": 0,
|
||||
"meta": {
|
||||
"stagger": 0,
|
||||
"spread": 19,
|
||||
"splay": 0,
|
||||
"origin": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"orient": 0,
|
||||
"shift": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"rotate": 0,
|
||||
"width": 18,
|
||||
"height": 18,
|
||||
"padding": 19,
|
||||
"autobind": 10,
|
||||
"skip": false,
|
||||
"asym": "both",
|
||||
"colrow": "right_top",
|
||||
"name": "other_right_top",
|
||||
"zone": {
|
||||
"columns": {
|
||||
"left": {
|
||||
"rows": {
|
||||
"bottom": {
|
||||
"asym": "source"
|
||||
},
|
||||
"top": {
|
||||
"asym": "clone"
|
||||
}
|
||||
},
|
||||
"key": {},
|
||||
"name": "left"
|
||||
},
|
||||
"right": null
|
||||
},
|
||||
"rows": {
|
||||
"bottom": {},
|
||||
"top": {}
|
||||
},
|
||||
"name": "other"
|
||||
},
|
||||
"col": {
|
||||
"rows": {},
|
||||
"key": {},
|
||||
"name": "right"
|
||||
},
|
||||
"row": "top",
|
||||
"bind": [
|
||||
0,
|
||||
0,
|
||||
10,
|
||||
10
|
||||
],
|
||||
"mirrored": false
|
||||
}
|
||||
},
|
||||
"mirror_other_left_top": {
|
||||
"x": -119,
|
||||
"y": 138,
|
||||
"r": 0,
|
||||
"meta": {
|
||||
"stagger": 0,
|
||||
"spread": 19,
|
||||
"splay": 0,
|
||||
"origin": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"orient": 0,
|
||||
"shift": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"rotate": 0,
|
||||
"width": 18,
|
||||
"height": 18,
|
||||
"padding": 19,
|
||||
"autobind": 10,
|
||||
"skip": false,
|
||||
"asym": "clone",
|
||||
"colrow": "mirror_left_top",
|
||||
"name": "mirror_other_left_top",
|
||||
"zone": {
|
||||
"columns": {
|
||||
"left": {
|
||||
"rows": {
|
||||
"bottom": {
|
||||
"asym": "source"
|
||||
},
|
||||
"top": {
|
||||
"asym": "clone"
|
||||
}
|
||||
},
|
||||
"key": {},
|
||||
"name": "left"
|
||||
},
|
||||
"right": null
|
||||
},
|
||||
"rows": {
|
||||
"bottom": {},
|
||||
"top": {}
|
||||
},
|
||||
"name": "other"
|
||||
},
|
||||
"col": {
|
||||
"rows": {
|
||||
"bottom": {
|
||||
"asym": "source"
|
||||
},
|
||||
"top": {
|
||||
"asym": "clone"
|
||||
}
|
||||
},
|
||||
"key": {},
|
||||
"name": "left"
|
||||
},
|
||||
"row": "top",
|
||||
"bind": [
|
||||
0,
|
||||
10,
|
||||
10,
|
||||
0
|
||||
],
|
||||
"mirrored": true
|
||||
}
|
||||
},
|
||||
"mirror_other_right_bottom": {
|
||||
"x": -138,
|
||||
"y": 119,
|
||||
"r": 0,
|
||||
"meta": {
|
||||
"stagger": 0,
|
||||
"spread": 19,
|
||||
"splay": 0,
|
||||
"origin": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"orient": 0,
|
||||
"shift": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"rotate": 0,
|
||||
"width": 18,
|
||||
"height": 18,
|
||||
"padding": 19,
|
||||
"autobind": 10,
|
||||
"skip": false,
|
||||
"asym": "both",
|
||||
"colrow": "mirror_right_bottom",
|
||||
"name": "mirror_other_right_bottom",
|
||||
"zone": {
|
||||
"columns": {
|
||||
"left": {
|
||||
"rows": {
|
||||
"bottom": {
|
||||
"asym": "source"
|
||||
},
|
||||
"top": {
|
||||
"asym": "clone"
|
||||
}
|
||||
},
|
||||
"key": {},
|
||||
"name": "left"
|
||||
},
|
||||
"right": null
|
||||
},
|
||||
"rows": {
|
||||
"bottom": {},
|
||||
"top": {}
|
||||
},
|
||||
"name": "other"
|
||||
},
|
||||
"col": {
|
||||
"rows": {},
|
||||
"key": {},
|
||||
"name": "right"
|
||||
},
|
||||
"row": "bottom",
|
||||
"bind": [
|
||||
10,
|
||||
0,
|
||||
0,
|
||||
10
|
||||
],
|
||||
"mirrored": true
|
||||
}
|
||||
},
|
||||
"mirror_other_right_top": {
|
||||
"x": -138,
|
||||
"y": 138,
|
||||
"r": 0,
|
||||
"meta": {
|
||||
"stagger": 0,
|
||||
"spread": 19,
|
||||
"splay": 0,
|
||||
"origin": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"orient": 0,
|
||||
"shift": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"rotate": 0,
|
||||
"width": 18,
|
||||
"height": 18,
|
||||
"padding": 19,
|
||||
"autobind": 10,
|
||||
"skip": false,
|
||||
"asym": "both",
|
||||
"colrow": "mirror_right_top",
|
||||
"name": "mirror_other_right_top",
|
||||
"zone": {
|
||||
"columns": {
|
||||
"left": {
|
||||
"rows": {
|
||||
"bottom": {
|
||||
"asym": "source"
|
||||
},
|
||||
"top": {
|
||||
"asym": "clone"
|
||||
}
|
||||
},
|
||||
"key": {},
|
||||
"name": "left"
|
||||
},
|
||||
"right": null
|
||||
},
|
||||
"rows": {
|
||||
"bottom": {},
|
||||
"top": {}
|
||||
},
|
||||
"name": "other"
|
||||
},
|
||||
"col": {
|
||||
"rows": {},
|
||||
"key": {},
|
||||
"name": "right"
|
||||
},
|
||||
"row": "top",
|
||||
"bind": [
|
||||
0,
|
||||
0,
|
||||
10,
|
||||
10
|
||||
],
|
||||
"mirrored": true
|
||||
}
|
||||
},
|
||||
"mirror_matrix_left_top": {
|
||||
"x": 57.05,
|
||||
"y": 19,
|
||||
"r": 0,
|
||||
"meta": {
|
||||
"stagger": 0,
|
||||
"spread": 19,
|
||||
"splay": 0,
|
||||
"origin": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"orient": 0,
|
||||
"shift": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"rotate": 0,
|
||||
"width": 18,
|
||||
"height": 18,
|
||||
"padding": 19,
|
||||
"autobind": 10,
|
||||
"skip": false,
|
||||
"asym": "clone",
|
||||
"colrow": "mirror_left_top",
|
||||
"name": "mirror_matrix_left_top",
|
||||
"zone": {
|
||||
"columns": {
|
||||
"left": {
|
||||
"rows": {
|
||||
"bottom": {
|
||||
"asym": "source"
|
||||
},
|
||||
"top": {
|
||||
"asym": "clone"
|
||||
}
|
||||
},
|
||||
"key": {},
|
||||
"name": "left"
|
||||
},
|
||||
"right": null
|
||||
},
|
||||
"rows": {
|
||||
"bottom": {},
|
||||
"top": {}
|
||||
},
|
||||
"name": "matrix"
|
||||
},
|
||||
"col": {
|
||||
"rows": {
|
||||
"bottom": {
|
||||
"asym": "source"
|
||||
},
|
||||
"top": {
|
||||
"asym": "clone"
|
||||
}
|
||||
},
|
||||
"key": {},
|
||||
"name": "left"
|
||||
},
|
||||
"row": "top",
|
||||
"bind": [
|
||||
0,
|
||||
10,
|
||||
10,
|
||||
0
|
||||
],
|
||||
"mirrored": true
|
||||
}
|
||||
},
|
||||
"mirror_matrix_right_bottom": {
|
||||
"x": 38.05,
|
||||
"y": 0,
|
||||
"r": 0,
|
||||
"meta": {
|
||||
"stagger": 0,
|
||||
"spread": 19,
|
||||
"splay": 0,
|
||||
"origin": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"orient": 0,
|
||||
"shift": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"rotate": 0,
|
||||
"width": 18,
|
||||
"height": 18,
|
||||
"padding": 19,
|
||||
"autobind": 10,
|
||||
"skip": false,
|
||||
"asym": "both",
|
||||
"colrow": "mirror_right_bottom",
|
||||
"name": "mirror_matrix_right_bottom",
|
||||
"zone": {
|
||||
"columns": {
|
||||
"left": {
|
||||
"rows": {
|
||||
"bottom": {
|
||||
"asym": "source"
|
||||
},
|
||||
"top": {
|
||||
"asym": "clone"
|
||||
}
|
||||
},
|
||||
"key": {},
|
||||
"name": "left"
|
||||
},
|
||||
"right": null
|
||||
},
|
||||
"rows": {
|
||||
"bottom": {},
|
||||
"top": {}
|
||||
},
|
||||
"name": "matrix"
|
||||
},
|
||||
"col": {
|
||||
"rows": {},
|
||||
"key": {},
|
||||
"name": "right"
|
||||
},
|
||||
"row": "bottom",
|
||||
"bind": [
|
||||
10,
|
||||
0,
|
||||
0,
|
||||
10
|
||||
],
|
||||
"mirrored": true
|
||||
}
|
||||
},
|
||||
"mirror_matrix_right_top": {
|
||||
"x": 38.05,
|
||||
"y": 19,
|
||||
"r": 0,
|
||||
"meta": {
|
||||
"stagger": 0,
|
||||
"spread": 19,
|
||||
"splay": 0,
|
||||
"origin": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"orient": 0,
|
||||
"shift": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"rotate": 0,
|
||||
"width": 18,
|
||||
"height": 18,
|
||||
"padding": 19,
|
||||
"autobind": 10,
|
||||
"skip": false,
|
||||
"asym": "both",
|
||||
"colrow": "mirror_right_top",
|
||||
"name": "mirror_matrix_right_top",
|
||||
"zone": {
|
||||
"columns": {
|
||||
"left": {
|
||||
"rows": {
|
||||
"bottom": {
|
||||
"asym": "source"
|
||||
},
|
||||
"top": {
|
||||
"asym": "clone"
|
||||
}
|
||||
},
|
||||
"key": {},
|
||||
"name": "left"
|
||||
},
|
||||
"right": null
|
||||
},
|
||||
"rows": {
|
||||
"bottom": {},
|
||||
"top": {}
|
||||
},
|
||||
"name": "matrix"
|
||||
},
|
||||
"col": {
|
||||
"rows": {},
|
||||
"key": {},
|
||||
"name": "right"
|
||||
},
|
||||
"row": "top",
|
||||
"bind": [
|
||||
0,
|
||||
0,
|
||||
10,
|
||||
10
|
||||
],
|
||||
"mirrored": true
|
||||
}
|
||||
}
|
||||
}
|
2
test/points/samename.yaml
Normal file
2
test/points/samename.yaml
Normal file
|
@ -0,0 +1,2 @@
|
|||
points.zones.matrix.key.name: samename
|
||||
points.zones.other.key.name: samename
|
1
test/points/samename___EXCEPTION.txt
Normal file
1
test/points/samename___EXCEPTION.txt
Normal file
|
@ -0,0 +1 @@
|
|||
defined more than once
|
22
test/unit/internals.js
Normal file
22
test/unit/internals.js
Normal file
|
@ -0,0 +1,22 @@
|
|||
const m = require('makerjs')
|
||||
const pcb_lib = require('../../src/pcbs')
|
||||
const ergogen = require('../../src/ergogen')
|
||||
|
||||
describe('Internals', function() {
|
||||
|
||||
it('makerjs2kicad', function() {
|
||||
// warn on unknown path type
|
||||
sinon.stub(m.model, 'walk').callsFake(function(model, config) {
|
||||
config.onPath({pathContext: {type: 'nonexistent'}})
|
||||
})
|
||||
pcb_lib._makerjs2kicad.bind(this).should.throw("Can't convert path type")
|
||||
})
|
||||
|
||||
it('injection', function() {
|
||||
// warn on unknown injection type
|
||||
ergogen.inject.bind(this, 'nonexistent', 'name', 'value').should.throw('Unknown injection type')
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue