mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 13:00:39 +03:00
Refactor and test language API
This commit is contained in:
parent
c5d80328ef
commit
edda87c7ee
|
@ -11,7 +11,7 @@ import { ArrowLeftIcon, ArrowRightIcon, CheckIcon, ChevronDoubleDownIcon, CrossI
|
||||||
import { useConceptTheme } from '../context/ThemeContext';
|
import { useConceptTheme } from '../context/ThemeContext';
|
||||||
import useConceptText from '../hooks/useConceptText';
|
import useConceptText from '../hooks/useConceptText';
|
||||||
import { Grammeme, ITextRequest, IWordForm, IWordFormPlain } from '../models/language';
|
import { Grammeme, ITextRequest, IWordForm, IWordFormPlain } from '../models/language';
|
||||||
import { getCompatibleGrams, matchWordForm, parseGrammemes } from '../models/languageAPI';
|
import { getCompatibleGrams, wordFormEquals, parseGrammemes } from '../models/languageAPI';
|
||||||
import { IConstituenta, TermForm } from '../models/rsform';
|
import { IConstituenta, TermForm } from '../models/rsform';
|
||||||
import { colorfgGrammeme } from '../utils/color';
|
import { colorfgGrammeme } from '../utils/color';
|
||||||
import { labelGrammeme } from '../utils/labels';
|
import { labelGrammeme } from '../utils/labels';
|
||||||
|
@ -81,7 +81,7 @@ function DlgEditWordForms({ hideWindow, target, onSave }: DlgEditWordFormsProps)
|
||||||
};
|
};
|
||||||
setForms(forms => [
|
setForms(forms => [
|
||||||
newForm,
|
newForm,
|
||||||
...forms.filter(value => !matchWordForm(value, newForm))
|
...forms.filter(value => !wordFormEquals(value, newForm))
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,7 +143,7 @@ function DlgEditWordForms({ hideWindow, target, onSave }: DlgEditWordFormsProps)
|
||||||
text: form.text,
|
text: form.text,
|
||||||
grams: parseGrammemes(form.grams).filter(gram => SelectorGrammemesList.find(item => item === gram as Grammeme))
|
grams: parseGrammemes(form.grams).filter(gram => SelectorGrammemesList.find(item => item === gram as Grammeme))
|
||||||
}
|
}
|
||||||
if (newForm.grams.length === 2 && !lexeme.some(test => matchWordForm(test, newForm))) {
|
if (newForm.grams.length === 2 && !lexeme.some(test => wordFormEquals(test, newForm))) {
|
||||||
lexeme.push(newForm);
|
lexeme.push(newForm);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,13 +1,96 @@
|
||||||
import { Grammeme } from './language';
|
import { Case, Grammeme, NounGrams, Plurality, VerbGrams } from './language';
|
||||||
import { parseEntityReference, parseGrammemes, parseSyntacticReference } from './languageAPI';
|
import {
|
||||||
|
getCompatibleGrams, grammemeCompare,
|
||||||
|
parseEntityReference, parseGrammemes, parseSyntacticReference,
|
||||||
|
wordFormEquals
|
||||||
|
} from './languageAPI';
|
||||||
|
|
||||||
|
|
||||||
|
describe('Testing wordform equality', () => {
|
||||||
|
test('empty input',
|
||||||
|
() => {
|
||||||
|
expect(wordFormEquals({text: '', grams: []}, {text: '', grams: []})).toEqual(true);
|
||||||
|
expect(wordFormEquals({text: '', grams: []}, {text: '11', grams: []})).toEqual(true);
|
||||||
|
expect(wordFormEquals({text: '11', grams: []}, {text: '', grams: []})).toEqual(true);
|
||||||
|
expect(wordFormEquals({text: '11', grams: []}, {text: '42', grams: []})).toEqual(true);
|
||||||
|
expect(wordFormEquals({text: '', grams: ['nomn']}, {text: '', grams: []})).toEqual(false);
|
||||||
|
expect(wordFormEquals({text: '11', grams: ['nomn']}, {text: '11', grams: []})).toEqual(false);
|
||||||
|
expect(wordFormEquals({text: '', grams: []}, {text: '', grams: ['nomn']})).toEqual(false);
|
||||||
|
expect(wordFormEquals({text: '11', grams: []}, {text: '11', grams: ['nomn']})).toEqual(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('regular grammemes',
|
||||||
|
() => {
|
||||||
|
expect(wordFormEquals({text: '', grams: ['nomn']}, {text: '', grams: ['nomn']})).toEqual(true);
|
||||||
|
expect(wordFormEquals({text: '', grams: ['nomn']}, {text: '', grams: ['sing']})).toEqual(false);
|
||||||
|
expect(wordFormEquals({text: '', grams: ['nomn', 'sing']}, {text: '', grams: ['nomn', 'sing']})).toEqual(true);
|
||||||
|
expect(wordFormEquals({text: '', grams: ['nomn', 'sing']}, {text: '11', grams: ['nomn', 'sing']})).toEqual(true);
|
||||||
|
expect(wordFormEquals({text: '11', grams: ['nomn', 'sing']}, {text: '', grams: ['nomn', 'sing']})).toEqual(true);
|
||||||
|
expect(wordFormEquals({text: '11', grams: ['nomn', 'sing']}, {text: '11', grams: ['nomn', 'sing']})).toEqual(true);
|
||||||
|
expect(wordFormEquals({text: '42', grams: ['nomn', 'sing']}, {text: '11', grams: ['nomn', 'sing']})).toEqual(true);
|
||||||
|
expect(wordFormEquals({text: '', grams: ['nomn', 'sing']}, {text: '', grams: ['sing', 'nomn']})).toEqual(false);
|
||||||
|
expect(wordFormEquals({text: '', grams: ['nomn', 'sing']}, {text: '', grams: ['nomn']})).toEqual(false);
|
||||||
|
expect(wordFormEquals({text: '', grams: ['nomn', 'nomn']}, {text: '', grams: ['nomn']})).toEqual(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('custom grammemes',
|
||||||
|
() => {
|
||||||
|
expect(wordFormEquals({text: '', grams: ['с1']}, {text: '', grams: ['с1']})).toEqual(true);
|
||||||
|
expect(wordFormEquals({text: '', grams: ['с1']}, {text: '', grams: ['с2']})).toEqual(false);
|
||||||
|
expect(wordFormEquals({text: '', grams: ['sing']}, {text: '', grams: ['с1']})).toEqual(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('Testing grammeme ordering', () => {
|
||||||
|
test('empty input',
|
||||||
|
() => {
|
||||||
|
expect(grammemeCompare('', '')).toEqual(0);
|
||||||
|
expect(grammemeCompare(' ', ' ')).toEqual(0);
|
||||||
|
expect(grammemeCompare('', '123')).toBeLessThan(0);
|
||||||
|
expect(grammemeCompare('123', '')).toBeGreaterThan(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('regular grammemes',
|
||||||
|
() => {
|
||||||
|
expect(grammemeCompare('NOUN', 'NOUN')).toEqual(0);
|
||||||
|
expect(grammemeCompare('NOUN', Grammeme.NOUN)).toEqual(0);
|
||||||
|
|
||||||
|
expect(grammemeCompare(Grammeme.sing, Grammeme.plur)).toBeLessThan(0);
|
||||||
|
expect(grammemeCompare('sing', 'plur')).toBeLessThan(0);
|
||||||
|
expect(grammemeCompare('plur', 'sing')).toBeGreaterThan(0);
|
||||||
|
|
||||||
|
expect(grammemeCompare('NOUN', 'ADJF')).toBeLessThan(0);
|
||||||
|
expect(grammemeCompare('ADJF', 'NOUN')).toBeGreaterThan(0);
|
||||||
|
expect(grammemeCompare('ADJS', 'NOUN')).toBeGreaterThan(0);
|
||||||
|
expect(grammemeCompare('ADJS', 'ADJF')).toBeGreaterThan(0);
|
||||||
|
|
||||||
|
expect(grammemeCompare('loct', 'ablt')).toBeGreaterThan(0);
|
||||||
|
expect(grammemeCompare('ablt', 'accs')).toBeGreaterThan(0);
|
||||||
|
expect(grammemeCompare('accs', 'datv')).toBeGreaterThan(0);
|
||||||
|
expect(grammemeCompare('datv', 'gent')).toBeGreaterThan(0);
|
||||||
|
expect(grammemeCompare('gent', 'nomn')).toBeGreaterThan(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('custom grammemes',
|
||||||
|
() => {
|
||||||
|
expect(grammemeCompare('noun', 'noun')).toEqual(0);
|
||||||
|
expect(grammemeCompare('NOUN', 'noun')).toBeLessThan(0);
|
||||||
|
expect(grammemeCompare('PRTF', 'noun')).toBeLessThan(0);
|
||||||
|
expect(grammemeCompare('noun', 'NOUN')).toBeGreaterThan(0);
|
||||||
|
expect(grammemeCompare('aab', 'aaa')).toBeGreaterThan(0);
|
||||||
|
expect(grammemeCompare('aaa', 'aab')).toBeLessThan(0);
|
||||||
|
expect(grammemeCompare('test', 'abcd')).toBeGreaterThan(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
describe('Testing grammeme parsing', () => {
|
describe('Testing grammeme parsing', () => {
|
||||||
test('empty input',
|
test('empty input',
|
||||||
() => {
|
() => {
|
||||||
expect(parseGrammemes('').length).toBe(0);
|
expect(parseGrammemes('')).toStrictEqual([]);
|
||||||
expect(parseGrammemes(' ').length).toBe(0);
|
expect(parseGrammemes(' ')).toStrictEqual([]);
|
||||||
expect(parseGrammemes(' , ').length).toBe(0);
|
expect(parseGrammemes(' , ')).toStrictEqual([]);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('regular grammemes',
|
test('regular grammemes',
|
||||||
|
@ -15,12 +98,29 @@ describe('Testing grammeme parsing', () => {
|
||||||
expect(parseGrammemes('NOUN')).toStrictEqual([Grammeme.NOUN]);
|
expect(parseGrammemes('NOUN')).toStrictEqual([Grammeme.NOUN]);
|
||||||
expect(parseGrammemes('sing,nomn')).toStrictEqual([Grammeme.sing, Grammeme.nomn]);
|
expect(parseGrammemes('sing,nomn')).toStrictEqual([Grammeme.sing, Grammeme.nomn]);
|
||||||
expect(parseGrammemes('nomn,sing')).toStrictEqual([Grammeme.sing, Grammeme.nomn]);
|
expect(parseGrammemes('nomn,sing')).toStrictEqual([Grammeme.sing, Grammeme.nomn]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('custom grammemes',
|
||||||
|
() => {
|
||||||
expect(parseGrammemes('nomn,invalid,sing')).toStrictEqual([Grammeme.sing, Grammeme.nomn, 'invalid']);
|
expect(parseGrammemes('nomn,invalid,sing')).toStrictEqual([Grammeme.sing, Grammeme.nomn, 'invalid']);
|
||||||
expect(parseGrammemes('invalid,test')).toStrictEqual(['invalid', 'test']);
|
expect(parseGrammemes('invalid,test')).toStrictEqual(['invalid', 'test']);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('Testing grammeme compatibility', () => {
|
||||||
|
test('empty input',
|
||||||
|
() => {
|
||||||
|
expect(getCompatibleGrams([])).toStrictEqual([...VerbGrams, ...NounGrams]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('regular grammemes',
|
||||||
|
() => {
|
||||||
|
expect(getCompatibleGrams([Grammeme.NOUN])).toStrictEqual([...Case, ...Plurality]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
describe('Testing reference parsing', () => {
|
describe('Testing reference parsing', () => {
|
||||||
test('entity reference',
|
test('entity reference',
|
||||||
() => {
|
() => {
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { GramData, Grammeme, GrammemeGroups, IEntityReference, ISyntacticReferen
|
||||||
/**
|
/**
|
||||||
* Equality comparator for {@link IWordForm}. Compares a set of Grammemes attached to wordforms
|
* Equality comparator for {@link IWordForm}. Compares a set of Grammemes attached to wordforms
|
||||||
*/
|
*/
|
||||||
export function matchWordForm(left: IWordForm, right: IWordForm): boolean {
|
export function wordFormEquals(left: IWordForm, right: IWordForm): boolean {
|
||||||
if (left.grams.length !== right.grams.length) {
|
if (left.grams.length !== right.grams.length) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -19,18 +19,10 @@ export function matchWordForm(left: IWordForm, right: IWordForm): boolean {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseSingleGrammeme(text: string): GramData {
|
|
||||||
if (Object.values(Grammeme).includes(text as Grammeme)) {
|
|
||||||
return text as Grammeme;
|
|
||||||
} else {
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compares {@link GramData} based on Grammeme enum and alpha order for strings.
|
* Compares {@link GramData} based on Grammeme enum and alpha order for strings.
|
||||||
*/
|
*/
|
||||||
export function compareGrammemes(left: GramData, right: GramData): number {
|
export function grammemeCompare(left: GramData, right: GramData): number {
|
||||||
const indexLeft = Object.values(Grammeme).findIndex(gram => gram === left as Grammeme);
|
const indexLeft = Object.values(Grammeme).findIndex(gram => gram === left as Grammeme);
|
||||||
const indexRight = Object.values(Grammeme).findIndex(gram => gram === right as Grammeme);
|
const indexRight = Object.values(Grammeme).findIndex(gram => gram === right as Grammeme);
|
||||||
if (indexLeft === -1 && indexRight === -1) {
|
if (indexLeft === -1 && indexRight === -1) {
|
||||||
|
@ -51,12 +43,12 @@ export function parseGrammemes(termForm: string): GramData[] {
|
||||||
const result: GramData[] = [];
|
const result: GramData[] = [];
|
||||||
const chunks = termForm.split(',');
|
const chunks = termForm.split(',');
|
||||||
chunks.forEach(chunk => {
|
chunks.forEach(chunk => {
|
||||||
chunk = chunk.trim();
|
const gram = chunk.trim();
|
||||||
if (chunk !== '') {
|
if (gram !== '') {
|
||||||
result.push(parseSingleGrammeme(chunk));
|
result.push(gram);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return result.sort(compareGrammemes);
|
return result.sort(grammemeCompare);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
import { LayoutTypes } from 'reagraph';
|
import { LayoutTypes } from 'reagraph';
|
||||||
|
|
||||||
import { type GramData, Grammeme, ReferenceType } from '../models/language';
|
import { type GramData, Grammeme, ReferenceType } from '../models/language';
|
||||||
import { compareGrammemes } from '../models/languageAPI';
|
import { grammemeCompare } from '../models/languageAPI';
|
||||||
import { CstType } from '../models/rsform';
|
import { CstType } from '../models/rsform';
|
||||||
import { ColoringScheme } from '../pages/RSFormPage/EditorTermGraph';
|
import { ColoringScheme } from '../pages/RSFormPage/EditorTermGraph';
|
||||||
import { labelGrammeme, labelReferenceType } from './labels';
|
import { labelGrammeme, labelReferenceType } from './labels';
|
||||||
|
@ -61,7 +61,7 @@ export interface IGrammemeOption {
|
||||||
* Compares {@link IGrammemeOption} based on Grammeme comparison.
|
* Compares {@link IGrammemeOption} based on Grammeme comparison.
|
||||||
*/
|
*/
|
||||||
export function compareGrammemeOptions(left: IGrammemeOption, right: IGrammemeOption): number {
|
export function compareGrammemeOptions(left: IGrammemeOption, right: IGrammemeOption): number {
|
||||||
return compareGrammemes(left.value, right.value);
|
return grammemeCompare(left.value, right.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue
Block a user