• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 The Guava Authors
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.google.common.base;
18 
19 import static com.google.common.base.ReflectionFreeAssertThrows.assertThrows;
20 import static com.google.common.truth.Truth.assertThat;
21 
22 import com.google.common.annotations.GwtCompatible;
23 import com.google.common.annotations.GwtIncompatible;
24 import com.google.common.annotations.J2ktIncompatible;
25 import com.google.common.testing.NullPointerTester;
26 import junit.framework.TestCase;
27 
28 /**
29  * Unit test for {@link Strings}.
30  *
31  * @author Kevin Bourrillion
32  */
33 @ElementTypesAreNonnullByDefault
34 @GwtCompatible(emulated = true)
35 public class StringsTest extends TestCase {
testNullToEmpty()36   public void testNullToEmpty() {
37     assertEquals("", Strings.nullToEmpty(null));
38     assertEquals("", Strings.nullToEmpty(""));
39     assertEquals("a", Strings.nullToEmpty("a"));
40   }
41 
testEmptyToNull()42   public void testEmptyToNull() {
43     assertNull(Strings.emptyToNull(null));
44     assertNull(Strings.emptyToNull(""));
45     assertEquals("a", Strings.emptyToNull("a"));
46   }
47 
testIsNullOrEmpty()48   public void testIsNullOrEmpty() {
49     assertTrue(Strings.isNullOrEmpty(null));
50     assertTrue(Strings.isNullOrEmpty(""));
51     assertFalse(Strings.isNullOrEmpty("a"));
52   }
53 
testPadStart_noPadding()54   public void testPadStart_noPadding() {
55     assertSame("", Strings.padStart("", 0, '-'));
56     assertSame("x", Strings.padStart("x", 0, '-'));
57     assertSame("x", Strings.padStart("x", 1, '-'));
58     assertSame("xx", Strings.padStart("xx", 0, '-'));
59     assertSame("xx", Strings.padStart("xx", 2, '-'));
60   }
61 
testPadStart_somePadding()62   public void testPadStart_somePadding() {
63     assertEquals("-", Strings.padStart("", 1, '-'));
64     assertEquals("--", Strings.padStart("", 2, '-'));
65     assertEquals("-x", Strings.padStart("x", 2, '-'));
66     assertEquals("--x", Strings.padStart("x", 3, '-'));
67     assertEquals("-xx", Strings.padStart("xx", 3, '-'));
68   }
69 
testPadStart_negativeMinLength()70   public void testPadStart_negativeMinLength() {
71     assertSame("x", Strings.padStart("x", -1, '-'));
72   }
73 
74   // TODO: could remove if we got NPT working in GWT somehow
testPadStart_null()75   public void testPadStart_null() {
76     assertThrows(NullPointerException.class, () -> Strings.padStart(null, 5, '0'));
77   }
78 
testPadEnd_noPadding()79   public void testPadEnd_noPadding() {
80     assertSame("", Strings.padEnd("", 0, '-'));
81     assertSame("x", Strings.padEnd("x", 0, '-'));
82     assertSame("x", Strings.padEnd("x", 1, '-'));
83     assertSame("xx", Strings.padEnd("xx", 0, '-'));
84     assertSame("xx", Strings.padEnd("xx", 2, '-'));
85   }
86 
testPadEnd_somePadding()87   public void testPadEnd_somePadding() {
88     assertEquals("-", Strings.padEnd("", 1, '-'));
89     assertEquals("--", Strings.padEnd("", 2, '-'));
90     assertEquals("x-", Strings.padEnd("x", 2, '-'));
91     assertEquals("x--", Strings.padEnd("x", 3, '-'));
92     assertEquals("xx-", Strings.padEnd("xx", 3, '-'));
93   }
94 
testPadEnd_negativeMinLength()95   public void testPadEnd_negativeMinLength() {
96     assertSame("x", Strings.padEnd("x", -1, '-'));
97   }
98 
testPadEnd_null()99   public void testPadEnd_null() {
100     assertThrows(NullPointerException.class, () -> Strings.padEnd(null, 5, '0'));
101   }
102 
103   @SuppressWarnings("InlineMeInliner") // test of method that doesn't just delegate
testRepeat()104   public void testRepeat() {
105     String input = "20";
106     assertEquals("", Strings.repeat(input, 0));
107     assertEquals("20", Strings.repeat(input, 1));
108     assertEquals("2020", Strings.repeat(input, 2));
109     assertEquals("202020", Strings.repeat(input, 3));
110 
111     assertEquals("", Strings.repeat("", 4));
112 
113     for (int i = 0; i < 100; ++i) {
114       assertEquals(2 * i, Strings.repeat(input, i).length());
115     }
116 
117     assertThrows(IllegalArgumentException.class, () -> Strings.repeat("x", -1));
118     assertThrows(
119         ArrayIndexOutOfBoundsException.class, () -> Strings.repeat("12345678", (1 << 30) + 3));
120   }
121 
122   @SuppressWarnings("InlineMeInliner") // test of method that doesn't just delegate
testRepeat_null()123   public void testRepeat_null() {
124     assertThrows(NullPointerException.class, () -> Strings.repeat(null, 5));
125   }
126 
127   @SuppressWarnings("UnnecessaryStringBuilder") // We want to test a non-String CharSequence
testCommonPrefix()128   public void testCommonPrefix() {
129     assertEquals("", Strings.commonPrefix("", ""));
130     assertEquals("", Strings.commonPrefix("abc", ""));
131     assertEquals("", Strings.commonPrefix("", "abc"));
132     assertEquals("", Strings.commonPrefix("abcde", "xyz"));
133     assertEquals("", Strings.commonPrefix("xyz", "abcde"));
134     assertEquals("", Strings.commonPrefix("xyz", "abcxyz"));
135     assertEquals("a", Strings.commonPrefix("abc", "aaaaa"));
136     assertEquals("aa", Strings.commonPrefix("aa", "aaaaa"));
137     assertEquals("abc", Strings.commonPrefix(new StringBuilder("abcdef"), "abcxyz"));
138 
139     // Identical valid surrogate pairs.
140     assertEquals(
141         "abc\uD8AB\uDCAB", Strings.commonPrefix("abc\uD8AB\uDCABdef", "abc\uD8AB\uDCABxyz"));
142     // Differing valid surrogate pairs.
143     assertEquals("abc", Strings.commonPrefix("abc\uD8AB\uDCABdef", "abc\uD8AB\uDCACxyz"));
144     // One invalid pair.
145     assertEquals("abc", Strings.commonPrefix("abc\uD8AB\uDCABdef", "abc\uD8AB\uD8ABxyz"));
146     // Two identical invalid pairs.
147     assertEquals(
148         "abc\uD8AB\uD8AC", Strings.commonPrefix("abc\uD8AB\uD8ACdef", "abc\uD8AB\uD8ACxyz"));
149     // Two differing invalid pairs.
150     assertEquals("abc\uD8AB", Strings.commonPrefix("abc\uD8AB\uD8ABdef", "abc\uD8AB\uD8ACxyz"));
151     // One orphan high surrogate.
152     assertEquals("", Strings.commonPrefix("\uD8AB\uDCAB", "\uD8AB"));
153     // Two orphan high surrogates.
154     assertEquals("\uD8AB", Strings.commonPrefix("\uD8AB", "\uD8AB"));
155   }
156 
157   @SuppressWarnings("UnnecessaryStringBuilder") // We want to test a non-String CharSequence
testCommonSuffix()158   public void testCommonSuffix() {
159     assertEquals("", Strings.commonSuffix("", ""));
160     assertEquals("", Strings.commonSuffix("abc", ""));
161     assertEquals("", Strings.commonSuffix("", "abc"));
162     assertEquals("", Strings.commonSuffix("abcde", "xyz"));
163     assertEquals("", Strings.commonSuffix("xyz", "abcde"));
164     assertEquals("", Strings.commonSuffix("xyz", "xyzabc"));
165     assertEquals("c", Strings.commonSuffix("abc", "ccccc"));
166     assertEquals("aa", Strings.commonSuffix("aa", "aaaaa"));
167     assertEquals("abc", Strings.commonSuffix(new StringBuilder("xyzabc"), "xxxabc"));
168 
169     // Identical valid surrogate pairs.
170     assertEquals(
171         "\uD8AB\uDCABdef", Strings.commonSuffix("abc\uD8AB\uDCABdef", "xyz\uD8AB\uDCABdef"));
172     // Differing valid surrogate pairs.
173     assertEquals("def", Strings.commonSuffix("abc\uD8AB\uDCABdef", "abc\uD8AC\uDCABdef"));
174     // One invalid pair.
175     assertEquals("def", Strings.commonSuffix("abc\uD8AB\uDCABdef", "xyz\uDCAB\uDCABdef"));
176     // Two identical invalid pairs.
177     assertEquals(
178         "\uD8AB\uD8ABdef", Strings.commonSuffix("abc\uD8AB\uD8ABdef", "xyz\uD8AB\uD8ABdef"));
179     // Two differing invalid pairs.
180     assertEquals("\uDCABdef", Strings.commonSuffix("abc\uDCAB\uDCABdef", "abc\uDCAC\uDCABdef"));
181     // One orphan low surrogate.
182     assertEquals("", Strings.commonSuffix("x\uD8AB\uDCAB", "\uDCAB"));
183     // Two orphan low surrogates.
184     assertEquals("\uDCAB", Strings.commonSuffix("\uDCAB", "\uDCAB"));
185   }
186 
testValidSurrogatePairAt()187   public void testValidSurrogatePairAt() {
188     assertTrue(Strings.validSurrogatePairAt("\uD8AB\uDCAB", 0));
189     assertTrue(Strings.validSurrogatePairAt("abc\uD8AB\uDCAB", 3));
190     assertTrue(Strings.validSurrogatePairAt("abc\uD8AB\uDCABxyz", 3));
191     assertFalse(Strings.validSurrogatePairAt("\uD8AB\uD8AB", 0));
192     assertFalse(Strings.validSurrogatePairAt("\uDCAB\uDCAB", 0));
193     assertFalse(Strings.validSurrogatePairAt("\uD8AB\uDCAB", -1));
194     assertFalse(Strings.validSurrogatePairAt("\uD8AB\uDCAB", 1));
195     assertFalse(Strings.validSurrogatePairAt("\uD8AB\uDCAB", -2));
196     assertFalse(Strings.validSurrogatePairAt("\uD8AB\uDCAB", 2));
197     assertFalse(Strings.validSurrogatePairAt("x\uDCAB", 0));
198     assertFalse(Strings.validSurrogatePairAt("\uD8ABx", 0));
199   }
200 
201   @SuppressWarnings("LenientFormatStringValidation") // Intentional for testing.
testLenientFormat()202   public void testLenientFormat() {
203     assertEquals("%s", Strings.lenientFormat("%s"));
204     assertEquals("5", Strings.lenientFormat("%s", 5));
205     assertEquals("foo [5]", Strings.lenientFormat("foo", 5));
206     assertEquals("foo [5, 6, 7]", Strings.lenientFormat("foo", 5, 6, 7));
207     assertEquals("%s 1 2", Strings.lenientFormat("%s %s %s", "%s", 1, 2));
208     assertEquals(" [5, 6]", Strings.lenientFormat("", 5, 6));
209     assertEquals("123", Strings.lenientFormat("%s%s%s", 1, 2, 3));
210     assertEquals("1%s%s", Strings.lenientFormat("%s%s%s", 1));
211     assertEquals("5 + 6 = 11", Strings.lenientFormat("%s + 6 = 11", 5));
212     assertEquals("5 + 6 = 11", Strings.lenientFormat("5 + %s = 11", 6));
213     assertEquals("5 + 6 = 11", Strings.lenientFormat("5 + 6 = %s", 11));
214     assertEquals("5 + 6 = 11", Strings.lenientFormat("%s + %s = %s", 5, 6, 11));
215     assertEquals("null [null, null]", Strings.lenientFormat("%s", null, null, null));
216     assertEquals("null [5, 6]", Strings.lenientFormat(null, 5, 6));
217     assertEquals("null", Strings.lenientFormat("%s", (Object) null));
218   }
219 
220   @J2ktIncompatible // TODO(b/319404022): Allow passing null array as varargs
testLenientFormat_nullArrayVarargs()221   public void testLenientFormat_nullArrayVarargs() {
222     assertEquals("(Object[])null", Strings.lenientFormat("%s", (Object[]) null));
223   }
224 
225   @GwtIncompatible // GWT reflection includes less data
testLenientFormat_badArgumentToString()226   public void testLenientFormat_badArgumentToString() {
227     assertThat(Strings.lenientFormat("boiler %s plate", new ThrowsOnToString()))
228         .matches(
229             // J2kt nested class name does not use "$"
230             "boiler <com\\.google\\.common\\.base\\.StringsTest[.$]ThrowsOnToString@[0-9a-f]+ "
231                 + "threw java\\.lang\\.UnsupportedOperationException> plate");
232   }
233 
testLenientFormat_badArgumentToString_gwtFriendly()234   public void testLenientFormat_badArgumentToString_gwtFriendly() {
235     assertThat(Strings.lenientFormat("boiler %s plate", new ThrowsOnToString()))
236         .matches("boiler <.*> plate");
237   }
238 
239   private static class ThrowsOnToString {
240     @Override
toString()241     public String toString() {
242       throw new UnsupportedOperationException();
243     }
244   }
245 
246   @J2ktIncompatible
247   @GwtIncompatible // NullPointerTester
testNullPointers()248   public void testNullPointers() {
249     NullPointerTester tester = new NullPointerTester();
250     tester.testAllPublicStaticMethods(Strings.class);
251   }
252 }
253