test(serde-ext): Add a test for mutable structured entry serde
This commit is contained in:
+27
-2
@@ -3,16 +3,23 @@ package de.siphalor.tweed5.serde.extension.impl;
|
|||||||
import de.siphalor.tweed5.core.api.container.ConfigContainer;
|
import de.siphalor.tweed5.core.api.container.ConfigContainer;
|
||||||
import de.siphalor.tweed5.core.api.entry.CollectionConfigEntry;
|
import de.siphalor.tweed5.core.api.entry.CollectionConfigEntry;
|
||||||
import de.siphalor.tweed5.core.api.entry.CompoundConfigEntry;
|
import de.siphalor.tweed5.core.api.entry.CompoundConfigEntry;
|
||||||
|
import de.siphalor.tweed5.core.api.entry.ConfigEntry;
|
||||||
|
import de.siphalor.tweed5.core.api.entry.ConfigEntryValueVisitor;
|
||||||
|
import de.siphalor.tweed5.core.api.entry.ConfigEntryVisitor;
|
||||||
|
import de.siphalor.tweed5.core.api.entry.MutableStructuredConfigEntry;
|
||||||
import de.siphalor.tweed5.core.api.entry.SimpleConfigEntry;
|
import de.siphalor.tweed5.core.api.entry.SimpleConfigEntry;
|
||||||
import de.siphalor.tweed5.core.impl.DefaultConfigContainer;
|
import de.siphalor.tweed5.core.impl.DefaultConfigContainer;
|
||||||
import de.siphalor.tweed5.core.impl.entry.CollectionConfigEntryImpl;
|
import de.siphalor.tweed5.core.impl.entry.CollectionConfigEntryImpl;
|
||||||
import de.siphalor.tweed5.core.impl.entry.SimpleConfigEntryImpl;
|
import de.siphalor.tweed5.core.impl.entry.SimpleConfigEntryImpl;
|
||||||
import de.siphalor.tweed5.core.impl.entry.StaticMapCompoundConfigEntryImpl;
|
import de.siphalor.tweed5.core.impl.entry.StaticMapCompoundConfigEntryImpl;
|
||||||
|
import de.siphalor.tweed5.patchwork.api.Patchwork;
|
||||||
import de.siphalor.tweed5.serde.extension.api.ReadWriteExtension;
|
import de.siphalor.tweed5.serde.extension.api.ReadWriteExtension;
|
||||||
import de.siphalor.tweed5.serde.hjson.HjsonLexer;
|
import de.siphalor.tweed5.serde.hjson.HjsonLexer;
|
||||||
import de.siphalor.tweed5.serde.hjson.HjsonReader;
|
import de.siphalor.tweed5.serde.hjson.HjsonReader;
|
||||||
import de.siphalor.tweed5.serde.hjson.HjsonWriter;
|
import de.siphalor.tweed5.serde.hjson.HjsonWriter;
|
||||||
import de.siphalor.tweed5.serde_api.api.TweedDataVisitor;
|
import de.siphalor.tweed5.serde_api.api.TweedDataVisitor;
|
||||||
|
import org.jspecify.annotations.NonNull;
|
||||||
|
import org.jspecify.annotations.Nullable;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
@@ -51,13 +58,21 @@ class ReadWriteExtensionImplTest {
|
|||||||
.apply(entryReaderWriter(booleanReaderWriter()))
|
.apply(entryReaderWriter(booleanReaderWriter()))
|
||||||
).apply(entryReaderWriter(collectionReaderWriter()));
|
).apply(entryReaderWriter(collectionReaderWriter()));
|
||||||
|
|
||||||
|
MutableStructuredConfigEntry<Map<String, Integer>> mapEntry = new TestMapConfigEntry<>(
|
||||||
|
configContainer,
|
||||||
|
(Class<Map<String, Integer>>)(Class) Map.class,
|
||||||
|
new SimpleConfigEntryImpl<>(configContainer, Integer.class)
|
||||||
|
.apply(entryReaderWriter(intReaderWriter()))
|
||||||
|
).apply(entryReaderWriter(mutableStructuredReaderWriter()));
|
||||||
|
|
||||||
rootEntry = new StaticMapCompoundConfigEntryImpl<>(
|
rootEntry = new StaticMapCompoundConfigEntryImpl<>(
|
||||||
configContainer,
|
configContainer,
|
||||||
((Class<Map<String, Object>>) (Class<?>) Map.class),
|
((Class<Map<String, Object>>) (Class<?>) Map.class),
|
||||||
LinkedHashMap::new,
|
LinkedHashMap::new,
|
||||||
sequencedMap(List.of(
|
sequencedMap(List.of(
|
||||||
entry("int", intEntry),
|
entry("int", intEntry),
|
||||||
entry("list", listEntry)
|
entry("list", listEntry),
|
||||||
|
entry("map", mapEntry)
|
||||||
))
|
))
|
||||||
).apply(entryReaderWriter(compoundReaderWriter()));
|
).apply(entryReaderWriter(compoundReaderWriter()));
|
||||||
|
|
||||||
@@ -71,6 +86,7 @@ class ReadWriteExtensionImplTest {
|
|||||||
Map<String, Object> value = new HashMap<>();
|
Map<String, Object> value = new HashMap<>();
|
||||||
value.put("int", 123);
|
value.put("int", 123);
|
||||||
value.put("list", Arrays.asList(true, false, true));
|
value.put("list", Arrays.asList(true, false, true));
|
||||||
|
value.put("map", sequencedMap(List.of(entry("a", 1), entry("b", 2))));
|
||||||
|
|
||||||
ReadWriteExtension readWriteExtension = configContainer.extension(ReadWriteExtension.class).orElseThrow();
|
ReadWriteExtension readWriteExtension = configContainer.extension(ReadWriteExtension.class).orElseThrow();
|
||||||
assertDoesNotThrow(() -> readWriteExtension.write(
|
assertDoesNotThrow(() -> readWriteExtension.write(
|
||||||
@@ -88,6 +104,10 @@ class ReadWriteExtensionImplTest {
|
|||||||
\t\tfalse
|
\t\tfalse
|
||||||
\t\ttrue
|
\t\ttrue
|
||||||
\t]
|
\t]
|
||||||
|
\tmap: {
|
||||||
|
\t\ta: 1
|
||||||
|
\t\tb: 2
|
||||||
|
\t}
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
);
|
);
|
||||||
@@ -105,6 +125,10 @@ class ReadWriteExtensionImplTest {
|
|||||||
\t\tfalse
|
\t\tfalse
|
||||||
\t\ttrue
|
\t\ttrue
|
||||||
\t]
|
\t]
|
||||||
|
\tmap: {
|
||||||
|
\t\ta: 1
|
||||||
|
\t\tb: 2
|
||||||
|
\t}
|
||||||
}
|
}
|
||||||
"""))),
|
"""))),
|
||||||
rootEntry,
|
rootEntry,
|
||||||
@@ -115,7 +139,8 @@ class ReadWriteExtensionImplTest {
|
|||||||
assertThat(result.hasValue()).isTrue();
|
assertThat(result.hasValue()).isTrue();
|
||||||
assertThat(result.value()).isEqualTo(Map.of(
|
assertThat(result.value()).isEqualTo(Map.of(
|
||||||
"int", 123,
|
"int", 123,
|
||||||
"list", Arrays.asList(true, false, true)
|
"list", Arrays.asList(true, false, true),
|
||||||
|
"map", Map.of("a", 1, "b", 2)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+87
@@ -0,0 +1,87 @@
|
|||||||
|
package de.siphalor.tweed5.serde.extension.impl;
|
||||||
|
|
||||||
|
import de.siphalor.tweed5.core.api.Arity;
|
||||||
|
import de.siphalor.tweed5.core.api.container.ConfigContainer;
|
||||||
|
import de.siphalor.tweed5.core.api.entry.BaseConfigEntry;
|
||||||
|
import de.siphalor.tweed5.core.api.entry.ConfigEntry;
|
||||||
|
import de.siphalor.tweed5.core.api.entry.ConfigEntryValueVisitor;
|
||||||
|
import de.siphalor.tweed5.core.api.entry.ConfigEntryVisitor;
|
||||||
|
import de.siphalor.tweed5.core.api.entry.MutableStructuredConfigEntry;
|
||||||
|
import de.siphalor.tweed5.core.api.entry.SubEntryKey;
|
||||||
|
import org.jspecify.annotations.NonNull;
|
||||||
|
import org.jspecify.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class TestMapConfigEntry<V>
|
||||||
|
extends BaseConfigEntry<Map<String, V>>
|
||||||
|
implements MutableStructuredConfigEntry<Map<String, V>> {
|
||||||
|
private final ConfigEntry<V> valueEntry;
|
||||||
|
|
||||||
|
public TestMapConfigEntry(
|
||||||
|
ConfigContainer<?> container,
|
||||||
|
Class<Map<String, V>> valueClass,
|
||||||
|
ConfigEntry<V> valueEntry
|
||||||
|
) {
|
||||||
|
super(container, valueClass);
|
||||||
|
this.valueEntry = valueEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NonNull Map<String, V> instantiateValue() {
|
||||||
|
return new LinkedHashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void set(Map<String, V> value, String dataKey, Object subValue) {
|
||||||
|
value.put(dataKey, (V) subValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable ConfigEntry<?> getEntry(String dataKey) {
|
||||||
|
return valueEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object get(Map<String, V> value, String dataKey) {
|
||||||
|
return value.get(dataKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, ConfigEntry<?>> subEntries() {
|
||||||
|
return Map.of(":value", valueEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitInOrder(ConfigEntryVisitor visitor) {
|
||||||
|
if (visitor.enterStructuredEntry(this)) {
|
||||||
|
if (visitor.enterStructuredSubEntry(":value", Arity.ANY)) {
|
||||||
|
valueEntry.visitInOrder(visitor);
|
||||||
|
visitor.leaveStructuredSubEntry(":value", Arity.ANY);
|
||||||
|
}
|
||||||
|
visitor.leaveStructuredEntry(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitInOrder(ConfigEntryValueVisitor visitor, Map<String, V> value) {
|
||||||
|
if (visitor.enterStructuredEntry(this, value)) {
|
||||||
|
value.forEach((key, subValue) -> {
|
||||||
|
SubEntryKey subEntryKey = SubEntryKey.addressable(":value", key, key);
|
||||||
|
if (visitor.enterSubEntry(subEntryKey)) {
|
||||||
|
valueEntry.visitInOrder(visitor, subValue);
|
||||||
|
visitor.leaveSubEntry(subEntryKey);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
visitor.leaveStructuredEntry(this, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, V> deepCopy(Map<String, V> value) {
|
||||||
|
Map<String, V> copy = instantiateValue();
|
||||||
|
value.forEach((key, subValue) -> copy.put(key, valueEntry.deepCopy(subValue)));
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user