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