From 1f3ecb5c58a39d0af93579315b5cedb4c401875d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1n=20D=C3=A9nes?= Date: Fri, 16 Jul 2021 20:18:09 +0200 Subject: [PATCH] Improved interface testing --- package-lock.json | 45 +++--- package.json | 9 +- rollup.config.js | 5 +- src/io.js | 44 +++--- src/kle.js | 13 +- test/fixtures/atreus_kle.json | 271 ++++++++++++++++++++++++++++++++++ test/fixtures/big.yaml | 24 +++ test/fixtures/minimal.yaml | 3 + test/helpers/register.js | 4 + test/unit/interface.js | 109 ++++++-------- 10 files changed, 407 insertions(+), 120 deletions(-) create mode 100644 test/fixtures/atreus_kle.json create mode 100644 test/fixtures/big.yaml create mode 100644 test/fixtures/minimal.yaml create mode 100644 test/helpers/register.js diff --git a/package-lock.json b/package-lock.json index cce7fd3..dcd7e46 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,9 +9,9 @@ "license": "MIT", "dependencies": { "@jscad/openjscad": "github:mrzealot/oldjscad", + "chai-as-promised": "^7.1.1", "fs-extra": "^9.0.1", "js-yaml": "^3.14.0", - "json5": "^2.2.0", "kle-serial": "github:mrzealot/kle-serial", "makerjs": "github:mrzealot/maker.js-dist", "mathjs": "^8.1.1", @@ -833,7 +833,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true, "engines": { "node": "*" } @@ -970,7 +969,6 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", - "dev": true, "dependencies": { "assertion-error": "^1.1.0", "check-error": "^1.0.2", @@ -983,6 +981,17 @@ "node": ">=4" } }, + "node_modules/chai-as-promised": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz", + "integrity": "sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==", + "dependencies": { + "check-error": "^1.0.2" + }, + "peerDependencies": { + "chai": ">= 2.1.2 < 5" + } + }, "node_modules/chalk": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", @@ -1015,7 +1024,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true, "engines": { "node": "*" } @@ -1217,7 +1225,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, "dependencies": { "type-detect": "^4.0.0" }, @@ -1486,7 +1493,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true, "engines": { "node": "*" } @@ -2545,7 +2551,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true, "engines": { "node": "*" } @@ -2961,7 +2966,6 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, "engines": { "node": ">=4" } @@ -3958,8 +3962,7 @@ "assertion-error": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==" }, "astring": { "version": "1.7.5", @@ -4061,7 +4064,6 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", - "dev": true, "requires": { "assertion-error": "^1.1.0", "check-error": "^1.0.2", @@ -4071,6 +4073,14 @@ "type-detect": "^4.0.5" } }, + "chai-as-promised": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz", + "integrity": "sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==", + "requires": { + "check-error": "^1.0.2" + } + }, "chalk": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", @@ -4095,8 +4105,7 @@ "check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=" }, "chokidar": { "version": "3.5.1", @@ -4252,7 +4261,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, "requires": { "type-detect": "^4.0.0" } @@ -4431,8 +4439,7 @@ "get-func-name": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=" }, "get-package-type": { "version": "0.1.0", @@ -5237,8 +5244,7 @@ "pathval": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==" }, "picomatch": { "version": "2.3.0", @@ -5545,8 +5551,7 @@ "type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" }, "type-fest": { "version": "0.8.1", diff --git a/package.json b/package.json index 457bbed..d51b6e7 100644 --- a/package.json +++ b/package.json @@ -11,15 +11,15 @@ "bin": "./src/cli.js", "scripts": { "build": "rollup -c", - "test": "mocha -r chai/register-should test/index.js", + "test": "mocha -r test/helpers/register test/index.js", "coverage": "nyc --reporter=html --reporter=text npm test" }, "dependencies": { - "kle-serial": "github:mrzealot/kle-serial", "@jscad/openjscad": "github:mrzealot/oldjscad", + "chai-as-promised": "^7.1.1", "fs-extra": "^9.0.1", "js-yaml": "^3.14.0", - "json5": "^2.2.0", + "kle-serial": "github:mrzealot/kle-serial", "makerjs": "github:mrzealot/maker.js-dist", "mathjs": "^8.1.1", "yargs": "^15.4.1" @@ -37,9 +37,6 @@ "all": true, "include": [ "src/**/*.js" - ], - "exclude": [ - "src/cli.js" ] } } diff --git a/rollup.config.js b/rollup.config.js index 2e6df9f..7de20f0 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -4,7 +4,7 @@ import replace from '@rollup/plugin-replace' export default { input: 'src/ergogen.js', - external: ['makerjs', 'js-yaml', 'mathjs', 'json5'], + external: ['makerjs', 'js-yaml', 'mathjs'], output: { name: 'ergogen', file: 'dist/ergogen.js', @@ -13,8 +13,7 @@ export default { globals: { 'makerjs': 'makerjs', 'js-yaml': 'jsyaml', - 'mathjs': 'math', - 'json5': 'json5' + 'mathjs': 'math' } }, plugins: [ diff --git a/src/io.js b/src/io.js index 73a6943..f32c82d 100644 --- a/src/io.js +++ b/src/io.js @@ -1,4 +1,3 @@ -const json5 = require('json5') const yaml = require('js-yaml') const makerjs = require('makerjs') const jscad = require('@jscad/openjscad') @@ -10,38 +9,43 @@ const kle = require('./kle') exports.interpret = (raw, logger) => { let config = raw let format = 'OBJ' - if (a.type(raw)() != 'object') { + if (a.type(raw)() == 'string') { try { config = yaml.safeLoad(raw) format = 'YAML' } catch (yamlex) { try { - config = json5.parse(raw) - format = 'JSON' - } catch (jsonex) { - try { - config = new Function(raw)() - format = 'JS Code' - } catch (codeex) { - logger('YAML exception:', yamlex) - logger('JSON exception:', jsonex) - logger('Code exception:', codeex) - throw new Error('Input is not valid YAML, JSON, or JS Code!') - } + config = new Function(raw)() + a.assert( + a.type(config)() == 'object', + 'Input JS Code doesn\'t resolve into an object!' + ) + format = 'JS' + } catch (codeex) { + logger('YAML exception:', yamlex) + logger('Code exception:', codeex) + throw new Error('Input is not valid YAML, JSON, or JS Code!') } } - if (!config) { - throw new Error('Input appears to be empty!') - } } try { // assume it's KLE and try to convert it - // if it's not, it'll throw anyway - return kle.convert(config, logger) + config = kle.convert(config, logger) + format = 'KLE' } catch (kleex) { - return [config, format] + // nope... nevermind } + + if (a.type(config)() != 'object') { + throw new Error('Input doesn\'t resolve into an object!') + } + + if (!Object.keys(config).length) { + throw new Error('Input appears to be empty!') + } + + return [config, format] } exports.twodee = (model, debug) => { diff --git a/src/kle.js b/src/kle.js index e971f7e..592f916 100644 --- a/src/kle.js +++ b/src/kle.js @@ -1,18 +1,19 @@ const u = require('./utils') const kle = require('kle-serial') -const json5 = require('json5') +const yaml = require('js-yaml') exports.convert = (config, logger) => { const keyboard = kle.Serial.deserialize(config) const result = {points: {zones: {}}, pcbs: {main: {}}} - // if the keyboard notes are valid JSON, they get added to each key as metadata - let meta = {} + // if the keyboard notes are valid YAML/JSON, they get added to each key as metadata + let meta try { - meta = json5.parse(keyboard.meta.notes) + meta = yaml.load(keyboard.meta.notes) } catch (ex) { - // notes were not valid JSON, oh well... + // notes were not valid YAML/JSON, oh well... } + meta = meta || {} let index = 1 for (const key of keyboard.keys) { @@ -68,5 +69,5 @@ exports.convert = (config, logger) => { result.points.zones[id] = converted } - return [result, 'KLE'] + return result } \ No newline at end of file diff --git a/test/fixtures/atreus_kle.json b/test/fixtures/atreus_kle.json new file mode 100644 index 0000000..957d56e --- /dev/null +++ b/test/fixtures/atreus_kle.json @@ -0,0 +1,271 @@ +[ + [ + { + "r": 10, + "rx": 1, + "y": -0.09999999999999998, + "x": 2 + }, + "E" + ], + [ + { + "y": -0.65, + "x": 1 + }, + "W", + { + "x": 1 + }, + "R" + ], + [ + { + "y": -0.75 + }, + "Q" + ], + [ + { + "y": -0.9, + "x": 4 + }, + "T" + ], + [ + { + "y": -0.7000000000000001, + "x": 2 + }, + "D" + ], + [ + { + "y": -0.6499999999999999, + "x": 1 + }, + "S", + { + "x": 1 + }, + "F" + ], + [ + { + "y": -0.75 + }, + "A" + ], + [ + { + "y": -0.8999999999999999, + "x": 4 + }, + "G" + ], + [ + { + "y": -0.7000000000000002, + "x": 2 + }, + "C" + ], + [ + { + "y": -0.6499999999999999, + "x": 1 + }, + "X", + { + "x": 1 + }, + "V" + ], + [ + { + "y": -0.75 + }, + "Z" + ], + [ + { + "y": -0.8999999999999999, + "x": 4 + }, + "B" + ], + [ + { + "y": -0.75, + "x": 5, + "h": 1.5 + }, + "Ctrl" + ], + [ + { + "y": -0.9500000000000002, + "x": 2 + }, + "super" + ], + [ + { + "y": -0.6499999999999999, + "x": 1 + }, + "Tab", + { + "x": 1 + }, + "Shift" + ], + [ + { + "y": -0.75 + }, + "Esc" + ], + [ + { + "y": -0.8999999999999999, + "x": 4 + }, + "Bksp" + ], + [ + { + "r": -10, + "rx": 7, + "ry": 0.965, + "y": -0.20000000000000018, + "x": 2 + }, + "I" + ], + [ + { + "y": -0.6499999999999999, + "x": 1 + }, + "U", + { + "x": 1 + }, + "O" + ], + [ + { + "y": -0.75, + "x": 4 + }, + "P" + ], + [ + { + "y": -0.8999999999999999 + }, + "Y" + ], + [ + { + "y": -0.7000000000000002, + "x": 2 + }, + "K" + ], + [ + { + "y": -0.6499999999999999, + "x": 1 + }, + "J", + { + "x": 1 + }, + "L" + ], + [ + { + "y": -0.75, + "x": 4 + }, + ":\n;" + ], + [ + { + "y": -0.8999999999999999 + }, + "H" + ], + [ + { + "y": -0.7000000000000002, + "x": 2 + }, + "<\n," + ], + [ + { + "y": -0.6499999999999999, + "x": 1 + }, + "M", + { + "x": 1 + }, + ">\n." + ], + [ + { + "y": -0.7500000000000004, + "x": 4 + }, + "?\n/" + ], + [ + { + "y": -0.9000000000000004 + }, + "N" + ], + [ + { + "y": -0.7499999999999996, + "x": -1, + "h": 1.5 + }, + "Alt" + ], + [ + { + "y": -0.9499999999999997, + "x": 2 + }, + "_\n-" + ], + [ + { + "y": -0.6500000000000004, + "x": 1 + }, + "fn", + { + "x": 1 + }, + "\"\n'" + ], + [ + { + "y": -0.75, + "x": 4 + }, + "Enter" + ], + [ + { + "y": -0.9000000000000004 + }, + "Space" + ] +] \ No newline at end of file diff --git a/test/fixtures/big.yaml b/test/fixtures/big.yaml new file mode 100644 index 0000000..c9f82ec --- /dev/null +++ b/test/fixtures/big.yaml @@ -0,0 +1,24 @@ +units: + a: 28 + u +points.zones.matrix: + columns.col: {} + rows.row: {} +outlines.exports: + export: + - type: 'keys' + side: 'left' + size: 18 + _export: + - type: 'keys' + side: 'left' + size: 18 +cases: + export: + - name: 'export' + extrude: 1 + _export: + - name: 'export' + extrude: 1 +pcbs: + export: {} + _export: {} diff --git a/test/fixtures/minimal.yaml b/test/fixtures/minimal.yaml new file mode 100644 index 0000000..c878ca1 --- /dev/null +++ b/test/fixtures/minimal.yaml @@ -0,0 +1,3 @@ +points.zones.matrix: + columns.col: {} + rows.row: {} \ No newline at end of file diff --git a/test/helpers/register.js b/test/helpers/register.js new file mode 100644 index 0000000..8007d73 --- /dev/null +++ b/test/helpers/register.js @@ -0,0 +1,4 @@ +global.chai = require('chai') +global.chai.use(require('chai-as-promised')) +global.expect = global.chai.expect +global.should = global.chai.should() \ No newline at end of file diff --git a/test/unit/interface.js b/test/unit/interface.js index 3de110d..4bdedf6 100644 --- a/test/unit/interface.js +++ b/test/unit/interface.js @@ -1,76 +1,55 @@ -const u = require('../../src/utils') +const fs = require('fs') +const path = require('path') +const yaml = require('js-yaml') const ergogen = require('../../src/ergogen') -const minimal = { - 'points.zones.matrix': { - columns: {col: {}}, - rows: {row: {}} - } -} - -const full = { - 'points.zones.matrix': { - columns: {col: {}}, - rows: {row: {}} - }, - 'outlines.exports': { - export: [{ - type: 'keys', - side: 'left', - size: 18 - }], - _export: [{ - type: 'keys', - side: 'left', - size: 18 - }] - }, - cases: { - export: [{ - name: 'export', - extrude: 1 - }], - _export: [{ - name: 'export', - extrude: 1 - }] - }, - pcbs: { - export: {}, - _export: {} - } -} - -// to check whether the output has "private" exports -const underscore = obj => { - for (const val of Object.values(obj)) { - for (const key of Object.keys(val)) { - if (key.startsWith('_')) return true - } - } - return false -} - +// fixtures +const load = name => yaml.safeLoad(fs.readFileSync( + path.join(__dirname, `../fixtures/${name}`) +).toString()) +const minimal = load('minimal.yaml') +const big = load('big.yaml') +const kle = load('atreus_kle.json') describe('Interface', function() { - it('minimal', async function() { + it('debug', async function() { + // to check whether the output has "private" exports + const underscore = obj => { + for (const val of Object.values(obj)) { + for (const key of Object.keys(val)) { + if (key.startsWith('_')) return true + } + } + return false + } underscore(await ergogen.process(minimal)).should.be.false + underscore(await ergogen.process(big, false)).should.be.false + underscore(await ergogen.process(big, true)).should.be.true }) - it('production', async function() { - underscore(await ergogen.process(full, false)).should.be.false + it('formats', async function() { + const logger = msg => { + if (msg.startsWith('Interpreting format:')) { + throw msg.split(':')[1].trim() + } + } + return Promise.all([ + ergogen.process(minimal, true, logger).should.be.rejectedWith('OBJ'), + ergogen.process(yaml.dump(minimal), true, logger).should.be.rejectedWith('YAML'), + ergogen.process(` + //: + return {points: {}} + `, true, logger).should.be.rejectedWith('JS'), + ergogen.process(` + //: + return 'not an object'; + `, true, logger).should.be.rejectedWith('not valid'), + ergogen.process(kle, true, logger).should.be.rejectedWith('KLE'), + ergogen.process('not an object', true, logger).should.be.rejectedWith('object'), + ergogen.process({}, true, logger).should.be.rejectedWith('empty'), + ergogen.process({not_points: {}}, true, () => {}).should.be.rejectedWith('any points') + ]) }) - it('debug', async function() { - underscore(await ergogen.process(full, true)).should.be.true - }) - - it('logging', async function() { - const flag = {value: false} - const logger = msg => { flag.value = true } - await ergogen.process(full, false, logger) - flag.value.should.be.true - }) - }) \ No newline at end of file