001package org.apache.maven.doxia.module; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import java.io.IOException; 023import java.io.StringReader; 024import java.io.StringWriter; 025import java.io.Writer; 026 027import org.apache.maven.doxia.AbstractModuleTest; 028 029import org.apache.maven.doxia.logging.PlexusLoggerWrapper; 030import org.apache.maven.doxia.parser.ParseException; 031import org.apache.maven.doxia.parser.Parser; 032 033import org.apache.maven.doxia.sink.Sink; 034import org.apache.maven.doxia.sink.impl.SinkTestDocument; 035import org.apache.maven.doxia.sink.impl.TextSink; 036import org.codehaus.plexus.DefaultPlexusContainer; 037import org.codehaus.plexus.util.IOUtil; 038 039/** 040 * If a module provides both Parser and Sink, this class 041 * can be used to check that chaining them together 042 * results in the identity transformation, ie the model is still the same 043 * after being piped through a Parser and the corresponding Sink. 044 * 045 * @version $Id$ 046 */ 047public abstract class AbstractIdentityTest 048 extends AbstractModuleTest 049{ 050 /** Expected Identity String */ 051 private String expected; 052 053 /** 054 * Set to true if the identity transformation should actually be asserted, 055 * by default only the expected and actual results are written to a file, but not compared. 056 */ 057 private boolean assertIdentity; 058 059 /** 060 * Create a new instance of the parser to test. 061 * 062 * @return the parser to test. 063 */ 064 protected abstract Parser createParser(); 065 066 /** 067 * Return a new instance of the sink that is being tested. 068 * 069 * @param writer The writer for the sink. 070 * @return A new sink. 071 */ 072 protected abstract Sink createSink( Writer writer ); 073 074 /** 075 * Pipes a full model generated by {@link SinkTestDocument} through 076 * a Sink (generated by {@link #createSink(Writer)}) and a Parser 077 * (generated by {@link #createParser()}) and checks if the result 078 * is the same as the original model. By default, this doesn't actually 079 * assert anything (use {@link #assertIdentity(boolean)} in the setUp() 080 * of an implementation to switch on the test), but the two generated 081 * output files, expected.txt and actual.txt, can be compared for differences. 082 * 083 * @throws IOException if there's a problem reading/writing a test file. 084 * @throws ParseException if a model cannot be parsed. 085 */ 086 public void testIdentity() 087 throws IOException, ParseException 088 { 089 // generate the expected model 090 StringWriter writer = new StringWriter(); 091 Sink sink = new TextSink( writer ); 092 SinkTestDocument.generate( sink ); 093 sink.close(); 094 expected = writer.toString(); 095 096 // write to file for comparison 097 Writer fileWriter = getTestWriter( "expected" ); 098 fileWriter.write( expected ); 099 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}