View Javadoc
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.logging.PlexusLoggerWrapper;
30  import org.apache.maven.doxia.parser.ParseException;
31  import org.apache.maven.doxia.parser.Parser;
32  
33  import org.apache.maven.doxia.sink.Sink;
34  import org.apache.maven.doxia.sink.impl.SinkTestDocument;
35  import org.apache.maven.doxia.sink.impl.TextSink;
36  import org.codehaus.plexus.DefaultPlexusContainer;
37  import org.codehaus.plexus.util.IOUtil;
38  
39  /**
40   * If a module provides both Parser and Sink, this class
41   * can be used to check that chaining them together
42   * results in the identity transformation, ie the model is still the same
43   * after being piped through a Parser and the corresponding Sink.
44   *
45   * @version $Id$
46   */
47  public abstract class AbstractIdentityTest
48      extends AbstractModuleTest
49  {
50      /** Expected Identity String */
51      private String expected;
52  
53      /**
54       * Set to true if the identity transformation should actually be asserted,
55       * by default only the expected and actual results are written to a file, but not compared.
56       */
57      private boolean assertIdentity;
58  
59      /**
60       * Create a new instance of the parser to test.
61       *
62       * @return the parser to test.
63       */
64      protected abstract Parser createParser();
65  
66      /**
67       * Return a new instance of the sink that is being tested.
68       *
69       * @param writer The writer for the sink.
70       * @return A new sink.
71       */
72      protected abstract Sink createSink( Writer writer );
73  
74      /**
75       * Pipes a full model generated by {@link SinkTestDocument} through
76       * a Sink (generated by {@link #createSink(Writer)}) and a Parser
77       * (generated by {@link #createParser()}) and checks if the result
78       * is the same as the original model. By default, this doesn't actually
79       * assert anything (use {@link #assertIdentity(boolean)} in the setUp()
80       * of an implementation to switch on the test), but the two generated
81       * output files, expected.txt and actual.txt, can be compared for differences.
82       *
83       * @throws IOException if there's a problem reading/writing a test file.
84       * @throws ParseException if a model cannot be parsed.
85       */
86      public void testIdentity()
87          throws IOException, ParseException
88      {
89          // generate the expected model
90          StringWriter writer = new StringWriter();
91          Sink sink = new TextSink( writer );
92          SinkTestDocument.generate( sink );
93          sink.close();
94          expected = writer.toString();
95  
96          // write to file for comparison
97          Writer fileWriter = getTestWriter( "expected" );
98          fileWriter.write( expected );
99          IOUtil.close( fileWriter );
100 
101         // generate the actual model
102         writer = new StringWriter();
103         sink = createSink( writer );
104         SinkTestDocument.generate( sink );
105         sink.close();
106         StringReader reader = new StringReader( writer.toString() );
107 
108         writer = new StringWriter();
109         sink = new TextSink( writer );
110         Parser parser = createParser();
111         parser.enableLogging( new PlexusLoggerWrapper( ( ( DefaultPlexusContainer )getContainer() ).getLogger() ) );
112         parser.parse( reader, sink );
113         String actual = writer.toString();
114 
115         // write to file for comparison
116         fileWriter = getTestWriter( "actual" );
117         fileWriter.write( actual );
118         IOUtil.close( fileWriter );
119 
120         // Disabled by default, it's unlikely that all our modules
121         // will pass this test any time soon, but the generated
122         // output files can still be compared.
123 
124         if ( assertIdentity )
125         {
126             // TODO: make this work for at least apt and xdoc modules?
127             assertEquals( "Identity test failed! See results in " + getTestWriterFile( "actual" ).getParent(),
128                           getExpected(), actual );
129         }
130     }
131 
132     /** {@inheritDoc} */
133     protected String getOutputDir()
134     {
135         return "identity/";
136     }
137 
138     /**
139      * The output files generated by this class are text files,
140      * independent of the kind of module being tested.
141      *
142      * @return The String "txt".
143      */
144     protected String outputExtension()
145     {
146         return "txt";
147     }
148 
149     /**
150      * Set to true if the identity transformation should actually be asserted,
151      * by default only the expected and actual results are written to a file, but not compared.
152      * This should be called during setUp().
153      *
154      * @param doAssert True to actually execute the test.
155      */
156     protected void assertIdentity( boolean doAssert )
157     {
158         this.assertIdentity = doAssert;
159     }
160 
161     /**
162      * @return the expected identity string
163      */
164     protected String getExpected()
165     {
166         return expected;
167     }
168 }