View Javadoc
1   /*
2    * Copyright (c) 2002-2025 Gargoyle Software Inc.
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    * https://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   */
15  package org.htmlunit.util;
16  
17  import static java.nio.charset.StandardCharsets.UTF_8;
18  import static org.junit.Assert.assertEquals;
19  import static org.junit.Assert.assertFalse;
20  import static org.junit.Assert.assertNull;
21  import static org.junit.Assert.assertThrows;
22  import static org.junit.Assert.assertTrue;
23  
24  import org.htmlunit.html.impl.Color;
25  import org.junit.Test;
26  
27  /**
28   * Tests for {@link StringUtils}.
29   *
30   * @author Ronald Brill
31   */
32  public class StringUtilsTest {
33  
34      /**
35       * @throws Exception if the test fails
36       */
37      @Test
38      public void isEmptyString() throws Exception {
39          assertFalse(StringUtils.isEmptyString(null));
40          assertTrue(StringUtils.isEmptyString(""));
41          assertFalse(StringUtils.isEmptyString(" "));
42          assertFalse(StringUtils.isEmptyString("\t"));
43          assertFalse(StringUtils.isEmptyString("\r"));
44          assertFalse(StringUtils.isEmptyString("\n"));
45          assertFalse(StringUtils.isEmptyString("string"));
46      }
47  
48      /**
49       * @throws Exception if the test fails
50       */
51      @Test
52      public void equalsChar() throws Exception {
53          assertFalse(StringUtils.equalsChar('#', null));
54          assertFalse(StringUtils.equalsChar('#', ""));
55          assertFalse(StringUtils.equalsChar('#', " "));
56          assertTrue(StringUtils.equalsChar('#', "#"));
57          assertFalse(StringUtils.equalsChar('#', "##"));
58          assertFalse(StringUtils.equalsChar('#', " #"));
59          assertFalse(StringUtils.equalsChar('#', "# "));
60      }
61  
62      /**
63       * @throws Exception if the test fails
64       */
65      @Test
66      public void startsWithIgnoreCase() throws Exception {
67          assertTrue(StringUtils.startsWithIgnoreCase("abcd", "ab"));
68          assertTrue(StringUtils.startsWithIgnoreCase("abcd", "abcd"));
69          assertTrue(StringUtils.startsWithIgnoreCase("abcd", "AB"));
70          assertTrue(StringUtils.startsWithIgnoreCase("Abcd", "abCd"));
71  
72          assertFalse(StringUtils.startsWithIgnoreCase("AB", "x"));
73          assertFalse(StringUtils.startsWithIgnoreCase("AB", "xxzOO"));
74          assertFalse(StringUtils.startsWithIgnoreCase("", "x"));
75          assertFalse(StringUtils.startsWithIgnoreCase("abcd", "bc"));
76  
77          assertFalse(StringUtils.startsWithIgnoreCase(null, "x"));
78  
79          assertThrows(IllegalArgumentException.class, () -> StringUtils.startsWithIgnoreCase("AB", null));
80          assertThrows(IllegalArgumentException.class, () -> StringUtils.startsWithIgnoreCase("AB", ""));
81          assertThrows(IllegalArgumentException.class, () -> StringUtils.startsWithIgnoreCase("", ""));
82      }
83  
84      /**
85       * @throws Exception if the test fails
86       */
87      @Test
88      public void asColorHexadecimal() throws Exception {
89          assertNull(StringUtils.asColorHexadecimal(null));
90          assertNull(StringUtils.asColorHexadecimal(""));
91          assertNull(StringUtils.asColorHexadecimal("    "));
92  
93          assertNull(StringUtils.asColorHexadecimal("#a1"));
94          assertEquals(new Color(0, 17, 170), StringUtils.asColorHexadecimal("#0011aa"));
95          assertEquals(new Color(0, 17, 170), StringUtils.asColorHexadecimal("#01A"));
96      }
97  
98      /**
99       * @throws Exception if the test fails
100      */
101     @Test
102     public void findColorRGB() throws Exception {
103         assertNull(StringUtils.findColorRGB(null));
104         assertNull(StringUtils.findColorRGB(""));
105         assertNull(StringUtils.findColorRGB("    "));
106 
107         assertNull(StringUtils.findColorRGB("#a1"));
108         assertNull(StringUtils.findColorRGB("rgb(1,12,256)"));
109         assertNull(StringUtils.findColorRGB("rgb(1,256,7)"));
110         assertNull(StringUtils.findColorRGB("rgb(256,13,7)"));
111 
112         assertEquals(new Color(1, 12, 13), StringUtils.findColorRGB("rgb(1,12,13)"));
113         assertEquals(new Color(1, 12, 13), StringUtils.findColorRGB("rgb(  1, \t12, 13  )"));
114         assertEquals(new Color(1, 12, 13), StringUtils.findColorRGB("beforergb(1,12,13)after"));
115     }
116 
117     /**
118      * @throws Exception if the test fails
119      */
120     @Test
121     public void findColorRGBA() throws Exception {
122         assertNull(StringUtils.findColorRGBA(null));
123         assertNull(StringUtils.findColorRGBA(""));
124         assertNull(StringUtils.findColorRGBA("    "));
125 
126         assertNull(StringUtils.findColorRGBA("#a1"));
127         assertNull(StringUtils.findColorRGBA("rgba(1,12,256, .1)"));
128 
129         assertEquals(new Color(1, 12, 13), StringUtils.findColorRGBA("rgba(1,12,13, 1)"));
130         assertEquals(new Color(1, 12, 17, 25), StringUtils.findColorRGBA("rgba(1, 12, 17, 0.1)"));
131         assertEquals(new Color(1, 12, 17, 25), StringUtils.findColorRGBA("rgba(1, 12, 17, .1)"));
132         assertEquals(new Color(1, 12, 13, 127), StringUtils.findColorRGBA("beforergba(1,12,13,0.5)after"));
133     }
134 
135     /**
136      * @throws Exception if the test fails
137      */
138     @Test
139     public void findColorHSL() throws Exception {
140         assertNull(StringUtils.findColorHSL(null));
141         assertNull(StringUtils.findColorHSL(""));
142         assertNull(StringUtils.findColorHSL("    "));
143 
144         assertNull(StringUtils.findColorHSL("#a1"));
145         assertNull(StringUtils.findColorHSL("hsl(1,12,256, .1)"));
146 
147         assertEquals(new Color(255, 0, 0), StringUtils.findColorHSL("hsl(0, 100%, 50%)"));
148         assertEquals(new Color(255, 85, 0), StringUtils.findColorHSL("hsl(20, 100%, 50%)"));
149         assertEquals(new Color(204, 68, 0), StringUtils.findColorHSL("hsl(20, 100%, 40%)"));
150         assertEquals(new Color(51, 153, 153), StringUtils.findColorHSL("hsl( 180 ,50%, 40% )"));
151         assertEquals(new Color(51, 153, 153), StringUtils.findColorHSL("beforehsl(180,50%,40%)after"));
152 
153         assertEquals(new Color(37, 58, 59), StringUtils.findColorHSL("hsl(181 , 22%, 19% )"));
154         assertEquals(new Color(38, 60, 60), StringUtils.findColorHSL("hsl(180.75 , 22.3%, 19.3333% )"));
155     }
156 
157     /**
158      * @throws Exception if the test fails
159      */
160     @Test
161     public void formatColor() throws Exception {
162         assertEquals("rgb(1, 12, 13)", StringUtils.formatColor(new Color(1, 12, 13)));
163     }
164 
165     /**
166      * Test for method {@link StringUtils#sanitizeForAppendReplacement(String)}.
167      */
168     @Test
169     public void sanitizeForAppendReplacement() {
170         assertNull(StringUtils.sanitizeForAppendReplacement(null));
171         assertEquals("", StringUtils.sanitizeForAppendReplacement(""));
172         assertEquals("aBc", StringUtils.sanitizeForAppendReplacement("aBc"));
173 
174         assertEquals("\\$1", StringUtils.sanitizeForAppendReplacement("$1"));
175         assertEquals("\\$1\\$2 \\$3", StringUtils.sanitizeForAppendReplacement("$1$2 $3"));
176         assertEquals("\\\\1", StringUtils.sanitizeForAppendReplacement("\\1"));
177         assertEquals("\\\\1\\$2 \\\\3", StringUtils.sanitizeForAppendReplacement("\\1$2 \\3"));
178     }
179 
180     /**
181      * Test for method {@link StringUtils#sanitizeForFileName(String)}.
182      */
183     @Test
184     public void sanitizeForFileName() {
185         assertEquals("HtmlUnit", StringUtils.sanitizeForFileName("HtmlUnit"));
186         assertEquals("Html_Uni_", StringUtils.sanitizeForFileName("Html:Uni\t"));
187         assertEquals("Html_Unit", StringUtils.sanitizeForFileName("Html\\Unit"));
188     }
189 
190     /**
191      * @throws Exception if the test fails
192      */
193     @Test
194     public void stringToByteArray() throws Exception {
195         byte[] result = StringUtils.toByteArray(null, UTF_8);
196         assertEquals(0, result.length);
197 
198         result = StringUtils.toByteArray("", UTF_8);
199         assertEquals(0, result.length);
200 
201         result = StringUtils.toByteArray("htmlunit", UTF_8);
202         assertEquals(8, result.length);
203         assertEquals(104, result[0]);
204     }
205 
206     /**
207      * @throws Exception if the test fails
208      */
209     @Test
210     public void escapeXmlAttributeValue() throws Exception {
211         final StringBuilder sb = new StringBuilder();
212         for (int i = 0; i < 1024; i++) {
213             sb.append((char) i);
214         }
215 
216         final StringBuilder expected = new StringBuilder("\t\n\r");
217         for (int i = 32; i < 1024; i++) {
218             if (i == '&') {
219                 expected.append("&amp;");
220             }
221             else if (i == '<') {
222                 expected.append("&lt;");
223             }
224             else if (i == '"') {
225                 expected.append("&quot;");
226             }
227             else {
228                 expected.append((char) i);
229             }
230         }
231 
232         assertEquals(expected.toString(), StringUtils.escapeXmlAttributeValue(sb.toString()));
233     }
234 
235     /**
236      * @throws Exception if the test fails
237      */
238     @Test
239     public void escapeXmlAttributeValueBorderCases() throws Exception {
240         assertEquals(null, StringUtils.escapeXmlAttributeValue(null));
241         assertEquals("", StringUtils.escapeXmlAttributeValue(""));
242 
243         // [#x20-#xD7FF]
244         assertEquals("", StringUtils.escapeXmlAttributeValue("\u001f"));
245         assertEquals("\u0020", StringUtils.escapeXmlAttributeValue("\u0020"));
246         assertEquals("\u0021", StringUtils.escapeXmlAttributeValue("\u0021"));
247 
248         assertEquals("\uD7FE", StringUtils.escapeXmlAttributeValue("\uD7FE"));
249         assertEquals("\uD7FF", StringUtils.escapeXmlAttributeValue("\uD7FF"));
250         assertEquals("", StringUtils.escapeXmlAttributeValue("\uD800"));
251 
252         // [#xE000-#xFFFD]
253         assertEquals("", StringUtils.escapeXmlAttributeValue("\uDFFF"));
254         assertEquals("\uE000", StringUtils.escapeXmlAttributeValue("\uE000"));
255         assertEquals("\uE001", StringUtils.escapeXmlAttributeValue("\uE001"));
256 
257         assertEquals("\uFFFC", StringUtils.escapeXmlAttributeValue("\uFFFC"));
258         assertEquals("\uFFFD", StringUtils.escapeXmlAttributeValue("\uFFFD"));
259         assertEquals("", StringUtils.escapeXmlAttributeValue("\uFFFE"));
260 
261         // [#x10000-#x10FFFF]
262     }
263 
264     /**
265      * @throws Exception if the test fails
266      */
267     @Test
268     public void escapeXml() throws Exception {
269         final StringBuilder sb = new StringBuilder();
270         for (int i = 0; i < 1024; i++) {
271             sb.append((char) i);
272         }
273 
274         final StringBuilder expected = new StringBuilder("\t\n\r");
275         for (int i = 32; i < 1024; i++) {
276             if (i == '&') {
277                 expected.append("&amp;");
278             }
279             else if (i == '<') {
280                 expected.append("&lt;");
281             }
282             else if (i == '>') {
283                 expected.append("&gt;");
284             }
285             else if (i == '\'') {
286                 expected.append("&apos;");
287             }
288             else if (i == '"') {
289                 expected.append("&quot;");
290             }
291             else {
292                 expected.append((char) i);
293             }
294         }
295 
296         assertEquals(expected.toString(), StringUtils.escapeXml(sb.toString()));
297     }
298 
299     /**
300      * @throws Exception if the test fails
301      */
302     @Test
303     public void escapeXmlBorderCases() throws Exception {
304         assertEquals(null, StringUtils.escapeXml(null));
305         assertEquals("", StringUtils.escapeXml(""));
306 
307         // [#x20-#xD7FF]
308         assertEquals("", StringUtils.escapeXml("\u001f"));
309         assertEquals("\u0020", StringUtils.escapeXml("\u0020"));
310         assertEquals("\u0021", StringUtils.escapeXml("\u0021"));
311 
312         assertEquals("\uD7FE", StringUtils.escapeXml("\uD7FE"));
313         assertEquals("\uD7FF", StringUtils.escapeXml("\uD7FF"));
314         assertEquals("", StringUtils.escapeXml("\uD800"));
315 
316         // [#xE000-#xFFFD]
317         assertEquals("", StringUtils.escapeXml("\uDFFF"));
318         assertEquals("\uE000", StringUtils.escapeXml("\uE000"));
319         assertEquals("\uE001", StringUtils.escapeXml("\uE001"));
320 
321         assertEquals("\uFFFC", StringUtils.escapeXml("\uFFFC"));
322         assertEquals("\uFFFD", StringUtils.escapeXml("\uFFFD"));
323         assertEquals("", StringUtils.escapeXml("\uFFFE"));
324 
325         // [#x10000-#x10FFFF]
326     }
327 }