001/*
002 * ModeShape (http://www.modeshape.org)
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *       http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.modeshape.common.util;
017
018import static org.hamcrest.core.Is.is;
019import static org.junit.Assert.assertThat;
020import java.io.ByteArrayInputStream;
021import java.io.IOException;
022import java.io.InputStream;
023import java.io.OutputStream;
024import java.io.Reader;
025import java.io.StringReader;
026import java.io.Writer;
027import org.junit.Test;
028
029public class IoUtilTest {
030
031    @Test
032    public void readBytesShouldReturnEmptyByteArrayForNullInputStream() throws Exception {
033        assertThat(IoUtil.readBytes((InputStream)null), is(new byte[] {}));
034    }
035
036    @Test
037    public void readBytesShouldReadInputStreamCorrectlyAndShouldCloseStream() throws Exception {
038        // Read content shorter than buffer size ...
039        String content = "This is the way to grandma's house.";
040        InputStream stream = new ByteArrayInputStream(content.getBytes());
041        InputStreamWrapper wrapper = new InputStreamWrapper(stream);
042        assertThat(wrapper.isClosed(), is(false));
043        byte[] bytes = IoUtil.readBytes(wrapper);
044        String output = new String(bytes);
045        assertThat(output, is(content));
046        assertThat(wrapper.isClosed(), is(true));
047
048        // Read content longer than buffer size ...
049        for (int i = 0; i != 10; ++i) {
050            content += content; // note this doubles each time!
051        }
052        stream = new ByteArrayInputStream(content.getBytes());
053        wrapper = new InputStreamWrapper(stream);
054        assertThat(wrapper.isClosed(), is(false));
055        bytes = IoUtil.readBytes(wrapper);
056        output = new String(bytes);
057        assertThat(output, is(content));
058        assertThat(wrapper.isClosed(), is(true));
059    }
060
061    @Test
062    public void readShouldReturnEmptyStringForNullInputStream() throws Exception {
063        assertThat(IoUtil.read((InputStream)null), is(""));
064    }
065
066    @Test
067    public void readShouldReturnEmptyStringForNullReader() throws Exception {
068        assertThat(IoUtil.read((Reader)null), is(""));
069    }
070
071    @Test
072    public void readShouldReadInputStreamCorrectlyAndShouldCloseStream() throws Exception {
073        // Read content shorter than buffer size ...
074        String content = "This is the way to grandma's house.";
075        InputStream stream = new ByteArrayInputStream(content.getBytes());
076        InputStreamWrapper wrapper = new InputStreamWrapper(stream);
077        assertThat(wrapper.isClosed(), is(false));
078        assertThat(IoUtil.read(wrapper), is(content));
079        assertThat(wrapper.isClosed(), is(true));
080
081        // Read content longer than buffer size ...
082        for (int i = 0; i != 10; ++i) {
083            content += content; // note this doubles each time!
084        }
085        stream = new ByteArrayInputStream(content.getBytes());
086        wrapper = new InputStreamWrapper(stream);
087        assertThat(wrapper.isClosed(), is(false));
088        assertThat(IoUtil.read(wrapper), is(content));
089        assertThat(wrapper.isClosed(), is(true));
090    }
091
092    @Test
093    public void readShouldReadReaderCorrectlyAndShouldCloseStream() throws Exception {
094        // Read content shorter than buffer size ...
095        String content = "This is the way to grandma's house.";
096        Reader reader = new StringReader(content);
097        ReaderWrapper wrapper = new ReaderWrapper(reader);
098        assertThat(wrapper.isClosed(), is(false));
099        assertThat(IoUtil.read(wrapper), is(content));
100        assertThat(wrapper.isClosed(), is(true));
101
102        // Read content longer than buffer size ...
103        for (int i = 0; i != 10; ++i) {
104            content += content; // note this doubles each time!
105        }
106        reader = new StringReader(content);
107        wrapper = new ReaderWrapper(reader);
108        assertThat(wrapper.isClosed(), is(false));
109        assertThat(IoUtil.read(wrapper), is(content));
110        assertThat(wrapper.isClosed(), is(true));
111    }
112
113    protected class InputStreamWrapper extends InputStream {
114
115        private boolean closed = false;
116        private final InputStream stream;
117
118        protected InputStreamWrapper( InputStream stream ) {
119            this.stream = stream;
120        }
121
122        public boolean isClosed() {
123            return closed;
124        }
125
126        @Override
127        public int read() throws IOException {
128            return stream.read();
129        }
130
131        @Override
132        public void close() throws IOException {
133            stream.close();
134            this.closed = true;
135        }
136
137    }
138
139    protected class ReaderWrapper extends Reader {
140
141        private boolean closed = false;
142        private final Reader reader;
143
144        protected ReaderWrapper( Reader reader ) {
145            this.reader = reader;
146        }
147
148        public boolean isClosed() {
149            return closed;
150        }
151
152        @Override
153        public void close() throws IOException {
154            reader.close();
155            this.closed = true;
156        }
157
158        @Override
159        public int read( char[] cbuf,
160                         int off,
161                         int len ) throws IOException {
162            return reader.read(cbuf, off, len);
163        }
164    }
165
166    protected class OutputStreamWrapper extends OutputStream {
167
168        private boolean closed = false;
169        private final OutputStream stream;
170
171        protected OutputStreamWrapper( OutputStream stream ) {
172            this.stream = stream;
173        }
174
175        public boolean isClosed() {
176            return closed;
177        }
178
179        @Override
180        public void close() throws IOException {
181            stream.close();
182            this.closed = true;
183        }
184
185        /**
186         * {@inheritDoc}
187         */
188        @Override
189        public void write( int b ) throws IOException {
190            stream.write(b);
191        }
192
193    }
194
195    protected class WriterWrapper extends Writer {
196
197        private boolean closed = false;
198        private final Writer writer;
199
200        protected WriterWrapper( Writer writer ) {
201            this.writer = writer;
202        }
203
204        public boolean isClosed() {
205            return closed;
206        }
207
208        @Override
209        public void close() throws IOException {
210            writer.close();
211            this.closed = true;
212        }
213
214        /**
215         * {@inheritDoc}
216         */
217        @Override
218        public void flush() throws IOException {
219            writer.flush();
220        }
221
222        /**
223         * {@inheritDoc}
224         */
225        @Override
226        public void write( char[] cbuf,
227                           int off,
228                           int len ) throws IOException {
229            writer.write(cbuf, off, len);
230        }
231
232    }
233
234}