/* * Copyright (C) 2010 Google Inc. * * Licensed 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 io.gitlab.jfronny.commons.serialize.xml.test; import io.gitlab.jfronny.commons.serialize.xml.NativeXmlWriter; import org.junit.jupiter.api.Test; import java.io.IOException; import java.io.StringWriter; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertThrows; import static org.junit.Assert.fail; @SuppressWarnings("resource") public final class NativeXmlWriterTest { @Test public void testWriteComments() throws IOException { String expectedJson = """ true false """; StringWriter sw = new StringWriter(); NativeXmlWriter jw = new NativeXmlWriter(sw); jw.setLenient(true); jw.setIndent(" "); jw.comment("comment at file head") .beginTag("root") .comment("comment directly after context") .beginTag("a") .text("true") .endTag() .comment("comment before context") .beginTag("inner") .attributeName("att") .comment("comment directly after attribute name") .attributeValue("value") .beginTag("b") .attributeName("att") .attributeValue("value") .comment("comment after attribute value") .text("false") .endTag() .beginTag("cnt") .comment("only comment inside tag") .endTag() .endTag() .comment("comment before context end") .endTag() .comment("comment behind the object"); jw.close(); assertThat(sw.toString()).isEqualTo(expectedJson); sw.close(); } @Test public void testDefaultStrictness() throws IOException { NativeXmlWriter jsonWriter = new NativeXmlWriter(new StringWriter()); assertThat(jsonWriter.isLenient()).isEqualTo(false); jsonWriter.text("false"); jsonWriter.close(); } // for NativeXmlWriter.setLenient @Test public void testSetLenientTrue() throws IOException { NativeXmlWriter jsonWriter = new NativeXmlWriter(new StringWriter()); jsonWriter.setLenient(true); assertThat(jsonWriter.isLenient()).isEqualTo(true); jsonWriter.text("false"); jsonWriter.close(); } // for NativeXmlWriter.setLenient @Test public void testSetLenientFalse() throws IOException { NativeXmlWriter jsonWriter = new NativeXmlWriter(new StringWriter()); jsonWriter.setLenient(false); assertThat(jsonWriter.isLenient()).isEqualTo(false); jsonWriter.text("false"); jsonWriter.close(); } @Test public void testEmptyTag() throws IOException { StringWriter sw = new StringWriter(); NativeXmlWriter jw = new NativeXmlWriter(sw); jw.beginTag("empty").endTag(); jw.close(); assertThat(sw.toString()).isEqualTo(""); } @Test public void testTopLevelValueTypes() throws IOException { StringWriter string5 = new StringWriter(); NativeXmlWriter writert = new NativeXmlWriter(string5); writert.text("a"); writert.close(); assertThat(string5.toString()).isEqualTo("a"); } @Test public void testNameWithoutValue() throws IOException { StringWriter stringWriter = new StringWriter(); NativeXmlWriter jsonWriter = new NativeXmlWriter(stringWriter); jsonWriter.beginTag("tag"); jsonWriter.attributeName("a"); try { jsonWriter.endTag(); fail(); } catch (IllegalStateException expected) { assertThat(expected).hasMessageThat().isEqualTo("Dangling name."); } } @Test public void testValueWithoutName() throws IOException { StringWriter stringWriter = new StringWriter(); NativeXmlWriter jsonWriter = new NativeXmlWriter(stringWriter); jsonWriter.beginTag("tag"); try { jsonWriter.attributeValue("a"); fail(); } catch (IllegalStateException expected) { assertThat(expected).hasMessageThat().isEqualTo("Nesting problem."); } } @Test public void testMultipleTopLevelValuesStrict() throws IOException { StringWriter stringWriter = new StringWriter(); NativeXmlWriter jsonWriter = new NativeXmlWriter(stringWriter); jsonWriter.setLenient(false); jsonWriter.beginTag("tag").endTag(); IllegalStateException expected = assertThrows(IllegalStateException.class, () -> jsonWriter.beginTag("tag")); assertThat(expected).hasMessageThat().isEqualTo("XML must have only one top-level value."); } @Test public void testMultipleTopLevelValuesLenient() throws IOException { StringWriter stringWriter = new StringWriter(); NativeXmlWriter writer = new NativeXmlWriter(stringWriter); writer.setLenient(true); writer.beginTag("tag"); writer.endTag(); writer.beginTag("tag2"); writer.endTag(); writer.close(); assertThat(stringWriter.toString()).isEqualTo(""); } @Test public void testNullName() throws IOException { StringWriter stringWriter = new StringWriter(); NativeXmlWriter jsonWriter = new NativeXmlWriter(stringWriter); jsonWriter.beginTag("tag"); try { jsonWriter.attributeName(null); fail(); } catch (NullPointerException expected) { } } @Test public void testNullStringValue() throws IOException { StringWriter stringWriter = new StringWriter(); NativeXmlWriter jsonWriter = new NativeXmlWriter(stringWriter); jsonWriter.beginTag("tag"); jsonWriter.attributeName("a"); jsonWriter.attributeValue(null); jsonWriter.endTag(); assertThat(stringWriter.toString()).isEqualTo(""); } @Test public void testUnicodeLineBreaksEscaped() throws IOException { StringWriter stringWriter = new StringWriter(); NativeXmlWriter jsonWriter = new NativeXmlWriter(stringWriter); jsonWriter.beginTag("body"); jsonWriter.text("\u2028 \u2029"); jsonWriter.endTag(); // JSON specification does not require that they are escaped, but Gson escapes them for // compatibility with JavaScript where they are considered line breaks assertThat(stringWriter.toString()).isEqualTo("
 
"); } @Test public void testDeepNesting() throws IOException { StringWriter stringWriter = new StringWriter(); NativeXmlWriter jsonWriter = new NativeXmlWriter(stringWriter); for (int i = 0; i < 20; i++) { jsonWriter.beginTag("a"); } for (int i = 0; i < 20; i++) { jsonWriter.endTag(); } assertThat(stringWriter.toString()) .isEqualTo( "" + "" + "" + "" + ""); } @Test public void testRepeatedName() throws IOException { StringWriter stringWriter = new StringWriter(); NativeXmlWriter jsonWriter = new NativeXmlWriter(stringWriter); jsonWriter.beginTag("tag"); jsonWriter.attributeName("a"); jsonWriter.attributeValue("true"); jsonWriter.attributeName("a"); jsonWriter.attributeValue("false"); jsonWriter.beginTag("a").text("true").endTag(); jsonWriter.beginTag("a").text("false").endTag(); jsonWriter.endTag(); // NativeXmlWriter doesn't attempt to detect duplicate names assertThat(stringWriter.toString()).isEqualTo("truefalse"); } @Test public void testPrettyPrintArray() throws IOException { StringWriter stringWriter = new StringWriter(); NativeXmlWriter jsonWriter = new NativeXmlWriter(stringWriter); jsonWriter.setIndent(" "); jsonWriter.beginTag("tag"); jsonWriter.attribute("a", "b"); jsonWriter.text("true"); jsonWriter.text("false"); jsonWriter.text("5.0"); jsonWriter.text(null); jsonWriter.beginTag("object"); jsonWriter.attributeName("a").attributeValue("6.0"); jsonWriter.beginTag("b").text("7.0").endTag(); jsonWriter.endTag(); jsonWriter.beginTag("tag"); jsonWriter.text("8.0"); jsonWriter.text("9.0"); jsonWriter.endTag(); jsonWriter.endTag(); String expected = """ true false 5.0 null 7.0 8.0 9.0 """; assertThat(stringWriter.toString()).isEqualTo(expected); } @Test public void testClosedWriterThrowsOnStructure() throws IOException { StringWriter stringWriter = new StringWriter(); NativeXmlWriter writer = new NativeXmlWriter(stringWriter); writer.beginTag("tag"); writer.endTag(); writer.close(); try { writer.beginTag("tag"); fail(); } catch (IllegalStateException expected) { } try { writer.endTag(); fail(); } catch (IllegalStateException expected) { } } @Test public void testClosedWriterThrowsOnName() throws IOException { StringWriter stringWriter = new StringWriter(); NativeXmlWriter writer = new NativeXmlWriter(stringWriter); writer.beginTag("tag"); writer.endTag(); writer.close(); try { writer.attributeName("a"); fail(); } catch (IllegalStateException expected) { } } @Test public void testClosedWriterThrowsOnValue() throws IOException { StringWriter stringWriter = new StringWriter(); NativeXmlWriter writer = new NativeXmlWriter(stringWriter); writer.beginTag("tag"); writer.endTag(); writer.close(); try { writer.attributeValue("a"); fail(); } catch (IllegalStateException expected) { } } @Test public void testClosedWriterThrowsOnFlush() throws IOException { StringWriter stringWriter = new StringWriter(); NativeXmlWriter writer = new NativeXmlWriter(stringWriter); writer.beginTag("tag"); writer.endTag(); writer.close(); try { writer.flush(); fail(); } catch (IllegalStateException expected) { } } @Test public void testWriterCloseIsIdempotent() throws IOException { StringWriter stringWriter = new StringWriter(); NativeXmlWriter writer = new NativeXmlWriter(stringWriter); writer.beginTag("tag"); writer.endTag(); writer.close(); writer.close(); } }