const assert = require('node:assert'); const metamorpov = require('./metamorpov'); const options = { firstPerson: { name: "Amy", preset: "she", pov: "first" }, secondPerson: { name: "Amy", preset: "she", pov: "second" }, thirdPerson: { name: "Amy", preset: "she", pov: "third" }, thirdPersonPlural: { name: "Amy", preset: "they", pov: "third" }, thirdPersonOther: { name: "Amy", preset: "other", pov: "third", other: { "subjective": "xie", "objective": "xer", "possessive": "xer", "adjective": "xers", "reflexive": "xerself", "honorific-abbr": "Mx.", "honorific": "mix", "adult": "person", "youth": "kid", "parent": "parent", "child": "child", "sibling": "sibling", "married": "spouse", "dating": "partner", "plurality": "singular" } }, also: { name: "Amy", preset: "she", pov: "first", also: { "Amy": "Amelia", "abc": "abc abc", "cde": "cde", "slash": "\/" } } } /* vrb, vrn */ assert.equal(metamorpov.translate("vrb/be/", options.firstPerson), "was"); // I was assert.equal(metamorpov.translate("vrb/be/", options.secondPerson), "were"); // You were assert.equal(metamorpov.translate("vrb/be/", options.thirdPerson), "was"); // She was assert.equal(metamorpov.translate("vrb/be/", options.thirdPersonPlural), "were"); // They were assert.equal(metamorpov.translate("vrb/be/", options.thirdPersonOther), "was"); // Xie was assert.equal(metamorpov.translate("vrB/be/", options.firstPerson), "was"); // I was assert.equal(metamorpov.translate("vrB/be/", options.thirdPerson), "was"); // Amy was assert.equal(metamorpov.translate("Vrb/be/", options.firstPerson), "Was"); // Was I assert.equal(metamorpov.translate("Vrb/be/", options.secondPerson), "Were"); // Were you assert.equal(metamorpov.translate("vrb/present/be/", options.firstPerson), "am"); // I am assert.equal(metamorpov.translate("vrb/present/be/", options.secondPerson), "are"); // You are assert.equal(metamorpov.translate("vrn/present/be/", options.firstPerson), "is"); // She is assert.equal(metamorpov.translate("vrn/present/be/", options.thirdPerson), "is"); // She is assert.equal(metamorpov.translate("vrb/be/ good", options.firstPerson), "was good"); // Should continue after replacing assert.equal(metamorpov.translate("vrb/be/ vrb/have/", options.firstPerson), "was had"); // Should replace both /* pov */ assert.equal(metamorpov.translate("pov/s", options.firstPerson), "I"); assert.equal(metamorpov.translate("pov/s", options.secondPerson), "you"); assert.equal(metamorpov.translate("pov/s", options.thirdPerson), "she"); assert.equal(metamorpov.translate("pov/s", options.thirdPersonPlural), "they"); assert.equal(metamorpov.translate("pov/s", options.thirdPersonOther), "xie"); assert.equal(metamorpov.translate("pov/S", options.firstPerson), "I"); assert.equal(metamorpov.translate("pov/S", options.thirdPerson), "Amy"); assert.equal(metamorpov.translate("pov/o", options.firstPerson), "me"); assert.equal(metamorpov.translate("pov/o", options.secondPerson), "you"); assert.equal(metamorpov.translate("pov/o", options.thirdPerson), "her"); assert.equal(metamorpov.translate("pov/o", options.thirdPersonOther), "xer"); assert.equal(metamorpov.translate("pov/O", options.firstPerson), "me"); assert.equal(metamorpov.translate("pov/O", options.thirdPerson), "Amy"); assert.equal(metamorpov.translate("pov/p", options.firstPerson), "my"); assert.equal(metamorpov.translate("pov/p", options.secondPerson), "your"); assert.equal(metamorpov.translate("pov/p", options.thirdPerson), "her"); assert.equal(metamorpov.translate("pov/p", options.thirdPersonOther), "xer"); assert.equal(metamorpov.translate("pov/a", options.firstPerson), "mine"); assert.equal(metamorpov.translate("pov/a", options.secondPerson), "yours"); assert.equal(metamorpov.translate("pov/a", options.thirdPerson), "hers"); assert.equal(metamorpov.translate("pov/a", options.thirdPersonOther), "xers"); assert.equal(metamorpov.translate("pov/r", options.firstPerson), "myself"); assert.equal(metamorpov.translate("pov/r", options.secondPerson), "yourself"); assert.equal(metamorpov.translate("pov/r", options.thirdPerson), "herself"); assert.equal(metamorpov.translate("pov/r", options.thirdPersonOther), "xerself"); assert.equal(metamorpov.translate("pov/s knew", options.firstPerson), "I knew"); // Should continue after replacing assert.equal(metamorpov.translate("pov/s pov/r", options.firstPerson), "I myself"); // Should replace both /* plv */ assert.equal(metamorpov.translate("plv/s", options.firstPerson), "we"); assert.equal(metamorpov.translate("plv/s", options.secondPerson), "you"); assert.equal(metamorpov.translate("plv/s", options.thirdPerson), "they"); assert.equal(metamorpov.translate("plv/s", options.thirdPersonPlural), "they"); assert.equal(metamorpov.translate("plv/s", options.thirdPersonOther), "they"); assert.equal(metamorpov.translate("plv/S", options.firstPerson), "plv/S"); // Reference by name doesn't make sense for a group assert.equal(metamorpov.translate("plv/s knew", options.firstPerson), "we knew"); // Should continue after replacing assert.equal(metamorpov.translate("plv/s plv/r", options.firstPerson), "we ourselves"); // Should replace both /* y/n */ assert.equal(metamorpov.translate("Y/n", options.firstPerson), "Amy"); assert.equal(metamorpov.translate("y/n", options.firstPerson), "Amy"); // All lowercase assert.equal(metamorpov.translate("Y/N", options.firstPerson), "Amy"); // All uppercase assert.equal(metamorpov.translate("yn", options.firstPerson), "yn"); // Invalid, ignored assert.equal(metamorpov.translate("Y/n knew", options.firstPerson), "Amy knew"); // Should continue after replacing assert.equal(metamorpov.translate("Y/n Y/n", options.firstPerson), "Amy Amy"); // Should replace both /* prn */ assert.equal(metamorpov.translate("prn/s", options.firstPerson), "she"); assert.equal(metamorpov.translate("prn/s", options.secondPerson), "she"); assert.equal(metamorpov.translate("prn/s", options.thirdPerson), "she"); assert.equal(metamorpov.translate("prn/s", options.thirdPersonPlural), "they"); assert.equal(metamorpov.translate("prn/s", options.thirdPersonOther), "xie"); assert.equal(metamorpov.translate("prn/s knew", options.firstPerson), "she knew"); // Should continue after replacing assert.equal(metamorpov.translate("prn/s prn/s", options.firstPerson), "she she"); // Should replace both /* also */ assert.equal(metamorpov.translate("Y/n was here", options.also), "Amelia was here"); // Should run after Y/n assert.equal(metamorpov.translate("abc", options.also), "abc abc"); // Shouldn't recurse assert.equal(metamorpov.translate("cde", options.also), "cde"); // Also shouldn't recurse assert.equal(metamorpov.translate("slash", options.also), "\/"); // Shouldn't crash with special characters assert.equal(metamorpov.translate("Amy was here", options.also), "Amelia was here"); // Should continue after replacing assert.equal(metamorpov.translate("abc abc", options.also), "abc abc abc abc"); // Should replace both /* alt */ assert.equal(metamorpov.translate("alt/first/a/", options.firstPerson), "a"); assert.equal(metamorpov.translate("alt/first/a/", options.secondPerson), ""); assert.equal(metamorpov.translate("alt/first and second/a/", options.firstPerson), "a"); assert.equal(metamorpov.translate("alt/first and second/a/", options.secondPerson), "a"); assert.equal(metamorpov.translate("alt/third and first/a/", options.thirdPerson), "a"); assert.equal(metamorpov.translate("alt/first or second/a/b/", options.firstPerson), "a"); assert.equal(metamorpov.translate("alt/first or second/a/b/", options.secondPerson), "b"); assert.equal(metamorpov.translate("alt/first and second or third/a/b/", options.firstPerson), "a"); assert.equal(metamorpov.translate("alt/first and second or third/a/b/", options.secondPerson), "a"); assert.equal(metamorpov.translate("alt/first and second or third/a/b/", options.thirdPerson), "b"); assert.equal(metamorpov.translate("alt/first and second or third/a/b/", options.thirdPerson), "b"); assert.equal(metamorpov.translate("alt/first or second or third/a/b/c/", options.thirdPerson), "c"); assert.equal(metamorpov.translate("alt/a/b/c/", options.thirdPerson), "c"); assert.equal(metamorpov.translate("alt/first and first/a/", options.firstPerson), "alt/first and first/a/"); // Invalid, ignored assert.equal(metamorpov.translate("alt/first and second and third/a/", options.firstPerson), "alt/first and second and third/a/"); // Invalid, ignored assert.equal(metamorpov.translate("alt/first/a/bcdef", options.firstPerson), "abcdef"); // Should continue after replacing assert.equal(metamorpov.translate("alt/first/a/ alt/first/bc/", options.firstPerson), "a bc"); // Should replace both /* if, ife */ assert.equal(metamorpov.translate("if/prn/n is girl/bestie/", options.firstPerson), "bestie"); // prn/n is "girl" so if assert.equal(metamorpov.translate("if/prn/n is girl/bestie/", options.thirdPersonPlural), ""); // prn/n is "kid" so nothing assert.equal(metamorpov.translate("ife/prn/n is girl/bestie/broski/", options.firstPerson), "bestie"); // prn/n is "girl" so if assert.equal(metamorpov.translate("ife/prn/n is girl/bestie/broski/", options.thirdPersonOther), "broski"); // prn/n is "kid" so else assert.equal(metamorpov.translate("if/a is a/abc/def", options.firstPerson), "abcdef"); // Should continue after replacing assert.equal(metamorpov.translate("if/a is a/abc/ if/b is b/def/", options.firstPerson), "abc def"); // Should replace both /* cut */ assert.equal(metamorpov.translate("cut/off first -1/word/", options.firstPerson), "cut/off first -1/word/"); // Ignore negatives assert.equal(metamorpov.translate("cut/off first 0/word/", options.firstPerson), "cut/off first 0/word/"); // Ignore zero assert.equal(metamorpov.translate("cut/off first 1/word/", options.firstPerson), "ord"); assert.equal(metamorpov.translate("cut/off first 2/word/", options.firstPerson), "rd"); assert.equal(metamorpov.translate("cut/off first 3/word/", options.firstPerson), "d"); assert.equal(metamorpov.translate("cut/off first 4/word/", options.firstPerson), "d"); // Keep at least one letter assert.equal(metamorpov.translate("cut/off first 5/word/", options.firstPerson), "d"); // Don't worry about out-of-bounds assert.equal(metamorpov.translate("cut/off last 1/word/", options.firstPerson), "wor"); assert.equal(metamorpov.translate("cut/off last 2/word/", options.firstPerson), "wo"); assert.equal(metamorpov.translate("cut/off last 3/word/", options.firstPerson), "w"); assert.equal(metamorpov.translate("cut/off last 4/word/", options.firstPerson), "w"); // Keep at least one letter assert.equal(metamorpov.translate("cut/only first 1/word/", options.firstPerson), "w"); assert.equal(metamorpov.translate("cut/only first 2/word/", options.firstPerson), "wo"); assert.equal(metamorpov.translate("cut/only first 3/word/", options.firstPerson), "wor"); assert.equal(metamorpov.translate("cut/only first 4/word/", options.firstPerson), "wor"); // Cut at least one letter assert.equal(metamorpov.translate("cut/only last 1/word/", options.firstPerson), "d"); assert.equal(metamorpov.translate("cut/only last 2/word/", options.firstPerson), "rd"); assert.equal(metamorpov.translate("cut/only last 3/word/", options.firstPerson), "ord"); assert.equal(metamorpov.translate("cut/only last 4/word/", options.firstPerson), "ord"); // Cut at least one letter assert.equal(metamorpov.translate("cut/off first 1/cut/off last 1/word//", options.firstPerson), "or"); // Cut twice assert.equal(metamorpov.translate("cut/only first 1/word/oah", options.firstPerson), "woah"); // Should continue after replacing assert.equal(metamorpov.translate("cut/off last 1/ab/ cut/only last 2/abc/", options.firstPerson), "a bc"); // Should replace both /* cap */ assert.equal(metamorpov.translate("cap/WORD/", options.firstPerson), "word"); // All to lowercase assert.equal(metamorpov.translate("Cap/word/", options.firstPerson), "Word"); // First letter to capital assert.equal(metamorpov.translate("CAP/word/", options.firstPerson), "WORD"); // All to capital assert.equal(metamorpov.translate("Cap/woRD/", options.firstPerson), "WoRD"); // First letter to capital, other letters stay capital assert.equal(metamorpov.translate("cAP/word/", options.firstPerson), "cAP/word/"); // Avoid case insensitivity assert.equal(metamorpov.translate("cap/WORD/?", options.firstPerson), "word?"); // Should continue after replacing assert.equal(metamorpov.translate("cap/NO/ CAP/way/", options.firstPerson), "no WAY"); // Should replace both /* mrr */ assert.equal(metamorpov.translate("mrr/word/", options.firstPerson), "drow"); assert.equal(metamorpov.translate("mrr/Y/n/", options.firstPerson), "ymA"); // Should run after Y/n assert.equal(metamorpov.translate("mrr/word/sy", options.firstPerson), "drowsy"); // Should continue after replacing assert.equal(metamorpov.translate("mrr/word/ mrr/drow/", options.firstPerson), "drow word"); // Should replace both /* a/an */ assert.equal(metamorpov.translate("a/an pear", options.firstPerson), "a pear"); // Starts with a consonant sound assert.equal(metamorpov.translate("a/an apple", options.firstPerson), "an apple"); // Starts with a vowel sound assert.equal(metamorpov.translate("a/an hour", options.firstPerson), "an hour"); // Starts with a vowel sound despite consonant letter assert.equal(metamorpov.translate("a/an 1800s-era", options.firstPerson), "an 1800s-era"); // "Eighteen-hundreds" starts with a vowel sound