001/*
002 * ModeShape (http://www.modeshape.org)
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *       http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.modeshape.common.text;
017
018import static org.junit.Assert.assertEquals;
019import org.junit.Before;
020import org.junit.Test;
021
022public class InflectorTest {
023
024    private Inflector inflector;
025
026    @Before
027    public void beforeEach() {
028        this.inflector = new Inflector();
029    }
030
031    public void singularToPlural( Object singular,
032                                  String expectedPlural ) {
033        // Test pluralizing the singular string
034        String actualPlural = inflector.pluralize(singular);
035        assertEquals(expectedPlural, actualPlural);
036
037        // Test singularizing the given (expected) pluralized form
038        String actualSingular = inflector.singularize(expectedPlural);
039        assertEquals(singular, actualSingular);
040
041        // Test singularizing the already singular form (should not change)
042        assertEquals(singular, inflector.singularize(singular));
043
044        // Test pluralizing the already plural form (should not change)
045        assertEquals(expectedPlural, inflector.pluralize(expectedPlural));
046    }
047
048    public void upperCamelCase( String word,
049                                String expectedCamelized,
050                                char... delimiterChars ) {
051        // Test uppercasing the string
052        String actualCamelized = inflector.camelCase(word, true, delimiterChars);
053        assertEquals(expectedCamelized, actualCamelized);
054        assertEquals(expectedCamelized, inflector.upperCamelCase(word, delimiterChars));
055
056        if (delimiterChars == null || delimiterChars.length == 0) {
057            // Test underscoring the camelized word ...
058            String actualUnderscored = inflector.underscore(expectedCamelized);
059            assertEquals(word, actualUnderscored);
060        }
061    }
062
063    public void lowerCamelCase( String word,
064                                String expectedCamelized,
065                                char... delimiterChars ) {
066        // Test lowercasing the string
067        String actualCamelized = inflector.camelCase(word, false, delimiterChars);
068        assertEquals(expectedCamelized, actualCamelized);
069        assertEquals(expectedCamelized, inflector.lowerCamelCase(word, delimiterChars));
070
071        if (delimiterChars == null || delimiterChars.length == 0) {
072            // Test underscoring the camelized word ...
073            String actualUnderscored = inflector.underscore(expectedCamelized);
074            assertEquals(word, actualUnderscored);
075        }
076    }
077
078    public void underscore( String word,
079                            String expectedUnderscored,
080                            char... delimiterChars ) {
081        // Test underscoring the word
082        String actualUnderscored = inflector.underscore(word, delimiterChars);
083        assertEquals(expectedUnderscored, actualUnderscored);
084    }
085
086    public void capitalize( String words,
087                            String expectedValue ) {
088        // Test capitalizing the phrase
089        String actualValue = inflector.capitalize(words);
090        assertEquals(expectedValue, actualValue);
091    }
092
093    public void humanize( String word,
094                          String expectedValue,
095                          String... removableTokens ) {
096        // Test humanizing the word
097        String actualValue = inflector.humanize(word, removableTokens);
098        assertEquals(expectedValue, actualValue);
099    }
100
101    public void titleCase( String word,
102                           String expectedValue,
103                           String... removableTokens ) {
104        // Test title casing the word
105        String actualValue = inflector.titleCase(word, removableTokens);
106        assertEquals(expectedValue, actualValue);
107    }
108
109    public void ordinalize( int number,
110                            String expectedValue ) {
111        // Test underscoring the camelized word
112        String actualValue = inflector.ordinalize(number);
113        assertEquals(expectedValue, actualValue);
114    }
115
116    @Test
117    public void shouldReplaceAllWithUppercase() {
118        assertEquals("hEllO", Inflector.replaceAllWithUppercase("hello", "([aeiou])", 1));
119        assertEquals("hLlo", Inflector.replaceAllWithUppercase("hello", "([aeiou])(l)", 2));
120    }
121
122    @Test
123    public void shouldPluralizeAndSingularize() {
124        // These are examples of words that do not have special rules
125        singularToPlural("class", "classes");
126        singularToPlural("glass", "glasses");
127        singularToPlural("package", "packages");
128        singularToPlural("setting", "settings");
129        singularToPlural("sample", "samples");
130        singularToPlural("message", "messages");
131        singularToPlural("content", "contents");
132        singularToPlural("ball", "balls");
133        // These are special cases that are handled by standard rules ...
134        singularToPlural("axis", "axes");
135        singularToPlural("octopus", "octopi");
136        singularToPlural("virus", "viri");
137        singularToPlural("alien", "aliens");
138        singularToPlural("status", "statuses");
139        singularToPlural("bus", "buses");
140        singularToPlural("buffalo", "buffaloes");
141        singularToPlural("tomato", "tomatoes");
142
143        singularToPlural("quiz", "quizzes");
144        singularToPlural("party", "parties");
145        singularToPlural("half", "halves");
146        singularToPlural("stadium", "stadiums");
147
148        // From activesupport/test/inflector_test.rb
149        singularToPlural("search", "searches");
150        singularToPlural("switch", "switches");
151        singularToPlural("fix", "fixes");
152        singularToPlural("box", "boxes");
153        singularToPlural("process", "processes");
154        singularToPlural("address", "addresses");
155        singularToPlural("case", "cases");
156        singularToPlural("stack", "stacks");
157        singularToPlural("wish", "wishes");
158        singularToPlural("fish", "fish");
159
160        singularToPlural("category", "categories");
161        singularToPlural("query", "queries");
162        singularToPlural("ability", "abilities");
163        singularToPlural("agency", "agencies");
164        singularToPlural("movie", "movies");
165
166        singularToPlural("archive", "archives");
167
168        singularToPlural("index", "indices");
169
170        singularToPlural("wife", "wives");
171        singularToPlural("safe", "saves");
172        singularToPlural("half", "halves");
173
174        singularToPlural("move", "moves");
175
176        singularToPlural("salesperson", "salespeople");
177        singularToPlural("person", "people");
178
179        singularToPlural("spokesman", "spokesmen");
180        singularToPlural("man", "men");
181        singularToPlural("woman", "women");
182
183        singularToPlural("basis", "bases");
184        singularToPlural("diagnosis", "diagnoses");
185
186        singularToPlural("datum", "data");
187        singularToPlural("medium", "media");
188        singularToPlural("analysis", "analyses");
189
190        singularToPlural("node_child", "node_children");
191        singularToPlural("child", "children");
192
193        singularToPlural("experience", "experiences");
194        singularToPlural("day", "days");
195
196        singularToPlural("comment", "comments");
197        singularToPlural("foobar", "foobars");
198        singularToPlural("newsletter", "newsletters");
199
200        singularToPlural("old_news", "old_news");
201        singularToPlural("news", "news");
202
203        singularToPlural("series", "series");
204        singularToPlural("species", "species");
205
206        singularToPlural("quiz", "quizzes");
207
208        singularToPlural("perspective", "perspectives");
209
210        singularToPlural("ox", "oxen");
211        singularToPlural("photo", "photos");
212        singularToPlural("buffalo", "buffaloes");
213        singularToPlural("tomato", "tomatoes");
214        singularToPlural("dwarf", "dwarves");
215        singularToPlural("elf", "elves");
216        singularToPlural("information", "information");
217        singularToPlural("equipment", "equipment");
218        singularToPlural("bus", "buses");
219        singularToPlural("status", "statuses");
220        singularToPlural("status_code", "status_codes");
221        singularToPlural("mouse", "mice");
222
223        singularToPlural("louse", "lice");
224        singularToPlural("house", "houses");
225        singularToPlural("octopus", "octopi");
226        singularToPlural("virus", "viri");
227        singularToPlural("alias", "aliases");
228        singularToPlural("portfolio", "portfolios");
229
230        singularToPlural("vertex", "vertices");
231        singularToPlural("matrix", "matrices");
232
233        singularToPlural("axis", "axes");
234        singularToPlural("testis", "testes");
235        singularToPlural("crisis", "crises");
236
237        singularToPlural("rice", "rice");
238        singularToPlural("shoe", "shoes");
239
240        singularToPlural("horse", "horses");
241        singularToPlural("prize", "prizes");
242        singularToPlural("edge", "edges");
243    }
244
245    @Test
246    public void shouldConvertToCamelCase() {
247        lowerCamelCase("edge", "edge");
248        lowerCamelCase("active_record", "activeRecord");
249        lowerCamelCase("product", "product");
250        lowerCamelCase("special_guest", "specialGuest");
251        lowerCamelCase("application_controller", "applicationController");
252        lowerCamelCase("area51_controller", "area51Controller");
253        lowerCamelCase("the-first_name", "theFirstName", '-');
254
255        upperCamelCase("edge", "Edge");
256        upperCamelCase("active_record", "ActiveRecord");
257        upperCamelCase("product", "Product");
258        upperCamelCase("special_guest", "SpecialGuest");
259        upperCamelCase("application_controller", "ApplicationController");
260        upperCamelCase("area51_controller", "Area51Controller");
261        upperCamelCase("the-first_name", "TheFirstName", '-');
262    }
263
264    @Test
265    public void shouldConvertToUnderscore() {
266        underscore("activeRecord", "active_record");
267        underscore("ActiveRecord", "active_record");
268        underscore("ACTIVERecord", "active_record");
269        underscore("firstName", "first_name");
270        underscore("FirstName", "first_name");
271        underscore("name", "name");
272        underscore("The.firstName", "the_first_name", '.');
273
274    }
275
276    @Test
277    public void shouldCapitalize() {
278        capitalize("active record", "Active record");
279        capitalize("first name", "First name");
280        capitalize("name", "Name");
281        capitalize("the first name", "The first name");
282        capitalize("employee_salary", "Employee_salary");
283        capitalize("underground", "Underground");
284    }
285
286    @Test
287    public void shouldHumanize() {
288        humanize("active_record", "Active record");
289        humanize("first_name", "First name");
290        humanize("name", "Name");
291        humanize("the_first_name", "The first name");
292        humanize("employee_salary", "Employee salary");
293        humanize("underground", "Underground");
294        humanize("id", "Id");
295        humanize("employee_id", "Employee");
296        humanize("employee_value_string", "Employee string", "value");
297    }
298
299    @Test
300    public void shouldConvertToTitleCase() {
301        titleCase("active_record", "Active Record");
302        titleCase("first_name", "First Name");
303        titleCase("name", "Name");
304        titleCase("the_first_name", "The First Name");
305        titleCase("employee_salary", "Employee Salary");
306        titleCase("underground", "Underground");
307        titleCase("id", "Id");
308        titleCase("employee_id", "Employee");
309        titleCase("employee_value_string", "Employee String", "value");
310    }
311
312    @Test
313    public void shouldOrdinalize() {
314        ordinalize(1, "1st");
315        ordinalize(2, "2nd");
316        ordinalize(3, "3rd");
317        ordinalize(4, "4th");
318        ordinalize(5, "5th");
319        ordinalize(6, "6th");
320        ordinalize(7, "7th");
321        ordinalize(8, "8th");
322        ordinalize(9, "9th");
323        ordinalize(10, "10th");
324        ordinalize(11, "11th");
325        ordinalize(12, "12th");
326        ordinalize(13, "13th");
327        ordinalize(14, "14th");
328        ordinalize(15, "15th");
329        ordinalize(16, "16th");
330        ordinalize(17, "17th");
331        ordinalize(18, "18th");
332        ordinalize(19, "19th");
333        ordinalize(20, "20th");
334        ordinalize(21, "21st");
335        ordinalize(22, "22nd");
336        ordinalize(23, "23rd");
337        ordinalize(24, "24th");
338        ordinalize(25, "25th");
339        ordinalize(26, "26th");
340        ordinalize(27, "27th");
341        ordinalize(28, "28th");
342        ordinalize(29, "29th");
343        ordinalize(30, "30th");
344        ordinalize(31, "31st");
345        ordinalize(32, "32nd");
346        ordinalize(33, "33rd");
347        ordinalize(34, "34th");
348        ordinalize(35, "35th");
349        ordinalize(36, "36th");
350        ordinalize(37, "37th");
351        ordinalize(38, "38th");
352        ordinalize(39, "39th");
353        ordinalize(100, "100th");
354        ordinalize(101, "101st");
355        ordinalize(102, "102nd");
356        ordinalize(103, "103rd");
357        ordinalize(104, "104th");
358        ordinalize(200, "200th");
359        ordinalize(201, "201st");
360        ordinalize(202, "202nd");
361        ordinalize(203, "203rd");
362        ordinalize(204, "204th");
363        ordinalize(1000, "1000th");
364        ordinalize(1001, "1001st");
365        ordinalize(1002, "1002nd");
366        ordinalize(1003, "1003rd");
367        ordinalize(1004, "1004th");
368        ordinalize(10000, "10000th");
369        ordinalize(10001, "10001st");
370        ordinalize(10002, "10002nd");
371        ordinalize(10003, "10003rd");
372        ordinalize(10004, "10004th");
373        ordinalize(100000, "100000th");
374        ordinalize(100001, "100001st");
375        ordinalize(100002, "100002nd");
376        ordinalize(100003, "100003rd");
377        ordinalize(100004, "100004th");
378    }
379
380}