View Javadoc
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 }