summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authortoasted-nutbread <toasted-nutbread@users.noreply.github.com>2023-12-19 00:33:38 -0500
committerGitHub <noreply@github.com>2023-12-19 05:33:38 +0000
commit1ced9aafc00c10992bab8bd3f1b6b1397f05b7b9 (patch)
tree305bb2b3bfc7fc3b051ee1cd3d1c35f442af0de4 /test
parent5f96276fda93dcad39f2165fd3c8d890aa5f9be5 (diff)
Make JSON.parse usage safer (#373)
* Make JSON.parse usage safer * Fix any type * Add readResponseJson * Use readResponseJson * Additional updates * Rename files * Add types
Diffstat (limited to 'test')
-rw-r--r--test/anki-note-builder.test.js8
-rw-r--r--test/database.test.js7
-rw-r--r--test/deinflector.test.js4
-rw-r--r--test/dom-text-scanner.test.js18
-rw-r--r--test/fixtures/translator-test.js6
-rw-r--r--test/json-schema.test.js3
-rw-r--r--test/options-util.test.js3
-rw-r--r--test/translator.test.js11
8 files changed, 40 insertions, 20 deletions
diff --git a/test/anki-note-builder.test.js b/test/anki-note-builder.test.js
index cc136957..bdf3f8e4 100644
--- a/test/anki-note-builder.test.js
+++ b/test/anki-note-builder.test.js
@@ -22,6 +22,7 @@ import {readFileSync} from 'fs';
import {fileURLToPath} from 'node:url';
import path from 'path';
import {describe, vi} from 'vitest';
+import {parseJson} from '../dev/json.js';
import {AnkiNoteBuilder} from '../ext/js/data/anki-note-builder.js';
import {JapaneseUtil} from '../ext/js/language/sandbox/japanese-util.js';
import {createTranslatorTest} from './fixtures/translator-test.js';
@@ -170,11 +171,12 @@ async function getRenderResults(dictionaryEntries, type, mode, template, expect)
const testInputsFilePath = path.join(dirname, 'data/translator-test-inputs.json');
-/** @type {import('test/anki-note-builder').TranslatorTestInputs} */
-const {optionsPresets, tests} = JSON.parse(readFileSync(testInputsFilePath, {encoding: 'utf8'}));
+/** @type {import('test/translator').TranslatorTestInputs} */
+const {optionsPresets, tests} = parseJson(readFileSync(testInputsFilePath, {encoding: 'utf8'}));
const testResults1FilePath = path.join(dirname, 'data/anki-note-builder-test-results.json');
-const expectedResults1 = JSON.parse(readFileSync(testResults1FilePath, {encoding: 'utf8'}));
+/** @type {import('test/translator').AnkiNoteBuilderTestResults} */
+const expectedResults1 = parseJson(readFileSync(testResults1FilePath, {encoding: 'utf8'}));
const template = readFileSync(path.join(dirname, '../ext/data/templates/default-anki-field-templates.handlebars'), {encoding: 'utf8'});
diff --git a/test/database.test.js b/test/database.test.js
index 2fdea99c..702de9f8 100644
--- a/test/database.test.js
+++ b/test/database.test.js
@@ -20,6 +20,7 @@ import {IDBFactory, IDBKeyRange} from 'fake-indexeddb';
import {fileURLToPath} from 'node:url';
import path from 'path';
import {beforeEach, describe, expect, test, vi} from 'vitest';
+import {parseJson} from '../dev/json.js';
import {createDictionaryArchive} from '../dev/util.js';
import {DictionaryDatabase} from '../ext/js/language/dictionary-database.js';
import {DictionaryImporter} from '../ext/js/language/dictionary-importer.js';
@@ -109,7 +110,8 @@ async function testDatabase1() {
// Load dictionary data
const testDictionary = createTestDictionaryArchive('valid-dictionary1');
const testDictionarySource = await testDictionary.generateAsync({type: 'arraybuffer'});
- const testDictionaryIndex = JSON.parse(await testDictionary.files['index.json'].async('string'));
+ /** @type {import('dictionary-data').Index} */
+ const testDictionaryIndex = parseJson(await testDictionary.files['index.json'].async('string'));
const title = testDictionaryIndex.title;
const titles = new Map([
@@ -852,7 +854,8 @@ async function testDatabase2() {
// Load dictionary data
const testDictionary = createTestDictionaryArchive('valid-dictionary1');
const testDictionarySource = await testDictionary.generateAsync({type: 'arraybuffer'});
- const testDictionaryIndex = JSON.parse(await testDictionary.files['index.json'].async('string'));
+ /** @type {import('dictionary-data').Index} */
+ const testDictionaryIndex = parseJson(await testDictionary.files['index.json'].async('string'));
const title = testDictionaryIndex.title;
const titles = new Map([
diff --git a/test/deinflector.test.js b/test/deinflector.test.js
index adb347f1..1d7a39cf 100644
--- a/test/deinflector.test.js
+++ b/test/deinflector.test.js
@@ -22,6 +22,7 @@ import fs from 'fs';
import {fileURLToPath} from 'node:url';
import path from 'path';
import {describe, expect, test} from 'vitest';
+import {parseJson} from '../dev/json.js';
import {Deinflector} from '../ext/js/language/deinflector.js';
const dirname = path.dirname(fileURLToPath(import.meta.url));
@@ -929,7 +930,8 @@ function testDeinflections() {
}
];
- const deinflectionReasons = JSON.parse(fs.readFileSync(path.join(dirname, '..', 'ext', 'data/deinflect.json'), {encoding: 'utf8'}));
+ /** @type {import('deinflector').ReasonsRaw} */
+ const deinflectionReasons = parseJson(fs.readFileSync(path.join(dirname, '..', 'ext', 'data/deinflect.json'), {encoding: 'utf8'}));
const deinflector = new Deinflector(deinflectionReasons);
describe('deinflections', () => {
diff --git a/test/dom-text-scanner.test.js b/test/dom-text-scanner.test.js
index d62e334d..f53e326d 100644
--- a/test/dom-text-scanner.test.js
+++ b/test/dom-text-scanner.test.js
@@ -19,6 +19,7 @@
import {fileURLToPath} from 'node:url';
import path from 'path';
import {describe, expect} from 'vitest';
+import {parseJson} from '../dev/json.js';
import {DOMTextScanner} from '../ext/js/dom/dom-text-scanner.js';
import {createDomTest} from './fixtures/dom-test.js';
@@ -109,28 +110,33 @@ describe('DOMTextScanner', () => {
window.getComputedStyle = createAbsoluteGetComputedStyle(window);
for (const testElement of /** @type {NodeListOf<HTMLElement>} */ (document.querySelectorAll('y-test'))) {
- let testData = JSON.parse(/** @type {string} */ (testElement.dataset.testData));
+ /** @type {import('test/dom-text-scanner').TestData|import('test/dom-text-scanner').TestData[]} */
+ let testData = parseJson(/** @type {string} */ (testElement.dataset.testData));
if (!Array.isArray(testData)) {
testData = [testData];
}
for (const testDataItem of testData) {
- let {
- node,
+ const {
+ node: nodeSelector,
offset,
length,
forcePreserveWhitespace,
generateLayoutContent,
reversible,
expected: {
- node: expectedNode,
+ node: expectedNodeSelector,
offset: expectedOffset,
content: expectedContent,
remainder: expectedRemainder
}
} = testDataItem;
- node = querySelectorTextNode(testElement, node);
- expectedNode = querySelectorTextNode(testElement, expectedNode);
+ const node = querySelectorTextNode(testElement, nodeSelector);
+ const expectedNode = querySelectorTextNode(testElement, expectedNodeSelector);
+
+ expect(node).not.toEqual(null);
+ expect(expectedNode).not.toEqual(null);
+ if (node === null || expectedNode === null) { continue; }
// Standard test
{
diff --git a/test/fixtures/translator-test.js b/test/fixtures/translator-test.js
index b17c37d9..cb1a3ef5 100644
--- a/test/fixtures/translator-test.js
+++ b/test/fixtures/translator-test.js
@@ -21,6 +21,7 @@ import {readFileSync} from 'fs';
import {fileURLToPath, pathToFileURL} from 'node:url';
import {dirname, join, resolve} from 'path';
import {expect, vi} from 'vitest';
+import {parseJson} from '../../dev/json.js';
import {createDictionaryArchive} from '../../dev/util.js';
import {AnkiNoteDataCreator} from '../../ext/js/data/sandbox/anki-note-data-creator.js';
import {DictionaryDatabase} from '../../ext/js/language/dictionary-database.js';
@@ -60,7 +61,7 @@ async function fetch(url) {
status: 200,
statusText: 'OK',
text: async () => content.toString('utf8'),
- json: async () => JSON.parse(content.toString('utf8'))
+ json: async () => parseJson(content.toString('utf8'))
};
}
@@ -96,7 +97,8 @@ async function createTranslatorContext(dictionaryDirectory, dictionaryName) {
// Setup translator
const japaneseUtil = new JapaneseUtil(null);
const translator = new Translator({japaneseUtil, database: dictionaryDatabase});
- const deinflectionReasons = JSON.parse(readFileSync(deinflectionReasonsPath, {encoding: 'utf8'}));
+ /** @type {import('deinflector').ReasonsRaw} */
+ const deinflectionReasons = parseJson(readFileSync(deinflectionReasonsPath, {encoding: 'utf8'}));
translator.prepare(deinflectionReasons);
// Assign properties
diff --git a/test/json-schema.test.js b/test/json-schema.test.js
index a93e5002..e6817d23 100644
--- a/test/json-schema.test.js
+++ b/test/json-schema.test.js
@@ -19,6 +19,7 @@
/* eslint-disable no-multi-spaces */
import {expect, test} from 'vitest';
+import {parseJson} from '../dev/json.js';
import {JsonSchema} from '../ext/js/data/json-schema.js';
/**
@@ -54,7 +55,7 @@ function createProxy(schema, value) {
* @returns {T}
*/
function clone(value) {
- return JSON.parse(JSON.stringify(value));
+ return parseJson(JSON.stringify(value));
}
diff --git a/test/options-util.test.js b/test/options-util.test.js
index f2ffa36c..41185756 100644
--- a/test/options-util.test.js
+++ b/test/options-util.test.js
@@ -22,6 +22,7 @@ import fs from 'fs';
import url, {fileURLToPath} from 'node:url';
import path from 'path';
import {expect, test, vi} from 'vitest';
+import {parseJson} from '../dev/json.js';
import {OptionsUtil} from '../ext/js/data/options-util.js';
import {TemplatePatcher} from '../ext/js/templates/template-patcher.js';
@@ -40,7 +41,7 @@ async function fetch(url2) {
status: 200,
statusText: 'OK',
text: async () => Promise.resolve(content.toString('utf8')),
- json: async () => Promise.resolve(JSON.parse(content.toString('utf8')))
+ json: async () => Promise.resolve(parseJson(content.toString('utf8')))
};
}
/** @type {import('dev/vm').PseudoChrome} */
diff --git a/test/translator.test.js b/test/translator.test.js
index 59887d7e..42a9076e 100644
--- a/test/translator.test.js
+++ b/test/translator.test.js
@@ -20,6 +20,7 @@ import {readFileSync} from 'fs';
import {fileURLToPath} from 'node:url';
import path from 'path';
import {describe} from 'vitest';
+import {parseJson} from '../dev/json.js';
import {createTranslatorTest} from './fixtures/translator-test.js';
import {createTestAnkiNoteData} from './utilities/anki.js';
import {createFindOptions} from './utilities/translator.js';
@@ -27,14 +28,16 @@ import {createFindOptions} from './utilities/translator.js';
const dirname = path.dirname(fileURLToPath(import.meta.url));
const testInputsFilePath = path.join(dirname, 'data/translator-test-inputs.json');
-/** @type {import('test/anki-note-builder').TranslatorTestInputs} */
-const {optionsPresets, tests} = JSON.parse(readFileSync(testInputsFilePath, {encoding: 'utf8'}));
+/** @type {import('test/translator').TranslatorTestInputs} */
+const {optionsPresets, tests} = parseJson(readFileSync(testInputsFilePath, {encoding: 'utf8'}));
const testResults1FilePath = path.join(dirname, 'data/translator-test-results.json');
-const expectedResults1 = JSON.parse(readFileSync(testResults1FilePath, {encoding: 'utf8'}));
+/** @type {import('test/translator').TranslatorTestResults} */
+const expectedResults1 = parseJson(readFileSync(testResults1FilePath, {encoding: 'utf8'}));
const testResults2FilePath = path.join(dirname, 'data/translator-test-results-note-data1.json');
-const expectedResults2 = JSON.parse(readFileSync(testResults2FilePath, {encoding: 'utf8'}));
+/** @type {import('test/translator').TranslatorTestNoteDataResults} */
+const expectedResults2 = parseJson(readFileSync(testResults2FilePath, {encoding: 'utf8'}));
const dictionaryName = 'Test Dictionary 2';
const test = await createTranslatorTest(void 0, path.join(dirname, 'data/dictionaries/valid-dictionary1'), dictionaryName);