diff options
| author | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2023-11-29 21:53:22 -0500 | 
|---|---|---|
| committer | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2023-11-29 21:53:22 -0500 | 
| commit | f0c5ef69ca1758d5ef9201bc8a4375e5933888be (patch) | |
| tree | dfbc206fccaac88d59dac7ed90eca87f5fc8044d /test | |
| parent | bfcc9d3fba4a3ff85be167eb771a4c0f26f9cc49 (diff) | |
Update types
Diffstat (limited to 'test')
| -rw-r--r-- | test/deinflector.test.js | 14 | ||||
| -rw-r--r-- | test/document-util.test.js | 118 | ||||
| -rw-r--r-- | test/dom-text-scanner.test.js | 43 | ||||
| -rw-r--r-- | test/hotkey-util.test.js | 7 | 
4 files changed, 147 insertions, 35 deletions
| diff --git a/test/deinflector.test.js b/test/deinflector.test.js index edb85833..77184799 100644 --- a/test/deinflector.test.js +++ b/test/deinflector.test.js @@ -21,8 +21,16 @@ import path from 'path';  import {describe, expect, test} from 'vitest';  import {Deinflector} from '../ext/js/language/deinflector.js'; +/** + * @param {Deinflector} deinflector + * @param {string} source + * @param {string} expectedTerm + * @param {string} expectedRule + * @param {string[]|undefined} expectedReasons + * @returns {{has: false, reasons: null, rules: null}|{has: true, reasons: string[], rules: number}} + */  function hasTermReasons(deinflector, source, expectedTerm, expectedRule, expectedReasons) { -    for (const {term, reasons, rules} of deinflector.deinflect(source, source)) { +    for (const {term, reasons, rules} of deinflector.deinflect(source)) {          if (term !== expectedTerm) { continue; }          if (typeof expectedRule !== 'undefined') {              const expectedFlags = Deinflector.rulesToRuleFlags([expectedRule]); @@ -46,6 +54,7 @@ function hasTermReasons(deinflector, source, expectedTerm, expectedRule, expecte  } +/** */  function testDeinflections() {      const data = [          { @@ -915,7 +924,7 @@ function testDeinflections() {          }      ]; -    const deinflectionReasons = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'ext', 'data/deinflect.json'))); +    const deinflectionReasons = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'ext', 'data/deinflect.json'), {encoding: 'utf8'}));      const deinflector = new Deinflector(deinflectionReasons);      describe('deinflections', () => { @@ -939,6 +948,7 @@ function testDeinflections() {  } +/** */  function main() {      testDeinflections();  } diff --git a/test/document-util.test.js b/test/document-util.test.js index f2552f78..8c6ab69b 100644 --- a/test/document-util.test.js +++ b/test/document-util.test.js @@ -30,24 +30,48 @@ const dirname = path.dirname(fileURLToPath(import.meta.url));  // DOMRect class definition  class DOMRect { +    /** +     * @param {number} x +     * @param {number} y +     * @param {number} width +     * @param {number} height +     */      constructor(x, y, width, height) { +        /** @type {number} */          this._x = x; +        /** @type {number} */          this._y = y; +        /** @type {number} */          this._width = width; +        /** @type {number} */          this._height = height;      } +    /** @type {number} */      get x() { return this._x; } +    /** @type {number} */      get y() { return this._y; } +    /** @type {number} */      get width() { return this._width; } +    /** @type {number} */      get height() { return this._height; } +    /** @type {number} */      get left() { return this._x + Math.min(0, this._width); } +    /** @type {number} */      get right() { return this._x + Math.max(0, this._width); } +    /** @type {number} */      get top() { return this._y + Math.min(0, this._height); } +    /** @type {number} */      get bottom() { return this._y + Math.max(0, this._height); } +    /** @returns {string} */ +    toJSON() { return '<not implemented>'; }  } +/** + * @param {string} fileName + * @returns {JSDOM} + */  function createJSDOM(fileName) {      const domSource = fs.readFileSync(fileName, {encoding: 'utf8'});      const dom = new JSDOM(domSource); @@ -65,10 +89,20 @@ function createJSDOM(fileName) {      return dom;  } +/** + * @param {Element} element + * @param {string|undefined} selector + * @returns {?Element} + */  function querySelectorChildOrSelf(element, selector) {      return selector ? element.querySelector(selector) : element;  } +/** + * @param {JSDOM} dom + * @param {?Node} node + * @returns {?Text|Node} + */  function getChildTextNodeOrSelf(dom, node) {      if (node === null) { return null; }      const Node = dom.window.Node; @@ -76,6 +110,10 @@ function getChildTextNodeOrSelf(dom, node) {      return (childNode !== null && childNode.nodeType === Node.TEXT_NODE ? childNode : node);  } +/** + * @param {unknown} value + * @returns {unknown} + */  function getPrototypeOfOrNull(value) {      try {          return Object.getPrototypeOf(value); @@ -84,12 +122,17 @@ function getPrototypeOfOrNull(value) {      }  } +/** + * @param {Document} document + * @returns {?Element} + */  function findImposterElement(document) {      // Finds the imposter element based on it's z-index style      return document.querySelector('div[style*="2147483646"]>*');  } +/** */  async function testDocument1() {      const dom = createJSDOM(path.join(dirname, 'data', 'html', 'test-document1.html'));      const window = dom.window; @@ -102,13 +145,16 @@ async function testDocument1() {      }  } +/** + * @param {JSDOM} dom + */  async function testDocumentTextScanningFunctions(dom) {      const document = dom.window.document;      test('DocumentTextScanningFunctions', () => { -        for (const testElement of document.querySelectorAll('.test[data-test-type=scan]')) { -        // Get test parameters -            let { +        for (const testElement of /** @type {NodeListOf<HTMLElement>} */ (document.querySelectorAll('.test[data-test-type=scan]'))) { +            // Get test parameters +            const {                  elementFromPointSelector,                  caretRangeFromPointSelector,                  startNodeSelector, @@ -127,10 +173,10 @@ async function testDocumentTextScanningFunctions(dom) {              const startNode = getChildTextNodeOrSelf(dom, querySelectorChildOrSelf(testElement, startNodeSelector));              const endNode = getChildTextNodeOrSelf(dom, querySelectorChildOrSelf(testElement, endNodeSelector)); -            startOffset = parseInt(startOffset, 10); -            endOffset = parseInt(endOffset, 10); -            sentenceScanExtent = parseInt(sentenceScanExtent, 10); -            terminateAtNewlines = (terminateAtNewlines !== 'false'); +            const startOffset2 = parseInt(/** @type {string} */ (startOffset), 10); +            const endOffset2 = parseInt(/** @type {string} */ (endOffset), 10); +            const sentenceScanExtent2 = parseInt(/** @type {string} */ (sentenceScanExtent), 10); +            const terminateAtNewlines2 = (terminateAtNewlines !== 'false');              expect(elementFromPointValue).not.toStrictEqual(null);              expect(caretRangeFromPointValue).not.toStrictEqual(null); @@ -145,11 +191,25 @@ async function testDocumentTextScanningFunctions(dom) {                  expect(!!imposter).toStrictEqual(hasImposter === 'true');                  const range = document.createRange(); -                range.setStart(imposter ? imposter : startNode, startOffset); -                range.setEnd(imposter ? imposter : startNode, endOffset); +                range.setStart(/** @type {Node} */ (imposter ? imposter : startNode), startOffset2); +                range.setEnd(/** @type {Node} */ (imposter ? imposter : startNode), endOffset2);                  // Override getClientRects to return a rect guaranteed to contain (x, y) -                range.getClientRects = () => [new DOMRect(x - 1, y - 1, 2, 2)]; +                range.getClientRects = () => { +                    /** @type {import('test/document-types').PseudoDOMRectList} */ +                    const domRectList = Object.assign( +                        [new DOMRect(x - 1, y - 1, 2, 2)], +                        { +                            /** +                             * @this {DOMRect[]} +                             * @param {number} index +                             * @returns {DOMRect} +                             */ +                            item: function item(index) { return this[index]; } +                        } +                    ); +                    return domRectList; +                };                  return range;              }; @@ -192,8 +252,8 @@ async function testDocumentTextScanningFunctions(dom) {              const sentenceActual = DocumentUtil.extractSentence(                  source,                  false, -                sentenceScanExtent, -                terminateAtNewlines, +                sentenceScanExtent2, +                terminateAtNewlines2,                  terminatorMap,                  forwardQuoteMap,                  backwardQuoteMap @@ -206,13 +266,16 @@ async function testDocumentTextScanningFunctions(dom) {      });  } +/** + * @param {JSDOM} dom + */  async function testTextSourceRangeSeekFunctions(dom) {      const document = dom.window.document;      test('TextSourceRangeSeekFunctions', async () => { -        for (const testElement of document.querySelectorAll('.test[data-test-type=text-source-range-seek]')) { -        // Get test parameters -            let { +        for (const testElement of /** @type {NodeListOf<HTMLElement>} */ (document.querySelectorAll('.test[data-test-type=text-source-range-seek]'))) { +            // Get test parameters +            const {                  seekNodeSelector,                  seekNodeIsText,                  seekOffset, @@ -224,34 +287,37 @@ async function testTextSourceRangeSeekFunctions(dom) {                  expectedResultContent              } = testElement.dataset; -            seekOffset = parseInt(seekOffset, 10); -            seekLength = parseInt(seekLength, 10); -            expectedResultOffset = parseInt(expectedResultOffset, 10); +            const seekOffset2 = parseInt(/** @type {string} */ (seekOffset), 10); +            const seekLength2 = parseInt(/** @type {string} */ (seekLength), 10); +            const expectedResultOffset2 = parseInt(/** @type {string} */ (expectedResultOffset), 10); -            let seekNode = testElement.querySelector(seekNodeSelector); -            if (seekNodeIsText === 'true') { +            /** @type {?Node} */ +            let seekNode = testElement.querySelector(/** @type {string} */ (seekNodeSelector)); +            if (seekNodeIsText === 'true' && seekNode !== null) {                  seekNode = seekNode.firstChild;              } -            let expectedResultNode = testElement.querySelector(expectedResultNodeSelector); -            if (expectedResultNodeIsText === 'true') { +            /** @type {?Node} */ +            let expectedResultNode = testElement.querySelector(/** @type {string} */ (expectedResultNodeSelector)); +            if (expectedResultNodeIsText === 'true' && expectedResultNode !== null) {                  expectedResultNode = expectedResultNode.firstChild;              }              const {node, offset, content} = ( -            seekDirection === 'forward' ? -            new DOMTextScanner(seekNode, seekOffset, true, false).seek(seekLength) : -            new DOMTextScanner(seekNode, seekOffset, true, false).seek(-seekLength) +                seekDirection === 'forward' ? +                new DOMTextScanner(/** @type {Node} */ (seekNode), seekOffset2, true, false).seek(seekLength2) : +                new DOMTextScanner(/** @type {Node} */ (seekNode), seekOffset2, true, false).seek(-seekLength2)              );              expect(node).toStrictEqual(expectedResultNode); -            expect(offset).toStrictEqual(expectedResultOffset); +            expect(offset).toStrictEqual(expectedResultOffset2);              expect(content).toStrictEqual(expectedResultContent);          }      });  } +/** */  async function main() {      await testDocument1();  } diff --git a/test/dom-text-scanner.test.js b/test/dom-text-scanner.test.js index d1b31276..6d0c047b 100644 --- a/test/dom-text-scanner.test.js +++ b/test/dom-text-scanner.test.js @@ -22,11 +22,21 @@ import path from 'path';  import {expect, test} from 'vitest';  import {DOMTextScanner} from '../ext/js/dom/dom-text-scanner.js'; + +/** + * @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 + * @returns {?Node} + */  function querySelectorTextNode(element, selector) {      let textIndex = -1;      const match = /::text$|::nth-text\((\d+)\)$/.exec(selector); @@ -35,13 +45,16 @@ function querySelectorTextNode(element, selector) {          selector = selector.substring(0, selector.length - match[0].length);      }      const result = element.querySelector(selector); +    if (result === null) { +        return null; +    }      if (textIndex < 0) {          return result;      }      for (let n = result.firstChild; n !== null; n = n.nextSibling) { -        if (n.nodeType === n.constructor.TEXT_NODE) { +        if (n.nodeType === /** @type {typeof Node} */ (n.constructor).TEXT_NODE) {              if (textIndex === 0) { -                return n; +                return /** @type {Text} */ (n);              }              --textIndex;          } @@ -50,10 +63,16 @@ function querySelectorTextNode(element, selector) {  } +/** + * @param {import('jsdom').DOMWindow} window + * @param {(element: Element) => CSSStyleDeclaration} getComputedStyle + * @param {?Node} element + * @returns {number} + */  function getComputedFontSizeInPixels(window, getComputedStyle, element) {      for (; element !== null; element = element.parentNode) {          if (element.nodeType === window.Node.ELEMENT_NODE) { -            const fontSize = getComputedStyle(element).fontSize; +            const fontSize = getComputedStyle(/** @type {Element} */ (element)).fontSize;              if (fontSize.endsWith('px')) {                  const value = parseFloat(fontSize.substring(0, fontSize.length - 2));                  return value; @@ -64,14 +83,19 @@ function getComputedFontSizeInPixels(window, getComputedStyle, element) {      return defaultFontSize;  } +/** + * @param {import('jsdom').DOMWindow} window + * @returns {(element: Element, pseudoElement?: ?string) => CSSStyleDeclaration} + */  function createAbsoluteGetComputedStyle(window) {      // Wrapper to convert em units to px units      const getComputedStyleOld = window.getComputedStyle.bind(window); +    /** @type {(element: Element, pseudoElement?: ?string) => CSSStyleDeclaration} */      return (element, ...args) => {          const style = getComputedStyleOld(element, ...args);          return new Proxy(style, {              get: (target, property) => { -                let result = target[property]; +                let result = /** @type {import('core').SafeAny} */ (target)[property];                  if (typeof result === 'string') {                      result = result.replace(/([-+]?\d(?:\.\d)?(?:[eE][-+]?\d+)?)em/g, (g0, g1) => {                          const fontSize = getComputedFontSizeInPixels(window, getComputedStyleOld, element); @@ -85,12 +109,15 @@ function createAbsoluteGetComputedStyle(window) {  } +/** + * @param {JSDOM} dom + */  async function testDomTextScanner(dom) {      const document = dom.window.document;      test('DomTextScanner', () => { -        for (const testElement of document.querySelectorAll('y-test')) { -            let testData = JSON.parse(testElement.dataset.testData); +        for (const testElement of /** @type {NodeListOf<HTMLElement>} */ (document.querySelectorAll('y-test'))) { +            let testData = JSON.parse(/** @type {string} */ (testElement.dataset.testData));              if (!Array.isArray(testData)) {                  testData = [testData];              } @@ -159,19 +186,21 @@ 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, {DOMTextScanner}); +        await testDomTextScanner(dom);      } finally {          window.close();      }  } +/** */  async function main() {      await testDocument1();  } diff --git a/test/hotkey-util.test.js b/test/hotkey-util.test.js index 8666b98b..02622c40 100644 --- a/test/hotkey-util.test.js +++ b/test/hotkey-util.test.js @@ -19,8 +19,10 @@  import {expect, test} from 'vitest';  import {HotkeyUtil} from '../ext/js/input/hotkey-util.js'; +/** */  function testCommandConversions() {      test('CommandConversions', () => { +        /** @type {{os: import('environment').OperatingSystem, command: string, expectedCommand: string, expectedInput: {key: string, modifiers: import('input').Modifier[]}}[]} */          const data = [              {os: 'win', command: 'Alt+F', expectedCommand: 'Alt+F', expectedInput: {key: 'KeyF', modifiers: ['alt']}},              {os: 'win', command: 'F1',    expectedCommand: 'F1',    expectedInput: {key: 'F1', modifiers: []}}, @@ -49,8 +51,10 @@ function testCommandConversions() {      });  } +/** */  function testDisplayNames() {      test('DisplayNames', () => { +        /** @type {{os: import('environment').OperatingSystem, key: ?string, modifiers: import('input').Modifier[], expected: string}[]} */          const data = [              {os: 'win', key: null,   modifiers: [], expected: ''},              {os: 'win', key: 'KeyF', modifiers: [], expected: 'F'}, @@ -138,8 +142,10 @@ function testDisplayNames() {      });  } +/** */  function testSortModifiers() {      test('SortModifiers', () => { +        /** @type {{modifiers: import('input').Modifier[], expected: import('input').Modifier[]}[]} */          const data = [              {modifiers: [], expected: []},              {modifiers: ['shift', 'alt', 'ctrl', 'mouse4', 'meta', 'mouse1', 'mouse0'], expected: ['meta', 'ctrl', 'alt', 'shift', 'mouse0', 'mouse1', 'mouse4']} @@ -155,6 +161,7 @@ function testSortModifiers() {  } +/** */  function main() {      testCommandConversions();      testDisplayNames(); |