blob: 68a297468dff0ffaeef1078c0d795c65fe79b12e [file] [log] [blame]
/*
* Copyright 2014 Square Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okio;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import org.junit.Test;
import static okio.TestUtil.assertByteArraysEquals;
import static okio.TestUtil.assertEquivalent;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
public class ByteStringTest {
@Test public void ofCopyRange() {
byte[] bytes = "Hello, World!".getBytes(Util.UTF_8);
ByteString byteString = ByteString.of(bytes, 2, 9);
// Verify that the bytes were copied out.
bytes[4] = (byte) 'a';
assertEquals("llo, Worl", byteString.utf8());
}
@Test public void getByte() throws Exception {
ByteString byteString = ByteString.decodeHex("ab12");
assertEquals(-85, byteString.getByte(0));
assertEquals(18, byteString.getByte(1));
}
@Test public void getByteOutOfBounds() throws Exception {
ByteString byteString = ByteString.decodeHex("ab12");
try {
byteString.getByte(2);
fail();
} catch (IndexOutOfBoundsException expected) {
}
}
@Test public void equals() throws Exception {
ByteString byteString = ByteString.decodeHex("000102");
assertTrue(byteString.equals(byteString));
assertTrue(byteString.equals(ByteString.decodeHex("000102")));
assertTrue(ByteString.of().equals(ByteString.EMPTY));
assertTrue(ByteString.EMPTY.equals(ByteString.of()));
assertFalse(byteString.equals(new Object()));
assertFalse(byteString.equals(ByteString.decodeHex("000201")));
}
private final String bronzeHorseman = "На берегу пустынных волн";
@Test public void utf8() throws Exception {
ByteString byteString = ByteString.encodeUtf8(bronzeHorseman);
assertByteArraysEquals(byteString.toByteArray(), bronzeHorseman.getBytes(Util.UTF_8));
assertTrue(byteString.equals(ByteString.of(bronzeHorseman.getBytes(Util.UTF_8))));
assertEquals(byteString.utf8(), bronzeHorseman);
}
@Test public void md5() {
assertEquals("6cd3556deb0da54bca060b4c39479839",
ByteString.encodeUtf8("Hello, world!").md5().hex());
assertEquals("c71dc6df4b2e434b8c74fd6dd6ca3f85",
ByteString.encodeUtf8("One Two Three").md5().hex());
assertEquals("37b69fb926e239e049d7e43987974b99",
ByteString.encodeUtf8(bronzeHorseman).md5().hex());
}
@Test public void sha256() {
assertEquals("315f5bdb76d078c43b8ac0064e4a0164612b1fce77c869345bfc94c75894edd3",
ByteString.encodeUtf8("Hello, world!").sha256().hex());
assertEquals("641e54ba5e49e169408148a25bef8ca8fa4f8aab222fe8ce4b3535a570ddd68e",
ByteString.encodeUtf8("One Two Three").sha256().hex());
assertEquals("4d869e1c3d94568a5344235d9e4f187b8d5d78d06c5c622854c669f2f582d33e",
ByteString.encodeUtf8(bronzeHorseman).sha256().hex());
}
@Test public void testHashCode() throws Exception {
ByteString byteString = ByteString.decodeHex("0102");
assertEquals(byteString.hashCode(), byteString.hashCode());
assertEquals(byteString.hashCode(), ByteString.decodeHex("0102").hashCode());
}
@Test public void read() throws Exception {
InputStream in = new ByteArrayInputStream("abc".getBytes(Util.UTF_8));
assertEquals(ByteString.decodeHex("6162"), ByteString.read(in, 2));
assertEquals(ByteString.decodeHex("63"), ByteString.read(in, 1));
assertEquals(ByteString.of(), ByteString.read(in, 0));
}
@Test public void readAndToLowercase() throws Exception {
InputStream in = new ByteArrayInputStream("ABC".getBytes(Util.UTF_8));
assertEquals(ByteString.encodeUtf8("ab"), ByteString.read(in, 2).toAsciiLowercase());
assertEquals(ByteString.encodeUtf8("c"), ByteString.read(in, 1).toAsciiLowercase());
assertEquals(ByteString.EMPTY, ByteString.read(in, 0).toAsciiLowercase());
}
@Test public void toAsciiLowerCaseNoUppercase() throws Exception {
ByteString s = ByteString.encodeUtf8("a1_+");
assertSame(s, s.toAsciiLowercase());
}
@Test public void toAsciiAllUppercase() throws Exception {
assertEquals(ByteString.encodeUtf8("ab"), ByteString.encodeUtf8("AB").toAsciiLowercase());
}
@Test public void toAsciiStartsLowercaseEndsUppercase() throws Exception {
assertEquals(ByteString.encodeUtf8("abcd"), ByteString.encodeUtf8("abCD").toAsciiLowercase());
}
@Test public void readAndToUppercase() throws Exception {
InputStream in = new ByteArrayInputStream("abc".getBytes(Util.UTF_8));
assertEquals(ByteString.encodeUtf8("AB"), ByteString.read(in, 2).toAsciiUppercase());
assertEquals(ByteString.encodeUtf8("C"), ByteString.read(in, 1).toAsciiUppercase());
assertEquals(ByteString.EMPTY, ByteString.read(in, 0).toAsciiUppercase());
}
@Test public void toAsciiStartsUppercaseEndsLowercase() throws Exception {
assertEquals(ByteString.encodeUtf8("ABCD"), ByteString.encodeUtf8("ABcd").toAsciiUppercase());
}
@Test public void substring() throws Exception {
ByteString byteString = ByteString.encodeUtf8("Hello, World!");
assertEquals(byteString.substring(0), byteString);
assertEquals(byteString.substring(0, 5), ByteString.encodeUtf8("Hello"));
assertEquals(byteString.substring(7), ByteString.encodeUtf8("World!"));
assertEquals(byteString.substring(6, 6), ByteString.encodeUtf8(""));
}
@Test public void substringWithInvalidBounds() throws Exception {
ByteString byteString = ByteString.encodeUtf8("Hello, World!");
try {
byteString.substring(-1);
fail();
} catch (IllegalArgumentException expected) {
}
try {
byteString.substring(0, 14);
fail();
} catch (IllegalArgumentException expected) {
}
try {
byteString.substring(8, 7);
fail();
} catch (IllegalArgumentException expected) {
}
}
@Test public void write() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteString.decodeHex("616263").write(out);
assertByteArraysEquals(new byte[] { 0x61, 0x62, 0x63 }, out.toByteArray());
}
@Test public void encodeBase64() {
assertEquals("", ByteString.encodeUtf8("").base64());
assertEquals("AA==", ByteString.encodeUtf8("\u0000").base64());
assertEquals("AAA=", ByteString.encodeUtf8("\u0000\u0000").base64());
assertEquals("AAAA", ByteString.encodeUtf8("\u0000\u0000\u0000").base64());
assertEquals("SG93IG1hbnkgbGluZXMgb2YgY29kZSBhcmUgdGhlcmU/ICdib3V0IDIgbWlsbGlvbi4=",
ByteString.encodeUtf8("How many lines of code are there? 'bout 2 million.").base64());
}
@Test public void encodeBase64Url() {
assertEquals("", ByteString.encodeUtf8("").base64Url());
assertEquals("AA==", ByteString.encodeUtf8("\u0000").base64Url());
assertEquals("AAA=", ByteString.encodeUtf8("\u0000\u0000").base64Url());
assertEquals("AAAA", ByteString.encodeUtf8("\u0000\u0000\u0000").base64Url());
assertEquals("SG93IG1hbnkgbGluZXMgb2YgY29kZSBhcmUgdGhlcmU_ICdib3V0IDIgbWlsbGlvbi4=",
ByteString.encodeUtf8("How many lines of code are there? 'bout 2 million.").base64Url());
}
@Test public void ignoreUnnecessaryPadding() {
assertEquals("", ByteString.decodeBase64("====").utf8());
assertEquals("\u0000\u0000\u0000", ByteString.decodeBase64("AAAA====").utf8());
}
@Test public void decodeBase64() {
assertEquals("", ByteString.decodeBase64("").utf8());
assertEquals(null, ByteString.decodeBase64("/===")); // Can't do anything with 6 bits!
assertEquals(ByteString.decodeHex("ff"), ByteString.decodeBase64("//=="));
assertEquals(ByteString.decodeHex("ff"), ByteString.decodeBase64("__=="));
assertEquals(ByteString.decodeHex("ffff"), ByteString.decodeBase64("///="));
assertEquals(ByteString.decodeHex("ffff"), ByteString.decodeBase64("___="));
assertEquals(ByteString.decodeHex("ffffff"), ByteString.decodeBase64("////"));
assertEquals(ByteString.decodeHex("ffffff"), ByteString.decodeBase64("____"));
assertEquals(ByteString.decodeHex("ffffffffffff"), ByteString.decodeBase64("////////"));
assertEquals(ByteString.decodeHex("ffffffffffff"), ByteString.decodeBase64("________"));
assertEquals("What's to be scared about? It's just a little hiccup in the power...",
ByteString.decodeBase64("V2hhdCdzIHRvIGJlIHNjYXJlZCBhYm91dD8gSXQncyBqdXN0IGEgbGl0dGxlIGhpY2"
+ "N1cCBpbiB0aGUgcG93ZXIuLi4=").utf8());
// Uses two encoding styles. Malformed, but supported as a side-effect.
assertEquals(ByteString.decodeHex("ffffff"), ByteString.decodeBase64("__//"));
}
@Test public void decodeBase64WithWhitespace() {
assertEquals("\u0000\u0000\u0000", ByteString.decodeBase64(" AA AA ").utf8());
assertEquals("\u0000\u0000\u0000", ByteString.decodeBase64(" AA A\r\nA ").utf8());
assertEquals("\u0000\u0000\u0000", ByteString.decodeBase64("AA AA").utf8());
assertEquals("\u0000\u0000\u0000", ByteString.decodeBase64(" AA AA ").utf8());
assertEquals("\u0000\u0000\u0000", ByteString.decodeBase64(" AA A\r\nA ").utf8());
assertEquals("\u0000\u0000\u0000", ByteString.decodeBase64("A AAA").utf8());
assertEquals("", ByteString.decodeBase64(" ").utf8());
}
@Test public void encodeHex() throws Exception {
assertEquals("000102", ByteString.of((byte) 0x0, (byte) 0x1, (byte) 0x2).hex());
}
@Test public void decodeHex() throws Exception {
assertEquals(ByteString.of((byte) 0x0, (byte) 0x1, (byte) 0x2), ByteString.decodeHex("000102"));
}
@Test public void decodeHexOddNumberOfChars() throws Exception {
try {
ByteString.decodeHex("aaa");
fail();
} catch (IllegalArgumentException expected) {
}
}
@Test public void decodeHexInvalidChar() throws Exception {
try {
ByteString.decodeHex("a\u0000");
fail();
} catch (IllegalArgumentException expected) {
}
}
@Test public void toStringOnEmptyByteString() {
assertEquals("ByteString[size=0]", ByteString.of().toString());
}
@Test public void toStringOnSmallByteStringIncludesContents() {
assertEquals("ByteString[size=16 data=a1b2c3d4e5f61a2b3c4d5e6f10203040]",
ByteString.decodeHex("a1b2c3d4e5f61a2b3c4d5e6f10203040").toString());
}
@Test public void toStringOnLargeByteStringIncludesMd5() {
assertEquals("ByteString[size=17 md5=2c9728a2138b2f25e9f89f99bdccf8db]",
ByteString.encodeUtf8("12345678901234567").toString());
}
@Test public void javaSerializationTestNonEmpty() throws Exception {
ByteString byteString = ByteString.encodeUtf8(bronzeHorseman);
assertEquivalent(byteString, TestUtil.reserialize(byteString));
}
@Test public void javaSerializationTestEmpty() throws Exception {
ByteString byteString = ByteString.of();
assertEquivalent(byteString, TestUtil.reserialize(byteString));
}
@Test public void compareToSingleBytes() throws Exception {
List<ByteString> originalByteStrings = Arrays.asList(
ByteString.decodeHex("00"),
ByteString.decodeHex("01"),
ByteString.decodeHex("7e"),
ByteString.decodeHex("7f"),
ByteString.decodeHex("80"),
ByteString.decodeHex("81"),
ByteString.decodeHex("fe"),
ByteString.decodeHex("ff"));
List<ByteString> sortedByteStrings = new ArrayList<>(originalByteStrings);
Collections.shuffle(sortedByteStrings, new Random(0));
Collections.sort(sortedByteStrings);
assertEquals(originalByteStrings, sortedByteStrings);
}
@Test public void compareToMultipleBytes() throws Exception {
List<ByteString> originalByteStrings = Arrays.asList(
ByteString.decodeHex(""),
ByteString.decodeHex("00"),
ByteString.decodeHex("0000"),
ByteString.decodeHex("000000"),
ByteString.decodeHex("00000000"),
ByteString.decodeHex("0000000000"),
ByteString.decodeHex("0000000001"),
ByteString.decodeHex("000001"),
ByteString.decodeHex("00007f"),
ByteString.decodeHex("0000ff"),
ByteString.decodeHex("000100"),
ByteString.decodeHex("000101"),
ByteString.decodeHex("007f00"),
ByteString.decodeHex("00ff00"),
ByteString.decodeHex("010000"),
ByteString.decodeHex("010001"),
ByteString.decodeHex("01007f"),
ByteString.decodeHex("0100ff"),
ByteString.decodeHex("010100"),
ByteString.decodeHex("01010000"),
ByteString.decodeHex("0101000000"),
ByteString.decodeHex("0101000001"),
ByteString.decodeHex("010101"),
ByteString.decodeHex("7f0000"),
ByteString.decodeHex("7f0000ffff"),
ByteString.decodeHex("ffffff"));
List<ByteString> sortedByteStrings = new ArrayList<>(originalByteStrings);
Collections.shuffle(sortedByteStrings, new Random(0));
Collections.sort(sortedByteStrings);
assertEquals(originalByteStrings, sortedByteStrings);
}
}