Skip to content

Commit e17792f

Browse files
committed
Merge pull request #83 from glaukommatos/add-woman-women
Fix pluralization issue (in order to properly pluralize/singularize woman/women!)
2 parents f1e20a2 + cc30980 commit e17792f

File tree

2 files changed

+234
-14
lines changed

2 files changed

+234
-14
lines changed

addon/lib/system/inflector.js

+15-14
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,7 @@ Inflector.prototype = {
241241
*/
242242
inflect: function(word, typeRules, irregular) {
243243
var inflection, substitution, result, lowercase, wordSplit,
244-
firstPhrase, lastWord, isBlank, isCamelized, isUncountable,
245-
isIrregular, rule;
244+
firstPhrase, lastWord, isBlank, isCamelized, rule;
246245

247246
isBlank = !word || BLANK_REGEX.test(word);
248247

@@ -255,26 +254,28 @@ Inflector.prototype = {
255254

256255
lowercase = word.toLowerCase();
257256
wordSplit = LAST_WORD_DASHED_REGEX.exec(word) || LAST_WORD_CAMELIZED_REGEX.exec(word);
257+
258258
if (wordSplit){
259259
firstPhrase = wordSplit[1];
260260
lastWord = wordSplit[2].toLowerCase();
261261
}
262262

263-
isUncountable = this.rules.uncountable[lowercase] || this.rules.uncountable[lastWord];
264-
265-
if (isUncountable) {
266-
return word;
263+
for (rule in this.rules.uncountable) {
264+
if (lowercase.match(rule+"$")) {
265+
return word;
266+
}
267267
}
268268

269-
isIrregular = irregular && (irregular[lowercase] || irregular[lastWord]);
269+
for (rule in this.rules.irregular) {
270+
if (lowercase.match(rule+"$")) {
271+
substitution = irregular[rule];
270272

271-
if (isIrregular) {
272-
if (irregular[lowercase]){
273-
return isIrregular;
274-
}
275-
else {
276-
isIrregular = (isCamelized) ? capitalize(isIrregular) : isIrregular;
277-
return firstPhrase + isIrregular;
273+
if (isCamelized && irregular[lastWord]) {
274+
substitution = capitalize(substitution);
275+
rule = capitalize(rule);
276+
}
277+
278+
return word.replace(rule, substitution);
278279
}
279280
}
280281

tests/unit/inflector-test.js

+219
Original file line numberDiff line numberDiff line change
@@ -313,3 +313,222 @@ test('new Ember.Inflector with defaultRules matches docs', function(assert) {
313313
// defaultRules removes 's' from plural
314314
assert.equal(inflector.singularize('items'), 'item');
315315
});
316+
317+
test('words containing irregular and uncountable words can be pluralized', function(assert) {
318+
var inflector = new Ember.Inflector(Ember.Inflector.defaultRules);
319+
assert.equal(inflector.pluralize('woman'), 'women');
320+
assert.equal(inflector.pluralize('salesperson'), 'salespeople');
321+
assert.equal(inflector.pluralize('pufferfish'), 'pufferfish');
322+
});
323+
324+
325+
test('words containing irregular and uncountable words can be singularized', function(assert) {
326+
var inflector = new Ember.Inflector(Ember.Inflector.defaultRules);
327+
assert.equal(inflector.singularize('women'), 'woman');
328+
assert.equal(inflector.singularize('salespeople'), 'salesperson');
329+
assert.equal(inflector.singularize('pufferfish'), 'pufferfish');
330+
});
331+
332+
test('CamelCase and UpperCamelCase is preserved for irregular and uncountable pluralizations', function(assert) {
333+
var inflector = new Ember.Inflector(Ember.Inflector.defaultRules);
334+
assert.equal(inflector.pluralize('SuperWoman'), 'SuperWomen');
335+
assert.equal(inflector.pluralize('superWoman'), 'superWomen');
336+
assert.equal(inflector.pluralize('SuperMan'), 'SuperMen');
337+
assert.equal(inflector.pluralize('superMan'), 'superMen');
338+
assert.equal(inflector.pluralize('FriedRice'), 'FriedRice');
339+
assert.equal(inflector.pluralize('friedRice'), 'friedRice');
340+
});
341+
342+
343+
test('CamelCase and UpperCamelCase is preserved for irregular and uncountable singularization', function(assert) {
344+
var inflector = new Ember.Inflector(Ember.Inflector.defaultRules);
345+
assert.equal(inflector.singularize('SuperWomen'), 'SuperWoman');
346+
assert.equal(inflector.singularize('superWomen'), 'superWoman');
347+
assert.equal(inflector.singularize('SuperMen'), 'SuperMan');
348+
assert.equal(inflector.singularize('superMen'), 'superMan');
349+
assert.equal(inflector.singularize('FriedRice'), 'FriedRice');
350+
assert.equal(inflector.singularize('friedRice'), 'friedRice');
351+
});
352+
353+
test('Ember.Inflector.pluralize passes same test cases as ActiveSupport::Inflector#pluralize', function(assert) {
354+
var inflector = new Ember.Inflector(Ember.Inflector.defaultRules);
355+
356+
assert.equal(inflector.pluralize('search'), 'searches');
357+
assert.equal(inflector.pluralize('switch'), 'switches');
358+
assert.equal(inflector.pluralize('fix'), 'fixes');
359+
assert.equal(inflector.pluralize('box'), 'boxes');
360+
assert.equal(inflector.pluralize('process'), 'processes');
361+
assert.equal(inflector.pluralize('address'), 'addresses');
362+
assert.equal(inflector.pluralize('case'), 'cases');
363+
assert.equal(inflector.pluralize('stack'), 'stacks');
364+
assert.equal(inflector.pluralize('wish'), 'wishes');
365+
assert.equal(inflector.pluralize('fish'), 'fish');
366+
assert.equal(inflector.pluralize('jeans'), 'jeans');
367+
assert.equal(inflector.pluralize('funky jeans'), 'funky jeans');
368+
assert.equal(inflector.pluralize('my money'), 'my money');
369+
assert.equal(inflector.pluralize('category'), 'categories');
370+
assert.equal(inflector.pluralize('query'), 'queries');
371+
assert.equal(inflector.pluralize('ability'), 'abilities');
372+
assert.equal(inflector.pluralize('agency'), 'agencies');
373+
assert.equal(inflector.pluralize('movie'), 'movies');
374+
assert.equal(inflector.pluralize('archive'), 'archives');
375+
assert.equal(inflector.pluralize('index'), 'indices');
376+
assert.equal(inflector.pluralize('wife'), 'wives');
377+
assert.equal(inflector.pluralize('safe'), 'saves');
378+
assert.equal(inflector.pluralize('half'), 'halves');
379+
assert.equal(inflector.pluralize('move'), 'moves');
380+
assert.equal(inflector.pluralize('salesperson'), 'salespeople');
381+
assert.equal(inflector.pluralize('person'), 'people');
382+
assert.equal(inflector.pluralize('spokesman'), 'spokesmen');
383+
assert.equal(inflector.pluralize('man'), 'men');
384+
assert.equal(inflector.pluralize('woman'), 'women');
385+
assert.equal(inflector.pluralize('basis'), 'bases');
386+
assert.equal(inflector.pluralize('diagnosis'), 'diagnoses');
387+
assert.equal(inflector.pluralize('diagnosis_a'), 'diagnosis_as');
388+
assert.equal(inflector.pluralize('datum'), 'data');
389+
assert.equal(inflector.pluralize('medium'), 'media');
390+
assert.equal(inflector.pluralize('stadium'), 'stadia');
391+
assert.equal(inflector.pluralize('analysis'), 'analyses');
392+
assert.equal(inflector.pluralize('my_analysis'), 'my_analyses');
393+
assert.equal(inflector.pluralize('node_child'), 'node_children');
394+
assert.equal(inflector.pluralize('child'), 'children');
395+
assert.equal(inflector.pluralize('experience'), 'experiences');
396+
assert.equal(inflector.pluralize('day'), 'days');
397+
assert.equal(inflector.pluralize('comment'), 'comments');
398+
assert.equal(inflector.pluralize('foobar'), 'foobars');
399+
assert.equal(inflector.pluralize('newsletter'), 'newsletters');
400+
assert.equal(inflector.pluralize('old_news'), 'old_news');
401+
assert.equal(inflector.pluralize('news'), 'news');
402+
assert.equal(inflector.pluralize('series'), 'series');
403+
assert.equal(inflector.pluralize('miniseries'), 'miniseries');
404+
assert.equal(inflector.pluralize('species'), 'species');
405+
assert.equal(inflector.pluralize('quiz'), 'quizzes');
406+
assert.equal(inflector.pluralize('perspective'), 'perspectives');
407+
assert.equal(inflector.pluralize('ox'), 'oxen');
408+
assert.equal(inflector.pluralize('photo'), 'photos');
409+
assert.equal(inflector.pluralize('buffalo'), 'buffaloes');
410+
assert.equal(inflector.pluralize('tomato'), 'tomatoes');
411+
assert.equal(inflector.pluralize('dwarf'), 'dwarves');
412+
assert.equal(inflector.pluralize('elf'), 'elves');
413+
assert.equal(inflector.pluralize('information'), 'information');
414+
assert.equal(inflector.pluralize('equipment'), 'equipment');
415+
assert.equal(inflector.pluralize('bus'), 'buses');
416+
assert.equal(inflector.pluralize('status'), 'statuses');
417+
assert.equal(inflector.pluralize('status_code'), 'status_codes');
418+
assert.equal(inflector.pluralize('mouse'), 'mice');
419+
assert.equal(inflector.pluralize('louse'), 'lice');
420+
assert.equal(inflector.pluralize('house'), 'houses');
421+
assert.equal(inflector.pluralize('octopus'), 'octopi');
422+
assert.equal(inflector.pluralize('virus'), 'viri');
423+
assert.equal(inflector.pluralize('alias'), 'aliases');
424+
assert.equal(inflector.pluralize('portfolio'), 'portfolios');
425+
assert.equal(inflector.pluralize('vertex'), 'vertices');
426+
assert.equal(inflector.pluralize('matrix'), 'matrices');
427+
assert.equal(inflector.pluralize('matrix_fu'), 'matrix_fus');
428+
assert.equal(inflector.pluralize('axis'), 'axes');
429+
assert.equal(inflector.pluralize('taxi'), 'taxis');
430+
assert.equal(inflector.pluralize('testis'), 'testes');
431+
assert.equal(inflector.pluralize('crisis'), 'crises');
432+
assert.equal(inflector.pluralize('rice'), 'rice');
433+
assert.equal(inflector.pluralize('shoe'), 'shoes');
434+
assert.equal(inflector.pluralize('horse'), 'horses');
435+
assert.equal(inflector.pluralize('prize'), 'prizes');
436+
assert.equal(inflector.pluralize('edge'), 'edges');
437+
assert.equal(inflector.pluralize('database'), 'databases');
438+
assert.equal(inflector.pluralize('|ice'), '|ices');
439+
assert.equal(inflector.pluralize('|ouse'), '|ouses');
440+
assert.equal(inflector.pluralize('slice'), 'slices');
441+
assert.equal(inflector.pluralize('police'), 'police');
442+
});
443+
444+
test('Ember.Inflector.singularize passes same test cases as ActiveSupport::Inflector#singularize', function(assert) {
445+
var inflector = new Ember.Inflector(Ember.Inflector.defaultRules);
446+
447+
assert.equal(inflector.singularize('searches'), 'search');
448+
assert.equal(inflector.singularize('switches'), 'switch');
449+
assert.equal(inflector.singularize('fixes'), 'fix');
450+
assert.equal(inflector.singularize('boxes'), 'box');
451+
assert.equal(inflector.singularize('processes'), 'process');
452+
assert.equal(inflector.singularize('addresses'), 'address');
453+
assert.equal(inflector.singularize('cases'), 'case');
454+
assert.equal(inflector.singularize('stacks'), 'stack');
455+
assert.equal(inflector.singularize('wishes'), 'wish');
456+
assert.equal(inflector.singularize('fish'), 'fish');
457+
assert.equal(inflector.singularize('jeans'), 'jeans');
458+
assert.equal(inflector.singularize('funky jeans'), 'funky jeans');
459+
assert.equal(inflector.singularize('my money'), 'my money');
460+
assert.equal(inflector.singularize('categories'), 'category');
461+
assert.equal(inflector.singularize('queries'), 'query');
462+
assert.equal(inflector.singularize('abilities'), 'ability');
463+
assert.equal(inflector.singularize('agencies'), 'agency');
464+
assert.equal(inflector.singularize('movies'), 'movie');
465+
assert.equal(inflector.singularize('archives'), 'archive');
466+
assert.equal(inflector.singularize('indices'), 'index');
467+
assert.equal(inflector.singularize('wives'), 'wife');
468+
assert.equal(inflector.singularize('saves'), 'safe');
469+
assert.equal(inflector.singularize('halves'), 'half');
470+
assert.equal(inflector.singularize('moves'), 'move');
471+
assert.equal(inflector.singularize('salespeople'), 'salesperson');
472+
assert.equal(inflector.singularize('people'), 'person');
473+
assert.equal(inflector.singularize('spokesmen'), 'spokesman');
474+
assert.equal(inflector.singularize('men'), 'man');
475+
assert.equal(inflector.singularize('women'), 'woman');
476+
assert.equal(inflector.singularize('bases'), 'basis');
477+
assert.equal(inflector.singularize('diagnoses'), 'diagnosis');
478+
assert.equal(inflector.singularize('diagnosis_as'), 'diagnosis_a');
479+
assert.equal(inflector.singularize('data'), 'datum');
480+
assert.equal(inflector.singularize('media'), 'medium');
481+
assert.equal(inflector.singularize('stadia'), 'stadium');
482+
assert.equal(inflector.singularize('analyses'), 'analysis');
483+
assert.equal(inflector.singularize('my_analyses'), 'my_analysis');
484+
assert.equal(inflector.singularize('node_children'), 'node_child');
485+
assert.equal(inflector.singularize('children'), 'child');
486+
assert.equal(inflector.singularize('experiences'), 'experience');
487+
assert.equal(inflector.singularize('days'), 'day');
488+
assert.equal(inflector.singularize('comments'), 'comment');
489+
assert.equal(inflector.singularize('foobars'), 'foobar');
490+
assert.equal(inflector.singularize('newsletters'), 'newsletter');
491+
assert.equal(inflector.singularize('old_news'), 'old_news');
492+
assert.equal(inflector.singularize('news'), 'news');
493+
assert.equal(inflector.singularize('series'), 'series');
494+
assert.equal(inflector.singularize('miniseries'), 'miniseries');
495+
assert.equal(inflector.singularize('species'), 'species');
496+
assert.equal(inflector.singularize('quizzes'), 'quiz');
497+
assert.equal(inflector.singularize('perspectives'), 'perspective');
498+
assert.equal(inflector.singularize('oxen'), 'ox');
499+
assert.equal(inflector.singularize('photos'), 'photo');
500+
assert.equal(inflector.singularize('buffaloes'), 'buffalo');
501+
assert.equal(inflector.singularize('tomatoes'), 'tomato');
502+
assert.equal(inflector.singularize('dwarves'), 'dwarf');
503+
assert.equal(inflector.singularize('elves'), 'elf');
504+
assert.equal(inflector.singularize('information'), 'information');
505+
assert.equal(inflector.singularize('equipment'), 'equipment');
506+
assert.equal(inflector.singularize('buses'), 'bus');
507+
assert.equal(inflector.singularize('statuses'), 'status');
508+
assert.equal(inflector.singularize('status_codes'), 'status_code');
509+
assert.equal(inflector.singularize('mice'), 'mouse');
510+
assert.equal(inflector.singularize('lice'), 'louse');
511+
assert.equal(inflector.singularize('houses'), 'house');
512+
assert.equal(inflector.singularize('octopi'), 'octopus');
513+
assert.equal(inflector.singularize('viri'), 'virus');
514+
assert.equal(inflector.singularize('aliases'), 'alias');
515+
assert.equal(inflector.singularize('portfolios'), 'portfolio');
516+
assert.equal(inflector.singularize('vertices'), 'vertex');
517+
assert.equal(inflector.singularize('matrices'), 'matrix');
518+
assert.equal(inflector.singularize('matrix_fus'), 'matrix_fu');
519+
assert.equal(inflector.singularize('axes'), 'axis');
520+
assert.equal(inflector.singularize('taxis'), 'taxi');
521+
assert.equal(inflector.singularize('testes'), 'testis');
522+
assert.equal(inflector.singularize('crises'), 'crisis');
523+
assert.equal(inflector.singularize('rice'), 'rice');
524+
assert.equal(inflector.singularize('shoes'), 'shoe');
525+
assert.equal(inflector.singularize('horses'), 'horse');
526+
assert.equal(inflector.singularize('prizes'), 'prize');
527+
assert.equal(inflector.singularize('edges'), 'edge');
528+
assert.equal(inflector.singularize('databases'), 'database');
529+
assert.equal(inflector.singularize('|ices'), '|ice');
530+
assert.equal(inflector.singularize('|ouses'), '|ouse');
531+
assert.equal(inflector.singularize('slices'), 'slice');
532+
assert.equal(inflector.singularize('police'), 'police');
533+
});
534+

0 commit comments

Comments
 (0)