From 247b0f0c90a0694d42ee85adf68bc2da9ddbe4ff Mon Sep 17 00:00:00 2001 From: David Waltermire Date: Mon, 3 Jun 2024 11:02:18 -0400 Subject: [PATCH] Implemented the map:find, map:put, and map:remove Metapath functions. Completed unit tests for all implemented map functions. --- .../function/library/ArrayRemove.java | 4 +- .../library/DefaultFunctionLibrary.java | 9 +- .../metapath/function/library/MapFind.java | 157 ++++++++++++++++++ .../metapath/function/library/MapPut.java | 117 +++++++++++++ .../metapath/function/library/MapRemove.java | 115 +++++++++++++ .../function/library/MapContainsTest.java | 74 +++++++++ .../function/library/MapEntryTest.java | 65 ++++++++ .../function/library/MapFindTest.java | 80 +++++++++ .../metapath/function/library/MapGetTest.java | 50 +++--- .../metapath/function/library/MapPutTest.java | 85 ++++++++++ .../function/library/MapRemoveTest.java | 101 +++++++++++ 11 files changed, 828 insertions(+), 29 deletions(-) create mode 100644 core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapFind.java create mode 100644 core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapPut.java create mode 100644 core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapRemove.java create mode 100644 core/src/test/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapContainsTest.java create mode 100644 core/src/test/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapEntryTest.java create mode 100644 core/src/test/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapFindTest.java create mode 100644 core/src/test/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapPutTest.java create mode 100644 core/src/test/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapRemoveTest.java diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/ArrayRemove.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/ArrayRemove.java index 0f8552d36..64a1a2019 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/ArrayRemove.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/ArrayRemove.java @@ -118,11 +118,11 @@ public static IArrayItem remove( @NonNull Collection positions) { Set positionSet = positions instanceof Set ? (Set) positions : new HashSet<>(positions); - List removed = ObjectUtils.notNull(IntStream.range(1, array.size() + 1) + List remaining = ObjectUtils.notNull(IntStream.range(1, array.size() + 1) .filter(index -> !positionSet.contains(index)) .mapToObj(index -> array.get(index - 1)) .collect(Collectors.toList())); - return IArrayItem.ofCollection(removed); + return IArrayItem.ofCollection(remaining); } } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/DefaultFunctionLibrary.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/DefaultFunctionLibrary.java index ee82725d3..3e1d70f52 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/DefaultFunctionLibrary.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/DefaultFunctionLibrary.java @@ -236,11 +236,14 @@ public DefaultFunctionLibrary() { // NOPMD - intentional registerFunction(MapContains.SIGNATURE); // https://www.w3.org/TR/xpath-functions-31/#func-map-get registerFunction(MapGet.SIGNATURE); - // P0: https://www.w3.org/TR/xpath-functions-31/#func-map-find - // P0: https://www.w3.org/TR/xpath-functions-31/#func-map-put + // https://www.w3.org/TR/xpath-functions-31/#func-map-find + registerFunction(MapFind.SIGNATURE); + // https://www.w3.org/TR/xpath-functions-31/#func-map-put + registerFunction(MapPut.SIGNATURE); // https://www.w3.org/TR/xpath-functions-31/#func-map-entry registerFunction(MapEntry.SIGNATURE); - // P0: https://www.w3.org/TR/xpath-functions-31/#func-map-remove + // https://www.w3.org/TR/xpath-functions-31/#func-map-remove + registerFunction(MapRemove.SIGNATURE); // P3: https://www.w3.org/TR/xpath-functions-31/#func-map-for-each // xpath casting functions diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapFind.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapFind.java new file mode 100644 index 000000000..2b1bd6b22 --- /dev/null +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapFind.java @@ -0,0 +1,157 @@ +/* + * Portions of this software was developed by employees of the National Institute + * of Standards and Technology (NIST), an agency of the Federal Government and is + * being made available as a public service. Pursuant to title 17 United States + * Code Section 105, works of NIST employees are not subject to copyright + * protection in the United States. This software may be subject to foreign + * copyright. Permission in the United States and in foreign countries, to the + * extent that NIST may hold copyright, to use, copy, modify, create derivative + * works, and distribute this software and its documentation without fee is hereby + * granted on a non-exclusive basis, provided that this notice and disclaimer + * of warranty appears in all copies. + * + * THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER + * EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY + * THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM + * INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE + * SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT + * SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, + * INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM, + * OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY, + * CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR + * PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT + * OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER. + */ + +package gov.nist.secauto.metaschema.core.metapath.function.library; + +import gov.nist.secauto.metaschema.core.metapath.DynamicContext; +import gov.nist.secauto.metaschema.core.metapath.ICollectionValue; +import gov.nist.secauto.metaschema.core.metapath.ISequence; +import gov.nist.secauto.metaschema.core.metapath.MetapathConstants; +import gov.nist.secauto.metaschema.core.metapath.function.FunctionUtils; +import gov.nist.secauto.metaschema.core.metapath.function.IArgument; +import gov.nist.secauto.metaschema.core.metapath.function.IFunction; +import gov.nist.secauto.metaschema.core.metapath.item.IItem; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.IAnyAtomicItem; +import gov.nist.secauto.metaschema.core.metapath.item.function.IArrayItem; +import gov.nist.secauto.metaschema.core.metapath.item.function.IMapItem; +import gov.nist.secauto.metaschema.core.util.ObjectUtils; + +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import edu.umd.cs.findbugs.annotations.NonNull; + +public final class MapFind { + @NonNull + public static final IFunction SIGNATURE = IFunction.builder() + .name("find") + .namespace(MetapathConstants.NS_METAPATH_FUNCTIONS_MAP) + .deterministic() + .contextIndependent() + .focusIndependent() + .argument(IArgument.builder() + .name("input") + .type(IItem.class) + .zeroOrMore() + .build()) + .argument(IArgument.builder() + .name("key") + .type(IAnyAtomicItem.class) + .one() + .build()) + .returnType(IArrayItem.class) + .returnOne() + .functionHandler(MapFind::execute) + .build(); + + private MapFind() { + // disable construction + } + + @SuppressWarnings("unused") + @NonNull + private static ISequence execute(@NonNull IFunction function, + @NonNull List> arguments, + @NonNull DynamicContext dynamicContext, + IItem focus) { + ISequence input = FunctionUtils.asType(ObjectUtils.requireNonNull(arguments.get(0))); + IAnyAtomicItem key = FunctionUtils.asType(ObjectUtils.requireNonNull(arguments.get(1).getFirstItem(true))); + + return ISequence.of(IArrayItem.ofCollection( + ObjectUtils.notNull(find((Collection) input, key) + .collect(Collectors.toList())))); + } + + /** + * An implementation of XPath 3.1 map:find. + * + * @param input + * the item sequence to search for key matches + * @param key + * the key for the item to retrieve + * @return the retrieved item + */ + @NonNull + public static Stream find( + @NonNull Collection input, + @NonNull IAnyAtomicItem key) { + return ObjectUtils.notNull(input.stream() + // handle item + .flatMap(item -> find(ObjectUtils.notNull(item), key))); + } + + @NonNull + public static Stream find( + @NonNull IItem item, + @NonNull IAnyAtomicItem key) { + Stream retval; + if (item instanceof IArrayItem) { + IArrayItem array = (IArrayItem) item; + retval = ObjectUtils.notNull(array.stream() + // handle array values + .flatMap(value -> find(ObjectUtils.notNull(value), key))); + } else if (item instanceof IMapItem) { + IMapItem map = (IMapItem) item; + // handle map + retval = find(map, key); + } else { + // do nothing + retval = ObjectUtils.notNull(Stream.empty()); + } + return retval; + } + + @NonNull + private static Stream find( + @NonNull ICollectionValue value, + @NonNull IAnyAtomicItem key) { + Stream retval; + if (value instanceof ISequence) { + ISequence sequence = (ISequence) value; + // handle sequence items + retval = find((Collection) sequence, key); + } else { + // handle item + retval = find((IItem) value, key); + } + return retval; + } + + @NonNull + public static Stream find( + @NonNull IMapItem map, + @NonNull IAnyAtomicItem key) { + return ObjectUtils.notNull(Stream.concat( + // add matching value, if it exists + Stream.ofNullable(MapGet.get(map, key)), + map.values().stream() + // handle map values + .flatMap(value -> find(ObjectUtils.notNull(value), key)))); + } +} diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapPut.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapPut.java new file mode 100644 index 000000000..84013f091 --- /dev/null +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapPut.java @@ -0,0 +1,117 @@ +/* + * Portions of this software was developed by employees of the National Institute + * of Standards and Technology (NIST), an agency of the Federal Government and is + * being made available as a public service. Pursuant to title 17 United States + * Code Section 105, works of NIST employees are not subject to copyright + * protection in the United States. This software may be subject to foreign + * copyright. Permission in the United States and in foreign countries, to the + * extent that NIST may hold copyright, to use, copy, modify, create derivative + * works, and distribute this software and its documentation without fee is hereby + * granted on a non-exclusive basis, provided that this notice and disclaimer + * of warranty appears in all copies. + * + * THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER + * EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY + * THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM + * INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE + * SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT + * SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, + * INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM, + * OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY, + * CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR + * PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT + * OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER. + */ + +package gov.nist.secauto.metaschema.core.metapath.function.library; + +import gov.nist.secauto.metaschema.core.metapath.DynamicContext; +import gov.nist.secauto.metaschema.core.metapath.ICollectionValue; +import gov.nist.secauto.metaschema.core.metapath.ISequence; +import gov.nist.secauto.metaschema.core.metapath.MetapathConstants; +import gov.nist.secauto.metaschema.core.metapath.function.FunctionUtils; +import gov.nist.secauto.metaschema.core.metapath.function.IArgument; +import gov.nist.secauto.metaschema.core.metapath.function.IFunction; +import gov.nist.secauto.metaschema.core.metapath.item.IItem; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.IAnyAtomicItem; +import gov.nist.secauto.metaschema.core.metapath.item.function.IMapItem; +import gov.nist.secauto.metaschema.core.metapath.item.function.IMapKey; +import gov.nist.secauto.metaschema.core.util.ObjectUtils; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import edu.umd.cs.findbugs.annotations.NonNull; + +public final class MapPut { + @NonNull + public static final IFunction SIGNATURE = IFunction.builder() + .name("put") + .namespace(MetapathConstants.NS_METAPATH_FUNCTIONS_MAP) + .deterministic() + .contextIndependent() + .focusIndependent() + .argument(IArgument.builder() + .name("map") + .type(IMapItem.class) + .one() + .build()) + .argument(IArgument.builder() + .name("key") + .type(IAnyAtomicItem.class) + .one() + .build()) + .argument(IArgument.builder() + .name("value") + .type(IItem.class) + .zeroOrMore() + .build()) + .returnType(IMapItem.class) + .returnOne() + .functionHandler(MapPut::execute) + .build(); + + private MapPut() { + // disable construction + } + + @SuppressWarnings("unused") + @NonNull + private static ISequence execute(@NonNull IFunction function, + @NonNull List> arguments, + @NonNull DynamicContext dynamicContext, + IItem focus) { + IMapItem map = FunctionUtils.asType(ObjectUtils.requireNonNull(arguments.get(0).getFirstItem(true))); + IAnyAtomicItem key = FunctionUtils.asType(ObjectUtils.requireNonNull(arguments.get(1).getFirstItem(true))); + @SuppressWarnings("unchecked") V value = (V) ObjectUtils.requireNonNull(arguments.get(2)).toCollectionValue(); + + return put(map, key, value).asSequence(); + } + + /** + * An implementation of XPath 3.1 map:put. + * + * @param + * the type of items in the given Metapath map + * @param map + * the map of Metapath items that is to be modified + * @param key + * the key for the value to add to the map + * @param value + * the value to add to the map + * @return the modified map + */ + @NonNull + public static IMapItem put( + @NonNull IMapItem map, + @NonNull IAnyAtomicItem key, + @NonNull V value) { + Map copy = new HashMap<>(map); + copy.put(key.asMapKey(), value); + + return IMapItem.ofCollection(copy); + } +} diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapRemove.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapRemove.java new file mode 100644 index 000000000..313c939b4 --- /dev/null +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapRemove.java @@ -0,0 +1,115 @@ +/* + * Portions of this software was developed by employees of the National Institute + * of Standards and Technology (NIST), an agency of the Federal Government and is + * being made available as a public service. Pursuant to title 17 United States + * Code Section 105, works of NIST employees are not subject to copyright + * protection in the United States. This software may be subject to foreign + * copyright. Permission in the United States and in foreign countries, to the + * extent that NIST may hold copyright, to use, copy, modify, create derivative + * works, and distribute this software and its documentation without fee is hereby + * granted on a non-exclusive basis, provided that this notice and disclaimer + * of warranty appears in all copies. + * + * THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER + * EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY + * THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM + * INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE + * SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT + * SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, + * INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM, + * OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY, + * CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR + * PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT + * OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER. + */ + +package gov.nist.secauto.metaschema.core.metapath.function.library; + +import gov.nist.secauto.metaschema.core.metapath.DynamicContext; +import gov.nist.secauto.metaschema.core.metapath.ICollectionValue; +import gov.nist.secauto.metaschema.core.metapath.ISequence; +import gov.nist.secauto.metaschema.core.metapath.MetapathConstants; +import gov.nist.secauto.metaschema.core.metapath.function.FunctionUtils; +import gov.nist.secauto.metaschema.core.metapath.function.IArgument; +import gov.nist.secauto.metaschema.core.metapath.function.IFunction; +import gov.nist.secauto.metaschema.core.metapath.item.IItem; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.IAnyAtomicItem; +import gov.nist.secauto.metaschema.core.metapath.item.function.IMapItem; +import gov.nist.secauto.metaschema.core.metapath.item.function.IMapKey; +import gov.nist.secauto.metaschema.core.util.ObjectUtils; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import edu.umd.cs.findbugs.annotations.NonNull; + +public final class MapRemove { + @NonNull + public static final IFunction SIGNATURE = IFunction.builder() + .name("remove") + .namespace(MetapathConstants.NS_METAPATH_FUNCTIONS_MAP) + .deterministic() + .contextIndependent() + .focusIndependent() + .argument(IArgument.builder() + .name("map") + .type(IMapItem.class) + .one() + .build()) + .argument(IArgument.builder() + .name("keys") + .type(IAnyAtomicItem.class) + .zeroOrMore() + .build()) + .returnType(IMapItem.class) + .returnOne() + .functionHandler(MapRemove::execute) + .build(); + + private MapRemove() { + // disable construction + } + + @SuppressWarnings("unused") + @NonNull + private static ISequence execute(@NonNull IFunction function, + @NonNull List> arguments, + @NonNull DynamicContext dynamicContext, + IItem focus) { + IMapItem map = FunctionUtils.asType(ObjectUtils.requireNonNull(arguments.get(0).getFirstItem(true))); + ISequence keys = FunctionUtils.asType(ObjectUtils.requireNonNull(arguments.get(1))); + + return ISequence.of(removeItems(map, keys)); + } + + /** + * An implementation of XPath 3.1 map:remove. + * + * @param + * the type of items in the given Metapath map + * @param map + * the map of Metapath items that is to be modified + * @param keys + * the keys to remove from the map + * @return the modified map + */ + @NonNull + public static IMapItem removeItems( + @NonNull IMapItem map, + @NonNull Collection keys) { + Set keySet = keys.stream() + .map(IAnyAtomicItem::asMapKey) + .collect(Collectors.toSet()); + + Map remaining = ObjectUtils.notNull(map.entrySet().stream() + .filter(entry -> !keySet.contains(entry.getKey())) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))); + + return IMapItem.ofCollection(remaining); + } +} diff --git a/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapContainsTest.java b/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapContainsTest.java new file mode 100644 index 000000000..e32735fdc --- /dev/null +++ b/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapContainsTest.java @@ -0,0 +1,74 @@ +/* + * Portions of this software was developed by employees of the National Institute + * of Standards and Technology (NIST), an agency of the Federal Government and is + * being made available as a public service. Pursuant to title 17 United States + * Code Section 105, works of NIST employees are not subject to copyright + * protection in the United States. This software may be subject to foreign + * copyright. Permission in the United States and in foreign countries, to the + * extent that NIST may hold copyright, to use, copy, modify, create derivative + * works, and distribute this software and its documentation without fee is hereby + * granted on a non-exclusive basis, provided that this notice and disclaimer + * of warranty appears in all copies. + * + * THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER + * EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY + * THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM + * INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE + * SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT + * SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, + * INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM, + * OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY, + * CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR + * PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT + * OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER. + */ + +package gov.nist.secauto.metaschema.core.metapath.function.library; + +import static gov.nist.secauto.metaschema.core.metapath.TestUtils.bool; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import gov.nist.secauto.metaschema.core.metapath.ExpressionTestBase; +import gov.nist.secauto.metaschema.core.metapath.MetapathExpression; +import gov.nist.secauto.metaschema.core.metapath.item.IItem; +import gov.nist.secauto.metaschema.core.metapath.item.function.LookupTest; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.stream.Stream; + +import edu.umd.cs.findbugs.annotations.NonNull; + +class MapContainsTest + extends ExpressionTestBase { + private static Stream provideValues() { // NOPMD - false positive + return Stream.of( + Arguments.of( + bool(true), + "let $week := " + LookupTest.WEEKDAYS_GERMAN + " return map:contains($week, 2)"), + Arguments.of( + bool(false), + "let $week := " + LookupTest.WEEKDAYS_GERMAN + " return map:contains($week, 9)"), + Arguments.of( + bool(false), + "map:contains(map{}, \"xyz\")"), + Arguments.of( + bool(true), + "map:contains(map{\"xyz\":23}, \"xyz\")"), + Arguments.of( + bool(true), + "map:contains(map{\"abc\":23, \"xyz\":()}, \"xyz\")")); + } + + @ParameterizedTest + @MethodSource("provideValues") + void testExpression(@NonNull IItem expected, @NonNull String metapath) { + + IItem result = MetapathExpression.compile(metapath) + .evaluateAs(null, MetapathExpression.ResultType.NODE, newDynamicContext()); + assertEquals(expected, result); + } +} diff --git a/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapEntryTest.java b/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapEntryTest.java new file mode 100644 index 000000000..46c2dff1d --- /dev/null +++ b/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapEntryTest.java @@ -0,0 +1,65 @@ +/* + * Portions of this software was developed by employees of the National Institute + * of Standards and Technology (NIST), an agency of the Federal Government and is + * being made available as a public service. Pursuant to title 17 United States + * Code Section 105, works of NIST employees are not subject to copyright + * protection in the United States. This software may be subject to foreign + * copyright. Permission in the United States and in foreign countries, to the + * extent that NIST may hold copyright, to use, copy, modify, create derivative + * works, and distribute this software and its documentation without fee is hereby + * granted on a non-exclusive basis, provided that this notice and disclaimer + * of warranty appears in all copies. + * + * THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER + * EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY + * THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM + * INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE + * SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT + * SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, + * INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM, + * OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY, + * CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR + * PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT + * OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER. + */ + +package gov.nist.secauto.metaschema.core.metapath.function.library; + +import static gov.nist.secauto.metaschema.core.metapath.TestUtils.entry; +import static gov.nist.secauto.metaschema.core.metapath.TestUtils.map; +import static gov.nist.secauto.metaschema.core.metapath.TestUtils.string; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import gov.nist.secauto.metaschema.core.metapath.ExpressionTestBase; +import gov.nist.secauto.metaschema.core.metapath.MetapathExpression; +import gov.nist.secauto.metaschema.core.metapath.item.IItem; +import gov.nist.secauto.metaschema.core.metapath.item.function.IMapItem; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.stream.Stream; + +import edu.umd.cs.findbugs.annotations.NonNull; + +class MapEntryTest + extends ExpressionTestBase { + + private static Stream provideValues() { // NOPMD - false positive + return Stream.of( + Arguments.of( + map(entry(string("M"), string("Monday"))), + "map:entry(\"M\", \"Monday\")")); + } + + @ParameterizedTest + @MethodSource("provideValues") + void testExpression(@NonNull IMapItem expected, @NonNull String metapath) { + + IItem result = MetapathExpression.compile(metapath) + .evaluateAs(null, MetapathExpression.ResultType.NODE, newDynamicContext()); + assertEquals(expected, result); + } +} diff --git a/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapFindTest.java b/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapFindTest.java new file mode 100644 index 000000000..24df92682 --- /dev/null +++ b/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapFindTest.java @@ -0,0 +1,80 @@ +/* + * Portions of this software was developed by employees of the National Institute + * of Standards and Technology (NIST), an agency of the Federal Government and is + * being made available as a public service. Pursuant to title 17 United States + * Code Section 105, works of NIST employees are not subject to copyright + * protection in the United States. This software may be subject to foreign + * copyright. Permission in the United States and in foreign countries, to the + * extent that NIST may hold copyright, to use, copy, modify, create derivative + * works, and distribute this software and its documentation without fee is hereby + * granted on a non-exclusive basis, provided that this notice and disclaimer + * of warranty appears in all copies. + * + * THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER + * EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY + * THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM + * INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE + * SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT + * SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, + * INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM, + * OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY, + * CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR + * PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT + * OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER. + */ + +package gov.nist.secauto.metaschema.core.metapath.function.library; + +import static gov.nist.secauto.metaschema.core.metapath.TestUtils.array; +import static gov.nist.secauto.metaschema.core.metapath.TestUtils.entry; +import static gov.nist.secauto.metaschema.core.metapath.TestUtils.map; +import static gov.nist.secauto.metaschema.core.metapath.TestUtils.sequence; +import static gov.nist.secauto.metaschema.core.metapath.TestUtils.string; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import gov.nist.secauto.metaschema.core.metapath.ExpressionTestBase; +import gov.nist.secauto.metaschema.core.metapath.MetapathExpression; +import gov.nist.secauto.metaschema.core.metapath.item.IItem; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.stream.Stream; + +import edu.umd.cs.findbugs.annotations.NonNull; + +class MapFindTest + extends ExpressionTestBase { + private static final String RESPONSES = "[map{0:'no', 1:'yes'}, map{0:'non', 1:'oui'}," + + " map{0:'nein', 1:('ja', 'doch')}]"; + private static final String INVENTORY = "map{\"name\":\"car\", \"id\":\"QZ123\"," + + " \"parts\": [map{\"name\":\"engine\", \"id\":\"YW678\", \"parts\":[]}]}"; + + private static Stream provideValues() { // NOPMD - false positive + return Stream.of( + Arguments.of( + array(string("no"), string("non"), string("nein")), + "let $responses := " + RESPONSES + " return map:find($responses, 0)"), + Arguments.of( + array(string("yes"), string("oui"), sequence(string("ja"), string("doch"))), + "let $responses := " + RESPONSES + " return map:find($responses, 1)"), + Arguments.of( + array(), + "let $responses := " + RESPONSES + " return map:find($responses, 2)"), + Arguments.of( + array(array(map(entry(string("name"), string("engine")), entry(string("id"), string("YW678")), + entry(string("parts"), array()))), array()), + "let $inventory := " + INVENTORY + " return map:find($inventory, \"parts\")")); + } + + @ParameterizedTest + @MethodSource("provideValues") + void testExpression(@NonNull IItem expected, @NonNull String metapath) { + + IItem result = MetapathExpression.compile(metapath) + .evaluateAs(null, MetapathExpression.ResultType.NODE, newDynamicContext()); + assertEquals(expected, result); + } +} diff --git a/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapGetTest.java b/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapGetTest.java index df07fa8c0..be8a46f3d 100644 --- a/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapGetTest.java +++ b/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapGetTest.java @@ -26,43 +26,45 @@ package gov.nist.secauto.metaschema.core.metapath.function.library; -import static gov.nist.secauto.metaschema.core.metapath.TestUtils.entry; -import static gov.nist.secauto.metaschema.core.metapath.TestUtils.integer; -import static gov.nist.secauto.metaschema.core.metapath.TestUtils.map; +import static gov.nist.secauto.metaschema.core.metapath.TestUtils.sequence; import static gov.nist.secauto.metaschema.core.metapath.TestUtils.string; import static org.junit.jupiter.api.Assertions.assertEquals; -import gov.nist.secauto.metaschema.core.metapath.DynamicContext; import gov.nist.secauto.metaschema.core.metapath.ExpressionTestBase; import gov.nist.secauto.metaschema.core.metapath.ISequence; import gov.nist.secauto.metaschema.core.metapath.MetapathExpression; -import gov.nist.secauto.metaschema.core.metapath.item.IItem; -import gov.nist.secauto.metaschema.core.metapath.item.function.IMapItem; +import gov.nist.secauto.metaschema.core.metapath.item.function.LookupTest; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; -import javax.xml.namespace.QName; +import java.util.stream.Stream; + +import edu.umd.cs.findbugs.annotations.NonNull; class MapGetTest extends ExpressionTestBase { - @Test - void test() { - IMapItem week = map( - entry(integer(0), string("Sonntag")), - entry(integer(1), string("Montag")), - entry(integer(2), string("Dienstag")), - entry(integer(3), string("Mittwoch")), - entry(integer(4), string("Donnerstag")), - entry(integer(5), string("Freitag")), - entry(integer(6), string("Samstag"))); + private static Stream provideValues() { // NOPMD - false positive + return Stream.of( + Arguments.of( + sequence(string("Donnerstag")), + "let $week := " + LookupTest.WEEKDAYS_GERMAN + " return map:get($week, 4)"), + Arguments.of( + sequence(), + "let $week := " + LookupTest.WEEKDAYS_GERMAN + " return map:get($week, 9)"), + Arguments.of( + sequence(), + "map:get(map:entry(7,()), 7)")); + } - DynamicContext context = new DynamicContext(); - context.bindVariableValue(new QName("week"), ISequence.of(week)); + @ParameterizedTest + @MethodSource("provideValues") + void testExpression(@NonNull ISequence expected, @NonNull String metapath) { - IItem result = MetapathExpression.compile("map:get($week, 4)") - .evaluateAs(null, MetapathExpression.ResultType.NODE, context); - assertEquals(string("Donnerstag"), result); + ISequence result = MetapathExpression.compile(metapath) + .evaluateAs(null, MetapathExpression.ResultType.SEQUENCE, newDynamicContext()); + assertEquals(expected, result); } - } diff --git a/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapPutTest.java b/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapPutTest.java new file mode 100644 index 000000000..345b48e3f --- /dev/null +++ b/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapPutTest.java @@ -0,0 +1,85 @@ +/* + * Portions of this software was developed by employees of the National Institute + * of Standards and Technology (NIST), an agency of the Federal Government and is + * being made available as a public service. Pursuant to title 17 United States + * Code Section 105, works of NIST employees are not subject to copyright + * protection in the United States. This software may be subject to foreign + * copyright. Permission in the United States and in foreign countries, to the + * extent that NIST may hold copyright, to use, copy, modify, create derivative + * works, and distribute this software and its documentation without fee is hereby + * granted on a non-exclusive basis, provided that this notice and disclaimer + * of warranty appears in all copies. + * + * THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER + * EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY + * THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM + * INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE + * SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT + * SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, + * INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM, + * OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY, + * CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR + * PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT + * OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER. + */ + +package gov.nist.secauto.metaschema.core.metapath.function.library; + +import static gov.nist.secauto.metaschema.core.metapath.TestUtils.entry; +import static gov.nist.secauto.metaschema.core.metapath.TestUtils.integer; +import static gov.nist.secauto.metaschema.core.metapath.TestUtils.map; +import static gov.nist.secauto.metaschema.core.metapath.TestUtils.string; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import gov.nist.secauto.metaschema.core.metapath.ExpressionTestBase; +import gov.nist.secauto.metaschema.core.metapath.MetapathExpression; +import gov.nist.secauto.metaschema.core.metapath.item.IItem; +import gov.nist.secauto.metaschema.core.metapath.item.function.IMapItem; +import gov.nist.secauto.metaschema.core.metapath.item.function.LookupTest; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.stream.Stream; + +import edu.umd.cs.findbugs.annotations.NonNull; + +class MapPutTest + extends ExpressionTestBase { + + private static Stream provideValues() { // NOPMD - false positive + return Stream.of( + Arguments.of( + map( + entry(integer(0), string("Sonntag")), + entry(integer(1), string("Montag")), + entry(integer(2), string("Dienstag")), + entry(integer(3), string("Mittwoch")), + entry(integer(4), string("Donnerstag")), + entry(integer(5), string("Freitag")), + entry(integer(6), string("Sonnabend"))), + "let $week := " + LookupTest.WEEKDAYS_GERMAN + " return map:put($week, 6, \"Sonnabend\") "), + Arguments.of( + map( + entry(integer(0), string("Sonntag")), + entry(integer(1), string("Montag")), + entry(integer(2), string("Dienstag")), + entry(integer(3), string("Mittwoch")), + entry(integer(4), string("Donnerstag")), + entry(integer(5), string("Freitag")), + entry(integer(6), string("Samstag")), + entry(integer(-1), string("Unbekannt"))), + "let $week := " + LookupTest.WEEKDAYS_GERMAN + " return map:put($week, -1, \"Unbekannt\")")); + } + + @ParameterizedTest + @MethodSource("provideValues") + void testExpression(@NonNull IMapItem expected, @NonNull String metapath) { + + IItem result = MetapathExpression.compile(metapath) + .evaluateAs(null, MetapathExpression.ResultType.NODE, newDynamicContext()); + assertEquals(expected, result); + } +} diff --git a/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapRemoveTest.java b/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapRemoveTest.java new file mode 100644 index 000000000..d2955151e --- /dev/null +++ b/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapRemoveTest.java @@ -0,0 +1,101 @@ +/* + * Portions of this software was developed by employees of the National Institute + * of Standards and Technology (NIST), an agency of the Federal Government and is + * being made available as a public service. Pursuant to title 17 United States + * Code Section 105, works of NIST employees are not subject to copyright + * protection in the United States. This software may be subject to foreign + * copyright. Permission in the United States and in foreign countries, to the + * extent that NIST may hold copyright, to use, copy, modify, create derivative + * works, and distribute this software and its documentation without fee is hereby + * granted on a non-exclusive basis, provided that this notice and disclaimer + * of warranty appears in all copies. + * + * THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER + * EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY + * THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM + * INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE + * SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT + * SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, + * INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM, + * OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY, + * CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR + * PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT + * OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER. + */ + +package gov.nist.secauto.metaschema.core.metapath.function.library; + +import static gov.nist.secauto.metaschema.core.metapath.TestUtils.entry; +import static gov.nist.secauto.metaschema.core.metapath.TestUtils.integer; +import static gov.nist.secauto.metaschema.core.metapath.TestUtils.map; +import static gov.nist.secauto.metaschema.core.metapath.TestUtils.string; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import gov.nist.secauto.metaschema.core.metapath.ExpressionTestBase; +import gov.nist.secauto.metaschema.core.metapath.MetapathExpression; +import gov.nist.secauto.metaschema.core.metapath.item.IItem; +import gov.nist.secauto.metaschema.core.metapath.item.function.IMapItem; +import gov.nist.secauto.metaschema.core.metapath.item.function.LookupTest; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.stream.Stream; + +import edu.umd.cs.findbugs.annotations.NonNull; + +class MapRemoveTest + extends ExpressionTestBase { + + private static Stream provideValues() { // NOPMD - false positive + return Stream.of( + Arguments.of( + map( + entry(integer(0), string("Sonntag")), + entry(integer(1), string("Montag")), + entry(integer(2), string("Dienstag")), + entry(integer(3), string("Mittwoch")), + entry(integer(5), string("Freitag")), + entry(integer(6), string("Samstag"))), + "let $week := " + LookupTest.WEEKDAYS_GERMAN + " return map:remove($week, 4)"), + Arguments.of( + map( + entry(integer(0), string("Sonntag")), + entry(integer(1), string("Montag")), + entry(integer(2), string("Dienstag")), + entry(integer(3), string("Mittwoch")), + entry(integer(4), string("Donnerstag")), + entry(integer(5), string("Freitag")), + entry(integer(6), string("Samstag"))), + "let $week := " + LookupTest.WEEKDAYS_GERMAN + " return map:remove($week, 23)"), + Arguments.of( + map( + entry(integer(1), string("Montag")), + entry(integer(2), string("Dienstag")), + entry(integer(3), string("Mittwoch")), + entry(integer(4), string("Donnerstag")), + entry(integer(5), string("Freitag"))), + "let $week := " + LookupTest.WEEKDAYS_GERMAN + " return map:remove($week, (0, 6 to 7))"), + Arguments.of( + map( + entry(integer(0), string("Sonntag")), + entry(integer(1), string("Montag")), + entry(integer(2), string("Dienstag")), + entry(integer(3), string("Mittwoch")), + entry(integer(4), string("Donnerstag")), + entry(integer(5), string("Freitag")), + entry(integer(6), string("Samstag"))), + "let $week := " + LookupTest.WEEKDAYS_GERMAN + " return map:remove($week, ())")); + } + + @ParameterizedTest + @MethodSource("provideValues") + void testExpression(@NonNull IMapItem expected, @NonNull String metapath) { + + IItem result = MetapathExpression.compile(metapath) + .evaluateAs(null, MetapathExpression.ResultType.NODE, newDynamicContext()); + assertEquals(expected, result); + } +}