aboutsummaryrefslogtreecommitdiff
path: root/test/test-translator.js
diff options
context:
space:
mode:
Diffstat (limited to 'test/test-translator.js')
-rw-r--r--test/test-translator.js175
1 files changed, 175 insertions, 0 deletions
diff --git a/test/test-translator.js b/test/test-translator.js
new file mode 100644
index 00000000..97651be3
--- /dev/null
+++ b/test/test-translator.js
@@ -0,0 +1,175 @@
+/*
+ * 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 <https://www.gnu.org/licenses/>.
+ */
+
+const fs = require('fs');
+const path = require('path');
+const assert = require('assert');
+const {createDictionaryArchive, testMain} = require('../dev/util');
+const {DatabaseVM} = require('../dev/database-vm');
+
+
+function createTestDictionaryArchive(dictionary, dictionaryName) {
+ const dictionaryDirectory = path.join(__dirname, 'data', 'dictionaries', dictionary);
+ return createDictionaryArchive(dictionaryDirectory, dictionaryName);
+}
+
+function clone(value) {
+ return JSON.parse(JSON.stringify(value));
+}
+
+
+async function createVM() {
+ // Set up VM
+ const vm = new DatabaseVM();
+ vm.execute([
+ 'mixed/js/core.js',
+ 'mixed/js/cache-map.js',
+ 'mixed/js/japanese.js',
+ 'bg/js/json-schema.js',
+ 'bg/js/media-utility.js',
+ 'bg/js/dictionary-importer.js',
+ 'bg/js/database.js',
+ 'bg/js/dictionary-database.js',
+ 'bg/js/text-source-map.js',
+ 'bg/js/deinflector.js',
+ 'bg/js/translator.js'
+ ]);
+ const [
+ DictionaryImporter,
+ DictionaryDatabase,
+ JapaneseUtil,
+ Translator
+ ] = vm.get([
+ 'DictionaryImporter',
+ 'DictionaryDatabase',
+ 'JapaneseUtil',
+ 'Translator'
+ ]);
+
+ // Dictionary
+ const testDictionary = createTestDictionaryArchive('valid-dictionary2');
+ const testDictionaryContent = await testDictionary.generateAsync({type: 'string'});
+
+ // Setup database
+ const dictionaryImporter = new DictionaryImporter();
+ const dictionaryDatabase = new DictionaryDatabase();
+ await dictionaryDatabase.prepare();
+
+ const {result, errors} = await dictionaryImporter.importDictionary(
+ dictionaryDatabase,
+ testDictionaryContent,
+ {prefixWildcardsSupported: true},
+ () => {}
+ );
+
+ assert.deepStrictEqual(errors.length, 0);
+
+ // Setup translator
+ const japaneseUtil = new JapaneseUtil(null);
+ const translator = new Translator({japaneseUtil, database: dictionaryDatabase});
+ const deinflectionReasions = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'ext', 'bg/lang/deinflect.json')));
+ translator.prepare(deinflectionReasions);
+
+ // Done
+ return {vm, translator, dictionary: result};
+}
+
+function buildOptions(optionsPresets, optionsArray, dictionaryTitle) {
+ const options = {};
+ if (!Array.isArray(optionsArray)) { optionsArray = [optionsArray]; }
+ for (const entry of optionsArray) {
+ switch (typeof entry) {
+ case 'string':
+ if (!Object.prototype.hasOwnProperty.call(optionsPresets, entry)) {
+ throw new Error('Invalid options preset');
+ }
+ Object.assign(options, clone(optionsPresets[entry]));
+ break;
+ case 'object':
+ Object.assign(options, clone(entry));
+ break;
+ default:
+ throw new Error('Invalid options type');
+ }
+ }
+
+ // Update structure
+ const placeholder = '${title}';
+ if (options.mainDictionary === placeholder) {
+ options.mainDictionary = dictionaryTitle;
+ }
+ let {enabledDictionaryMap} = options;
+ if (Array.isArray(enabledDictionaryMap)) {
+ for (const entry of enabledDictionaryMap) {
+ if (entry[0] === placeholder) {
+ entry[0] = dictionaryTitle;
+ }
+ }
+ enabledDictionaryMap = new Map(enabledDictionaryMap);
+ options.enabledDictionaryMap = enabledDictionaryMap;
+ }
+
+ return options;
+}
+
+
+async function main() {
+ const write = (process.argv[2] === '--write');
+ const {translator, dictionary: {title}} = await createVM();
+
+ const dataFilePath = path.join(__dirname, 'data', 'test-translator-data.json');
+ const data = JSON.parse(fs.readFileSync(dataFilePath, {encoding: 'utf8'}));
+ const {optionsPresets, tests} = data;
+ for (const test of tests) {
+ switch (test.func) {
+ case 'findTerms':
+ {
+ const {mode, text} = test;
+ const options = buildOptions(optionsPresets, test.options, title);
+ const [definitions, length] = clone(await translator.findTerms(mode, text, options));
+ if (write) {
+ test.expected = {length, definitions};
+ } else {
+ const {expected} = test;
+ assert.deepStrictEqual(length, expected.length);
+ assert.deepStrictEqual(definitions, expected.definitions);
+ }
+ }
+ break;
+ case 'findKanji':
+ {
+ const {text} = test;
+ const options = buildOptions(optionsPresets, test.options, title);
+ const definitions = clone(await translator.findKanji(text, options));
+ if (write) {
+ test.expected = {definitions};
+ } else {
+ const {expected} = test;
+ assert.deepStrictEqual(definitions, expected.definitions);
+ }
+ }
+ break;
+ }
+ }
+
+ if (write) {
+ fs.writeFileSync(dataFilePath, JSON.stringify(data, null, 4), {encoding: 'utf8'});
+ }
+}
+
+
+if (require.main === module) { testMain(main); }