1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.inputmethod.latin.utils;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertTrue;
21 
22 import android.content.res.Resources;
23 import android.text.TextUtils;
24 
25 import androidx.test.InstrumentationRegistry;
26 import androidx.test.filters.SmallTest;
27 import androidx.test.runner.AndroidJUnit4;
28 
29 import com.android.inputmethod.latin.common.LocaleUtils;
30 import com.android.inputmethod.latin.settings.SpacingAndPunctuations;
31 
32 import org.junit.Test;
33 import org.junit.runner.RunWith;
34 
35 import java.util.Locale;
36 
37 @SmallTest
38 @RunWith(AndroidJUnit4.class)
39 public class CapsModeUtilsTests {
onePathForCaps(final CharSequence cs, final int expectedResult, final int mask, final SpacingAndPunctuations sp, final boolean hasSpaceBefore)40     private static void onePathForCaps(final CharSequence cs, final int expectedResult,
41             final int mask, final SpacingAndPunctuations sp, final boolean hasSpaceBefore) {
42         final int oneTimeResult = expectedResult & mask;
43         assertEquals("After >" + cs + "<", oneTimeResult,
44                 CapsModeUtils.getCapsMode(cs, mask, sp, hasSpaceBefore));
45     }
46 
allPathsForCaps(final CharSequence cs, final int expectedResult, final SpacingAndPunctuations sp, final boolean hasSpaceBefore)47     private static void allPathsForCaps(final CharSequence cs, final int expectedResult,
48             final SpacingAndPunctuations sp, final boolean hasSpaceBefore) {
49         final int c = TextUtils.CAP_MODE_CHARACTERS;
50         final int w = TextUtils.CAP_MODE_WORDS;
51         final int s = TextUtils.CAP_MODE_SENTENCES;
52         onePathForCaps(cs, expectedResult, c | w | s, sp, hasSpaceBefore);
53         onePathForCaps(cs, expectedResult, w | s, sp, hasSpaceBefore);
54         onePathForCaps(cs, expectedResult, c | s, sp, hasSpaceBefore);
55         onePathForCaps(cs, expectedResult, c | w, sp, hasSpaceBefore);
56         onePathForCaps(cs, expectedResult, c, sp, hasSpaceBefore);
57         onePathForCaps(cs, expectedResult, w, sp, hasSpaceBefore);
58         onePathForCaps(cs, expectedResult, s, sp, hasSpaceBefore);
59     }
60 
61     @Test
testGetCapsMode()62     public void testGetCapsMode() {
63         final int c = TextUtils.CAP_MODE_CHARACTERS;
64         final int w = TextUtils.CAP_MODE_WORDS;
65         final int s = TextUtils.CAP_MODE_SENTENCES;
66         final RunInLocale<SpacingAndPunctuations> job = new RunInLocale<SpacingAndPunctuations>() {
67             @Override
68             protected SpacingAndPunctuations job(final Resources res) {
69                 return new SpacingAndPunctuations(res);
70             }
71         };
72         final Resources res = InstrumentationRegistry.getTargetContext().getResources();
73         SpacingAndPunctuations sp = job.runInLocale(res, Locale.ENGLISH);
74         allPathsForCaps("", c | w | s, sp, false);
75         allPathsForCaps("Word", c, sp, false);
76         allPathsForCaps("Word.", c, sp, false);
77         allPathsForCaps("Word ", c | w, sp, false);
78         allPathsForCaps("Word. ", c | w | s, sp, false);
79         allPathsForCaps("Word..", c, sp, false);
80         allPathsForCaps("Word.. ", c | w | s, sp, false);
81         allPathsForCaps("Word... ", c | w | s, sp, false);
82         allPathsForCaps("Word ... ", c | w | s, sp, false);
83         allPathsForCaps("Word . ", c | w, sp, false);
84         allPathsForCaps("In the U.S ", c | w, sp, false);
85         allPathsForCaps("In the U.S. ", c | w, sp, false);
86         allPathsForCaps("Some stuff (e.g. ", c | w, sp, false);
87         allPathsForCaps("In the U.S.. ", c | w | s, sp, false);
88         allPathsForCaps("\"Word.\" ", c | w | s, sp, false);
89         allPathsForCaps("\"Word\". ", c | w | s, sp, false);
90         allPathsForCaps("\"Word\" ", c | w, sp, false);
91 
92         // Test for phantom space
93         allPathsForCaps("Word", c | w, sp, true);
94         allPathsForCaps("Word.", c | w | s, sp, true);
95 
96         // Tests after some whitespace
97         allPathsForCaps("Word\n", c | w | s, sp, false);
98         allPathsForCaps("Word\n", c | w | s, sp, true);
99         allPathsForCaps("Word\n ", c | w | s, sp, true);
100         allPathsForCaps("Word.\n", c | w | s, sp, false);
101         allPathsForCaps("Word.\n", c | w | s, sp, true);
102         allPathsForCaps("Word.\n ", c | w | s, sp, true);
103 
104         sp = job.runInLocale(res, Locale.FRENCH);
105         allPathsForCaps("\"Word.\" ", c | w, sp, false);
106         allPathsForCaps("\"Word\". ", c | w | s, sp, false);
107         allPathsForCaps("\"Word\" ", c | w, sp, false);
108 
109         // Test special case for German. German does not capitalize at the start of a
110         // line when the previous line starts with a comma. It does in other cases.
111         sp = job.runInLocale(res, Locale.GERMAN);
112         allPathsForCaps("Liebe Sara,\n", c | w, sp, false);
113         allPathsForCaps("Liebe Sara,\n", c | w, sp, true);
114         allPathsForCaps("Liebe Sara,  \n  ", c | w, sp, false);
115         allPathsForCaps("Liebe Sara  \n  ", c | w | s, sp, false);
116         allPathsForCaps("Liebe Sara.\n  ", c | w | s, sp, false);
117         sp = job.runInLocale(res, Locale.ENGLISH);
118         allPathsForCaps("Liebe Sara,\n", c | w | s, sp, false);
119         allPathsForCaps("Liebe Sara,\n", c | w | s, sp, true);
120         allPathsForCaps("Liebe Sara,  \n  ", c | w | s, sp, false);
121         allPathsForCaps("Liebe Sara  \n  ", c | w | s, sp, false);
122         allPathsForCaps("Liebe Sara.\n  ", c | w | s, sp, false);
123 
124         // Test armenian period
125         sp = job.runInLocale(res, LocaleUtils.constructLocaleFromString("hy_AM"));
126         assertTrue("Period is not sentence separator in Armenian",
127                 !sp.isSentenceSeparator('.'));
128         assertTrue("Sentence separator is Armenian period in Armenian",
129                 sp.isSentenceSeparator(0x589));
130         // No space : capitalize only if MODE_CHARACTERS
131         allPathsForCaps("Word", c, sp, false);
132         allPathsForCaps("Word.", c, sp, false);
133         // Space, but no armenian period : capitalize if MODE_WORDS but not SENTENCES
134         allPathsForCaps("Word. ", c | w, sp, false);
135         // Armenian period : capitalize if MODE_SENTENCES
136         allPathsForCaps("Word\u0589 ", c | w | s, sp, false);
137 
138         // Test for sentence terminators
139         sp = job.runInLocale(res, Locale.ENGLISH);
140         allPathsForCaps("Word? ", c | w | s, sp, false);
141         allPathsForCaps("Word?", c | w | s, sp, true);
142         allPathsForCaps("Word?", c, sp, false);
143         allPathsForCaps("Word! ", c | w | s, sp, false);
144         allPathsForCaps("Word!", c | w | s, sp, true);
145         allPathsForCaps("Word!", c, sp, false);
146         allPathsForCaps("Word; ", c | w, sp, false);
147         allPathsForCaps("Word;", c | w, sp, true);
148         allPathsForCaps("Word;", c, sp, false);
149         // Test for sentence terminators in Greek
150         sp = job.runInLocale(res, LocaleUtils.constructLocaleFromString("el"));
151         allPathsForCaps("Word? ", c | w | s, sp, false);
152         allPathsForCaps("Word?", c | w | s, sp, true);
153         allPathsForCaps("Word?", c, sp, false);
154         allPathsForCaps("Word! ", c | w | s, sp, false);
155         allPathsForCaps("Word!", c | w | s, sp, true);
156         allPathsForCaps("Word!", c, sp, false);
157         // In Greek ";" is the question mark and it terminates the sentence
158         allPathsForCaps("Word; ", c | w | s, sp, false);
159         allPathsForCaps("Word;", c | w | s, sp, true);
160         allPathsForCaps("Word;", c, sp, false);
161     }
162 }
163