From 51d4e5b0ff4c0054bf5012464414ec0657d09963 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sat, 19 Sep 2020 19:04:28 -0400 Subject: [PATCH] Dev/test script organization (#846) * Move lint scripts * Move dictionary-validate.js * Move schema-validate.js * Move createTestDictionaryArchive, remove yomichan-test.js * Rename yomichan-util.js to util.js * Move test/yomichan-vm.js to dev/vm.js * Move getArgs into util.js (and fix name) * Create test-all.js * Update test-code script --- dev/build.js | 50 +--------------- {test => dev}/dictionary-validate.js | 4 +- {test => dev}/lint/global-declarations.js | 2 +- {test => dev}/schema-validate.js | 2 +- dev/{yomichan-util.js => util.js} | 71 ++++++++++++++++++++++- test/yomichan-vm.js => dev/vm.js | 0 package.json | 4 +- test/test-all.js | 66 +++++++++++++++++++++ test/test-cache-map.js | 2 +- test/test-core.js | 2 +- test/test-database.js | 11 +++- test/test-dictionary.js | 11 +++- test/test-document-util.js | 2 +- test/test-dom-text-scanner.js | 2 +- test/test-japanese.js | 2 +- test/test-manifest.js | 2 +- test/test-object-property-accessor.js | 2 +- test/test-profile-conditions.js | 2 +- test/test-schema.js | 2 +- test/test-text-source-map.js | 2 +- test/yomichan-test.js | 49 ---------------- 21 files changed, 172 insertions(+), 118 deletions(-) rename {test => dev}/dictionary-validate.js (97%) rename {test => dev}/lint/global-declarations.js (98%) rename {test => dev}/schema-validate.js (97%) rename dev/{yomichan-util.js => util.js} (55%) rename test/yomichan-vm.js => dev/vm.js (100%) create mode 100644 test/test-all.js delete mode 100644 test/yomichan-test.js diff --git a/dev/build.js b/dev/build.js index 6afb82ae..b76a769b 100644 --- a/dev/build.js +++ b/dev/build.js @@ -19,8 +19,8 @@ const fs = require('fs'); const path = require('path'); const readline = require('readline'); const childProcess = require('child_process'); -const util = require('./yomichan-util'); -const {getAllFiles, getDefaultManifestAndVariants, createManifestString} = util; +const util = require('./util'); +const {getAllFiles, getDefaultManifestAndVariants, createManifestString, getArgs} = util; function clone(value) { @@ -208,54 +208,10 @@ async function build(manifest, buildDir, extDir, manifestPath, variantMap, varia } } -function getArs(args, argMap) { - let key = null; - let canKey = true; - let onKey = false; - for (const arg of args) { - onKey = false; - - if (canKey && arg.startsWith('--')) { - if (arg.length === 2) { - canKey = false; - key = null; - onKey = false; - } else { - key = arg.substring(2); - onKey = true; - } - } - - const target = argMap.get(key); - if (typeof target === 'boolean') { - argMap.set(key, true); - key = null; - } else if (typeof target === 'number') { - argMap.set(key, target + 1); - key = null; - } else if (target === null || typeof target === 'string') { - if (!onKey) { - argMap.set(key, arg); - key = null; - } - } else if (Array.isArray(target)) { - if (!onKey) { - target.push(arg); - key = null; - } - } else { - console.error(`Unknown argument: ${arg}`); - key = null; - } - } - - return argMap; -} - async function main() { const argv = process.argv.slice(2); - const args = getArs(argv, new Map([ + const args = getArgs(argv, new Map([ ['all', false], ['default', false], ['manifest', null], diff --git a/test/dictionary-validate.js b/dev/dictionary-validate.js similarity index 97% rename from test/dictionary-validate.js rename to dev/dictionary-validate.js index a669a542..cf449b09 100644 --- a/test/dictionary-validate.js +++ b/dev/dictionary-validate.js @@ -17,8 +17,8 @@ const fs = require('fs'); const path = require('path'); -const {JSZip} = require('../dev/yomichan-util'); -const {VM} = require('./yomichan-vm'); +const {JSZip} = require('./util'); +const {VM} = require('./vm'); const vm = new VM(); vm.execute([ diff --git a/test/lint/global-declarations.js b/dev/lint/global-declarations.js similarity index 98% rename from test/lint/global-declarations.js rename to dev/lint/global-declarations.js index 355cb64a..5448df85 100644 --- a/test/lint/global-declarations.js +++ b/dev/lint/global-declarations.js @@ -19,7 +19,7 @@ const fs = require('fs'); const path = require('path'); const assert = require('assert'); -const {getAllFiles} = require('../../dev/yomichan-util'); +const {getAllFiles} = require('../util'); function countOccurences(string, pattern) { diff --git a/test/schema-validate.js b/dev/schema-validate.js similarity index 97% rename from test/schema-validate.js rename to dev/schema-validate.js index 7b7a21a6..7b6bb5e7 100644 --- a/test/schema-validate.js +++ b/dev/schema-validate.js @@ -16,7 +16,7 @@ */ const fs = require('fs'); -const {VM} = require('./yomichan-vm'); +const {VM} = require('./vm'); const vm = new VM(); vm.execute([ diff --git a/dev/yomichan-util.js b/dev/util.js similarity index 55% rename from dev/yomichan-util.js rename to dev/util.js index 2d8f31ea..971837af 100644 --- a/dev/yomichan-util.js +++ b/dev/util.js @@ -32,6 +32,50 @@ function getJSZip() { } +function getArgs(args, argMap) { + let key = null; + let canKey = true; + let onKey = false; + for (const arg of args) { + onKey = false; + + if (canKey && arg.startsWith('--')) { + if (arg.length === 2) { + canKey = false; + key = null; + onKey = false; + } else { + key = arg.substring(2); + onKey = true; + } + } + + const target = argMap.get(key); + if (typeof target === 'boolean') { + argMap.set(key, true); + key = null; + } else if (typeof target === 'number') { + argMap.set(key, target + 1); + key = null; + } else if (target === null || typeof target === 'string') { + if (!onKey) { + argMap.set(key, arg); + key = null; + } + } else if (Array.isArray(target)) { + if (!onKey) { + target.push(arg); + key = null; + } + } else { + console.error(`Unknown argument: ${arg}`); + key = null; + } + } + + return argMap; +} + function getAllFiles(baseDirectory, relativeTo=null, predicate=null) { const results = []; const directories = [baseDirectory]; @@ -69,11 +113,36 @@ function createManifestString(manifest) { return JSON.stringify(manifest, null, 4) + '\n'; } +function createDictionaryArchive(dictionaryDirectory, dictionaryName) { + const fileNames = fs.readdirSync(dictionaryDirectory); + + const JSZip2 = getJSZip(); + const archive = new JSZip2(); + + for (const fileName of fileNames) { + if (/\.json$/.test(fileName)) { + const content = fs.readFileSync(path.join(dictionaryDirectory, fileName), {encoding: 'utf8'}); + const json = JSON.parse(content); + if (fileName === 'index.json' && typeof dictionaryName === 'string') { + json.title = dictionaryName; + } + archive.file(fileName, JSON.stringify(json, null, 0)); + } else { + const content = fs.readFileSync(path.join(dictionaryDirectory, fileName), {encoding: null}); + archive.file(fileName, content); + } + } + + return archive; +} + module.exports = { get JSZip() { return getJSZip(); }, + getArgs, getAllFiles, getDefaultManifest, getDefaultManifestAndVariants, - createManifestString + createManifestString, + createDictionaryArchive }; diff --git a/test/yomichan-vm.js b/dev/vm.js similarity index 100% rename from test/yomichan-vm.js rename to dev/vm.js diff --git a/package.json b/package.json index d276d701..7ba23ff5 100644 --- a/package.json +++ b/package.json @@ -8,8 +8,8 @@ "scripts": { "build": "node ./dev/build.js", "test": "npm run test-lint && npm run test-code && npm run test-manifest", - "test-lint": "eslint . && node ./test/lint/global-declarations.js", - "test-code": "node ./test/test-schema.js && node ./test/test-dictionary.js && node ./test/test-database.js && node ./test/test-document-util.js && node ./test/test-object-property-accessor.js && node ./test/test-japanese.js && node ./test/test-text-source-map.js && node ./test/test-dom-text-scanner.js && node ./test/test-cache-map.js && node ./test/test-profile-conditions.js && node ./test/test-core.js", + "test-lint": "eslint . && node ./dev/lint/global-declarations.js", + "test-code": "node ./test/test-all.js ./test --skip ./test/test-manifest.js", "test-manifest": "node ./test/test-manifest.js" }, "repository": { diff --git a/test/test-all.js b/test/test-all.js new file mode 100644 index 00000000..71261408 --- /dev/null +++ b/test/test-all.js @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2020 Yomichan Authors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +const fs = require('fs'); +const path = require('path'); +const {spawnSync} = require('child_process'); +const {getArgs} = require('../dev/util'); + + +function main() { + const args = getArgs(process.argv.slice(2), new Map([ + ['skip', []], + [null, []] + ])); + const directories = args.get(null); + const skip = new Set([__filename, ...args.get('skip')].map((value) => path.resolve(value))); + + const node = process.execPath; + const fileNamePattern = /\.js$/i; + + let first = true; + for (const directory of directories) { + const fileNames = fs.readdirSync(directory); + for (const fileName of fileNames) { + if (!fileNamePattern.test(fileName)) { continue; } + + const fullFileName = path.resolve(path.join(directory, fileName)); + if (skip.has(fullFileName)) { continue; } + + const stats = fs.lstatSync(fullFileName); + if (!stats.isFile()) { continue; } + + process.stdout.write(`${first ? '' : '\n'}Running ${fileName}...\n`); + first = false; + + const {error, status} = spawnSync(node, [fileName], {cwd: directory, stdio: 'inherit'}); + + if (status !== null && status !== 0) { + process.exit(status); + return; + } + if (error) { + throw error; + } + } + } + + process.exit(0); +} + + +if (require.main === module) { main(); } diff --git a/test/test-cache-map.js b/test/test-cache-map.js index 00383e65..9307dd2c 100644 --- a/test/test-cache-map.js +++ b/test/test-cache-map.js @@ -16,7 +16,7 @@ */ const assert = require('assert'); -const {VM} = require('./yomichan-vm'); +const {VM} = require('../dev/vm'); const vm = new VM({console}); vm.execute([ diff --git a/test/test-core.js b/test/test-core.js index d4a880d1..b5c0683f 100644 --- a/test/test-core.js +++ b/test/test-core.js @@ -17,7 +17,7 @@ const assert = require('assert'); const crypto = require('crypto'); -const {VM} = require('./yomichan-vm'); +const {VM} = require('../dev/vm'); const vm = new VM({ crypto: { diff --git a/test/test-database.js b/test/test-database.js index df152e57..dce89559 100644 --- a/test/test-database.js +++ b/test/test-database.js @@ -19,9 +19,8 @@ const fs = require('fs'); const url = require('url'); const path = require('path'); const assert = require('assert'); -const {JSZip} = require('../dev/yomichan-util'); -const {createTestDictionaryArchive} = require('./yomichan-test'); -const {VM} = require('./yomichan-vm'); +const {JSZip, createDictionaryArchive} = require('../dev/util'); +const {VM} = require('../dev/vm'); require('fake-indexeddb/auto'); const chrome = { @@ -125,6 +124,12 @@ const DictionaryImporter = vm.get('DictionaryImporter'); const DictionaryDatabase = vm.get('DictionaryDatabase'); +function createTestDictionaryArchive(dictionary, dictionaryName) { + const dictionaryDirectory = path.join(__dirname, 'data', 'dictionaries', dictionary); + return createDictionaryArchive(dictionaryDirectory, dictionaryName); +} + + function countTermsWithExpression(terms, expression) { return terms.reduce((i, v) => (i + (v.expression === expression ? 1 : 0)), 0); } diff --git a/test/test-dictionary.js b/test/test-dictionary.js index 2ca0c652..e7db75eb 100644 --- a/test/test-dictionary.js +++ b/test/test-dictionary.js @@ -15,8 +15,15 @@ * along with this program. If not, see . */ -const {createTestDictionaryArchive} = require('./yomichan-test'); -const dictionaryValidate = require('./dictionary-validate'); +const path = require('path'); +const {createDictionaryArchive} = require('../dev/util'); +const dictionaryValidate = require('../dev/dictionary-validate'); + + +function createTestDictionaryArchive(dictionary, dictionaryName) { + const dictionaryDirectory = path.join(__dirname, 'data', 'dictionaries', dictionary); + return createDictionaryArchive(dictionaryDirectory, dictionaryName); +} async function main() { diff --git a/test/test-document-util.js b/test/test-document-util.js index 4ff380ec..4489bdf1 100644 --- a/test/test-document-util.js +++ b/test/test-document-util.js @@ -19,7 +19,7 @@ const fs = require('fs'); const path = require('path'); const assert = require('assert'); const {JSDOM} = require('jsdom'); -const {VM} = require('./yomichan-vm'); +const {VM} = require('../dev/vm'); // DOMRect class definition diff --git a/test/test-dom-text-scanner.js b/test/test-dom-text-scanner.js index 7374ff87..b9ff6239 100644 --- a/test/test-dom-text-scanner.js +++ b/test/test-dom-text-scanner.js @@ -19,7 +19,7 @@ const fs = require('fs'); const path = require('path'); const assert = require('assert'); const {JSDOM} = require('jsdom'); -const {VM} = require('./yomichan-vm'); +const {VM} = require('../dev/vm'); function createJSDOM(fileName) { diff --git a/test/test-japanese.js b/test/test-japanese.js index 39004128..ad3084f1 100644 --- a/test/test-japanese.js +++ b/test/test-japanese.js @@ -16,7 +16,7 @@ */ const assert = require('assert'); -const {VM} = require('./yomichan-vm'); +const {VM} = require('../dev/vm'); const vm = new VM(); vm.execute([ diff --git a/test/test-manifest.js b/test/test-manifest.js index 07889105..230e6139 100644 --- a/test/test-manifest.js +++ b/test/test-manifest.js @@ -18,7 +18,7 @@ const fs = require('fs'); const path = require('path'); const assert = require('assert'); -const {getDefaultManifest, createManifestString} = require('../dev/yomichan-util'); +const {getDefaultManifest, createManifestString} = require('../dev/util'); function loadManifestString() { diff --git a/test/test-object-property-accessor.js b/test/test-object-property-accessor.js index 1e694946..42fa3d40 100644 --- a/test/test-object-property-accessor.js +++ b/test/test-object-property-accessor.js @@ -16,7 +16,7 @@ */ const assert = require('assert'); -const {VM} = require('./yomichan-vm'); +const {VM} = require('../dev/vm'); const vm = new VM({}); vm.execute('mixed/js/object-property-accessor.js'); diff --git a/test/test-profile-conditions.js b/test/test-profile-conditions.js index 23bbdacb..8ef24b5a 100644 --- a/test/test-profile-conditions.js +++ b/test/test-profile-conditions.js @@ -16,7 +16,7 @@ */ const assert = require('assert'); -const {VM} = require('./yomichan-vm'); +const {VM} = require('../dev/vm'); const vm = new VM({}); diff --git a/test/test-schema.js b/test/test-schema.js index a4a0de2e..a79650d6 100644 --- a/test/test-schema.js +++ b/test/test-schema.js @@ -16,7 +16,7 @@ */ const assert = require('assert'); -const {VM} = require('./yomichan-vm'); +const {VM} = require('../dev/vm'); const vm = new VM(); vm.execute([ diff --git a/test/test-text-source-map.js b/test/test-text-source-map.js index f092de2c..c9810d19 100644 --- a/test/test-text-source-map.js +++ b/test/test-text-source-map.js @@ -16,7 +16,7 @@ */ const assert = require('assert'); -const {VM} = require('./yomichan-vm'); +const {VM} = require('../dev/vm'); const vm = new VM(); vm.execute(['bg/js/text-source-map.js']); diff --git a/test/yomichan-test.js b/test/yomichan-test.js deleted file mode 100644 index af1ea2e3..00000000 --- a/test/yomichan-test.js +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2020 Yomichan Authors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -const fs = require('fs'); -const path = require('path'); - - -function createTestDictionaryArchive(dictionary, dictionaryName) { - const dictionaryDirectory = path.join(__dirname, 'data', 'dictionaries', dictionary); - const fileNames = fs.readdirSync(dictionaryDirectory); - - const {JSZip} = require('../dev/yomichan-util'); - const archive = new JSZip(); - - for (const fileName of fileNames) { - if (/\.json$/.test(fileName)) { - const content = fs.readFileSync(path.join(dictionaryDirectory, fileName), {encoding: 'utf8'}); - const json = JSON.parse(content); - if (fileName === 'index.json' && typeof dictionaryName === 'string') { - json.title = dictionaryName; - } - archive.file(fileName, JSON.stringify(json, null, 0)); - } else { - const content = fs.readFileSync(path.join(dictionaryDirectory, fileName), {encoding: null}); - archive.file(fileName, content); - } - } - - return archive; -} - - -module.exports = { - createTestDictionaryArchive -};