diff --git a/src/main/studio/kdb/K.java b/src/main/studio/kdb/K.java index 24d0ff1f..0b55eb03 100755 --- a/src/main/studio/kdb/K.java +++ b/src/main/studio/kdb/K.java @@ -11,6 +11,7 @@ import java.util.*; public class K { + private static final int TO_STRING_MAX_LENGTH = 50_000; private static final SimpleDateFormat formatter = new SimpleDateFormat(); private static final DecimalFormat nsFormatter = new DecimalFormat("000000000"); @@ -101,6 +102,18 @@ public Adverb(K.KBase o) { public Object getObject() { return o; } + + @Override + public String toString(boolean showType) { + try { + LimitedWriter writer = new LimitedWriter(TO_STRING_MAX_LENGTH); + toString(writer, showType); + return writer.toString(); + } catch (IOException e) { + e.printStackTrace(); + return super.toString(showType); + } + } } public static class BinaryPrimitive extends Primitive { @@ -241,12 +254,16 @@ public String getDataType() { } private final int primitive; - private String s = " "; + private final String s; public Primitive(String[] ops, int i) { primitive = i; - if (i >= 0 && i < ops.length) - s = ops[i]; + s = i >= 0 && i < ops.length ? ops[i] : " "; + } + + @Override + public String toString(boolean showType) { + return toString(); } @Override @@ -275,50 +292,32 @@ public Projection(K.KList objs) { this.objs = objs; } - public void toString(LimitedWriter w, boolean showType) throws IOException { - boolean listProjection = false; - if ((objs.getLength() > 0) && (objs.at(0) instanceof UnaryPrimitive)) { - UnaryPrimitive up = (UnaryPrimitive) objs.at(0); - if (up.getPrimitiveAsInt() == 41) // plist - listProjection = true; + @Override + public String toString(boolean showType) { + try { + LimitedWriter writer = new LimitedWriter(TO_STRING_MAX_LENGTH); + toString(writer, showType); + return writer.toString(); + } catch (IOException e) { + e.printStackTrace(); + return super.toString(showType); } + } - if (listProjection) { - w.write("("); - for (int i = 1; i < objs.getLength(); i++) { - if (i > 1) - w.write(";"); - - objs.at(i).toString(w, showType); - } - w.write(")"); - } else { - boolean isFunction = false; - - for (int i = 0; i < objs.getLength(); i++) { - if (i == 0) - if ((objs.at(0) instanceof Function) || (objs.at(0) instanceof UnaryPrimitive) || (objs.at(0) instanceof BinaryPrimitive)) - isFunction = true; - else - w.write("("); + public void toString(LimitedWriter w, boolean showType) throws IOException { + if (objs.getLength() == 0) { + return; + } - if (i > 0) - if (i == 1) - if (isFunction) - w.write("["); - else - w.write(";"); - else - w.write(";"); - - objs.at(i).toString(w, showType); + objs.at(0).toString(w, showType); + w.write('['); + for (int i = 1; i < objs.getLength(); i++) { + if (i > 1) { + w.write(';'); } - - if (isFunction) - w.write("]"); - else - w.write(")"); + objs.at(i).toString(w, showType); } + w.write(']'); } } @@ -561,7 +560,7 @@ public KSymbol(String s) { } public String toString(boolean showType) { - return s; + return showType ? "`" + s : s; } public boolean isNull() { @@ -681,18 +680,15 @@ public boolean isNull() { public String toString(boolean showType) { if (isNull()) - return "0ne"; + return showType ? "0Ne" : "0N"; else if (f == Float.POSITIVE_INFINITY) - return "0we"; + return showType ? "0We" : "0W"; else if (f == Float.NEGATIVE_INFINITY) - return "-0we"; + return showType ? "-0We" : "-0W"; else { String s = Config.getInstance().getNumberFormat().format(f); if (showType) { - double epsilon = 1e-9; - double diff = f - Math.round(f); - if ((diff < epsilon) && (diff > -epsilon)) - s += "e"; + s += "e"; } return s; } @@ -731,18 +727,15 @@ public boolean isNull() { public String toString(boolean showType) { if (isNull()) - return "0n"; + return showType ? "0nf" : "0n"; else if (d == Double.POSITIVE_INFINITY) - return "0w"; + return showType ? "0wf" : "0w"; else if (d == Double.NEGATIVE_INFINITY) - return "-0w"; + return showType ? "-0wf" : "-0w"; else { String s = Config.getInstance().getNumberFormat().format(d); if (showType) { - double epsilon = 1e-9; - double diff = d - Math.round(d); - if ((diff < epsilon) && (diff > -epsilon)) - s += "f"; + s += "f"; } return s; } @@ -875,14 +868,15 @@ public boolean isNull() { } public String toString(boolean showType) { - if (isNull()) - return "0nz"; - else if (time == Double.POSITIVE_INFINITY) - return "0wz"; - else if (time == Double.NEGATIVE_INFINITY) - return "-0wz"; - else - return sd("yyyy.MM.dd HH:mm:ss.SSS", toTimestamp()); + if (isNull()) { + return showType ? "0Nz" : "0N"; + } else if (time == Double.POSITIVE_INFINITY) { + return showType ? "0Wz" : "0W"; + } else if (time == Double.NEGATIVE_INFINITY) { + return showType ? "-0Wz" : "-0W"; + } else { + return sd(showType ? "yyyy.MM.dd HH:mm:ss.SSS'z'" : "yyyy.MM.dd HH:mm:ss.SSS", toTimestamp()); + } } public void toString(LimitedWriter w, boolean showType) throws IOException { @@ -1032,11 +1026,11 @@ public boolean isNull() { public String toString(boolean showType) { if (isNull()) - return "0Nm"; + return showType ? "0Nm" : "0N"; else if (i == Integer.MAX_VALUE) - return "0Wm"; + return showType ? "0Wm" : "0W"; else if (i == -Integer.MAX_VALUE) - return "-0Wm"; + return showType ? "-0Wm" : "-0W"; else { int m = i + 24000, y = m / 12; String s = i2(y / 100) + i2(y % 100) + "." + i2(1 + m % 12); @@ -1238,7 +1232,7 @@ public void append(KBaseVector x) { public final String toString(boolean showType) { try { - LimitedWriter writer = new LimitedWriter(256); + LimitedWriter writer = new LimitedWriter(TO_STRING_MAX_LENGTH); toString(writer, showType); return writer.toString(); } catch (IOException e) { @@ -1379,9 +1373,9 @@ public KBase at(int i) { } void toStringVector(LimitedWriter w, boolean showType) throws IOException { - if (getLength() == 0) + if (getLength() == 0) { w.write("`float$()"); - else { + } else { if (getLength() == 1) w.write(enlist); @@ -1401,14 +1395,11 @@ void toStringVector(LimitedWriter w, boolean showType) throws IOException { w.write("-0w"); printedP = true; } else { - double epsilon = 1e-9; - double diff = d - Math.round(d); - if (!((diff < epsilon) && (diff > -epsilon))) - printedP = true; + printedP = true; w.write(nf.format(d)); } } - if (!printedP) + if (showType && printedP) w.write("f"); } } @@ -1429,9 +1420,9 @@ public KBase at(int i) { } void toStringVector(LimitedWriter w, boolean showType) throws IOException { - if (getLength() == 0) + if (getLength() == 0) { w.write("`real$()"); - else { + } else { if (getLength() == 1) w.write(enlist); @@ -1451,12 +1442,11 @@ void toStringVector(LimitedWriter w, boolean showType) throws IOException { w.write("-0W"); printedP = true; } else { - if (d != ((int) d)) - printedP = true; + printedP = true; w.write(nf.format(d)); } } - if (!printedP) + if (showType && printedP) w.write("e"); } } @@ -1580,7 +1570,7 @@ else if (v == -Integer.MAX_VALUE) w.write(sd("yyyy.MM.dd", new Date(86400000L * (v + 10957)))); } } - if (printD) + if (showType && printD) w.write("d"); } } @@ -1670,27 +1660,23 @@ void toStringVector(LimitedWriter w, boolean showType) throws IOException { if (getLength() == 0) w.write("`datetime$()"); else { - boolean printZ = true; if (getLength() == 1) w.write(enlist); for (int i = 0; i < getLength(); i++) { - if (i > 0) - w.write(" "); double d = Array.getDouble(array, i); if (i > 0) w.write(" "); if (Double.isNaN(d)) w.write("0N"); else if (d == Double.POSITIVE_INFINITY) - w.write("0w"); + w.write("0W"); else if (d == Double.NEGATIVE_INFINITY) - w.write("-0w"); + w.write("-0W"); else { - printZ = false; w.write(sd("yyyy.MM.dd HH:mm:ss.SSS", new Timestamp(((long) (.5 + 8.64e7 * (d + 10957)))))); } } - if (printZ) + if (showType) w.write("z"); } } @@ -1867,7 +1853,6 @@ public void serialise(OutputStream o) throws IOException { } void toStringVector(LimitedWriter w, boolean showType) throws IOException { - w.write(super.toString(showType)); if (getLength() == 0) w.write("`boolean$()"); else { diff --git a/src/main/studio/kdb/LimitedWriter.java b/src/main/studio/kdb/LimitedWriter.java index c902a5fb..cd437a7f 100755 --- a/src/main/studio/kdb/LimitedWriter.java +++ b/src/main/studio/kdb/LimitedWriter.java @@ -4,7 +4,7 @@ import java.io.IOException; public class LimitedWriter extends CharArrayWriter { - private int limit; + private final int limit; public static class LimitException extends RuntimeException { } diff --git a/src/test/studio/kdb/KTest.java b/src/test/studio/kdb/KTest.java index 7c808c74..e7b1829d 100644 --- a/src/test/studio/kdb/KTest.java +++ b/src/test/studio/kdb/KTest.java @@ -2,6 +2,9 @@ import org.junit.Test; +import java.lang.reflect.Array; +import java.util.UUID; + import static org.junit.Assert.assertEquals; public class KTest { @@ -43,15 +46,13 @@ public void testKDoubleVector() { array[i] = i; } - // KDoubleVector like KFloat vector always print "f" if 1 double is an "integer" at 1e-9 - // and never prints it all of them are not assertEquals("0 1 2 3 4f", vector.toString()); - assertEquals("0 1 2 3 4f", vector.toString(false)); + assertEquals("0 1 2 3 4", vector.toString(false)); for (int i = 2; i < 7; i++) { array[i - 2] = 1 / (i * 1.0); } - assertEquals("0.5 0.3333333 0.25 0.2 0.1666667", vector.toString()); + assertEquals("0.5 0.3333333 0.25 0.2 0.1666667f", vector.toString()); assertEquals("0.5 0.3333333 0.25 0.2 0.1666667", vector.toString(false)); } @@ -64,8 +65,7 @@ public void testKFloatVector() { } assertEquals("0 1 2 3 4e", vector.toString()); - // KFloatVector like KDoubleVector always print e at the end - assertEquals("0 1 2 3 4e", vector.toString(false)); + assertEquals("0 1 2 3 4", vector.toString(false)); } @Test @@ -104,4 +104,311 @@ public void testSymbolVector() { assertEquals("`ABC`DEF", vector.toString(false)); } + private void check(K.KBase base, String expectedNoType, String expectedWithType) { + String actualNoType = base.toString(false); + String actualWithType = base.toString(true); + assertEquals("Test to not show type", expectedNoType, actualNoType); + assertEquals("Test to show type", expectedWithType, actualWithType); + } + + + private K.KBaseVector vector(Class clazz, Object... values) throws Exception { + K.KBaseVector baseVector = (K.KBaseVector) clazz.getConstructor(int.class).newInstance(values.length); + Object anArray = baseVector.getArray(); + for (int index=0; index < values.length; index++) { + Array.set(anArray, index, values[index]); + } + return baseVector; + } + + + @Test + public void testIntegerToString() throws Exception { + check(new K.KInteger(-123), "-123", "-123i"); + check(new K.KInteger(-Integer.MAX_VALUE), "-0W", "-0Wi"); + check(new K.KInteger(Integer. MAX_VALUE), "0W", "0Wi"); + check(new K.KInteger(Integer.MIN_VALUE), "0N", "0Ni"); + + check(vector(K.KIntVector.class, -10, 10, 3), "-10 10 3", "-10 10 3i"); + check(vector(K.KIntVector.class), "`int$()", "`int$()"); + check(vector(K.KIntVector.class, 0), "enlist 0", "enlist 0i"); + check(vector(K.KIntVector.class, 5, Integer.MIN_VALUE, Integer.MAX_VALUE, -Integer.MAX_VALUE), "5 0N 0W -0W", "5 0N 0W -0Wi"); + } + + @Test + public void testLongToString() throws Exception { + check(new K.KLong(-123456789), "-123456789", "-123456789j"); + check(new K.KLong(-Long.MAX_VALUE), "-0W", "-0Wj"); + check(new K.KLong(Long.MAX_VALUE), "0W", "0Wj"); + check(new K.KLong(Long.MIN_VALUE), "0N", "0Nj"); + + check(vector(K.KLongVector.class, -10, 10, 3), "-10 10 3", "-10 10 3j"); + check(vector(K.KLongVector.class), "`long$()", "`long$()"); + check(vector(K.KLongVector.class, 0), "enlist 0", "enlist 0j"); + check(vector(K.KLongVector.class, 5, Long.MIN_VALUE, Long.MAX_VALUE, -Long.MAX_VALUE), "5 0N 0W -0W", "5 0N 0W -0Wj"); + } + + @Test + public void testShortToString() throws Exception { + check(new K.KShort((short)-123), "-123", "-123h"); + check(new K.KShort((short) -32767 ), "-0W", "-0Wh"); + check(new K.KShort(Short.MAX_VALUE), "0W", "0Wh"); + check(new K.KShort(Short.MIN_VALUE), "0N", "0Nh"); + + check(vector(K.KShortVector.class, (short)-10, (short)10, (short)3), "-10 10 3", "-10 10 3h"); + check(vector(K.KShortVector.class), "`short$()", "`short$()"); + check(vector(K.KShortVector.class, (short)0), "enlist 0", "enlist 0h"); + check(vector(K.KShortVector.class, (short)5, Short.MIN_VALUE, Short.MAX_VALUE, (short)-Short.MAX_VALUE), "5 0N 0W -0W", "5 0N 0W -0Wh"); + } + + @Test + public void testByteToString() throws Exception { + check(new K.KByte((byte)123), "0x7b", "0x7b"); + check(new K.KByte((byte)0 ), "0x00", "0x00"); + check(new K.KByte((byte)-1 ), "0xff", "0xff"); + check(new K.KByte((byte)127), "0x7f", "0x7f"); + check(new K.KByte((byte)-128), "0x80", "0x80"); + check(new K.KByte((byte)-127), "0x81", "0x81"); + + check(vector(K.KByteVector.class, (byte)-10, (byte)10, (byte)3), "0xf60a03", "0xf60a03"); + check(vector(K.KByteVector.class), "`byte$()", "`byte$()"); + check(vector(K.KByteVector.class, (byte)0), "enlist 0x00", "enlist 0x00"); + check(vector(K.KByteVector.class, (byte)5, (byte)-127, (byte)128, (byte)0), "0x05818000", "0x05818000"); + } + + + @Test + public void testDoubleToString() throws Exception { + check(new K.KDouble(-1.23), "-1.23", "-1.23f"); + check(new K.KDouble(3), "3", "3f"); + check(new K.KDouble(0), "0", "0f"); + check(new K.KDouble(Double.POSITIVE_INFINITY ), "0w", "0wf"); + check(new K.KDouble(Double.NEGATIVE_INFINITY), "-0w", "-0wf"); + check(new K.KDouble(Double.NaN), "0n", "0nf"); + + check(vector(K.KDoubleVector.class, (double)-10, (double)10, (double)3), "-10 10 3", "-10 10 3f"); + check(vector(K.KDoubleVector.class, (double)-10, 10.1, (double)3), "-10 10.1 3", "-10 10.1 3f"); + check(vector(K.KDoubleVector.class), "`float$()", "`float$()"); + check(vector(K.KDoubleVector.class, (double)0), "enlist 0", "enlist 0f"); + check(vector(K.KDoubleVector.class, (double)5, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Double.NaN), "5 -0w 0w 0n", "5 -0w 0w 0nf"); + } + + @Test + public void testFloatToString() throws Exception { + check(new K.KFloat(-1.23f), "-1.23", "-1.23e"); + check(new K.KFloat(3), "3", "3e"); + check(new K.KFloat(0), "0", "0e"); + check(new K.KFloat(Float.POSITIVE_INFINITY ), "0W", "0We"); + check(new K.KFloat(Float.NEGATIVE_INFINITY), "-0W", "-0We"); + check(new K.KFloat(Float.NaN), "0N", "0Ne"); + + check(vector(K.KFloatVector.class, -10f, 10f, 3f), "-10 10 3", "-10 10 3e"); + check(vector(K.KFloatVector.class, -10f, 10.1f, 3f), "-10 10.1000004 3", "-10 10.1000004 3e"); + check(vector(K.KFloatVector.class), "`real$()", "`real$()"); + check(vector(K.KFloatVector.class, 0f), "enlist 0", "enlist 0e"); + check(vector(K.KFloatVector.class, 5f, Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY, Float.NaN), "5 -0W 0W 0N", "5 -0W 0W 0Ne"); + } + + @Test + public void testBooleanToString() throws Exception { + check(new K.KBoolean(false), "0", "0b"); + check(new K.KBoolean(true), "1", "1b"); + + check(vector(K.KBooleanVector.class, true, false), "10b", "10b"); + check(vector(K.KBooleanVector.class), "`boolean$()", "`boolean$()"); + check(vector(K.KBooleanVector.class, true), "enlist 1b", "enlist 1b"); + } + + @Test + public void testCharacterToString() { + check(new K.KCharacter(' '), " ", "\" \""); + check(new K.KCharacter('a'), "a", "\"a\""); + + check(new K.KCharacterVector(" a"), " a", "\" a\""); + check(new K.KCharacterVector(""), "", "\"\""); + check(new K.KCharacterVector("a"), "enlist a", "enlist \"a\""); + } + + @Test + public void testSymbolToString() throws Exception { + check(new K.KSymbol(""), "", "`"); + check(new K.KSymbol("a"), "a", "`a"); + check(new K.KSymbol("ab"), "ab", "`ab"); + check(new K.KSymbol(" "), " ", "` "); + + check(vector(K.KSymbolVector.class, "b", "aa"), "`b`aa", "`b`aa"); + check(vector(K.KSymbolVector.class), "0#`", "0#`"); + check(vector(K.KSymbolVector.class, "", " ", "ab"), "`` `ab", "`` `ab"); + } + + @Test + public void testGuidToString() throws Exception { + check(new K.KGuid(new UUID(12345,-987654)), "00000000-0000-3039-ffff-fffffff0edfa", "00000000-0000-3039-ffff-fffffff0edfa"); + check(new K.KGuid(new UUID(0,0)), "00000000-0000-0000-0000-000000000000", "00000000-0000-0000-0000-000000000000"); + + check(vector(K.KGuidVector.class, new UUID(1,-1), new UUID(0,1), new UUID(-1,0)), "00000000-0000-0001-ffff-ffffffffffff 00000000-0000-0000-0000-000000000001 ffffffff-ffff-ffff-0000-000000000000", "00000000-0000-0001-ffff-ffffffffffff 00000000-0000-0000-0000-000000000001 ffffffff-ffff-ffff-0000-000000000000"); + check(vector(K.KGuidVector.class), "`guid$()", "`guid$()"); + check(vector(K.KGuidVector.class, new UUID(0,0)), "enlist 00000000-0000-0000-0000-000000000000", "enlist 00000000-0000-0000-0000-000000000000"); + } + + @Test + public void testTimestampToString() throws Exception { + check(new K.KTimestamp(-123456789), "1999.12.31 23:59:59.876543211", "1999.12.31 23:59:59.876543211"); + check(new K.KTimestamp(123456), "2000.01.01 00:00:00.000123456", "2000.01.01 00:00:00.000123456"); + check(new K.KTimestamp(-Long.MAX_VALUE), "-0Wp", "-0Wp"); + check(new K.KTimestamp(Long. MAX_VALUE), "0Wp", "0Wp"); + check(new K.KTimestamp(Long.MIN_VALUE), "0Np", "0Np"); + + check(vector(K.KTimestampVector.class, -10, 10, 3), "1999.12.31 23:59:59.999999990 2000.01.01 00:00:00.000000010 2000.01.01 00:00:00.000000003", "1999.12.31 23:59:59.999999990 2000.01.01 00:00:00.000000010 2000.01.01 00:00:00.000000003"); + check(vector(K.KTimestampVector.class), "`timestamp$()", "`timestamp$()"); + check(vector(K.KTimestampVector.class, 0), "enlist 2000.01.01 00:00:00.000000000", "enlist 2000.01.01 00:00:00.000000000"); + check(vector(K.KTimestampVector.class, 5, Long.MIN_VALUE, Long.MAX_VALUE, -Long.MAX_VALUE), "2000.01.01 00:00:00.000000005 0Np 0Wp -0Wp", "2000.01.01 00:00:00.000000005 0Np 0Wp -0Wp"); + } + + @Test + public void testTimespanToString() throws Exception { + check(new K.KTimespan(-765432123456789L), "-8D20:37:12.123456789", "-8D20:37:12.123456789"); + check(new K.KTimespan(123456), "00:00:00.000123456", "00:00:00.000123456"); + check(new K.KTimespan(-Long.MAX_VALUE), "-0Wn", "-0Wn"); + check(new K.KTimespan(Long. MAX_VALUE), "0Wn", "0Wn"); + check(new K.KTimespan(Long.MIN_VALUE), "0Nn", "0Nn"); + + check(vector(K.KTimespanVector.class, -10, 10, 3), "-00:00:00.000000010 00:00:00.000000010 00:00:00.000000003", "-00:00:00.000000010 00:00:00.000000010 00:00:00.000000003"); + check(vector(K.KTimespanVector.class), "`timespan$()", "`timespan$()"); + check(vector(K.KTimespanVector.class, 0), "enlist 00:00:00.000000000", "enlist 00:00:00.000000000"); + check(vector(K.KTimespanVector.class, 5, Long.MIN_VALUE, Long.MAX_VALUE, -Long.MAX_VALUE), "00:00:00.000000005 0Nn 0Wn -0Wn", "00:00:00.000000005 0Nn 0Wn -0Wn"); + } + + @Test + public void testDateToString() throws Exception { + check(new K.KDate(-1234), "1996.08.15", "1996.08.15"); + check(new K.KDate(123456), "2338.01.05", "2338.01.05"); + check(new K.KDate(-Integer.MAX_VALUE), "-0Wd", "-0Wd"); + check(new K.KDate(Integer. MAX_VALUE), "0Wd", "0Wd"); + check(new K.KDate(Integer.MIN_VALUE), "0Nd", "0Nd"); + + check(vector(K.KDateVector.class, -10, 10, 3), "1999.12.22 2000.01.11 2000.01.04", "1999.12.22 2000.01.11 2000.01.04"); + check(vector(K.KDateVector.class), "`date$()", "`date$()"); + check(vector(K.KDateVector.class, 0), "enlist 2000.01.01", "enlist 2000.01.01"); + check(vector(K.KDateVector.class, 5, Integer.MIN_VALUE, Integer.MAX_VALUE, -Integer.MAX_VALUE), "2000.01.06 0N 0W -0W", "2000.01.06 0N 0W -0W"); + } + + @Test + public void testTimeToString() throws Exception { + check(new K.KTime(-1234567890), "17:03:52.110", "17:03:52.110"); + check(new K.KTime(323456789), "17:50:56.789", "17:50:56.789"); + + check(new K.KTime(-Integer.MAX_VALUE), "-0Wt", "-0Wt"); + check(new K.KTime(Integer. MAX_VALUE), "0Wt", "0Wt"); + check(new K.KTime(Integer.MIN_VALUE), "0Nt", "0Nt"); + + check(vector(K.KTimeVector.class, -10, 10, 3), "23:59:59.990 00:00:00.010 00:00:00.003", "23:59:59.990 00:00:00.010 00:00:00.003"); + check(vector(K.KTimeVector.class), "`time$()", "`time$()"); + check(vector(K.KTimeVector.class, 0), "enlist 00:00:00.000", "enlist 00:00:00.000"); + check(vector(K.KTimeVector.class, 5, Integer.MIN_VALUE, Integer.MAX_VALUE, -Integer.MAX_VALUE), "00:00:00.005 0Nt 0Wt -0Wt", "00:00:00.005 0Nt 0Wt -0Wt"); + } + + @Test + public void testMonthToString() throws Exception { + check(new K.Month(-12345), "0971.04", "0971.04m"); + check(new K.Month(123456), "12288.01", "12288.01m"); + check(new K.Month(-Integer.MAX_VALUE), "-0W", "-0Wm"); + check(new K.Month(Integer. MAX_VALUE), "0W", "0Wm"); + check(new K.Month(Integer.MIN_VALUE), "0N", "0Nm"); + + check(vector(K.KMonthVector.class, -10, 10, 3), "1999.03 2000.11 2000.04", "1999.03 2000.11 2000.04m"); + check(vector(K.KMonthVector.class), "`month$()", "`month$()"); + check(vector(K.KMonthVector.class, 0), "enlist 2000.01", "enlist 2000.01m"); + check(vector(K.KMonthVector.class, 5, Integer.MIN_VALUE, Integer.MAX_VALUE, -Integer.MAX_VALUE), "2000.06 0N 0W -0W", "2000.06 0N 0W -0Wm"); + } + + @Test + public void testMinuteToString() throws Exception { + //@ToDo Fix me + check(new K.Minute(-12345), "-205:-45", "-205:-45"); + + check(new K.Minute(123456), "2057:36", "2057:36"); + check(new K.Minute(-Integer.MAX_VALUE), "-0Wu", "-0Wu"); + check(new K.Minute(Integer. MAX_VALUE), "0Wu", "0Wu"); + check(new K.Minute(Integer.MIN_VALUE), "0Nu", "0Nu"); + + check(vector(K.KMinuteVector.class, -10, 10, 3), "00:-10 00:10 00:03", "00:-10 00:10 00:03"); + check(vector(K.KMinuteVector.class), "`minute$()", "`minute$()"); + check(vector(K.KMinuteVector.class, 0), "enlist 00:00", "enlist 00:00"); + check(vector(K.KMinuteVector.class, 5, Integer.MIN_VALUE, Integer.MAX_VALUE, -Integer.MAX_VALUE), "00:05 0Nu 0Wu -0Wu", "00:05 0Nu 0Wu -0Wu"); + } + + @Test + public void testSecondToString() throws Exception { + //@ToDo Fix me + check(new K.Second(-12345), "-03:-25:-45", "-03:-25:-45"); + + check(new K.Second(123456), "34:17:36", "34:17:36"); + check(new K.Second(-Integer.MAX_VALUE), "-0Wv", "-0Wv"); + check(new K.Second(Integer. MAX_VALUE), "0Wv", "0Wv"); + check(new K.Second(Integer.MIN_VALUE), "0Nv", "0Nv"); + + check(vector(K.KSecondVector.class, -10, 10, 3), "00:00:-10 00:00:10 00:00:03", "00:00:-10 00:00:10 00:00:03"); + check(vector(K.KSecondVector.class), "`second$()", "`second$()"); + check(vector(K.KSecondVector.class, 0), "enlist 00:00:00", "enlist 00:00:00"); + check(vector(K.KSecondVector.class, 5, Integer.MIN_VALUE, Integer.MAX_VALUE, -Integer.MAX_VALUE), "00:00:05 0Nv 0Wv -0Wv", "00:00:05 0Nv 0Wv -0Wv"); + } + + @Test + public void testDatetimeToString() throws Exception { + check(new K.KDatetime(-123456.789), "1661.12.26 05:03:50.401", "1661.12.26 05:03:50.401z"); + check(new K.KDatetime(123.456), "2000.05.03 10:56:38.400", "2000.05.03 10:56:38.400z"); + check(new K.KDatetime(Double.NEGATIVE_INFINITY), "-0W", "-0Wz"); + check(new K.KDatetime(Double.POSITIVE_INFINITY), "0W", "0Wz"); + check(new K.KDatetime(Double.NaN), "0N", "0Nz"); + + check(vector(K.KDatetimeVector.class, -10.0, 10.0, 3.0), "1999.12.22 00:00:00.000 2000.01.11 00:00:00.000 2000.01.04 00:00:00.000", "1999.12.22 00:00:00.000 2000.01.11 00:00:00.000 2000.01.04 00:00:00.000z"); + check(vector(K.KDatetimeVector.class), "`datetime$()", "`datetime$()"); + check(vector(K.KDatetimeVector.class, 0.0), "enlist 2000.01.01 00:00:00.000", "enlist 2000.01.01 00:00:00.000z"); + check(vector(K.KDatetimeVector.class, 5.0, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Double.NaN), "2000.01.06 00:00:00.000 -0W 0W 0N", "2000.01.06 00:00:00.000 -0W 0W 0Nz"); + } + + + @Test + public void testListToString() throws Exception { + check(vector(K.KList.class), "()", "()"); + check(vector(K.KList.class, new K.KLong(10), new K.KLong(Long.MAX_VALUE)), "(10;0W)", "(10j;0Wj)"); + check(vector(K.KList.class, new K.KLong(10), new K.KInteger(10)), "(10;10)", "(10j;10i)"); + check(vector(K.KList.class, new K.KLong(10), new K.KInteger(10), vector(K.KList.class, new K.KDouble(1.1))), "(10;10;enlist 1.1)", "(10j;10i;enlist 1.1f)"); + } + + + @Test + public void testOtherToString() throws Exception { + K.Function funcUnary = new K.Function(new K.KCharacterVector("{1+x}")); + K.Function funcBinary = new K.Function(new K.KCharacterVector("{x+y}")); + + check(funcUnary,"{1+x}", "{1+x}"); + check(funcBinary,"{x+y}", "{x+y}"); + + check(new K.FEachLeft(funcBinary), "{x+y}\\:", "{x+y}\\:"); + check(new K.FEachRight(funcBinary), "{x+y}/:", "{x+y}/:"); + check(new K.Feach(funcBinary), "{x+y}'", "{x+y}'"); + check(new K.Fover(funcBinary), "{x+y}/", "{x+y}/"); + check(new K.Fscan(funcBinary), "{x+y}\\", "{x+y}\\"); + check(new K.FPrior(funcBinary), "{x+y}':", "{x+y}':"); + + check(new K.FComposition(new Object[] {funcUnary, funcBinary}), "",""); + check(new K.Projection((K.KList)vector(K.KList.class, funcBinary, new K.KLong(1), new K.UnaryPrimitive(-1))), "{x+y}[1;]", "{x+y}[1j;]"); + check(new K.Projection((K.KList)vector(K.KList.class, funcBinary, new K.UnaryPrimitive(-1), new K.KLong(1))), "{x+y}[;1]", "{x+y}[;1j]"); + + check(new K.BinaryPrimitive(15), "~", "~"); + check(new K.UnaryPrimitive(0), "::", "::"); + check(new K.UnaryPrimitive(41), "enlist", "enlist"); + + //the output from +1 + check(new K.Projection((K.KList)vector(K.KList.class, new K.BinaryPrimitive(1), new K.KLong(1))), "+[1]", "+[1j]"); + //output from '[;] + check(new K.Projection((K.KList)vector(K.KList.class, new K.TernaryOperator(0), new K.UnaryPrimitive(-1), new K.UnaryPrimitive(-1))), "'[;]", "'[;]"); + //output from +/:[1;] + check(new K.Projection((K.KList)vector(K.KList.class, new K.FEachRight(new K.BinaryPrimitive(1)), new K.KLong(1), new K.UnaryPrimitive(-1) ) ),"+/:[1;]", "+/:[1j;]"); + //output from enlist[1;] + check(new K.Projection((K.KList)vector(K.KList.class, new K.UnaryPrimitive(41), new K.KLong(1), new K.UnaryPrimitive(-1) ) ),"enlist[1;]", "enlist[1j;]"); + } + } \ No newline at end of file