1e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller/*
2e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * Copyright (C) 2014 Square, Inc.
3e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller *
4e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * Licensed under the Apache License, Version 2.0 (the "License");
5e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * you may not use this file except in compliance with the License.
6e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * You may obtain a copy of the License at
7e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller *
8e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller *      http://www.apache.org/licenses/LICENSE-2.0
9e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller *
10e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * Unless required by applicable law or agreed to in writing, software
11e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * distributed under the License is distributed on an "AS IS" BASIS,
12e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * See the License for the specific language governing permissions and
14e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * limitations under the License.
15e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller */
16e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerpackage okio;
17e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
18e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport java.io.EOFException;
19e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport java.io.IOException;
20e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport java.util.Arrays;
21e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport java.util.List;
22e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport org.junit.Before;
23e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport org.junit.Test;
24e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport org.junit.runner.RunWith;
25e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport org.junit.runners.Parameterized;
26e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
27e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport static org.junit.Assert.assertEquals;
28e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport static org.junit.Assert.assertTrue;
29e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport static org.junit.Assert.fail;
30e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
31e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller@RunWith(Parameterized.class)
32e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerpublic final class ReadUtf8LineTest {
33e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  private interface Factory {
34e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    BufferedSource create(Buffer data);
35e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  }
36e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
37e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  // ANDROID-BEGIN
38e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  //  @Parameterized.Parameters(name = "{0}")
39e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  // ANDROID-END
40e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  public static List<Object[]> parameters() {
41e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    return Arrays.asList(
42e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller        new Object[] { new Factory() {
43e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller          @Override public BufferedSource create(Buffer data) {
44e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller            return data;
45e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller          }
46e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
47e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller          @Override public String toString() {
48e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller            return "Buffer";
49e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller          }
50e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller        }},
51e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller        new Object[] { new Factory() {
52e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller          @Override public BufferedSource create(Buffer data) {
53e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller            return new RealBufferedSource(data);
54e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller          }
55e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
56e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller          @Override public String toString() {
57e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller            return "RealBufferedSource";
58e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller          }
59e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller        }},
60e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller        new Object[] { new Factory() {
61e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller          @Override public BufferedSource create(Buffer data) {
62e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller            return new RealBufferedSource(new ForwardingSource(data) {
63e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller              @Override public long read(Buffer sink, long byteCount) throws IOException {
64e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller                return super.read(sink, Math.min(1, byteCount));
65e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller              }
66e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller            });
67e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller          }
68e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
69e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller          @Override public String toString() {
70e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller            return "Slow RealBufferedSource";
71e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller          }
72e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller        }}
73e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    );
74e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  }
75e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
76e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  // ANDROID-BEGIN
77e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  //  @Parameterized.Parameter
78e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  public Factory factory = (Factory) (parameters().get(0))[0];
79e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  // ANDROID-END
80e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
81e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  private Buffer data;
82e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  private BufferedSource source;
83e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
84e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  @Before public void setUp() {
85e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    data = new Buffer();
86e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    source = factory.create(data);
87e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  }
88e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
89e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  @Test public void readLines() throws IOException {
90e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    data.writeUtf8("abc\ndef\n");
91e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    assertEquals("abc", source.readUtf8LineStrict());
92e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    assertEquals("def", source.readUtf8LineStrict());
93e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    try {
94e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller      source.readUtf8LineStrict();
95e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller      fail();
96e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    } catch (EOFException expected) {
97e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller      assertEquals("\\n not found: size=0 content=...", expected.getMessage());
98e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    }
99e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  }
100e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
101e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  @Test public void eofExceptionProvidesLimitedContent() throws IOException {
102e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    data.writeUtf8("aaaaaaaabbbbbbbbccccccccdddddddde");
103e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    try {
104e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller      source.readUtf8LineStrict();
105e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller      fail();
106e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    } catch (EOFException expected) {
107e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller      assertEquals("\\n not found: size=33 content=616161616161616162626262626262626363636363636363"
108e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller          + "6464646464646464...", expected.getMessage());
109e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    }
110e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  }
111e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
112e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  @Test public void emptyLines() throws IOException {
113e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    data.writeUtf8("\n\n\n");
114e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    assertEquals("", source.readUtf8LineStrict());
115e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    assertEquals("", source.readUtf8LineStrict());
116e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    assertEquals("", source.readUtf8LineStrict());
117e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    assertTrue(source.exhausted());
118e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  }
119e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
120e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  @Test public void crDroppedPrecedingLf() throws IOException {
121e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    data.writeUtf8("abc\r\ndef\r\nghi\rjkl\r\n");
122e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    assertEquals("abc", source.readUtf8LineStrict());
123e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    assertEquals("def", source.readUtf8LineStrict());
124e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    assertEquals("ghi\rjkl", source.readUtf8LineStrict());
125e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  }
126e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
127e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  @Test public void bufferedReaderCompatible() throws IOException {
128e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    data.writeUtf8("abc\ndef");
129e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    assertEquals("abc", source.readUtf8Line());
130e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    assertEquals("def", source.readUtf8Line());
131e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    assertEquals(null, source.readUtf8Line());
132e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  }
133e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
134e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  @Test public void bufferedReaderCompatibleWithTrailingNewline() throws IOException {
135e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    data.writeUtf8("abc\ndef\n");
136e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    assertEquals("abc", source.readUtf8Line());
137e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    assertEquals("def", source.readUtf8Line());
138e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    assertEquals(null, source.readUtf8Line());
139e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  }
140e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller}
141