Java tutorial
/* * Copyright (C) 2008 Herve Quiroz * * This library 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 2.1 of the License, or (at your option) * any later version. * * This library 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 Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id$ */ package org.trancecode.xproc; import com.google.common.base.Throwables; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.util.Collection; import java.util.Iterator; import java.util.List; import javax.xml.transform.Source; import net.sf.saxon.s9api.Processor; import net.sf.saxon.s9api.QName; import net.sf.saxon.s9api.XdmNode; import org.apache.commons.io.FileUtils; import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.testng.Assert; import org.testng.AssertJUnit; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.trancecode.AbstractTest; import org.trancecode.TcAssert; import org.trancecode.io.Uris; import org.trancecode.xproc.api.XProcException; /** * @author Herve Quiroz */ public abstract class AbstractXProcTest extends AbstractTest { public static final String PROPERTY_TARGET_DIRECTORY = "project.build.directory"; public static final String DEFAULT_TARGET_DIRECTORY = "target"; private static final org.trancecode.logging.Logger LOG = org.trancecode.logging.Logger .getLogger(AbstractXProcTest.class); private XProcTestSuiteReportBuilder reportBuilder; @BeforeClass public void setupReportBuilder() { reportBuilder = new XProcTestSuiteReportBuilder(); } @AfterClass public void writeReportToFile() throws Exception { final String reportDirectoryPath = System.getProperty(PROPERTY_TARGET_DIRECTORY, DEFAULT_TARGET_DIRECTORY); final File reportDirectory = new File(reportDirectoryPath, "xproc-test-reports"); FileUtils.forceMkdir(reportDirectory); LOG.info("report directory: {}", reportDirectory.getAbsolutePath()); final File reportFile = new File(reportDirectory, getClass().getSimpleName() + ".xml"); LOG.info("report file: {}", reportFile.getAbsolutePath()); reportBuilder.write(reportFile); } @BeforeClass public static void setupLoggingLevel() { Logger.getLogger("org.trancecode").setLevel(Level.TRACE); Logger.getLogger("org.apache").setLevel(Level.TRACE); } @BeforeClass public static void parseStandardLibrary() { Logger.getLogger("org.trancecode").setLevel(Level.INFO); new PipelineConfiguration(); Logger.getLogger("org.trancecode").setLevel(Level.TRACE); } protected void test(final URL testUrl) throws Exception { test(testUrl, null); } protected void test(final URL testUrl, final String testSuite) throws Exception { LOG.info("Starting test: {}", testUrl); final PipelineConfiguration configuration = new PipelineConfiguration(); final PipelineProcessor pipelineProcessor = new PipelineProcessor(configuration); final XProcTestCase test = getTest(testUrl, configuration.getProcessor(), testSuite); try { test(test, pipelineProcessor); } catch (final XProcException e) { if (!reportBuilder.result(test, e).failed()) { return; } if (test.getError() != null) { Assert.fail(String.format("expected error: %s ; actual: %s", test.getError(), e.getName()), e); } throw e; } catch (final Throwable e) { reportBuilder.result(test, e); Throwables.propagateIfPossible(e); Assert.fail(e.getMessage(), e); } if (reportBuilder.result(test, null).failed()) { Assert.fail(String.format("expected error: %s", test.getError())); } LOG.info("Ending test: {}", testUrl); } private void test(final XProcTestCase test, final PipelineProcessor pipelineProcessor) { log.info(">>>> parse pipeline: {}", test.url()); final Pipeline pipeline = pipelineProcessor.buildPipeline(test.getPipeline().asSource()); log.info("<<<< parse pipeline"); final RunnablePipeline runnablePipeline = pipeline.load(); // Set inputs for (final String port : test.getInputs().keySet()) { final List<Source> sources = Lists.newArrayList(); for (final Collection<XdmNode> inputDocCollection : test.getInputs().get(port)) { for (final XdmNode inputDoc : inputDocCollection) { sources.add(inputDoc.asSource()); } } runnablePipeline.bindSourcePort(port, sources); } // Set options for (final QName name : test.getOptions().keySet()) { final String value = test.getOptions().get(name); LOG.trace(" option {} = {}", name, value); runnablePipeline.withOption(name, value); } // Set parameters // TODO how to deal with multiple parameter ports ? for (final String port : test.getParameters().keySet()) { for (final QName name : test.getParameters().get(port).keySet()) { final String value = test.getParameters().get(port).get(name); LOG.trace(" parameter {} = {}", name, value); runnablePipeline.withParam(name, value); } } log.info(">>>> run pipeline"); final PipelineResult result = runnablePipeline.run(); log.info("<<<< run pipeline"); PipelineResult compareResult = null; if (test.getComparePipeline() != null) { log.info(">>>> parse compare pipeline"); final Pipeline comparePipeline = pipelineProcessor.buildPipeline(test.getComparePipeline().asSource()); log.info("<<<< parse compare pipeline"); final RunnablePipeline compareRunnablePipeline = comparePipeline.load(); for (final String port : test.getOutputs().keySet()) { final List<Source> sources = Lists.newArrayList(); for (final XdmNode inputDoc : test.getOutputs().get(port)) { sources.add(inputDoc.asSource()); } compareRunnablePipeline.bindSourcePort(port, sources); } for (final QName name : test.getOptions().keySet()) { compareRunnablePipeline.withOption(name, test.getOptions().get(name)); } for (final String port : test.getParameters().keySet()) { for (final QName name : test.getParameters().get(port).keySet()) { compareRunnablePipeline.withParam(name, test.getParameters().get(port).get(name)); } } compareResult = compareRunnablePipeline.run(); } final PipelineResult resultPipeline = (test.getComparePipeline() != null) ? compareResult : result; assert resultPipeline != null; for (final String port : test.getOutputs().keySet()) { final Iterable<XdmNode> actualNodes = resultPipeline.readNodes(port); final Iterable<XdmNode> expectedNodes = test.getOutputs().get(port); AssertJUnit.assertEquals(port + " = " + actualNodes.toString(), Iterables.size(expectedNodes), Iterables.size(actualNodes)); final Iterator<XdmNode> expectedNodesIterator = expectedNodes.iterator(); final Iterator<XdmNode> actualNodesIterator = actualNodes.iterator(); while (expectedNodesIterator.hasNext()) { assert actualNodesIterator.hasNext(); final XdmNode expectedNode = expectedNodesIterator.next(); final XdmNode actualNode = actualNodesIterator.next(); TcAssert.compare(expectedNode, actualNode); } assert !actualNodesIterator.hasNext(); } } private XProcTestCase getTest(final URL testUrl, final Processor processor, final String testSuite) { final XProcTestParser parser = new XProcTestParser(processor, testUrl, testSuite); parser.parse(); return parser.getTest(); } protected String getTestUrlPrefix() { final String localPath = System.getProperty(LocalXProcTestsProvider.TEST_DIR_PROPERTY); if (localPath != null && !localPath.isEmpty()) { return Uris.asDirectory(new File(localPath).toURI()).toString(); } return "http://svn.xproc.org/tests/"; } protected void test(final String testName) throws Exception { final String testUrlString = getTestUrlPrefix() + testName; final URL testUrl; try { testUrl = new URL(testUrlString); } catch (final MalformedURLException e) { throw new IllegalArgumentException(testUrlString, e); } test(testUrl); } }