aboutsummaryrefslogtreecommitdiff
path: root/test/deinflection-cycles.test.js
diff options
context:
space:
mode:
authortoasted-nutbread <toasted-nutbread@users.noreply.github.com>2024-01-31 08:28:05 -0500
committerGitHub <noreply@github.com>2024-01-31 13:28:05 +0000
commit3e419aa562aab03ca20421aaf7e4d1a39194a5b4 (patch)
tree15e8bfe81fa5e3fae55e54802f14d94a7502a469 /test/deinflection-cycles.test.js
parent6807b05e9bd41f013364fae0cbcce83cf1ed37b6 (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.js165
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