Forráskód Böngészése

fix: DataAdapter#asReader#read
fix: DataAdapter#asReader#skip

Ranides Atterwim 10 éve
szülő
commit
4a25a1470f

+ 4 - 2
assira/src/main/java/net/ranides/assira/io/DataAdapter.java

@@ -250,6 +250,7 @@ public final class DataAdapter {
             int ret = 0;
             if(last != null) {
                 target[offset++] = last;
+                ret++;
                 last = null;
             } else {
                 try {
@@ -278,9 +279,10 @@ public final class DataAdapter {
             }
             if(last != null) {
                 last = null;
-                count--;
+                return idata.skipBytes(2*(int)count - 2) / 2 + 1;
+            } else {
+                return idata.skipBytes(2*(int)count) / 2;
             }
-            return idata.skipBytes(2*(int)count) / 2;
         }
 
         @Override

+ 13 - 14
assira/src/test/java/net/ranides/assira/io/DataAdapterTest.java

@@ -10,6 +10,7 @@ import java.io.DataInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.Reader;
+import java.util.function.Function;
 import net.ranides.assira.ContractTesters;
 import net.ranides.assira.collection.arrays.ArrayUtils;
 import net.ranides.assira.test.TReader;
@@ -29,25 +30,18 @@ public class DataAdapterTest {
     @Test
     public void testAsReader() throws IOException {
         // @todo (assira #0) DataBuffer implements DataInput, DataOutput
-        // @todo (assira #2) ContractTesterRunner support for testMethod(Function<String,Interface> generator)
-        //      ponieważ to trudne, to może po prostu ReaderTester będzie konwertował String na byte ?
-        //      to chyba nie przejdzie
-        //      oczywiście, że przejdzie. przecież przekazujemy int[]
-        //      możemy String <-> codepoints konwertować jednoznacznie
-        //      przekażemy int[] a potem sobie z tego String zrobimy i wykorzystamy po prostru TReader#append(string)
-        //      żadnych modyfikacji w assira.junit
-        //
-        //      w praktyce to po prostu kolejny test-case będzie w testerze.
-        //      w teście po prostu musimy zmyślną funkcję-generator napisać i przekazywać do TesterRunner#run
         
-        
-        TReader tr = (Reader r, String v) -> {
+        TReader tr = (r, v) -> {
             ((FDStream)((DataAdapter.DIReader)r).idata).append(v);
         };
+        Function<int[], Reader> mr = (array) -> {
+            return DataAdapter.asReader(new FDStream(array));
+        };
         ContractTesters.runner()
+            .debug(true)
+            .ignore("ReaderTester.mark")
             .param("reader!", tr)
-            .ignore("ReaderTester.functionalMark")
-            .run(()->DataAdapter.asReader(new FDStream()));
+            .run(mr);
         
         assertEquals("Hello world", TReader.decode(TReader.encode("Hello world")));
     }
@@ -58,6 +52,11 @@ public class DataAdapterTest {
             super(new FIStream());
         }
         
+        public FDStream(int[] content) {
+            this();
+            append(TReader.decode(content));
+        }
+        
         public void append(String value) {
             FIStream fis = ((FIStream)in);
             fis.buffer = ArrayUtils.concat(fis.buffer, value.getBytes(Charsets.UTF16BE));

+ 105 - 6
assira/src/test/java/net/ranides/assira/text/ReaderTester.java

@@ -8,13 +8,11 @@ package net.ranides.assira.text;
 
 import java.io.IOException;
 import java.io.Reader;
+import java.util.function.Function;
 import javax.annotation.Resource;
 import net.ranides.assira.junit.TestContract;
 import net.ranides.assira.test.TReader;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.*;
 
 /**
  *
@@ -26,7 +24,74 @@ public class ReaderTester {
     private TReader tr;
     
     @TestContract
-    public void functionalRead(Reader reader) throws IOException {
+    public void readBasic(Function<int[], Reader> f) throws IOException {
+        Reader reader = f.apply(TReader.encode("Hello world"));
+        
+        // #close should be NOP
+        reader.close();
+        
+        int a = reader.read();
+        assertEquals('H', (char)a);
+        
+        char[] b = ".##...".toCharArray();
+        assertEquals(2, reader.read(b, 1, 2));
+        assertArrayEquals(".el...".toCharArray(), b);
+
+        assertEquals(0, reader.skip(-5));        
+        assertEquals(5, reader.skip(5));
+        
+        assertTrue(reader.ready());
+        assertTrue(reader.ready());
+        
+        char[] c = ".###...".toCharArray();
+        assertEquals(3, reader.read(c, 1, 4));
+        assertArrayEquals(".rld...".toCharArray(), c);
+        
+        assertFalse(reader.ready());
+        assertFalse(reader.ready());
+        
+        assertEquals(0, reader.skip(3));
+        assertEquals(-1, reader.read());
+       
+        reader.close();
+    }
+    
+    @TestContract
+    public void readEOF(Function<int[], Reader> f) throws IOException {
+        Reader reader1 = f.apply(TReader.encode("Hello world"));
+        
+        char a1[] = new char[6];
+        assertEquals(6, reader1.read(a1));
+        assertArrayEquals("Hello ".toCharArray(), a1);
+        
+        char b1[] = "#####....".toCharArray();
+        assertEquals(5, reader1.read(b1));
+        assertArrayEquals("world....".toCharArray(), b1);
+        
+        assertEquals(-1, reader1.read(b1));
+        assertFalse(reader1.ready());
+        reader1.close();
+        
+        
+        Reader reader2 = f.apply(TReader.encode("Hello world"));
+        
+        char a2[] = new char[6];
+        assertEquals(6, reader2.read(a2));
+        assertArrayEquals("Hello ".toCharArray(), a2);
+        
+        assertTrue(reader2.ready());
+        
+        char b2[] = "#####....".toCharArray();
+        assertEquals(5, reader2.read(b2));
+        assertArrayEquals("world....".toCharArray(), b2);
+        
+        assertFalse(reader2.ready());
+        assertEquals(-1, reader2.read(b2));
+        reader2.close();
+    }
+    
+    @TestContract
+    public void readBasic_Append(Reader reader) throws IOException {
         tr.append(reader, "Hello world");
         
         // #close should be NOP
@@ -65,7 +130,7 @@ public class ReaderTester {
     }
     
     @TestContract
-    public void functionalMark(Reader reader) throws IOException {
+    public void mark(Reader reader) throws IOException {
         
         tr.append(reader, "text.");
         assertTrue(reader.ready());
@@ -87,4 +152,38 @@ public class ReaderTester {
         reader.close();
     }
     
+    @TestContract
+    public void skip(Function<int[], Reader> f) throws IOException {
+        Reader reader = f.apply(TReader.encode("Quick fox jumps over lazy dog."));
+        
+        assertEquals(0,reader.skip(0));
+        assertRead("Qui", reader);
+        
+        assertTrue(reader.ready());
+        assertEquals(0,reader.skip(0));
+        assertRead("ck ", reader);
+        
+        assertEquals(2,reader.skip(2));
+        assertRead("x j", reader);
+        
+        assertTrue(reader.ready());
+        assertEquals(2,reader.skip(2));
+        assertRead("ps ", reader);
+        
+        assertEquals(6,reader.skip(6));
+        assertEquals((int)'a', reader.read());
+        
+        assertEquals(7,reader.skip(10));
+        assertEquals(-1, reader.read());
+        assertFalse(reader.ready());
+        
+        reader.close();
+    }
+    
+    private static void assertRead(String expected, Reader reader) throws IOException {
+        char[] buffer = new char[expected.length()];
+        assertEquals(expected.length(), reader.read(buffer));
+        assertArrayEquals(expected.toCharArray(), buffer);
+    }
+    
 }

+ 1 - 1
assira/src/test/java/net/ranides/assira/text/StrBuilderTest.java

@@ -464,7 +464,7 @@ public class StrBuilderTest {
     public void testReader() throws IOException {
         ContractTesters.runner()
             .param("reader!", (TReader)StrBuilder::reader_append)
-            .run(()->new StrBuilder().asReader());
+            .run((array) -> new StrBuilder().append(TReader.decode(array)).asReader());
     }
     
     @Test