Skip to content

Commit

Permalink
Fix DOM tests (#363)
Browse files Browse the repository at this point in the history
* Only apply eslint rules to .test.js files

* Fix tests

* Use built-in environment

* Fix tests

* Optional file name

* Remove environment
  • Loading branch information
toasted-nutbread authored Dec 17, 2023
1 parent 64e4598 commit 77d2711
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 111 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -765,7 +765,7 @@
},
{
"files": [
"test/**"
"test/**/*.test.js"
],
"plugins": [
"vitest"
Expand Down
2 changes: 2 additions & 0 deletions test/anki-note-builder.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

// @vitest-environment jsdom

import 'fake-indexeddb/auto';
import fs from 'fs';
import {fileURLToPath} from 'node:url';
Expand Down
58 changes: 58 additions & 0 deletions test/document-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright (C) 2023 Yomitan Authors
* Copyright (C) 2020-2022 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/>.
*/

import fs from 'fs';
import {test} from 'vitest';
import {builtinEnvironments} from 'vitest/environments';

/**
* @param {import('jsdom').DOMWindow} window
*/
function prepareWindow(window) {
const {document} = window;

// Define innerText setter as an alias for textContent setter
Object.defineProperty(window.HTMLDivElement.prototype, 'innerText', {
set(value) { this.textContent = value; }
});

// Placeholder for feature detection
document.caretRangeFromPoint = () => null;
}

/**
* @param {string} [htmlFilePath]
* @returns {import('vitest').TestAPI<{window: import('jsdom').DOMWindow}>}
*/
export function domTest(htmlFilePath) {
return test.extend({
// eslint-disable-next-line no-empty-pattern
window: async ({}, use) => {
const html = typeof htmlFilePath === 'string' ? fs.readFileSync(htmlFilePath, {encoding: 'utf8'}) : '<!DOCTYPE html>';
const env = builtinEnvironments.jsdom;
const {teardown} = await env.setup(global, {jsdom: {html}});
const window = /** @type {import('jsdom').DOMWindow} */ (/** @type {unknown} */ (global.window));
prepareWindow(window);
try {
await use(window);
} finally {
teardown(global);
}
}
});
}
86 changes: 18 additions & 68 deletions test/document-util.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,14 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

import fs from 'fs';
import {JSDOM} from 'jsdom';
import {fileURLToPath} from 'node:url';
import path from 'path';
import {expect, test} from 'vitest';
import {describe, expect} from 'vitest';
import {DocumentUtil} from '../ext/js/dom/document-util.js';
import {DOMTextScanner} from '../ext/js/dom/dom-text-scanner.js';
import {TextSourceElement} from '../ext/js/dom/text-source-element.js';
import {TextSourceRange} from '../ext/js/dom/text-source-range.js';
import {domTest} from './document-test.js';

const dirname = path.dirname(fileURLToPath(import.meta.url));

Expand Down Expand Up @@ -68,27 +67,6 @@ class DOMRect {
}


/**
* @param {string} fileName
* @returns {JSDOM}
*/
function createJSDOM(fileName) {
const domSource = fs.readFileSync(fileName, {encoding: 'utf8'});
const dom = new JSDOM(domSource);
const document = dom.window.document;
const window = dom.window;

// Define innerText setter as an alias for textContent setter
Object.defineProperty(window.HTMLDivElement.prototype, 'innerText', {
set(value) { this.textContent = value; }
});

// Placeholder for feature detection
document.caretRangeFromPoint = () => null;

return dom;
}

/**
* @param {Element} element
* @param {string|undefined} selector
Expand All @@ -99,13 +77,13 @@ function querySelectorChildOrSelf(element, selector) {
}

/**
* @param {JSDOM} dom
* @param {import('jsdom').DOMWindow} window
* @param {?Node} node
* @returns {?Text|Node}
*/
function getChildTextNodeOrSelf(dom, node) {
function getChildTextNodeOrSelf(window, node) {
if (node === null) { return null; }
const Node = dom.window.Node;
const Node = window.Node;
const childNode = node.firstChild;
return (childNode !== null && childNode.nodeType === Node.TEXT_NODE ? childNode : node);
}
Expand All @@ -131,27 +109,10 @@ function findImposterElement(document) {
return document.querySelector('div[style*="2147483646"]>*');
}


/** */
async function testDocument1() {
const dom = createJSDOM(path.join(dirname, 'data', 'html', 'test-document1.html'));
const window = dom.window;

try {
await testDocumentTextScanningFunctions(dom);
await testTextSourceRangeSeekFunctions(dom);
} finally {
window.close();
}
}

/**
* @param {JSDOM} dom
*/
async function testDocumentTextScanningFunctions(dom) {
const document = dom.window.document;

test('DocumentTextScanningFunctions', () => {
describe('DocumentUtil', () => {
const testDoc = domTest(path.join(dirname, 'data/html/test-document1.html'));
testDoc('Text scanning functions', ({window}) => {
const {document} = window;
for (const testElement of /** @type {NodeListOf<HTMLElement>} */ (document.querySelectorAll('.test[data-test-type=scan]'))) {
// Get test parameters
const {
Expand All @@ -170,8 +131,8 @@ async function testDocumentTextScanningFunctions(dom) {

const elementFromPointValue = querySelectorChildOrSelf(testElement, elementFromPointSelector);
const caretRangeFromPointValue = querySelectorChildOrSelf(testElement, caretRangeFromPointSelector);
const startNode = getChildTextNodeOrSelf(dom, querySelectorChildOrSelf(testElement, startNodeSelector));
const endNode = getChildTextNodeOrSelf(dom, querySelectorChildOrSelf(testElement, endNodeSelector));
const startNode = getChildTextNodeOrSelf(window, querySelectorChildOrSelf(testElement, startNodeSelector));
const endNode = getChildTextNodeOrSelf(window, querySelectorChildOrSelf(testElement, endNodeSelector));

const startOffset2 = parseInt(/** @type {string} */ (startOffset), 10);
const endOffset2 = parseInt(/** @type {string} */ (endOffset), 10);
Expand All @@ -187,7 +148,7 @@ async function testDocumentTextScanningFunctions(dom) {
document.elementFromPoint = () => elementFromPointValue;

document.caretRangeFromPoint = (x, y) => {
const imposter = getChildTextNodeOrSelf(dom, findImposterElement(document));
const imposter = getChildTextNodeOrSelf(window, findImposterElement(document));
expect(!!imposter).toStrictEqual(hasImposter === 'true');

const range = document.createRange();
Expand Down Expand Up @@ -264,15 +225,12 @@ async function testDocumentTextScanningFunctions(dom) {
source.cleanup();
}
});
}
});

/**
* @param {JSDOM} dom
*/
async function testTextSourceRangeSeekFunctions(dom) {
const document = dom.window.document;

test('TextSourceRangeSeekFunctions', async () => {
describe('DOMTextScanner', () => {
const testDoc = domTest(path.join(dirname, 'data/html/test-document1.html'));
testDoc('Seek functions', async ({window}) => {
const {document} = window;
for (const testElement of /** @type {NodeListOf<HTMLElement>} */ (document.querySelectorAll('.test[data-test-type=text-source-range-seek]'))) {
// Get test parameters
const {
Expand Down Expand Up @@ -314,12 +272,4 @@ async function testTextSourceRangeSeekFunctions(dom) {
expect(content).toStrictEqual(expectedResultContent);
}
});
}


/** */
async function main() {
await testDocument1();
}

await main();
});
49 changes: 8 additions & 41 deletions test/dom-text-scanner.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,14 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

import fs from 'fs';
import {JSDOM} from 'jsdom';
import {fileURLToPath} from 'node:url';
import path from 'path';
import {expect, test} from 'vitest';
import {describe, expect} from 'vitest';
import {DOMTextScanner} from '../ext/js/dom/dom-text-scanner.js';
import {domTest} from './document-test.js';

const dirname = path.dirname(fileURLToPath(import.meta.url));

/**
* @param {string} fileName
* @returns {JSDOM}
*/
function createJSDOM(fileName) {
const domSource = fs.readFileSync(fileName, {encoding: 'utf8'});
return new JSDOM(domSource);
}

/**
* @param {Element} element
* @param {string} selector
Expand Down Expand Up @@ -111,13 +101,12 @@ function createAbsoluteGetComputedStyle(window) {
}


/**
* @param {JSDOM} dom
*/
async function testDomTextScanner(dom) {
const document = dom.window.document;
describe('DOMTextScanner', () => {
const testDoc = domTest(path.join(dirname, 'data/html/test-dom-text-scanner.html'));
testDoc('Seek tests', ({window}) => {
const {document} = window;
window.getComputedStyle = createAbsoluteGetComputedStyle(window);

test('DomTextScanner', () => {
for (const testElement of /** @type {NodeListOf<HTMLElement>} */ (document.querySelectorAll('y-test'))) {
let testData = JSON.parse(/** @type {string} */ (testElement.dataset.testData));
if (!Array.isArray(testData)) {
Expand Down Expand Up @@ -185,26 +174,4 @@ async function testDomTextScanner(dom) {
}
}
});
}


/** */
async function testDocument1() {
const dom = createJSDOM(path.join(dirname, 'data', 'html', 'test-dom-text-scanner.html'));
const window = dom.window;
try {
window.getComputedStyle = createAbsoluteGetComputedStyle(window);

await testDomTextScanner(dom);
} finally {
window.close();
}
}


/** */
async function main() {
await testDocument1();
}

await main();
});
1 change: 0 additions & 1 deletion vitest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ export default defineConfig({
'dev/lib/**',
'test/playwright/**'
],
environment: 'jsdom',
// @ts-expect-error - Appears to not be defined in the type definitions (https://vitest.dev/advanced/pool)
poolOptions: {
threads: {
Expand Down

0 comments on commit 77d2711

Please sign in to comment.