Ranides Atterwim 10 anni fa
parent
commit
d37391e928

+ 0 - 2
assira/pom.xml

@@ -81,8 +81,6 @@
                                 <include>net/ranides/assira/reflection/util/ReflectUtils*</include>
                                 
                                 <include>net/ranides/assira/text/LexicalCast*</include>
-                                <include>net/ranides/assira/text/StrBuffer*</include>
-                                <include>net/ranides/assira/text/StrBuffer*</include>
                                 <include>net/ranides/assira/text/StringIO*</include>
                                 
                                 <include>net/ranides/assira/xml/**</include>

+ 13 - 7
assira/src/main/java/net/ranides/assira/text/StrBuffer.java

@@ -16,6 +16,7 @@ import java.util.function.IntFunction;
 import net.ranides.assira.collection.arrays.ArrayUtils;
 import net.ranides.assira.collection.arrays.NativeArray;
 import net.ranides.assira.collection.arrays.NativeArrayUtils;
+import net.ranides.assira.math.MathUtils;
 
 /**
  *
@@ -58,9 +59,13 @@ public class StrBuffer implements Appendable, CharSequence, Serializable {
         if (length < 0) {
             throw new IllegalArgumentException("negative size: " + length);
         }
-        if (length > size) {
+        if (length > capacity()) {
             throw new IllegalArgumentException(length + " is greater than " + capacity());
         }
+        if(length > size) {
+            ArrayUtils.fill(buffer, size, length, c);
+        }
+        
         size = length;
         return this;
     }
@@ -106,11 +111,12 @@ public class StrBuffer implements Appendable, CharSequence, Serializable {
     }
     
     public String getRightFragment(int length) {
-        return new String(buffer, size - length, length);
+        int n = MathUtils.clip(length, 0, size);
+        return new String(buffer, size - n, n);
     }
 
     public String getLeftFragment(int length) {
-        return new String(buffer, 0, length);
+        return new String(buffer, 0, MathUtils.clip(length, 0, size));
     }
 
     public StrBuffer reverse() {
@@ -473,13 +479,13 @@ public class StrBuffer implements Appendable, CharSequence, Serializable {
 
         protected int counter;
 
-        private String endl;
+        private String endl = StringUtils.ENDL;
 
-        private String separator;
+        private String separator = ",";
 
-        private String open;
+        private String open = "";
 
-        private String close;
+        private String close = "";
 
         @Override
         public StrBuilder builder() {

+ 1 - 3
assira/src/test/java/net/ranides/assira/collection/suite/maps/MapTester.java

@@ -998,9 +998,7 @@ public final class MapTester<K,V> {
         assertEquals(0, target.size());
 	}
     
-    // @todo (assira #8) test: MapTester NULL keys
-    
-    // @todo (assira #8) test: MapTester NULL values
+    // @todo (assira #8) test: MapTester NULL keys & values
     
     private void assertRemove(Map<K,V> target, TItem<K,V> item) {
         int size = target.size();

+ 455 - 0
assira/src/test/java/net/ranides/assira/text/StrBufferTest.java

@@ -0,0 +1,455 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/assira
+ */
+package net.ranides.assira.text;
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.BiConsumer;
+import java.util.function.Function;
+import net.ranides.assira.ContractTesters;
+import net.ranides.assira.collection.arrays.NativeArray;
+import static net.ranides.assira.junit.NewAssert.assertEquality;
+import static net.ranides.assira.junit.NewAssert.assertThrows;
+import net.ranides.assira.test.TAdapter;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ * @author Ranides Atterwim <ranides@gmail.com>
+ */
+public class StrBufferTest {
+    
+    @Test
+    public void testUsage() {
+        int[] array = new int[]{0xA2,0xB2,0xC2,0xD2};
+        List<Integer> list1 = Arrays.asList(0xA1,0xB1,0xC1,0xD1);
+        List<Integer> list2 = Arrays.asList(10,11,12,13);
+        List<Integer> list3 = Arrays.asList(3,4,5);
+        
+        StrBuffer sb = new StrBuffer(256);
+        sb
+            .options().open("{ ").close(" }").separator(",");
+        sb
+            .open().append(list1, Integer::toHexString).close()
+            .endl()
+            .open().append(array.length, i -> Integer.toHexString(array[i])).close()
+            .endl();
+        sb
+            .open("<", ">", ":").append(list2).close()
+            .endl()
+            .open("[", "]", " ")
+                .item().append("Q")
+                .item().append("P")
+                .item().open().append(list3).close()
+                .item().open("{","}").append(list3).close()
+            .close()
+            .endl();
+                
+//        System.out.printf("%s%n", sb.toString());
+        
+        String expected = String.format(
+            "{ a1,b1,c1,d1 }%n" +
+            "{ a2,b2,c2,d2 }%n" +
+            "<10:11:12:13>%n" +
+            "[Q P [3 4 5]{3 4 5}}%n"
+        );
+        assertEquals(expected, sb.toString());
+    }
+    
+    @Test
+    public void testOpenClose() {
+        StrBuffer sb = new StrBuffer(256);
+        
+        sb.close();
+        
+        List<Integer> list = Arrays.asList(1,2,3);
+        sb
+            .options().open("{").close("}").separator("-");
+        sb
+            .open().append(list).close().append(" ")
+            .open("<", ">", "+").append(list).append(" ")
+                .open("(", ")").append(list).append(" ")
+                    .open("//").append(list).append(" ").close()
+                .close()
+            .close();
+        
+//        System.out.printf("%s%n", sb.toString());
+
+        assertEquals("{1-2-3} <1+2+3 (1+2+3 //1+2+3 )))", sb.toString());
+        
+        sb.close();
+    }
+    
+    @Test
+    public void testOptions() {
+        StrBuffer sb = new StrBuffer(256);
+        
+        assertThrows(UnsupportedOperationException.class, ()->{
+            sb.options().blank("b1");
+        });
+        assertThrows(UnsupportedOperationException.class, ()->{
+            sb.options().builder();
+        });
+        
+        sb
+            .options().endl("o1").separator("c1");
+        sb
+            .open()
+            .options().endl("o2");
+
+        
+        assertEquals("{ blank='', endl='6F 32', separator='63 31', open='', close='' }", sb.options().toString());
+        sb.close();
+        assertEquals("{ blank='', endl='6F 32', separator='63 31', open='', close='' }", sb.options().toString());
+        sb.close();
+        sb.close();
+
+    }
+    
+    @Test
+    public void testAppend_String() {
+        StrBuffer builder = new StrBuffer(256);
+        
+        // String
+        builder.append();
+        builder.append("Hello ");
+        builder.append();
+        builder.append("..world..", 2, 7);
+        builder.append();
+        
+        assertEquals("Hello world", builder.toString());
+        
+        // char
+        builder.append('!');
+        
+        // CharSequence
+        builder.append(cs(" Quick "));
+        builder.append(cs("..fox.."), 2, 5);
+        
+        assertEquals("Hello world! Quick fox", builder.toString());
+        
+        // StringBuffer
+        builder.append(new StringBuffer(" jumps "));
+        builder.append(new StringBuffer("..over..."), 2, 6);
+        
+        assertEquals("Hello world! Quick fox jumps over", builder.toString());
+        
+        // StringBuilder
+        builder.append(new StringBuilder(" lazy "));
+        builder.append(new StringBuilder("..dog..."), 2, 5);
+        
+        assertEquals("Hello world! Quick fox jumps over lazy dog", builder.toString());
+    }
+    
+    @Test
+    public void testAppend_Chars() {
+        StrBuffer builder = new StrBuffer(256);
+        
+        // char[]
+        builder.append("Quick ".toCharArray());
+        builder.append("..fox..".toCharArray(), 2, 5);
+        
+        assertEquals("Quick fox", builder.toString());
+        
+        // Object
+        builder.append(os(" jumps over lazy dog"));
+        assertEquals("Quick fox jumps over lazy dog", builder.toString());
+    }
+    
+    @Test
+    public void testAppend_Primitive() {
+        StrBuffer builder = new StrBuffer(256);
+
+        // boolean
+        builder
+            .append(true).append(" ")
+            .append(false).append(" ");
+        assertEquals("true false ", builder.toString());
+        
+        // numbers
+        builder
+            .append(334).append(" ")
+            .append(8000L).append(" ")
+            .append(0.5f).append(" ")
+            .append(0.25).append(" ");
+            
+        assertEquals("true false 334 8000 0.5 0.25 ", builder.toString());
+    }
+    
+    @Test
+    public void testAppend_Iterable() {
+        StrBuffer builder = new StrBuffer(256);
+        builder.options()
+            .separator(",")
+            .endl(" / ");
+        
+        // Iterable
+        builder.append(Arrays.asList("a","b","c")).endl();
+        builder.append(Arrays.asList("d")).endl();
+        builder.append(Arrays.asList()).endl();
+        
+        assertEquals("a,b,c / d /  / ", builder.toString());
+        
+        // Iterator
+        builder.append(Arrays.asList("A","B","C").iterator()).endl();
+        builder.append(Arrays.asList("D").iterator()).endl();
+        builder.append(Arrays.asList().iterator()).endl();
+        
+        assertEquals("a,b,c / d /  / A,B,C / D /  / ", builder.toString());
+        
+        // Iterable + Function
+        builder.append(Arrays.asList(11,12,13), v -> String.valueOf(v%10)).endl();
+        builder.append(Arrays.asList(14), v -> String.valueOf(v%10)).endl();
+        builder.append(Arrays.<Integer>asList(), v -> String.valueOf(v%10)).endl();
+        
+        assertEquals("a,b,c / d /  / A,B,C / D /  / 1,2,3 / 4 /  / ", builder.toString());
+        
+        // Iterator + Function
+        builder.append(Arrays.asList(11,12,13).iterator(), v -> String.valueOf(7 * (v%10))).endl();
+        builder.append(Arrays.asList(14).iterator(), v -> String.valueOf(7 * (v%10))).endl();
+        builder.append(Arrays.<Integer>asList().iterator(), v -> String.valueOf(7 * (v%10))).endl();
+        
+        assertEquals("a,b,c / d /  / A,B,C / D /  / 1,2,3 / 4 /  / 7,14,21 / 28 /  / ", builder.toString());
+    }
+    
+    @Test
+    public void testAppend_Array() {
+        StrBuffer builder = new StrBuffer(256);
+        builder.options()
+            .separator(",")
+            .endl(" / ");
+        
+        // array
+        builder.append(new String[]{"a","b","c"}).endl();
+        builder.append(new String[]{"d"}).endl();
+        builder.append(new String[]{}).endl();
+        
+        assertEquals("a,b,c / d /  / ", builder.toString());
+        
+        // array + Function
+        builder.append(new Integer[]{11,12,13}, v -> String.valueOf(v%10)).endl();
+        builder.append(new Integer[]{14}, v -> String.valueOf(v%10)).endl();
+        builder.append(new Integer[]{}, v -> String.valueOf(v%10)).endl();
+        
+        assertEquals("a,b,c / d /  / 1,2,3 / 4 /  / ", builder.toString());
+        
+        // NativeArray
+        builder.append(NativeArray.wrap(new String[]{"A","B","C"})).endl();
+        builder.append(NativeArray.wrap(new String[]{"D"})).endl();
+        builder.append(NativeArray.wrap(new String[]{})).endl();
+        
+        assertEquals("a,b,c / d /  / 1,2,3 / 4 /  / A,B,C / D /  / ", builder.toString());
+        
+        // size + IntFunction
+        builder.append(3, v -> String.valueOf(7*(1+v)) ).endl();
+        builder.append(1, v -> String.valueOf(7*(1+v)) ).endl();
+        builder.append(0, v -> String.valueOf(7*(1+v)) ).endl();
+        
+        assertEquals("a,b,c / d /  / 1,2,3 / 4 /  / A,B,C / D /  / 7,14,21 / 7 /  / ", builder.toString());
+
+    }
+      
+
+    @Test
+    public void testResize() {
+        StrBuffer sb = new StrBuffer(128);
+        sb.append("Hello world");
+
+        sb.resize(8, '.');
+        assertEquals("Hello wo", sb.toString());
+                
+        sb.resize(12, '.');
+        assertEquals("Hello wo....", sb.toString());
+        
+        assertThrows(IllegalArgumentException.class, ()->{
+            sb.resize(-5, '.');
+        });
+        assertThrows(IllegalArgumentException.class, ()->{
+            sb.resize(160, '.');
+        });
+        
+        sb.resize(0, '.');
+        assertEquals("", sb.toString());
+    }
+    
+    @Test
+    public void testClear() {
+        StrBuffer sb = new StrBuffer(32);
+        sb.append("Hello world");
+        assertEquals(32, sb.capacity());
+        assertEquals(11, sb.length());
+        
+        sb.clear();
+        assertEquals(32, sb.capacity());
+        assertEquals(0, sb.length());
+        assertEquals("", sb.toString());
+    }
+    
+    @Test
+    public void testSequence() {
+        StrBuffer sb = new StrBuffer(11).append("Hello world");
+        
+        StringTester.assertString("Hello world", sb);
+        StringTester.assertString("ello wo", sb.subSequence(1, 8));
+        
+        sb.setCharAt(0, 'h');
+        sb.setCharAt(1, 'a');
+        StringTester.assertString("hallo world", sb);
+        
+        assertThrows(IndexOutOfBoundsException.class, ()->{
+            sb.setCharAt(-1, 'z');
+        });
+        assertThrows(IndexOutOfBoundsException.class, ()->{
+            sb.setCharAt(53, 'z');
+        });
+    }
+    
+    @Test
+    public void testGetChars() {
+        StrBuffer sb = new StrBuffer(32).append("Hello world");
+        
+        assertArrayEquals("Hello world".toCharArray(), sb.getChars());
+        
+        assertArrayEquals("llo wo".toCharArray(), sb.getChars(2,8));
+        assertArrayEquals("".toCharArray(), sb.getChars(2,2));
+
+        assertArrayEquals("llo world\000\000".toCharArray(), sb.getChars(2,13));
+        assertArrayEquals("".toCharArray(), sb.getChars(13,13));
+
+
+        assertThrows(IndexOutOfBoundsException.class, ()->{
+            sb.getChars(-1,3);
+        });
+        
+        char[] a = "###########...".toCharArray();
+        sb.getChars(a);
+        assertArrayEquals("Hello world...".toCharArray(), a);
+        
+        char[] b = "###########...".toCharArray();
+        sb.getChars(2,8,b,3);
+        assertArrayEquals("###llo wo##...".toCharArray(), b);
+    }
+    
+    @Test
+    public void testFragmet() {
+        StrBuffer sb = new StrBuffer(32).append("Hello world");
+        
+        assertEquals("", sb.getLeftFragment(0));
+        assertEquals("Hell", sb.getLeftFragment(4));
+        assertEquals("Hello world", sb.getLeftFragment(60));
+        
+        assertEquals("", sb.getRightFragment(0));
+        assertEquals("orld", sb.getRightFragment(4));
+        assertEquals("Hello world", sb.getRightFragment(60));
+    }
+    
+    @Test
+    public void testReverse() {
+        StrBuffer sb = new StrBuffer(32).append("Hello world");
+        
+        sb.reverse();
+        assertEquals("dlrow olleH", sb.toString());
+        sb.append("!");
+        assertEquals("dlrow olleH!", sb.toString());
+        sb.reverse();
+        sb.append("?");
+        assertEquals("!Hello world?", sb.toString());
+    }
+    
+    @Test
+    public void testToBuilder() {
+        StrBuffer sb = new StrBuffer(32).append("Hello world");
+        assertEquals("Hello world!", sb.toBuilder().append("!").toString());
+        assertEquals("Hello world", sb.toString());
+    }
+    
+    @Test
+    @SuppressFBWarnings("EC_UNRELATED_TYPES")
+    public void testEquals() {
+        StrBuffer a = new StrBuffer(16).append("Hello");
+        StrBuffer b = new StrBuffer(160).append("He").append("llo");
+        StrBuffer c = new StrBuffer(160).append("He").append("ll!");
+        
+        assertTrue(a.equals(a));
+        
+        assertFalse(a.equals(null));
+        assertFalse(a.equals(new Object()));
+        
+        assertFalse(a.equals(new StrBuffer(160).append("Hallo")));
+        assertFalse(a.equals(new StrBuffer(160).append("Hello!")));
+        
+        assertFalse(a.equals("Hello!"));
+        assertFalse(a.equals("Hella"));
+        
+        assertTrue(a.equals("Hello"));
+
+        assertTrue(a.equals(b));
+        assertEquality(a, b, c);
+    }
+    
+    @Test
+    public void testWriter() throws IOException {
+        StrBuffer sb = new StrBuffer(256);
+        Writer writer = sb.asWriter();
+        sb.append("Hello ");
+        
+        // #close should be NOP
+        writer.close(); 
+        
+        writer.write('w');
+        writer.write("orld. ".toCharArray());
+        writer.write("##tex..".toCharArray(), 2, 5);
+        writer.write("t :)");
+        writer.write("##EOF..", 2, 5);
+        
+        // we don't have to use #flush
+        
+        assertEquals("Hello world. text :)EOF", sb.toString());
+    }
+    
+    @Test
+    public void testReader() throws IOException {
+        TAdapter<Reader, StrBuffer> map = new TAdapter<>();
+        
+        Function<String, Reader> rf = map.map(
+            (String text) -> new StrBuffer(256).append(text), builder -> builder.asReader()
+        );
+        BiConsumer<Reader, String> ra = (reader, text) -> {
+            map.get(reader).append(text);
+        };
+        ContractTesters.runner()
+            .param("reader.appender!", ra)
+            .function("", rf)
+			.run();
+        assertTrue(true);
+    }
+    
+    @Test
+    public void testHashcode() {
+        assertEquals(Arrays.hashCode("Hello".toCharArray()), new StrBuffer(32).append("Hello").hashCode());
+    }
+
+    
+    private static CharSequence cs(String value) {
+        return StringUtils.wrap(value.toCharArray());
+    }
+    
+    private static Object os(String value) {
+        return new Object(){
+            @Override
+            public String toString() {
+                return value;
+            }
+        };
+    }
+    
+}