/************************************************************************** OmegaT - Computer Assisted Translation (CAT) tool with fuzzy matching, translation memory, keyword search, glossaries, and translation leveraging into updated projects. Copyright (C) 2010 Alex Buloichik Home page: http://www.omegat.org/ Support center: http://groups.yahoo.com/group/OmegaT/ This file is part of OmegaT. OmegaT is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OmegaT 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.omegat.util; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.io.File; import java.io.FileInputStream; import java.io.InputStreamReader; import java.io.Reader; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Result; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathFactory; import org.custommonkey.xmlunit.XMLUnit; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.omegat.core.data.ProjectProperties; import org.omegat.core.data.RealProjectTest; import org.omegat.filters.TestFilterBase; import org.w3c.dom.Document; import org.w3c.dom.Node; /** * @author Alex Buloichik */ public class TMXWriterTest extends TestFilterBase { @Before public final void setUp() { XMLUnit.setControlEntityResolver(TMXReader2.TMX_DTD_RESOLVER); XMLUnit.setTestEntityResolver(TMXReader2.TMX_DTD_RESOLVER); XMLUnit.setIgnoreWhitespace(true); } @After public final void tearDown() throws Exception { XMLUnit.setControlEntityResolver(null); XMLUnit.setTestEntityResolver(null); } @Test public void testWriteInvalidChars() throws Exception { String in = ""; in += (char) 0x00; in += (char) 0x01; in += (char) 0x02; in += (char) 0x18; in += (char) 0x19; in += (char) 0xD8FF; in += (char) 0xFFFE; in += (char) 0x12FFFF; TMXWriter2 wr = new TMXWriter2(outFile, new Language("en-US"), new Language("be-BY"), false, true, false); wr.writeEntry(in, "test", RealProjectTest.createEmptyTMXEntry(), null); wr.close(); load(new ArrayList<String>(), null, false, false); } @Test public void testLevel2write() throws Exception { TMXWriter2 wr = new TMXWriter2(outFile, new Language("en-US"), new Language("be-BY"), false, true, false); wr.writeEntry("source", "target", RealProjectTest.createEmptyTMXEntry(), null); wr.writeEntry("1<a1/>2", "zz", RealProjectTest.createEmptyTMXEntry(), null); wr.writeEntry("3<a1>4</a1>5", "zz", RealProjectTest.createEmptyTMXEntry(), null); wr.writeEntry("6<a1>7", "zz", RealProjectTest.createEmptyTMXEntry(), null); wr.close(); compareTMX(outFile, new File("test/data/tmx/test-save-tmx14.tmx")); } @Test public void testLevel2reads() throws Exception { final List<String> sources = new ArrayList<String>(); // patch for 'OmegaT' tmx setCreationTool(new File("test/data/tmx/test-save-tmx14.tmx"), "OmegaT", outFile); load(sources, null, true, false); assertEquals(4, sources.size()); assertEquals("source", sources.get(0)); assertEquals("1<a1/>2", sources.get(1)); assertEquals("3<a1>4</a1>5", sources.get(2)); assertEquals("6<a1>7", sources.get(3)); // patch for 'ext' tmx setCreationTool(new File("test/data/tmx/test-save-tmx14.tmx"), "ext", outFile); // extLevel2 = false; useSlash = false load(sources, null, false, false); assertEquals(4, sources.size()); assertEquals("source", sources.get(0)); assertEquals("12", sources.get(1)); assertEquals("345", sources.get(2)); assertEquals("67", sources.get(3)); // extLevel2 = true; useSlash = false load(sources, null, true, false); assertEquals(4, sources.size()); assertEquals("source", sources.get(0)); assertEquals("1<a0>2", sources.get(1)); assertEquals("3<a0>4</a0>5", sources.get(2)); assertEquals("6<a0>7", sources.get(3)); // extLevel2 = true; useSlash = true load(sources, null, true, true); assertEquals(4, sources.size()); assertEquals("source", sources.get(0)); assertEquals("1<a0/>2", sources.get(1)); assertEquals("3<a0>4</a0>5", sources.get(2)); // This last seg has an <it> tag with @pos="begin", // which should be treated as a beginning tag even when // useSlash = true so that we can match after segmenting, // such as in TmxComplianceTests#testImport2A: // "First <b0>sentence. Second</b0> sentence." -> ["First <b0>sentence.", "Second</b0> sentence."] assertEquals("6<a0>7", sources.get(3)); } @Test public void testEOLwrite() throws Exception { String eol = TMXWriter2.LINE_SEPARATOR; try { TMXWriter2.LINE_SEPARATOR = "\r\n"; TMXWriter2 wr = new TMXWriter2(outFile, new Language("en-US"), new Language("be-BY"), false, true, false); wr.writeEntry("source", "tar\nget", RealProjectTest.createEmptyTMXEntry(), null); wr.close(); StringBuilder text = new StringBuilder(); Reader rd = new InputStreamReader(new FileInputStream(outFile), "UTF-8"); char[] buffer = new char[512]; while (true) { int len = rd.read(buffer); if (len < 0) break; text.append(buffer, 0, len); } rd.close(); assertTrue(text.toString().contains("tar\r\nget")); final List<String> trs = new ArrayList<String>(); load(null, trs, true, false); assertTrue(trs.get(0).contains("tar\nget")); } finally { TMXWriter2.LINE_SEPARATOR = eol; } final List<String> trs = new ArrayList<String>(); load(null, trs, true, false); assertTrue(trs.get(0).contains("tar\nget")); } private void setCreationTool(File in, String tool, File out) throws Exception { XPathExpression exprTool = XPathFactory.newInstance().newXPath().compile("/tmx/header/@creationtool"); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); DocumentBuilder builder = factory.newDocumentBuilder(); builder.setEntityResolver(TMXReader2.TMX_DTD_RESOLVER); Document doc = builder.parse(in); Node n = (Node) exprTool.evaluate(doc, XPathConstants.NODE); n.setNodeValue(tool); Transformer transformer = TransformerFactory.newInstance().newTransformer(); Result output = new StreamResult(out); Source input = new DOMSource(doc); transformer.transform(input, output); } private void load(final List<String> sources, final List<String> translations, boolean extLevel2, boolean useSlash) throws Exception { if (sources != null) { sources.clear(); } if (translations != null) { translations.clear(); } new TMXReader2().readTMX(outFile, new Language("en-US"), new Language("be-BY"), false, false, extLevel2, useSlash, new TMXReader2.LoadCallback() { public boolean onEntry(TMXReader2.ParsedTu tu, TMXReader2.ParsedTuv tuvSource, TMXReader2.ParsedTuv tuvTarget, boolean isParagraphSegtype) { if (sources != null) { sources.add(tuvSource.text); } if (translations != null) { translations.add(tuvTarget.text); } return true; } }); } static int tagNumber = 0; static boolean closeTag, standAloneTag; /** * ProjectProperties successor for create project without directory. */ protected static class ProjectPropertiesTest extends ProjectProperties { } }