From b5d57bf19b69dc2a544a9d2a7232e185548a9374 Mon Sep 17 00:00:00 2001 From: Valentyne Stigloher Date: Fri, 12 Jan 2024 23:01:16 +0100 Subject: [PATCH] (pronouns) add modifiers when formatting pronoun with slashes --- src/classes.js | 21 +++++++-- test/buildPronoun.test.js | 92 +++----------------------------------- test/classes.test.js | 53 +++++++++++++++++++++- test/fixtures/pronouns.js | 94 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 168 insertions(+), 92 deletions(-) diff --git a/src/classes.js b/src/classes.js index fe73e6fe3..c64cddbc1 100644 --- a/src/classes.js +++ b/src/classes.js @@ -1,4 +1,4 @@ -import { buildDict, buildList, capitalise, escapePronunciationString } from './helpers.js'; +import { buildDict, buildList, capitalise, escapeControlSymbols, escapePronunciationString } from './helpers.js'; import MORPHEMES from '../data/pronouns/morphemes.js'; const config = process.env.CONFIG || global.config; @@ -472,15 +472,28 @@ export class Pronoun { } toStringSlashes() { - if (!config.pronouns.slashes || this.description) { + if (!config.pronouns.slashes) { return null; } + let chunks; if (Array.isArray(config.pronouns.slashes)) { - return config.pronouns.slashes.map((m) => this.morphemes[m]).join('/'); + chunks = config.pronouns.slashes.map((m) => this.morphemes[m]); + } else { + chunks = Object.values(this.morphemes); } - return Object.values(this.morphemes).join('/'); + if (this.plural[0]) { + chunks.push(':plural'); + } + if (this.pluralHonorific[0]) { + chunks.push(':plural-honorific'); + } + if (this.description) { + chunks.push(`:description=${escapeControlSymbols(this.description)}`); + } + + return chunks.join('/'); } static from(data) { diff --git a/test/buildPronoun.test.js b/test/buildPronoun.test.js index 670982118..2442a0731 100644 --- a/test/buildPronoun.test.js +++ b/test/buildPronoun.test.js @@ -12,7 +12,7 @@ jest.unstable_mockModule('../data/pronouns/morphemes.js', () => { const { Pronoun } = await import('../src/classes.js'); const { buildPronoun } = await import('../src/buildPronoun.js'); -const { default: pronouns } = await import('./fixtures/pronouns.js'); +const { default: pronouns, generated: generatedPronouns } = await import('./fixtures/pronouns.js'); beforeEach(() => { global.config.pronouns = { @@ -132,86 +132,22 @@ describe('when configured that slashes contain all morphemes', () => { test('builds generated pronoun from all morphemes', () => { const actual = expect(buildPronoun(pronouns, 'ae/aer/aer/aers/aerself')); actual.toBeDefined(); - actual.toEqual(new Pronoun( - 'ae/aer', - '', - false, - { - pronoun_subject: 'ae', - pronoun_object: 'aer', - possessive_determiner: 'aer', - possessive_pronoun: 'aers', - reflexive: 'aerself', - }, - [false], - [false], - [], - '__generator__', - false, - )); + actual.toEqual(generatedPronouns.aer); }); test('builds generated pronoun from all required morphemes and plural modifier', () => { const actual = expect(buildPronoun(pronouns, 'ae/aer/aer/aers/aerselves/:plural')); actual.toBeDefined(); - actual.toEqual(new Pronoun( - 'ae/aer', - '', - false, - { - pronoun_subject: 'ae', - pronoun_object: 'aer', - possessive_determiner: 'aer', - possessive_pronoun: 'aers', - reflexive: 'aerselves', - }, - [true], - [false], - [], - '__generator__', - false, - )); + actual.toEqual(generatedPronouns.aerPlural); }); test('builds generated pronoun from all required morphemes and plural honorific modifier', () => { const actual = expect(buildPronoun(pronouns, 'ae/aer/aer/aers/aerselves/:plural-honorific')); actual.toBeDefined(); - actual.toEqual(new Pronoun( - 'ae/aer', - '', - false, - { - pronoun_subject: 'ae', - pronoun_object: 'aer', - possessive_determiner: 'aer', - possessive_pronoun: 'aers', - reflexive: 'aerselves', - }, - [false], - [true], - [], - '__generator__', - false, - )); + actual.toEqual(generatedPronouns.aerPluralHonorific); }); test('builds generated pronoun from all required morphemes and description', () => { const actual = expect(buildPronoun(pronouns, 'ae/aer/aer/aers/aerself/:description=Neopronoun “ae” `/ “æ”')); actual.toBeDefined(); - actual.toEqual(new Pronoun( - 'ae/aer', - 'Neopronoun “ae” / “æ”', - false, - { - pronoun_subject: 'ae', - pronoun_object: 'aer', - possessive_determiner: 'aer', - possessive_pronoun: 'aers', - reflexive: 'aerself', - }, - [false], - [false], - [], - '__generator__', - false, - )); + actual.toEqual(generatedPronouns.aerWithDescription); }); test('builds generated pronoun from all required morphemes and modifiers', () => { const actual = expect(buildPronoun( @@ -219,23 +155,7 @@ describe('when configured that slashes contain all morphemes', () => { 'ae/aer/:description=Neopronoun “ae” `/ “æ”/:plural/aer/aers/aerselves', )); actual.toBeDefined(); - actual.toEqual(new Pronoun( - 'ae/aer', - 'Neopronoun “ae” / “æ”', - false, - { - pronoun_subject: 'ae', - pronoun_object: 'aer', - possessive_determiner: 'aer', - possessive_pronoun: 'aers', - reflexive: 'aerselves', - }, - [true], - [false], - [], - '__generator__', - false, - )); + actual.toEqual(generatedPronouns.aerPluralWithDescription); }); test('builds nothing if morphemes are missing', () => { expect(buildPronoun(pronouns, 'ae/aer/aer/aerself')).toBeUndefined(); diff --git a/test/classes.test.js b/test/classes.test.js index 387d625dc..1e8bbcd7f 100644 --- a/test/classes.test.js +++ b/test/classes.test.js @@ -1,4 +1,4 @@ -import { describe, expect, test } from '@jest/globals'; +import { beforeEach, describe, expect, test } from '@jest/globals'; import { MergedPronounGroup, PronounGroup, PronounLibrary } from '../src/classes.js'; import { mockTranslations } from './fixtures/translations.js'; @@ -12,9 +12,58 @@ const translations = { }; mockTranslations(translations); -const { default: pronouns } = await import('./fixtures/pronouns.js'); +const { default: pronouns, generated: generatedPronouns } = await import('./fixtures/pronouns.js'); const { default: translator } = await import('../src/translator.js'); +describe('formatting a pronoun with slashes', () => { + describe('when slashes are not configured', () => { + beforeEach(() => { + global.config.pronouns = {}; + }); + + test('yields no result', () => { + expect(generatedPronouns.aer.toStringSlashes()).toBeNull(); + }); + }); + describe('when configured that slashes contain all morphemes', () => { + beforeEach(() => { + global.config.pronouns = { slashes: true }; + }); + + test('chunks contain all morphemes', () => { + expect(generatedPronouns.aer.toStringSlashes()) + .toEqual('ae/aer/aer/aers/aerself'); + }); + test('adds plural modifier if necessary', () => { + expect(generatedPronouns.aerPlural.toStringSlashes()) + .toEqual('ae/aer/aer/aers/aerselves/:plural'); + }); + test('adds plural honorific modifier if necessary', () => { + expect(generatedPronouns.aerPluralHonorific.toStringSlashes()) + .toEqual('ae/aer/aer/aers/aerselves/:plural-honorific'); + }); + test('adds escaped description if necessary', () => { + expect(generatedPronouns.aerWithDescription.toStringSlashes()) + .toEqual('ae/aer/aer/aers/aerself/:description=Neopronoun “ae” `/ “æ”'); + }); + test('adds multiple modifiers if necessary', () => { + expect(generatedPronouns.aerPluralWithDescription.toStringSlashes()) + .toEqual('ae/aer/aer/aers/aerselves/:plural/:description=Neopronoun “ae” `/ “æ”'); + }); + }); + describe('when configured that slashes contain some morphemes', () => { + beforeEach(() => { + global.config.pronouns = { + slashes: ['pronoun_subject', 'pronoun_object', 'possessive_determiner', 'reflexive'], + }; + }); + + test('chunks contain configured morphemes', () => { + expect(generatedPronouns.aer.toStringSlashes()).toEqual('ae/aer/aer/aerself'); + }); + }); +}); + describe('when merging pronoun groups by key', () => { test('groups without keys are not assigned a merged group', () => { const groups = [ diff --git a/test/fixtures/pronouns.js b/test/fixtures/pronouns.js index e1fbe4665..fdfd9d2a7 100644 --- a/test/fixtures/pronouns.js +++ b/test/fixtures/pronouns.js @@ -68,3 +68,97 @@ export default { she, they, }; + +const aer = new Pronoun( + 'ae/aer', + '', + false, + { + pronoun_subject: 'ae', + pronoun_object: 'aer', + possessive_determiner: 'aer', + possessive_pronoun: 'aers', + reflexive: 'aerself', + }, + [false], + [false], + [], + '__generator__', + false, +); +const aerPlural = new Pronoun( + 'ae/aer', + '', + false, + { + pronoun_subject: 'ae', + pronoun_object: 'aer', + possessive_determiner: 'aer', + possessive_pronoun: 'aers', + reflexive: 'aerselves', + }, + [true], + [false], + [], + '__generator__', + false, +); +const aerPluralHonorific = new Pronoun( + 'ae/aer', + '', + false, + { + pronoun_subject: 'ae', + pronoun_object: 'aer', + possessive_determiner: 'aer', + possessive_pronoun: 'aers', + reflexive: 'aerselves', + }, + [false], + [true], + [], + '__generator__', + false, +); +const aerWithDescription = new Pronoun( + 'ae/aer', + 'Neopronoun “ae” / “æ”', + false, + { + pronoun_subject: 'ae', + pronoun_object: 'aer', + possessive_determiner: 'aer', + possessive_pronoun: 'aers', + reflexive: 'aerself', + }, + [false], + [false], + [], + '__generator__', + false, +); +const aerPluralWithDescription = new Pronoun( + 'ae/aer', + 'Neopronoun “ae” / “æ”', + false, + { + pronoun_subject: 'ae', + pronoun_object: 'aer', + possessive_determiner: 'aer', + possessive_pronoun: 'aers', + reflexive: 'aerselves', + }, + [true], + [false], + [], + '__generator__', + false, +); + +export const generated = { + aer, + aerPlural, + aerPluralHonorific, + aerWithDescription, + aerPluralWithDescription, +};