Files
SubMiner/src/core/services/tokenizer/token-classification.test.ts
T

79 lines
2.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import assert from 'node:assert/strict';
import test from 'node:test';
import { MergedToken, PartOfSpeech } from '../../../types';
import {
isContentTokenByPos,
isKanaCandidateIgnorableChar,
isKanaCandidateText,
isKanaChar,
isKanaOnlyText,
isTokenPos2Excluded,
normalizeKana,
} from './token-classification';
const POS1_EXCLUSIONS = new Set(['助詞']);
const POS2_EXCLUSIONS = new Set(['非自立']);
function makeNoun(surface: string): MergedToken {
return {
surface,
reading: surface,
headword: surface,
startPos: 0,
endPos: surface.length,
partOfSpeech: PartOfSpeech.noun,
pos1: '名詞',
pos2: '非自立',
isMerged: false,
isKnown: false,
isNPlusOneTarget: false,
};
}
test('kana normalization folds halfwidth kana, composing the voiced pairs', () => {
// カ + ゙ is two code points for one character: without composing them, a
// halfwidth word counts as longer than the reading that spells it, which
// disqualifies the reading from known-word matching.
assert.equal(normalizeKana('ガク'), normalizeKana('ガク'));
assert.equal(normalizeKana('パン'), normalizeKana('パン'));
assert.equal(normalizeKana('ミナト'), 'みなと');
assert.ok(isKanaOnlyText('ガク'));
});
test('kana normalization leaves characters other than halfwidth kana alone', () => {
// The composition is scoped to the halfwidth runs: applied to the whole
// string, NFKC would also rewrite these into something the dictionary, the
// known-word list, and the frequency data were never keyed on.
assert.equal(normalizeKana('①ガ'), '①が');
assert.equal(normalizeKana('Aガ'), 'Aが');
assert.equal(normalizeKana('㍑ガ'), '㍑が');
assert.equal(normalizeKana('fiガ'), 'fiが');
});
test('kana classification excludes the katakana-hiragana double hyphen', () => {
assert.equal(isKanaChar(''), false);
assert.equal(isKanaOnlyText(''), false);
});
test('POS classification keeps kanji non-independent nouns as content', () => {
const token = makeNoun('日');
assert.equal(isTokenPos2Excluded(token, POS1_EXCLUSIONS, POS2_EXCLUSIONS), false);
assert.equal(isContentTokenByPos(token, POS1_EXCLUSIONS, POS2_EXCLUSIONS), true);
});
test('POS classification excludes kana non-independent nouns', () => {
const token = makeNoun('こと');
assert.equal(isTokenPos2Excluded(token, POS1_EXCLUSIONS, POS2_EXCLUSIONS), true);
assert.equal(isContentTokenByPos(token, POS1_EXCLUSIONS, POS2_EXCLUSIONS), false);
});
test('kana candidate classification allows punctuation around kana only', () => {
assert.equal(isKanaCandidateIgnorableChar(''), true);
assert.equal(isKanaCandidateIgnorableChar('猫'), false);
assert.equal(isKanaCandidateText('「かな!?」'), true);
assert.equal(isKanaCandidateText('「!?」'), false);
assert.equal(isKanaCandidateText('かな猫'), false);
});