/*
* Copyright (c) 2017 OBiBa. All rights reserved.
*
* This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.obiba.magma.js.methods;
import java.util.ArrayList;
import java.util.Collections;
import javax.annotation.Nullable;
import org.junit.Test;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.FunctionObject;
import org.mozilla.javascript.Scriptable;
import org.obiba.magma.Value;
import org.obiba.magma.ValueSequence;
import org.obiba.magma.js.AbstractJsTest;
import org.obiba.magma.js.MagmaJsEvaluationRuntimeException;
import org.obiba.magma.js.ScriptableValue;
import org.obiba.magma.support.Values;
import org.obiba.magma.type.DecimalType;
import org.obiba.magma.type.IntegerType;
import org.obiba.magma.type.TextType;
import static org.fest.assertions.api.Assertions.assertThat;
@SuppressWarnings({ "AssignmentToMethodParameter", "PMD.AvoidReassigningParameters", "ReuseOfLocalVariable" })
public class ValueSequenceMethodsTest extends AbstractJsTest {
@Test
public void testIsSequence() throws Exception {
ValueSequence valueSequence = TextType.get().sequenceOf("A");
ScriptableValue scriptableValue = newValue(valueSequence);
ScriptableValue result = ValueSequenceMethods.isSequence(Context.getCurrentContext(), scriptableValue, null, null);
assertThat(result.getValue().getValue()).isEqualTo(Boolean.TRUE);
}
@Test
public void testNullSequenceIsSequence() throws Exception {
ValueSequence valueSequence = TextType.get().nullSequence();
ScriptableValue scriptableValue = newValue(valueSequence);
ScriptableValue result = ValueSequenceMethods.isSequence(Context.getCurrentContext(), scriptableValue, null, null);
assertThat(result.getValue().getValue()).isEqualTo(Boolean.TRUE);
}
@Test
public void testIsNotSequence() throws Exception {
Value value = TextType.get().valueOf("A");
ScriptableValue scriptableValue = newValue(value);
ScriptableValue result = ValueSequenceMethods.isSequence(Context.getCurrentContext(), scriptableValue, null, null);
assertThat(result.getValue().getValue()).isEqualTo(Boolean.FALSE);
}
@Test
public void testNullValueIsNotSequence() throws Exception {
Value value = TextType.get().nullValue();
ScriptableValue scriptableValue = newValue(value);
ScriptableValue result = ValueSequenceMethods.isSequence(Context.getCurrentContext(), scriptableValue, null, null);
assertThat(result.getValue().getValue()).isEqualTo(Boolean.FALSE);
}
@Test
public void testFirstOfOne() throws Exception {
ValueSequence valueSequence = TextType.get().sequenceOf("A");
ScriptableValue scriptableValue = newValue(valueSequence);
ScriptableValue result = ValueSequenceMethods.first(Context.getCurrentContext(), scriptableValue, null, null);
assertThat(result.getValue()).isEqualTo(valueSequence.get(0));
}
@Test
public void testFirstOfTwo() throws Exception {
ValueSequence valueSequence = TextType.get().sequenceOf("\"A\", \"B\"");
ScriptableValue scriptableValue = newValue(valueSequence);
ScriptableValue result = ValueSequenceMethods.first(Context.getCurrentContext(), scriptableValue, null, null);
assertThat(result.getValue()).isEqualTo(valueSequence.get(0));
}
@Test
public void testFirstOnNonSequence() throws Exception {
Value value = TextType.get().valueOf("A-Value");
ScriptableValue scriptableValue = newValue(value);
ScriptableValue result = ValueSequenceMethods.first(Context.getCurrentContext(), scriptableValue, null, null);
assertThat(result.getValue()).isEqualTo(value);
}
@Test
public void testFirstOnNullOperand() throws Exception {
ScriptableValue scriptableValue = newValue(TextType.get().nullValue());
ScriptableValue result = ValueSequenceMethods.first(Context.getCurrentContext(), scriptableValue, null, null);
assertThat(result.getValue()).isEqualTo(scriptableValue.getValue());
}
@Test
public void testFirstOfNone() throws Exception {
ValueSequence valueSequence = TextType.get().sequenceOf(new ArrayList<Value>());
ScriptableValue scriptableValue = newValue(valueSequence);
ScriptableValue result = ValueSequenceMethods.first(Context.getCurrentContext(), scriptableValue, null, null);
assertThat(result.getValue()).isEqualTo(TextType.get().nullValue());
}
// last()
@Test
public void testLastOfOne() throws Exception {
ValueSequence valueSequence = TextType.get().sequenceOf("A");
ScriptableValue scriptableValue = newValue(valueSequence);
ScriptableValue result = ValueSequenceMethods.last(Context.getCurrentContext(), scriptableValue, null, null);
assertThat(result.getValue()).isEqualTo(valueSequence.get(0));
}
@Test
public void testLastOfTwo() throws Exception {
ValueSequence valueSequence = TextType.get().sequenceOf("\"A\", \"B\"");
ScriptableValue scriptableValue = newValue(valueSequence);
ScriptableValue result = ValueSequenceMethods.last(Context.getCurrentContext(), scriptableValue, null, null);
assertThat(result.getValue()).isEqualTo(valueSequence.get(1));
}
@Test
public void testLastOnNonSequence() throws Exception {
Value value = TextType.get().valueOf("A-Value");
ScriptableValue scriptableValue = newValue(value);
ScriptableValue result = ValueSequenceMethods.last(Context.getCurrentContext(), scriptableValue, null, null);
assertThat(result.getValue()).isEqualTo(value);
}
@Test
public void testLastOnNullOperand() throws Exception {
ScriptableValue scriptableValue = newValue(TextType.get().nullValue());
ScriptableValue result = ValueSequenceMethods.last(Context.getCurrentContext(), scriptableValue, null, null);
assertThat(result.getValue()).isEqualTo(scriptableValue.getValue());
}
@Test
public void testLastOfNone() throws Exception {
ValueSequence valueSequence = TextType.get().sequenceOf(new ArrayList<Value>());
ScriptableValue scriptableValue = newValue(valueSequence);
ScriptableValue result = ValueSequenceMethods.last(Context.getCurrentContext(), scriptableValue, null, null);
assertThat(result.getValue()).isEqualTo(TextType.get().nullValue());
}
// size()
@Test
public void testSizeOfOne() throws Exception {
ValueSequence valueSequence = TextType.get().sequenceOf("A");
ScriptableValue scriptableValue = newValue(valueSequence);
ScriptableValue result = ValueSequenceMethods.size(Context.getCurrentContext(), scriptableValue, null, null);
assertThat(result.getValue()).isEqualTo(IntegerType.get().valueOf(valueSequence.getSize()));
}
@Test
public void testSizeOfTwo() throws Exception {
ValueSequence valueSequence = TextType.get().sequenceOf("\"A\", \"B\"");
ScriptableValue scriptableValue = newValue(valueSequence);
ScriptableValue result = ValueSequenceMethods.size(Context.getCurrentContext(), scriptableValue, null, null);
assertThat(result.getValue()).isEqualTo(IntegerType.get().valueOf(valueSequence.getSize()));
}
@Test
public void testSizeOnNonSequence() throws Exception {
Value value = TextType.get().valueOf("A-Value");
ScriptableValue scriptableValue = newValue(value);
ScriptableValue result = ValueSequenceMethods.size(Context.getCurrentContext(), scriptableValue, null, null);
assertThat(result.getValue()).isEqualTo(IntegerType.get().valueOf(1));
}
@Test
public void testSizeOnNullOperand() throws Exception {
ScriptableValue scriptableValue = newValue(TextType.get().nullValue());
ScriptableValue result = ValueSequenceMethods.size(Context.getCurrentContext(), scriptableValue, null, null);
assertThat(result.getValue()).isEqualTo(IntegerType.get().nullValue());
}
@Test
public void testSizeOfNone() throws Exception {
ValueSequence valueSequence = TextType.get().sequenceOf(new ArrayList<Value>());
ScriptableValue scriptableValue = newValue(valueSequence);
ScriptableValue result = ValueSequenceMethods.size(Context.getCurrentContext(), scriptableValue, null, null);
assertThat(result.getValue()).isEqualTo(IntegerType.get().valueOf(valueSequence.getSize()));
}
// value(int index)
@Test
public void testValueFirstItemExists() throws Exception {
ValueSequence valueSequence = TextType.get().sequenceOf("\"A\", \"B\"");
ScriptableValue scriptableValue = newValue(valueSequence);
ScriptableValue result = ValueSequenceMethods
.valueAt(Context.getCurrentContext(), scriptableValue, new Object[] { 0 }, null);
assertThat(result.getValue()).isEqualTo(valueSequence.get(0));
}
@Test
public void testValueSecondItemExists() throws Exception {
ValueSequence valueSequence = TextType.get().sequenceOf("\"A\", \"B\"");
ScriptableValue scriptableValue = newValue(valueSequence);
ScriptableValue result = ValueSequenceMethods
.valueAt(Context.getCurrentContext(), scriptableValue, new Object[] { 1 }, null);
assertThat(result.getValue()).isEqualTo(valueSequence.get(1));
}
@Test
public void testValueIndexOutOfMaxBound() throws Exception {
ValueSequence valueSequence = TextType.get().sequenceOf("\"A\", \"B\"");
ScriptableValue scriptableValue = newValue(valueSequence);
ScriptableValue result = ValueSequenceMethods
.valueAt(Context.getCurrentContext(), scriptableValue, new Object[] { 2 }, null);
assertThat(result.getValue()).isEqualTo(TextType.get().nullValue());
}
@Test
public void testValueIndexOutOfMinBound() throws Exception {
ValueSequence valueSequence = TextType.get().sequenceOf("\"A\", \"B\"");
ScriptableValue scriptableValue = newValue(valueSequence);
ScriptableValue result = ValueSequenceMethods
.valueAt(Context.getCurrentContext(), scriptableValue, new Object[] { -1 }, null);
assertThat(result.getValue()).isEqualTo(TextType.get().nullValue());
}
@Test
public void testValueIndexNonIntegerType() throws Exception {
ValueSequence valueSequence = TextType.get().sequenceOf("\"A\", \"B\"");
ScriptableValue scriptableValue = newValue(valueSequence);
ScriptableValue result = ValueSequenceMethods
.valueAt(Context.getCurrentContext(), scriptableValue, new Object[] { "One" }, null);
assertThat(result.getValue()).isEqualTo(TextType.get().nullValue());
}
@Test
public void testNullSequenceValueAt() throws Exception {
ValueSequence valueSequence = TextType.get().nullSequence();
ScriptableValue scriptableValue = newValue(valueSequence);
ScriptableValue result = ValueSequenceMethods
.valueAt(Context.getCurrentContext(), scriptableValue, new Object[] { 2 }, null);
assertThat(result.getValue()).isEqualTo(TextType.get().nullValue());
}
@Test
public void testValueAtValue() throws Exception {
ValueSequence valueSequence = TextType.get().sequenceOf("\"A\", \"B\"");
ScriptableValue scriptableValue = newValue(valueSequence);
ScriptableValue result = ValueSequenceMethods
.valueAt(Context.getCurrentContext(), scriptableValue, new Object[] { IntegerType.get().valueOf(0) }, null);
assertThat(result.getValue()).isEqualTo(valueSequence.get(0));
}
@Test
public void testValueAtTextValue() throws Exception {
ValueSequence valueSequence = TextType.get().sequenceOf("\"A\", \"B\"");
ScriptableValue scriptableValue = newValue(valueSequence);
ScriptableValue result = ValueSequenceMethods
.valueAt(Context.getCurrentContext(), scriptableValue, new Object[] { TextType.get().valueOf("0") }, null);
assertThat(result.getValue()).isEqualTo(valueSequence.get(0));
}
@Test
public void testValueIndexOf() throws Exception {
ValueSequence valueSequence = TextType.get().sequenceOf("\"A\", \"B\", \"A\"");
ScriptableValue scriptableValue = newValue(valueSequence);
ScriptableValue result = ValueSequenceMethods
.indexOf(Context.getCurrentContext(), scriptableValue, new Object[] { "A" }, null);
assertThat(result.getValue()).isEqualTo(IntegerType.get().valueOf(0));
result = ValueSequenceMethods
.indexOf(Context.getCurrentContext(), scriptableValue, new Object[] { "B" }, null);
assertThat(result.getValue()).isEqualTo(IntegerType.get().valueOf(1));
result = ValueSequenceMethods
.indexOf(Context.getCurrentContext(), scriptableValue, new Object[] { "C" }, null);
assertThat(result.getValue()).isEqualTo(IntegerType.get().valueOf(-1));
result = ValueSequenceMethods
.indexOf(Context.getCurrentContext(), scriptableValue, new Object[] { }, null);
assertThat(result.getValue()).isEqualTo(IntegerType.get().valueOf(-1));
}
@Test
public void testNullValueIndexOf() throws Exception {
ValueSequence valueSequence = TextType.get().sequenceOf("\"A\",, \"B\"");
ScriptableValue scriptableValue = newValue(valueSequence);
ScriptableValue result = ValueSequenceMethods
.indexOf(Context.getCurrentContext(), scriptableValue, new Object[] { "A" }, null);
assertThat(result.getValue()).isEqualTo(IntegerType.get().valueOf(0));
result = ValueSequenceMethods
.indexOf(Context.getCurrentContext(), scriptableValue, new Object[] { "B" }, null);
assertThat(result.getValue()).isEqualTo(IntegerType.get().valueOf(2));
result = ValueSequenceMethods
.indexOf(Context.getCurrentContext(), scriptableValue, new Object[] { "C" }, null);
assertThat(result.getValue()).isEqualTo(IntegerType.get().valueOf(-1));
result = ValueSequenceMethods
.indexOf(Context.getCurrentContext(), scriptableValue, new Object[] { TextType.get().nullValue() }, null);
assertThat(result.getValue()).isEqualTo(IntegerType.get().valueOf(1));
}
@Test
public void testValueLastIndexOf() throws Exception {
ValueSequence valueSequence = TextType.get().sequenceOf("\"A\", \"B\", \"A\"");
ScriptableValue scriptableValue = newValue(valueSequence);
ScriptableValue result = ValueSequenceMethods
.lastIndexOf(Context.getCurrentContext(), scriptableValue, new Object[] { "A" }, null);
assertThat(result.getValue()).isEqualTo(IntegerType.get().valueOf(2));
result = ValueSequenceMethods
.lastIndexOf(Context.getCurrentContext(), scriptableValue, new Object[] { "B" }, null);
assertThat(result.getValue()).isEqualTo(IntegerType.get().valueOf(1));
result = ValueSequenceMethods
.lastIndexOf(Context.getCurrentContext(), scriptableValue, new Object[] { "C" }, null);
assertThat(result.getValue()).isEqualTo(IntegerType.get().valueOf(-1));
result = ValueSequenceMethods
.lastIndexOf(Context.getCurrentContext(), scriptableValue, new Object[] { }, null);
assertThat(result.getValue()).isEqualTo(IntegerType.get().valueOf(-1));
}
@Test
public void testNullValueLastIndexOf() throws Exception {
ValueSequence valueSequence = TextType.get().sequenceOf("\"A\",, \"B\"");
ScriptableValue scriptableValue = newValue(valueSequence);
ScriptableValue result = ValueSequenceMethods
.lastIndexOf(Context.getCurrentContext(), scriptableValue, new Object[] { "A" }, null);
assertThat(result.getValue()).isEqualTo(IntegerType.get().valueOf(0));
result = ValueSequenceMethods
.lastIndexOf(Context.getCurrentContext(), scriptableValue, new Object[] { "B" }, null);
assertThat(result.getValue()).isEqualTo(IntegerType.get().valueOf(2));
result = ValueSequenceMethods
.lastIndexOf(Context.getCurrentContext(), scriptableValue, new Object[] { "C" }, null);
assertThat(result.getValue()).isEqualTo(IntegerType.get().valueOf(-1));
result = ValueSequenceMethods
.lastIndexOf(Context.getCurrentContext(), scriptableValue, new Object[] { TextType.get().nullValue() }, null);
assertThat(result.getValue()).isEqualTo(IntegerType.get().valueOf(1));
}
// sort()
@Test
public void testSortTextNaturalOrder() throws Exception {
ValueSequence valueSequence = TextType.get().sequenceOf("\"D\", \"C\", \"A\", \"B\"");
ScriptableValue scriptableValue = newValue(valueSequence);
valueSequence = ValueSequenceMethods.sort(Context.getCurrentContext(), scriptableValue, null, null).getValue()
.asSequence();
assertThat(valueSequence.getValues().get(0)).isEqualTo(TextType.get().valueOf("A"));
assertThat(valueSequence.getValues().get(1)).isEqualTo(TextType.get().valueOf("B"));
assertThat(valueSequence.getValues().get(2)).isEqualTo(TextType.get().valueOf("C"));
assertThat(valueSequence.getValues().get(3)).isEqualTo(TextType.get().valueOf("D"));
}
@Test
public void testSortIntegerNaturalOrder() throws Exception {
ValueSequence valueSequence = IntegerType.get().sequenceOf("4,3,1,2");
ScriptableValue scriptableValue = newValue(valueSequence);
valueSequence = ValueSequenceMethods.sort(Context.getCurrentContext(), scriptableValue, null, null).getValue()
.asSequence();
assertThat(valueSequence.getValues().get(0)).isEqualTo(IntegerType.get().valueOf(1));
assertThat(valueSequence.getValues().get(1)).isEqualTo(IntegerType.get().valueOf(2));
assertThat(valueSequence.getValues().get(2)).isEqualTo(IntegerType.get().valueOf(3));
assertThat(valueSequence.getValues().get(3)).isEqualTo(IntegerType.get().valueOf(4));
}
@Test
public void testSortIntegerDescendingUsingSortFunction() throws Exception {
ValueSequence valueSequence = IntegerType.get().sequenceOf("4,3,1,2");
MyScriptableValueCustomSortDesc scriptableValue = newValueDesc(valueSequence);
FunctionObject funObj = new FunctionObject("sort",
scriptableValue.getClass().getMethod("sort", new Class[] { ScriptableValue.class, ScriptableValue.class }),
scriptableValue);
valueSequence = ValueSequenceMethods
.sort(Context.getCurrentContext(), scriptableValue, new Object[] { funObj }, null).getValue().asSequence();
assertThat(valueSequence.getValues().get(0)).isEqualTo(IntegerType.get().valueOf(4));
assertThat(valueSequence.getValues().get(1)).isEqualTo(IntegerType.get().valueOf(3));
assertThat(valueSequence.getValues().get(2)).isEqualTo(IntegerType.get().valueOf(2));
assertThat(valueSequence.getValues().get(3)).isEqualTo(IntegerType.get().valueOf(1));
}
@Test
public void testSortIntegerAscendingUsingSortFunction() throws Exception {
ValueSequence valueSequence = IntegerType.get().sequenceOf("4,3,1,2");
MyScriptableValueCustomSortAsc scriptableValue = newValueAsc(valueSequence);
FunctionObject funObj = new FunctionObject("sort",
scriptableValue.getClass().getMethod("sort", new Class[] { ScriptableValue.class, ScriptableValue.class }),
scriptableValue);
valueSequence = ValueSequenceMethods
.sort(Context.getCurrentContext(), scriptableValue, new Object[] { funObj }, null).getValue().asSequence();
assertThat(valueSequence.getValues().get(0)).isEqualTo(IntegerType.get().valueOf(1));
assertThat(valueSequence.getValues().get(1)).isEqualTo(IntegerType.get().valueOf(2));
assertThat(valueSequence.getValues().get(2)).isEqualTo(IntegerType.get().valueOf(3));
assertThat(valueSequence.getValues().get(3)).isEqualTo(IntegerType.get().valueOf(4));
}
@Test
public void test_sort_nullSequenceReturnsNullSequence() {
assertMethod("sort()", IntegerType.get().nullSequence(), IntegerType.get().nullSequence());
}
@Test
public void test_sort_nonSequenceReturnsSingleValue() {
assertMethod("sort()", IntegerType.get().valueOf(4), IntegerType.get().valueOf(4));
}
// avg
@Test
public void test_avg_integerType() {
assertAvgIs(Values.asSequence(IntegerType.get(), 1, 2, 3, 4), 2.5);
}
@Test
public void test_avg_decimalType() {
assertAvgIs(Values.asSequence(DecimalType.get(), 1, 2, 3, 4), 2.5);
assertAvgIs(Values.asSequence(DecimalType.get(), 0.5, 2.5, 3.8, 5.2), 3.0);
}
@Test
public void test_avg_sequenceContainsNullReturnsNotNullValue() {
assertAvgIs(Values.asSequence(DecimalType.get(), 1, null, 3, 4), 2.0);
}
@Test
public void test_avg_nullSequenceReturnsNullValue() {
assertAvgIs(DecimalType.get().nullSequence(), null);
}
@Test
public void test_avg_onNonSequenceReturnsValue() {
assertAvgIs(IntegerType.get().valueOf(4), 4);
assertAvgIs(DecimalType.get().valueOf(4), 4.0);
}
@Test(expected = MagmaJsEvaluationRuntimeException.class)
public void test_avg_onNonNumericTypeThrowsAnException() {
assertAvgIs(TextType.get().valueOf("This is not a number, so you can't call avg()"), null);
}
@Test
public void test_avg_emptySequence() {
assertAvgIs(DecimalType.get().sequenceOf(Collections.<Value>emptyList()), null);
}
@SuppressWarnings({ "AssignmentToMethodParameter", "PMD.AvoidReassigningParameters" })
private void assertAvgIs(Value valueToSum, @Nullable Number expectedSum) {
if(expectedSum instanceof Integer) {
expectedSum = expectedSum.longValue();
}
ScriptableValue result = evaluate("avg()", valueToSum);
assertThat(result).isNotNull();
if(expectedSum == null) {
assertThat(result.getValue().isNull()).isTrue();
} else {
assertThat(result.getValue().getValue()).isEqualTo(expectedSum);
}
}
// stddev
@Test
public void test_stddev_integerType() {
assertStdDevIs(Values.asSequence(IntegerType.get(), 2, 4, 4, 4, 5, 5, 7, 9), 2.0);
}
@Test
public void test_stddev_decimalType() {
assertStdDevIs(Values.asSequence(DecimalType.get(), 2, 4, 4, 4, 5, 5, 7, 9), 2.0);
}
@Test
public void test_stddev_sequenceContainsNullReturnsNotNullValue() {
assertStdDevIs(Values.asSequence(DecimalType.get(), 1, null, 3, 4), 1.224744871391589);
}
@Test
public void test_stddev_nullSequenceReturnsNullValue() {
assertStdDevIs(DecimalType.get().nullSequence(), null);
}
@Test
public void test_stddev_onNonSequenceReturnsValue() {
assertStdDevIs(IntegerType.get().valueOf(4), 0.0);
assertStdDevIs(DecimalType.get().valueOf(4), 0.0);
}
@Test(expected = MagmaJsEvaluationRuntimeException.class)
public void test_stddev_onNonNumericTypeThrowsAnException() {
assertStdDevIs(TextType.get().valueOf("This is not a number, so you can't call stddev()"), null);
}
@Test
public void test_stddev_emptySequence() {
assertStdDevIs(DecimalType.get().sequenceOf(Collections.<Value>emptyList()), null);
}
@SuppressWarnings({ "AssignmentToMethodParameter", "PMD.AvoidReassigningParameters" })
private void assertStdDevIs(Value testValue, @Nullable Number expected) {
if(expected instanceof Integer) {
expected = expected.longValue();
}
ScriptableValue result = evaluate("stddev()", testValue);
assertThat(result).isNotNull();
if(expected == null) {
assertThat(result.getValue().isNull()).isTrue();
} else {
assertThat(result.getValue().getValue()).isEqualTo(expected);
}
}
// sum
@Test
public void test_sum_integerType() {
assertSumIs(Values.asSequence(IntegerType.get(), 1, 2, 3, 4), 10);
}
@Test
public void test_sum_decimalType() {
assertSumIs(Values.asSequence(DecimalType.get(), 1, 2, 3, 4), 10.0);
assertSumIs(Values.asSequence(DecimalType.get(), 0.5, 2.5, 3.8, 4.2), 11.0);
}
@Test
public void test_sum_sequenceContainsNullReturnsNotNullValue() {
assertSumIs(Values.asSequence(DecimalType.get(), 1, null, 3, 4), 8.0);
}
@Test
public void test_sum_nullSequenceReturnsNullValue() {
assertSumIs(DecimalType.get().nullSequence(), null);
}
@Test
public void test_sum_onNonSequenceReturnsValue() {
assertSumIs(IntegerType.get().valueOf(4), 4);
assertSumIs(DecimalType.get().valueOf(4), 4.0);
}
@Test(expected = MagmaJsEvaluationRuntimeException.class)
public void test_sum_onNonNumericTypeThrowsAnException() {
assertSumIs(TextType.get().valueOf("This is not a number, so you can't call sum()"), null);
}
@Test
public void test_sum_emptySequence() {
assertSumIs(DecimalType.get().sequenceOf(Collections.<Value>emptyList()), 0.0);
}
private void assertSumIs(Value valueToSum, @Nullable Number expectedSum) {
if(expectedSum instanceof Integer) {
expectedSum = expectedSum.longValue();
}
ScriptableValue result = evaluate("sum()", valueToSum);
assertThat(result).isNotNull();
if(expectedSum == null) {
assertThat(result.getValue().isNull()).isTrue();
} else {
assertThat(result.getValue().getValue()).isEqualTo(expectedSum);
}
}
// push
@Test
public void test_push() {
assertPushIs(Values.asSequence(IntegerType.get(), 1, 2, 3), "4", Values.asSequence(IntegerType.get(), 1, 2, 3, 4));
}
@Test
public void test_append() {
assertAppendIs(Values.asSequence(IntegerType.get(), 1, 2, 3), "4", Values.asSequence(IntegerType.get(), 1, 2, 3, 4));
}
@Test
public void test_prepend() {
assertPrependIs(Values.asSequence(IntegerType.get(), 1, 2, 3), "4", Values.asSequence(IntegerType.get(), 4, 1, 2, 3));
}
@Test
public void test_push_nothing() {
assertPushIs(Values.asSequence(IntegerType.get(), 1, 2, 3), "", Values.asSequence(IntegerType.get(), 1, 2, 3));
}
@Test
public void test_append_nothing() {
assertAppendIs(Values.asSequence(IntegerType.get(), 1, 2, 3), "", Values.asSequence(IntegerType.get(), 1, 2, 3));
}
@Test
public void test_prepend_nothing() {
assertPrependIs(Values.asSequence(IntegerType.get(), 1, 2, 3), "", Values.asSequence(IntegerType.get(), 1, 2, 3));
}
@Test
public void test_push_multipleValues() {
assertPushIs(Values.asSequence(IntegerType.get(), 1, 2, 3), "4,5", Values.asSequence(IntegerType.get(), 1, 2, 3, 4, 5));
}
@Test
public void test_append_multipleValues() {
assertAppendIs(Values.asSequence(IntegerType.get(), 1, 2, 3), "4,5", Values.asSequence(IntegerType.get(), 1, 2, 3, 4, 5));
}
@Test
public void test_prepend_multipleValues() {
assertPrependIs(Values.asSequence(IntegerType.get(), 1, 2, 3), "4,5", Values.asSequence(IntegerType.get(), 4, 5, 1, 2, 3));
}
@Test
public void test_push_convertsTypes() {
assertPushIs(Values.asSequence(TextType.get(), 1, 2, 3), "4,5", Values.asSequence(TextType.get(), 1, 2, 3, 4, 5));
}
@Test
public void test_push_nullSequenceProducesNull() {
assertPushIs(TextType.get().nullSequence(), "'this will not be pushed'", TextType.get().nullSequence());
}
@Test
public void test_append_nullSequence() {
assertAppendIs(TextType.get().nullSequence(), "'foo'", Values.asSequence(TextType.get(), "foo"));
}
@Test
public void test_prepend_nullSequence() {
assertPrependIs(TextType.get().nullSequence(), "'foo'", Values.asSequence(TextType.get(), "foo"));
}
@Test
public void test_push_acceptsNullArgument() {
assertPushIs(Values.asSequence(IntegerType.get(), 1, 2, 3), "null", Values.asSequence(IntegerType.get(), 1, 2, 3, null));
}
@Test
public void test_append_acceptsNullArgument() {
assertAppendIs(Values.asSequence(IntegerType.get(), 1, 2, 3), "null", Values.asSequence(IntegerType.get(), 1, 2, 3, null));
}
@Test
public void test_prepend_acceptsNullArgument() {
assertPrependIs(Values.asSequence(IntegerType.get(), 1, 2, 3), "null", Values.asSequence(IntegerType.get(), null, 1, 2, 3));
}
@Test
public void test_push_acceptsNonSequenceOperand() {
assertPushIs(TextType.get().valueOf("this is not a sequence"), "'neither is this'",
Values.asSequence(TextType.get(), "this is not a sequence", "neither is this"));
}
@Test
public void test_append_acceptsNonSequenceOperand() {
assertAppendIs(TextType.get().valueOf("this is not a sequence"), "'neither is this'",
Values.asSequence(TextType.get(), "this is not a sequence", "neither is this"));
}
@Test
public void test_prepend_acceptsNonSequenceOperand() {
assertPrependIs(TextType.get().valueOf("this is not a sequence"), "'neither is this'",
Values.asSequence(TextType.get(), "neither is this", "this is not a sequence"));
}
private void assertPushIs(Value valueToPushInto, String push, Value expected) {
assertPendIs("push", valueToPushInto, push, expected);
}
private void assertAppendIs(Value valueToPushInto, String push, Value expected) {
assertPendIs("append", valueToPushInto, push, expected);
}
private void assertPrependIs(Value valueToPushInto, String push, Value expected) {
assertPendIs("prepend", valueToPushInto, push, expected);
}
private void assertPendIs(String pendMethod, Value valueToPushInto, String push, Value expected) {
ScriptableValue result = evaluate(pendMethod + "(" + push + ")", valueToPushInto);
assertThat(result).isNotNull();
if(expected.isNull()) {
assertThat(result.getValue().isNull()).isTrue();
} else {
assertThat(result.getValue().asSequence().getValue()).isEqualTo(expected.asSequence().getValue());
}
}
// join
@Test
public void test_join() {
assertJoinIs(Values.asSequence(IntegerType.get(), 1, 2, 3), "", TextType.get().valueOf("123"));
}
@Test
public void test_join_not_a_sequence() {
assertJoinIs(IntegerType.get().valueOf(1), "', ','[', ']'", TextType.get().valueOf("[1]"));
}
@Test
public void test_join_null() {
assertJoinIs(IntegerType.get().nullSequence(), "", TextType.get().nullValue());
}
@Test
public void test_join_delimiter() {
assertJoinIs(Values.asSequence(IntegerType.get(), 1, 2, 3), "', '", TextType.get().valueOf("1, 2, 3"));
}
@Test
public void test_join_delimiter_prefix() {
assertJoinIs(Values.asSequence(IntegerType.get(), 1, 2, 3), "', ','=> '", TextType.get().valueOf("=> 1, 2, 3"));
}
@Test
public void test_join_delimiter_prefix_suffix() {
assertJoinIs(Values.asSequence(IntegerType.get(), 1, 2, 3), "', ','[', ']'", TextType.get().valueOf("[1, 2, 3]"));
}
@Test
public void test_join_delimiter_prefix_suffix_empty() {
assertJoinIs(Values.asSequence(IntegerType.get()), "', ','[', ']'", TextType.get().valueOf(""));
}
private void assertJoinIs(Value valueToJoin, String args, Value expected) {
ScriptableValue result = evaluate("join(" + args + ")", valueToJoin);
assertThat(result).isNotNull();
if(expected.isNull()) {
assertThat(result.getValue().isNull()).isTrue();
} else {
assertThat(expected.getValue()).isEqualTo(result.getValue().getValue());
}
}
// zip
@Test
public void test_zip_concat() {
assertZipIs(Values.asSequence(IntegerType.get(), 1, 2, 3), "'foo', function(o1,o2) { return o1.concat(o2); }",
Values.asSequence(TextType.get(), "1foo", "2foo", "3foo"));
}
@Test
public void test_zip_concat_value() {
assertZipIs(Values.asSequence(IntegerType.get(), 1, 2, 3),
"newValue('foo'), function(o1,o2) { return o1.concat(o2); }",
Values.asSequence(TextType.get(), "1foo", "2foo", "3foo"));
}
@Test
public void test_zip_concat_value_sequence() {
assertZipIs(Values.asSequence(IntegerType.get(), 1, 2, 3),
"newValue('foo').push('bar'), function(o1,o2) { return o1.concat(o2); }",
Values.asSequence(TextType.get(), "1foo", "2bar", "3null"));
}
@Test
public void test_zip_concat_value_sequence_longer() {
assertZipIs(Values.asSequence(IntegerType.get(), 1, 2, 3),
"newValue('foo').push('bar').push('patate').push('pwel'), function(o1,o2) { return o1.concat(o2); }",
Values.asSequence(TextType.get(), "1foo", "2bar", "3patate", "nullpwel"));
}
@Test
public void test_zip_concat_empty() {
assertZipIs(Values.asSequence(IntegerType.get()), "'foo', function(o1,o2) { return o1.concat(o2); }",
Values.asSequence(TextType.get(), "nullfoo"));
}
@Test
public void test_zip_concat_null() {
assertZipIs(IntegerType.get().nullSequence(), "'foo', function(o1,o2) { return o1.concat(o2); }",
Values.asSequence(TextType.get(), "nullfoo"));
}
@Test
public void test_zip_plus() {
assertZipIs(Values.asSequence(IntegerType.get(), 1, 2, 3), "1, function(o1,o2) { return o1.plus(o2); }",
Values.asSequence(IntegerType.get(), 2, 3, 4));
}
private void assertZipIs(Value valueToZip, String args, Value expected) {
ScriptableValue result = evaluate("zip(" + args + ")", valueToZip);
assertThat(result).isNotNull();
if(expected.isNull()) {
assertThat(result.getValue().isNull()).isTrue();
} else {
assertThat(result.getValue().isSequence()).isTrue();
assertThat(result.getValue().asSequence().getValue()).isEqualTo(expected.asSequence().getValue());
}
}
@SuppressWarnings("serial")
private static class MyScriptableValueCustomSortAsc extends ScriptableValue {
private MyScriptableValueCustomSortAsc(Scriptable scope, Value value) {
super(scope, value);
}
public int sort(ScriptableValue value1, ScriptableValue value2) {
return (int) ((Long) value1.getValue().getValue() - (Long) value2.getValue().getValue());
}
}
@SuppressWarnings("serial")
private static class MyScriptableValueCustomSortDesc extends ScriptableValue {
private MyScriptableValueCustomSortDesc(Scriptable scope, Value value) {
super(scope, value);
}
public int sort(ScriptableValue value1, ScriptableValue value2) {
return (int) ((Long) value2.getValue().getValue() - (Long) value1.getValue().getValue());
}
}
private MyScriptableValueCustomSortAsc newValueAsc(Value value) {
return new MyScriptableValueCustomSortAsc(getSharedScope(), value);
}
private MyScriptableValueCustomSortDesc newValueDesc(Value value) {
return new MyScriptableValueCustomSortDesc(getSharedScope(), value);
}
}