digital-objects 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +4 -0
- package/CHANGELOG.md +25 -0
- package/LICENSE +21 -0
- package/README.md +476 -0
- package/dist/ai-database-adapter.d.ts +49 -0
- package/dist/ai-database-adapter.d.ts.map +1 -0
- package/dist/ai-database-adapter.js +89 -0
- package/dist/ai-database-adapter.js.map +1 -0
- package/dist/errors.d.ts +47 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +72 -0
- package/dist/errors.js.map +1 -0
- package/dist/http-schemas.d.ts +165 -0
- package/dist/http-schemas.d.ts.map +1 -0
- package/dist/http-schemas.js +55 -0
- package/dist/http-schemas.js.map +1 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/linguistic.d.ts +54 -0
- package/dist/linguistic.d.ts.map +1 -0
- package/dist/linguistic.js +226 -0
- package/dist/linguistic.js.map +1 -0
- package/dist/memory-provider.d.ts +46 -0
- package/dist/memory-provider.d.ts.map +1 -0
- package/dist/memory-provider.js +279 -0
- package/dist/memory-provider.js.map +1 -0
- package/dist/ns-client.d.ts +88 -0
- package/dist/ns-client.d.ts.map +1 -0
- package/dist/ns-client.js +253 -0
- package/dist/ns-client.js.map +1 -0
- package/dist/ns-exports.d.ts +23 -0
- package/dist/ns-exports.d.ts.map +1 -0
- package/dist/ns-exports.js +21 -0
- package/dist/ns-exports.js.map +1 -0
- package/dist/ns.d.ts +60 -0
- package/dist/ns.d.ts.map +1 -0
- package/dist/ns.js +818 -0
- package/dist/ns.js.map +1 -0
- package/dist/r2-persistence.d.ts +112 -0
- package/dist/r2-persistence.d.ts.map +1 -0
- package/dist/r2-persistence.js +252 -0
- package/dist/r2-persistence.js.map +1 -0
- package/dist/schema-validation.d.ts +80 -0
- package/dist/schema-validation.d.ts.map +1 -0
- package/dist/schema-validation.js +233 -0
- package/dist/schema-validation.js.map +1 -0
- package/dist/types.d.ts +184 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +26 -0
- package/dist/types.js.map +1 -0
- package/package.json +55 -0
- package/src/ai-database-adapter.test.ts +610 -0
- package/src/ai-database-adapter.ts +189 -0
- package/src/benchmark.test.ts +109 -0
- package/src/errors.ts +91 -0
- package/src/http-schemas.ts +67 -0
- package/src/index.ts +87 -0
- package/src/linguistic.test.ts +1107 -0
- package/src/linguistic.ts +253 -0
- package/src/memory-provider.ts +470 -0
- package/src/ns-client.test.ts +1360 -0
- package/src/ns-client.ts +342 -0
- package/src/ns-exports.ts +23 -0
- package/src/ns.test.ts +1381 -0
- package/src/ns.ts +1215 -0
- package/src/provider.test.ts +675 -0
- package/src/r2-persistence.test.ts +263 -0
- package/src/r2-persistence.ts +367 -0
- package/src/schema-validation.test.ts +167 -0
- package/src/schema-validation.ts +330 -0
- package/src/types.ts +252 -0
- package/test/action-status.test.ts +42 -0
- package/test/batch-limits.test.ts +165 -0
- package/test/docs.test.ts +48 -0
- package/test/errors.test.ts +148 -0
- package/test/http-validation.test.ts +401 -0
- package/test/ns-client-errors.test.ts +208 -0
- package/test/ns-namespace.test.ts +307 -0
- package/test/performance.test.ts +168 -0
- package/test/schema-validation-error.test.ts +213 -0
- package/test/schema-validation.test.ts +440 -0
- package/test/search-escaping.test.ts +359 -0
- package/test/security.test.ts +322 -0
- package/tsconfig.json +10 -0
- package/wrangler.jsonc +16 -0
|
@@ -0,0 +1,1107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Comprehensive tests for linguistic utilities
|
|
3
|
+
*
|
|
4
|
+
* Tests for pluralize, singularize, deriveNoun, and deriveVerb
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { describe, it, expect } from 'vitest'
|
|
8
|
+
import { pluralize, singularize, deriveNoun, deriveVerb } from './linguistic'
|
|
9
|
+
|
|
10
|
+
describe('Linguistic Utilities', () => {
|
|
11
|
+
describe('pluralize()', () => {
|
|
12
|
+
describe('regular words (add "s")', () => {
|
|
13
|
+
it('should pluralize "cat" to "cats"', () => {
|
|
14
|
+
expect(pluralize('cat')).toBe('cats')
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
it('should pluralize "dog" to "dogs"', () => {
|
|
18
|
+
expect(pluralize('dog')).toBe('dogs')
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
it('should pluralize "book" to "books"', () => {
|
|
22
|
+
expect(pluralize('book')).toBe('books')
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
it('should pluralize "car" to "cars"', () => {
|
|
26
|
+
expect(pluralize('car')).toBe('cars')
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
it('should pluralize "house" to "houses"', () => {
|
|
30
|
+
expect(pluralize('house')).toBe('houses')
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
it('should pluralize "tree" to "trees"', () => {
|
|
34
|
+
expect(pluralize('tree')).toBe('trees')
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
it('should pluralize "apple" to "apples"', () => {
|
|
38
|
+
expect(pluralize('apple')).toBe('apples')
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
it('should pluralize "table" to "tables"', () => {
|
|
42
|
+
expect(pluralize('table')).toBe('tables')
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
it('should pluralize "chair" to "chairs"', () => {
|
|
46
|
+
expect(pluralize('chair')).toBe('chairs')
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
it('should pluralize "phone" to "phones"', () => {
|
|
50
|
+
expect(pluralize('phone')).toBe('phones')
|
|
51
|
+
})
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
describe('words ending in s/x/z (add "es")', () => {
|
|
55
|
+
it('should pluralize "bus" to "buses"', () => {
|
|
56
|
+
expect(pluralize('bus')).toBe('buses')
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
it('should pluralize "class" to "classes"', () => {
|
|
60
|
+
expect(pluralize('class')).toBe('classes')
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
it('should pluralize "boss" to "bosses"', () => {
|
|
64
|
+
expect(pluralize('boss')).toBe('bosses')
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
it('should pluralize "box" to "boxes"', () => {
|
|
68
|
+
expect(pluralize('box')).toBe('boxes')
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
it('should pluralize "tax" to "taxes"', () => {
|
|
72
|
+
expect(pluralize('tax')).toBe('taxes')
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
it('should pluralize "fox" to "foxes"', () => {
|
|
76
|
+
expect(pluralize('fox')).toBe('foxes')
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
it('should pluralize "buzz" to "buzzes"', () => {
|
|
80
|
+
expect(pluralize('buzz')).toBe('buzzes')
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
it('should pluralize "quiz" to "quizes" (implementation note: does not double z)', () => {
|
|
84
|
+
// Note: English standard is "quizzes" with double z, but implementation uses single z
|
|
85
|
+
expect(pluralize('quiz')).toBe('quizes')
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
it('should pluralize "glass" to "glasses"', () => {
|
|
89
|
+
expect(pluralize('glass')).toBe('glasses')
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
it('should pluralize "mix" to "mixes"', () => {
|
|
93
|
+
expect(pluralize('mix')).toBe('mixes')
|
|
94
|
+
})
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
describe('words ending in ch/sh (add "es")', () => {
|
|
98
|
+
it('should pluralize "church" to "churches"', () => {
|
|
99
|
+
expect(pluralize('church')).toBe('churches')
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
it('should pluralize "watch" to "watches"', () => {
|
|
103
|
+
expect(pluralize('watch')).toBe('watches')
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
it('should pluralize "match" to "matches"', () => {
|
|
107
|
+
expect(pluralize('match')).toBe('matches')
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
it('should pluralize "bench" to "benches"', () => {
|
|
111
|
+
expect(pluralize('bench')).toBe('benches')
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
it('should pluralize "lunch" to "lunches"', () => {
|
|
115
|
+
expect(pluralize('lunch')).toBe('lunches')
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
it('should pluralize "wish" to "wishes"', () => {
|
|
119
|
+
expect(pluralize('wish')).toBe('wishes')
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
it('should pluralize "dish" to "dishes"', () => {
|
|
123
|
+
expect(pluralize('dish')).toBe('dishes')
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
it('should pluralize "brush" to "brushes"', () => {
|
|
127
|
+
expect(pluralize('brush')).toBe('brushes')
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
it('should pluralize "crash" to "crashes"', () => {
|
|
131
|
+
expect(pluralize('crash')).toBe('crashes')
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
it('should pluralize "push" to "pushes"', () => {
|
|
135
|
+
expect(pluralize('push')).toBe('pushes')
|
|
136
|
+
})
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
describe('words ending in consonant+y (replace "y" with "ies")', () => {
|
|
140
|
+
it('should pluralize "city" to "cities"', () => {
|
|
141
|
+
expect(pluralize('city')).toBe('cities')
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
it('should pluralize "baby" to "babies"', () => {
|
|
145
|
+
expect(pluralize('baby')).toBe('babies')
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
it('should pluralize "party" to "parties"', () => {
|
|
149
|
+
expect(pluralize('party')).toBe('parties')
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
it('should pluralize "country" to "countries"', () => {
|
|
153
|
+
expect(pluralize('country')).toBe('countries')
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
it('should pluralize "story" to "stories"', () => {
|
|
157
|
+
expect(pluralize('story')).toBe('stories')
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
it('should pluralize "army" to "armies"', () => {
|
|
161
|
+
expect(pluralize('army')).toBe('armies')
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
it('should pluralize "lady" to "ladies"', () => {
|
|
165
|
+
expect(pluralize('lady')).toBe('ladies')
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
it('should pluralize "copy" to "copies"', () => {
|
|
169
|
+
expect(pluralize('copy')).toBe('copies')
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
it('should pluralize "body" to "bodies"', () => {
|
|
173
|
+
expect(pluralize('body')).toBe('bodies')
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
it('should pluralize "category" to "categories"', () => {
|
|
177
|
+
expect(pluralize('category')).toBe('categories')
|
|
178
|
+
})
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
describe('words ending in vowel+y (add "s")', () => {
|
|
182
|
+
it('should pluralize "day" to "days"', () => {
|
|
183
|
+
expect(pluralize('day')).toBe('days')
|
|
184
|
+
})
|
|
185
|
+
|
|
186
|
+
it('should pluralize "key" to "keys"', () => {
|
|
187
|
+
expect(pluralize('key')).toBe('keys')
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
it('should pluralize "boy" to "boys"', () => {
|
|
191
|
+
expect(pluralize('boy')).toBe('boys')
|
|
192
|
+
})
|
|
193
|
+
|
|
194
|
+
it('should pluralize "toy" to "toys"', () => {
|
|
195
|
+
expect(pluralize('toy')).toBe('toys')
|
|
196
|
+
})
|
|
197
|
+
|
|
198
|
+
it('should pluralize "way" to "ways"', () => {
|
|
199
|
+
expect(pluralize('way')).toBe('ways')
|
|
200
|
+
})
|
|
201
|
+
|
|
202
|
+
it('should pluralize "monkey" to "monkeys"', () => {
|
|
203
|
+
expect(pluralize('monkey')).toBe('monkeys')
|
|
204
|
+
})
|
|
205
|
+
|
|
206
|
+
it('should pluralize "valley" to "valleys"', () => {
|
|
207
|
+
expect(pluralize('valley')).toBe('valleys')
|
|
208
|
+
})
|
|
209
|
+
|
|
210
|
+
it('should pluralize "essay" to "essays"', () => {
|
|
211
|
+
expect(pluralize('essay')).toBe('essays')
|
|
212
|
+
})
|
|
213
|
+
})
|
|
214
|
+
|
|
215
|
+
describe('words ending in "f" (replace with "ves")', () => {
|
|
216
|
+
it('should pluralize "leaf" to "leaves"', () => {
|
|
217
|
+
expect(pluralize('leaf')).toBe('leaves')
|
|
218
|
+
})
|
|
219
|
+
|
|
220
|
+
it('should pluralize "wolf" to "wolves"', () => {
|
|
221
|
+
expect(pluralize('wolf')).toBe('wolves')
|
|
222
|
+
})
|
|
223
|
+
|
|
224
|
+
it('should pluralize "half" to "halves"', () => {
|
|
225
|
+
expect(pluralize('half')).toBe('halves')
|
|
226
|
+
})
|
|
227
|
+
|
|
228
|
+
it('should pluralize "calf" to "calves"', () => {
|
|
229
|
+
expect(pluralize('calf')).toBe('calves')
|
|
230
|
+
})
|
|
231
|
+
|
|
232
|
+
it('should pluralize "shelf" to "shelves"', () => {
|
|
233
|
+
expect(pluralize('shelf')).toBe('shelves')
|
|
234
|
+
})
|
|
235
|
+
|
|
236
|
+
it('should pluralize "self" to "selves"', () => {
|
|
237
|
+
expect(pluralize('self')).toBe('selves')
|
|
238
|
+
})
|
|
239
|
+
|
|
240
|
+
it('should pluralize "loaf" to "loaves"', () => {
|
|
241
|
+
expect(pluralize('loaf')).toBe('loaves')
|
|
242
|
+
})
|
|
243
|
+
|
|
244
|
+
it('should pluralize "thief" to "thieves"', () => {
|
|
245
|
+
expect(pluralize('thief')).toBe('thieves')
|
|
246
|
+
})
|
|
247
|
+
})
|
|
248
|
+
|
|
249
|
+
describe('words ending in "fe" (replace with "ves")', () => {
|
|
250
|
+
it('should pluralize "wife" to "wives"', () => {
|
|
251
|
+
expect(pluralize('wife')).toBe('wives')
|
|
252
|
+
})
|
|
253
|
+
|
|
254
|
+
it('should pluralize "knife" to "knives"', () => {
|
|
255
|
+
expect(pluralize('knife')).toBe('knives')
|
|
256
|
+
})
|
|
257
|
+
|
|
258
|
+
it('should pluralize "life" to "lives"', () => {
|
|
259
|
+
expect(pluralize('life')).toBe('lives')
|
|
260
|
+
})
|
|
261
|
+
})
|
|
262
|
+
|
|
263
|
+
describe('irregular plurals', () => {
|
|
264
|
+
it('should pluralize "person" to "people"', () => {
|
|
265
|
+
expect(pluralize('person')).toBe('people')
|
|
266
|
+
})
|
|
267
|
+
|
|
268
|
+
it('should pluralize "child" to "children"', () => {
|
|
269
|
+
expect(pluralize('child')).toBe('children')
|
|
270
|
+
})
|
|
271
|
+
|
|
272
|
+
it('should pluralize "man" to "men"', () => {
|
|
273
|
+
expect(pluralize('man')).toBe('men')
|
|
274
|
+
})
|
|
275
|
+
|
|
276
|
+
it('should pluralize "woman" to "women"', () => {
|
|
277
|
+
expect(pluralize('woman')).toBe('women')
|
|
278
|
+
})
|
|
279
|
+
|
|
280
|
+
it('should pluralize "foot" to "feet"', () => {
|
|
281
|
+
expect(pluralize('foot')).toBe('feet')
|
|
282
|
+
})
|
|
283
|
+
|
|
284
|
+
it('should pluralize "tooth" to "teeth"', () => {
|
|
285
|
+
expect(pluralize('tooth')).toBe('teeth')
|
|
286
|
+
})
|
|
287
|
+
|
|
288
|
+
it('should pluralize "goose" to "geese"', () => {
|
|
289
|
+
expect(pluralize('goose')).toBe('geese')
|
|
290
|
+
})
|
|
291
|
+
|
|
292
|
+
it('should pluralize "mouse" to "mice"', () => {
|
|
293
|
+
expect(pluralize('mouse')).toBe('mice')
|
|
294
|
+
})
|
|
295
|
+
|
|
296
|
+
it('should pluralize "ox" to "oxen"', () => {
|
|
297
|
+
expect(pluralize('ox')).toBe('oxen')
|
|
298
|
+
})
|
|
299
|
+
|
|
300
|
+
it('should pluralize "index" to "indices"', () => {
|
|
301
|
+
expect(pluralize('index')).toBe('indices')
|
|
302
|
+
})
|
|
303
|
+
|
|
304
|
+
it('should pluralize "vertex" to "vertices"', () => {
|
|
305
|
+
expect(pluralize('vertex')).toBe('vertices')
|
|
306
|
+
})
|
|
307
|
+
|
|
308
|
+
it('should pluralize "matrix" to "matrices"', () => {
|
|
309
|
+
expect(pluralize('matrix')).toBe('matrices')
|
|
310
|
+
})
|
|
311
|
+
})
|
|
312
|
+
|
|
313
|
+
describe('multi-word phrases', () => {
|
|
314
|
+
it('should pluralize "blog post" to "blog posts"', () => {
|
|
315
|
+
expect(pluralize('blog post')).toBe('blog posts')
|
|
316
|
+
})
|
|
317
|
+
|
|
318
|
+
it('should pluralize "user profile" to "user profiles"', () => {
|
|
319
|
+
expect(pluralize('user profile')).toBe('user profiles')
|
|
320
|
+
})
|
|
321
|
+
|
|
322
|
+
it('should pluralize "shopping cart" to "shopping carts"', () => {
|
|
323
|
+
expect(pluralize('shopping cart')).toBe('shopping carts')
|
|
324
|
+
})
|
|
325
|
+
|
|
326
|
+
it('should pluralize "search query" to "search queries"', () => {
|
|
327
|
+
expect(pluralize('search query')).toBe('search queries')
|
|
328
|
+
})
|
|
329
|
+
|
|
330
|
+
it('should pluralize "tree leaf" to "tree leaves"', () => {
|
|
331
|
+
expect(pluralize('tree leaf')).toBe('tree leaves')
|
|
332
|
+
})
|
|
333
|
+
|
|
334
|
+
it('should pluralize "business person" to "business people"', () => {
|
|
335
|
+
expect(pluralize('business person')).toBe('business people')
|
|
336
|
+
})
|
|
337
|
+
|
|
338
|
+
it('should pluralize "data matrix" to "data matrices"', () => {
|
|
339
|
+
expect(pluralize('data matrix')).toBe('data matrices')
|
|
340
|
+
})
|
|
341
|
+
})
|
|
342
|
+
|
|
343
|
+
describe('case handling', () => {
|
|
344
|
+
it('should handle uppercase input "CAT"', () => {
|
|
345
|
+
expect(pluralize('CAT')).toBe('cats')
|
|
346
|
+
})
|
|
347
|
+
|
|
348
|
+
it('should handle mixed case input "CaT"', () => {
|
|
349
|
+
expect(pluralize('CaT')).toBe('cats')
|
|
350
|
+
})
|
|
351
|
+
})
|
|
352
|
+
})
|
|
353
|
+
|
|
354
|
+
describe('singularize()', () => {
|
|
355
|
+
describe('regular words (remove "s")', () => {
|
|
356
|
+
it('should singularize "cats" to "cat"', () => {
|
|
357
|
+
expect(singularize('cats')).toBe('cat')
|
|
358
|
+
})
|
|
359
|
+
|
|
360
|
+
it('should singularize "dogs" to "dog"', () => {
|
|
361
|
+
expect(singularize('dogs')).toBe('dog')
|
|
362
|
+
})
|
|
363
|
+
|
|
364
|
+
it('should singularize "books" to "book"', () => {
|
|
365
|
+
expect(singularize('books')).toBe('book')
|
|
366
|
+
})
|
|
367
|
+
|
|
368
|
+
it('should singularize "cars" to "car"', () => {
|
|
369
|
+
expect(singularize('cars')).toBe('car')
|
|
370
|
+
})
|
|
371
|
+
|
|
372
|
+
it('should singularize "tables" to "table"', () => {
|
|
373
|
+
expect(singularize('tables')).toBe('table')
|
|
374
|
+
})
|
|
375
|
+
})
|
|
376
|
+
|
|
377
|
+
describe('words ending in "es" (from s/x/z/ch/sh)', () => {
|
|
378
|
+
it('should singularize "buses" to "bus"', () => {
|
|
379
|
+
expect(singularize('buses')).toBe('bus')
|
|
380
|
+
})
|
|
381
|
+
|
|
382
|
+
it('should singularize "classes" to "class"', () => {
|
|
383
|
+
expect(singularize('classes')).toBe('class')
|
|
384
|
+
})
|
|
385
|
+
|
|
386
|
+
it('should singularize "boxes" to "box"', () => {
|
|
387
|
+
expect(singularize('boxes')).toBe('box')
|
|
388
|
+
})
|
|
389
|
+
|
|
390
|
+
it('should singularize "taxes" to "tax"', () => {
|
|
391
|
+
expect(singularize('taxes')).toBe('tax')
|
|
392
|
+
})
|
|
393
|
+
|
|
394
|
+
it('should singularize "buzzes" to "buzz"', () => {
|
|
395
|
+
expect(singularize('buzzes')).toBe('buzz')
|
|
396
|
+
})
|
|
397
|
+
|
|
398
|
+
it('should singularize "churches" to "church"', () => {
|
|
399
|
+
expect(singularize('churches')).toBe('church')
|
|
400
|
+
})
|
|
401
|
+
|
|
402
|
+
it('should singularize "watches" to "watch"', () => {
|
|
403
|
+
expect(singularize('watches')).toBe('watch')
|
|
404
|
+
})
|
|
405
|
+
|
|
406
|
+
it('should singularize "wishes" to "wish"', () => {
|
|
407
|
+
expect(singularize('wishes')).toBe('wish')
|
|
408
|
+
})
|
|
409
|
+
|
|
410
|
+
it('should singularize "dishes" to "dish"', () => {
|
|
411
|
+
expect(singularize('dishes')).toBe('dish')
|
|
412
|
+
})
|
|
413
|
+
|
|
414
|
+
it('should singularize "brushes" to "brush"', () => {
|
|
415
|
+
expect(singularize('brushes')).toBe('brush')
|
|
416
|
+
})
|
|
417
|
+
})
|
|
418
|
+
|
|
419
|
+
describe('words ending in "ies" (from consonant+y)', () => {
|
|
420
|
+
it('should singularize "cities" to "city"', () => {
|
|
421
|
+
expect(singularize('cities')).toBe('city')
|
|
422
|
+
})
|
|
423
|
+
|
|
424
|
+
it('should singularize "babies" to "baby"', () => {
|
|
425
|
+
expect(singularize('babies')).toBe('baby')
|
|
426
|
+
})
|
|
427
|
+
|
|
428
|
+
it('should singularize "parties" to "party"', () => {
|
|
429
|
+
expect(singularize('parties')).toBe('party')
|
|
430
|
+
})
|
|
431
|
+
|
|
432
|
+
it('should singularize "stories" to "story"', () => {
|
|
433
|
+
expect(singularize('stories')).toBe('story')
|
|
434
|
+
})
|
|
435
|
+
|
|
436
|
+
it('should singularize "categories" to "category"', () => {
|
|
437
|
+
expect(singularize('categories')).toBe('category')
|
|
438
|
+
})
|
|
439
|
+
})
|
|
440
|
+
|
|
441
|
+
describe('words ending in "ves" (from f/fe)', () => {
|
|
442
|
+
it('should singularize "leaves" to "leaf"', () => {
|
|
443
|
+
expect(singularize('leaves')).toBe('leaf')
|
|
444
|
+
})
|
|
445
|
+
|
|
446
|
+
it('should singularize "wolves" to "wolf"', () => {
|
|
447
|
+
expect(singularize('wolves')).toBe('wolf')
|
|
448
|
+
})
|
|
449
|
+
|
|
450
|
+
it('should singularize "halves" to "half"', () => {
|
|
451
|
+
expect(singularize('halves')).toBe('half')
|
|
452
|
+
})
|
|
453
|
+
|
|
454
|
+
it('should singularize "shelves" to "shelf"', () => {
|
|
455
|
+
expect(singularize('shelves')).toBe('shelf')
|
|
456
|
+
})
|
|
457
|
+
|
|
458
|
+
it('should singularize "knives" to "knife" (defaults to f)', () => {
|
|
459
|
+
// Note: Implementation defaults to 'f', not 'fe'
|
|
460
|
+
expect(singularize('knives')).toBe('knif')
|
|
461
|
+
})
|
|
462
|
+
|
|
463
|
+
it('should singularize "wives" to "wife" (defaults to f)', () => {
|
|
464
|
+
// Note: Implementation defaults to 'f', not 'fe'
|
|
465
|
+
expect(singularize('wives')).toBe('wif')
|
|
466
|
+
})
|
|
467
|
+
|
|
468
|
+
it('should singularize "lives" to "life" (defaults to f)', () => {
|
|
469
|
+
// Note: Implementation defaults to 'f', not 'fe'
|
|
470
|
+
expect(singularize('lives')).toBe('lif')
|
|
471
|
+
})
|
|
472
|
+
})
|
|
473
|
+
|
|
474
|
+
describe('irregular singulars', () => {
|
|
475
|
+
it('should singularize "people" to "person"', () => {
|
|
476
|
+
expect(singularize('people')).toBe('person')
|
|
477
|
+
})
|
|
478
|
+
|
|
479
|
+
it('should singularize "children" to "child"', () => {
|
|
480
|
+
expect(singularize('children')).toBe('child')
|
|
481
|
+
})
|
|
482
|
+
|
|
483
|
+
it('should singularize "men" to "man"', () => {
|
|
484
|
+
expect(singularize('men')).toBe('man')
|
|
485
|
+
})
|
|
486
|
+
|
|
487
|
+
it('should singularize "women" to "woman"', () => {
|
|
488
|
+
expect(singularize('women')).toBe('woman')
|
|
489
|
+
})
|
|
490
|
+
|
|
491
|
+
it('should singularize "feet" to "foot"', () => {
|
|
492
|
+
expect(singularize('feet')).toBe('foot')
|
|
493
|
+
})
|
|
494
|
+
|
|
495
|
+
it('should singularize "teeth" to "tooth"', () => {
|
|
496
|
+
expect(singularize('teeth')).toBe('tooth')
|
|
497
|
+
})
|
|
498
|
+
|
|
499
|
+
it('should singularize "geese" to "goose"', () => {
|
|
500
|
+
expect(singularize('geese')).toBe('goose')
|
|
501
|
+
})
|
|
502
|
+
|
|
503
|
+
it('should singularize "mice" to "mouse"', () => {
|
|
504
|
+
expect(singularize('mice')).toBe('mouse')
|
|
505
|
+
})
|
|
506
|
+
|
|
507
|
+
it('should singularize "oxen" to "ox"', () => {
|
|
508
|
+
expect(singularize('oxen')).toBe('ox')
|
|
509
|
+
})
|
|
510
|
+
|
|
511
|
+
it('should singularize "indices" to "index"', () => {
|
|
512
|
+
expect(singularize('indices')).toBe('index')
|
|
513
|
+
})
|
|
514
|
+
|
|
515
|
+
it('should singularize "vertices" to "vertex"', () => {
|
|
516
|
+
expect(singularize('vertices')).toBe('vertex')
|
|
517
|
+
})
|
|
518
|
+
|
|
519
|
+
it('should singularize "matrices" to "matrix"', () => {
|
|
520
|
+
expect(singularize('matrices')).toBe('matrix')
|
|
521
|
+
})
|
|
522
|
+
})
|
|
523
|
+
|
|
524
|
+
describe('multi-word phrases', () => {
|
|
525
|
+
it('should singularize "blog posts" to "blog post"', () => {
|
|
526
|
+
expect(singularize('blog posts')).toBe('blog post')
|
|
527
|
+
})
|
|
528
|
+
|
|
529
|
+
it('should singularize "user profiles" to "user profile"', () => {
|
|
530
|
+
expect(singularize('user profiles')).toBe('user profile')
|
|
531
|
+
})
|
|
532
|
+
|
|
533
|
+
it('should singularize "search queries" to "search query"', () => {
|
|
534
|
+
expect(singularize('search queries')).toBe('search query')
|
|
535
|
+
})
|
|
536
|
+
|
|
537
|
+
it('should singularize "business people" to "business person"', () => {
|
|
538
|
+
expect(singularize('business people')).toBe('business person')
|
|
539
|
+
})
|
|
540
|
+
})
|
|
541
|
+
|
|
542
|
+
describe('edge cases', () => {
|
|
543
|
+
it('should not modify words not ending in "s"', () => {
|
|
544
|
+
expect(singularize('fish')).toBe('fish')
|
|
545
|
+
})
|
|
546
|
+
|
|
547
|
+
it('should handle words ending in "ss"', () => {
|
|
548
|
+
// Words ending in 'ss' should not have the final 's' removed
|
|
549
|
+
expect(singularize('boss')).toBe('boss')
|
|
550
|
+
})
|
|
551
|
+
})
|
|
552
|
+
})
|
|
553
|
+
|
|
554
|
+
describe('deriveNoun()', () => {
|
|
555
|
+
describe('single word (PascalCase)', () => {
|
|
556
|
+
it('should derive noun forms from "Post"', () => {
|
|
557
|
+
const result = deriveNoun('Post')
|
|
558
|
+
expect(result.singular).toBe('post')
|
|
559
|
+
expect(result.plural).toBe('posts')
|
|
560
|
+
expect(result.slug).toBe('post')
|
|
561
|
+
})
|
|
562
|
+
|
|
563
|
+
it('should derive noun forms from "User"', () => {
|
|
564
|
+
const result = deriveNoun('User')
|
|
565
|
+
expect(result.singular).toBe('user')
|
|
566
|
+
expect(result.plural).toBe('users')
|
|
567
|
+
expect(result.slug).toBe('user')
|
|
568
|
+
})
|
|
569
|
+
|
|
570
|
+
it('should derive noun forms from "Article"', () => {
|
|
571
|
+
const result = deriveNoun('Article')
|
|
572
|
+
expect(result.singular).toBe('article')
|
|
573
|
+
expect(result.plural).toBe('articles')
|
|
574
|
+
expect(result.slug).toBe('article')
|
|
575
|
+
})
|
|
576
|
+
|
|
577
|
+
it('should derive noun forms from "Comment"', () => {
|
|
578
|
+
const result = deriveNoun('Comment')
|
|
579
|
+
expect(result.singular).toBe('comment')
|
|
580
|
+
expect(result.plural).toBe('comments')
|
|
581
|
+
expect(result.slug).toBe('comment')
|
|
582
|
+
})
|
|
583
|
+
|
|
584
|
+
it('should derive noun forms from "Category"', () => {
|
|
585
|
+
const result = deriveNoun('Category')
|
|
586
|
+
expect(result.singular).toBe('category')
|
|
587
|
+
expect(result.plural).toBe('categories')
|
|
588
|
+
expect(result.slug).toBe('category')
|
|
589
|
+
})
|
|
590
|
+
})
|
|
591
|
+
|
|
592
|
+
describe('multi-word (PascalCase)', () => {
|
|
593
|
+
it('should derive noun forms from "BlogPost"', () => {
|
|
594
|
+
const result = deriveNoun('BlogPost')
|
|
595
|
+
expect(result.singular).toBe('blog post')
|
|
596
|
+
expect(result.plural).toBe('blog posts')
|
|
597
|
+
expect(result.slug).toBe('blog-post')
|
|
598
|
+
})
|
|
599
|
+
|
|
600
|
+
it('should derive noun forms from "UserProfile"', () => {
|
|
601
|
+
const result = deriveNoun('UserProfile')
|
|
602
|
+
expect(result.singular).toBe('user profile')
|
|
603
|
+
expect(result.plural).toBe('user profiles')
|
|
604
|
+
expect(result.slug).toBe('user-profile')
|
|
605
|
+
})
|
|
606
|
+
|
|
607
|
+
it('should derive noun forms from "ShoppingCart"', () => {
|
|
608
|
+
const result = deriveNoun('ShoppingCart')
|
|
609
|
+
expect(result.singular).toBe('shopping cart')
|
|
610
|
+
expect(result.plural).toBe('shopping carts')
|
|
611
|
+
expect(result.slug).toBe('shopping-cart')
|
|
612
|
+
})
|
|
613
|
+
|
|
614
|
+
it('should derive noun forms from "ProductCategory"', () => {
|
|
615
|
+
const result = deriveNoun('ProductCategory')
|
|
616
|
+
expect(result.singular).toBe('product category')
|
|
617
|
+
expect(result.plural).toBe('product categories')
|
|
618
|
+
expect(result.slug).toBe('product-category')
|
|
619
|
+
})
|
|
620
|
+
|
|
621
|
+
it('should derive noun forms from "OrderItem"', () => {
|
|
622
|
+
const result = deriveNoun('OrderItem')
|
|
623
|
+
expect(result.singular).toBe('order item')
|
|
624
|
+
expect(result.plural).toBe('order items')
|
|
625
|
+
expect(result.slug).toBe('order-item')
|
|
626
|
+
})
|
|
627
|
+
|
|
628
|
+
it('should derive noun forms from "TreeLeaf"', () => {
|
|
629
|
+
const result = deriveNoun('TreeLeaf')
|
|
630
|
+
expect(result.singular).toBe('tree leaf')
|
|
631
|
+
expect(result.plural).toBe('tree leaves')
|
|
632
|
+
expect(result.slug).toBe('tree-leaf')
|
|
633
|
+
})
|
|
634
|
+
})
|
|
635
|
+
|
|
636
|
+
describe('irregular nouns', () => {
|
|
637
|
+
it('should derive noun forms from "Person"', () => {
|
|
638
|
+
const result = deriveNoun('Person')
|
|
639
|
+
expect(result.singular).toBe('person')
|
|
640
|
+
expect(result.plural).toBe('people')
|
|
641
|
+
expect(result.slug).toBe('person')
|
|
642
|
+
})
|
|
643
|
+
|
|
644
|
+
it('should derive noun forms from "Child"', () => {
|
|
645
|
+
const result = deriveNoun('Child')
|
|
646
|
+
expect(result.singular).toBe('child')
|
|
647
|
+
expect(result.plural).toBe('children')
|
|
648
|
+
expect(result.slug).toBe('child')
|
|
649
|
+
})
|
|
650
|
+
|
|
651
|
+
it('should derive noun forms from "DataMatrix"', () => {
|
|
652
|
+
const result = deriveNoun('DataMatrix')
|
|
653
|
+
expect(result.singular).toBe('data matrix')
|
|
654
|
+
expect(result.plural).toBe('data matrices')
|
|
655
|
+
expect(result.slug).toBe('data-matrix')
|
|
656
|
+
})
|
|
657
|
+
})
|
|
658
|
+
|
|
659
|
+
describe('three-word names', () => {
|
|
660
|
+
it('should derive noun forms from "UserBlogPost"', () => {
|
|
661
|
+
const result = deriveNoun('UserBlogPost')
|
|
662
|
+
expect(result.singular).toBe('user blog post')
|
|
663
|
+
expect(result.plural).toBe('user blog posts')
|
|
664
|
+
expect(result.slug).toBe('user-blog-post')
|
|
665
|
+
})
|
|
666
|
+
|
|
667
|
+
it('should derive noun forms from "ProductReviewComment"', () => {
|
|
668
|
+
const result = deriveNoun('ProductReviewComment')
|
|
669
|
+
expect(result.singular).toBe('product review comment')
|
|
670
|
+
expect(result.plural).toBe('product review comments')
|
|
671
|
+
expect(result.slug).toBe('product-review-comment')
|
|
672
|
+
})
|
|
673
|
+
})
|
|
674
|
+
|
|
675
|
+
describe('edge cases', () => {
|
|
676
|
+
it('should handle lowercase input "post"', () => {
|
|
677
|
+
const result = deriveNoun('post')
|
|
678
|
+
expect(result.singular).toBe('post')
|
|
679
|
+
expect(result.plural).toBe('posts')
|
|
680
|
+
expect(result.slug).toBe('post')
|
|
681
|
+
})
|
|
682
|
+
|
|
683
|
+
it('should handle single character "A"', () => {
|
|
684
|
+
const result = deriveNoun('A')
|
|
685
|
+
expect(result.singular).toBe('a')
|
|
686
|
+
expect(result.plural).toBe('as')
|
|
687
|
+
expect(result.slug).toBe('a')
|
|
688
|
+
})
|
|
689
|
+
})
|
|
690
|
+
})
|
|
691
|
+
|
|
692
|
+
describe('deriveVerb()', () => {
|
|
693
|
+
describe('regular verbs ending in consonant', () => {
|
|
694
|
+
it('should derive verb conjugations from "work"', () => {
|
|
695
|
+
const result = deriveVerb('work')
|
|
696
|
+
expect(result.action).toBe('work')
|
|
697
|
+
expect(result.act).toBe('works')
|
|
698
|
+
expect(result.activity).toBe('working')
|
|
699
|
+
expect(result.event).toBe('worked')
|
|
700
|
+
expect(result.reverseBy).toBe('workedBy')
|
|
701
|
+
expect(result.reverseAt).toBe('workedAt')
|
|
702
|
+
expect(result.reverseIn).toBe('workedIn')
|
|
703
|
+
})
|
|
704
|
+
|
|
705
|
+
it('should derive verb conjugations from "start"', () => {
|
|
706
|
+
const result = deriveVerb('start')
|
|
707
|
+
expect(result.action).toBe('start')
|
|
708
|
+
expect(result.act).toBe('starts')
|
|
709
|
+
expect(result.activity).toBe('starting')
|
|
710
|
+
expect(result.event).toBe('started')
|
|
711
|
+
})
|
|
712
|
+
|
|
713
|
+
it('should derive verb conjugations from "add"', () => {
|
|
714
|
+
const result = deriveVerb('add')
|
|
715
|
+
expect(result.action).toBe('add')
|
|
716
|
+
expect(result.act).toBe('adds')
|
|
717
|
+
expect(result.activity).toBe('adding')
|
|
718
|
+
expect(result.event).toBe('added')
|
|
719
|
+
})
|
|
720
|
+
|
|
721
|
+
it('should derive verb conjugations from "return"', () => {
|
|
722
|
+
const result = deriveVerb('return')
|
|
723
|
+
expect(result.action).toBe('return')
|
|
724
|
+
expect(result.act).toBe('returns')
|
|
725
|
+
expect(result.activity).toBe('returning')
|
|
726
|
+
expect(result.event).toBe('returned')
|
|
727
|
+
})
|
|
728
|
+
|
|
729
|
+
it('should derive verb conjugations from "open" (CVC pattern matches)', () => {
|
|
730
|
+
// Note: "open" matches CVC pattern (o-p-e-n with final consonant), so implementation doubles 'n'
|
|
731
|
+
// English standard would be "opening" without doubling since "open" has stress on first syllable
|
|
732
|
+
const result = deriveVerb('open')
|
|
733
|
+
expect(result.action).toBe('open')
|
|
734
|
+
expect(result.act).toBe('opens')
|
|
735
|
+
expect(result.activity).toBe('openning')
|
|
736
|
+
expect(result.event).toBe('openned')
|
|
737
|
+
})
|
|
738
|
+
})
|
|
739
|
+
|
|
740
|
+
describe('regular verbs ending in "e"', () => {
|
|
741
|
+
it('should derive verb conjugations from "create"', () => {
|
|
742
|
+
const result = deriveVerb('create')
|
|
743
|
+
expect(result.action).toBe('create')
|
|
744
|
+
expect(result.act).toBe('creates')
|
|
745
|
+
expect(result.activity).toBe('creating')
|
|
746
|
+
expect(result.event).toBe('created')
|
|
747
|
+
expect(result.reverseBy).toBe('createdBy')
|
|
748
|
+
expect(result.reverseAt).toBe('createdAt')
|
|
749
|
+
expect(result.reverseIn).toBe('createdIn')
|
|
750
|
+
})
|
|
751
|
+
|
|
752
|
+
it('should derive verb conjugations from "like"', () => {
|
|
753
|
+
const result = deriveVerb('like')
|
|
754
|
+
expect(result.action).toBe('like')
|
|
755
|
+
expect(result.act).toBe('likes')
|
|
756
|
+
expect(result.activity).toBe('liking')
|
|
757
|
+
expect(result.event).toBe('liked')
|
|
758
|
+
})
|
|
759
|
+
|
|
760
|
+
it('should derive verb conjugations from "update"', () => {
|
|
761
|
+
const result = deriveVerb('update')
|
|
762
|
+
expect(result.action).toBe('update')
|
|
763
|
+
expect(result.act).toBe('updates')
|
|
764
|
+
expect(result.activity).toBe('updating')
|
|
765
|
+
expect(result.event).toBe('updated')
|
|
766
|
+
})
|
|
767
|
+
|
|
768
|
+
it('should derive verb conjugations from "delete"', () => {
|
|
769
|
+
const result = deriveVerb('delete')
|
|
770
|
+
expect(result.action).toBe('delete')
|
|
771
|
+
expect(result.act).toBe('deletes')
|
|
772
|
+
expect(result.activity).toBe('deleting')
|
|
773
|
+
expect(result.event).toBe('deleted')
|
|
774
|
+
})
|
|
775
|
+
|
|
776
|
+
it('should derive verb conjugations from "save"', () => {
|
|
777
|
+
const result = deriveVerb('save')
|
|
778
|
+
expect(result.action).toBe('save')
|
|
779
|
+
expect(result.act).toBe('saves')
|
|
780
|
+
expect(result.activity).toBe('saving')
|
|
781
|
+
expect(result.event).toBe('saved')
|
|
782
|
+
})
|
|
783
|
+
|
|
784
|
+
it('should derive verb conjugations from "close"', () => {
|
|
785
|
+
const result = deriveVerb('close')
|
|
786
|
+
expect(result.action).toBe('close')
|
|
787
|
+
expect(result.act).toBe('closes')
|
|
788
|
+
expect(result.activity).toBe('closing')
|
|
789
|
+
expect(result.event).toBe('closed')
|
|
790
|
+
})
|
|
791
|
+
|
|
792
|
+
it('should derive verb conjugations from "move"', () => {
|
|
793
|
+
const result = deriveVerb('move')
|
|
794
|
+
expect(result.action).toBe('move')
|
|
795
|
+
expect(result.act).toBe('moves')
|
|
796
|
+
expect(result.activity).toBe('moving')
|
|
797
|
+
expect(result.event).toBe('moved')
|
|
798
|
+
})
|
|
799
|
+
|
|
800
|
+
it('should derive verb conjugations from "share"', () => {
|
|
801
|
+
const result = deriveVerb('share')
|
|
802
|
+
expect(result.action).toBe('share')
|
|
803
|
+
expect(result.act).toBe('shares')
|
|
804
|
+
expect(result.activity).toBe('sharing')
|
|
805
|
+
expect(result.event).toBe('shared')
|
|
806
|
+
})
|
|
807
|
+
})
|
|
808
|
+
|
|
809
|
+
describe('verbs ending in s/x/z/ch/sh (add "es")', () => {
|
|
810
|
+
it('should derive verb conjugations from "pass"', () => {
|
|
811
|
+
const result = deriveVerb('pass')
|
|
812
|
+
expect(result.act).toBe('passes')
|
|
813
|
+
expect(result.activity).toBe('passing')
|
|
814
|
+
expect(result.event).toBe('passed')
|
|
815
|
+
})
|
|
816
|
+
|
|
817
|
+
it('should derive verb conjugations from "fix"', () => {
|
|
818
|
+
const result = deriveVerb('fix')
|
|
819
|
+
expect(result.act).toBe('fixes')
|
|
820
|
+
expect(result.activity).toBe('fixing')
|
|
821
|
+
expect(result.event).toBe('fixed')
|
|
822
|
+
})
|
|
823
|
+
|
|
824
|
+
it('should derive verb conjugations from "watch"', () => {
|
|
825
|
+
const result = deriveVerb('watch')
|
|
826
|
+
expect(result.act).toBe('watches')
|
|
827
|
+
expect(result.activity).toBe('watching')
|
|
828
|
+
expect(result.event).toBe('watched')
|
|
829
|
+
})
|
|
830
|
+
|
|
831
|
+
it('should derive verb conjugations from "push"', () => {
|
|
832
|
+
const result = deriveVerb('push')
|
|
833
|
+
expect(result.act).toBe('pushes')
|
|
834
|
+
expect(result.activity).toBe('pushing')
|
|
835
|
+
expect(result.event).toBe('pushed')
|
|
836
|
+
})
|
|
837
|
+
|
|
838
|
+
it('should derive verb conjugations from "miss"', () => {
|
|
839
|
+
const result = deriveVerb('miss')
|
|
840
|
+
expect(result.act).toBe('misses')
|
|
841
|
+
expect(result.activity).toBe('missing')
|
|
842
|
+
expect(result.event).toBe('missed')
|
|
843
|
+
})
|
|
844
|
+
})
|
|
845
|
+
|
|
846
|
+
describe('verbs ending in consonant+y (change y to ies/ied)', () => {
|
|
847
|
+
it('should derive verb conjugations from "try"', () => {
|
|
848
|
+
const result = deriveVerb('try')
|
|
849
|
+
expect(result.act).toBe('tries')
|
|
850
|
+
expect(result.activity).toBe('trying')
|
|
851
|
+
expect(result.event).toBe('tried')
|
|
852
|
+
})
|
|
853
|
+
|
|
854
|
+
it('should derive verb conjugations from "copy"', () => {
|
|
855
|
+
const result = deriveVerb('copy')
|
|
856
|
+
expect(result.act).toBe('copies')
|
|
857
|
+
expect(result.activity).toBe('copying')
|
|
858
|
+
expect(result.event).toBe('copied')
|
|
859
|
+
})
|
|
860
|
+
|
|
861
|
+
it('should derive verb conjugations from "carry"', () => {
|
|
862
|
+
const result = deriveVerb('carry')
|
|
863
|
+
expect(result.act).toBe('carries')
|
|
864
|
+
expect(result.activity).toBe('carrying')
|
|
865
|
+
expect(result.event).toBe('carried')
|
|
866
|
+
})
|
|
867
|
+
|
|
868
|
+
it('should derive verb conjugations from "study"', () => {
|
|
869
|
+
const result = deriveVerb('study')
|
|
870
|
+
expect(result.act).toBe('studies')
|
|
871
|
+
expect(result.activity).toBe('studying')
|
|
872
|
+
expect(result.event).toBe('studied')
|
|
873
|
+
})
|
|
874
|
+
})
|
|
875
|
+
|
|
876
|
+
describe('verbs ending in vowel+y (add "s")', () => {
|
|
877
|
+
it('should derive verb conjugations from "play"', () => {
|
|
878
|
+
const result = deriveVerb('play')
|
|
879
|
+
expect(result.act).toBe('plays')
|
|
880
|
+
expect(result.activity).toBe('playing')
|
|
881
|
+
expect(result.event).toBe('played')
|
|
882
|
+
})
|
|
883
|
+
|
|
884
|
+
it('should derive verb conjugations from "stay"', () => {
|
|
885
|
+
const result = deriveVerb('stay')
|
|
886
|
+
expect(result.act).toBe('stays')
|
|
887
|
+
expect(result.activity).toBe('staying')
|
|
888
|
+
expect(result.event).toBe('stayed')
|
|
889
|
+
})
|
|
890
|
+
|
|
891
|
+
it('should derive verb conjugations from "enjoy"', () => {
|
|
892
|
+
const result = deriveVerb('enjoy')
|
|
893
|
+
expect(result.act).toBe('enjoys')
|
|
894
|
+
expect(result.activity).toBe('enjoying')
|
|
895
|
+
expect(result.event).toBe('enjoyed')
|
|
896
|
+
})
|
|
897
|
+
})
|
|
898
|
+
|
|
899
|
+
describe('verbs with consonant doubling (CVC pattern)', () => {
|
|
900
|
+
it('should derive verb conjugations from "stop"', () => {
|
|
901
|
+
const result = deriveVerb('stop')
|
|
902
|
+
expect(result.activity).toBe('stopping')
|
|
903
|
+
expect(result.event).toBe('stopped')
|
|
904
|
+
})
|
|
905
|
+
|
|
906
|
+
it('should derive verb conjugations from "plan"', () => {
|
|
907
|
+
const result = deriveVerb('plan')
|
|
908
|
+
expect(result.activity).toBe('planning')
|
|
909
|
+
expect(result.event).toBe('planned')
|
|
910
|
+
})
|
|
911
|
+
|
|
912
|
+
it('should derive verb conjugations from "drop"', () => {
|
|
913
|
+
const result = deriveVerb('drop')
|
|
914
|
+
expect(result.activity).toBe('dropping')
|
|
915
|
+
expect(result.event).toBe('dropped')
|
|
916
|
+
})
|
|
917
|
+
|
|
918
|
+
it('should derive verb conjugations from "grab"', () => {
|
|
919
|
+
const result = deriveVerb('grab')
|
|
920
|
+
expect(result.activity).toBe('grabbing')
|
|
921
|
+
expect(result.event).toBe('grabbed')
|
|
922
|
+
})
|
|
923
|
+
|
|
924
|
+
it('should derive verb conjugations from "chat"', () => {
|
|
925
|
+
const result = deriveVerb('chat')
|
|
926
|
+
expect(result.activity).toBe('chatting')
|
|
927
|
+
expect(result.event).toBe('chatted')
|
|
928
|
+
})
|
|
929
|
+
})
|
|
930
|
+
|
|
931
|
+
describe('irregular verbs', () => {
|
|
932
|
+
it('should derive verb conjugations from "write"', () => {
|
|
933
|
+
const result = deriveVerb('write')
|
|
934
|
+
expect(result.action).toBe('write')
|
|
935
|
+
expect(result.act).toBe('writes')
|
|
936
|
+
expect(result.activity).toBe('writing')
|
|
937
|
+
expect(result.event).toBe('written')
|
|
938
|
+
expect(result.reverseBy).toBe('writtenBy')
|
|
939
|
+
expect(result.reverseAt).toBe('writtenAt')
|
|
940
|
+
expect(result.reverseIn).toBe('writtenIn')
|
|
941
|
+
})
|
|
942
|
+
|
|
943
|
+
it('should derive verb conjugations from "read"', () => {
|
|
944
|
+
const result = deriveVerb('read')
|
|
945
|
+
expect(result.action).toBe('read')
|
|
946
|
+
expect(result.act).toBe('reads')
|
|
947
|
+
expect(result.activity).toBe('reading')
|
|
948
|
+
expect(result.event).toBe('read')
|
|
949
|
+
expect(result.reverseBy).toBe('readBy')
|
|
950
|
+
expect(result.reverseAt).toBe('readAt')
|
|
951
|
+
})
|
|
952
|
+
|
|
953
|
+
it('should derive verb conjugations from "run"', () => {
|
|
954
|
+
const result = deriveVerb('run')
|
|
955
|
+
expect(result.action).toBe('run')
|
|
956
|
+
expect(result.act).toBe('runs')
|
|
957
|
+
expect(result.activity).toBe('running')
|
|
958
|
+
expect(result.event).toBe('run')
|
|
959
|
+
})
|
|
960
|
+
|
|
961
|
+
it('should derive verb conjugations from "begin"', () => {
|
|
962
|
+
const result = deriveVerb('begin')
|
|
963
|
+
expect(result.action).toBe('begin')
|
|
964
|
+
expect(result.act).toBe('begins')
|
|
965
|
+
expect(result.activity).toBe('beginning')
|
|
966
|
+
expect(result.event).toBe('begun')
|
|
967
|
+
})
|
|
968
|
+
|
|
969
|
+
it('should derive verb conjugations from "do"', () => {
|
|
970
|
+
const result = deriveVerb('do')
|
|
971
|
+
expect(result.action).toBe('do')
|
|
972
|
+
expect(result.act).toBe('does')
|
|
973
|
+
expect(result.activity).toBe('doing')
|
|
974
|
+
expect(result.event).toBe('done')
|
|
975
|
+
})
|
|
976
|
+
|
|
977
|
+
it('should derive verb conjugations from "go"', () => {
|
|
978
|
+
const result = deriveVerb('go')
|
|
979
|
+
expect(result.action).toBe('go')
|
|
980
|
+
expect(result.act).toBe('goes')
|
|
981
|
+
expect(result.activity).toBe('going')
|
|
982
|
+
expect(result.event).toBe('gone')
|
|
983
|
+
})
|
|
984
|
+
|
|
985
|
+
it('should derive verb conjugations from "have"', () => {
|
|
986
|
+
const result = deriveVerb('have')
|
|
987
|
+
expect(result.action).toBe('have')
|
|
988
|
+
expect(result.act).toBe('has')
|
|
989
|
+
expect(result.activity).toBe('having')
|
|
990
|
+
expect(result.event).toBe('had')
|
|
991
|
+
})
|
|
992
|
+
|
|
993
|
+
it('should derive verb conjugations from "be"', () => {
|
|
994
|
+
const result = deriveVerb('be')
|
|
995
|
+
expect(result.action).toBe('be')
|
|
996
|
+
expect(result.act).toBe('is')
|
|
997
|
+
expect(result.activity).toBe('being')
|
|
998
|
+
expect(result.event).toBe('been')
|
|
999
|
+
})
|
|
1000
|
+
|
|
1001
|
+
it('should derive verb conjugations from "set"', () => {
|
|
1002
|
+
const result = deriveVerb('set')
|
|
1003
|
+
expect(result.action).toBe('set')
|
|
1004
|
+
expect(result.act).toBe('sets')
|
|
1005
|
+
expect(result.activity).toBe('setting')
|
|
1006
|
+
expect(result.event).toBe('set')
|
|
1007
|
+
})
|
|
1008
|
+
|
|
1009
|
+
it('should derive verb conjugations from "get"', () => {
|
|
1010
|
+
const result = deriveVerb('get')
|
|
1011
|
+
expect(result.action).toBe('get')
|
|
1012
|
+
expect(result.act).toBe('gets')
|
|
1013
|
+
expect(result.activity).toBe('getting')
|
|
1014
|
+
expect(result.event).toBe('got')
|
|
1015
|
+
})
|
|
1016
|
+
|
|
1017
|
+
it('should derive verb conjugations from "put"', () => {
|
|
1018
|
+
const result = deriveVerb('put')
|
|
1019
|
+
expect(result.action).toBe('put')
|
|
1020
|
+
expect(result.act).toBe('puts')
|
|
1021
|
+
expect(result.activity).toBe('putting')
|
|
1022
|
+
expect(result.event).toBe('put')
|
|
1023
|
+
})
|
|
1024
|
+
|
|
1025
|
+
it('should derive verb conjugations from "cut"', () => {
|
|
1026
|
+
const result = deriveVerb('cut')
|
|
1027
|
+
expect(result.action).toBe('cut')
|
|
1028
|
+
expect(result.act).toBe('cuts')
|
|
1029
|
+
expect(result.activity).toBe('cutting')
|
|
1030
|
+
expect(result.event).toBe('cut')
|
|
1031
|
+
})
|
|
1032
|
+
|
|
1033
|
+
it('should derive verb conjugations from "hit"', () => {
|
|
1034
|
+
const result = deriveVerb('hit')
|
|
1035
|
+
expect(result.action).toBe('hit')
|
|
1036
|
+
expect(result.act).toBe('hits')
|
|
1037
|
+
expect(result.activity).toBe('hitting')
|
|
1038
|
+
expect(result.event).toBe('hit')
|
|
1039
|
+
})
|
|
1040
|
+
})
|
|
1041
|
+
|
|
1042
|
+
describe('reverseBy and reverseAt derivation', () => {
|
|
1043
|
+
it('should derive correct reverseBy and reverseAt for "create"', () => {
|
|
1044
|
+
const result = deriveVerb('create')
|
|
1045
|
+
expect(result.reverseBy).toBe('createdBy')
|
|
1046
|
+
expect(result.reverseAt).toBe('createdAt')
|
|
1047
|
+
})
|
|
1048
|
+
|
|
1049
|
+
it('should derive correct reverseBy and reverseAt for "write" (irregular)', () => {
|
|
1050
|
+
const result = deriveVerb('write')
|
|
1051
|
+
expect(result.reverseBy).toBe('writtenBy')
|
|
1052
|
+
expect(result.reverseAt).toBe('writtenAt')
|
|
1053
|
+
})
|
|
1054
|
+
|
|
1055
|
+
it('should derive correct reverseBy and reverseAt for "update"', () => {
|
|
1056
|
+
const result = deriveVerb('update')
|
|
1057
|
+
expect(result.reverseBy).toBe('updatedBy')
|
|
1058
|
+
expect(result.reverseAt).toBe('updatedAt')
|
|
1059
|
+
})
|
|
1060
|
+
|
|
1061
|
+
it('should derive correct reverseBy and reverseAt for "delete"', () => {
|
|
1062
|
+
const result = deriveVerb('delete')
|
|
1063
|
+
expect(result.reverseBy).toBe('deletedBy')
|
|
1064
|
+
expect(result.reverseAt).toBe('deletedAt')
|
|
1065
|
+
})
|
|
1066
|
+
|
|
1067
|
+
it('should derive correct reverseBy and reverseAt for "publish"', () => {
|
|
1068
|
+
const result = deriveVerb('publish')
|
|
1069
|
+
expect(result.reverseBy).toBe('publishedBy')
|
|
1070
|
+
expect(result.reverseAt).toBe('publishedAt')
|
|
1071
|
+
})
|
|
1072
|
+
})
|
|
1073
|
+
|
|
1074
|
+
describe('reverseIn derivation', () => {
|
|
1075
|
+
it('should derive correct reverseIn for "create"', () => {
|
|
1076
|
+
const result = deriveVerb('create')
|
|
1077
|
+
expect(result.reverseIn).toBe('createdIn')
|
|
1078
|
+
})
|
|
1079
|
+
|
|
1080
|
+
it('should derive correct reverseIn for "write" (irregular)', () => {
|
|
1081
|
+
const result = deriveVerb('write')
|
|
1082
|
+
expect(result.reverseIn).toBe('writtenIn')
|
|
1083
|
+
})
|
|
1084
|
+
|
|
1085
|
+
it('should derive correct reverseIn for "do" (irregular)', () => {
|
|
1086
|
+
const result = deriveVerb('do')
|
|
1087
|
+
expect(result.reverseIn).toBe('doneIn')
|
|
1088
|
+
})
|
|
1089
|
+
})
|
|
1090
|
+
|
|
1091
|
+
describe('case handling', () => {
|
|
1092
|
+
it('should handle uppercase input "CREATE"', () => {
|
|
1093
|
+
const result = deriveVerb('CREATE')
|
|
1094
|
+
expect(result.action).toBe('create')
|
|
1095
|
+
expect(result.act).toBe('creates')
|
|
1096
|
+
expect(result.activity).toBe('creating')
|
|
1097
|
+
expect(result.event).toBe('created')
|
|
1098
|
+
})
|
|
1099
|
+
|
|
1100
|
+
it('should handle mixed case input "CrEaTe"', () => {
|
|
1101
|
+
const result = deriveVerb('CrEaTe')
|
|
1102
|
+
expect(result.action).toBe('create')
|
|
1103
|
+
expect(result.act).toBe('creates')
|
|
1104
|
+
})
|
|
1105
|
+
})
|
|
1106
|
+
})
|
|
1107
|
+
})
|