Skip to content

Commit

Permalink
allows Java arrays as input parameters for lists (#441)
Browse files Browse the repository at this point in the history
  • Loading branch information
uklimaschewski authored Feb 26, 2024
1 parent ee40a3d commit 87b678a
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 11 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ Expression expression = new Expression("\"Hello \" + name + \", you are \" + age
System.out.println(expression.evaluate().getStringValue()); // prints Hello Frank, you are 38
```

### Arrays (also multidimensional) are supported and can be passed as Java _Lists_.
### Arrays (also multidimensional) are supported and can be passed as Java _Lists_ or instances of Java arrays.

See the [Documentation](https://ezylang.github.io/EvalEx/concepts/datatypes.html#array)
for more details.
Expand All @@ -177,7 +177,7 @@ Expression expression = new Expression("values[i-1] * factors[i-1]");

EvaluationValue result = expression
.with("values", List.of(2, 3, 4))
.and("factors", List.of(2, 4, 6))
.and("factors", new Object[] {2, 4, 6})
.and("i", 1)
.evaluate();

Expand Down
4 changes: 2 additions & 2 deletions docs/concepts/datatypes.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ Duration are stored as a _java.time.Duration_. The duration values are useful fo

Arrays are stored internally as a _java.util.List<EvaluationValue>_. When passed as a
variable, the list will be iterated and each entry will be converted using the data type conversion
rules.
So, for example, a list of double values will be converted to a list of _EvaluationValue_
rules. Instances of _java.util.List_ and Java arrays can be passed as parameters.
So, for example, a list or array of double values will be converted to a list of _EvaluationValue_
objects of type _NUMBER_, with an internal BigDecimal representation.

Arrays can hold mixed data types:
Expand Down
4 changes: 2 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ Expression expression = new Expression("\"Hello \" + name + \", you are \" + age
System.out.println(expression.evaluate().getStringValue()); // prints Hello Frank, you are 38
```

### Arrays (also multidimensional) are supported and can be passed as Java _Lists_.
### Arrays (also multidimensional) are supported and can be passed as Java _Lists_ or instances of Java arrays.

See the [Documentation](https://ezylang.github.io/EvalEx/concepts/datatypes.html#array)
for more details.
Expand All @@ -171,7 +171,7 @@ Expression expression = new Expression("values[i-1] * factors[i-1]");

EvaluationValue result = expression
.with("values", List.of(2, 3, 4))
.and("factors", List.of(2, 4, 6))
.and("factors", new Object[] {2, 4, 6})
.and("i", 1)
.evaluate();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,23 @@
public class ArrayConverter implements ConverterIfc {
@Override
public EvaluationValue convert(Object object, ExpressionConfiguration configuration) {
List<EvaluationValue> array = new ArrayList<>();
((List) object).forEach(element -> array.add(new EvaluationValue(element, configuration)));
List<EvaluationValue> list = new ArrayList<>();

return EvaluationValue.arrayValue(array);
if (object instanceof Object[]) {
for (Object element : (Object[]) object) {
list.add(new EvaluationValue(element, configuration));
}
} else if (object instanceof List) {
((List<?>) object).forEach(element -> list.add(new EvaluationValue(element, configuration)));
} else {
throw illegalArgument(object);
}

return EvaluationValue.arrayValue(list);
}

@Override
public boolean canConvert(Object object) {
return object instanceof List;
return object instanceof List || object instanceof Object[];
}
}
11 changes: 11 additions & 0 deletions src/test/java/com/ezylang/evalex/ExpressionEvaluatorArrayTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,17 @@ void testMixedArray() throws ParseException, EvaluationException {
assertThat(expression3.evaluate().getStringValue()).isEqualTo("true");
}

@Test
void testArrayAndList() throws EvaluationException, ParseException {
Expression expression =
createExpression("values[i-1] * factors[i-1]")
.with("values", List.of(2, 3, 4))
.and("factors", new Object[] {2, 4, 6})
.and("i", 1);

assertThat(expression.evaluate().getStringValue()).isEqualTo("4");
}

@Test
void testThrowsUnsupportedDataTypeForArray() {
assertThatThrownBy(() -> createExpression("a[0]").with("a", "aString").evaluate())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@
package com.ezylang.evalex.data.conversion;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

import com.ezylang.evalex.config.ExpressionConfiguration;
import com.ezylang.evalex.data.EvaluationValue;
import java.math.BigDecimal;
import java.time.Instant;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
Expand Down Expand Up @@ -61,15 +63,44 @@ void testArrayEmpty() {
assertThat(value.getArrayValue()).isEmpty();
}

@Test
void testArrayFromJavaArray() {
Instant now = Instant.now();
Object[] array =
new Object[] {"1", 2, new BigDecimal(3), null, EvaluationValue.dateTimeValue(now)};

EvaluationValue value = converter.convert(array, defaultConfiguration);

assertThat(value.isArrayValue()).isTrue();
assertThat(value.getArrayValue()).hasSize(5);
assertThat(value.getArrayValue().get(0).isStringValue()).isTrue();
assertThat(value.getArrayValue().get(0).getStringValue()).isEqualTo("1");
assertThat(value.getArrayValue().get(1).isNumberValue()).isTrue();
assertThat(value.getArrayValue().get(1).getStringValue()).isEqualTo("2");
assertThat(value.getArrayValue().get(2).isNumberValue()).isTrue();
assertThat(value.getArrayValue().get(2).getStringValue()).isEqualTo("3");
assertThat(value.getArrayValue().get(3).isNullValue()).isTrue();
assertThat(value.getArrayValue().get(3).getStringValue()).isNull();
assertThat(value.getArrayValue().get(4).isDateTimeValue()).isTrue();
assertThat(value.getArrayValue().get(4).getDateTimeValue()).isEqualTo(now);
}

@Test
void testCanConvert() {
assertThat(converter.canConvert(new String[] {"1", "2", "3"})).isTrue();
assertThat(converter.canConvert(Collections.EMPTY_LIST)).isTrue();
assertThat(converter.canConvert(Arrays.asList(1, 2, 3))).isTrue();
}

@Test
void testCanNotConvert() {
assertThat(converter.canConvert(new String[] {"1", "2", "3"})).isFalse();
assertThat(converter.canConvert(new BigDecimal(1))).isFalse();
}

@Test
void testIllegalArgumentException() {
assertThatThrownBy(() -> converter.convert("test", defaultConfiguration))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Unsupported data type 'java.lang.String'");
}
}

0 comments on commit 87b678a

Please sign in to comment.