/* * Copyright (C) 2008 Laurent Caillette * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation, either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.novelang.outfit.xml; import org.junit.Test; import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.SAXException; import static org.fest.assertions.Assertions.assertThat; /** * Tests for {@link org.novelang.outfit.xml.SaxPipeline}. * * @author Laurent Caillette */ public class SaxPipelineTest { @Test public void singleStage() throws SAXException { final Counter lastStage = new Counter( "end" ) ; final SaxPipeline pipeline = new SaxPipeline( lastStage ) ; activatePipeline( pipeline ) ; verifyCallCount( pipeline, lastStage, 1 ) ; } @Test public void threeStages() throws SAXException { final Counter lastStage = new Counter( "end" ) ; final SaxPipeline pipeline = new SaxPipeline( lastStage ) ; final Counter counter0 = addNewCounterAsFork( pipeline, 0 ); final Counter counter1 = addNewCounterAsFork( pipeline, 1 ); activatePipeline( pipeline ) ; verifyCallCount( pipeline, counter0, 1 ) ; verifyCallCount( pipeline, counter1, 1 ) ; verifyCallCount( pipeline, lastStage, 1 ) ; } @Test public void threeStagesWithReplace() throws SAXException { final Counter lastStage = new Counter( "end") ; final SaxPipeline pipeline = new SaxPipeline( lastStage ) ; final Counter counter0 = addNewCounterAsFork( pipeline, 0 ) ; final Counter counter1 = addNewCounterAsFork( pipeline, 1 ) ; final Counter counter1bis = new Counter( "1bis" ) ; activatePipeline( pipeline ) ; pipeline.replace( 1, new SaxPipeline.ForkingStage( counter1bis ) ) ; activatePipeline( pipeline ) ; verifyCallCount( pipeline, counter0, 2 ) ; verifyCallCount( pipeline, counter1, 1 ) ; verifyCallCount( pipeline, counter1bis, 1 ) ; verifyCallCount( pipeline, lastStage, 2 ) ; } // ======= // Fixture // ======= private static Counter addNewCounterAsFork( final SaxPipeline pipeline, final int position ) { return addNewCounterAsFork( pipeline, position, "" + position ) ; } private static Counter addNewCounterAsFork( final SaxPipeline pipeline, final int position, final String name ) { final Counter counter = new Counter( name ) ; pipeline.add( new SaxPipeline.ForkingStage( counter ), position ) ; return counter ; } private static void activatePipeline( final SaxPipeline pipeline ) throws SAXException { pipeline.startDocument() ; pipeline.startElement( "", "", "", null ) ; pipeline.endElement( "", "", "" ) ; pipeline.endDocument() ; } private static void verifyCallCount( final SaxPipeline pipeline, final Counter counter, final int callCount ) { final String pipelineAsString = asString( pipeline ); assertThat( counter.startDocumentCallCount ).describedAs( pipelineAsString ) .isEqualTo( callCount ) ; assertThat( counter.startElementCallCount ).describedAs( pipelineAsString ) .isEqualTo( callCount ) ; assertThat( counter.endElementCallCount ).describedAs( pipelineAsString ) .isEqualTo( callCount ) ; assertThat( counter.endDocumentCallCount ).describedAs( pipelineAsString ) .isEqualTo( callCount ) ; } private static String asString( final SaxPipeline pipeline ) { final StringBuilder stringBuilder = new StringBuilder( SaxPipeline.class.getSimpleName() ) ; stringBuilder.append( "{" ) ; for( int i = 0 ; i < pipeline.getContentHandlerCount() ; i ++ ) { final ContentHandler contentHandler = pipeline.getContentHandlerAt( i ) ; stringBuilder.append( i == 0 ? "" : ", " ) ; stringBuilder.append( i ).append( ":" ) ; if( contentHandler instanceof SaxPipeline.ForkingStage ) { final ContentHandler fork = ( ( SaxPipeline.ForkingStage ) contentHandler ).getFork() ; stringBuilder.append( fork ) ; } else { stringBuilder.append( contentHandler ) ; } } stringBuilder.append( "}" ) ; return stringBuilder.toString() ; } private static class Counter extends ContentHandlerAdapter { private final String name ; private Counter( final String name ) { this.name = name ; } private int startDocumentCallCount = 0 ; private int endDocumentCallCount = 0 ; private int startElementCallCount = 0 ; private int endElementCallCount = 0 ; @Override public String toString() { return getClass().getSimpleName() + "{" + name + ", " + startDocumentCallCount // Don't need everything. + "}" ; } @Override public void startDocument() { startDocumentCallCount ++ ; } @Override public void startElement( final String uri, final String localName, final String qName, final Attributes attributes ) { startElementCallCount ++ ; } @Override public void endElement( final String uri, final String localName, final String qName ) { endElementCallCount ++ ; } @Override public void endDocument() { endDocumentCallCount ++ ; } } }