1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 package org.apache.maven.doxia.module; 20 21 import java.io.IOException; 22 import java.io.StringReader; 23 import java.io.StringWriter; 24 import java.io.Writer; 25 26 import org.apache.maven.doxia.AbstractModuleTest; 27 import org.apache.maven.doxia.parser.ParseException; 28 import org.apache.maven.doxia.parser.Parser; 29 import org.apache.maven.doxia.sink.Sink; 30 import org.apache.maven.doxia.sink.impl.SinkTestDocument; 31 import org.apache.maven.doxia.sink.impl.TextSink; 32 import org.junit.jupiter.api.Test; 33 34 import static org.junit.jupiter.api.Assertions.assertEquals; 35 36 /** 37 * If a module provides both Parser and Sink, this class 38 * can be used to check that chaining them together 39 * results in the identity transformation, ie the model is still the same 40 * after being piped through a Parser and the corresponding Sink. 41 */ 42 public abstract class AbstractIdentityTest extends AbstractModuleTest { 43 /** Expected Identity String */ 44 private String expected; 45 46 /** 47 * Set to true if the identity transformation should actually be asserted, 48 * by default only the expected and actual results are written to a file, but not compared. 49 */ 50 private boolean assertIdentity; 51 52 /** 53 * Create a new instance of the parser to test. 54 * 55 * @return the parser to test. 56 */ 57 protected abstract Parser createParser(); 58 59 /** 60 * Return a new instance of the sink that is being tested. 61 * 62 * @param writer The writer for the sink. 63 * @return A new sink. 64 */ 65 protected abstract Sink createSink(Writer writer); 66 67 /** 68 * Pipes a full model generated by {@link SinkTestDocument} through 69 * a Sink (generated by {@link #createSink(Writer)}) and a Parser 70 * (generated by {@link #createParser()}) and checks if the result 71 * is the same as the original model. By default, this doesn't actually 72 * assert anything (use {@link #assertIdentity(boolean)} in the setUp() 73 * of an implementation to switch on the test), but the two generated 74 * output files, expected.txt and actual.txt, can be compared for differences. 75 * 76 * @throws IOException if there's a problem reading/writing a test file. 77 * @throws ParseException if a model cannot be parsed. 78 */ 79 @Test 80 public void testIdentity() throws IOException, ParseException { 81 // generate the expected model 82 StringWriter writer = new StringWriter(); 83 Sink sink = new TextSink(writer); 84 SinkTestDocument.generate(sink); 85 sink.close(); 86 expected = writer.toString(); 87 88 // write to file for comparison 89 try (Writer fileWriter = getTestWriter("expectedTextSink")) { 90 fileWriter.write(expected); 91 } 92 // generate the actual model 93 writer = new StringWriter(); 94 sink = createSink(writer); 95 SinkTestDocument.generate(sink); 96 sink.close(); 97 98 String expectedViaTargetSink = writer.toString(); 99 // write to file for comparison 100 try (Writer fileWriter = getTestWriter("expectedTargetSink")) { 101 fileWriter.write(expectedViaTargetSink); 102 } 103 StringReader reader = new StringReader(expectedViaTargetSink); 104 writer = new StringWriter(); 105 sink = new TextSink(writer); 106 Parser parser = createParser(); 107 parser.parse(reader, sink); 108 String actual = writer.toString(); 109 110 // write to file for comparison 111 try (Writer fileWriter = getTestWriter("actualTextSink")) { 112 fileWriter.write(actual); 113 } 114 115 // Disabled by default, it's unlikely that all our modules 116 // will pass this test any time soon, but the generated 117 // output files can still be compared. 118 119 if (assertIdentity) { 120 // TODO: make this work for at least apt and xdoc modules? 121 assertEquals( 122 getExpected(), 123 actual, 124 "Identity test failed! See results in " 125 + getTestWriterFile("actual").getParent()); 126 } 127 } 128 129 /** {@inheritDoc} */ 130 protected String getOutputDir() { 131 return "identity/"; 132 } 133 134 /** 135 * The output files generated by this class are text files, 136 * independent of the kind of module being tested. 137 * 138 * @return The String "txt". 139 */ 140 protected String outputExtension() { 141 return "txt"; 142 } 143 144 /** 145 * Set to true if the identity transformation should actually be asserted, 146 * by default only the expected and actual results are written to a file, but not compared. 147 * This should be called during setUp(). 148 * 149 * @param doAssert True to actually execute the test. 150 */ 151 protected void assertIdentity(boolean doAssert) { 152 this.assertIdentity = doAssert; 153 } 154 155 /** 156 * @return the expected identity string 157 */ 158 protected String getExpected() { 159 return expected; 160 } 161 }