Pop-up dictionary browser extension for language learning. Successor to Yomichan. (PERSONAL FORK)
1/*
2 * Copyright (C) 2024-2025 Yomitan Authors
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18import {fail} from 'node:assert';
19import {fileURLToPath} from 'node:url';
20import path from 'path';
21import {afterAll, describe, expect, test} from 'vitest';
22import {TextSourceRange} from '../ext/js/dom/text-source-range.js';
23import {setupDomTest} from './fixtures/dom-test.js';
24
25
26const dirname = path.dirname(fileURLToPath(import.meta.url));
27const textSourceRangeTestEnv = await setupDomTest(path.join(dirname, 'data/html/text-source-range.html'));
28
29
30describe('TextSourceRange', () => {
31 const {window, teardown} = textSourceRangeTestEnv;
32 afterAll(() => teardown(global));
33
34 test('lazy', () => {
35 const {document} = window;
36 const testElement /** @type {NodeListOf<HTMLElement>} */ = document.getElementById('text-source-range-lazy');
37 if (testElement === null) {
38 fail('test element not found');
39 }
40
41 const range = new Range();
42 range.selectNodeContents(testElement);
43
44 const source = TextSourceRange.createLazy(range);
45 const startLength = source.setStartOffset(200, false);
46 const endLength = source.setEndOffset(200, true, false);
47
48 const text = source.text();
49 const textLength = text.length;
50
51 expect(startLength).toBeLessThanOrEqual(textLength);
52 expect(endLength).toBeLessThan(textLength);
53 const count = (text.match(/人/g) || []).length;
54 expect(count).toEqual(1);
55 });
56
57 test('standard', () => {
58 const {document} = window;
59 const testElement /** @type {NodeListOf<HTMLElement>} */ = document.getElementById('text-source-range');
60 if (testElement === null) {
61 fail('test element not found');
62 }
63
64 const range = new Range();
65
66 range.selectNodeContents(testElement);
67
68 const source = TextSourceRange.create(range);
69 const startLength = source.setStartOffset(15, false);
70 const endLength = source.setEndOffset(15, true, false);
71
72 const text = source.text();
73 const textLength = text.length;
74
75 expect(startLength).toBeLessThan(textLength);
76 expect(endLength).toBeLessThan(textLength);
77 const count = (text.match(/山/g) || []).length;
78 expect(count).toEqual(1);
79 });
80});