You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by ti...@apache.org on 2014/10/21 20:57:04 UTC

svn commit: r1633434 - /pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/cos/TestCOSFloat.java

Author: tilman
Date: Tue Oct 21 18:57:04 2014
New Revision: 1633434

URL: http://svn.apache.org/r1633434
Log:
PDFBOX-1980: refactored, added deterministic / non-deterministic test; make it easier to add corner cases in the future

Modified:
    pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/cos/TestCOSFloat.java

Modified: pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/cos/TestCOSFloat.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/cos/TestCOSFloat.java?rev=1633434&r1=1633433&r2=1633434&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/cos/TestCOSFloat.java (original)
+++ pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/cos/TestCOSFloat.java Tue Oct 21 18:57:04 2014
@@ -33,12 +33,9 @@ import org.apache.pdfbox.pdfwriter.COSWr
  */
 public class TestCOSFloat extends TestCOSNumber
 {
-    // Use random number to ensure various float values are expressed in the test
-    private Random rnd;
-
+    @Override
     public void setUp()
     {
-        rnd = new Random();
         try
         {
             testCOSBase = COSNumber.get("1.1");
@@ -50,159 +47,257 @@ public class TestCOSFloat extends TestCO
     }
 
     /**
-     * Tests equals() - ensures that the Object.equals() contract is obeyed. These are tested over
-     * a range of arbitrary values to ensure Consistency, Reflexivity, Symmetry, Transitivity and
-     * non-nullity.
+     * base class to run looped tests with float numbers to use it, derive a
+     * class and just implement runTest(). Then either call runTests for a
+     * series of random and pseudorandom tests, or runTest to test with corner
+     * values.
      */
-    public void testEquals()
+    abstract class BaseTester
     {
-        // Consistency
-        for (int i = -100000; i < 300000; i += 20000)
+        private int low = -100000;
+        private int high = 300000;
+        private int step = 20000;
+
+        public void setLoop(int low, int high, int step)
         {
-            float num = i * rnd.nextFloat();
-            COSFloat test1 = new COSFloat(num);
-            COSFloat test2 = new COSFloat(num);
-            COSFloat test3 = new COSFloat(num);
-            // Reflexive (x == x)
-            assertTrue(test1.equals(test1));
-            // Symmetric is preserved ( x==y then y==x)
-            assertTrue(test2.equals(test1));
-            assertTrue(test1.equals(test2));
-            // Transitive (if x==y && y==z then x==z)
-            assertTrue(test1.equals(test2));
-            assertTrue(test2.equals(test3));
-            assertTrue(test1.equals(test3));
-            // Non-nullity
-            assertFalse(test1 == null);
-            assertFalse(test2 == null);
-            assertFalse(test3 == null);
-            
-            float nf = Float.intBitsToFloat(Float.floatToIntBits(num)+1);
-            COSFloat test4 = new COSFloat(nf);
-            assertFalse(test4.equals(test1));
+            this.low = low;
+            this.high = high;
+            this.step = step;
         }
+
+        // deterministic and non-deterministic test
+        public void runTests()
+        {
+            // deterministic test
+            loop(123456);
+
+            // non-deterministic test
+            loop(System.currentTimeMillis());
+        }
+
+        // look through a series of pseudorandom tests influenced by a seed
+        private void loop(long seed)
+        {
+            Random rnd = new Random(seed);
+            for (int i = low; i < high; i += step)
+            {
+                float num = i * rnd.nextFloat();
+                try
+                {
+                    runTest(num);
+                }
+                catch (AssertionError a)
+                {
+                    fail("num = " + num + ", seed = " + seed);
+                }
+            }
+        }
+
+        abstract void runTest(float num);
+
     }
 
     /**
-     * Tests hashCode() - ensures that the Object.hashCode() contract is obeyed over a range of
-     * arbitrary values.
+     * Tests equals() - ensures that the Object.equals() contract is obeyed.
+     * These are tested over a range of arbitrary values to ensure Consistency,
+     * Reflexivity, Symmetry, Transitivity and non-nullity.
      */
-    public void testHashCode()
+    public void testEquals()
     {
-        for (int i = -100000; i < 300000; i += 20000)
+        new BaseTester()
+        {
+            @Override
+            void runTest(float num)
+            {
+                COSFloat test1 = new COSFloat(num);
+                COSFloat test2 = new COSFloat(num);
+                COSFloat test3 = new COSFloat(num);
+                // Reflexive (x == x)
+                assertTrue(test1.equals(test1));
+                // Symmetric is preserved ( x==y then y==x)
+                assertTrue(test2.equals(test3));
+                assertTrue(test1.equals(test2));
+                // Transitive (if x==y && y==z then x==z)
+                assertTrue(test1.equals(test2));
+                assertTrue(test2.equals(test3));
+                assertTrue(test1.equals(test3));
+
+                float nf = Float.intBitsToFloat(Float.floatToIntBits(num) + 1);
+                COSFloat test4 = new COSFloat(nf);
+                assertFalse(test4.equals(test1));
+            }
+        }.runTests();
+    }
+
+    class HashCodeTester extends BaseTester
+    {
+
+        @Override
+        void runTest(float num)
         {
-            float num = i * rnd.nextFloat();
             COSFloat test1 = new COSFloat(num);
             COSFloat test2 = new COSFloat(num);
             assertEquals(test1.hashCode(), test2.hashCode());
-            
-            float nf = Float.intBitsToFloat(Float.floatToIntBits(num)+1);
+
+            float nf = Float.intBitsToFloat(Float.floatToIntBits(num) + 1);
             COSFloat test3 = new COSFloat(nf);
-            assertFalse(test3.hashCode()==test1.hashCode());
+            assertFalse(test3.hashCode() == test1.hashCode());
         }
     }
 
-    @Override
-    public void testFloatValue()
+    /**
+     * Tests hashCode() - ensures that the Object.hashCode() contract is obeyed
+     * over a range of arbitrary values.
+     */
+    public void testHashCode()
+    {
+        new HashCodeTester().runTests();
+    }
+
+    class FloatValueTester extends BaseTester
     {
-        for (int i = -100000; i < 300000; i += 20000)
+
+        @Override
+        void runTest(float num)
         {
-            float num = i * rnd.nextFloat();
             COSFloat testFloat = new COSFloat(num);
             assertEquals(num, testFloat.floatValue());
         }
+
     }
 
     @Override
-    public void testDoubleValue()
+    public void testFloatValue()
+    {
+        new FloatValueTester().runTests();
+    }
+
+    class DoubleValueTester extends BaseTester
     {
-        for (int i = -100000; i < 300000; i += 20000)
+
+        @Override
+        void runTest(float num)
         {
-            float num = i * rnd.nextFloat();
             COSFloat testFloat = new COSFloat(num);
             // compare the string representation instead of the numeric values 
             // as the cast from float to double adds some more fraction digits
             assertEquals(Float.toString(num), Double.toString(testFloat.doubleValue()));
         }
+
     }
 
     @Override
-    public void testIntValue()
+    public void testDoubleValue()
+    {
+        new DoubleValueTester().runTests();
+    }
+
+    class IntValueTester extends BaseTester
     {
-        for (int i = -100000; i < 300000; i += 20000)
+
+        @Override
+        void runTest(float num)
         {
-            float num = i * rnd.nextFloat();
             COSFloat testFloat = new COSFloat(num);
             assertEquals((int) num, testFloat.intValue());
         }
+
     }
 
     @Override
-    public void testLongValue()
+    public void testIntValue()
+    {
+        new IntValueTester().runTests();
+    }
+
+    class LongValueTester extends BaseTester
     {
-        for (int i = -100000; i < 300000; i += 20000)
+
+        @Override
+        void runTest(float num)
         {
-            float num = i * rnd.nextFloat();
             COSFloat testFloat = new COSFloat(num);
             assertEquals((long) num, testFloat.longValue());
         }
+        
     }
-
+    
     @Override
-    public void testAccept()
+    public void testLongValue()
+    {
+        new LongValueTester().runTests();
+    }
+
+    class AcceptTester extends BaseTester
     {
         ByteArrayOutputStream outStream = new ByteArrayOutputStream();
         COSWriter visitor = new COSWriter(outStream);
-        float num = 0;
-        try
+
+        @Override
+        void runTest(float num)
         {
-            for (int i = -100000; i < 300000; i += 20000)
+            try
             {
-                num = i * rnd.nextFloat();
                 COSFloat cosFloat = new COSFloat(num);
                 cosFloat.accept(visitor);
                 assertEquals(floatToString(cosFloat.floatValue()), outStream.toString("ISO-8859-1"));
-                testByteArrays(floatToString(num).getBytes("ISO-8859-1"),
-                        outStream.toByteArray());
+                testByteArrays(floatToString(num).getBytes("ISO-8859-1"), outStream.toByteArray());
                 outStream.reset();
             }
+            catch (IOException e)
+            {
+                fail("Failed to write " + num + " exception: " + e.getMessage());
+            }
         }
-        catch (Exception e)
-        {
-            fail("Failed to write " + num + " exception: " + e.getMessage());
-        }
+
     }
 
-    /**
-     * Tests writePDF() - this method takes an {@link OutputStream} and writes this object to it.
-     */
-    public void testWritePDF()
+    @Override
+    public void testAccept()
+    {
+        new AcceptTester().runTests();
+    }
+
+    class WritePDFTester extends BaseTester
     {
         ByteArrayOutputStream outStream = new ByteArrayOutputStream();
-        float num = 0;
-        try
+
+        public WritePDFTester()
+        {
+            setLoop(-1000, 3000, 200);
+        }
+
+        @Override
+        void runTest(float num)
         {
-            for (int i = -1000; i < 3000; i += 200)
+            try
             {
-                num = i * rnd.nextFloat();
                 COSFloat cosFloat = new COSFloat(num);
                 cosFloat.writePDF(outStream);
                 assertEquals(floatToString(cosFloat.floatValue()), outStream.toString("ISO-8859-1"));
-                testByteArrays(floatToString(num).getBytes("ISO-8859-1"),
-                        outStream.toByteArray());
+                assertEquals(floatToString(num), outStream.toString("ISO-8859-1"));
+                testByteArrays(floatToString(num).getBytes("ISO-8859-1"), outStream.toByteArray());
                 outStream.reset();
             }
-            // test a corner case as described in PDFBOX-1778
-            num = 0.000000000000000000000000000000001f;
-            COSFloat test = new COSFloat(num);
-            test.writePDF(outStream);
-            assertEquals(floatToString(num), outStream.toString("ISO-8859-1"));
-            outStream.reset();
-        }
-        catch (IOException e)
-        {
-            fail("Failed to write " + num + " exception: " + e.getMessage());
+            catch (IOException e)
+            {
+                fail("Failed to write " + num + " exception: " + e.getMessage());
+            }
         }
+
+    }
+
+    /**
+     * Tests writePDF() - this method takes an {@link OutputStream} and writes
+     * this object to it.
+     */
+    public void testWritePDF()
+    {
+        WritePDFTester writePDFTester = new WritePDFTester();
+        writePDFTester.runTests();
+
+        // test a corner case as described in PDFBOX-1778
+        writePDFTester.runTest(0.000000000000000000000000000000001f);
     }
 
     private String floatToString(float value)