1 /* 2 * Copyright (C) 2012 The Guava Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the License 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 * or implied. See the License for the specific language governing permissions and limitations under 12 * the License. 13 */ 14 15 package com.google.common.io; 16 17 import static com.google.common.base.Charsets.UTF_8; 18 import static com.google.common.io.BaseEncoding.base16; 19 import static com.google.common.io.BaseEncoding.base32; 20 import static com.google.common.io.BaseEncoding.base32Hex; 21 import static com.google.common.io.BaseEncoding.base64; 22 import static com.google.common.truth.Truth.assertThat; 23 24 import com.google.common.annotations.GwtCompatible; 25 import com.google.common.annotations.GwtIncompatible; 26 import com.google.common.base.Ascii; 27 import com.google.common.base.Joiner; 28 import com.google.common.base.Splitter; 29 import com.google.common.collect.ImmutableList; 30 import com.google.common.io.BaseEncoding.DecodingException; 31 import java.io.IOException; 32 import java.io.InputStream; 33 import java.io.OutputStream; 34 import java.io.StringReader; 35 import java.io.StringWriter; 36 import junit.framework.TestCase; 37 import org.checkerframework.checker.nullness.qual.Nullable; 38 39 /** 40 * Tests for {@code BaseEncoding}. 41 * 42 * @author Louis Wasserman 43 */ 44 @GwtCompatible(emulated = true) 45 public class BaseEncodingTest extends TestCase { 46 testSeparatorsExplicitly()47 public void testSeparatorsExplicitly() { 48 testEncodes(base64().withSeparator("\n", 3), "foobar", "Zm9\nvYm\nFy"); 49 testEncodes(base64().withSeparator("$", 4), "foobar", "Zm9v$YmFy"); 50 testEncodes(base32().withSeparator("*", 4), "foobar", "MZXW*6YTB*OI==*===="); 51 } 52 testSeparatorSameAsPadChar()53 public void testSeparatorSameAsPadChar() { 54 try { 55 base64().withSeparator("=", 3); 56 fail("Expected IllegalArgumentException"); 57 } catch (IllegalArgumentException expected) { 58 } 59 60 try { 61 base64().withPadChar('#').withSeparator("!#!", 3); 62 fail("Expected IllegalArgumentException"); 63 } catch (IllegalArgumentException expected) { 64 } 65 } 66 testAtMostOneSeparator()67 public void testAtMostOneSeparator() { 68 BaseEncoding separated = base64().withSeparator("\n", 3); 69 try { 70 separated.withSeparator("$", 4); 71 fail("Expected UnsupportedOperationException"); 72 } catch (UnsupportedOperationException expected) { 73 } 74 } 75 testBase64()76 public void testBase64() { 77 // The following test vectors are specified in RFC 4648 itself 78 testEncodingWithSeparators(base64(), "", ""); 79 testEncodingWithSeparators(base64(), "f", "Zg=="); 80 testEncodingWithSeparators(base64(), "fo", "Zm8="); 81 testEncodingWithSeparators(base64(), "foo", "Zm9v"); 82 testEncodingWithSeparators(base64(), "foob", "Zm9vYg=="); 83 testEncodingWithSeparators(base64(), "fooba", "Zm9vYmE="); 84 testEncodingWithSeparators(base64(), "foobar", "Zm9vYmFy"); 85 } 86 87 @GwtIncompatible // Reader/Writer testBase64Streaming()88 public void testBase64Streaming() throws IOException { 89 // The following test vectors are specified in RFC 4648 itself 90 testStreamingEncodingWithSeparators(base64(), "", ""); 91 testStreamingEncodingWithSeparators(base64(), "f", "Zg=="); 92 testStreamingEncodingWithSeparators(base64(), "fo", "Zm8="); 93 testStreamingEncodingWithSeparators(base64(), "foo", "Zm9v"); 94 testStreamingEncodingWithSeparators(base64(), "foob", "Zm9vYg=="); 95 testStreamingEncodingWithSeparators(base64(), "fooba", "Zm9vYmE="); 96 testStreamingEncodingWithSeparators(base64(), "foobar", "Zm9vYmFy"); 97 } 98 testBase64LenientPadding()99 public void testBase64LenientPadding() { 100 testDecodes(base64(), "Zg", "f"); 101 testDecodes(base64(), "Zg=", "f"); 102 testDecodes(base64(), "Zg==", "f"); // proper padding length 103 testDecodes(base64(), "Zg===", "f"); 104 testDecodes(base64(), "Zg====", "f"); 105 } 106 testBase64InvalidDecodings()107 public void testBase64InvalidDecodings() { 108 // These contain bytes not in the decodabet. 109 assertFailsToDecode(base64(), "A\u007f", "Unrecognized character: 0x7f"); 110 assertFailsToDecode(base64(), "Wf2!", "Unrecognized character: !"); 111 // This sentence just isn't base64() encoded. 112 assertFailsToDecode(base64(), "let's not talk of love or chains!"); 113 // A 4n+1 length string is never legal base64(). 114 assertFailsToDecode(base64(), "12345", "Invalid input length 5"); 115 // These have a combination of invalid length, unrecognized characters and wrong padding. 116 assertFailsToDecode(base64(), "AB=C", "Unrecognized character: ="); 117 assertFailsToDecode(base64(), "A=BCD", "Invalid input length 5"); 118 assertFailsToDecode(base64(), "?", "Invalid input length 1"); 119 } 120 testBase64CannotUpperCase()121 public void testBase64CannotUpperCase() { 122 try { 123 base64().upperCase(); 124 fail(); 125 } catch (IllegalStateException expected) { 126 // success 127 } 128 } 129 testBase64CannotLowerCase()130 public void testBase64CannotLowerCase() { 131 try { 132 base64().lowerCase(); 133 fail(); 134 } catch (IllegalStateException expected) { 135 // success 136 } 137 } 138 testBase64AlternatePadding()139 public void testBase64AlternatePadding() { 140 BaseEncoding enc = base64().withPadChar('~'); 141 testEncodingWithSeparators(enc, "", ""); 142 testEncodingWithSeparators(enc, "f", "Zg~~"); 143 testEncodingWithSeparators(enc, "fo", "Zm8~"); 144 testEncodingWithSeparators(enc, "foo", "Zm9v"); 145 testEncodingWithSeparators(enc, "foob", "Zm9vYg~~"); 146 testEncodingWithSeparators(enc, "fooba", "Zm9vYmE~"); 147 testEncodingWithSeparators(enc, "foobar", "Zm9vYmFy"); 148 } 149 150 @GwtIncompatible // Reader/Writer testBase64StreamingAlternatePadding()151 public void testBase64StreamingAlternatePadding() throws IOException { 152 BaseEncoding enc = base64().withPadChar('~'); 153 testStreamingEncodingWithSeparators(enc, "", ""); 154 testStreamingEncodingWithSeparators(enc, "f", "Zg~~"); 155 testStreamingEncodingWithSeparators(enc, "fo", "Zm8~"); 156 testStreamingEncodingWithSeparators(enc, "foo", "Zm9v"); 157 testStreamingEncodingWithSeparators(enc, "foob", "Zm9vYg~~"); 158 testStreamingEncodingWithSeparators(enc, "fooba", "Zm9vYmE~"); 159 testStreamingEncodingWithSeparators(enc, "foobar", "Zm9vYmFy"); 160 } 161 testBase64OmitPadding()162 public void testBase64OmitPadding() { 163 BaseEncoding enc = base64().omitPadding(); 164 testEncodingWithSeparators(enc, "", ""); 165 testEncodingWithSeparators(enc, "f", "Zg"); 166 testEncodingWithSeparators(enc, "fo", "Zm8"); 167 testEncodingWithSeparators(enc, "foo", "Zm9v"); 168 testEncodingWithSeparators(enc, "foob", "Zm9vYg"); 169 testEncodingWithSeparators(enc, "fooba", "Zm9vYmE"); 170 testEncodingWithSeparators(enc, "foobar", "Zm9vYmFy"); 171 } 172 173 @GwtIncompatible // Reader/Writer testBase64StreamingOmitPadding()174 public void testBase64StreamingOmitPadding() throws IOException { 175 BaseEncoding enc = base64().omitPadding(); 176 testStreamingEncodingWithSeparators(enc, "", ""); 177 testStreamingEncodingWithSeparators(enc, "f", "Zg"); 178 testStreamingEncodingWithSeparators(enc, "fo", "Zm8"); 179 testStreamingEncodingWithSeparators(enc, "foo", "Zm9v"); 180 testStreamingEncodingWithSeparators(enc, "foob", "Zm9vYg"); 181 testStreamingEncodingWithSeparators(enc, "fooba", "Zm9vYmE"); 182 testStreamingEncodingWithSeparators(enc, "foobar", "Zm9vYmFy"); 183 } 184 testBase64Offset()185 public void testBase64Offset() { 186 testEncodesWithOffset(base64(), "foobar", 0, 6, "Zm9vYmFy"); 187 testEncodesWithOffset(base64(), "foobar", 1, 5, "b29iYXI="); 188 testEncodesWithOffset(base64(), "foobar", 2, 3, "b2Jh"); 189 testEncodesWithOffset(base64(), "foobar", 3, 1, "Yg=="); 190 testEncodesWithOffset(base64(), "foobar", 4, 0, ""); 191 } 192 testBase32()193 public void testBase32() { 194 // The following test vectors are specified in RFC 4648 itself 195 testEncodingWithCasing(base32(), "", ""); 196 testEncodingWithCasing(base32(), "f", "MY======"); 197 testEncodingWithCasing(base32(), "fo", "MZXQ===="); 198 testEncodingWithCasing(base32(), "foo", "MZXW6==="); 199 testEncodingWithCasing(base32(), "foob", "MZXW6YQ="); 200 testEncodingWithCasing(base32(), "fooba", "MZXW6YTB"); 201 testEncodingWithCasing(base32(), "foobar", "MZXW6YTBOI======"); 202 } 203 204 @GwtIncompatible // Reader/Writer testBase32Streaming()205 public void testBase32Streaming() throws IOException { 206 // The following test vectors are specified in RFC 4648 itself 207 testStreamingEncodingWithCasing(base32(), "", ""); 208 testStreamingEncodingWithCasing(base32(), "f", "MY======"); 209 testStreamingEncodingWithCasing(base32(), "fo", "MZXQ===="); 210 testStreamingEncodingWithCasing(base32(), "foo", "MZXW6==="); 211 testStreamingEncodingWithCasing(base32(), "foob", "MZXW6YQ="); 212 testStreamingEncodingWithCasing(base32(), "fooba", "MZXW6YTB"); 213 testStreamingEncodingWithCasing(base32(), "foobar", "MZXW6YTBOI======"); 214 } 215 testBase32LenientPadding()216 public void testBase32LenientPadding() { 217 testDecodes(base32(), "MZXW6", "foo"); 218 testDecodes(base32(), "MZXW6=", "foo"); 219 testDecodes(base32(), "MZXW6==", "foo"); 220 testDecodes(base32(), "MZXW6===", "foo"); // proper padding length 221 testDecodes(base32(), "MZXW6====", "foo"); 222 testDecodes(base32(), "MZXW6=====", "foo"); 223 } 224 testBase32AlternatePadding()225 public void testBase32AlternatePadding() { 226 BaseEncoding enc = base32().withPadChar('~'); 227 testEncodingWithCasing(enc, "", ""); 228 testEncodingWithCasing(enc, "f", "MY~~~~~~"); 229 testEncodingWithCasing(enc, "fo", "MZXQ~~~~"); 230 testEncodingWithCasing(enc, "foo", "MZXW6~~~"); 231 testEncodingWithCasing(enc, "foob", "MZXW6YQ~"); 232 testEncodingWithCasing(enc, "fooba", "MZXW6YTB"); 233 testEncodingWithCasing(enc, "foobar", "MZXW6YTBOI~~~~~~"); 234 } 235 testBase32InvalidDecodings()236 public void testBase32InvalidDecodings() { 237 // These contain bytes not in the decodabet. 238 assertFailsToDecode(base32(), "A ", "Unrecognized character: 0x20"); 239 assertFailsToDecode(base32(), "Wf2!", "Unrecognized character: f"); 240 // This sentence just isn't base32() encoded. 241 assertFailsToDecode(base32(), "let's not talk of love or chains!"); 242 // An 8n+{1,3,6} length string is never legal base32. 243 assertFailsToDecode(base32(), "A", "Invalid input length 1"); 244 assertFailsToDecode(base32(), "ABC"); 245 assertFailsToDecode(base32(), "ABCDEF"); 246 // These have a combination of invalid length, unrecognized characters and wrong padding. 247 assertFailsToDecode(base32(), "AB=C", "Unrecognized character: ="); 248 assertFailsToDecode(base32(), "A=BCDE", "Invalid input length 6"); 249 assertFailsToDecode(base32(), "?", "Invalid input length 1"); 250 } 251 testBase32UpperCaseIsNoOp()252 public void testBase32UpperCaseIsNoOp() { 253 assertSame(base32(), base32().upperCase()); 254 } 255 testBase32Offset()256 public void testBase32Offset() { 257 testEncodesWithOffset(base32(), "foobar", 0, 6, "MZXW6YTBOI======"); 258 testEncodesWithOffset(base32(), "foobar", 1, 5, "N5XWEYLS"); 259 testEncodesWithOffset(base32(), "foobar", 2, 3, "N5RGC==="); 260 testEncodesWithOffset(base32(), "foobar", 3, 1, "MI======"); 261 testEncodesWithOffset(base32(), "foobar", 4, 0, ""); 262 } 263 testBase32Hex()264 public void testBase32Hex() { 265 // The following test vectors are specified in RFC 4648 itself 266 testEncodingWithCasing(base32Hex(), "", ""); 267 testEncodingWithCasing(base32Hex(), "f", "CO======"); 268 testEncodingWithCasing(base32Hex(), "fo", "CPNG===="); 269 testEncodingWithCasing(base32Hex(), "foo", "CPNMU==="); 270 testEncodingWithCasing(base32Hex(), "foob", "CPNMUOG="); 271 testEncodingWithCasing(base32Hex(), "fooba", "CPNMUOJ1"); 272 testEncodingWithCasing(base32Hex(), "foobar", "CPNMUOJ1E8======"); 273 } 274 275 @GwtIncompatible // Reader/Writer testBase32HexStreaming()276 public void testBase32HexStreaming() throws IOException { 277 // The following test vectors are specified in RFC 4648 itself 278 testStreamingEncodingWithCasing(base32Hex(), "", ""); 279 testStreamingEncodingWithCasing(base32Hex(), "f", "CO======"); 280 testStreamingEncodingWithCasing(base32Hex(), "fo", "CPNG===="); 281 testStreamingEncodingWithCasing(base32Hex(), "foo", "CPNMU==="); 282 testStreamingEncodingWithCasing(base32Hex(), "foob", "CPNMUOG="); 283 testStreamingEncodingWithCasing(base32Hex(), "fooba", "CPNMUOJ1"); 284 testStreamingEncodingWithCasing(base32Hex(), "foobar", "CPNMUOJ1E8======"); 285 } 286 testBase32HexLenientPadding()287 public void testBase32HexLenientPadding() { 288 testDecodes(base32Hex(), "CPNMU", "foo"); 289 testDecodes(base32Hex(), "CPNMU=", "foo"); 290 testDecodes(base32Hex(), "CPNMU==", "foo"); 291 testDecodes(base32Hex(), "CPNMU===", "foo"); // proper padding length 292 testDecodes(base32Hex(), "CPNMU====", "foo"); 293 testDecodes(base32Hex(), "CPNMU=====", "foo"); 294 } 295 testBase32HexInvalidDecodings()296 public void testBase32HexInvalidDecodings() { 297 // These contain bytes not in the decodabet. 298 assertFailsToDecode(base32Hex(), "A\u007f", "Unrecognized character: 0x7f"); 299 assertFailsToDecode(base32Hex(), "Wf2!", "Unrecognized character: W"); 300 // This sentence just isn't base32 encoded. 301 assertFailsToDecode(base32Hex(), "let's not talk of love or chains!"); 302 // An 8n+{1,3,6} length string is never legal base32. 303 assertFailsToDecode(base32Hex(), "A"); 304 assertFailsToDecode(base32Hex(), "ABC"); 305 assertFailsToDecode(base32Hex(), "ABCDEF"); 306 } 307 testBase32HexUpperCaseIsNoOp()308 public void testBase32HexUpperCaseIsNoOp() { 309 assertSame(base32Hex(), base32Hex().upperCase()); 310 } 311 testBase16()312 public void testBase16() { 313 testEncodingWithCasing(base16(), "", ""); 314 testEncodingWithCasing(base16(), "f", "66"); 315 testEncodingWithCasing(base16(), "fo", "666F"); 316 testEncodingWithCasing(base16(), "foo", "666F6F"); 317 testEncodingWithCasing(base16(), "foob", "666F6F62"); 318 testEncodingWithCasing(base16(), "fooba", "666F6F6261"); 319 testEncodingWithCasing(base16(), "foobar", "666F6F626172"); 320 } 321 testBase16UpperCaseIsNoOp()322 public void testBase16UpperCaseIsNoOp() { 323 assertSame(base16(), base16().upperCase()); 324 } 325 testBase16InvalidDecodings()326 public void testBase16InvalidDecodings() { 327 // These contain bytes not in the decodabet. 328 assertFailsToDecode(base16(), "\n\n", "Unrecognized character: 0xa"); 329 assertFailsToDecode(base16(), "EFGH", "Unrecognized character: G"); 330 // Valid base16 strings always have an even length. 331 assertFailsToDecode(base16(), "A", "Invalid input length 1"); 332 assertFailsToDecode(base16(), "ABC"); 333 // These have a combination of invalid length and unrecognized characters. 334 assertFailsToDecode(base16(), "?", "Invalid input length 1"); 335 } 336 testBase16Offset()337 public void testBase16Offset() { 338 testEncodesWithOffset(base16(), "foobar", 0, 6, "666F6F626172"); 339 testEncodesWithOffset(base16(), "foobar", 1, 5, "6F6F626172"); 340 testEncodesWithOffset(base16(), "foobar", 2, 3, "6F6261"); 341 testEncodesWithOffset(base16(), "foobar", 3, 1, "62"); 342 testEncodesWithOffset(base16(), "foobar", 4, 0, ""); 343 } 344 testEncodingWithCasing( BaseEncoding encoding, String decoded, String encoded)345 private static void testEncodingWithCasing( 346 BaseEncoding encoding, String decoded, String encoded) { 347 testEncodingWithSeparators(encoding, decoded, encoded); 348 testEncodingWithSeparators(encoding.upperCase(), decoded, Ascii.toUpperCase(encoded)); 349 testEncodingWithSeparators(encoding.lowerCase(), decoded, Ascii.toLowerCase(encoded)); 350 } 351 testEncodingWithSeparators( BaseEncoding encoding, String decoded, String encoded)352 private static void testEncodingWithSeparators( 353 BaseEncoding encoding, String decoded, String encoded) { 354 testEncoding(encoding, decoded, encoded); 355 356 // test separators work 357 for (int sepLength = 3; sepLength <= 5; sepLength++) { 358 for (String separator : ImmutableList.of(",", "\n", ";;", "")) { 359 testEncoding( 360 encoding.withSeparator(separator, sepLength), 361 decoded, 362 Joiner.on(separator).join(Splitter.fixedLength(sepLength).split(encoded))); 363 } 364 } 365 } 366 testEncoding(BaseEncoding encoding, String decoded, String encoded)367 private static void testEncoding(BaseEncoding encoding, String decoded, String encoded) { 368 testEncodes(encoding, decoded, encoded); 369 testDecodes(encoding, encoded, decoded); 370 } 371 testEncodes(BaseEncoding encoding, String decoded, String encoded)372 private static void testEncodes(BaseEncoding encoding, String decoded, String encoded) { 373 assertThat(encoding.encode(decoded.getBytes(UTF_8))).isEqualTo(encoded); 374 } 375 testEncodesWithOffset( BaseEncoding encoding, String decoded, int offset, int len, String encoded)376 private static void testEncodesWithOffset( 377 BaseEncoding encoding, String decoded, int offset, int len, String encoded) { 378 assertThat(encoding.encode(decoded.getBytes(UTF_8), offset, len)).isEqualTo(encoded); 379 } 380 testDecodes(BaseEncoding encoding, String encoded, String decoded)381 private static void testDecodes(BaseEncoding encoding, String encoded, String decoded) { 382 assertTrue(encoding.canDecode(encoded)); 383 assertThat(encoding.decode(encoded)).isEqualTo(decoded.getBytes(UTF_8)); 384 } 385 assertFailsToDecode(BaseEncoding encoding, String cannotDecode)386 private static void assertFailsToDecode(BaseEncoding encoding, String cannotDecode) { 387 assertFailsToDecode(encoding, cannotDecode, null); 388 } 389 assertFailsToDecode( BaseEncoding encoding, String cannotDecode, @Nullable String expectedMessage)390 private static void assertFailsToDecode( 391 BaseEncoding encoding, String cannotDecode, @Nullable String expectedMessage) { 392 assertFalse(encoding.canDecode(cannotDecode)); 393 try { 394 encoding.decode(cannotDecode); 395 fail("Expected IllegalArgumentException"); 396 } catch (IllegalArgumentException expected) { 397 if (expectedMessage != null) { 398 assertThat(expected).hasCauseThat().hasMessageThat().isEqualTo(expectedMessage); 399 } 400 } 401 try { 402 encoding.decodeChecked(cannotDecode); 403 fail("Expected DecodingException"); 404 } catch (DecodingException expected) { 405 if (expectedMessage != null) { 406 assertThat(expected).hasMessageThat().isEqualTo(expectedMessage); 407 } 408 } 409 } 410 411 @GwtIncompatible // Reader/Writer testStreamingEncodingWithCasing( BaseEncoding encoding, String decoded, String encoded)412 private static void testStreamingEncodingWithCasing( 413 BaseEncoding encoding, String decoded, String encoded) throws IOException { 414 testStreamingEncodingWithSeparators(encoding, decoded, encoded); 415 testStreamingEncodingWithSeparators(encoding.upperCase(), decoded, Ascii.toUpperCase(encoded)); 416 testStreamingEncodingWithSeparators(encoding.lowerCase(), decoded, Ascii.toLowerCase(encoded)); 417 } 418 419 @GwtIncompatible // Reader/Writer testStreamingEncodingWithSeparators( BaseEncoding encoding, String decoded, String encoded)420 private static void testStreamingEncodingWithSeparators( 421 BaseEncoding encoding, String decoded, String encoded) throws IOException { 422 testStreamingEncoding(encoding, decoded, encoded); 423 424 // test separators work 425 for (int sepLength = 3; sepLength <= 5; sepLength++) { 426 for (String separator : ImmutableList.of(",", "\n", ";;", "")) { 427 testStreamingEncoding( 428 encoding.withSeparator(separator, sepLength), 429 decoded, 430 Joiner.on(separator).join(Splitter.fixedLength(sepLength).split(encoded))); 431 } 432 } 433 } 434 435 @GwtIncompatible // Reader/Writer testStreamingEncoding(BaseEncoding encoding, String decoded, String encoded)436 private static void testStreamingEncoding(BaseEncoding encoding, String decoded, String encoded) 437 throws IOException { 438 testStreamingEncodes(encoding, decoded, encoded); 439 testStreamingDecodes(encoding, encoded, decoded); 440 } 441 442 @GwtIncompatible // Writer testStreamingEncodes(BaseEncoding encoding, String decoded, String encoded)443 private static void testStreamingEncodes(BaseEncoding encoding, String decoded, String encoded) 444 throws IOException { 445 StringWriter writer = new StringWriter(); 446 OutputStream encodingStream = encoding.encodingStream(writer); 447 encodingStream.write(decoded.getBytes(UTF_8)); 448 encodingStream.close(); 449 assertThat(writer.toString()).isEqualTo(encoded); 450 } 451 452 @GwtIncompatible // Reader testStreamingDecodes(BaseEncoding encoding, String encoded, String decoded)453 private static void testStreamingDecodes(BaseEncoding encoding, String encoded, String decoded) 454 throws IOException { 455 byte[] bytes = decoded.getBytes(UTF_8); 456 InputStream decodingStream = encoding.decodingStream(new StringReader(encoded)); 457 for (int i = 0; i < bytes.length; i++) { 458 assertThat(decodingStream.read()).isEqualTo(bytes[i] & 0xFF); 459 } 460 assertThat(decodingStream.read()).isEqualTo(-1); 461 decodingStream.close(); 462 } 463 testToString()464 public void testToString() { 465 assertEquals("BaseEncoding.base64().withPadChar('=')", base64().toString()); 466 assertEquals("BaseEncoding.base32Hex().omitPadding()", base32Hex().omitPadding().toString()); 467 assertEquals( 468 "BaseEncoding.base32().lowerCase().withPadChar('$')", 469 base32().lowerCase().withPadChar('$').toString()); 470 assertEquals( 471 "BaseEncoding.base16().withSeparator(\"\n\", 10)", 472 base16().withSeparator("\n", 10).toString()); 473 } 474 } 475