11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/*
21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2007 The Guava Authors
31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License");
51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * you may not use this file except in compliance with the License.
61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * You may obtain a copy of the License at
71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0
91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unless required by applicable law or agreed to in writing, software
111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS,
121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * See the License for the specific language governing permissions and
141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * limitations under the License.
151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.io;
181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Charsets.UTF_8;
201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.io.CharStreams.copy;
211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.io.CharStreams.newReaderSupplier;
221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Charsets;
241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.ImmutableList;
251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.ImmutableSet;
261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.testing.TestLogHandler;
271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.ByteArrayInputStream;
291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.EOFException;
301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.FilterReader;
311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.FilterWriter;
321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.IOException;
331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.InputStreamReader;
341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.Reader;
351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.StringReader;
361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.StringWriter;
371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.Writer;
381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.List;
391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/**
411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unit test for {@link CharStreams}.
421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Chris Nokleberg
441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic class CharStreamsTest extends IoTestCase {
461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static final String TEXT
471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      = "The quick brown fox jumped over the lazy dog.";
481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static final InputSupplier<? extends Reader> BROKEN_READ
501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      = CharStreams.newReaderSupplier(ByteStreamsTest.BROKEN_READ, UTF_8);
511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static final OutputSupplier<? extends Writer> BROKEN_WRITE
531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      = CharStreams.newWriterSupplier(ByteStreamsTest.BROKEN_WRITE, UTF_8);
541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static final InputSupplier<? extends Reader> BROKEN_CLOSE_INPUT
561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      = CharStreams.newReaderSupplier(ByteStreamsTest.BROKEN_CLOSE_INPUT, UTF_8);
571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static final OutputSupplier<? extends Writer> BROKEN_CLOSE_OUTPUT
591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      = CharStreams.newWriterSupplier(ByteStreamsTest.BROKEN_CLOSE_OUTPUT, UTF_8);
601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static final InputSupplier<? extends Reader> BROKEN_GET_INPUT
621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      = CharStreams.newReaderSupplier(ByteStreamsTest.BROKEN_GET_INPUT, UTF_8);
631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static final OutputSupplier<? extends Writer> BROKEN_GET_OUTPUT
651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      = CharStreams.newWriterSupplier(ByteStreamsTest.BROKEN_GET_OUTPUT, UTF_8);
661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static final ImmutableSet<InputSupplier<? extends Reader>> BROKEN_INPUTS =
681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      ImmutableSet.of(BROKEN_CLOSE_INPUT, BROKEN_GET_INPUT, BROKEN_READ);
691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static final ImmutableSet<OutputSupplier<? extends Writer>> BROKEN_OUTPUTS
701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      = ImmutableSet.of(BROKEN_CLOSE_OUTPUT, BROKEN_GET_OUTPUT, BROKEN_WRITE);
711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testToString() throws IOException {
731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(TEXT, CharStreams.toString(new StringReader(TEXT)));
741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(TEXT,
751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        CharStreams.toString(CharStreams.newReaderSupplier(TEXT)));
761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSkipFully_blockingRead() throws IOException {
791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Reader reader = new NonSkippingReader("abcdef");
801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    CharStreams.skipFully(reader, 6);
811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(-1, reader.read());
821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static class NonSkippingReader extends StringReader {
851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    NonSkippingReader(String s) {
861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      super(s);
871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public long skip(long n) {
911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return 0;
921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testReadLines_fromReadable() throws IOException {
961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    byte[] bytes = "a\nb\nc".getBytes(Charsets.UTF_8.name());
971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    List<String> lines = CharStreams.readLines(
981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        new InputStreamReader(new ByteArrayInputStream(bytes), Charsets.UTF_8));
991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableList.of("a", "b", "c"), lines);
1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testReadLines_withLineProcessor() throws IOException {
1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    InputSupplier<StringReader> r = CharStreams.newReaderSupplier("a\nb\nc");
1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Test a LineProcessor that always returns false.
1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    LineProcessor<Integer> alwaysFalse = new LineProcessor<Integer>() {
1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      int seen;
1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override
1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      public boolean processLine(String line) {
1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        seen++;
1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return false;
1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override
1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      public Integer getResult() {
1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return seen;
1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    };
1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("processLine was called more than once", 1,
1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        CharStreams.readLines(r, alwaysFalse).intValue());
1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Test a LineProcessor that always returns true.
1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    LineProcessor<Integer> alwaysTrue = new LineProcessor<Integer>() {
1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      int seen;
1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override
1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      public boolean processLine(String line) {
1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        seen++;
1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return true;
1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override
1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      public Integer getResult() {
1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return seen;
1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    };
1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("processLine was not called for all the lines", 3,
1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        CharStreams.readLines(r, alwaysTrue).intValue());
1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Test a LineProcessor that is conditional.
1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final StringBuilder sb = new StringBuilder();
1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    LineProcessor<Integer> conditional = new LineProcessor<Integer>() {
1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      int seen;
1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override
1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      public boolean processLine(String line) {
1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        seen++;
1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        sb.append(line);
1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return seen < 2;
1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override
1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      public Integer getResult() {
1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return seen;
1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    };
1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(2, CharStreams.readLines(r, conditional).intValue());
1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("ab", sb.toString());
1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testAlwaysCloses() throws IOException {
1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    CheckCloseSupplier.Input<Reader> okRead
1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        = newCheckReader(CharStreams.newReaderSupplier(TEXT));
1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    CheckCloseSupplier.Output<Writer> okWrite
1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        = newCheckWriter(new OutputSupplier<Writer>() {
1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          @Override
1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          public Writer getOutput() {
1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            return new StringWriter();
1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        });
1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    CheckCloseSupplier.Input<Reader> brokenRead = newCheckReader(BROKEN_READ);
1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    CheckCloseSupplier.Output<Writer> brokenWrite
1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        = newCheckWriter(BROKEN_WRITE);
1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    CharStreams.copy(okRead, okWrite);
1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(okRead.areClosed());
1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(okWrite.areClosed());
1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      CharStreams.copy(okRead, brokenWrite);
1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("expected exception");
1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (Exception e) {
1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertEquals("broken write", e.getMessage());
1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(okRead.areClosed());
1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(brokenWrite.areClosed());
1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      CharStreams.copy(brokenRead, okWrite);
1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("expected exception");
1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (Exception e) {
1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertEquals("broken read", e.getMessage());
1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(brokenRead.areClosed());
1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(okWrite.areClosed());
1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      CharStreams.copy(brokenRead, brokenWrite);
1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("expected exception");
1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (Exception e) {
1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertEquals("broken read", e.getMessage());
1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(brokenRead.areClosed());
1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(brokenWrite.areClosed());
2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(TEXT, CharStreams.toString(okRead));
2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(okRead.areClosed());
2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
2051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      CharStreams.toString(brokenRead);
2061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("expected exception");
2071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (Exception e) {
2081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertEquals("broken read", e.getMessage());
2091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(brokenRead.areClosed());
2111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
2131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      CharStreams.write("hello world", brokenWrite);
2141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("expected exception");
2151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (Exception e) {
2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertEquals("broken write", e.getMessage());
2171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(brokenWrite.areClosed());
2191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static int getAndResetRecords(TestLogHandler logHandler) {
2221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    int records = logHandler.getStoredLogRecords().size();
2231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    logHandler.clear();
2241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return records;
2251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static void runFailureTest(
2281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      InputSupplier<? extends Reader> in, OutputSupplier<? extends Writer> out) {
2291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
2301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      copy(in, out);
2311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail();
2321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (IOException expected) {
2331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static OutputSupplier<Writer> newStringWriterSupplier() {
2371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new OutputSupplier<Writer>() {
2381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public Writer getOutput() {
2391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return new StringWriter();
2401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
2411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    };
2421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSkipFully_EOF() throws IOException {
2451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Reader reader = new StringReader("abcde");
2461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
2471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      CharStreams.skipFully(reader, 6);
2481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("expected EOFException");
2491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (EOFException e) {
2501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // expected
2511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSkipFully() throws IOException {
2551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    String testString = "abcdef";
2561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Reader reader = new StringReader(testString);
2571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(testString.charAt(0), reader.read());
2591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    CharStreams.skipFully(reader, 1);
2601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(testString.charAt(2), reader.read());
2611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    CharStreams.skipFully(reader, 2);
2621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(testString.charAt(5), reader.read());
2631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(-1, reader.read());
2651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testAsWriter() {
2681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Should wrap Appendable in a new object
2691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Appendable plainAppendable = new StringBuilder();
2701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Writer result = CharStreams.asWriter(plainAppendable);
2711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertNotSame(plainAppendable, result);
2721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertNotNull(result);
2731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // A Writer should not be wrapped
2751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Appendable secretlyAWriter = new StringWriter();
2761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    result = CharStreams.asWriter(secretlyAWriter);
2771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertSame(secretlyAWriter, result);
2781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testWriteString() throws IOException {
2811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final StringWriter sw = new StringWriter();
2821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    String expected = "foo";
2831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    CharStreams.write(expected, new OutputSupplier<Writer>() {
2841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public Writer getOutput() {
2851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return sw;
2861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
2871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    });
2881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(expected, sw.toString());
2891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static CheckCloseSupplier.Input<Reader> newCheckReader(
2921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      InputSupplier<? extends Reader> delegate) {
2931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new CheckCloseSupplier.Input<Reader>(delegate) {
2941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override protected Reader wrap(Reader object, final Callback callback) {
2951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return new FilterReader(object) {
2961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          @Override public void close() throws IOException {
2971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            callback.delegateClosed();
2981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            super.close();
2991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
3001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        };
3011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
3021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    };
3031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static CheckCloseSupplier.Output<Writer> newCheckWriter(
3061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      OutputSupplier<? extends Writer> delegate) {
3071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new CheckCloseSupplier.Output<Writer>(delegate) {
3081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override protected Writer wrap(Writer object, final Callback callback) {
3091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return new FilterWriter(object) {
3101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          @Override public void close() throws IOException {
3111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            callback.delegateClosed();
3121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            super.close();
3131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
3141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        };
3151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
3161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    };
3171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert}
319