From 5c430aaaa36f973d3573477962aee26943ed947a Mon Sep 17 00:00:00 2001 From: Gabriele Cardosi Date: Mon, 22 Apr 2024 17:05:06 +0200 Subject: [PATCH] [incubator-kie-issues#1100] Fix oas-generation. Add tests (#5858) Co-authored-by: Gabriele-Cardosi --- .../kie/dmn/openapi/impl/DMNTypeSchemas.java | 13 +- .../kie/dmn/openapi/impl/FEELSchemaEnum.java | 73 +++++-- .../kie/dmn/openapi/FEELSchemaEnumTest.java | 60 ----- .../dmn/openapi/impl/FEELSchemaEnumTest.java | 206 ++++++++++++++++++ 4 files changed, 269 insertions(+), 83 deletions(-) delete mode 100644 kie-dmn/kie-dmn-openapi/src/test/java/org/kie/dmn/openapi/FEELSchemaEnumTest.java create mode 100644 kie-dmn/kie-dmn-openapi/src/test/java/org/kie/dmn/openapi/impl/FEELSchemaEnumTest.java diff --git a/kie-dmn/kie-dmn-openapi/src/main/java/org/kie/dmn/openapi/impl/DMNTypeSchemas.java b/kie-dmn/kie-dmn-openapi/src/main/java/org/kie/dmn/openapi/impl/DMNTypeSchemas.java index 94706266053..92a04692a81 100644 --- a/kie-dmn/kie-dmn-openapi/src/main/java/org/kie/dmn/openapi/impl/DMNTypeSchemas.java +++ b/kie-dmn/kie-dmn-openapi/src/main/java/org/kie/dmn/openapi/impl/DMNTypeSchemas.java @@ -18,8 +18,10 @@ */ package org.kie.dmn.openapi.impl; +import java.time.LocalDate; import java.util.ArrayList; import java.util.Collections; +import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -72,8 +74,7 @@ private Schema refOrBuiltinSchema(DMNType t) { return FEELBuiltinTypeSchemas.from(t); } if (typesIndex.contains(t)) { - Schema schema = OASFactory.createObject(Schema.class).ref(namingPolicy.getRef(t)); - return schema; + return OASFactory.createObject(Schema.class).ref(namingPolicy.getRef(t)); } throw new UnsupportedOperationException(); } @@ -131,7 +132,7 @@ private Schema schemaFromSimpleType(SimpleTypeImpl t) { parseSimpleType(DMNOASConstants.X_DMN_ALLOWED_VALUES, t, schema, t.getAllowedValuesFEEL(), t.getAllowedValues()); } if (t.getTypeConstraint() != null && !t.getTypeConstraint().isEmpty()) { - parseSimpleType(DMNOASConstants.X_DMN_TYPE_CONSTRAINTS, t, schema, t.getTypeConstraintFEEL(), t.getAllowedValues()); + parseSimpleType(DMNOASConstants.X_DMN_TYPE_CONSTRAINTS, t, schema, t.getTypeConstraintFEEL(), t.getTypeConstraint()); } schema = nestAsItemIfCollection(schema, t); schema.addExtension(X_DMN_TYPE, getDMNTypeSchemaXDMNTYPEdescr(t)); @@ -142,7 +143,9 @@ private Schema schemaFromSimpleType(SimpleTypeImpl t) { private void parseSimpleType(String schemaString, SimpleTypeImpl t, Schema schema, List feelUnaryTests, List dmnUnaryTests) { schema.addExtension(schemaString, feelUnaryTests.stream().map(UnaryTest::toString).collect(Collectors.joining(", "))); if (DMNTypeUtils.getFEELBuiltInType(ancestor(t)) == BuiltInType.NUMBER) { - FEELSchemaEnum.parseNumbersIntoSchema(schema, dmnUnaryTests); + FEELSchemaEnum.parseRangeableValuesIntoSchema(schema, dmnUnaryTests, Number.class); + } else if (DMNTypeUtils.getFEELBuiltInType(ancestor(t)) == BuiltInType.DATE) { + FEELSchemaEnum.parseRangeableValuesIntoSchema(schema, dmnUnaryTests, LocalDate.class); } else { FEELSchemaEnum.parseValuesIntoSchema(schema, dmnUnaryTests); } @@ -154,7 +157,7 @@ private Schema schemaFromCompositeType(CompositeTypeImpl ct) { for (Entry fkv : ct.getFields().entrySet()) { schema.addProperty(fkv.getKey(), refOrBuiltinSchema(fkv.getValue())); } - if (isIOSetForInputScope(ct) && ct.getFields().size() > 0) { + if (isIOSetForInputScope(ct) && !ct.getFields().isEmpty()) { schema.required(new ArrayList<>(ct.getFields().keySet())); } } else { diff --git a/kie-dmn/kie-dmn-openapi/src/main/java/org/kie/dmn/openapi/impl/FEELSchemaEnum.java b/kie-dmn/kie-dmn-openapi/src/main/java/org/kie/dmn/openapi/impl/FEELSchemaEnum.java index 30e2cb58138..ccdb377508f 100644 --- a/kie-dmn/kie-dmn-openapi/src/main/java/org/kie/dmn/openapi/impl/FEELSchemaEnum.java +++ b/kie-dmn/kie-dmn-openapi/src/main/java/org/kie/dmn/openapi/impl/FEELSchemaEnum.java @@ -18,10 +18,6 @@ */ package org.kie.dmn.openapi.impl; -import java.math.BigDecimal; -import java.util.List; -import java.util.stream.Collectors; - import org.eclipse.microprofile.openapi.models.media.Schema; import org.kie.dmn.api.core.DMNUnaryTest; import org.kie.dmn.feel.FEEL; @@ -32,24 +28,35 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.math.BigDecimal; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + public class FEELSchemaEnum { private static final Logger LOG = LoggerFactory.getLogger(FEELSchemaEnum.class); - public static void parseValuesIntoSchema(Schema schema, List list) { - List expectLiterals = evaluateUnaryTests(list); + public static void parseValuesIntoSchema(Schema schema, List unaryTests) { + List expectLiterals = evaluateUnaryTests(unaryTests); + try { + checkEvaluatedUnaryTestsForTypeConsistency(expectLiterals); + } catch (IllegalArgumentException e) { + LOG.warn("Unable to parse generic value into the JSON Schema for enumeration"); + return; + } if (expectLiterals.contains(null)) { schema.setNullable(true); } - boolean allLiterals = expectLiterals.stream().allMatch(o -> o == null || o instanceof String || o instanceof Number || o instanceof Boolean); + boolean allLiterals = !expectLiterals.isEmpty() && expectLiterals.stream().allMatch(o -> o == null || o instanceof String || o instanceof Number || o instanceof Boolean); if (allLiterals) { schema.enumeration(expectLiterals); } else { LOG.warn("Unable to parse generic value into the JSON Schema for enumeration"); } } - - public static void parseNumbersIntoSchema(Schema schema, List list) { + + public static void parseRangeableValuesIntoSchema(Schema schema, List list, Class expectedType) { List uts = evaluateUnaryTests(list); // we leverage the property of the *base* FEEL grammar(non visited by ASTVisitor, only the ParseTree->AST Visitor) that `>x` is a Range boolean allowNull = uts.remove(null); if (allowNull) { @@ -67,13 +74,13 @@ public static void parseNumbersIntoSchema(Schema schema, List list schema.exclusiveMaximum(range.getHighBoundary() == RangeBoundary.OPEN); } } - } else if (uts.stream().allMatch(o -> o instanceof Number)) { + } else if (uts.stream().allMatch(expectedType::isInstance)) { if (allowNull) { uts.add(null); } schema.enumeration(uts); } else { - LOG.warn("Unable to parse number value into the JSON Schema for enumeration"); + LOG.warn("Unable to parse {} value into the JSON Schema for enumeration", expectedType); } } @@ -99,13 +106,43 @@ public static Range consolidateRanges(List ranges) { return consistent ? result : null; } - private static List evaluateUnaryTests(List list) { - FEEL SimpleFEEL = FEEL.newInstance(); - List utEvaluated = list.stream().map(UnaryTestImpl.class::cast) - .map(UnaryTestImpl::toString) - .map(SimpleFEEL::evaluate) - .collect(Collectors.toList()); - return utEvaluated; + static List evaluateUnaryTests(List list) { + FEEL feelInstance = FEEL.newInstance(); + List toReturn = list.stream() + .map(UnaryTestImpl.class::cast) + .map(UnaryTestImpl::toString) + .filter(str -> !str.contains("?")) // We have to exclude "TEST" expressions, because they can't be evaluated without a context and their return is meaningless + .map(feelInstance::evaluate) + .collect(Collectors.toList()); + checkEvaluatedUnaryTestsForNull(toReturn); + return toReturn; + } + + /** + * Method used to verify if the given List contains at most one null, + * since those should be put in the "enum" attribute + * + * @param toCheck + */ + static void checkEvaluatedUnaryTestsForNull(List toCheck) { + if (toCheck.stream().filter(Objects::isNull).toList().size() > 1) { + throw new IllegalArgumentException("More then one object is null, only one allowed at maximum"); + } + } + + /** + * Method used to verify if the given List contains the same type of Objects, + * since those should be put in the "enum" attribute + * + * @param toCheck + */ + static void checkEvaluatedUnaryTestsForTypeConsistency(List toCheck) { + if (toCheck.stream().filter(Objects::nonNull) + .map(Object::getClass) + .collect(Collectors.toUnmodifiableSet()) + .size() > 1) { + throw new IllegalArgumentException("Different types of objects, only one allowed"); + } } private FEELSchemaEnum() { diff --git a/kie-dmn/kie-dmn-openapi/src/test/java/org/kie/dmn/openapi/FEELSchemaEnumTest.java b/kie-dmn/kie-dmn-openapi/src/test/java/org/kie/dmn/openapi/FEELSchemaEnumTest.java deleted file mode 100644 index 6cfc24287b1..00000000000 --- a/kie-dmn/kie-dmn-openapi/src/test/java/org/kie/dmn/openapi/FEELSchemaEnumTest.java +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.kie.dmn.openapi; - -import java.util.ArrayList; -import java.util.List; - -import org.junit.Test; -import org.kie.dmn.feel.runtime.Range; -import org.kie.dmn.feel.runtime.Range.RangeBoundary; -import org.kie.dmn.feel.runtime.impl.RangeImpl; -import org.kie.dmn.openapi.impl.FEELSchemaEnum; - -import static org.assertj.core.api.Assertions.assertThat; - -public class FEELSchemaEnumTest extends BaseDMNOASTest { - - @Test - public void testBasic() { - List list = new ArrayList<>(); - list.add(new RangeImpl(RangeBoundary.CLOSED, 0, null, RangeBoundary.CLOSED)); - list.add(new RangeImpl(RangeBoundary.CLOSED, null, 100, RangeBoundary.CLOSED)); - Range result = FEELSchemaEnum.consolidateRanges(list); - assertThat(result).isNotNull().isEqualTo(new RangeImpl(RangeBoundary.CLOSED, 0, 100, RangeBoundary.CLOSED)); - } - - @Test - public void testInvalidRepeatedLB() { - List list = new ArrayList<>(); - list.add(new RangeImpl(RangeBoundary.CLOSED, 0, null, RangeBoundary.CLOSED)); - list.add(new RangeImpl(RangeBoundary.CLOSED, 0, 100, RangeBoundary.CLOSED)); - Range result = FEELSchemaEnum.consolidateRanges(list); - assertThat(result).isNull(); - } - - @Test - public void testInvalidRepeatedUB() { - List list = new ArrayList<>(); - list.add(new RangeImpl(RangeBoundary.CLOSED, null, 50, RangeBoundary.CLOSED)); - list.add(new RangeImpl(RangeBoundary.CLOSED, null, 100, RangeBoundary.CLOSED)); - Range result = FEELSchemaEnum.consolidateRanges(list); - assertThat(result).isNull(); - } -} diff --git a/kie-dmn/kie-dmn-openapi/src/test/java/org/kie/dmn/openapi/impl/FEELSchemaEnumTest.java b/kie-dmn/kie-dmn-openapi/src/test/java/org/kie/dmn/openapi/impl/FEELSchemaEnumTest.java new file mode 100644 index 00000000000..70704d44524 --- /dev/null +++ b/kie-dmn/kie-dmn-openapi/src/test/java/org/kie/dmn/openapi/impl/FEELSchemaEnumTest.java @@ -0,0 +1,206 @@ +package org.kie.dmn.openapi.impl; + + +import org.eclipse.microprofile.openapi.OASFactory; +import org.eclipse.microprofile.openapi.models.media.Schema; +import org.junit.Test; +import org.kie.dmn.api.core.DMNUnaryTest; +import org.kie.dmn.feel.FEEL; +import org.kie.dmn.feel.runtime.Range; +import org.kie.dmn.feel.runtime.impl.RangeImpl; + +import java.math.BigDecimal; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.kie.dmn.openapi.impl.FEELSchemaEnum.checkEvaluatedUnaryTestsForNull; +import static org.kie.dmn.openapi.impl.FEELSchemaEnum.checkEvaluatedUnaryTestsForTypeConsistency; +import static org.kie.dmn.openapi.impl.FEELSchemaEnum.evaluateUnaryTests; +import static org.kie.dmn.openapi.impl.FEELSchemaEnum.parseRangeableValuesIntoSchema; +import static org.kie.dmn.openapi.impl.FEELSchemaEnum.parseValuesIntoSchema; + +public class FEELSchemaEnumTest { + + private static final FEEL feel = FEEL.newInstance(); + + @Test + public void testParseValuesIntoSchemaWithoutNull() { + Schema toPopulate = OASFactory.createObject(Schema.class); + List expectedStrings = Arrays.asList("ONE", "TWO"); + List toEnum = expectedStrings.stream().map(toMap -> String.format("\"%s\"", toMap)).collect(Collectors.toUnmodifiableList()); + String expression = String.join(",", toEnum.stream().map(toMap -> String.format("%s", toMap.toString())).toList()); + expression += ", count (?) > 1"; + List unaryTests = feel.evaluateUnaryTests(expression).stream().map(DMNUnaryTest.class::cast).toList(); + parseValuesIntoSchema(toPopulate, unaryTests); + assertNull(toPopulate.getNullable()); + assertNotNull(toPopulate.getEnumeration()); + assertEquals(expectedStrings.size(), toPopulate.getEnumeration().size()); + expectedStrings.forEach(expectedString -> assertTrue(toPopulate.getEnumeration().contains(expectedString))); + } + + @Test + public void testParseValuesIntoSchemaWithNull() { + Schema toPopulate = OASFactory.createObject(Schema.class); + List expectedStrings = Arrays.asList(null, "ONE", "TWO"); + List toEnum = expectedStrings.stream().map(toFormat -> toFormat == null ? "null": String.format("\"%s\"", toFormat)).collect(Collectors.toUnmodifiableList()); + String expression = String.join(",", toEnum.stream().map(toMap -> String.format("%s", toMap.toString())).toList()); + List unaryTests = feel.evaluateUnaryTests(expression).stream().map(DMNUnaryTest.class::cast).toList(); + parseValuesIntoSchema(toPopulate, unaryTests); + assertTrue(toPopulate.getNullable()); + assertNotNull(toPopulate.getEnumeration()); + assertEquals(expectedStrings.size(), toPopulate.getEnumeration().size()); + expectedStrings.stream().filter(Objects::nonNull).forEach(expectedString -> assertTrue(toPopulate.getEnumeration().contains(expectedString))); + } + + @Test + public void testParseRangeableValuesIntoSchemaNumberWithoutNull() { + Schema toPopulate = OASFactory.createObject(Schema.class); + List expectedNumbers = Arrays.asList(1, 2); + String expression = String.join(",", expectedNumbers.stream().map(toMap -> String.format("%s", toMap)).toList()); + List unaryTests = feel.evaluateUnaryTests(expression).stream().map(DMNUnaryTest.class::cast).toList(); + parseRangeableValuesIntoSchema(toPopulate, unaryTests, Number.class); + assertNull(toPopulate.getNullable()); + assertNotNull(toPopulate.getEnumeration()); + assertEquals(expectedNumbers.size(), toPopulate.getEnumeration().size()); + List expected = Arrays.asList(BigDecimal.valueOf(1), BigDecimal.valueOf(2)); + expected.forEach(expectedNumber -> assertTrue(toPopulate.getEnumeration().contains(expectedNumber))); + } + + @Test + public void testParseRangeableValuesNumberIntoSchemaWithNull() { + Schema toPopulate = OASFactory.createObject(Schema.class); + List expectedNumbers = Arrays.asList(null, 1, 2); + String expression = String.join(",", expectedNumbers.stream().map(toMap -> String.format("%s", toMap)).toList()); + List unaryTests = feel.evaluateUnaryTests(expression).stream().map(DMNUnaryTest.class::cast).toList(); + parseRangeableValuesIntoSchema(toPopulate, unaryTests, Number.class); + assertTrue(toPopulate.getNullable()); + assertNotNull(toPopulate.getEnumeration()); + assertEquals(expectedNumbers.size(), toPopulate.getEnumeration().size()); + List expected = Arrays.asList(null, BigDecimal.valueOf(1), BigDecimal.valueOf(2)); + expected.stream().forEach(expectedNumber -> assertTrue(toPopulate.getEnumeration().contains(expectedNumber))); + } + + @Test + public void testParseRangeableValuesIntoSchemaLocalDateWithoutNull() { + Schema toPopulate = OASFactory.createObject(Schema.class); + List expectedDates = Arrays.asList(LocalDate.of(2022, 1, 1), LocalDate.of(2024, 1, 1)); + List formattedDates = expectedDates.stream() + .map(toFormat -> String.format("@\"%s-0%s-0%s\"", toFormat.getYear(), toFormat.getMonthValue(), toFormat.getDayOfMonth())) + .toList(); + String expression = String.join(",", formattedDates.stream().map(toMap -> String.format("%s", toMap)).toList()); + List unaryTests = feel.evaluateUnaryTests(expression).stream().map(DMNUnaryTest.class::cast).toList(); + parseRangeableValuesIntoSchema(toPopulate, unaryTests, LocalDate.class); + assertNull(toPopulate.getNullable()); + assertNotNull(toPopulate.getEnumeration()); + assertEquals(expectedDates.size(), toPopulate.getEnumeration().size()); + expectedDates.forEach(expectedDate -> assertTrue(toPopulate.getEnumeration().contains(expectedDate))); + } + + @Test + public void testParseRangeableValuesDateIntoSchemaWithNull() { + Schema toPopulate = OASFactory.createObject(Schema.class); + List expectedDates = Arrays.asList(null, LocalDate.of(2022, 1, 1), LocalDate.of(2024, 1, 1)); + List formattedDates = expectedDates.stream() + .map(toFormat -> toFormat == null ? "null" : String.format("@\"%s-0%s-0%s\"", toFormat.getYear(), toFormat.getMonthValue(), toFormat.getDayOfMonth())) + .toList(); + String expression = String.join(",", formattedDates.stream().map(toMap -> String.format("%s", toMap)).toList()); + List unaryTests = feel.evaluateUnaryTests(expression).stream().map(DMNUnaryTest.class::cast).toList(); + parseRangeableValuesIntoSchema(toPopulate, unaryTests, LocalDate.class); + assertTrue(toPopulate.getNullable()); + assertNotNull(toPopulate.getEnumeration()); + assertEquals(expectedDates.size(), toPopulate.getEnumeration().size()); + expectedDates.forEach(expectedDate -> assertTrue(toPopulate.getEnumeration().contains(expectedDate))); + } + + @Test + public void testConsolidateRangesSucceed() { + Range lowRange = new RangeImpl(Range.RangeBoundary.CLOSED, 0, null, Range.RangeBoundary.CLOSED); + Range highRange = new RangeImpl(Range.RangeBoundary.CLOSED, null, 100, Range.RangeBoundary.CLOSED); + List list = Arrays.asList(lowRange, highRange); + Range result = FEELSchemaEnum.consolidateRanges(list); + assertThat(result).isNotNull().isEqualTo(new RangeImpl(lowRange.getLowBoundary(), lowRange.getLowEndPoint(), highRange.getHighEndPoint(), highRange.getHighBoundary())); + // + lowRange = new RangeImpl(Range.RangeBoundary.CLOSED, LocalDate.of(2022, 1, 1), null, Range.RangeBoundary.CLOSED); + highRange = new RangeImpl(Range.RangeBoundary.CLOSED, null, LocalDate.of(2024, 1, 1), Range.RangeBoundary.CLOSED); + list = Arrays.asList(lowRange, highRange); + result = FEELSchemaEnum.consolidateRanges(list); + assertThat(result).isNotNull().isEqualTo(new RangeImpl(lowRange.getLowBoundary(), lowRange.getLowEndPoint(), highRange.getHighEndPoint(), highRange.getHighBoundary())); + } + + @Test + public void testConsolidateRangesInvalidRepeatedLB() { + List list = new ArrayList<>(); + list.add(new RangeImpl(Range.RangeBoundary.CLOSED, 0, null, Range.RangeBoundary.CLOSED)); + list.add(new RangeImpl(Range.RangeBoundary.CLOSED, 0, 100, Range.RangeBoundary.CLOSED)); + Range result = FEELSchemaEnum.consolidateRanges(list); + assertThat(result).isNull(); + } + + @Test + public void testConsolidateRangesInvalidRepeatedUB() { + List list = new ArrayList<>(); + list.add(new RangeImpl(Range.RangeBoundary.CLOSED, null, 50, Range.RangeBoundary.CLOSED)); + list.add(new RangeImpl(Range.RangeBoundary.CLOSED, null, 100, Range.RangeBoundary.CLOSED)); + Range result = FEELSchemaEnum.consolidateRanges(list); + assertThat(result).isNull(); + } + + @Test + public void testEvaluateUnaryTestsSucceed() { + List toEnum = Arrays.asList("\"a string\"", 3, "@\"2024-01-01\""); + String expression = String.join(",", toEnum.stream().map(toMap -> String.format("%s", toMap.toString())).toList()); + expression += ", count (?) > 1"; + List toCheck = feel.evaluateUnaryTests(expression).stream().map(DMNUnaryTest.class::cast).toList(); + assertEquals(toEnum.size() + 1, toCheck.size()); + List retrieved = evaluateUnaryTests(toCheck); + List expected = Arrays.asList("a string", BigDecimal.valueOf(3), LocalDate.of(2024, 1, 1)); + assertEquals(expected.size(), retrieved.size()); + expected.forEach(expectedEntry -> assertTrue("Failing asserts for " + expectedEntry, retrieved.stream().anyMatch(ret -> Objects.equals(expectedEntry, ret)))); + } + + @Test(expected = IllegalArgumentException.class) + public void testEvaluateUnaryTestsFails() { + List toEnum = Arrays.asList(null, null, "@\"2024-01-01\""); + String expression = String.join(",", toEnum.stream().map(toMap -> String.format("%s", toMap)).toList()); + List toCheck = feel.evaluateUnaryTests(expression).stream().map(DMNUnaryTest.class::cast).toList(); + assertEquals(toEnum.size(), toCheck.size()); + evaluateUnaryTests(toCheck); + } + + @Test + public void testCheckEvaluatedUnaryTestsForNullSucceed() { + List toCheck = new ArrayList<>(Arrays.asList("1", "2", "3")); + checkEvaluatedUnaryTestsForNull(toCheck); + toCheck.add(null); + checkEvaluatedUnaryTestsForNull(toCheck); + } + + @Test(expected = IllegalArgumentException.class) + public void testCheckEvaluatedUnaryTestsForNullFails() { + List toCheck = new ArrayList<>(Arrays.asList("1", "2", "3")); + toCheck.add(null); + toCheck.add(null); + checkEvaluatedUnaryTestsForNull(toCheck); + } + + @Test + public void testCheckEvaluatedUnaryTestsForTypeConsistencySucceed() { + List toCheck = Arrays.asList("1", "2", "3"); + checkEvaluatedUnaryTestsForTypeConsistency(toCheck); + } + + @Test(expected = IllegalArgumentException.class) + public void testCheckEvaluatedUnaryTestsForTypeConsistencyFails() { + List toCheck = Arrays.asList("1", "2", 3); + checkEvaluatedUnaryTestsForTypeConsistency(toCheck); + } +} \ No newline at end of file