aboutsummaryrefslogtreecommitdiff
path: root/okio/src/jvmTest/java/okio/BufferedSinkTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'okio/src/jvmTest/java/okio/BufferedSinkTest.java')
-rw-r--r--okio/src/jvmTest/java/okio/BufferedSinkTest.java380
1 files changed, 380 insertions, 0 deletions
diff --git a/okio/src/jvmTest/java/okio/BufferedSinkTest.java b/okio/src/jvmTest/java/okio/BufferedSinkTest.java
new file mode 100644
index 00000000..e0132846
--- /dev/null
+++ b/okio/src/jvmTest/java/okio/BufferedSinkTest.java
@@ -0,0 +1,380 @@
+/*
+ * Copyright (C) 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.EOFException;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.math.BigInteger;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.util.Arrays;
+import java.util.List;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+import static java.util.Arrays.asList;
+import static kotlin.text.Charsets.UTF_8;
+import static kotlin.text.StringsKt.repeat;
+import static okio.TestUtil.SEGMENT_SIZE;
+import static okio.TestUtil.segmentSizes;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+@RunWith(Parameterized.class)
+public final class BufferedSinkTest {
+ private interface Factory {
+ Factory BUFFER = new Factory() {
+ @Override public BufferedSink create(Buffer data) {
+ return data;
+ }
+
+ @Override public String toString() {
+ return "Buffer";
+ }
+ };
+
+ Factory REAL_BUFFERED_SINK = new Factory() {
+ @Override public BufferedSink create(Buffer data) {
+ return Okio.buffer((Sink) data);
+ }
+
+ @Override public String toString() {
+ return "RealBufferedSink";
+ }
+ };
+
+ BufferedSink create(Buffer data);
+ }
+
+ @Parameters(name = "{0}")
+ public static List<Object[]> parameters() {
+ return Arrays.asList(
+ new Object[] {Factory.BUFFER},
+ new Object[] {Factory.REAL_BUFFERED_SINK});
+ }
+
+ @Parameter public Factory factory;
+ private Buffer data;
+ private BufferedSink sink;
+
+ @Before public void setUp() {
+ data = new Buffer();
+ sink = factory.create(data);
+ }
+
+ @Test public void writeNothing() throws IOException {
+ sink.writeUtf8("");
+ sink.flush();
+ assertEquals(0, data.size());
+ }
+
+ @Test public void writeBytes() throws Exception {
+ sink.writeByte(0xab);
+ sink.writeByte(0xcd);
+ sink.flush();
+ assertEquals("[hex=abcd]", data.toString());
+ }
+
+ @Test public void writeLastByteInSegment() throws Exception {
+ sink.writeUtf8(repeat("a", SEGMENT_SIZE - 1));
+ sink.writeByte(0x20);
+ sink.writeByte(0x21);
+ sink.flush();
+ assertEquals(asList(SEGMENT_SIZE, 1), segmentSizes(data));
+ assertEquals(repeat("a", SEGMENT_SIZE - 1), data.readUtf8(SEGMENT_SIZE - 1));
+ assertEquals("[text= !]", data.toString());
+ }
+
+ @Test public void writeShort() throws Exception {
+ sink.writeShort(0xabcd);
+ sink.writeShort(0x4321);
+ sink.flush();
+ assertEquals("[hex=abcd4321]", data.toString());
+ }
+
+ @Test public void writeShortLe() throws Exception {
+ sink.writeShortLe(0xcdab);
+ sink.writeShortLe(0x2143);
+ sink.flush();
+ assertEquals("[hex=abcd4321]", data.toString());
+ }
+
+ @Test public void writeInt() throws Exception {
+ sink.writeInt(0xabcdef01);
+ sink.writeInt(0x87654321);
+ sink.flush();
+ assertEquals("[hex=abcdef0187654321]", data.toString());
+ }
+
+ @Test public void writeLastIntegerInSegment() throws Exception {
+ sink.writeUtf8(repeat("a", SEGMENT_SIZE - 4));
+ sink.writeInt(0xabcdef01);
+ sink.writeInt(0x87654321);
+ sink.flush();
+ assertEquals(asList(SEGMENT_SIZE, 4), segmentSizes(data));
+ assertEquals(repeat("a", SEGMENT_SIZE - 4), data.readUtf8(SEGMENT_SIZE - 4));
+ assertEquals("[hex=abcdef0187654321]", data.toString());
+ }
+
+ @Test public void writeIntegerDoesNotQuiteFitInSegment() throws Exception {
+ sink.writeUtf8(repeat("a", SEGMENT_SIZE - 3));
+ sink.writeInt(0xabcdef01);
+ sink.writeInt(0x87654321);
+ sink.flush();
+ assertEquals(asList(SEGMENT_SIZE - 3, 8), segmentSizes(data));
+ assertEquals(repeat("a", SEGMENT_SIZE - 3), data.readUtf8(SEGMENT_SIZE - 3));
+ assertEquals("[hex=abcdef0187654321]", data.toString());
+ }
+
+ @Test public void writeIntLe() throws Exception {
+ sink.writeIntLe(0xabcdef01);
+ sink.writeIntLe(0x87654321);
+ sink.flush();
+ assertEquals("[hex=01efcdab21436587]", data.toString());
+ }
+
+ @Test public void writeLong() throws Exception {
+ sink.writeLong(0xabcdef0187654321L);
+ sink.writeLong(0xcafebabeb0b15c00L);
+ sink.flush();
+ assertEquals("[hex=abcdef0187654321cafebabeb0b15c00]", data.toString());
+ }
+
+ @Test public void writeLongLe() throws Exception {
+ sink.writeLongLe(0xabcdef0187654321L);
+ sink.writeLongLe(0xcafebabeb0b15c00L);
+ sink.flush();
+ assertEquals("[hex=2143658701efcdab005cb1b0bebafeca]", data.toString());
+ }
+
+ @Test public void writeByteString() throws IOException {
+ sink.write(ByteString.encodeUtf8("təˈranəˌsôr"));
+ sink.flush();
+ assertEquals(ByteString.decodeHex("74c999cb8872616ec999cb8c73c3b472"), data.readByteString());
+ }
+
+ @Test public void writeByteStringOffset() throws IOException {
+ sink.write(ByteString.encodeUtf8("təˈranəˌsôr"), 5, 5);
+ sink.flush();
+ assertEquals(ByteString.decodeHex("72616ec999"), data.readByteString());
+ }
+
+ @Test public void writeSegmentedByteString() throws IOException {
+ sink.write(new Buffer().write(ByteString.encodeUtf8("təˈranəˌsôr")).snapshot());
+ sink.flush();
+ assertEquals(ByteString.decodeHex("74c999cb8872616ec999cb8c73c3b472"), data.readByteString());
+ }
+
+ @Test public void writeSegmentedByteStringOffset() throws IOException {
+ sink.write(new Buffer().write(ByteString.encodeUtf8("təˈranəˌsôr")).snapshot(), 5, 5);
+ sink.flush();
+ assertEquals(ByteString.decodeHex("72616ec999"), data.readByteString());
+ }
+
+ @Test public void writeStringUtf8() throws IOException {
+ sink.writeUtf8("təˈranəˌsôr");
+ sink.flush();
+ assertEquals(ByteString.decodeHex("74c999cb8872616ec999cb8c73c3b472"), data.readByteString());
+ }
+
+ @Test public void writeSubstringUtf8() throws IOException {
+ sink.writeUtf8("təˈranəˌsôr", 3, 7);
+ sink.flush();
+ assertEquals(ByteString.decodeHex("72616ec999"), data.readByteString());
+ }
+
+ @Test public void writeStringWithCharset() throws IOException {
+ sink.writeString("təˈranəˌsôr", Charset.forName("utf-32be"));
+ sink.flush();
+ assertEquals(ByteString.decodeHex("0000007400000259000002c800000072000000610000006e00000259"
+ + "000002cc00000073000000f400000072"), data.readByteString());
+ }
+
+ @Test public void writeSubstringWithCharset() throws IOException {
+ sink.writeString("təˈranəˌsôr", 3, 7, Charset.forName("utf-32be"));
+ sink.flush();
+ assertEquals(ByteString.decodeHex("00000072000000610000006e00000259"), data.readByteString());
+ }
+
+ @Test public void writeUtf8SubstringWithCharset() throws IOException {
+ sink.writeString("təˈranəˌsôr", 3, 7, Charset.forName("utf-8"));
+ sink.flush();
+ assertEquals(ByteString.encodeUtf8("ranə"), data.readByteString());
+ }
+
+ @Test public void writeAll() throws Exception {
+ Buffer source = new Buffer().writeUtf8("abcdef");
+
+ assertEquals(6, sink.writeAll(source));
+ assertEquals(0, source.size());
+ sink.flush();
+ assertEquals("abcdef", data.readUtf8());
+ }
+
+ @Test public void writeSource() throws Exception {
+ Buffer source = new Buffer().writeUtf8("abcdef");
+
+ // Force resolution of the Source method overload.
+ sink.write((Source) source, 4);
+ sink.flush();
+ assertEquals("abcd", data.readUtf8());
+ assertEquals("ef", source.readUtf8());
+ }
+
+ @Test public void writeSourceReadsFully() throws Exception {
+ Source source = new ForwardingSource(new Buffer()) {
+ @Override public long read(Buffer sink, long byteCount) throws IOException {
+ sink.writeUtf8("abcd");
+ return 4;
+ }
+ };
+
+ sink.write(source, 8);
+ sink.flush();
+ assertEquals("abcdabcd", data.readUtf8());
+ }
+
+ @Test public void writeSourcePropagatesEof() throws IOException {
+ Source source = new Buffer().writeUtf8("abcd");
+
+ try {
+ sink.write(source, 8);
+ fail();
+ } catch (EOFException expected) {
+ }
+
+ // Ensure that whatever was available was correctly written.
+ sink.flush();
+ assertEquals("abcd", data.readUtf8());
+ }
+
+ @Test public void writeSourceWithZeroIsNoOp() throws IOException {
+ // This test ensures that a zero byte count never calls through to read the source. It may be
+ // tied to something like a socket which will potentially block trying to read a segment when
+ // ultimately we don't want any data.
+ Source source = new ForwardingSource(new Buffer()) {
+ @Override public long read(Buffer sink, long byteCount) throws IOException {
+ throw new AssertionError();
+ }
+ };
+ sink.write(source, 0);
+ assertEquals(0, data.size());
+ }
+
+ @Test public void writeAllExhausted() throws Exception {
+ Buffer source = new Buffer();
+ assertEquals(0, sink.writeAll(source));
+ assertEquals(0, source.size());
+ }
+
+ @Test public void closeEmitsBufferedBytes() throws IOException {
+ sink.writeByte('a');
+ sink.close();
+ assertEquals('a', data.readByte());
+ }
+
+ @Test public void outputStream() throws Exception {
+ OutputStream out = sink.outputStream();
+ out.write('a');
+ out.write(repeat("b", 9998).getBytes(UTF_8));
+ out.write('c');
+ out.flush();
+ assertEquals("a" + repeat("b", 9998) + "c", data.readUtf8());
+ }
+
+ @Test public void outputStreamBounds() throws Exception {
+ OutputStream out = sink.outputStream();
+ try {
+ out.write(new byte[100], 50, 51);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException expected) {
+ }
+ }
+
+ @Test public void longDecimalString() throws IOException {
+ assertLongDecimalString(0);
+ assertLongDecimalString(Long.MIN_VALUE);
+ assertLongDecimalString(Long.MAX_VALUE);
+
+ for (int i = 1; i < 20; i++) {
+ long value = BigInteger.valueOf(10L).pow(i).longValue();
+ assertLongDecimalString(value - 1);
+ assertLongDecimalString(value);
+ }
+ }
+
+ private void assertLongDecimalString(long value) throws IOException {
+ sink.writeDecimalLong(value).writeUtf8("zzz").flush();
+ String expected = Long.toString(value) + "zzz";
+ String actual = data.readUtf8();
+ assertEquals(value + " expected " + expected + " but was " + actual, actual, expected);
+ }
+
+ @Test public void longHexString() throws IOException {
+ assertLongHexString(0);
+ assertLongHexString(Long.MIN_VALUE);
+ assertLongHexString(Long.MAX_VALUE);
+
+ for (int i = 0; i < 63; i++) {
+ assertLongHexString((1L << i) - 1);
+ assertLongHexString(1L << i);
+ }
+ }
+
+ @Test public void writeNioBuffer() throws Exception {
+ String expected = "abcdefg";
+
+ ByteBuffer nioByteBuffer = ByteBuffer.allocate(1024);
+ nioByteBuffer.put("abcdefg".getBytes(UTF_8));
+ nioByteBuffer.flip();
+
+ int byteCount = sink.write(nioByteBuffer);
+ assertEquals(expected.length(), byteCount);
+ assertEquals(expected.length(), nioByteBuffer.position());
+ assertEquals(expected.length(), nioByteBuffer.limit());
+
+ sink.flush();
+ assertEquals(expected, data.readUtf8());
+ }
+
+ @Test public void writeLargeNioBufferWritesAllData() throws Exception {
+ String expected = repeat("a", SEGMENT_SIZE * 3);
+
+ ByteBuffer nioByteBuffer = ByteBuffer.allocate(SEGMENT_SIZE * 4);
+ nioByteBuffer.put(repeat("a", SEGMENT_SIZE * 3).getBytes(UTF_8));
+ nioByteBuffer.flip();
+
+ int byteCount = sink.write(nioByteBuffer);
+ assertEquals(expected.length(), byteCount);
+ assertEquals(expected.length(), nioByteBuffer.position());
+ assertEquals(expected.length(), nioByteBuffer.limit());
+
+ sink.flush();
+ assertEquals(expected, data.readUtf8());
+ }
+
+ private void assertLongHexString(long value) throws IOException {
+ sink.writeHexadecimalUnsignedLong(value).writeUtf8("zzz").flush();
+ String expected = String.format("%x", value) + "zzz";
+ String actual = data.readUtf8();
+ assertEquals(value + " expected " + expected + " but was " + actual, actual, expected);
+ }
+}