1ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka/* 2ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka * Copyright (C) 2013 The Android Open Source Project 3ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka * 4ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka * Licensed under the Apache License, Version 2.0 (the "License"); 5ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka * you may not use this file except in compliance with the License. 6ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka * You may obtain a copy of the License at 7ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka * 8ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka * http://www.apache.org/licenses/LICENSE-2.0 9ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka * 10ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka * Unless required by applicable law or agreed to in writing, software 11ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka * distributed under the License is distributed on an "AS IS" BASIS, 12ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka * See the License for the specific language governing permissions and 14ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka * limitations under the License. 15ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka */ 16ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka 17e28eba5074664d5716b8e58b8d0a235746b261ebKen Wakasapackage com.android.inputmethod.latin.utils; 18ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka 190a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaokaimport android.content.res.Resources; 20ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaokaimport android.test.AndroidTestCase; 21ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaokaimport android.test.suitebuilder.annotation.SmallTest; 22ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaokaimport android.text.TextUtils; 23ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka 245b91b551e5ffaf2c2e691dfbd434f21c82293986Jean Chalardimport com.android.inputmethod.latin.common.LocaleUtils; 250a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaokaimport com.android.inputmethod.latin.settings.SpacingAndPunctuations; 260a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka 27ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaokaimport java.util.Locale; 28ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka 29ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka@SmallTest 30ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaokapublic class CapsModeUtilsTests extends AndroidTestCase { 31ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka private static void onePathForCaps(final CharSequence cs, final int expectedResult, 320a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka final int mask, final SpacingAndPunctuations sp, final boolean hasSpaceBefore) { 330a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka final int oneTimeResult = expectedResult & mask; 34ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka assertEquals("After >" + cs + "<", oneTimeResult, 350a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka CapsModeUtils.getCapsMode(cs, mask, sp, hasSpaceBefore)); 36ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka } 37ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka 38ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka private static void allPathsForCaps(final CharSequence cs, final int expectedResult, 390a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka final SpacingAndPunctuations sp, final boolean hasSpaceBefore) { 40ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka final int c = TextUtils.CAP_MODE_CHARACTERS; 41ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka final int w = TextUtils.CAP_MODE_WORDS; 42ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka final int s = TextUtils.CAP_MODE_SENTENCES; 430a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka onePathForCaps(cs, expectedResult, c | w | s, sp, hasSpaceBefore); 440a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka onePathForCaps(cs, expectedResult, w | s, sp, hasSpaceBefore); 450a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka onePathForCaps(cs, expectedResult, c | s, sp, hasSpaceBefore); 460a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka onePathForCaps(cs, expectedResult, c | w, sp, hasSpaceBefore); 470a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka onePathForCaps(cs, expectedResult, c, sp, hasSpaceBefore); 480a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka onePathForCaps(cs, expectedResult, w, sp, hasSpaceBefore); 490a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka onePathForCaps(cs, expectedResult, s, sp, hasSpaceBefore); 50ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka } 51ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka 52ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka public void testGetCapsMode() { 53ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka final int c = TextUtils.CAP_MODE_CHARACTERS; 54ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka final int w = TextUtils.CAP_MODE_WORDS; 55ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka final int s = TextUtils.CAP_MODE_SENTENCES; 560a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka final RunInLocale<SpacingAndPunctuations> job = new RunInLocale<SpacingAndPunctuations>() { 570a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka @Override 580a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka protected SpacingAndPunctuations job(final Resources res) { 590a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka return new SpacingAndPunctuations(res); 600a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka } 610a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka }; 620a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka final Resources res = getContext().getResources(); 630a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka SpacingAndPunctuations sp = job.runInLocale(res, Locale.ENGLISH); 640a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka allPathsForCaps("", c | w | s, sp, false); 650a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka allPathsForCaps("Word", c, sp, false); 660a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka allPathsForCaps("Word.", c, sp, false); 670a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka allPathsForCaps("Word ", c | w, sp, false); 680a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka allPathsForCaps("Word. ", c | w | s, sp, false); 690a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka allPathsForCaps("Word..", c, sp, false); 700a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka allPathsForCaps("Word.. ", c | w | s, sp, false); 710a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka allPathsForCaps("Word... ", c | w | s, sp, false); 720a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka allPathsForCaps("Word ... ", c | w | s, sp, false); 730a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka allPathsForCaps("Word . ", c | w, sp, false); 740a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka allPathsForCaps("In the U.S ", c | w, sp, false); 750a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka allPathsForCaps("In the U.S. ", c | w, sp, false); 760a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka allPathsForCaps("Some stuff (e.g. ", c | w, sp, false); 770a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka allPathsForCaps("In the U.S.. ", c | w | s, sp, false); 780a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka allPathsForCaps("\"Word.\" ", c | w | s, sp, false); 790a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka allPathsForCaps("\"Word\". ", c | w | s, sp, false); 800a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka allPathsForCaps("\"Word\" ", c | w, sp, false); 81ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka 82ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka // Test for phantom space 830a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka allPathsForCaps("Word", c | w, sp, true); 840a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka allPathsForCaps("Word.", c | w | s, sp, true); 85ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka 86ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka // Tests after some whitespace 870a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka allPathsForCaps("Word\n", c | w | s, sp, false); 880a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka allPathsForCaps("Word\n", c | w | s, sp, true); 890a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka allPathsForCaps("Word\n ", c | w | s, sp, true); 900a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka allPathsForCaps("Word.\n", c | w | s, sp, false); 910a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka allPathsForCaps("Word.\n", c | w | s, sp, true); 920a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka allPathsForCaps("Word.\n ", c | w | s, sp, true); 93ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka 940a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka sp = job.runInLocale(res, Locale.FRENCH); 950a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka allPathsForCaps("\"Word.\" ", c | w, sp, false); 960a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka allPathsForCaps("\"Word\". ", c | w | s, sp, false); 970a75cf51afbdc79ccb2c6eabaf06a0aa26263af5Tadashi G. Takaoka allPathsForCaps("\"Word\" ", c | w, sp, false); 9860afa7000f14f8f8ca890236f636d45a2b59b61eJean Chalard 9960afa7000f14f8f8ca890236f636d45a2b59b61eJean Chalard // Test special case for German. German does not capitalize at the start of a 10060afa7000f14f8f8ca890236f636d45a2b59b61eJean Chalard // line when the previous line starts with a comma. It does in other cases. 10160afa7000f14f8f8ca890236f636d45a2b59b61eJean Chalard sp = job.runInLocale(res, Locale.GERMAN); 10260afa7000f14f8f8ca890236f636d45a2b59b61eJean Chalard allPathsForCaps("Liebe Sara,\n", c | w, sp, false); 10360afa7000f14f8f8ca890236f636d45a2b59b61eJean Chalard allPathsForCaps("Liebe Sara,\n", c | w, sp, true); 10460afa7000f14f8f8ca890236f636d45a2b59b61eJean Chalard allPathsForCaps("Liebe Sara, \n ", c | w, sp, false); 10560afa7000f14f8f8ca890236f636d45a2b59b61eJean Chalard allPathsForCaps("Liebe Sara \n ", c | w | s, sp, false); 10660afa7000f14f8f8ca890236f636d45a2b59b61eJean Chalard allPathsForCaps("Liebe Sara.\n ", c | w | s, sp, false); 10760afa7000f14f8f8ca890236f636d45a2b59b61eJean Chalard sp = job.runInLocale(res, Locale.ENGLISH); 10860afa7000f14f8f8ca890236f636d45a2b59b61eJean Chalard allPathsForCaps("Liebe Sara,\n", c | w | s, sp, false); 10960afa7000f14f8f8ca890236f636d45a2b59b61eJean Chalard allPathsForCaps("Liebe Sara,\n", c | w | s, sp, true); 11060afa7000f14f8f8ca890236f636d45a2b59b61eJean Chalard allPathsForCaps("Liebe Sara, \n ", c | w | s, sp, false); 11160afa7000f14f8f8ca890236f636d45a2b59b61eJean Chalard allPathsForCaps("Liebe Sara \n ", c | w | s, sp, false); 11260afa7000f14f8f8ca890236f636d45a2b59b61eJean Chalard allPathsForCaps("Liebe Sara.\n ", c | w | s, sp, false); 113bfea7dec1a4260104b6d4b316f2163368478869cJean Chalard 114bfea7dec1a4260104b6d4b316f2163368478869cJean Chalard // Test armenian period 115bfea7dec1a4260104b6d4b316f2163368478869cJean Chalard sp = job.runInLocale(res, LocaleUtils.constructLocaleFromString("hy_AM")); 116bfea7dec1a4260104b6d4b316f2163368478869cJean Chalard assertTrue("Period is not sentence separator in Armenian", 117bfea7dec1a4260104b6d4b316f2163368478869cJean Chalard !sp.isSentenceSeparator('.')); 118bfea7dec1a4260104b6d4b316f2163368478869cJean Chalard assertTrue("Sentence separator is Armenian period in Armenian", 119bfea7dec1a4260104b6d4b316f2163368478869cJean Chalard sp.isSentenceSeparator(0x589)); 120bfea7dec1a4260104b6d4b316f2163368478869cJean Chalard // No space : capitalize only if MODE_CHARACTERS 121bfea7dec1a4260104b6d4b316f2163368478869cJean Chalard allPathsForCaps("Word", c, sp, false); 122bfea7dec1a4260104b6d4b316f2163368478869cJean Chalard allPathsForCaps("Word.", c, sp, false); 123bfea7dec1a4260104b6d4b316f2163368478869cJean Chalard // Space, but no armenian period : capitalize if MODE_WORDS but not SENTENCES 124bfea7dec1a4260104b6d4b316f2163368478869cJean Chalard allPathsForCaps("Word. ", c | w, sp, false); 125bfea7dec1a4260104b6d4b316f2163368478869cJean Chalard // Armenian period : capitalize if MODE_SENTENCES 126bfea7dec1a4260104b6d4b316f2163368478869cJean Chalard allPathsForCaps("Word\u0589 ", c | w | s, sp, false); 12717901db6910317a4266b06035455b92f3a85a2e9Jean Chalard 12817901db6910317a4266b06035455b92f3a85a2e9Jean Chalard // Test for sentence terminators 12917901db6910317a4266b06035455b92f3a85a2e9Jean Chalard sp = job.runInLocale(res, Locale.ENGLISH); 13017901db6910317a4266b06035455b92f3a85a2e9Jean Chalard allPathsForCaps("Word? ", c | w | s, sp, false); 13117901db6910317a4266b06035455b92f3a85a2e9Jean Chalard allPathsForCaps("Word?", c | w | s, sp, true); 13217901db6910317a4266b06035455b92f3a85a2e9Jean Chalard allPathsForCaps("Word?", c, sp, false); 13317901db6910317a4266b06035455b92f3a85a2e9Jean Chalard allPathsForCaps("Word! ", c | w | s, sp, false); 13417901db6910317a4266b06035455b92f3a85a2e9Jean Chalard allPathsForCaps("Word!", c | w | s, sp, true); 13517901db6910317a4266b06035455b92f3a85a2e9Jean Chalard allPathsForCaps("Word!", c, sp, false); 13617901db6910317a4266b06035455b92f3a85a2e9Jean Chalard allPathsForCaps("Word; ", c | w, sp, false); 13717901db6910317a4266b06035455b92f3a85a2e9Jean Chalard allPathsForCaps("Word;", c | w, sp, true); 13817901db6910317a4266b06035455b92f3a85a2e9Jean Chalard allPathsForCaps("Word;", c, sp, false); 139b526a894db0f475596abbed56c4b311b5e4904dcJean Chalard // Test for sentence terminators in Greek 140b526a894db0f475596abbed56c4b311b5e4904dcJean Chalard sp = job.runInLocale(res, LocaleUtils.constructLocaleFromString("el")); 141b526a894db0f475596abbed56c4b311b5e4904dcJean Chalard allPathsForCaps("Word? ", c | w | s, sp, false); 142b526a894db0f475596abbed56c4b311b5e4904dcJean Chalard allPathsForCaps("Word?", c | w | s, sp, true); 143b526a894db0f475596abbed56c4b311b5e4904dcJean Chalard allPathsForCaps("Word?", c, sp, false); 144b526a894db0f475596abbed56c4b311b5e4904dcJean Chalard allPathsForCaps("Word! ", c | w | s, sp, false); 145b526a894db0f475596abbed56c4b311b5e4904dcJean Chalard allPathsForCaps("Word!", c | w | s, sp, true); 146b526a894db0f475596abbed56c4b311b5e4904dcJean Chalard allPathsForCaps("Word!", c, sp, false); 147b526a894db0f475596abbed56c4b311b5e4904dcJean Chalard // In Greek ";" is the question mark and it terminates the sentence 148b526a894db0f475596abbed56c4b311b5e4904dcJean Chalard allPathsForCaps("Word; ", c | w | s, sp, false); 149b526a894db0f475596abbed56c4b311b5e4904dcJean Chalard allPathsForCaps("Word;", c | w | s, sp, true); 150b526a894db0f475596abbed56c4b311b5e4904dcJean Chalard allPathsForCaps("Word;", c, sp, false); 151ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka } 152ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka} 153