xref: /aosp_15_r20/cts/tests/tests/text/src/android/text/cts/MakeSafeForPresentationTest.java (revision b7c941bb3fa97aba169d73cee0bed2de8ac964bf)
1 /*
2  * Copyright (C) 2018 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 android.text.cts;
18 
19 import static android.text.TextUtils.SAFE_STRING_FLAG_FIRST_LINE;
20 import static android.text.TextUtils.SAFE_STRING_FLAG_SINGLE_LINE;
21 import static android.text.TextUtils.SAFE_STRING_FLAG_TRIM;
22 import static android.text.TextUtils.makeSafeForPresentation;
23 
24 import static org.junit.Assert.assertEquals;
25 import static org.junit.Assert.assertTrue;
26 
27 import org.junit.Test;
28 
29 public class MakeSafeForPresentationTest {
30     private static final String LONG_STRING = "Lorem ipsum dolor sit amet, consectetur adipiscing "
31             + "elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim "
32             + "ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
33             + "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse "
34             + "cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non "
35             + "proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
36 
37     private static final String VERY_LONG_STRING = LONG_STRING + LONG_STRING + LONG_STRING
38             + LONG_STRING + LONG_STRING + LONG_STRING + LONG_STRING + LONG_STRING + LONG_STRING
39             + LONG_STRING + LONG_STRING + LONG_STRING + LONG_STRING + LONG_STRING + LONG_STRING;
40 
41     private static final int DEFAULT_MAX_LABEL_SIZE_PX = 500;
42 
43     /**
44      * Convert a string into a list of code-points
45      */
strToCodePoints(String in)46     private static String strToCodePoints(String in) {
47         StringBuilder out = new StringBuilder();
48         int offset = 0;
49         while (offset < in.length()) {
50             if (out.length() != 0) {
51                 out.append(", ");
52             }
53             int charCount = Character.charCount(in.codePointAt(offset));
54             out.append(Integer.toHexString(in.codePointAt(offset))).append("=\"")
55                     .append(in.substring(offset, offset + charCount)).append("\"");
56             offset += charCount;
57         }
58 
59         return out.toString();
60     }
61 
62     /**
63      * Assert that {@code a.equals(b)} and if not throw a nicely formatted error.
64      *
65      * @param a First string to compare
66      * @param b String to compare first string to
67      */
assertStringEquals(String a, CharSequence b)68     private static void assertStringEquals(String a, CharSequence b) {
69         if (a.equals(b.toString())) {
70             return;
71         }
72 
73         throw new AssertionError("[" + strToCodePoints(a) + "] != ["
74                 + strToCodePoints(b.toString()) + "]");
75     }
76 
77     /**
78      * Make sure {@code abbreviated} is an abbreviation of {@code full}.
79      *
80      * @param full        The non-abbreviated string
81      * @param abbreviated The abbreviated string
82      * @return {@code true} iff the string was abbreviated
83      */
isAbbreviation(String full, CharSequence abbreviated)84     private static boolean isAbbreviation(String full, CharSequence abbreviated) {
85         String abbrStr = abbreviated.toString();
86         int abbrLength = abbrStr.length();
87         int offset = 0;
88 
89         while (offset < abbrLength) {
90             final int abbrCodePoint = abbrStr.codePointAt(offset);
91             final int fullCodePoint = full.codePointAt(offset);
92             final int codePointLen = Character.charCount(abbrCodePoint);
93 
94             if (abbrCodePoint != fullCodePoint) {
95                 return (abbrLength == offset + codePointLen)
96                         && (/* ellipses */8230 == (abbrStr.codePointAt(offset)));
97             }
98 
99             offset += codePointLen;
100         }
101 
102         return false;
103     }
104 
105     @Test
removeIllegal()106     public void removeIllegal() {
107         assertStringEquals("ab", makeSafeForPresentation("a&#x8;b", 0, 0, 0));
108     }
109 
110     @Test
convertHTMLCharacters()111     public void convertHTMLCharacters() {
112         assertStringEquals("a&b", makeSafeForPresentation("a&amp;b", 0, 0, 0));
113     }
114 
115     @Test
convertHTMLGTAndLT()116     public void convertHTMLGTAndLT() {
117         assertStringEquals("a<br>b", makeSafeForPresentation("a&lt;br&gt;b", 0, 0, 0));
118     }
119 
120     @Test
removeHTMLFormatting()121     public void removeHTMLFormatting() {
122         assertStringEquals("ab", makeSafeForPresentation("a<b>b</>", 0, 0, 0));
123     }
124 
125     @Test
replaceImgTags()126     public void replaceImgTags() {
127         assertStringEquals("a\ufffcb", makeSafeForPresentation("a<img src=\"myimg.jpg\" />b", 0, 0,
128                 0));
129     }
130 
131     @Test
replacePTags()132     public void replacePTags() {
133         assertStringEquals("a\n\nb\n\n", makeSafeForPresentation("a<p>b", 0, 0, 0));
134     }
135 
136     @Test
aTagIsIgnored()137     public void aTagIsIgnored() {
138         assertStringEquals("ab", makeSafeForPresentation("a<a href=\"foo.bar\">b</a>", 0, 0, 0));
139     }
140 
141     @Test
leadingAndMoreThanOneTrailingSpacesAreAlwaysTrimmed()142     public void leadingAndMoreThanOneTrailingSpacesAreAlwaysTrimmed() {
143         assertStringEquals("ab ", makeSafeForPresentation("    ab    ", 0, 0, 0));
144     }
145 
146     @Test
preIsIgnored()147     public void preIsIgnored() {
148         assertStringEquals("a b ", makeSafeForPresentation("<pre>  a\n b   </pre>", 0, 0, 0));
149     }
150 
151     @Test
removeSpecialNotHtmlCharacters()152     public void removeSpecialNotHtmlCharacters() {
153         assertStringEquals("ab", makeSafeForPresentation("a\bb", 0, 0, 0));
154     }
155 
156     @Test
collapseInternalConsecutiveSpaces()157     public void collapseInternalConsecutiveSpaces() {
158         assertStringEquals("a b", makeSafeForPresentation("a  b", 0, 0, 0));
159     }
160 
161     @Test
replaceNonHtmlNewLineWithSpace()162     public void replaceNonHtmlNewLineWithSpace() {
163         assertStringEquals("a b", makeSafeForPresentation("a\nb", 0, 0, 0));
164     }
165 
166     @Test
keepNewLines()167     public void keepNewLines() {
168         assertStringEquals("a\nb", makeSafeForPresentation("a<br/>b", 0, 0, 0));
169     }
170 
171     @Test
removeNewLines()172     public void removeNewLines() {
173         assertStringEquals("ab", makeSafeForPresentation("a<br/>b", 0, 0,
174                 SAFE_STRING_FLAG_SINGLE_LINE));
175     }
176 
177     @Test
truncateAtNewLine()178     public void truncateAtNewLine() {
179         assertStringEquals("a", makeSafeForPresentation("a<br/>b", 0, 0,
180                 SAFE_STRING_FLAG_FIRST_LINE));
181     }
182 
183     @Test
nbspIsTrimmed()184     public void nbspIsTrimmed() {
185         /*
186          * A non breaking white space "&nbsp;" in HTML is not a white space according to
187          * Character.isWhitespace, but for clean string it is treated as shite-space
188          */
189         assertStringEquals("a b", makeSafeForPresentation("&nbsp; a b", 0, 0,
190                 SAFE_STRING_FLAG_TRIM));
191     }
192 
193     @Test
trimFront()194     public void trimFront() {
195         assertStringEquals("a b", makeSafeForPresentation("<br/> <br/> a b", 0, 0,
196                 SAFE_STRING_FLAG_TRIM));
197     }
198 
199     @Test
trimAll()200     public void trimAll() {
201         assertStringEquals("", makeSafeForPresentation(" <br/> <br/> ", 0, 0,
202                 SAFE_STRING_FLAG_TRIM));
203     }
204 
205     @Test
trimEnd()206     public void trimEnd() {
207         assertStringEquals("a b", makeSafeForPresentation("a b <br/> <br/>", 0, 0,
208                 SAFE_STRING_FLAG_TRIM));
209     }
210 
211     @Test
trimBoth()212     public void trimBoth() {
213         assertStringEquals("a b", makeSafeForPresentation("<br/> <br/> a b <br/> <br/>", 0, 0,
214                 SAFE_STRING_FLAG_TRIM));
215     }
216 
217     @Test
ellipsizeShort()218     public void ellipsizeShort() {
219         assertTrue(isAbbreviation(VERY_LONG_STRING, makeSafeForPresentation(VERY_LONG_STRING, 0,
220                 DEFAULT_MAX_LABEL_SIZE_PX, 0)));
221     }
222 
223     @Test
ellipsizeLong()224     public void ellipsizeLong() {
225         assertTrue(isAbbreviation(VERY_LONG_STRING, makeSafeForPresentation(VERY_LONG_STRING, 0,
226                 DEFAULT_MAX_LABEL_SIZE_PX * 20, 0)));
227     }
228 
229     @Test
thousandDipLengthIs50Characters()230     public void thousandDipLengthIs50Characters() {
231         assertEquals(50, makeSafeForPresentation(VERY_LONG_STRING, 0, 1000, 0).length(), 10);
232     }
233 
234     @Test
ellipsizeShouldBeProportional()235     public void ellipsizeShouldBeProportional() {
236         assertEquals(20, (float) makeSafeForPresentation(VERY_LONG_STRING, 0,
237                 DEFAULT_MAX_LABEL_SIZE_PX * 20, 0).length() / makeSafeForPresentation(
238                 VERY_LONG_STRING, 0, DEFAULT_MAX_LABEL_SIZE_PX, 0).length(), 3);
239     }
240 
241     @Test
ignoreLastCharacters()242     public void ignoreLastCharacters() {
243         assertEquals(42, makeSafeForPresentation(VERY_LONG_STRING, 42, 0, 0).length());
244     }
245 
246     @Test
ignoreLastCharactersShortStirng()247     public void ignoreLastCharactersShortStirng() {
248         assertEquals("abc", makeSafeForPresentation("abc", 42, 0, 0));
249     }
250 
251     @Test
ignoreLastCharactersWithTrim()252     public void ignoreLastCharactersWithTrim() {
253         assertEquals("abc", makeSafeForPresentation("abc ", 4, 0, SAFE_STRING_FLAG_TRIM));
254     }
255 
256     @Test
ignoreLastCharactersWithHtml()257     public void ignoreLastCharactersWithHtml() {
258         assertEquals("a\nbcd", makeSafeForPresentation("a<br />bcdef", 10, 0, 0));
259     }
260 
261     @Test
ignoreLastCharactersWithTrailingWhitespace()262     public void ignoreLastCharactersWithTrailingWhitespace() {
263         assertEquals("abc ", makeSafeForPresentation("abc ", 4, 0, 0));
264     }
265 
266     @Test(expected = IllegalArgumentException.class)
cannotKeepAndTruncateNewLines()267     public void cannotKeepAndTruncateNewLines() {
268         makeSafeForPresentation("", 0, 0,
269                 SAFE_STRING_FLAG_SINGLE_LINE | SAFE_STRING_FLAG_FIRST_LINE);
270     }
271 
272     @Test(expected = IllegalArgumentException.class)
invalidFlags()273     public void invalidFlags() {
274         makeSafeForPresentation("", 0, 0, 0xffff);
275     }
276 
277     @Test(expected = IllegalArgumentException.class)
invalidEllipsizeDip()278     public void invalidEllipsizeDip() {
279         makeSafeForPresentation("", 0, -1, 0);
280     }
281 
282     @Test(expected = IllegalArgumentException.class)
invalidMaxCharacters()283     public void invalidMaxCharacters() {
284         makeSafeForPresentation("", -1, 0, 0);
285     }
286 
287     @Test(expected = NullPointerException.class)
nullString()288     public void nullString() {
289         makeSafeForPresentation(null, 0, 0, 0);
290     }
291 }
292