Return-Path: Delivered-To: apmail-jakarta-commons-dev-archive@www.apache.org Received: (qmail 91688 invoked from network); 9 Oct 2006 02:35:32 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 9 Oct 2006 02:35:32 -0000 Received: (qmail 57022 invoked by uid 500); 9 Oct 2006 02:35:30 -0000 Delivered-To: apmail-jakarta-commons-dev-archive@jakarta.apache.org Received: (qmail 56458 invoked by uid 500); 9 Oct 2006 02:35:29 -0000 Mailing-List: contact commons-dev-help@jakarta.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Help: List-Post: List-Id: "Jakarta Commons Developers List" Reply-To: "Jakarta Commons Developers List" Delivered-To: mailing list commons-dev@jakarta.apache.org Received: (qmail 56447 invoked by uid 500); 9 Oct 2006 02:35:29 -0000 Received: (qmail 56444 invoked by uid 99); 9 Oct 2006 02:35:29 -0000 Received: from idunn.apache.osuosl.org (HELO idunn.apache.osuosl.org) (140.211.166.84) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 08 Oct 2006 19:35:29 -0700 X-ASF-Spam-Status: No, hits=-9.4 required=5.0 tests=ALL_TRUSTED,NO_REAL_NAME Received: from [140.211.166.113] ([140.211.166.113:59129] helo=eris.apache.org) by idunn.apache.osuosl.org (ecelerity 2.1.1.8 r(12930)) with ESMTP id 02/34-03466-433A9254 for ; Sun, 08 Oct 2006 18:17:41 -0700 Received: by eris.apache.org (Postfix, from userid 65534) id 9BFCB1A981C; Sun, 8 Oct 2006 18:17:38 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r454248 - in /jakarta/commons/proper/io/trunk/src: java/org/apache/commons/io/input/MockReader.java test/org/apache/commons/io/input/MockReaderTestCase.java Date: Mon, 09 Oct 2006 01:17:38 -0000 To: commons-cvs@jakarta.apache.org From: niallp@apache.org X-Mailer: svnmailer-1.1.0 Message-Id: <20061009011738.9BFCB1A981C@eris.apache.org> X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Author: niallp Date: Sun Oct 8 18:17:37 2006 New Revision: 454248 URL: http://svn.apache.org/viewvc?view=rev&rev=454248 Log: IO-94 - New MockReader implementation Added: jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/input/MockReader.java (with props) jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/input/MockReaderTestCase.java (with props) Added: jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/input/MockReader.java URL: http://svn.apache.org/viewvc/jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/input/MockReader.java?view=auto&rev=454248 ============================================================================== --- jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/input/MockReader.java (added) +++ jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/input/MockReader.java Sun Oct 8 18:17:37 2006 @@ -0,0 +1,293 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.commons.io.input; + +import java.io.EOFException; +import java.io.IOException; +import java.io.Reader; + +/** + * A mock {@link Reader} for testing purposes. + *

+ * This implementation provides a light weight mock + * object for testing with a {@link Reader} + * where the contents don't matter. + *

+ * One use case would be for testing the handling of + * large {@link Reader} as it can emulate that + * scenario without the overhead of actually processing + * large numbers of characters - significantly speeding up + * test execution times. + *

+ * Alternatively, if some kind of data is required as part + * of a test the processChar() and + * processChars() methods can be implemented to generate + * test data. + * + * + * @since Commons IO 1.3 + * @version $Revision$ + */ +public class MockReader extends Reader { + + private long size; + private long position; + private long mark = -1; + private long readlimit; + private boolean eof; + private boolean throwEofException; + private boolean markSupported; + + /** + * Create a mock {@link Reader} of the specified size. + * + * @param size The size of the mock Reader. + */ + public MockReader(long size) { + this(size, true, false); + } + + /** + * Create a mock {@link Reader} of the specified + * size and option settings. + * + * @param size The size of the mock Reader. + * @param markSupported Whether this instance will support + * the mark() functionality. + * @param throwEofException Whether this implementation + * will throw an {@link EOFException} or return -1 when the + * end of file is reached. + */ + public MockReader(long size, boolean markSupported, boolean throwEofException) { + this.size = size; + this.markSupported = markSupported; + this.throwEofException = throwEofException; + } + + /** + * Return the current position. + * + * @return the current position. + */ + public long getPosition() { + return position; + } + + /** + * Return the size of this Mock {@link Reader} + * + * @return the size of the mock Reader. + */ + public long getSize() { + return size; + } + + /** + * Close this Reader - resets the internal state to + * the initial values. + * + * @throws IOException If an error occurs. + */ + public void close() throws IOException { + eof = false; + position = 0; + mark = -1; + } + + /** + * Mark the current position. + * + * @param readlimit The number of characters before this marked position + * is invalid. + * @throws UnsupportedOperationException if mark is not supported. + */ + public synchronized void mark(int readlimit) { + if (!markSupported) { + throw new UnsupportedOperationException("Mark not supported"); + } + mark = position; + this.readlimit = readlimit; + } + + /** + * Indicates whether mark is supported. + * + * @return Whether mark is supported or not. + */ + public boolean markSupported() { + return markSupported; + } + + /** + * Read a character. + * + * @return Either The character value returned by processChar() + * or -1 if the end of file has been reached and + * throwEofException is set to false. + * @throws EOFException if the end of file is reached and + * throwEofException is set to true. + * @throws IOException if trying to read past the end of file. + */ + public int read() throws IOException { + if (eof) { + throw new IOException("Read after end of file"); + } + if (position == size) { + return doEndOfFile(); + } + position++; + return processChar(); + } + + /** + * Read some characters into the specified array. + * + * @param chars The character array to read into + * @return The number of characters read or -1 + * if the end of file has been reached and + * throwEofException is set to false. + * @throws EOFException if the end of file is reached and + * throwEofException is set to true. + * @throws IOException if trying to read past the end of file. + */ + public int read(char[] chars) throws IOException { + return read(chars, 0, chars.length); + } + + /** + * Read the specified number characters into an array. + * + * @param chars The character array to read into. + * @param offset The offset to start reading characters into. + * @param length The number of characters to read. + * @return The number of characters read or -1 + * if the end of file has been reached and + * throwEofException is set to false. + * @throws EOFException if the end of file is reached and + * throwEofException is set to true. + * @throws IOException if trying to read past the end of file. + */ + public int read(char[] chars, int offset, int length) throws IOException { + if (eof) { + throw new IOException("Read after end of file"); + } + if (position == size) { + return doEndOfFile(); + } + position += length; + int returnLength = length; + if (position > size) { + returnLength = length - (int)(position - size); + position = size; + } + processChars(chars, offset, returnLength); + return returnLength; + } + + /** + * Reset the stream to the point when mark was last called. + * + * @throws UnsupportedOperationException if mark is not supported. + * @throws IOException If no position has been marked + * or the read limit has been exceed since the last position was + * marked. + */ + public synchronized void reset() throws IOException { + if (!markSupported) { + throw new UnsupportedOperationException("Mark not supported"); + } + if (mark < 0) { + throw new IOException("No position has been marked"); + } + if (position > (mark + readlimit)) { + throw new IOException("Marked position [" + mark + + "] is no longer valid - passed the read limit [" + + readlimit + "]"); + } + position = mark; + eof = false; + } + + /** + * Skip a specified number of characters. + * + * @param numberOfChars The number of characters to skip. + * @return The number of characters skipped or -1 + * if the end of file has been reached and + * throwEofException is set to false. + * @throws EOFException if the end of file is reached and + * throwEofException is set to true. + * @throws IOException if trying to read past the end of file. + */ + public long skip(long numberOfChars) throws IOException { + if (eof) { + throw new IOException("Skip after end of file"); + } + if (position == size) { + return doEndOfFile(); + } + position += numberOfChars; + long returnLength = numberOfChars; + if (position > size) { + returnLength = numberOfChars - (position - size); + position = size; + } + return returnLength; + } + + /** + * Return a character value for the read() method. + *

+ * N.B. This implementation returns + * zero. + * + * @return This implementation always returns zero. + */ + protected int processChar() { + return 0; + } + + /** + * Process the characters for the read(char[], offset, length) + * method. + *

+ * N.B. This implementation leaves the character + * array unchanged. + * + * @param chars The character array + * @param offset The offset to start at. + * @param length The number of characters. + */ + protected void processChars(char[] chars, int offset, int length) { + } + + /** + * Handle End of File. + * + * @return -1 if throwEofException is + * set to false + * @throws EOFException if throwEofException is set + * to true. + */ + private int doEndOfFile() throws EOFException { + eof = true; + if (throwEofException) { + throw new EOFException(); + } + return -1; + } +} Propchange: jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/input/MockReader.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/input/MockReader.java ------------------------------------------------------------------------------ svn:keywords = Date Author Id Revision HeadURL Added: jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/input/MockReaderTestCase.java URL: http://svn.apache.org/viewvc/jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/input/MockReaderTestCase.java?view=auto&rev=454248 ============================================================================== --- jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/input/MockReaderTestCase.java (added) +++ jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/input/MockReaderTestCase.java Sun Oct 8 18:17:37 2006 @@ -0,0 +1,253 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.commons.io.input; + +import java.io.EOFException; +import java.io.IOException; +import java.io.Reader; + +import junit.framework.TestCase; + +/** + * JUnit Test Case for {@link MockReader}. + * + * @version $Id$ + */ +public class MockReaderTestCase extends TestCase { + + /** Constructor */ + public MockReaderTestCase(String name) { + super(name); + } + + /** Set up */ + protected void setUp() throws Exception { + super.setUp(); + } + + /** Tear Down */ + protected void tearDown() throws Exception { + super.tearDown(); + } + + /** + * Test available() method. + */ + public void testRead() throws Exception { + int size = 5; + TestMockReader reader = new TestMockReader(size); + for (int i = 0; i < size; i++) { + assertEquals("Check Value [" + i + "]", i, reader.read()); + } + + // Check End of File + assertEquals("End of File", -1, reader.read()); + + // Test reading after the end of file + try { + int result = reader.read(); + fail("Should have thrown an IOException, value=[" + result + "]"); + } catch (IOException e) { + assertEquals("Read after end of file", e.getMessage()); + } + + // Close - should reset + reader.close(); + assertEquals("Available after close", 0, reader.getPosition()); + } + + /** + * Test read(char[]) method. + */ + public void testReadCharArray() throws Exception { + char[] chars = new char[10]; + Reader reader = new TestMockReader(15); + + // Read into array + int count1 = reader.read(chars); + assertEquals("Read 1", chars.length, count1); + for (int i = 0; i < count1; i++) { + assertEquals("Check Chars 1", i, chars[i]); + } + + // Read into array + int count2 = reader.read(chars); + assertEquals("Read 2", 5, count2); + for (int i = 0; i < count2; i++) { + assertEquals("Check Chars 2", count1 + i, chars[i]); + } + + // End of File + int count3 = reader.read(chars); + assertEquals("Read 3 (EOF)", -1, count3); + + // Test reading after the end of file + try { + int count4 = reader.read(chars); + fail("Should have thrown an IOException, value=[" + count4 + "]"); + } catch (IOException e) { + assertEquals("Read after end of file", e.getMessage()); + } + + // reset by closing + reader.close(); + + // Read into array using offset & length + int offset = 2; + int lth = 4; + int count5 = reader.read(chars, offset, lth); + assertEquals("Read 5", lth, count5); + for (int i = offset; i < lth; i++) { + assertEquals("Check Chars 3", i, chars[i]); + } + } + + /** + * Test when configured to throw an EOFException at the end of file + * (rather than return -1). + */ + public void testEOFException() throws Exception { + Reader reader = new TestMockReader(2, false, true); + assertEquals("Read 1", 0, reader.read()); + assertEquals("Read 2", 1, reader.read()); + try { + int result = reader.read(); + fail("Should have thrown an EOFException, value=[" + result + "]"); + } catch (EOFException e) { + // expected + } + } + + /** + * Test mark() and reset() methods. + */ + public void testMarkAndReset() throws Exception { + int position = 0; + int readlimit = 10; + Reader reader = new TestMockReader(100, true, false); + + assertTrue("Mark Should be Supported", reader.markSupported()); + + // No Mark + try { + reader.reset(); + fail("Read limit exceeded, expected IOException "); + } catch (Exception e) { + assertEquals("No Mark IOException message", + "No position has been marked", + e.getMessage()); + } + + for (; position < 3; position++) { + assertEquals("Read Before Mark [" + position +"]", position, reader.read()); + } + + // Mark + reader.mark(readlimit); + + // Read further + for (int i = 0; i < 3; i++) { + assertEquals("Read After Mark [" + i +"]", (position + i), reader.read()); + } + + // Reset + reader.reset(); + + // Read From marked position + for (int i = 0; i < readlimit + 1; i++) { + assertEquals("Read After Reset [" + i +"]", (position + i), reader.read()); + } + + // Reset after read limit passed + try { + reader.reset(); + fail("Read limit exceeded, expected IOException "); + } catch (Exception e) { + assertEquals("Read limit IOException message", + "Marked position [" + position + + "] is no longer valid - passed the read limit [" + + readlimit + "]", + e.getMessage()); + } + } + + /** + * Test mark() not supported. + */ + public void testMarkNotSupported() throws Exception { + Reader reader = new TestMockReader(100, false, true); + assertFalse("Mark Should NOT be Supported", reader.markSupported()); + + try { + reader.mark(5); + fail("mark() should throw UnsupportedOperationException"); + } catch (UnsupportedOperationException e) { + assertEquals("mark() error message", "Mark not supported", e.getMessage()); + } + + try { + reader.reset(); + fail("reset() should throw UnsupportedOperationException"); + } catch (UnsupportedOperationException e) { + assertEquals("reset() error message", "Mark not supported", e.getMessage()); + } + } + + /** + * Test skip() method. + */ + public void testSkip() throws Exception { + int skip = 20; + Reader reader = new TestMockReader(10, true, false); + assertEquals("Read 1", 0, reader.read()); + assertEquals("Read 2", 1, reader.read()); + assertEquals("Skip 1", 5, reader.skip(5)); + assertEquals("Read 3", 7, reader.read()); + assertEquals("Skip 2", 2, reader.skip(5)); // only 2 left to skip + assertEquals("Skip 3 (EOF)", -1, reader.skip(5)); // End of file + try { + reader.skip(5); // + fail("Expected IOException for skipping after end of file"); + } catch (Exception e) { + assertEquals("Skip after EOF IOException message", + "Skip after end of file", + e.getMessage()); + } + } + + + // ------------- Test MockReader implementation ------------- + + private static final class TestMockReader extends MockReader { + public TestMockReader(int size) { + super(size); + } + public TestMockReader(int size, boolean markSupported, boolean throwEofException) { + super(size, markSupported, throwEofException); + } + protected int processChar() { + return ((int)getPosition() - 1); + } + protected void processChars(char[] chars, int offset, int length) { + int startPos = (int)getPosition() - length; + for (int i = offset; i < length; i++) { + chars[i] = (char)(startPos + i); + } + } + + } +} Propchange: jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/input/MockReaderTestCase.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/input/MockReaderTestCase.java ------------------------------------------------------------------------------ svn:keywords = Date Author Id Revision HeadURL --------------------------------------------------------------------- To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org For additional commands, e-mail: commons-dev-help@jakarta.apache.org