diff options
author | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2024-01-31 08:28:05 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-31 13:28:05 +0000 |
commit | 3e419aa562aab03ca20421aaf7e4d1a39194a5b4 (patch) | |
tree | 15e8bfe81fa5e3fae55e54802f14d94a7502a469 /test/deinflection-cycles.test.js | |
parent | 6807b05e9bd41f013364fae0cbcce83cf1ed37b6 (diff) |
Language transformer (#582)
* Set up new deinflection data file
* Define types
* Test
* Add internal types
* Set up loading for transforms
* Add getPartOfSpeechFlags
* Convert static methods
* Add note
* Add transform function
* Update trace structure
* Add a language tag to the language transform descriptor
* Add clear function
* Add function for multiple parts of speech
* Clarify naming
* Add getConditionFlagsFromConditionType
* Add plural function
* Replace usages of Deinflector
* Update tests
* Update config
* Remove old
* Rename
* Rename files
Diffstat (limited to 'test/deinflection-cycles.test.js')
-rw-r--r-- | test/deinflection-cycles.test.js | 165 |
1 files changed, 0 insertions, 165 deletions
diff --git a/test/deinflection-cycles.test.js b/test/deinflection-cycles.test.js deleted file mode 100644 index a010d7a3..00000000 --- a/test/deinflection-cycles.test.js +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (C) 2024 Yomitan 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 {readFileSync} from 'fs'; -import {join, dirname as pathDirname} from 'path'; -import {fileURLToPath} from 'url'; -import {describe, test} from 'vitest'; -import {parseJson} from '../dev/json.js'; -import {Deinflector} from '../ext/js/language/deinflector.js'; - -class DeinflectionNode { - /** - * @param {string} text - * @param {import('deinflector').ReasonTypeRaw[]} ruleNames - * @param {?RuleNode} ruleNode - * @param {?DeinflectionNode} previous - */ - constructor(text, ruleNames, ruleNode, previous) { - /** @type {string} */ - this.text = text; - /** @type {import('deinflector').ReasonTypeRaw[]} */ - this.ruleNames = ruleNames; - /** @type {?RuleNode} */ - this.ruleNode = ruleNode; - /** @type {?DeinflectionNode} */ - this.previous = previous; - } - - /** - * @param {DeinflectionNode} other - * @returns {boolean} - */ - historyIncludes(other) { - /** @type {?DeinflectionNode} */ - // eslint-disable-next-line @typescript-eslint/no-this-alias - let node = this; - for (; node !== null; node = node.previous) { - if ( - node.ruleNode === other.ruleNode && - node.text === other.text && - arraysAreEqual(node.ruleNames, other.ruleNames) - ) { - return true; - } - } - return false; - } - - /** - * @returns {DeinflectionNode[]} - */ - getHistory() { - /** @type {DeinflectionNode[]} */ - const results = []; - /** @type {?DeinflectionNode} */ - // eslint-disable-next-line @typescript-eslint/no-this-alias - let node = this; - for (; node !== null; node = node.previous) { - results.unshift(node); - } - return results; - } -} - -class RuleNode { - /** - * @param {string} groupName - * @param {import('deinflector').ReasonRaw} rule - */ - constructor(groupName, rule) { - /** @type {string} */ - this.groupName = groupName; - /** @type {import('deinflector').ReasonRaw} */ - this.rule = rule; - } -} - -/** - * @template [T=unknown] - * @param {T[]} rules1 - * @param {T[]} rules2 - * @returns {boolean} - */ -function arraysAreEqual(rules1, rules2) { - if (rules1.length !== rules2.length) { return false; } - for (const rule1 of rules1) { - if (!rules2.includes(rule1)) { return false; } - } - return true; -} - -describe('Deinflection data', () => { - test('Check for cycles', ({expect}) => { - const dirname = pathDirname(fileURLToPath(import.meta.url)); - - /** @type {import('deinflector').ReasonsRaw} */ - const deinflectionReasons = parseJson(readFileSync(join(dirname, '../ext/data/deinflect.json'), {encoding: 'utf8'})); - - /** @type {RuleNode[]} */ - const ruleNodes = []; - for (const [groupName, reasonInfo] of Object.entries(deinflectionReasons)) { - for (const rule of reasonInfo) { - ruleNodes.push(new RuleNode(groupName, rule)); - } - } - - /** @type {DeinflectionNode[]} */ - const deinflectionNodes = []; - for (const ruleNode of ruleNodes) { - deinflectionNodes.push(new DeinflectionNode(`?${ruleNode.rule.kanaIn}`, [], null, null)); - } - for (let i = 0; i < deinflectionNodes.length; ++i) { - const deinflectionNode = deinflectionNodes[i]; - const {text, ruleNames} = deinflectionNode; - for (const ruleNode of ruleNodes) { - const {kanaIn, kanaOut, rulesIn, rulesOut} = ruleNode.rule; - if ( - !Deinflector.rulesMatch(Deinflector.rulesToRuleFlags(ruleNames), Deinflector.rulesToRuleFlags(rulesIn)) || - !text.endsWith(kanaIn) || - (text.length - kanaIn.length + kanaOut.length) <= 0 - ) { - continue; - } - - const newDeinflectionNode = new DeinflectionNode( - text.substring(0, text.length - kanaIn.length) + kanaOut, - rulesOut, - ruleNode, - deinflectionNode - ); - - // Cycle check - if (deinflectionNode.historyIncludes(newDeinflectionNode)) { - const stack = []; - for (const item of newDeinflectionNode.getHistory()) { - stack.push( - item.ruleNode === null ? - `${item.text} (start)` : - `${item.text} (${item.ruleNode.groupName}, ${item.ruleNode.rule.rulesIn.join(',')}=>${item.ruleNode.rule.rulesOut.join(',')}, ${item.ruleNode.rule.kanaIn}=>${item.ruleNode.rule.kanaOut})` - ); - } - const message = `Cycle detected:\n ${stack.join('\n ')}`; - expect.soft(true, message).toEqual(false); - continue; - } - - deinflectionNodes.push(newDeinflectionNode); - } - } - }); -});
\ No newline at end of file |