feat: add new JSON Object method (`deepMerge`)

Report of:
- minimal-json/PR 98

[Thanks to @pbi-qfs]
This commit is contained in:
The-Lum 2024-05-05 20:53:27 +00:00
parent 3dba008497
commit 2c666eb968
2 changed files with 116 additions and 0 deletions

View File

@ -555,6 +555,33 @@ public class JsonObject extends JsonValue implements Iterable<Member> {
return this;
}
/**
* Copies all members of the specified object into this object. When the specified object contains
* members with names that also exist in this object, the existing values in this object will be
* replaced by the corresponding values in the specified object, except for the case that both values
* are JsonObjects themselves, which will trigger another merge of these objects.
*
* @param object the object to deep merge
* @return the object itself, to enable method chaining
*/
public JsonObject deepMerge(JsonObject object) {
if (object == null) {
throw new NullPointerException("object is null");
}
for (Member member : object) {
final String name = member.name;
JsonValue value = member.value;
if (value instanceof JsonObject) {
final JsonValue existingValue = this.get(member.name);
if (existingValue instanceof JsonObject) {
value = ((JsonObject) existingValue).deepMerge((JsonObject) value);
}
}
this.set(name, value);
}
return this;
}
/**
* Returns the value of the member with the specified name in this object. If
* this object contains multiple members with the given name, this method will

View File

@ -0,0 +1,89 @@
package net.sourceforge.plantuml.json;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatNullPointerException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores;
import org.junit.jupiter.api.IndicativeSentencesGeneration;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
@IndicativeSentencesGeneration(separator = ": ", generator = ReplaceUnderscores.class)
class JsonObjectTest {
private JsonObject object;
@BeforeEach
void setUp() {
object = new JsonObject();
}
@Nested
class Merge_Test {
@Test
void merge_fails_With_Null() {
assertThatNullPointerException().isThrownBy(() -> object.merge(null)).withMessage("object is null");
}
@Test
void merge_appends_Members() {
object.add("a", 1).add("b", 1);
object.merge(Json.object().add("c", 2).add("d", 2));
assertThat(object).isEqualTo(Json.object().add("a", 1).add("b", 1).add("c", 2).add("d", 2));
}
@Test
void merge_replaces_Members() {
object.add("a", 1).add("b", 1).add("c", 1);
object.merge(Json.object().add("b", 2).add("d", 2));
assertThat(object).isEqualTo(Json.object().add("a", 1).add("b", 2).add("c", 1).add("d", 2));
}
@Test
void merge_replaces_Members_With_no_deep() {
object.add("a", 1).add("b", Json.object().add("x", 1).add("y", 1)).add("c", Json.object().add("A", 1));
object.merge(Json.object().add("b", Json.object().add("y", 2).add("z", 1)).add("c", 1)
.add("d", Json.object().add("B", 1)));
assertThat(object).isEqualTo(Json.object().add("a", 1).add("b", Json.object().add("y", 2).add("z", 1)).add("c", 1)
.add("d", Json.object().add("B", 1)));
}
}
@Nested
class DeepMerge_Test {
@Test
void deepMerge_fails_With_Null() {
assertThatNullPointerException().isThrownBy(() -> object.deepMerge(null)).withMessage("object is null");
}
@Test
void deepMerge_appends_Members() {
object.add("a", 1).add("b", 1);
object.deepMerge(Json.object().add("c", 2).add("d", 2));
assertThat(object).isEqualTo(Json.object().add("a", 1).add("b", 1).add("c", 2).add("d", 2));
}
@Test
void deepMerge_replaces_Members() {
object.add("a", 1).add("b", 1).add("c", 1);
object.deepMerge(Json.object().add("b", 2).add("d", 2));
assertThat(object).isEqualTo(Json.object().add("a", 1).add("b", 2).add("c", 1).add("d", 2));
}
@Test
void deepMerge_merges_Member_Object() {
object.add("a", 1).add("b", Json.object().add("x", 1).add("y", 1)).add("c", Json.object().add("A", 1));
object.deepMerge(Json.object().add("b", Json.object().add("y", 2).add("z", 1)).add("c", 1)
.add("d", Json.object().add("B", 1)));
assertThat(object).isEqualTo(Json.object().add("a", 1).add("b", Json.object().add("x", 1).add("y", 2).add("z", 1)).add("c", 1)
.add("d", Json.object().add("B", 1)));
}
}
}