diff --git a/main/src/com/google/refine/expr/functions/arrays/Uniques.java b/main/src/com/google/refine/expr/functions/arrays/Uniques.java index ed78bd370..f5414c485 100644 --- a/main/src/com/google/refine/expr/functions/arrays/Uniques.java +++ b/main/src/com/google/refine/expr/functions/arrays/Uniques.java @@ -33,7 +33,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.google.refine.expr.functions.arrays; -import java.util.HashSet; +import java.util.Arrays; +import java.util.LinkedHashSet; import java.util.List; import java.util.Properties; import java.util.Set; @@ -51,25 +52,18 @@ public class Uniques implements Function { public Object call(Properties bindings, Object[] args) { if (args.length == 1) { Object v = args[0]; - + if (v != null) { if (v instanceof ArrayNode) { v = JSONUtilities.toArray((ArrayNode) v); } - - if (v.getClass().isArray() || v instanceof List) { - Set set = null; - - if (v.getClass().isArray()) { - Object[] a = (Object[]) v; - - set = new HashSet(a.length); - for (Object element : a) { - set.add(element); - } - } else { - set = new HashSet(ExpressionUtils.toObjectList(v)); - } + Set set = null; + if (v.getClass().isArray()) { + set = new LinkedHashSet(Arrays.asList((Object[]) v)); + } else if (v instanceof List) { + set = new LinkedHashSet(ExpressionUtils.toObjectList(v)); + } + if (set != null) { return set.toArray(); } } diff --git a/main/tests/server/src/com/google/refine/expr/functions/arrays/JoinTests.java b/main/tests/server/src/com/google/refine/expr/functions/arrays/JoinTests.java index dc06c9b25..47bfdd061 100644 --- a/main/tests/server/src/com/google/refine/expr/functions/arrays/JoinTests.java +++ b/main/tests/server/src/com/google/refine/expr/functions/arrays/JoinTests.java @@ -28,13 +28,35 @@ package com.google.refine.expr.functions.arrays; import org.testng.annotations.Test; +import com.google.refine.RefineTest; +import com.google.refine.expr.ParsingException; import com.google.refine.util.TestUtils; -public class JoinTests { +public class JoinTests extends RefineTest { @Test public void serializeJoin() { String json = "{\"description\":\"Returns the string obtained by joining the array a with the separator sep\",\"params\":\"array a, string sep\",\"returns\":\"string\"}"; TestUtils.isSerializedTo(new Join(), json); } + + @Test + public void joinArray() throws ParsingException { + String[] test = {"[2,1,3].join('|')", "2|1|3"}; + parseEval(bindings, test); + + // TODO: This is current behavior, but is it what we want? + String[] test1 = {"[2,null,3].join(', ')", "2, 3"}; + parseEval(bindings, test1); + + String[] test2 = {"['z','b','c','a'].join('-')", "z-b-c-a"}; + parseEval(bindings, test2); + + // TODO: Do we really want the following two tests to return different results? + String[] test3 = {"['z', null,'c','a'].join('-')", "z-c-a"}; + parseEval(bindings, test3); + String[] test4 = {"['z', '','c','a'].join('-')", "z--c-a"}; + parseEval(bindings, test4); + } + } diff --git a/main/tests/server/src/com/google/refine/expr/functions/arrays/ReverseTests.java b/main/tests/server/src/com/google/refine/expr/functions/arrays/ReverseTests.java index 283ad34ca..81c31e003 100644 --- a/main/tests/server/src/com/google/refine/expr/functions/arrays/ReverseTests.java +++ b/main/tests/server/src/com/google/refine/expr/functions/arrays/ReverseTests.java @@ -28,13 +28,38 @@ package com.google.refine.expr.functions.arrays; import org.testng.annotations.Test; +import com.google.refine.RefineTest; +import com.google.refine.expr.ParsingException; import com.google.refine.util.TestUtils; -public class ReverseTests { +public class ReverseTests extends RefineTest { @Test public void serializeReverse() { String json = "{\"description\":\"Reverses array a\",\"params\":\"array a\",\"returns\":\"array\"}"; TestUtils.isSerializedTo(new Reverse(), json); } + + @Test + public void reverseJsonArray() throws ParsingException { + String[] test = {"'[2,1,3]'.parseJson().reverse().toString()", "[3, 1, 2]"}; + parseEval(bindings, test); + String[] test1 = {"'[2,null,3]'.parseJson().reverse().toString()", "[3, null, 2]"}; + parseEval(bindings, test1); + } + + @Test + public void reverseArray() throws ParsingException { + String[] test = {"[2,1,3].reverse().toString()", "[3, 1, 2]"}; + parseEval(bindings, test); + String[] test1 = {"[2,null,3].reverse().toString()", "[3, null, 2]"}; + parseEval(bindings, test1); + + String[] test2 = {"['z','b','c','a'].reverse().toString()", "[a, c, b, z]"}; + parseEval(bindings, test2); + String[] test3 = {"['z',null,'c','a'].reverse().toString()", "[a, c, null, z]"}; + parseEval(bindings, test3); + } + + } diff --git a/main/tests/server/src/com/google/refine/expr/functions/arrays/SortTests.java b/main/tests/server/src/com/google/refine/expr/functions/arrays/SortTests.java index ff8b62e25..4a2879a7d 100644 --- a/main/tests/server/src/com/google/refine/expr/functions/arrays/SortTests.java +++ b/main/tests/server/src/com/google/refine/expr/functions/arrays/SortTests.java @@ -64,6 +64,7 @@ public class SortTests extends RefineTest { parseEval(bindings, test4); } + @Test public void sortMixedArray() throws ParsingException { String test = "[2,1.0,3].sort().toString()"; parseEvalType(bindings, test, EvalError.class); diff --git a/main/tests/server/src/com/google/refine/expr/functions/arrays/UniquesTests.java b/main/tests/server/src/com/google/refine/expr/functions/arrays/UniquesTests.java index ca85c6e37..fcb38ce86 100644 --- a/main/tests/server/src/com/google/refine/expr/functions/arrays/UniquesTests.java +++ b/main/tests/server/src/com/google/refine/expr/functions/arrays/UniquesTests.java @@ -28,13 +28,51 @@ package com.google.refine.expr.functions.arrays; import org.testng.annotations.Test; +import com.google.refine.RefineTest; +import com.google.refine.expr.ParsingException; import com.google.refine.util.TestUtils; -public class UniquesTests { +public class UniquesTests extends RefineTest { @Test public void serializeUniques() { String json = "{\"description\":\"Returns array a with duplicates removed\",\"params\":\"array a\",\"returns\":\"array\"}"; TestUtils.isSerializedTo(new Uniques(), json); } + + @Test + public void uniquesJsonArray() throws ParsingException { + String[] test = {"'{a:[2,1,1,3]}'.parseJson().a.uniques().toString()", "[2, 1, 3]"}; + parseEval(bindings, test); + String[] test1 = {"'[2,2,null,null,3,3]'.parseJson().uniques().toString()", "[2, null, 3]"}; + parseEval(bindings, test1); + } + + @Test + public void uniquesArray() throws ParsingException { + String[] test = {"[2,1,1,3].uniques().toString()", "[2, 1, 3]"}; + parseEval(bindings, test); + String[] test1 = {"[2,2,null,null,3,3,3].uniques().toString()", "[2, null, 3]"}; + parseEval(bindings, test1); + + String[] test2 = {"['z','b','c','c','a'].uniques().toString()", "[z, b, c, a]"}; + parseEval(bindings, test2); + String[] test3 = {"['z','z',null,'c','a'].uniques().toString()", "[z, null, c, a]"}; + parseEval(bindings, test3); + + String[] test4 = {"[toDate(2020), '2018-03-02'.toDate(), toDate(2020)].uniques().toString()", "[2020-01-01T00:00Z, 2018-03-02T00:00Z]"}; + parseEval(bindings, test4); + + String[] test5 = {"[null,null,null].uniques().toString()", "[null]"}; + parseEval(bindings, test5); + } + + @Test + public void uniquesMixedArray() throws ParsingException { + String[] test = {"[2,1.0,3,1.0].uniques().toString()", "[2, 1.0, 3]"}; + parseEval(bindings, test); + String[] test1 = {"[2,'a',3,3,'a'].uniques().toString()", "[2, a, 3]"}; + parseEval(bindings, test1); + } + }