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}