@@ -38,6 +38,204 @@ describe('pluralize', () => {
3838 expect ( pluralize ( 5 , 'member' ) ) . toBe ( '5 members' )
3939 expect ( pluralize ( 10 , 'invitation' ) ) . toBe ( '10 invitations' )
4040 } )
41+
42+ it ( 'should return only the word when includeCount is false' , ( ) => {
43+ expect ( pluralize ( 1 , 'answer' , { includeCount : false } ) ) . toBe ( 'answer' )
44+ expect ( pluralize ( 2 , 'answer' , { includeCount : false } ) ) . toBe ( 'answers' )
45+ expect ( pluralize ( 1 , 'question' , { includeCount : false } ) ) . toBe ( 'question' )
46+ expect ( pluralize ( 5 , 'question' , { includeCount : false } ) ) . toBe ( 'questions' )
47+ expect ( pluralize ( 2 , 'city' , { includeCount : false } ) ) . toBe ( 'cities' )
48+ expect ( pluralize ( 2 , 'leaf' , { includeCount : false } ) ) . toBe ( 'leaves' )
49+ } )
50+
51+ // Tech/CS irregular plurals (truly irregular, no derivable pattern)
52+ it ( 'should handle truly irregular plurals' , ( ) => {
53+ // Common irregulars
54+ expect ( pluralize ( 2 , 'person' ) ) . toBe ( '2 people' )
55+ expect ( pluralize ( 2 , 'child' ) ) . toBe ( '2 children' )
56+ expect ( pluralize ( 2 , 'mouse' ) ) . toBe ( '2 mice' )
57+
58+ // -ex/-ix → -ices (no reliable rule, must be hardcoded)
59+ expect ( pluralize ( 2 , 'index' ) ) . toBe ( '2 indices' )
60+ expect ( pluralize ( 2 , 'vertex' ) ) . toBe ( '2 vertices' )
61+ expect ( pluralize ( 2 , 'matrix' ) ) . toBe ( '2 matrices' )
62+ expect ( pluralize ( 2 , 'appendix' ) ) . toBe ( '2 appendices' )
63+
64+ // Latin -um → -a
65+ expect ( pluralize ( 2 , 'datum' ) ) . toBe ( '2 data' )
66+ expect ( pluralize ( 2 , 'medium' ) ) . toBe ( '2 media' )
67+ expect ( pluralize ( 2 , 'criterion' ) ) . toBe ( '2 criteria' )
68+ expect ( pluralize ( 2 , 'phenomenon' ) ) . toBe ( '2 phenomena' )
69+ } )
70+
71+ // Derived rule: -sis → -ses
72+ it ( 'should handle -sis → -ses by rule' , ( ) => {
73+ expect ( pluralize ( 2 , 'analysis' ) ) . toBe ( '2 analyses' )
74+ expect ( pluralize ( 2 , 'basis' ) ) . toBe ( '2 bases' )
75+ expect ( pluralize ( 2 , 'hypothesis' ) ) . toBe ( '2 hypotheses' )
76+ expect ( pluralize ( 2 , 'thesis' ) ) . toBe ( '2 theses' )
77+ expect ( pluralize ( 2 , 'parenthesis' ) ) . toBe ( '2 parentheses' )
78+ expect ( pluralize ( 2 , 'synopsis' ) ) . toBe ( '2 synopses' )
79+ expect ( pluralize ( 2 , 'crisis' ) ) . toBe ( '2 crises' )
80+ expect ( pluralize ( 2 , 'diagnosis' ) ) . toBe ( '2 diagnoses' )
81+ expect ( pluralize ( 2 , 'ellipsis' ) ) . toBe ( '2 ellipses' )
82+ // Any new -sis word should work without adding to list
83+ expect ( pluralize ( 2 , 'oasis' ) ) . toBe ( '2 oases' )
84+ expect ( pluralize ( 2 , 'genesis' ) ) . toBe ( '2 geneses' )
85+ } )
86+
87+ // Derived rule: -xis → -xes
88+ it ( 'should handle -xis → -xes by rule' , ( ) => {
89+ expect ( pluralize ( 2 , 'axis' ) ) . toBe ( '2 axes' )
90+ // Any new -xis word should work without adding to list
91+ expect ( pluralize ( 2 , 'praxis' ) ) . toBe ( '2 praxes' )
92+ } )
93+
94+ // Derived rule: -ware stays unchanged
95+ it ( 'should handle -ware words staying unchanged by rule' , ( ) => {
96+ expect ( pluralize ( 2 , 'software' ) ) . toBe ( '2 software' )
97+ expect ( pluralize ( 2 , 'hardware' ) ) . toBe ( '2 hardware' )
98+ expect ( pluralize ( 2 , 'firmware' ) ) . toBe ( '2 firmware' )
99+ expect ( pluralize ( 2 , 'malware' ) ) . toBe ( '2 malware' )
100+ expect ( pluralize ( 2 , 'middleware' ) ) . toBe ( '2 middleware' )
101+ expect ( pluralize ( 2 , 'freeware' ) ) . toBe ( '2 freeware' )
102+ expect ( pluralize ( 2 , 'shareware' ) ) . toBe ( '2 shareware' )
103+ // Any new -ware word should work without adding to list
104+ expect ( pluralize ( 2 , 'spyware' ) ) . toBe ( '2 spyware' )
105+ expect ( pluralize ( 2 , 'bloatware' ) ) . toBe ( '2 bloatware' )
106+ } )
107+
108+ // Derived rule: -ics stays unchanged
109+ it ( 'should handle -ics words staying unchanged by rule' , ( ) => {
110+ expect ( pluralize ( 2 , 'analytics' ) ) . toBe ( '2 analytics' )
111+ expect ( pluralize ( 2 , 'graphics' ) ) . toBe ( '2 graphics' )
112+ expect ( pluralize ( 2 , 'physics' ) ) . toBe ( '2 physics' )
113+ expect ( pluralize ( 2 , 'mathematics' ) ) . toBe ( '2 mathematics' )
114+ expect ( pluralize ( 2 , 'statistics' ) ) . toBe ( '2 statistics' )
115+ expect ( pluralize ( 2 , 'logistics' ) ) . toBe ( '2 logistics' )
116+ expect ( pluralize ( 2 , 'economics' ) ) . toBe ( '2 economics' )
117+ // Any new -ics word should work without adding to list
118+ expect ( pluralize ( 2 , 'semantics' ) ) . toBe ( '2 semantics' )
119+ expect ( pluralize ( 2 , 'heuristics' ) ) . toBe ( '2 heuristics' )
120+ } )
121+
122+ it ( 'should handle other unchanging plurals' , ( ) => {
123+ // Data terms (hardcoded because 'data' is special case)
124+ expect ( pluralize ( 2 , 'data' ) ) . toBe ( '2 data' )
125+ expect ( pluralize ( 2 , 'metadata' ) ) . toBe ( '2 metadata' )
126+ expect ( pluralize ( 2 , 'feedback' ) ) . toBe ( '2 feedback' )
127+
128+ // Other words ending in -s that don't change
129+ expect ( pluralize ( 2 , 'series' ) ) . toBe ( '2 series' )
130+ expect ( pluralize ( 2 , 'chassis' ) ) . toBe ( '2 chassis' )
131+ expect ( pluralize ( 2 , 'species' ) ) . toBe ( '2 species' )
132+ } )
133+
134+ it ( 'should handle tech -o endings' , ( ) => {
135+ // Words that add -es (default for -o)
136+ expect ( pluralize ( 2 , 'hero' ) ) . toBe ( '2 heroes' )
137+ expect ( pluralize ( 2 , 'echo' ) ) . toBe ( '2 echoes' )
138+ expect ( pluralize ( 2 , 'veto' ) ) . toBe ( '2 vetoes' )
139+
140+ // Tech terms that just add -s
141+ expect ( pluralize ( 2 , 'photo' ) ) . toBe ( '2 photos' )
142+ expect ( pluralize ( 2 , 'video' ) ) . toBe ( '2 videos' )
143+ expect ( pluralize ( 2 , 'audio' ) ) . toBe ( '2 audios' )
144+ expect ( pluralize ( 2 , 'logo' ) ) . toBe ( '2 logos' )
145+ expect ( pluralize ( 2 , 'demo' ) ) . toBe ( '2 demos' )
146+ expect ( pluralize ( 2 , 'repo' ) ) . toBe ( '2 repos' )
147+ expect ( pluralize ( 2 , 'memo' ) ) . toBe ( '2 memos' )
148+ expect ( pluralize ( 2 , 'typo' ) ) . toBe ( '2 typos' )
149+ expect ( pluralize ( 2 , 'intro' ) ) . toBe ( '2 intros' )
150+ expect ( pluralize ( 2 , 'macro' ) ) . toBe ( '2 macros' )
151+ expect ( pluralize ( 2 , 'scenario' ) ) . toBe ( '2 scenarios' )
152+ expect ( pluralize ( 2 , 'portfolio' ) ) . toBe ( '2 portfolios' )
153+ expect ( pluralize ( 2 , 'ratio' ) ) . toBe ( '2 ratios' )
154+ expect ( pluralize ( 2 , 'zero' ) ) . toBe ( '2 zeros' )
155+ expect ( pluralize ( 2 , 'silo' ) ) . toBe ( '2 silos' ) // data silos
156+ } )
157+
158+ it ( 'should handle -f/-fe endings' , ( ) => {
159+ // Words that change -f to -ves (default behavior)
160+ expect ( pluralize ( 2 , 'half' ) ) . toBe ( '2 halves' )
161+ expect ( pluralize ( 2 , 'shelf' ) ) . toBe ( '2 shelves' )
162+ expect ( pluralize ( 2 , 'self' ) ) . toBe ( '2 selves' )
163+ expect ( pluralize ( 2 , 'leaf' ) ) . toBe ( '2 leaves' )
164+
165+ // -fe to -ves
166+ expect ( pluralize ( 2 , 'knife' ) ) . toBe ( '2 knives' )
167+ expect ( pluralize ( 2 , 'life' ) ) . toBe ( '2 lives' )
168+
169+ // Tech/design terms that just add -s
170+ expect ( pluralize ( 2 , 'proof' ) ) . toBe ( '2 proofs' ) // mathematical proofs
171+ expect ( pluralize ( 2 , 'brief' ) ) . toBe ( '2 briefs' ) // design briefs
172+ expect ( pluralize ( 2 , 'chief' ) ) . toBe ( '2 chiefs' ) // tech leads
173+ expect ( pluralize ( 2 , 'staff' ) ) . toBe ( '2 staffs' )
174+ expect ( pluralize ( 2 , 'serif' ) ) . toBe ( '2 serifs' ) // font serifs
175+ expect ( pluralize ( 2 , 'motif' ) ) . toBe ( '2 motifs' ) // design motifs
176+ expect ( pluralize ( 2 , 'gif' ) ) . toBe ( '2 gifs' )
177+ expect ( pluralize ( 2 , 'pdf' ) ) . toBe ( '2 pdfs' )
178+ } )
179+
180+ it ( 'should handle words ending in -y with vowel before' , ( ) => {
181+ // vowel + y -> just add -s
182+ expect ( pluralize ( 2 , 'key' ) ) . toBe ( '2 keys' )
183+ expect ( pluralize ( 2 , 'monkey' ) ) . toBe ( '2 monkeys' )
184+ expect ( pluralize ( 2 , 'toy' ) ) . toBe ( '2 toys' )
185+ expect ( pluralize ( 2 , 'boy' ) ) . toBe ( '2 boys' )
186+ expect ( pluralize ( 2 , 'day' ) ) . toBe ( '2 days' )
187+ expect ( pluralize ( 2 , 'way' ) ) . toBe ( '2 ways' )
188+ expect ( pluralize ( 2 , 'tray' ) ) . toBe ( '2 trays' )
189+ expect ( pluralize ( 2 , 'valley' ) ) . toBe ( '2 valleys' )
190+ expect ( pluralize ( 2 , 'donkey' ) ) . toBe ( '2 donkeys' )
191+ expect ( pluralize ( 2 , 'essay' ) ) . toBe ( '2 essays' )
192+ } )
193+
194+ it ( 'should handle words ending in -ful' , ( ) => {
195+ expect ( pluralize ( 2 , 'cupful' ) ) . toBe ( '2 cupfuls' )
196+ expect ( pluralize ( 2 , 'handful' ) ) . toBe ( '2 handfuls' )
197+ expect ( pluralize ( 2 , 'spoonful' ) ) . toBe ( '2 spoonfuls' )
198+ } )
199+
200+ it ( 'should handle words already ending in -s' , ( ) => {
201+ expect ( pluralize ( 2 , 'bus' ) ) . toBe ( '2 buses' )
202+ expect ( pluralize ( 2 , 'lens' ) ) . toBe ( '2 lenses' )
203+ expect ( pluralize ( 2 , 'gas' ) ) . toBe ( '2 gases' )
204+ } )
205+
206+ it ( 'should handle words ending in -z' , ( ) => {
207+ // Single z doubles
208+ expect ( pluralize ( 2 , 'quiz' ) ) . toBe ( '2 quizzes' )
209+ expect ( pluralize ( 2 , 'fez' ) ) . toBe ( '2 fezzes' )
210+ // Double z just adds -es
211+ expect ( pluralize ( 2 , 'buzz' ) ) . toBe ( '2 buzzes' )
212+ expect ( pluralize ( 2 , 'fizz' ) ) . toBe ( '2 fizzes' )
213+ } )
214+
215+ it ( 'should handle common tech terms' , ( ) => {
216+ // Regular tech plurals
217+ expect ( pluralize ( 2 , 'schema' ) ) . toBe ( '2 schemas' )
218+ expect ( pluralize ( 2 , 'API' ) ) . toBe ( '2 APIs' )
219+ expect ( pluralize ( 2 , 'SDK' ) ) . toBe ( '2 SDKs' )
220+ expect ( pluralize ( 2 , 'URL' ) ) . toBe ( '2 URLs' )
221+ expect ( pluralize ( 2 , 'CLI' ) ) . toBe ( '2 CLIs' )
222+ expect ( pluralize ( 2 , 'bug' ) ) . toBe ( '2 bugs' )
223+ expect ( pluralize ( 2 , 'feature' ) ) . toBe ( '2 features' )
224+ expect ( pluralize ( 2 , 'commit' ) ) . toBe ( '2 commits' )
225+ expect ( pluralize ( 2 , 'branch' ) ) . toBe ( '2 branches' )
226+ expect ( pluralize ( 2 , 'merge' ) ) . toBe ( '2 merges' )
227+ expect ( pluralize ( 2 , 'deploy' ) ) . toBe ( '2 deploys' )
228+ expect ( pluralize ( 2 , 'release' ) ) . toBe ( '2 releases' )
229+ expect ( pluralize ( 2 , 'sprint' ) ) . toBe ( '2 sprints' )
230+ expect ( pluralize ( 2 , 'ticket' ) ) . toBe ( '2 tickets' )
231+ expect ( pluralize ( 2 , 'endpoint' ) ) . toBe ( '2 endpoints' )
232+ expect ( pluralize ( 2 , 'webhook' ) ) . toBe ( '2 webhooks' )
233+ expect ( pluralize ( 2 , 'callback' ) ) . toBe ( '2 callbacks' )
234+ expect ( pluralize ( 2 , 'payload' ) ) . toBe ( '2 payloads' )
235+ expect ( pluralize ( 2 , 'token' ) ) . toBe ( '2 tokens' )
236+ expect ( pluralize ( 2 , 'query' ) ) . toBe ( '2 queries' )
237+ expect ( pluralize ( 2 , 'dependency' ) ) . toBe ( '2 dependencies' )
238+ } )
41239} )
42240
43241describe ( 'replaceNonStandardPlaceholderComments' , ( ) => {
0 commit comments