All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ee.jakarta.tck.jsonp.api.patchtests.PatchOperationMove Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package ee.jakarta.tck.jsonp.api.patchtests;

import ee.jakarta.tck.jsonp.api.common.JsonAssert;
import ee.jakarta.tck.jsonp.api.common.SimpleValues;
import ee.jakarta.tck.jsonp.api.common.TestResult;
import jakarta.json.Json;
import jakarta.json.JsonArray;
import jakarta.json.JsonException;
import jakarta.json.JsonObject;
import jakarta.json.JsonPatch;
import jakarta.json.JsonPatchBuilder;
import jakarta.json.JsonPointer;
import jakarta.json.JsonValue;

import java.util.logging.Logger;

// $Id$
/**
 * RFC 6902: JavaScript Object Notation (JSON) Patch compatibility tests.
* {@see RFC 6902}. *

* Implements * {@see RFC 6902: * 4.4. move} tests. */ public class PatchOperationMove extends CommonOperation { private static final Logger LOGGER = Logger.getLogger(PatchOperationMove.class.getName()); /** Tested operation name. */ private final String OPERATION = "MOVE"; /** * Creates an instance of RFC 6902 replace operation test. */ PatchOperationMove() { super(); } /** * Test RFC 6902 MOVE operation. Suite entry point. * * @return Result of all tests in this suite. */ TestResult test() { final TestResult result = new TestResult("RFC 6902 move operation"); LOGGER.info("Testing RFC 6902 move operation:"); testMoveStringOnSimpleObject(result); testMoveStringOnSimpleArray(result); testMoveStringOnSimpleArray2(result); testMoveIntOnSimpleObject(result); testMoveIntOnSimpleArray(result); testMoveIntOnSimpleArray2(result); testMoveBoolOnSimpleObject(result); testMoveBoolOnSimpleArray(result); testMoveBoolOnSimpleArray2(result); testMoveObjectOnSimpleObject(result); testMoveObjectOnSimpleArray(result); testMoveObjectOnSimpleArray2(result); testMoveStringOnCompoundObject(result); testMoveOfNonExistingLocationInObject(result); testMoveOfNonExistingLocationInArray(result); testMoveVsRemoveAddOnSelfContainedPath(result); return result; } /** * Test RFC 6902 MOVE operation for {@code String} on simple JSON object. * * @param result * Tests result record. */ private void testMoveStringOnSimpleObject(final TestResult result) { LOGGER.info(" - for String on simple JSON object"); final JsonObject in = SimpleValues.createSimpleObjectStr(); final JsonObject check = SimpleValues.createSimpleObjectMoveStr(); simpleOperation(result, in, check, SimpleValues.STR_PATH, SimpleValues.DEF_PATH); } /** * Test RFC 6902 MOVE operation for {@code String} on simple JSON array. * * @param result * Tests result record. */ private void testMoveStringOnSimpleArray(final TestResult result) { LOGGER.info(" - for String on simple JSON array of size 2"); final JsonArray in = SimpleValues.createStringArray2(); final JsonArray check = SimpleValues.createStringArray2R(); simpleOperation(result, in, in, "/0", "/0"); simpleOperation(result, in, check, "/1", "/0"); simpleOperation(result, in, check, "/0", "/1"); simpleOperation(result, in, check, "/0", "/-"); } /** * Test RFC 6902 MOVE operation for {@code String} on simple JSON array. * * @param result * Tests result record. */ private void testMoveStringOnSimpleArray2(final TestResult result) { LOGGER.info(" - for String on simple JSON array of size 5"); final JsonArray in = SimpleValues.createSimpleStringArray5(); final JsonArray check = SimpleValues.createSimpleStringArray5R(); complexOperation(result, in, check, new String[] { "/3", "/0", "/3", "/4" }, new String[] { "/1", "/2", "/1", "/0" }); complexOperation(result, in, check, new String[] { "/0", "/1", "/0", "/2" }, new String[] { "/-", "/2", "/3", "/0" }); } /** * Test RFC 6902 MOVE operation for {@code int} on simple JSON object. * * @param result * Tests result record. */ private void testMoveIntOnSimpleObject(final TestResult result) { LOGGER.info(" - for int on simple JSON object"); final JsonObject in = SimpleValues.createSimpleObjectInt(); final JsonObject check = SimpleValues.createSimpleObjectMoveInt(); simpleOperation(result, in, check, SimpleValues.INT_PATH, SimpleValues.DEF_PATH); } /** * Test RFC 6902 MOVE operation for {@code int} on simple JSON array. * * @param result * Tests result record. */ private void testMoveIntOnSimpleArray(final TestResult result) { LOGGER.info(" - for int on simple JSON array of size 2"); final JsonArray in = SimpleValues.createIntArray2(); final JsonArray check = SimpleValues.createIntArray2R(); simpleOperation(result, in, in, "/0", "/0"); simpleOperation(result, in, check, "/1", "/0"); simpleOperation(result, in, check, "/0", "/1"); simpleOperation(result, in, check, "/0", "/-"); } /** * Test RFC 6902 MOVE operation for {@code int} on simple JSON array. * * @param result * Tests result record. */ private void testMoveIntOnSimpleArray2(final TestResult result) { LOGGER.info(" - for int on simple JSON array of size 5"); final JsonArray in = SimpleValues.createSimpleIntArray5(); final JsonArray check = SimpleValues.createSimpleIntArray5R(); complexOperation(result, in, check, new String[] { "/3", "/0", "/3", "/4" }, new String[] { "/1", "/2", "/1", "/0" }); complexOperation(result, in, check, new String[] { "/0", "/1", "/0", "/2" }, new String[] { "/-", "/2", "/3", "/0" }); } /** * Test RFC 6902 MOVE operation for {@code boolean} on simple JSON object. * * @param result * Tests result record. */ private void testMoveBoolOnSimpleObject(final TestResult result) { LOGGER.info(" - for boolean on simple JSON object"); final JsonObject in = SimpleValues.createSimpleObjectBool(); final JsonObject check = SimpleValues.createSimpleObjectMoveBool(); simpleOperation(result, in, check, SimpleValues.BOOL_PATH, SimpleValues.DEF_PATH); } /** * Test RFC 6902 MOVE operation for {@code boolean} on simple JSON array. * * @param result * Tests result record. */ private void testMoveBoolOnSimpleArray(final TestResult result) { LOGGER.info(" - for boolean on simple JSON array of size 2"); final JsonArray in = SimpleValues.createBoolArray2(); final JsonArray check = SimpleValues.createBoolArray2R(); simpleOperation(result, in, in, "/0", "/0"); simpleOperation(result, in, check, "/1", "/0"); simpleOperation(result, in, check, "/0", "/1"); simpleOperation(result, in, check, "/0", "/-"); } /** * Test RFC 6902 MOVE operation for {@code boolean} on simple JSON array. * * @param result * Tests result record. */ private void testMoveBoolOnSimpleArray2(final TestResult result) { LOGGER.info(" - for boolean on simple JSON array of size 5"); final JsonArray in = SimpleValues.createSimpleBoolArray5(); final JsonArray check = SimpleValues.createSimpleBoolArray5R(); complexOperation(result, in, check, new String[] { "/3", "/0", "/3", "/4" }, new String[] { "/1", "/2", "/1", "/0" }); complexOperation(result, in, check, new String[] { "/0", "/1", "/0", "/2" }, new String[] { "/-", "/2", "/3", "/0" }); } /** * Test RFC 6902 MOVE operation for {@code JsonObject} on simple JSON object. * * @param result * Tests result record. */ private void testMoveObjectOnSimpleObject(final TestResult result) { LOGGER.info(" - for JsonObject on simple JSON object"); final JsonObject in = SimpleValues.createSimpleObjectObject(); final JsonObject check = SimpleValues.createSimpleObjectMoveObject(); simpleOperation(result, in, check, SimpleValues.OBJ_PATH, SimpleValues.DEF_PATH); } /** * Test RFC 6902 MOVE operation for {@code JsonObject} on simple JSON array. * * @param result * Tests result record. */ private void testMoveObjectOnSimpleArray(final TestResult result) { LOGGER.info(" - for JsonObject on simple JSON array of size 2"); final JsonArray in = SimpleValues.createObjectArray2(); final JsonArray check = SimpleValues.createObjectArray2R(); simpleOperation(result, in, in, "/0", "/0"); simpleOperation(result, in, check, "/1", "/0"); simpleOperation(result, in, check, "/0", "/1"); simpleOperation(result, in, check, "/0", "/-"); } /** * Test RFC 6902 MOVE operation for {@code JsonObject} on simple JSON array. * * @param result * Tests result record. */ private void testMoveObjectOnSimpleArray2(final TestResult result) { LOGGER.info(" - for JsonObject on simple JSON array of size 5"); final JsonArray in = SimpleValues.createSimpleObjectArray5(); final JsonArray check = SimpleValues.createSimpleObjectArray5R(); complexOperation(result, in, check, new String[] { "/3", "/0", "/3", "/4" }, new String[] { "/1", "/2", "/1", "/0" }); complexOperation(result, in, check, new String[] { "/0", "/1", "/0", "/2" }, new String[] { "/-", "/2", "/3", "/0" }); } /** * Test RFC 6902 MOVE operation for {@code String} on compound JSON object. * Moved value overwrites an existing value. * * @param result * Tests result record. */ private void testMoveStringOnCompoundObject(final TestResult result) { LOGGER.info(" - for String on compound JSON object"); final JsonObject in = SimpleValues.createCompoundObject(); final JsonObject check = SimpleValues.createCompoundObjectMoveValue(); simpleOperation(result, in, check, SimpleValues.DEF_PATH, SimpleValues.DEF_OBJ_PATH + SimpleValues.DEF_PATH); } // Tests based on RFC 6902 definitions and examples. /** * Test RFC 6902 MOVE operation for non existing location in object. * {@see RFC 6902: * 4.4. move} defines:
* The "from" location MUST exist for the operation to be successful. */ private void testMoveOfNonExistingLocationInObject(final TestResult result) { LOGGER.info(" - for non existing location in JsonObject"); final JsonObject[] objsIn = new JsonObject[] { SimpleValues.createEmptyObject(), SimpleValues.createSimpleObject(), SimpleValues.createCompoundObject() }; final String[] paths = new String[] { SimpleValues.STR_PATH, SimpleValues.INT_PATH, SimpleValues.BOOL_PATH, SimpleValues.OBJ_PATH }; final Object[] values = new Object[] { SimpleValues.OBJ_PATH, SimpleValues.BOOL_PATH, SimpleValues.INT_PATH, SimpleValues.STR_PATH }; // Go trough all objects for (int i = 0; i < objsIn.length; i++) { // Go trough all paths for (int j = 0; j < paths.length; j++) { simpleOperationFail(result, objsIn[i], paths[j], values[i]); } } } /** * Test RFC 6902 MOVE operation for non existing location in array. * {@see RFC 6902: * 4.4. move} defines:
* The "from" location MUST exist for the operation to be successful. */ private void testMoveOfNonExistingLocationInArray(final TestResult result) { LOGGER.info(" - for non existing location in JsonArray"); final JsonArray[] arraysIn = new JsonArray[] { SimpleValues.createEmptyArray(), SimpleValues.createStringArray1(), SimpleValues.createIntArray2(), SimpleValues.createSimpleBoolArray5(), SimpleValues.createObjectArray2() }; final String[] paths = new String[] { "/", "/-1", "/-", "/5", "/0a", "/42", SimpleValues.STR_PATH + "/0" }; final Object[] values = new Object[] { "/0", "/1", "/2", "/5", "/1" }; // Go trough all arrays for (int i = 0; i < arraysIn.length; i++) { // Go trough all paths for (int j = 0; j < paths.length; j++) { simpleOperationFail(result, arraysIn[i], paths[j], values[i]); } } } /** * Test RFC 6902 MOVE operation for moving existing path into path containing * source path as a prefix. * {@see RFC 6902: * 4.4. move} defines:
* This operation is functionally identical to a "remove" operation on the * "from" location, followed immediately by an "add" operation at the target * location with the value that was just removed. * {@see RFC 6901: 7. * Error Handling} defines:
* This specification does not define how errors are handled. An application * of JSON Pointer SHOULD specify the impact and handling of each type of * error.
* For example, some applications might stop pointer processing upon an error, * while others may attempt to recover from missing values by inserting * default ones.
* This means, that such an operation may fail on non existing target "path" * after ADD operation, but also missing pointer error recovery may take care * of creating missing "path" elements. In both cases MOVE and sequence of * REMOVE and ADD operations MUST produce the same result. */ private void testMoveVsRemoveAddOnSelfContainedPath(final TestResult result) { LOGGER.info(" - for moving JsonObject under itself"); final JsonObject in = SimpleValues.createCompoundObject(); final String targetPath = SimpleValues.DEF_OBJ_PATH + SimpleValues.DEF_PATH; final JsonPointer ptr = Json.createPointer(SimpleValues.DEF_OBJ_PATH); final JsonValue value = ptr.getValue(in); final JsonPatchBuilder moveBuilder = Json.createPatchBuilder() .move(targetPath, SimpleValues.DEF_OBJ_PATH); final JsonPatchBuilder remAddBuilder = Json.createPatchBuilder() .remove(SimpleValues.DEF_OBJ_PATH).add(targetPath, value); final JsonPatch movePatch = moveBuilder.build(); final JsonPatch remAddPatch = remAddBuilder.build(); // Check REMOVE and ADD sequence first. JsonObject remAddOut; try { remAddOut = remAddPatch.apply(in); LOGGER.info(" REMOVE and ADD passed"); } catch (JsonException e) { remAddOut = null; LOGGER.info(" REMOVE and ADD failed: " + e.getMessage()); } // Check MOVE second JsonObject moveOut; try { moveOut = movePatch.apply(in); LOGGER.info(" MOVE passed"); } catch (JsonException e) { moveOut = null; LOGGER.info(" MOVE failed: " + e.getMessage()); } // Results evaluation if (remAddOut != null) { // Both output values are not null: Compare them if (moveOut != null) { if (!JsonAssert.assertEquals(remAddOut, moveOut)) { result.fail("MOVE vs REMOVE and ADD", "Returned values are not equal"); } // REMOVE and ADD output is not null but MOVE output is null } else { result.fail("MOVE vs REMOVE and ADD", "REMOVE and ADD failed but MOVE dit not"); } } else { // REMOVE and ADD output is null but MOVE output is not null if (moveOut != null) { result.fail("MOVE vs REMOVE and ADD", "MOVE failed but REMOVE and ADD dit not"); } // else: Both output values are null: both patch operations failed -> test // passed } } /** * Tested operation name {@code "MOVE"}. * * @return Operation name to be used in logs. */ @Override protected String operationName() { return OPERATION; } /** * Create and initialize patch builder to contain MOVE operation to be * applied. * * @param path * Source JSON path of MOVE operation. * @param value * Target JSON path of MOVE operation. Must be instance of * {@link String}. * @return Patch builder containing operation to be applied. */ @Override protected JsonPatchBuilder createOperationBuilder(final String path, final Object value) { if (value instanceof String) { // LOGGER.info(" MOVE "+path+" -> "+(String)value); return Json.createPatchBuilder().move((String) value, path); } else { throw new IllegalArgumentException( "Argument \"value\" is not an instance of String"); } } /** * Update patch builder to contain next MOVE operation to be applied. * * @param builder * JSON patch builder to update. * @param path * Source JSON path of MOVE operation. * @param value * Target JSON path of MOVE operation. Must be instance of * {@link String}. * @return Patch builder containing operation to be applied. */ @Override protected JsonPatchBuilder updateOperationBuilder( final JsonPatchBuilder builder, final String path, final Object value) { if (value instanceof String) { // LOGGER.info(" MOVE "+path+" -> "+(String)value); return builder.move((String) value, path); } else { throw new IllegalArgumentException( "Argument \"value\" is not an instance of String"); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy