1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.codec.binary;
19
20 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
21 import static org.junit.jupiter.api.Assertions.assertEquals;
22 import static org.junit.jupiter.api.Assertions.assertNull;
23 import static org.junit.jupiter.api.Assertions.assertThrows;
24
25 import java.io.UnsupportedEncodingException;
26 import java.nio.ByteBuffer;
27 import java.nio.charset.Charset;
28 import java.nio.charset.StandardCharsets;
29 import java.util.function.Function;
30 import java.util.stream.Stream;
31
32 import org.junit.jupiter.api.Named;
33 import org.junit.jupiter.api.Test;
34 import org.junit.jupiter.params.ParameterizedTest;
35 import org.junit.jupiter.params.provider.Arguments;
36 import org.junit.jupiter.params.provider.MethodSource;
37
38
39
40
41 class StringUtilsTest {
42
43 private static final byte[] BYTES_FIXTURE = { 'a', 'b', 'c' };
44
45
46 private static final byte[] BYTES_FIXTURE_16BE = { 0, 'a', 0, 'b', 0, 'c' };
47
48
49 private static final byte[] BYTES_FIXTURE_16LE = { 'a', 0, 'b', 0, 'c', 0 };
50
51 private static final String STRING_FIXTURE = "ABC";
52
53 static Stream<Arguments> getBytesCases() {
54 return Stream.of(
55 Arguments.of(StandardCharsets.ISO_8859_1,
56 Named.<Function<String, byte[]>>of("getBytesIso8859_1", StringUtils::getBytesIso8859_1)),
57 Arguments.of(StandardCharsets.US_ASCII,
58 Named.<Function<String, byte[]>>of("getBytesUsAscii", StringUtils::getBytesUsAscii)),
59 Arguments.of(StandardCharsets.UTF_16,
60 Named.<Function<String, byte[]>>of("getBytesUtf16", StringUtils::getBytesUtf16)),
61 Arguments.of(StandardCharsets.UTF_16BE,
62 Named.<Function<String, byte[]>>of("getBytesUtf16Be", StringUtils::getBytesUtf16Be)),
63 Arguments.of(StandardCharsets.UTF_16LE,
64 Named.<Function<String, byte[]>>of("getBytesUtf16Le", StringUtils::getBytesUtf16Le)),
65 Arguments.of(StandardCharsets.UTF_8,
66 Named.<Function<String, byte[]>>of("getBytesUtf8", StringUtils::getBytesUtf8)));
67 }
68
69 static Stream<Arguments> mixedEqualityCases() {
70 return Stream.of(
71 Arguments.of(Named.of("String(abc)", "abc"), Named.of("StringBuilder(abc)", new StringBuilder("abc")), true),
72 Arguments.of(Named.of("StringBuilder(abc)", new StringBuilder("abc")), Named.of("String(abcd)", "abcd"), false),
73 Arguments.of(Named.of("String(abcd)", "abcd"), Named.of("StringBuilder(abc)", new StringBuilder("abc")), false),
74 Arguments.of(Named.of("StringBuilder(abc)", new StringBuilder("abc")), Named.of("String(ABC)", "ABC"), false));
75 }
76
77 static Stream<Arguments> newStringCases() {
78 return Stream.of(
79 Arguments.of(StandardCharsets.ISO_8859_1,
80 Named.<Function<byte[], String>>of("newStringIso8859_1", StringUtils::newStringIso8859_1), BYTES_FIXTURE),
81 Arguments.of(StandardCharsets.US_ASCII,
82 Named.<Function<byte[], String>>of("newStringUsAscii", StringUtils::newStringUsAscii), BYTES_FIXTURE),
83 Arguments.of(StandardCharsets.UTF_16,
84 Named.<Function<byte[], String>>of("newStringUtf16", StringUtils::newStringUtf16), BYTES_FIXTURE),
85 Arguments.of(StandardCharsets.UTF_16BE,
86 Named.<Function<byte[], String>>of("newStringUtf16Be", StringUtils::newStringUtf16Be), BYTES_FIXTURE_16BE),
87 Arguments.of(StandardCharsets.UTF_16LE,
88 Named.<Function<byte[], String>>of("newStringUtf16Le", StringUtils::newStringUtf16Le), BYTES_FIXTURE_16LE),
89 Arguments.of(StandardCharsets.UTF_8,
90 Named.<Function<byte[], String>>of("newStringUtf8", StringUtils::newStringUtf8), BYTES_FIXTURE));
91 }
92
93 static Stream<Named<Function<byte[], String>>> newStringFunctions() {
94 return Stream.of(
95 Named.<Function<byte[], String>>of("newStringIso8859_1", StringUtils::newStringIso8859_1),
96 Named.<Function<byte[], String>>of("newStringUsAscii", StringUtils::newStringUsAscii),
97 Named.<Function<byte[], String>>of("newStringUtf16", StringUtils::newStringUtf16),
98 Named.<Function<byte[], String>>of("newStringUtf16Be", StringUtils::newStringUtf16Be),
99 Named.<Function<byte[], String>>of("newStringUtf16Le", StringUtils::newStringUtf16Le),
100 Named.<Function<byte[], String>>of("newStringUtf8", StringUtils::newStringUtf8));
101 }
102
103 static Stream<Arguments> stringBuilderEqualityCases() {
104 return Stream.of(
105 Arguments.of(Named.of("StringBuilder(abc)", new StringBuilder("abc")), null, false),
106 Arguments.of(null, Named.of("StringBuilder(abc)", new StringBuilder("abc")), false),
107 Arguments.of(Named.of("StringBuilder(abc)", new StringBuilder("abc")), Named.of("StringBuilder(abc)", new StringBuilder("abc")), true),
108 Arguments.of(Named.of("StringBuilder(abc)", new StringBuilder("abc")), Named.of("StringBuilder(abcd)", new StringBuilder("abcd")), false),
109 Arguments.of(Named.of("StringBuilder(abcd)", new StringBuilder("abcd")), Named.of("StringBuilder(abc)", new StringBuilder("abc")), false),
110 Arguments.of(Named.of("StringBuilder(abc)", new StringBuilder("abc")), Named.of("StringBuilder(ABC)", new StringBuilder("ABC")), false));
111 }
112
113 static Stream<Arguments> stringEqualityCases() {
114 return Stream.of(
115 Arguments.of(null, null, true),
116 Arguments.of(Named.of("String(abc)", "abc"), null, false),
117 Arguments.of(null, Named.of("String(abc)", "abc"), false),
118 Arguments.of(Named.of("String(abc)", "abc"), Named.of("String(abc)", "abc"), true),
119 Arguments.of(Named.of("String(abc)", "abc"), Named.of("String(abcd)", "abcd"), false),
120 Arguments.of(Named.of("String(abcd)", "abcd"), Named.of("String(abc)", "abc"), false),
121 Arguments.of(Named.of("String(abc)", "abc"), Named.of("String(ABC)", "ABC"), false));
122 }
123
124 @Test
125 void testByteBufferUtf8() {
126 assertNull(StringUtils.getByteBufferUtf8(null), "Should be null safe");
127 final String text = "asdhjfhsadiogasdjhagsdygfjasfgsdaksjdhfk";
128 final ByteBuffer bb = StringUtils.getByteBufferUtf8(text);
129 assertArrayEquals(text.getBytes(StandardCharsets.UTF_8), bb.array());
130 }
131
132
133
134
135
136 @Test
137 void testConstructor() {
138 new StringUtils();
139 }
140
141 @ParameterizedTest(name = "{0}, {1}: {2}")
142 @MethodSource("mixedEqualityCases")
143 void testEqualsMixedCharSequences(final CharSequence left, final CharSequence right, final boolean expected) {
144 assertEquals(expected, StringUtils.equals(left, right));
145 }
146
147 @ParameterizedTest(name = "{0}, {1}: {2}")
148 @MethodSource("stringBuilderEqualityCases")
149 void testEqualsStringBuilders(final CharSequence left, final CharSequence right, final boolean expected) {
150 assertEquals(expected, StringUtils.equals(left, right));
151 }
152
153 @ParameterizedTest(name = "{0}, {1}: {2}")
154 @MethodSource("stringEqualityCases")
155 void testEqualsStrings(final CharSequence left, final CharSequence right, final boolean expected) {
156 assertEquals(expected, StringUtils.equals(left, right));
157 }
158
159 @ParameterizedTest(name = "{0}: {1}")
160 @MethodSource("getBytesCases")
161 void testGetBytes(final Charset charset, final Function<String, byte[]> encoder) throws UnsupportedEncodingException {
162 final String charsetName = charset.name();
163 final byte[] expected = STRING_FIXTURE.getBytes(charsetName);
164 assertArrayEquals(expected, StringUtils.getBytesUnchecked(STRING_FIXTURE, charsetName));
165 assertArrayEquals(expected, encoder.apply(STRING_FIXTURE));
166 }
167
168 @Test
169 void testGetBytesUncheckedBadName() {
170 assertThrows(IllegalStateException.class, () -> StringUtils.getBytesUnchecked(STRING_FIXTURE, "UNKNOWN"));
171 }
172
173 @Test
174 void testGetBytesUncheckedNullInput() {
175 assertNull(StringUtils.getBytesUnchecked(null, "UNKNOWN"));
176 }
177
178 @ParameterizedTest(name = "{0}: {1}")
179 @MethodSource("newStringCases")
180 void testNewString(final Charset charset, final Function<byte[], String> decoder, final byte[] input) throws UnsupportedEncodingException {
181 final String charsetName = charset.name();
182 assertEquals(new String(BYTES_FIXTURE, charsetName), StringUtils.newString(BYTES_FIXTURE, charsetName));
183 assertEquals(new String(input, charsetName), decoder.apply(input));
184 }
185
186 @Test
187 void testNewStringBadEnc() {
188 assertThrows(IllegalStateException.class, () -> StringUtils.newString(BYTES_FIXTURE, "UNKNOWN"));
189 }
190
191 @Test
192 void testNewStringNullInput() {
193 assertNull(StringUtils.newString(null, "UNKNOWN"));
194 }
195
196 @ParameterizedTest(name = "{0}")
197 @MethodSource("newStringFunctions")
198 void testNewStringNullInput_CODEC229(final Function<byte[], String> decoder) {
199 assertNull(decoder.apply(null));
200 }
201 }