mirror of
https://gitlab.com/PronounsPage/PronounsPage.git
synced 2025-09-08 06:51:43 -04:00
(test) check that grammar tables contain valid morphemes
This commit is contained in:
parent
db8c3c97f3
commit
22161f04d7
@ -1,8 +1,12 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { loadGrammarTableVariantsConverter } from '~/src/data.ts';
|
import { loadGrammarTableVariantsConverter } from '~/src/data.ts';
|
||||||
import type { Example, ExampleValues } from '~/src/language/examples.ts';
|
import type { Example, ExampleValues } from '~/src/language/examples.ts';
|
||||||
import type { GrammarTableDefinition, Variant, SectionDefinition } from '~/src/language/grammarTables.ts';
|
import {
|
||||||
import { toMorphemeValue } from '~/src/language/morphemes.ts';
|
type GrammarTableDefinition,
|
||||||
|
type Variant,
|
||||||
|
type SectionDefinition,
|
||||||
|
expandVariantsForSection,
|
||||||
|
} from '~/src/language/grammarTables.ts';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
grammarTable: GrammarTableDefinition;
|
grammarTable: GrammarTableDefinition;
|
||||||
@ -12,51 +16,15 @@ const props = defineProps<{
|
|||||||
|
|
||||||
const variantsFromBaseConverter = await loadGrammarTableVariantsConverter();
|
const variantsFromBaseConverter = await loadGrammarTableVariantsConverter();
|
||||||
|
|
||||||
const expandVariantsForSection = (sectionVariants: SectionDefinition['variants']): Variant[] => {
|
|
||||||
if (Array.isArray(sectionVariants)) {
|
|
||||||
return sectionVariants.map((sectionVariant) => {
|
|
||||||
const cells = sectionVariant.cells.map((cellDefinition) => {
|
|
||||||
if (cellDefinition === null) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
if (typeof cellDefinition === 'string') {
|
|
||||||
return [{ morpheme: cellDefinition }];
|
|
||||||
}
|
|
||||||
const cellPartDefinitions = Array.isArray(cellDefinition) ? cellDefinition : [cellDefinition];
|
|
||||||
return cellPartDefinitions
|
|
||||||
.map((cellPartDefinition) => {
|
|
||||||
if ('singular' in cellPartDefinition) {
|
|
||||||
return cellPartDefinition[!props.exampleValues.plural ? 'singular' : 'plural'];
|
|
||||||
}
|
|
||||||
return cellPartDefinition;
|
|
||||||
})
|
|
||||||
.map((cellPartDefinition) => ({
|
|
||||||
...cellPartDefinition,
|
|
||||||
prefix: cellPartDefinition.prefix ? toMorphemeValue(cellPartDefinition.prefix) : undefined,
|
|
||||||
suffix: cellPartDefinition.suffix ? toMorphemeValue(cellPartDefinition.suffix) : undefined,
|
|
||||||
highlightsMorphemes: cellPartDefinition.highlightsMorphemes
|
|
||||||
? new Set(cellPartDefinition.highlightsMorphemes)
|
|
||||||
: undefined,
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
return { ...sectionVariant, cells };
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
if (Object.hasOwn(variantsFromBaseConverter, sectionVariants.type)) {
|
|
||||||
return variantsFromBaseConverter[sectionVariants.type](sectionVariants);
|
|
||||||
}
|
|
||||||
throw new Error(`variant type ${sectionVariants.type} is unknown`);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const buildVariantsForSection = (
|
const buildVariantsForSection = (
|
||||||
sectionVariants: SectionDefinition['variants'],
|
sectionVariants: SectionDefinition['variants'],
|
||||||
): Variant[] => {
|
): Variant[] => {
|
||||||
return expandVariantsForSection(sectionVariants).filter((variant) => {
|
return expandVariantsForSection(sectionVariants, variantsFromBaseConverter, props.exampleValues)
|
||||||
return variant.cells.flatMap((cell) => cell).some((cellPart) => {
|
.filter((variant) => {
|
||||||
return props.exampleValues.morphemeValues.getSpelling(cellPart.morpheme) !== undefined;
|
return variant.cells.flatMap((cell) => cell).some((cellPart) => {
|
||||||
|
return props.exampleValues.morphemeValues.getSpelling(cellPart.morpheme) !== undefined;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const sections = computed(() => {
|
const sections = computed(() => {
|
||||||
|
@ -23,9 +23,9 @@ export const loadTranslations = async (locale?: string): Promise<Translations> =
|
|||||||
return (await import(`~/locale/${locale ?? getLocale()}/translations.suml`)).default;
|
return (await import(`~/locale/${locale ?? getLocale()}/translations.suml`)).default;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const loadGrammarTableVariantsConverter = async () => {
|
export const loadGrammarTableVariantsConverter = async (locale?: string) => {
|
||||||
try {
|
try {
|
||||||
return (await import(`~/locale/${getLocale()}/language/grammarTableVariantsConverter.ts`)).default as
|
return (await import(`~/locale/${locale ?? getLocale()}/language/grammarTableVariantsConverter.ts`)).default as
|
||||||
VariantsFromBaseConverter;
|
VariantsFromBaseConverter;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return {};
|
return {};
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import type { MorphemeValue } from '~/src/language/morphemes.ts';
|
import type { ExampleValues } from '~/src/language/examples.ts';
|
||||||
|
import { type MorphemeValue, toMorphemeValue } from '~/src/language/morphemes.ts';
|
||||||
|
|
||||||
export type GrammarTablesDefinition = (GrammarTableDefinition | string)[]
|
export type GrammarTablesDefinition = (GrammarTableDefinition | string)[]
|
||||||
| { simple: (GrammarTableDefinition | string)[]; comprehensive: (GrammarTableDefinition | string)[] };
|
| { simple: (GrammarTableDefinition | string)[]; comprehensive: (GrammarTableDefinition | string)[] };
|
||||||
@ -56,3 +57,44 @@ export interface CellPart {
|
|||||||
prefix?: MorphemeValue;
|
prefix?: MorphemeValue;
|
||||||
suffix?: MorphemeValue;
|
suffix?: MorphemeValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const expandVariantsForSection = (
|
||||||
|
sectionVariants: SectionDefinition['variants'],
|
||||||
|
variantsFromBaseConverter: VariantsFromBaseConverter,
|
||||||
|
exampleValues: ExampleValues,
|
||||||
|
): Variant[] => {
|
||||||
|
if (Array.isArray(sectionVariants)) {
|
||||||
|
return sectionVariants.map((sectionVariant) => {
|
||||||
|
const cells = sectionVariant.cells.map((cellDefinition) => {
|
||||||
|
if (cellDefinition === null) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
if (typeof cellDefinition === 'string') {
|
||||||
|
return [{ morpheme: cellDefinition }];
|
||||||
|
}
|
||||||
|
const cellPartDefinitions = Array.isArray(cellDefinition) ? cellDefinition : [cellDefinition];
|
||||||
|
return cellPartDefinitions
|
||||||
|
.map((cellPartDefinition) => {
|
||||||
|
if ('singular' in cellPartDefinition) {
|
||||||
|
return cellPartDefinition[!exampleValues.plural ? 'singular' : 'plural'];
|
||||||
|
}
|
||||||
|
return cellPartDefinition;
|
||||||
|
})
|
||||||
|
.map((cellPartDefinition) => ({
|
||||||
|
...cellPartDefinition,
|
||||||
|
prefix: cellPartDefinition.prefix ? toMorphemeValue(cellPartDefinition.prefix) : undefined,
|
||||||
|
suffix: cellPartDefinition.suffix ? toMorphemeValue(cellPartDefinition.suffix) : undefined,
|
||||||
|
highlightsMorphemes: cellPartDefinition.highlightsMorphemes
|
||||||
|
? new Set(cellPartDefinition.highlightsMorphemes)
|
||||||
|
: undefined,
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
return { ...sectionVariant, cells };
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (Object.hasOwn(variantsFromBaseConverter, sectionVariants.type)) {
|
||||||
|
return variantsFromBaseConverter[sectionVariants.type](sectionVariants);
|
||||||
|
}
|
||||||
|
throw new Error(`variant type ${sectionVariants.type} is unknown`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
49
test/language/grammarTables.ts
Normal file
49
test/language/grammarTables.ts
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import { expect } from 'vitest';
|
||||||
|
|
||||||
|
import type { ExampleValues } from '~/src/language/examples.ts';
|
||||||
|
import { expandVariantsForSection } from '~/src/language/grammarTables.ts';
|
||||||
|
import type {
|
||||||
|
CellPart,
|
||||||
|
GrammarTableDefinition,
|
||||||
|
GrammarTablesDefinition, VariantsFromBaseConverter,
|
||||||
|
} from '~/src/language/grammarTables.ts';
|
||||||
|
import { MorphemeValues } from '~/src/language/morphemes.ts';
|
||||||
|
|
||||||
|
const getGrammarTableDefinitions = (grammarTablesDefinition: GrammarTablesDefinition): GrammarTableDefinition[] => {
|
||||||
|
let grammarTableDefinitions: (GrammarTableDefinition | string)[];
|
||||||
|
if (Array.isArray(grammarTablesDefinition)) {
|
||||||
|
grammarTableDefinitions = grammarTablesDefinition;
|
||||||
|
} else {
|
||||||
|
grammarTableDefinitions = [...grammarTablesDefinition.simple, ...grammarTablesDefinition.comprehensive];
|
||||||
|
}
|
||||||
|
return grammarTableDefinitions.filter((grammarTableDefinition) => typeof grammarTableDefinition !== 'string');
|
||||||
|
};
|
||||||
|
|
||||||
|
const getCellParts = (
|
||||||
|
grammarTablesDefinition: GrammarTablesDefinition,
|
||||||
|
variantsFromBaseConverter: VariantsFromBaseConverter,
|
||||||
|
exampleValues: ExampleValues,
|
||||||
|
): CellPart[] => {
|
||||||
|
return getGrammarTableDefinitions(grammarTablesDefinition)
|
||||||
|
.flatMap((grammarTableDefinition) => grammarTableDefinition.sections)
|
||||||
|
.flatMap((sectionDefinition) => {
|
||||||
|
return expandVariantsForSection(sectionDefinition.variants, variantsFromBaseConverter, exampleValues);
|
||||||
|
})
|
||||||
|
.flatMap((variant) => variant.cells)
|
||||||
|
.flatMap((cell) => cell);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const checkContainsValidMorphemes = (
|
||||||
|
grammarTablesDefinition: GrammarTablesDefinition,
|
||||||
|
variantsFromBaseConverter: VariantsFromBaseConverter,
|
||||||
|
morphemes: string[],
|
||||||
|
) => {
|
||||||
|
for (const plural of [false, true]) {
|
||||||
|
const exampleValues = { morphemeValues: new MorphemeValues({}), plural };
|
||||||
|
const cellParts = getCellParts(grammarTablesDefinition, variantsFromBaseConverter, exampleValues);
|
||||||
|
for (const cellPart of cellParts) {
|
||||||
|
expect(morphemes).toContain(cellPart.morpheme);
|
||||||
|
expect(morphemes).toEqual(expect.arrayContaining([...cellPart.highlightsMorphemes ?? []]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
@ -5,11 +5,14 @@ import type { PronounData } from '~/locale/data.ts';
|
|||||||
import allLocales from '~/locale/locales.ts';
|
import allLocales from '~/locale/locales.ts';
|
||||||
import { loadSuml, loadTsv } from '~/server/loader.ts';
|
import { loadSuml, loadTsv } from '~/server/loader.ts';
|
||||||
import { parsePronouns } from '~/src/buildPronoun.ts';
|
import { parsePronouns } from '~/src/buildPronoun.ts';
|
||||||
|
import { loadGrammarTableVariantsConverter } from '~/src/data.ts';
|
||||||
|
import { checkContainsValidMorphemes } from '~/test/language/grammarTables.ts';
|
||||||
|
|
||||||
describe.each(allLocales)('config for $code', async ({ code }) => {
|
describe.each(allLocales)('config for $code', async ({ code }) => {
|
||||||
const config = await loadSuml<Config>(`locale/${code}/config.suml`);
|
const config = await loadSuml<Config>(`locale/${code}/config.suml`);
|
||||||
const pronounsRaw = await loadTsv<PronounData<string>>(`locale/${code}/pronouns/pronouns.tsv`);
|
const pronounsRaw = await loadTsv<PronounData<string>>(`locale/${code}/pronouns/pronouns.tsv`);
|
||||||
const pronouns = parsePronouns(config, pronounsRaw);
|
const pronouns = parsePronouns(config, pronounsRaw);
|
||||||
|
const variantsFromBaseConverter = await loadGrammarTableVariantsConverter(code);
|
||||||
|
|
||||||
test('pronouns.generator.startPronoun must be a valid pronoun', () => {
|
test('pronouns.generator.startPronoun must be a valid pronoun', () => {
|
||||||
if (!config.pronouns.enabled || !config.pronouns.generator.enabled) {
|
if (!config.pronouns.enabled || !config.pronouns.generator.enabled) {
|
||||||
@ -29,4 +32,11 @@ describe.each(allLocales)('config for $code', async ({ code }) => {
|
|||||||
}
|
}
|
||||||
expect(config.pronouns.morphemes).toEqual(expect.arrayContaining(Object.keys(config.pronouns.emoji.morphemes)));
|
expect(config.pronouns.morphemes).toEqual(expect.arrayContaining(Object.keys(config.pronouns.emoji.morphemes)));
|
||||||
});
|
});
|
||||||
|
test('pronouns.grammarTables contain valid morphemes', () => {
|
||||||
|
if (!config.pronouns.enabled || !config.pronouns.grammarTables) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
checkContainsValidMorphemes(config.pronouns.grammarTables, variantsFromBaseConverter, config.pronouns.morphemes);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user