Home | History | Annotate | Download | only in cts
      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      */
     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      */
     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      */
     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
    106     public void removeIllegal() {
    107         assertStringEquals("ab", makeSafeForPresentation("a&#x8;b", 0, 0, 0));
    108     }
    109 
    110     @Test
    111     public void convertHTMLCharacters() {
    112         assertStringEquals("a&b", makeSafeForPresentation("a&amp;b", 0, 0, 0));
    113     }
    114 
    115     @Test
    116     public void convertHTMLGTAndLT() {
    117         assertStringEquals("a<br>b", makeSafeForPresentation("a&lt;br&gt;b", 0, 0, 0));
    118     }
    119 
    120     @Test
    121     public void removeHTMLFormatting() {
    122         assertStringEquals("ab", makeSafeForPresentation("a<b>b</>", 0, 0, 0));
    123     }
    124 
    125     @Test
    126     public void replaceImgTags() {
    127         assertStringEquals("a\ufffcb", makeSafeForPresentation("a<img src=\"myimg.jpg\" />b", 0, 0,
    128                 0));
    129     }
    130 
    131     @Test
    132     public void replacePTags() {
    133         assertStringEquals("a\n\nb\n\n", makeSafeForPresentation("a<p>b", 0, 0, 0));
    134     }
    135 
    136     @Test
    137     public void aTagIsIgnored() {
    138         assertStringEquals("ab", makeSafeForPresentation("a<a href=\"foo.bar\">b</a>", 0, 0, 0));
    139     }
    140 
    141     @Test
    142     public void leadingAndMoreThanOneTrailingSpacesAreAlwaysTrimmed() {
    143         assertStringEquals("ab ", makeSafeForPresentation("    ab    ", 0, 0, 0));
    144     }
    145 
    146     @Test
    147     public void preIsIgnored() {
    148         assertStringEquals("a b ", makeSafeForPresentation("<pre>  a\n b   </pre>", 0, 0, 0));
    149     }
    150 
    151     @Test
    152     public void removeSpecialNotHtmlCharacters() {
    153         assertStringEquals("ab", makeSafeForPresentation("a\bb", 0, 0, 0));
    154     }
    155 
    156     @Test
    157     public void collapseInternalConsecutiveSpaces() {
    158         assertStringEquals("a b", makeSafeForPresentation("a  b", 0, 0, 0));
    159     }
    160 
    161     @Test
    162     public void replaceNonHtmlNewLineWithSpace() {
    163         assertStringEquals("a b", makeSafeForPresentation("a\nb", 0, 0, 0));
    164     }
    165 
    166     @Test
    167     public void keepNewLines() {
    168         assertStringEquals("a\nb", makeSafeForPresentation("a<br/>b", 0, 0, 0));
    169     }
    170 
    171     @Test
    172     public void removeNewLines() {
    173         assertStringEquals("ab", makeSafeForPresentation("a<br/>b", 0, 0,
    174                 SAFE_STRING_FLAG_SINGLE_LINE));
    175     }
    176 
    177     @Test
    178     public void truncateAtNewLine() {
    179         assertStringEquals("a", makeSafeForPresentation("a<br/>b", 0, 0,
    180                 SAFE_STRING_FLAG_FIRST_LINE));
    181     }
    182 
    183     @Test
    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
    194     public void trimFront() {
    195         assertStringEquals("a b", makeSafeForPresentation("<br/> <br/> a b", 0, 0,
    196                 SAFE_STRING_FLAG_TRIM));
    197     }
    198 
    199     @Test
    200     public void trimAll() {
    201         assertStringEquals("", makeSafeForPresentation(" <br/> <br/> ", 0, 0,
    202                 SAFE_STRING_FLAG_TRIM));
    203     }
    204 
    205     @Test
    206     public void trimEnd() {
    207         assertStringEquals("a b", makeSafeForPresentation("a b <br/> <br/>", 0, 0,
    208                 SAFE_STRING_FLAG_TRIM));
    209     }
    210 
    211     @Test
    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
    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
    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
    230     public void thousandDipLengthIs50Characters() {
    231         assertEquals(50, makeSafeForPresentation(VERY_LONG_STRING, 0, 1000, 0).length(), 10);
    232     }
    233 
    234     @Test
    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
    242     public void ignoreLastCharacters() {
    243         assertEquals(42, makeSafeForPresentation(VERY_LONG_STRING, 42, 0, 0).length());
    244     }
    245 
    246     @Test
    247     public void ignoreLastCharactersShortStirng() {
    248         assertEquals("abc", makeSafeForPresentation("abc", 42, 0, 0));
    249     }
    250 
    251     @Test
    252     public void ignoreLastCharactersWithTrim() {
    253         assertEquals("abc", makeSafeForPresentation("abc ", 4, 0, SAFE_STRING_FLAG_TRIM));
    254     }
    255 
    256     @Test
    257     public void ignoreLastCharactersWithHtml() {
    258         assertEquals("a\nbcd", makeSafeForPresentation("a<br />bcdef", 10, 0, 0));
    259     }
    260 
    261     @Test
    262     public void ignoreLastCharactersWithTrailingWhitespace() {
    263         assertEquals("abc ", makeSafeForPresentation("abc ", 4, 0, 0));
    264     }
    265 
    266     @Test(expected = IllegalArgumentException.class)
    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)
    273     public void invalidFlags() {
    274         makeSafeForPresentation("", 0, 0, 0xffff);
    275     }
    276 
    277     @Test(expected = IllegalArgumentException.class)
    278     public void invalidEllipsizeDip() {
    279         makeSafeForPresentation("", 0, -1, 0);
    280     }
    281 
    282     @Test(expected = IllegalArgumentException.class)
    283     public void invalidMaxCharacters() {
    284         makeSafeForPresentation("", -1, 0, 0);
    285     }
    286 
    287     @Test(expected = NullPointerException.class)
    288     public void nullString() {
    289         makeSafeForPresentation(null, 0, 0, 0);
    290     }
    291 }
    292