<commit_before>/*
 * 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.apache.johnzon.core;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

import java.io.StringReader;

import javax.json.Json;
import javax.json.JsonArray;
import javax.json.JsonObject;
import javax.json.JsonPatch;
import javax.json.JsonValue;

import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;

public class JsonPatchDiffTest {

    @Test
    public void testAddDiff() {
        // {"a":"xa"}
        String jsonA = "{\"a\":\"xa\"}";

        // {"a":"xa","b":"xb"}
        String jsonB = "{\"a\":\"xa\",\"b\":\"xb\"}";

        // this results in 1 diff operations:
        // adding "b"
        JsonPatch jsonPatch = Json.createDiff(Json.createReader(new StringReader(jsonA)).readObject(),
                Json.createReader(new StringReader(jsonB)).readObject());
        assertNotNull(jsonPatch);
        JsonArray patchOperations = jsonPatch.toJsonArray();
        assertNotNull(patchOperations);
        assertEquals(1, patchOperations.size());
        containsOperation(patchOperations, JsonPatch.Operation.ADD, "/b", Json.createValue("xb"));
    }

    @Test
    public void testAddDiffNewObject() {

        JsonObject target = Json.createObjectBuilder()
                .add("a", Json.createObjectBuilder()
                        .add("aa", "value")
                        .add("ab", "another"))
                .build();

        JsonPatch patch = Json.createDiff(JsonValue.EMPTY_JSON_OBJECT, target);
        assertNotNull(patch);

        JsonArray operations = patch.toJsonArray();
        assertEquals(1, operations.size());

        containsOperation(operations, JsonPatch.Operation.ADD, "/a", target.get("a"));

        // now try to apply that patch.
        JsonObject patched = patch.apply(JsonValue.EMPTY_JSON_OBJECT);
        Assert.assertEquals(target, patched);
    }

    @Test
    public void testAddDiffNewObjectWithEscaping() {

        JsonObject target = Json.createObjectBuilder()
                .add("a~/", Json.createObjectBuilder()
                        .add("esc/aped", "value")
                        .add("tilde", "another"))
                .build();

        JsonPatch patch = Json.createDiff(JsonValue.EMPTY_JSON_OBJECT, target);
        assertNotNull(patch);

        JsonArray operations = patch.toJsonArray();
        assertEquals(1, operations.size());

        containsOperation(operations, JsonPatch.Operation.ADD, "/a~0~1", target.get("a"));

        // now try to apply that patch.
        JsonObject patched = patch.apply(JsonValue.EMPTY_JSON_OBJECT);
        Assert.assertEquals(target, patched);
    }

    @Test
    public void testAddDiffInNestedObject() {

        JsonObject source = Json.createObjectBuilder()
                .add("a", Json.createObjectBuilder()
                        .add("aa", "value"))
                .build();

        JsonObject target = Json.createObjectBuilder()
                .add("a", Json.createObjectBuilder()
                        .add("aa", "value")
                        .add("bb", "another value"))
                .build();

        JsonPatch patch = Json.createDiff(source, target);
        assertNotNull(patch);

        JsonArray operations = patch.toJsonArray();
        assertEquals(1, operations.size());

        containsOperation(operations, JsonPatch.Operation.ADD, "/a/bb", Json.createValue("another value"));
    }

    @Test
    public void testRemoveDiffObject() {

        JsonObject source = Json.createObjectBuilder()
                .add("a", "value")
                .build();

        JsonPatch patch = Json.createDiff(source, JsonValue.EMPTY_JSON_OBJECT);
        assertNotNull(patch);

        JsonArray operations = patch.toJsonArray();
        assertEquals(1, operations.size());

        containsOperation(operations, JsonPatch.Operation.REMOVE, "/a");
    }

    @Test
    public void testRemoveDiffNestedObject() {

        JsonObject source = Json.createObjectBuilder()
                .add("a", "value")
                .add("nested", Json.createObjectBuilder()
                        .add("1", 1)
                        .add("2", 2))
                .build();

        {
            JsonPatch patch = Json.createDiff(source, JsonValue.EMPTY_JSON_OBJECT);
            assertNotNull(patch);

            JsonArray operations = patch.toJsonArray();
            assertEquals(2, operations.size());

            containsOperation(operations, JsonPatch.Operation.REMOVE, "/a");
            containsOperation(operations, JsonPatch.Operation.REMOVE, "/nested");
        }

        {
            JsonObject target = Json.createObjectBuilder()
                    .add("a", "value")
                    .add("nested", Json.createObjectBuilder()
                            .add("1", 1))
                    .build();

            JsonPatch patch = Json.createDiff(source, target);
            assertNotNull(patch);

            JsonArray operations = patch.toJsonArray();
            assertEquals(1, operations.size());

            containsOperation(operations, JsonPatch.Operation.REMOVE, "/nested/2");
        }
    }

    @Test
    public void testDiffEqualObjects() {

        JsonObject source = Json.createObjectBuilder()
                .add("a", "value")
                .build();

        JsonObject target = Json.createObjectBuilder()
                .add("a", "value")
                .build();

        JsonPatch patch = Json.createDiff(source, target);
        assertNotNull(patch);
        assertEquals(0, patch.toJsonArray().size());
    }


    //X TODO arrays...
    //X TODO test add/remove JsonArray
    //X TODO test add object to JsonArray
    //X TODO test remove object to JsonArray



    @Test<commit_msg>JOHNZON-103 added tests for REPLACE<commit_after>/*
 * 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.apache.johnzon.core;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

import java.io.StringReader;

import javax.json.Json;
import javax.json.JsonArray;
import javax.json.JsonObject;
import javax.json.JsonPatch;
import javax.json.JsonValue;

import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;

public class JsonPatchDiffTest {

    @Test
    public void testAddDiff() {
        // {"a":"xa"}
        String jsonA = "{\"a\":\"xa\"}";

        // {"a":"xa","b":"xb"}
        String jsonB = "{\"a\":\"xa\",\"b\":\"xb\"}";

        // this results in 1 diff operations:
        // adding "b"
        JsonPatch jsonPatch = Json.createDiff(Json.createReader(new StringReader(jsonA)).readObject(),
                Json.createReader(new StringReader(jsonB)).readObject());
        assertNotNull(jsonPatch);
        JsonArray patchOperations = jsonPatch.toJsonArray();
        assertNotNull(patchOperations);
        assertEquals(1, patchOperations.size());
        containsOperation(patchOperations, JsonPatch.Operation.ADD, "/b", Json.createValue("xb"));
    }

    @Test
    public void testAddDiffNewObject() {

        JsonObject target = Json.createObjectBuilder()
                .add("a", Json.createObjectBuilder()
                        .add("aa", "value")
                        .add("ab", "another"))
                .build();

        JsonPatch patch = Json.createDiff(JsonValue.EMPTY_JSON_OBJECT, target);
        assertNotNull(patch);

        JsonArray operations = patch.toJsonArray();
        assertEquals(1, operations.size());

        containsOperation(operations, JsonPatch.Operation.ADD, "/a", target.get("a"));

        // now try to apply that patch.
        JsonObject patched = patch.apply(JsonValue.EMPTY_JSON_OBJECT);
        Assert.assertEquals(target, patched);
    }

    @Test
    public void testAddDiffNewObjectWithEscaping() {

        JsonObject target = Json.createObjectBuilder()
                .add("a~/", Json.createObjectBuilder()
                        .add("esc/aped", "value")
                        .add("tilde", "another"))
                .build();

        JsonPatch patch = Json.createDiff(JsonValue.EMPTY_JSON_OBJECT, target);
        assertNotNull(patch);

        JsonArray operations = patch.toJsonArray();
        assertEquals(1, operations.size());

        containsOperation(operations, JsonPatch.Operation.ADD, "/a~0~1", target.get("a"));

        // now try to apply that patch.
        JsonObject patched = patch.apply(JsonValue.EMPTY_JSON_OBJECT);
        Assert.assertEquals(target, patched);
    }

    @Test
    public void testAddDiffInNestedObject() {

        JsonObject source = Json.createObjectBuilder()
                .add("a", Json.createObjectBuilder()
                        .add("aa", "value"))
                .build();

        JsonObject target = Json.createObjectBuilder()
                .add("a", Json.createObjectBuilder()
                        .add("aa", "value")
                        .add("bb", "another value"))
                .build();

        JsonPatch patch = Json.createDiff(source, target);
        assertNotNull(patch);

        JsonArray operations = patch.toJsonArray();
        assertEquals(1, operations.size());

        containsOperation(operations, JsonPatch.Operation.ADD, "/a/bb", Json.createValue("another value"));
    }

    @Test
    public void testRemoveDiffObject() {

        JsonObject source = Json.createObjectBuilder()
                .add("a", "value")
                .build();

        JsonPatch patch = Json.createDiff(source, JsonValue.EMPTY_JSON_OBJECT);
        assertNotNull(patch);

        JsonArray operations = patch.toJsonArray();
        assertEquals(1, operations.size());

        containsOperation(operations, JsonPatch.Operation.REMOVE, "/a");
    }

    @Test
    public void testRemoveDiffNestedObject() {

        JsonObject source = Json.createObjectBuilder()
                .add("a", "value")
                .add("nested", Json.createObjectBuilder()
                        .add("1", 1)
                        .add("2", 2))
                .build();

        {
            JsonPatch patch = Json.createDiff(source, JsonValue.EMPTY_JSON_OBJECT);
            assertNotNull(patch);

            JsonArray operations = patch.toJsonArray();
            assertEquals(2, operations.size());

            containsOperation(operations, JsonPatch.Operation.REMOVE, "/a");
            containsOperation(operations, JsonPatch.Operation.REMOVE, "/nested");
        }

        {
            JsonObject target = Json.createObjectBuilder()
                    .add("a", "value")
                    .add("nested", Json.createObjectBuilder()
                            .add("1", 1))
                    .build();

            JsonPatch patch = Json.createDiff(source, target);
            assertNotNull(patch);

            JsonArray operations = patch.toJsonArray();
            assertEquals(1, operations.size());

            containsOperation(operations, JsonPatch.Operation.REMOVE, "/nested/2");
        }
    }

    @Test
    public void testDiffEqualObjects() {

        JsonObject source = Json.createObjectBuilder()
                .add("a", "value")
                .build();

        JsonObject target = Json.createObjectBuilder()
                .add("a", "value")
                .build();

        JsonPatch patch = Json.createDiff(source, target);
        assertNotNull(patch);
        assertEquals(0, patch.toJsonArray().size());
    }

    @Test
    public void testDiffReplaceObject() {

        JsonObject source = Json.createObjectBuilder()
                .add("a", "value")
                .build();

        JsonObject target = Json.createObjectBuilder()
                .add("a", "replaced")
                .build();

        JsonPatch patch = Json.createDiff(source, target);
        assertNotNull(patch);

        JsonArray operations = patch.toJsonArray();
        assertEquals(1, operations.size());

        containsOperation(operations, JsonPatch.Operation.REPLACE, "/a", Json.createValue("replaced"));
    }

    @Test
    public void testDiffReplaceFromNestedObject() {

        JsonObject source = Json.createObjectBuilder()
                .add("a", Json.createObjectBuilder()
                        .add("aa", "value"))
                .build();

        JsonObject target = Json.createObjectBuilder()
                .add("a", Json.createObjectBuilder()
                        .add("aa", "replaced"))
                .build();

        JsonPatch patch = Json.createDiff(source, target);
        assertNotNull(patch);

        JsonArray operations = patch.toJsonArray();
        assertEquals(1, operations.size());

        containsOperation(operations, JsonPatch.Operation.REPLACE, "/a/aa", Json.createValue("replaced"));
    }

    //X TODO add move support -> see https://issues.apache.org/jira/browse/JOHNZON-105
    @Test
    @Ignore
    public void testDiffMoveValue() {

        JsonObject source = Json.createObjectBuilder()
                .add("a", Json.createObjectBuilder()
                        .add("aa", "valueToMove"))
                .add("b", JsonValue.EMPTY_JSON_OBJECT)
                .build();

        JsonObject target = Json.createObjectBuilder()
                .add("a", JsonValue.EMPTY_JSON_OBJECT)
                .add("b", Json.createObjectBuilder()
                        .add("aa", "valueToMove"))
                .build();

        JsonPatch patch = Json.createDiff(source, target);
        assertNotNull(patch);

        JsonArray operations = patch.toJsonArray();
        assertEquals(1, operations.size());

        JsonObject operation = operations.getJsonObject(0);
        assertEquals(JsonPatch.Operation.MOVE.operationName(), operation.getString("op"));
        assertEquals("/a/aa", operation.getString("from"));
        assertEquals("/b/aa", operation.getString("to"));
    }



    //X TODO arrays...
    //X TODO test add/remove JsonArray
    //X TODO test add object to JsonArray
    //X TODO test remove object to JsonArray



    @Test
{'fraction_non_alphanumeric': 0.12090177133655394, 'fraction_numerical': 0.0034782608695652175, 'mean_word_length': 2.225176568342335, 'pattern_counts': {'":': 12, '<': 3, '<?xml version=': 0, '>': 4, 'https://': 1, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '535186', 'n_tokens_mistral': 4072, 'n_tokens_neox': 3874, 'n_words': 956}