diff --git a/src/main/java/in/dragonbra/javasteam/types/KVTextReader.java b/src/main/java/in/dragonbra/javasteam/types/KVTextReader.java index c8ffc499..05e0deaf 100644 --- a/src/main/java/in/dragonbra/javasteam/types/KVTextReader.java +++ b/src/main/java/in/dragonbra/javasteam/types/KVTextReader.java @@ -168,7 +168,6 @@ public String readToken(Passable wasQuoted, Passable wasCondit // " read(); - // convert the output stream as an utf-8 supported string. return sb.toString(); } diff --git a/src/test/java/in/dragonbra/javasteam/types/KeyValueTest.java b/src/test/java/in/dragonbra/javasteam/types/KeyValueTest.java index ad8dfa67..bae763c4 100644 --- a/src/test/java/in/dragonbra/javasteam/types/KeyValueTest.java +++ b/src/test/java/in/dragonbra/javasteam/types/KeyValueTest.java @@ -14,14 +14,13 @@ import java.io.EOFException; import java.io.IOException; import java.net.URL; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.EnumSet; import java.util.UUID; -import static org.junit.jupiter.api.Assertions.*; - /** * @author lngtr * @since 2018-02-26 @@ -37,9 +36,9 @@ public class KeyValueTest extends TestBase { public void keyValueInitializesCorrectly() { KeyValue kv = new KeyValue("name", "value"); - assertEquals("name", kv.getName()); - assertEquals("value", kv.getValue()); - assertTrue(kv.getChildren().isEmpty()); + Assertions.assertEquals("name", kv.getName()); + Assertions.assertEquals("value", kv.getValue()); + Assertions.assertTrue(kv.getChildren().isEmpty()); } @Test @@ -48,8 +47,8 @@ public void keyValueIndexerReturnsValidAndInvalid() { kv.getChildren().add(new KeyValue("exists", "value")); - assertEquals("value", kv.get("exists").getValue()); - assertEquals(KeyValue.INVALID, kv.get("thiskeydoesntexist")); + Assertions.assertEquals("value", kv.get("exists").getValue()); + Assertions.assertEquals(KeyValue.INVALID, kv.get("thiskeydoesntexist")); } @Test @@ -58,15 +57,15 @@ public void keyValueIndexerDoesntallowDuplicates() { kv.set("key", new KeyValue()); - assertEquals(1, kv.getChildren().size()); + Assertions.assertEquals(1, kv.getChildren().size()); kv.set("key", new KeyValue()); - assertEquals(1, kv.getChildren().size()); + Assertions.assertEquals(1, kv.getChildren().size()); kv.set("key2", new KeyValue()); - assertEquals(2, kv.getChildren().size()); + Assertions.assertEquals(2, kv.getChildren().size()); } @Test @@ -75,12 +74,12 @@ public void keyValueIndexerUpdatesKey() { KeyValue subkey = new KeyValue(); - assertNull(subkey.getName()); + Assertions.assertNull(subkey.getName()); kv.set("subkey", subkey); - assertEquals("subkey", subkey.getName()); - assertEquals("subkey", kv.get("subkey").getName()); + Assertions.assertEquals("subkey", subkey.getName()); + Assertions.assertEquals("subkey", kv.get("subkey").getName()); } @Test @@ -95,26 +94,26 @@ public void keyValueLoadsFromString() { " }" + "}"); - assertEquals("root", kv.getName()); - assertNull(kv.getValue()); + Assertions.assertEquals("root", kv.getName()); + Assertions.assertNull(kv.getValue()); - assertEquals("name", kv.get("name").getName()); - assertEquals("value", kv.get("name").getValue()); - assertEquals(0, kv.get("name").getChildren().size()); + Assertions.assertEquals("name", kv.get("name").getName()); + Assertions.assertEquals("value", kv.get("name").getValue()); + Assertions.assertEquals(0, kv.get("name").getChildren().size()); KeyValue subKey = kv.get("subkey"); - assertEquals(1, subKey.getChildren().size()); + Assertions.assertEquals(1, subKey.getChildren().size()); - assertEquals("name2", subKey.get("name2").getName()); - assertEquals("value2", subKey.get("name2").getValue()); - assertEquals(0, subKey.get("name2").getChildren().size()); + Assertions.assertEquals("name2", subKey.get("name2").getName()); + Assertions.assertEquals("value2", subKey.get("name2").getValue()); + Assertions.assertEquals(0, subKey.get("name2").getChildren().size()); } @Test public void keyValuesMissingKeysGiveInvalid() { KeyValue kv = new KeyValue(); - assertSame(KeyValue.INVALID, kv.get("missingkey")); + Assertions.assertSame(KeyValue.INVALID, kv.get("missingkey")); } @Test @@ -125,9 +124,9 @@ public void keyValuesKeysAreCaseInsensitive() { " \"name\" \"value\"" + "}"); - assertEquals("value", kv.get("name").getValue()); - assertEquals("value", kv.get("NAME").getValue()); - assertEquals("value", kv.get("NAme").getValue()); + Assertions.assertEquals("value", kv.get("name").getValue()); + Assertions.assertEquals("value", kv.get("NAME").getValue()); + Assertions.assertEquals("value", kv.get("NAme").getValue()); } @Test @@ -138,16 +137,16 @@ public void keyValuesHandlesBool() { " \"name\" \"1\"" + "}"); - assertTrue(kv.get("name").asBoolean()); + Assertions.assertTrue(kv.get("name").asBoolean()); kv.get("name").setValue("0"); - assertFalse(kv.get("name").asBoolean()); + Assertions.assertFalse(kv.get("name").asBoolean()); kv.get("name").setValue("1000"); - assertTrue(kv.get("name").asBoolean(), "values other than 0 are truthy"); + Assertions.assertTrue(kv.get("name").asBoolean(), "values other than 0 are truthy"); kv.get("name").setValue("inavlidbool"); - assertFalse(kv.get("name").asBoolean(), "values that cannot be converted to integers are falsey"); + Assertions.assertFalse(kv.get("name").asBoolean(), "values that cannot be converted to integers are falsey"); } @Test @@ -158,11 +157,11 @@ public void keyValuesHandlesFloat() { " \"name\" \"123.456\"" + "}"); - assertEquals(123.456f, kv.get("name").asFloat(), 0.0f); + Assertions.assertEquals(123.456f, kv.get("name").asFloat(), 0.0f); kv.get("name").setValue("invalidfloat"); - assertEquals(654.321f, kv.get("name").asFloat(654.321f), 0.0f); + Assertions.assertEquals(654.321f, kv.get("name").asFloat(654.321f), 0.0f); } @Test @@ -173,11 +172,11 @@ public void keyValuesHandlesInteger() { " \"name\" \"123\"" + "}"); - assertEquals(123, kv.get("name").asInteger()); + Assertions.assertEquals(123, kv.get("name").asInteger()); kv.get("name").setValue("invalidint"); - assertEquals(321, kv.get("name").asInteger(321)); + Assertions.assertEquals(321, kv.get("name").asInteger(321)); } @Test @@ -188,11 +187,11 @@ public void keyValuesHandlesLong() { " \"name\" \"-5001050759734897745\"" + "}"); - assertEquals(-5001050759734897745L, kv.get("name").asLong()); + Assertions.assertEquals(-5001050759734897745L, kv.get("name").asLong()); kv.get("name").setValue("invalidint"); - assertEquals(678L, kv.get("name").asLong(678L)); + Assertions.assertEquals(678L, kv.get("name").asLong(678L)); } @Test @@ -203,8 +202,8 @@ public void keyValuesHandlesString() { " \"name\" \"stringvalue\"" + "}"); - assertEquals("stringvalue", kv.get("name").asString()); - assertEquals("stringvalue", kv.get("name").getValue()); + Assertions.assertEquals("stringvalue", kv.get("name").asString()); + Assertions.assertEquals("stringvalue", kv.get("name").getValue()); } @Test @@ -226,7 +225,7 @@ public void keyValuesWritesBinaryToFile() throws IOException { byte[] binaryValue = Files.readAllBytes(Paths.get(tempFile.toFile().getPath())); String hexValue = Hex.encodeHexString(binaryValue, false).replaceAll("-", ""); - assertEquals(expectedHexValue, hexValue); + Assertions.assertEquals(expectedHexValue, hexValue); } @Test @@ -246,9 +245,9 @@ public void keyValuesWritesBinaryToStream() { String hexValue = Hex.encodeHexString(ms.toByteArray(), false).replaceAll("-", ""); - assertEquals(expectedHexValue, hexValue); + Assertions.assertEquals(expectedHexValue, hexValue); } catch (Exception e) { - fail(e.getMessage()); + Assertions.fail(e); } } @@ -265,17 +264,17 @@ public void keyValueBinarySerializationIsSymmetric() throws IOException { ms.seek(0, SeekOrigin.BEGIN); loaded = deserializedKv.tryReadAsBinary(ms); - assertTrue(loaded); + Assertions.assertTrue(loaded); - assertEquals(kv.getName(), deserializedKv.getName()); - assertEquals(kv.getChildren().size(), deserializedKv.getChildren().size()); + Assertions.assertEquals(kv.getName(), deserializedKv.getName()); + Assertions.assertEquals(kv.getChildren().size(), deserializedKv.getChildren().size()); for (int i = 0; i < kv.getChildren().size(); i++) { KeyValue originalChild = kv.getChildren().get(i); KeyValue deserializedChild = deserializedKv.getChildren().get(i); - assertEquals(originalChild.getName(), deserializedChild.getName()); - assertEquals(originalChild.getValue(), deserializedChild.getValue()); + Assertions.assertEquals(originalChild.getName(), deserializedChild.getName()); + Assertions.assertEquals(originalChild.getValue(), deserializedChild.getValue()); } } @@ -287,13 +286,13 @@ public void keyValues_TryReadAsBinary_ReadsBinary() throws IOException, DecoderE MemoryStream ms = new MemoryStream(binary); success = kv.tryReadAsBinary(ms); - assertEquals(ms.getLength(), ms.getPosition()); + Assertions.assertEquals(ms.getLength(), ms.getPosition()); - assertTrue(success, "Should have read test object."); - assertEquals("TestObject", kv.getName()); - assertEquals(1, kv.getChildren().size()); - assertEquals("key", kv.getChildren().get(0).getName()); - assertEquals("value", kv.getChildren().get(0).getValue()); + Assertions.assertTrue(success, "Should have read test object."); + Assertions.assertEquals("TestObject", kv.getName()); + Assertions.assertEquals(1, kv.getChildren().size()); + Assertions.assertEquals("key", kv.getChildren().get(0).getName()); + Assertions.assertEquals("value", kv.getChildren().get(0).getValue()); } @Test @@ -304,14 +303,14 @@ public void keyValuesReadsBinaryWithLeftoverData() throws IOException, DecoderEx MemoryStream ms = new MemoryStream(binary); success = kv.tryReadAsBinary(ms); - assertEquals(TEST_OBJECT_HEX.length() / 2, ms.getPosition()); - assertEquals(16, ms.getLength() - ms.getPosition()); - - assertTrue(success, "Should have read test object."); - assertEquals("TestObject", kv.getName()); - assertEquals(1, kv.getChildren().size()); - assertEquals("key", kv.getChildren().get(0).getName()); - assertEquals("value", kv.getChildren().get(0).getValue()); + Assertions.assertEquals(TEST_OBJECT_HEX.length() / 2, ms.getPosition()); + Assertions.assertEquals(16, ms.getLength() - ms.getPosition()); + + Assertions.assertTrue(success, "Should have read test object."); + Assertions.assertEquals("TestObject", kv.getName()); + Assertions.assertEquals(1, kv.getChildren().size()); + Assertions.assertEquals("key", kv.getChildren().get(0).getName()); + Assertions.assertEquals("value", kv.getChildren().get(0).getValue()); } @Test @@ -325,12 +324,12 @@ public void keyValuesFailsToReadTruncatedBinary() throws IOException, DecoderExc MemoryStream ms = new MemoryStream(binary); try { success = kv.tryReadAsBinary(ms); - fail(); + Assertions.fail(); } catch (EOFException ignored) { } - assertEquals(ms.getLength(), ms.getPosition()); + Assertions.assertEquals(ms.getLength(), ms.getPosition()); - assertFalse(success, "Should not have read test object."); + Assertions.assertFalse(success, "Should not have read test object."); } } @@ -343,14 +342,14 @@ public void keyValuesReadsBinaryWithMultipleChildren() throws IOException, Decod MemoryStream ms = new MemoryStream(binary); success = kv.tryReadAsBinary(ms); - assertTrue(success); + Assertions.assertTrue(success); - assertEquals("TestObject", kv.getName()); - assertEquals(2, kv.getChildren().size()); - assertEquals("key1", kv.getChildren().get(0).getName()); - assertEquals("value1", kv.getChildren().get(0).getValue()); - assertEquals("key2", kv.getChildren().get(1).getName()); - assertEquals("value2", kv.getChildren().get(1).getValue()); + Assertions.assertEquals("TestObject", kv.getName()); + Assertions.assertEquals(2, kv.getChildren().size()); + Assertions.assertEquals("key1", kv.getChildren().get(0).getName()); + Assertions.assertEquals("value1", kv.getChildren().get(0).getValue()); + Assertions.assertEquals("key2", kv.getChildren().get(1).getName()); + Assertions.assertEquals("value2", kv.getChildren().get(1).getValue()); } @Test @@ -370,7 +369,7 @@ public void keyValuesSavesTextToFile() throws IOException { kv.saveToFile(tempFile.toFile(), false); text = new String(Files.readAllBytes(Paths.get(tempFile.toFile().getPath()))); - assertEquals(expected, text); + Assertions.assertEquals(expected, text); } @Test @@ -384,29 +383,89 @@ public void keyValuesSavesTextToStream() { kv.getChildren().add(new KeyValue("key1", "value1")); kv.getChildren().add(kv2); - String text; + String text = saveToText(kv); + Assertions.assertEquals(expected, text); + } - try (MemoryStream ms = new MemoryStream()) { - kv.saveToStream(ms.asOutputStream(), false); - ms.seek(0, SeekOrigin.BEGIN); + @Test + public void canLoadUnicodeTextDocument() { + String expected = "\"RootNode\"\n{\n\t\"key1\"\t\t\"value1\"\n\t\"key2\"\n\t{\n\t\t\"ChildKey\"\t\t\"ChildValue\"\n\t}\n}\n"; + KeyValue kv = new KeyValue(); - text = new String(ms.toByteArray()); - assertEquals(expected, text); - } catch (Exception e) { - fail(e.getMessage()); + try { + Path tempFile = Files.createFile(folder.resolve("tempFile.txt")); + + Files.writeString(tempFile, expected, StandardCharsets.UTF_8); + + kv.readFileAsText(tempFile.toString()); + + Assertions.assertEquals("RootNode", kv.getName()); + Assertions.assertEquals(2, kv.getChildren().size()); + Assertions.assertEquals("key1", kv.getChildren().get(0).getName()); + Assertions.assertEquals("value1", kv.getChildren().get(0).getValue()); + Assertions.assertEquals("key2", kv.getChildren().get(1).getName()); + Assertions.assertEquals(1, kv.getChildren().get(1).getChildren().size()); + Assertions.assertEquals("ChildKey", kv.getChildren().get(1).getChildren().get(0).getName()); + Assertions.assertEquals("ChildValue", kv.getChildren().get(1).getChildren().get(0).getValue()); + } catch (IOException e) { + Assertions.fail(e); } } + @Test + public void canLoadUnicodeTextStream() { + var expected = "\"RootNode\"\n{\n\t\"key1\"\t\t\"value1\"\n\t\"key2\"\n\t{\n\t\t\"ChildKey\"\t\t\"ChildValue\"\n\t}\n}\n"; + var kv = new KeyValue(); + + try { + final Path tempFile = Files.createFile(folder.resolve("canLoadUnicodeTextStream.txt")); + + Files.writeString(tempFile, expected, StandardCharsets.UTF_8); + + try (var fs = Files.newInputStream(tempFile)) { + kv.readAsText(fs); + } + + Assertions.assertEquals("RootNode", kv.getName()); + Assertions.assertEquals(2, kv.getChildren().size()); + Assertions.assertEquals("key1", kv.getChildren().get(0).getName()); + Assertions.assertEquals("value1", kv.getChildren().get(0).getValue()); + Assertions.assertEquals("key2", kv.getChildren().get(1).getName()); + Assertions.assertEquals(1, kv.getChildren().get(1).getChildren().size()); + Assertions.assertEquals("ChildKey", kv.getChildren().get(1).getChildren().get(0).getName()); + Assertions.assertEquals("ChildValue", kv.getChildren().get(1).getChildren().get(0).getValue()); + } catch (IOException e) { + Assertions.fail(e); + } + } + + // @Test + // public void canReadAndIgnoreConditionals() { + // } + + @Test + public void writesNewLineAsSlashN() { + KeyValue kv = new KeyValue("abc"); + kv.getChildren().add(new KeyValue("def", "ghi\njkl")); + + String text = saveToText(kv); + String expected = ("\n" + + "\"abc\"\n" + + "{\n" + "\t" + "\"def\"\t\t\"ghi\\njkl\"\n" + + "}\n").trim().replace("\r\n", "\n") + "\n"; + + Assertions.assertEquals(expected, text); + } + @Test public void keyValuesUnsignedByteConversion() { byte expectedValue = 37; KeyValue kv = new KeyValue("key", "37"); - assertEquals(expectedValue, kv.asByte()); + Assertions.assertEquals(expectedValue, kv.asByte()); kv.setValue("256"); - - assertEquals(expectedValue, kv.asByte(expectedValue)); + Assertions.assertEquals(expectedValue, kv.asByte(expectedValue)); } @Test @@ -414,11 +473,10 @@ public void keyValuesUnsignedShortConversion() { short expectedValue = 1337; KeyValue kv = new KeyValue("key", "1337"); - assertEquals(expectedValue, kv.asShort()); + Assertions.assertEquals(expectedValue, kv.asShort()); kv.setValue("123456"); - - assertEquals(expectedValue, kv.asShort(expectedValue)); + Assertions.assertEquals(expectedValue, kv.asShort(expectedValue)); } @Test @@ -427,20 +485,10 @@ public void keyValuesEscapesTextWhenSerializing() { kv.getChildren().add(new KeyValue("slashes", "\\o/")); kv.getChildren().add(new KeyValue("newline", "\r\n")); - String text; - - try (MemoryStream ms = new MemoryStream()) { - kv.saveToStream(ms.asOutputStream(), false); - ms.seek(0, SeekOrigin.BEGIN); - - text = new String(ms.toByteArray()); - - String expectedValue = "\"key\"\n{\n\t\"slashes\"\t\t\"\\\\o/\"\n\t\"newline\"\t\t\"\\r\\n\"\n}\n"; - assertEquals(expectedValue, text); + String text = saveToText(kv); - } catch (Exception e) { - fail(e.getMessage()); - } + String expectedValue = "\"key\"\n{\n\t\"slashes\"\t\t\"\\\\o/\"\n\t\"newline\"\t\t\"\\r\\n\"\n}\n"; + Assertions.assertEquals(expectedValue, text); } @Test @@ -449,23 +497,14 @@ public void keyValuesTextPreserveEmptyObjects() { kv.getChildren().add(new KeyValue("emptyObj")); kv.getChildren().add(new KeyValue("emptyString", "")); - String text; - - try (MemoryStream ms = new MemoryStream()) { - kv.saveToStream(ms.asOutputStream(), false); - ms.seek(0, SeekOrigin.BEGIN); + String text = saveToText(kv); - text = new String(ms.toByteArray()); - - String expectedValue = "\"key\"\n{\n\t\"emptyObj\"\n\t{\n\t}\n\t\"emptyString\"\t\t\"\"\n}\n"; - assertEquals(expectedValue, text); - } catch (Exception e) { - fail(e.getMessage()); - } + String expectedValue = "\"key\"\n{\n\t\"emptyObj\"\n\t{\n\t}\n\t\"emptyString\"\t\t\"\"\n}\n"; + Assertions.assertEquals(expectedValue, text); } @Test - public void keyValuesBinaryPreserveEmptyObjects() throws IOException { + public void keyValuesBinaryPreserveEmptyObjects() { String expectedHexString = "006B65790000656D7074794F626A000801656D707479537472696E6700000808"; KeyValue kv = new KeyValue("key"); @@ -473,37 +512,42 @@ public void keyValuesBinaryPreserveEmptyObjects() throws IOException { kv.getChildren().add(new KeyValue("emptyString", "")); KeyValue deserializedKv = new KeyValue(); - byte[] binaryValue; - - MemoryStream ms = new MemoryStream(); - kv.saveToStream(ms.asOutputStream(), true); - ms.seek(0, SeekOrigin.BEGIN); - - binaryValue = ms.toByteArray(); - deserializedKv.tryReadAsBinary(ms); - - StringBuilder hexValue = new StringBuilder(); - for (byte value : binaryValue) { - String string = String.format("%02X", value); - hexValue.append(string); + byte[] binaryValue = new byte[0]; + try (var ms = new MemoryStream()) { + kv.saveToStream(ms.asOutputStream(), true); + ms.seek(0, SeekOrigin.BEGIN); + binaryValue = ms.toByteArray(); + deserializedKv.tryReadAsBinary(ms); + } catch (IOException e) { + Assertions.fail(e); } - assertEquals(expectedHexString, hexValue.toString()); - assertNull(deserializedKv.get("emptyObj").getValue()); - assertTrue(deserializedKv.get("emptyObj").getChildren().isEmpty()); - assertEquals("", deserializedKv.get("emptyString").getValue()); + String hexValue = Hex.encodeHexString(binaryValue).toUpperCase(); + + Assertions.assertEquals(expectedHexString, hexValue); + Assertions.assertNull(deserializedKv.get("emptyObj").getValue()); + Assertions.assertTrue(deserializedKv.get("emptyObj").getChildren().isEmpty()); + Assertions.assertEquals("", deserializedKv.get("emptyString").getValue()); } @Test - public void DecodesBinaryWithFieldType10() throws IOException, DecoderException { - String hex = "00546573744F626A656374000A6B65790001020304050607080808"; - byte[] binary = Hex.decodeHex(hex); - KeyValue kv = new KeyValue(); - MemoryStream ms = new MemoryStream(binary); - boolean read = kv.tryReadAsBinary(ms); - assertTrue(read); + public void decodesBinaryWithFieldType10() { + var hex = "00546573744F626A656374000A6B65790001020304050607080808"; + byte[] binary = null; + try { + binary = Hex.decodeHex(hex); + } catch (DecoderException e) { + Assertions.fail(e); + } + var kv = new KeyValue(); + try (var ms = new MemoryStream(binary)) { + var read = kv.tryReadAsBinary(ms); + Assertions.assertTrue(read); + } catch (IOException e) { + Assertions.fail(e); + } - assertEquals(0x0807060504030201L, kv.get("key").asLong()); + Assertions.assertEquals(0x0807060504030201L, kv.get("key").asLong()); } @Test @@ -514,20 +558,20 @@ public void keyValuesHandlesEnum() { " \"name\" \"Talk\"" + "}"); - assertEquals(EnumSet.of(EChatPermission.Talk), kv.get("name").asEnum(EChatPermission.class, EChatPermission.EveryoneDefault)); + Assertions.assertEquals(EnumSet.of(EChatPermission.Talk), kv.get("name").asEnum(EChatPermission.class, EChatPermission.EveryoneDefault)); kv.get("name").setValue("8"); - assertEquals(EnumSet.of(EChatPermission.Talk), kv.get("name").asEnum(EChatPermission.class, EChatPermission.EveryoneDefault)); + Assertions.assertEquals(EnumSet.of(EChatPermission.Talk), kv.get("name").asEnum(EChatPermission.class, EChatPermission.EveryoneDefault)); kv.get("name").setValue("10"); - assertEquals(EnumSet.of(EChatPermission.Talk, EChatPermission.Invite), kv.get("name").asEnum(EChatPermission.class, EChatPermission.EveryoneDefault)); - assertEquals(EnumSet.of(EResult.Busy), kv.get("name").asEnum(EResult.class, EResult.Invalid)); + Assertions.assertEquals(EnumSet.of(EChatPermission.Talk, EChatPermission.Invite), kv.get("name").asEnum(EChatPermission.class, EChatPermission.EveryoneDefault)); + Assertions.assertEquals(EnumSet.of(EResult.Busy), kv.get("name").asEnum(EResult.class, EResult.Invalid)); kv.get("name").setValue("OwnerDefault"); - assertEquals(EChatPermission.OwnerDefault, kv.get("name").asEnum(EChatPermission.class, EChatPermission.EveryoneDefault)); + Assertions.assertEquals(EChatPermission.OwnerDefault, kv.get("name").asEnum(EChatPermission.class, EChatPermission.EveryoneDefault)); } @Test @@ -541,4 +585,18 @@ public void keyValues_loadAsText_should_read_successfully() { Assertions.assertEquals("1234567", kv.get("appid").getValue(), "appid should be 1234567"); Assertions.assertEquals(2, kv.getChildren().size(), "Children should be 2"); } + + private static String saveToText(KeyValue kv) { + String text = null; + + try (MemoryStream ms = new MemoryStream()) { + kv.saveToStream(ms.asOutputStream(), false); + ms.seek(0, SeekOrigin.BEGIN); + text = new String(ms.toByteArray()); + } catch (IOException e) { + Assertions.fail(e); + } + + return text; + } }