[armedbear-cvs] r11527 - in trunk/abcl: . src/org/armedbear/lisp test test/src test/src/org test/src/org/armedbear test/src/org/armedbear/lisp

Mark Evenson mevenson at common-lisp.net
Sat Jan 3 12:30:17 UTC 2009


Author: mevenson
Date: Sat Jan  3 12:30:16 2009
New Revision: 11527

Log:
(Phil Hudson) Make FastStringBuffer an adapter to java-1.5's StringBuilder.

JUnit tests integrated into 'build.xml', run via 'ant abcl.test'.

Further integration with other build systems (Lisp and Netbeans) has not been done.



Added:
   trunk/abcl/test/
   trunk/abcl/test/src/
   trunk/abcl/test/src/org/
   trunk/abcl/test/src/org/armedbear/
   trunk/abcl/test/src/org/armedbear/lisp/
   trunk/abcl/test/src/org/armedbear/lisp/FastStringBufferTest.java
Modified:
   trunk/abcl/build.xml
   trunk/abcl/src/org/armedbear/lisp/FastStringBuffer.java

Modified: trunk/abcl/build.xml
==============================================================================
--- trunk/abcl/build.xml	(original)
+++ trunk/abcl/build.xml	Sat Jan  3 12:30:16 2009
@@ -17,19 +17,24 @@
 	      value="${basedir}/dist"/>
     <property name="abcl.jar.path"
 	      value="${dist.dir}/abcl.jar"/>
+    <property name="abcl.ext.dir"
+	      value="${basedir}/ext"/>
+
 
     <target name="help">
       <echo>Main Ant targets:
  abcl.compile  
-   -- compile ABCL to ${build.classes.dir}
+   -- compile ABCL to ${build.classes.dir}.
  abcl.jar      
-   -- create packaged ${abcl.jar.path}
+   -- create packaged ${abcl.jar.path}.
  abcl.wrapper  
-   -- create executable wrapper for ABCL
+   -- create executable wrapper for ABCL.
  abcl.source.zip abcl.source.tar
-    -- create source distributions in ${dist.dir}
+   -- create source distributions in ${dist.dir}.
+ acbl.test.java
+   -- Run junit tests under ${abcl.test.src.dir}.
  abcl.clean 
-    -- remove ABCL intermediate files</echo>
+   -- remove ABCL intermediate files</echo>
       <echo>Corresponding targets for J have been removed.</echo>
     </target>
 
@@ -393,6 +398,56 @@
       </zip>
     </target>
 
+    <property name="abcl.test.classes.dir"
+	      value="${build.dir}/classes-test"/>
+
+    <property name="abcl.test.src.dir"
+	      value="${basedir}/test/src"/>
+
+    <patternset id="abcl.test.source.java">
+      <!-- For now, we list tests explicitly, because we have to
+           enumerate them later to the JUnit test runner. -->
+      <include name="org/armedbear/lisp/FastStringBufferTest.java"/>
+    </patternset>
+
+    <property name="junit-4.5.path"
+	      value="${abcl.ext.dir}/junit-4.5.jar"/>
+
+    <path id="abcl.test.compile.classpath">
+      <pathelement location="${junit-4.5.path}"/>
+      <pathelement location="${build.classes.dir}"/>
+    </path>
+
+    <target name="abcl.test.pre-compile">
+      <mkdir dir="${abcl.ext.dir}"/>
+      <get src="http://downloads.sourceforge.net/junit/junit-4.5.jar?modtime=1218209625"
+	  dest="${junit-4.5.path}"/>
+    </target>
+	
+    <target name="abcl.test.compile" depends="abcl.test.pre-compile,abcl.compile">
+      <mkdir dir="${abcl.test.classes.dir}"/>
+      <javac destdir="${abcl.test.classes.dir}"
+	     classpathref="abcl.test.compile.classpath"
+	     debug="true"
+	     target="1.5">
+	<src path="${abcl.test.src.dir}"/>
+	<patternset refid="abcl.test.source.java"/>
+      </javac>
+    </target>
+
+    <path id="abcl.test.run.classpath">
+      <path refid="abcl.test.compile.classpath"/>
+      <pathelement location="${abcl.test.classes.dir}"/>
+    </path>
+	
+    <target name="abcl.test.java" depends="abcl.test.compile">
+      <java fork="true"
+	    classpathref="abcl.test.run.classpath"
+	    classname="org.junit.runner.JUnitCore">
+	<arg value="org.armedbear.lisp.FastStringBufferTest"/>
+      </java>
+    </target>
+
     <import file="netbeans-build.xml" optional="true"/> 
 <!--    <import file="j-build.xml" optional="true"/>  -->
     <import file="not.org-build.xml" optional="true"/> 

Modified: trunk/abcl/src/org/armedbear/lisp/FastStringBuffer.java
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/FastStringBuffer.java	(original)
+++ trunk/abcl/src/org/armedbear/lisp/FastStringBuffer.java	Sat Jan  3 12:30:16 2009
@@ -2,6 +2,7 @@
  * FastStringBuffer.java
  *
  * Copyright (C) 1998-2005 Peter Graves
+ * Copyright (C) 2008 Phil Hudson
  * $Id$
  *
  * This program is free software; you can redistribute it and/or
@@ -33,128 +34,84 @@
 
 package org.armedbear.lisp;
 
-public final class FastStringBuffer
+/** 
+ * An adaptor of the Java 1.5 java.lang.StringBuilder.
+ * 
+ * "This class should be removed with all references to it replaced
+ *  with java.lang.StringBuilder once enough confidence in this change
+ *  has been gained." -- Phil Hudson 20090202 via <armedbear-j-devel>.
+ */
+public final class FastStringBuffer implements Appendable, CharSequence
 {
   private static final int SPARE_CAPACITY = 128;
 
-  private char[] buffer;
-  private int used;
+  private final StringBuilder builder;
 
   public FastStringBuffer()
   {
-    buffer = new char[SPARE_CAPACITY];
+    this(SPARE_CAPACITY);
   }
 
-  public FastStringBuffer(String s)
+  public FastStringBuffer(String s) 
   {
-    used = s.length();
-    buffer = new char[used + SPARE_CAPACITY];
-    s.getChars(0, used, buffer, 0);
+    builder = new StringBuilder(s);
   }
 
   public FastStringBuffer(char c)
   {
-    used = 1;
-    buffer = new char[1 + SPARE_CAPACITY];
-    buffer[0] = c;
+    this(String.valueOf(c));
   }
 
   public FastStringBuffer(int length) throws NegativeArraySizeException
   {
-    if (length < 0)
-      throw new NegativeArraySizeException();
-    buffer = new char[length];
+    builder = new StringBuilder(length);
   }
 
   public final int length()
   {
-    return used;
+    return builder.length();
   }
 
   public final int capacity()
   {
-    return buffer.length;
+    return builder.capacity();
   }
 
   public final char charAt(int index)
   {
-    try
-      {
-        return buffer[index];
-      }
-    catch (ArrayIndexOutOfBoundsException e)
-      {
-        throw new StringIndexOutOfBoundsException();
-      }
+    return builder.charAt(index);
   }
 
   public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin)
   {
-    if (srcBegin < 0 || srcBegin > srcEnd || srcEnd > used)
-      throw new StringIndexOutOfBoundsException();
-    System.arraycopy(buffer, srcBegin, dst, dstBegin, srcEnd - srcBegin);
+    builder.getChars(srcBegin, srcEnd, dst, dstBegin);
   }
 
   public void setCharAt(int index, char c)
   {
-    try
-      {
-        buffer[index] = c;
-      }
-    catch (ArrayIndexOutOfBoundsException e)
-      {
-        throw new StringIndexOutOfBoundsException();
-      }
+    builder.setCharAt(index, c);
   }
 
   public void ensureCapacity(int minimumCapacity)
   {
-    if (buffer.length < minimumCapacity)
-      {
-        int newCapacity = buffer.length * 2 + 2;
-        if (newCapacity < minimumCapacity)
-          newCapacity = minimumCapacity;
-        char newBuffer[] = new char[newCapacity];
-        System.arraycopy(buffer, 0, newBuffer, 0, used);
-        buffer = newBuffer;
-      }
-  }
-
-  public void setText(String s)
-  {
-    used = 0;
-    append(s);
+    builder.ensureCapacity(minimumCapacity);
   }
 
   public FastStringBuffer append(String s)
   {
-    if (s == null)
-      s = "null";
-    int addedLength = s.length();
-    int combinedLength = used + addedLength;
-    ensureCapacity(combinedLength);
-    s.getChars(0, addedLength, buffer, used);
-    used = combinedLength;
+    builder.append(s);
     return this;
   }
 
   public FastStringBuffer append(char[] chars)
   {
-    if (used + chars.length > buffer.length)
-      ensureCapacity(used + chars.length);
-    System.arraycopy(chars, 0, buffer, used, chars.length);
-    used += chars.length;
+    builder.append(chars);
     return this;
   }
 
   public FastStringBuffer append(char[] chars, int offset, int len)
   {
-    if (offset < 0 || len < 0 || offset + len > chars.length)
-      throw new StringIndexOutOfBoundsException();
-    if (used + len > buffer.length)
-      ensureCapacity(used + len);
-    System.arraycopy(chars, offset, buffer, used, len);
-    used += len;
+    builder.append(chars, offset, len);
     return this;
   }
 
@@ -165,9 +122,7 @@
 
   public FastStringBuffer append(char c)
   {
-    if (used + 1 > buffer.length)
-      ensureCapacity(used + 1);
-    buffer[used++] = c;
+    builder.append(c);
     return this;
   }
 
@@ -183,34 +138,40 @@
 
   public void setLength(int newLength) throws IndexOutOfBoundsException
   {
-    if (newLength < 0)
-      throw new StringIndexOutOfBoundsException(newLength);
-    ensureCapacity(newLength);
-    used = newLength;
+    builder.setLength(newLength);
   }
 
   public FastStringBuffer reverse()
   {
-    final int limit = used / 2;
-    for (int i = 0; i < limit; ++i)
-      {
-        char c = buffer[i];
-        buffer[i] = buffer[used - i - 1];
-        buffer[used - i - 1] = c;
-      }
-    return this;
+    builder.reverse();
+    return this; 
   }
 
   @Override
   public final String toString()
   {
-    return new String(buffer, 0, used);
+    return builder.toString();
   }
 
   public final char[] toCharArray()
   {
-    char[] copy = new char[used];
-    System.arraycopy(buffer, 0, copy, 0, used);
-    return copy;
+    return toString().toCharArray();
   }
+
+   public CharSequence subSequence(int start, int end)
+  {
+    return builder.subSequence(start, end);
+   }
+ 
+   public FastStringBuffer append(CharSequence seq)
+   {
+     builder.append(seq);
+     return this;
+   }
+ 
+   public FastStringBuffer append(CharSequence seq, int start, int end)
+   {
+     builder.append(seq, start, end);
+     return this;
+   }
 }

Added: trunk/abcl/test/src/org/armedbear/lisp/FastStringBufferTest.java
==============================================================================
--- (empty file)
+++ trunk/abcl/test/src/org/armedbear/lisp/FastStringBufferTest.java	Sat Jan  3 12:30:16 2009
@@ -0,0 +1,289 @@
+package org.armedbear.lisp;
+
+import static java.lang.Math.abs;
+import java.util.Random;
+
+import org.junit.After;
+import static org.junit.Assert.*;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.JUnitCore;
+import org.junit.Assert;
+import java.util.Date;
+
+/**
+ * Unit tests for {@link FastStringBuffer}.
+ */
+public class FastStringBufferTest
+{
+    /** Class under test. */
+    private static final Class CLASS = FastStringBuffer.class;
+    private static final Random random = new Random();
+    private static final String CTOR_ARG = "abcde";
+
+    public static void main(final String args[]) {
+        JUnitCore.main("org.armedbear.lisp.FastStringBufferTest");
+    }
+
+    /** Test instance. */
+    private FastStringBuffer buffer = null;
+
+    @Before
+    public void setUp()
+    {
+        buffer = new FastStringBuffer(CTOR_ARG);
+    }
+
+    @After
+    public void tearDown()
+    {
+        buffer = null;
+    }
+
+    @Test
+    public void defaultConstructor()
+    {
+        assertNotNull("Default constructor failed", new FastStringBuffer());
+    }
+
+    @Test
+    public void constructorString()
+    {
+        assertNotNull("String constructor failed",
+                      new FastStringBuffer(CTOR_ARG));
+    }
+
+    @Test
+    public void constructorchar()
+    {
+        assertNotNull("char constructor failed", new FastStringBuffer('c'));
+    }
+
+    @Test
+    public void constructorint()
+    {
+        assertNotNull("int constructor failed", new FastStringBuffer(12));
+    }
+
+    @Test(expected=OutOfMemoryError.class)
+    public void constructorMaxint()
+    {
+        new FastStringBuffer(Integer.MAX_VALUE);
+    }
+
+    @Test(expected=NegativeArraySizeException.class)
+    public void constructorMinint()
+    {
+        new FastStringBuffer(Integer.MIN_VALUE);
+    }
+
+    @Test
+    public void lengthAfterConstructorint()
+    {
+        final FastStringBuffer foo = new FastStringBuffer(234);
+        assertEquals("Length from int constructor not 0", 0, foo.length());
+    }
+
+    @Test
+    public void lengthAfterDefaultConstructor()
+    {
+        assertEquals("Length from default constructor not 0", 0,
+                     new FastStringBuffer().length());
+    }
+
+    @Test
+    public void lengthAfterConstructorString()
+    {
+        final int len = CTOR_ARG.length();
+        assertEquals("Length from String constructor not " + len, len,
+                     new FastStringBuffer(CTOR_ARG).length());
+    }
+
+    @Test
+    public void lengthAfterConstructorchar()
+    {
+        final char w = 'w';
+        final FastStringBuffer newBuffer = new FastStringBuffer(w);
+        final int len = newBuffer.length();
+        assertEquals("Length from char constructor: " + len, 1, len);
+    }
+
+    // Target method to be made private during refactoring
+    // @Test(expect=NoSuchMethodException.class)
+    @Test
+    public void capacity() throws NoSuchMethodException
+    {
+        CLASS.getMethod("capacity", (Class[]) null);
+    }
+
+    @Test
+    public void charAt()
+    {
+        assertEquals("Indexed char unexpected", 'c', buffer.charAt(2));
+    }
+
+    @Test
+    public void getChars()
+    {
+        final char[] dst = {0, 0};
+        final char[] cmp = {'b', 'c'};
+        buffer.getChars(1, 3, dst, 0);
+        assertArrayEquals("Subarray unexpected; cmp: " + new String(cmp) +
+                          ", dst: " + new String(dst), cmp, dst);
+    }
+
+    @Test(expected=StringIndexOutOfBoundsException.class)
+    public void getCharsBadStartIndex()
+    {
+        buffer.getChars(-1, -1, null, 0);
+    }
+
+    @Test(expected=StringIndexOutOfBoundsException.class)
+    public void getCharsInvertedStartEnd()
+    {
+        buffer.getChars(3, 1, null, 0);
+    }
+
+    @Test(expected=StringIndexOutOfBoundsException.class)
+    public void getCharsExcessiveEnd()
+    {
+        buffer.getChars(1, 7, null, 0);
+    }
+
+    @Test
+    public void setCharAt()
+    {
+        buffer.setCharAt(2, 'z');
+        assertEquals("Incorrect setCharAt", "abzde", buffer.toString());
+    }
+
+    @Test(expected=IndexOutOfBoundsException.class)
+    public void setCharAtExcess()
+    {
+        buffer.setCharAt(8, 'x');
+    }
+
+    @Test(expected=StringIndexOutOfBoundsException.class)
+    public void setCharAtNeg()
+    {
+        buffer.setCharAt(-2, 'x');
+    }
+
+    @Test
+    public void ensureCapacity()
+    {
+        buffer.ensureCapacity(200);
+        assertTrue("Unexpected capacity", buffer.capacity() >= 200);
+    }
+
+    @Test(expected=NoSuchMethodException.class)
+    public void setText() throws NoSuchMethodException
+    {
+        FastStringBuffer.class.getMethod("setText");
+    }
+
+    @Test
+    public void append()
+    {
+        buffer.append("fgh");
+        assertEquals("abcdefgh", buffer.toString());
+    }
+
+    @Test
+    public void appendNullString()
+    {
+        buffer.append((String)null);
+        assertEquals("abcdenull", buffer.toString());
+    }
+
+    @Test
+    public void appendcharArray()
+    {
+        buffer.append(new char[]{'x', 'y', 'z'});
+        assertEquals("abcdexyz", buffer.toString());
+    }
+
+    @Test(expected=NullPointerException.class)
+    public void appendNullcharArray()
+    {
+        buffer.append((char []) null);
+    }
+
+    @Test(expected=IndexOutOfBoundsException.class)
+    public void appendWithin()
+    {
+        buffer.append(new char[]{'x', 'y', 'z'}, 1, 3);
+        assertEquals("abcdexyz", buffer.toString());
+    }
+
+    @Test
+    public void appendObject()
+    {
+        buffer.append(new Date());
+        assertTrue(buffer.length() > 5);
+    }
+
+    @Test
+    public void appendchar()
+    {
+        buffer.append('f');
+        assertEquals("abcdef", buffer.toString());
+    }
+
+    @Test
+    public void appendint()
+    {
+        buffer.append(1);
+        assertEquals("abcde1", buffer.toString());
+    }
+
+    @Test
+    public void appendlong()
+    {
+        buffer.append(1L);
+        assertEquals("abcde1", buffer.toString());
+    }
+
+    @Test
+    public void setLength()
+    {
+        buffer.setLength(3);
+        assertEquals("abc", buffer.toString());
+    }
+
+    @Test(expected=IndexOutOfBoundsException.class)
+    public void setLengthNeg()
+    {
+        buffer.setLength(-1);
+    }
+
+    @Test
+    public void setLengthExcess()
+    {
+        buffer.setLength(12);
+        assertEquals(12, buffer.length());
+        // This just seems weird to me
+        assertFalse(CTOR_ARG.equals(buffer.toString()));
+    }
+
+    @Test
+    public void reverse()
+    {
+        buffer.reverse();
+        assertEquals("edcba", buffer.toString());
+    }
+
+    @Test
+    public void testToString()
+    {
+        assertEquals(CTOR_ARG, buffer.toString());
+    }
+
+    @Test
+    public void toCharArray()
+    {
+        assertArrayEquals(new char[] {'a', 'b', 'c', 'd', 'e'},
+                          buffer.toCharArray());
+    }
+
+}




More information about the armedbear-cvs mailing list