• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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