Home | History | Annotate | Download | only in testframework
      1 /*
      2  *  Licensed to the Apache Software Foundation (ASF) under one or more
      3  *  contributor license agreements.  See the NOTICE file distributed with
      4  *  this work for additional information regarding copyright ownership.
      5  *  The ASF licenses this file to You under the Apache License, Version 2.0
      6  *  (the "License"); you may not use this file except in compliance with
      7  *  the License.  You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  */
     17 
     18 package org.apache.harmony.testframework;
     19 
     20 import junit.framework.Assert;
     21 import junit.framework.TestCase;
     22 import junit.framework.TestSuite;
     23 
     24 import java.io.IOException;
     25 import java.io.Writer;
     26 import java.util.Arrays;
     27 import java.util.Random;
     28 
     29 /**
     30  * Tests behaviour common to all implementations of {@link Writer}. This adapts
     31  * writers that collects untransformed chars so that they may be tested.
     32  */
     33 public abstract class CharSinkTester {
     34 
     35     private boolean throwsExceptions = true;
     36 
     37     /**
     38      * Creates a new writer ready to receive an arbitrary number of chars. Each
     39      * time this method is invoked, any previously returned writers may be
     40      * discarded.
     41      */
     42     public abstract Writer create() throws Exception;
     43 
     44     /**
     45      * Returns the current set of chars written to the writer last returned by
     46      * {@link #create}, and releases any resources held by that writer.
     47      */
     48     public abstract char[] getChars() throws Exception;
     49 
     50     /**
     51      * Configures whether the writer is expected to throw exceptions when an
     52      * error is encountered. Classes like {@code PrintWriter} report errors via
     53      * an API method instead.
     54      */
     55     public CharSinkTester setThrowsExceptions(boolean throwsExceptions) {
     56         this.throwsExceptions = throwsExceptions;
     57         return this;
     58     }
     59 
     60     public final TestSuite createTests() {
     61         TestSuite result = new TestSuite();
     62         result.addTest(new SinkTestCase("sinkTestNoWriting"));
     63         result.addTest(new SinkTestCase("sinkTestWriteZeroChars"));
     64         result.addTest(new SinkTestCase("sinkTestWriteCharByChar"));
     65         result.addTest(new SinkTestCase("sinkTestWriteArray"));
     66         result.addTest(new SinkTestCase("sinkTestWriteOffset"));
     67         result.addTest(new SinkTestCase("sinkTestWriteLargeArray"));
     68 
     69         if (throwsExceptions) {
     70             result.addTest(new SinkTestCase("sinkTestWriteAfterClose"));
     71         } else {
     72             result.addTest(new SinkTestCase("sinkTestWriteAfterCloseSuppressed"));
     73         }
     74 
     75         return result;
     76     }
     77 
     78     @Override
     79     public String toString() {
     80         return getClass().getName();
     81     }
     82 
     83     private static void assertArrayEquals(char[] expected, char[] actual) {
     84         Assert.assertEquals(Arrays.toString(expected), Arrays.toString(actual));
     85     }
     86 
     87     public class SinkTestCase extends TestCase {
     88 
     89         private SinkTestCase(String name) {
     90             super(name);
     91         }
     92 
     93         public void sinkTestNoWriting() throws Exception {
     94             char[] expected = new char[] { };
     95 
     96             Writer out = create();
     97             out.close();
     98             assertArrayEquals(expected, getChars());
     99         }
    100 
    101         public void sinkTestWriteZeroChars() throws Exception {
    102             char[] expected = new char[] { };
    103 
    104             Writer out = create();
    105             char[] a = new char[1024];
    106             out.write(a, 1000, 0);
    107             out.write(a, 0, 0);
    108             out.write(new char[] { });
    109 
    110             out.close();
    111             assertArrayEquals(expected, getChars());
    112         }
    113 
    114         public void sinkTestWriteCharByChar() throws Exception {
    115             char[] expected = "EFGCDECBA".toCharArray();
    116 
    117             Writer out = create();
    118             for (char c : expected) {
    119                 out.write(c);
    120             }
    121 
    122             out.close();
    123             assertArrayEquals(expected, getChars());
    124         }
    125 
    126         public void sinkTestWriteArray() throws Exception {
    127             char[] expected = "EFGCDECBA".toCharArray();
    128 
    129             Writer out = create();
    130 
    131             out.write("EF".toCharArray());
    132             out.write("GCDE".toCharArray());
    133             out.write("CBA".toCharArray());
    134 
    135             out.close();
    136             assertArrayEquals(expected, getChars());
    137         }
    138 
    139         public void sinkTestWriteOffset() throws Exception {
    140             char[] expected = "EFGCDECBA".toCharArray();
    141             Writer out = create();
    142 
    143             char[] a = new char[1024];
    144             a[1000] = 'E';
    145             a[1001] = 'F';
    146             out.write(a, 1000, 2);
    147 
    148             char[] b = new char[1024];
    149             b[1020] = 'G';
    150             b[1021] = 'C';
    151             b[1022] = 'D';
    152             b[1023] = 'E';
    153             out.write(b, 1020, 4);
    154 
    155             char[] c = new char[1024];
    156             c[0] = 'C';
    157             c[1] = 'B';
    158             c[2] = 'A';
    159             out.write(c, 0, 3);
    160 
    161             out.close();
    162             assertArrayEquals(expected, getChars());
    163         }
    164 
    165         public void sinkTestWriteLargeArray() throws Exception {
    166             Random dice = new Random();
    167             char[] expected = new char[(1024 * 1024) + 1]; // 2 MB + 1 char
    168             for (int c = 0; c < expected.length; c++) {
    169                 expected[c] = (char) ('A' + dice.nextInt(26));
    170             }
    171 
    172             Writer out = create();
    173             out.write(expected);
    174             out.close();
    175 
    176             assertArrayEquals(expected, getChars());
    177         }
    178 
    179         public void sinkTestWriteAfterClose() throws Exception {
    180             char[] expectedChars = "EF".toCharArray();
    181             Writer out = create();
    182 
    183             out.write(expectedChars);
    184             out.close();
    185 
    186             try {
    187                 out.write("GCDE".toCharArray());
    188                 fail("expected already closed exception");
    189             } catch (IOException expected) {
    190             }
    191 
    192             assertArrayEquals(expectedChars, getChars());
    193         }
    194 
    195         public void sinkTestWriteAfterCloseSuppressed() throws Exception {
    196             Writer out = create();
    197             out.write("EF".toCharArray());
    198             out.close();
    199             out.write("GCDE".toCharArray()); // no exception expected!
    200         }
    201 
    202         // adding a new test? Don't forget to update createTests().
    203 
    204         @Override
    205         public String getName() {
    206             return CharSinkTester.this.toString() + ":" + super.getName();
    207         }
    208     }
    209 }
    210