/**************************************************************************
OmegaT - Computer Assisted Translation (CAT) tool
with fuzzy matching, translation memory, keyword search,
glossaries, and translation leveraging into updated projects.
Copyright (C) 2016 Aaron Madlon-Kay
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.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.omegat.core.data.ProjectException;
import org.omegat.core.data.ProjectProperties;
import org.omegat.tokenizer.LuceneEnglishTokenizer;
import org.omegat.tokenizer.LuceneFrenchTokenizer;
import gen.core.project.Omegat;
public class ProjectFileStorageTest {
private static final File PROJECT_DIR = new File("test/data/project");
private File tempDir;
@Before
public final void setUp() throws Exception {
tempDir = Files.createTempDirectory("omegat").toFile().getAbsoluteFile();
assertTrue(tempDir.isDirectory());
TestPreferencesInitializer.init(tempDir.getPath());
}
@After
public final void tearDown() throws Exception {
FileUtils.deleteDirectory(tempDir);
}
@Test
public void testLoadDefaults() throws Exception {
ProjectProperties props = ProjectFileStorage.loadPropertiesFile(tempDir,
new File(PROJECT_DIR, "defaultdirs.project"));
try {
props.verifyProject();
fail("Project props should fail verification when dirs don't exist yet");
} catch (ProjectException ex) {
}
props.autocreateDirectories();
props.verifyProject();
assertTrue(props.getSourceRoot().endsWith("source/"));
assertTrue(props.getTargetRoot().endsWith("target/"));
assertTrue(props.getGlossaryRoot().endsWith("glossary/"));
assertTrue(props.getWriteableGlossary().endsWith("glossary/glossary.txt"));
assertTrue(props.getTMRoot().endsWith("tm/"));
assertTrue(props.getDictRoot().endsWith("dictionary/"));
assertEquals(tempDir.getName(), props.getProjectName());
assertEquals(new Language("en-us"), props.getSourceLanguage());
assertEquals(new Language("fr-fr"), props.getTargetLanguage());
assertEquals(LuceneEnglishTokenizer.class, props.getSourceTokenizer());
assertEquals(LuceneFrenchTokenizer.class, props.getTargetTokenizer());
assertTrue(props.isSentenceSegmentingEnabled());
assertTrue(props.isSupportDefaultTranslations());
assertFalse(props.isRemoveTags());
assertTrue(props.getExternalCommand().isEmpty());
List<String> excludes = props.getSourceRootExcludes();
assertEquals(6, excludes.size());
assertEquals("**/.svn/**", excludes.get(0));
}
@Test
public void testLoadCustomGlossaryDir() throws Exception {
ProjectProperties props = ProjectFileStorage.loadPropertiesFile(tempDir,
new File(PROJECT_DIR, "customglossarydir.project"));
props.autocreateDirectories();
props.verifyProject();
assertTrue(props.getWriteableGlossary().endsWith("foo/glossary.txt"));
}
@Test
public void testLoadCustomGlossaryFile() throws Exception {
ProjectProperties props = ProjectFileStorage.loadPropertiesFile(tempDir,
new File(PROJECT_DIR, "customglossaryfile.project"));
props.autocreateDirectories();
props.verifyProject();
assertTrue(props.getWriteableGlossary().endsWith("glossary/bar.txt"));
}
@Test
public void testLoadCustomGlossaryDirAndFile() throws Exception {
ProjectProperties props = ProjectFileStorage.loadPropertiesFile(tempDir,
new File(PROJECT_DIR, "customglossarydirfile.project"));
props.autocreateDirectories();
props.verifyProject();
assertTrue(props.getWriteableGlossary().endsWith("foo/bar.txt"));
}
@Test
public void testNearAbsolutePaths() throws Exception {
File projFile = new File(PROJECT_DIR, "defaultdirs.project");
Omegat omt = ProjectFileStorage.parseProjectFile(projFile);
for (int i = 0; i < OConsts.MAX_PARENT_DIRECTORIES_ABS2REL; i++) {
String prefix = repeat(i, "a/");
File projRoot = Paths.get(tempDir.getAbsolutePath(), prefix, "root").toFile();
projRoot.mkdirs();
// Set project folders to absolute paths
File srcDir = new File(tempDir, "source").getAbsoluteFile();
File trgDir = new File(tempDir, "target").getAbsoluteFile();
File dictDir = new File(tempDir, "dictionary").getAbsoluteFile();
File glosDir = new File(tempDir, "glossary").getAbsoluteFile();
File tmDir = new File(tempDir, "tm").getAbsoluteFile();
omt.getProject().setSourceDir(srcDir.getPath());
omt.getProject().setTargetDir(trgDir.getPath());
omt.getProject().setDictionaryDir(dictDir.getPath());
omt.getProject().setGlossaryDir(glosDir.getPath());
omt.getProject().setTmDir(tmDir.getPath());
// Make all the actual folders
Arrays.asList(srcDir, trgDir, dictDir, glosDir, tmDir).forEach(File::mkdirs);
// Load the ProjectProperties and verify that the project folders
// are resolved correctly
ProjectProperties props = ProjectFileStorage.loadPropertiesFile(projRoot, omt);
props.verifyProject();
// Write the project file out and read it again to make sure the
// paths are correctly round-tripped. Since these are "near" paths
// they should become relative and not be absolute.
ProjectFileStorage.writeProjectFile(props);
File outProjFile = new File(projRoot, OConsts.FILE_PROJECT);
assertTrue(outProjFile.isFile());
Omegat outOmt = ProjectFileStorage.parseProjectFile(outProjFile);
String relPrefix = repeat(i + 1, "../");
assertEquals(relPrefix + srcDir.getName(), outOmt.getProject().getSourceDir());
assertEquals(relPrefix + trgDir.getName(), outOmt.getProject().getTargetDir());
assertEquals(relPrefix + dictDir.getName(), outOmt.getProject().getDictionaryDir());
assertEquals(relPrefix + glosDir.getName(), outOmt.getProject().getGlossaryDir());
assertEquals(relPrefix + tmDir.getName(), outOmt.getProject().getTmDir());
}
}
@Test
public void testNearRelativePaths() throws Exception {
File projFile = new File(PROJECT_DIR, "defaultdirs.project");
Omegat omt = ProjectFileStorage.parseProjectFile(projFile);
for (int i = 0; i < OConsts.MAX_PARENT_DIRECTORIES_ABS2REL; i++) {
File projRoot = Paths.get(tempDir.getAbsolutePath(), repeat(i, "a/"), "root").toFile();
projRoot.mkdirs();
// Set project folders to relative paths
File srcDir = new File(tempDir, "source").getAbsoluteFile();
File trgDir = new File(tempDir, "target").getAbsoluteFile();
File dictDir = new File(tempDir, "dictionary").getAbsoluteFile();
File glosDir = new File(tempDir, "glossary").getAbsoluteFile();
File tmDir = new File(tempDir, "tm").getAbsoluteFile();
String prefix = repeat(i + 1, "../");
omt.getProject().setSourceDir(prefix + srcDir.getName());
omt.getProject().setTargetDir(prefix + trgDir.getName());
omt.getProject().setDictionaryDir(prefix + dictDir.getName());
omt.getProject().setGlossaryDir(prefix + glosDir.getName());
omt.getProject().setTmDir(prefix + tmDir.getName());
// Make all the actual folders
Arrays.asList(srcDir, trgDir, dictDir, glosDir, tmDir).forEach(File::mkdirs);
// Load the ProjectProperties and verify that the project folders
// are resolved correctly
ProjectProperties props = ProjectFileStorage.loadPropertiesFile(projRoot, omt);
props.verifyProject();
// Indirections should be resolved.
assertFalse(props.getSourceRoot().contains("../"));
assertFalse(props.getTargetRoot().contains("../"));
assertFalse(props.getDictRoot().contains("../"));
assertFalse(props.getGlossaryRoot().contains("../"));
assertFalse(props.getTMRoot().contains("../"));
// Write the project file out and read it again to make sure the
// paths are correctly round-tripped. Since these are "near" paths
// they should remain relative and not absolute.
ProjectFileStorage.writeProjectFile(props);
File outProjFile = new File(projRoot, OConsts.FILE_PROJECT);
assertTrue(outProjFile.isFile());
Omegat outOmt = ProjectFileStorage.parseProjectFile(outProjFile);
assertEquals(prefix + srcDir.getName(), outOmt.getProject().getSourceDir());
assertEquals(prefix + trgDir.getName(), outOmt.getProject().getTargetDir());
assertEquals(prefix + dictDir.getName(), outOmt.getProject().getDictionaryDir());
assertEquals(prefix + glosDir.getName(), outOmt.getProject().getGlossaryDir());
assertEquals(prefix + tmDir.getName(), outOmt.getProject().getTmDir());
}
}
@Test
public void testFarAbsolutePaths() throws Exception {
File projFile = new File(PROJECT_DIR, "defaultdirs.project");
Omegat omt = ProjectFileStorage.parseProjectFile(projFile);
String prefix = repeat(OConsts.MAX_PARENT_DIRECTORIES_ABS2REL, "a/");
File projRoot = Paths.get(tempDir.getAbsolutePath(), prefix, "root").toFile();
projRoot.mkdirs();
// Set project folders to absolute paths
File srcDir = new File(tempDir, "source").getAbsoluteFile();
File trgDir = new File(tempDir, "target").getAbsoluteFile();
File dictDir = new File(tempDir, "dictionary").getAbsoluteFile();
File glosDir = new File(tempDir, "glossary").getAbsoluteFile();
File tmDir = new File(tempDir, "tm").getAbsoluteFile();
omt.getProject().setSourceDir(srcDir.getPath());
omt.getProject().setTargetDir(trgDir.getPath());
omt.getProject().setDictionaryDir(dictDir.getPath());
omt.getProject().setGlossaryDir(glosDir.getPath());
omt.getProject().setTmDir(tmDir.getPath());
// Make all the actual folders
Arrays.asList(srcDir, trgDir, dictDir, glosDir, tmDir).forEach(File::mkdirs);
// Load the ProjectProperties and verify that the project folders
// are resolved correctly
ProjectProperties props = ProjectFileStorage.loadPropertiesFile(projRoot, omt);
props.verifyProject();
// Write the project file out and read it again to make sure the
// paths are correctly round-tripped. Since these are "far" paths
// they should remain absolute.
ProjectFileStorage.writeProjectFile(props);
File outProjFile = new File(projRoot, OConsts.FILE_PROJECT);
assertTrue(outProjFile.isFile());
Omegat outOmt = ProjectFileStorage.parseProjectFile(outProjFile);
assertEquals(ProjectFileStorage.normalizeSlashes(srcDir.getPath()), outOmt.getProject().getSourceDir());
assertEquals(ProjectFileStorage.normalizeSlashes(trgDir.getPath()), outOmt.getProject().getTargetDir());
assertEquals(ProjectFileStorage.normalizeSlashes(dictDir.getPath()), outOmt.getProject().getDictionaryDir());
assertEquals(ProjectFileStorage.normalizeSlashes(glosDir.getPath()), outOmt.getProject().getGlossaryDir());
assertEquals(ProjectFileStorage.normalizeSlashes(tmDir.getPath()), outOmt.getProject().getTmDir());
}
@Test
public void testFarRelativePaths() throws Exception {
File projFile = new File(PROJECT_DIR, "defaultdirs.project");
Omegat omt = ProjectFileStorage.parseProjectFile(projFile);
String prefix = repeat(OConsts.MAX_PARENT_DIRECTORIES_ABS2REL, "a/");
File projRoot = Paths.get(tempDir.getAbsolutePath(), prefix, "root").toFile();
projRoot.mkdirs();
// Set project folders to absolute paths
File srcDir = new File(tempDir, "source").getAbsoluteFile();
File trgDir = new File(tempDir, "target").getAbsoluteFile();
File dictDir = new File(tempDir, "dictionary").getAbsoluteFile();
File glosDir = new File(tempDir, "glossary").getAbsoluteFile();
File tmDir = new File(tempDir, "tm").getAbsoluteFile();
String relPrefix = repeat(OConsts.MAX_PARENT_DIRECTORIES_ABS2REL + 1, "../");
omt.getProject().setSourceDir(relPrefix + srcDir.getName());
omt.getProject().setTargetDir(relPrefix + trgDir.getName());
omt.getProject().setDictionaryDir(relPrefix + dictDir.getName());
omt.getProject().setGlossaryDir(relPrefix + glosDir.getName());
omt.getProject().setTmDir(relPrefix + tmDir.getName());
// Make all the actual folders
Arrays.asList(srcDir, trgDir, dictDir, glosDir, tmDir).forEach(File::mkdirs);
// Load the ProjectProperties and verify that the project folders
// are resolved correctly
ProjectProperties props = ProjectFileStorage.loadPropertiesFile(projRoot, omt);
props.verifyProject();
// Indirections should be resolved.
assertFalse(props.getSourceRoot().contains("../"));
assertFalse(props.getTargetRoot().contains("../"));
assertFalse(props.getDictRoot().contains("../"));
assertFalse(props.getGlossaryRoot().contains("../"));
assertFalse(props.getTMRoot().contains("../"));
// Write the project file out and read it again to make sure the
// paths are correctly round-tripped. Since these are "far" paths
// they should become absolute and not remain relative.
ProjectFileStorage.writeProjectFile(props);
File outProjFile = new File(projRoot, OConsts.FILE_PROJECT);
assertTrue(outProjFile.isFile());
Omegat outOmt = ProjectFileStorage.parseProjectFile(outProjFile);
assertEquals(ProjectFileStorage.normalizeSlashes(srcDir.getPath()), outOmt.getProject().getSourceDir());
assertEquals(ProjectFileStorage.normalizeSlashes(trgDir.getPath()), outOmt.getProject().getTargetDir());
assertEquals(ProjectFileStorage.normalizeSlashes(dictDir.getPath()), outOmt.getProject().getDictionaryDir());
assertEquals(ProjectFileStorage.normalizeSlashes(glosDir.getPath()), outOmt.getProject().getGlossaryDir());
assertEquals(ProjectFileStorage.normalizeSlashes(tmDir.getPath()), outOmt.getProject().getTmDir());
}
@Test
public void testMissingDirs() throws Exception {
// Older project files can be missing path definitions, in which case
// we should fall back to the default values.
File projFile = new File(PROJECT_DIR, "missingdirs.project");
ProjectProperties props = ProjectFileStorage.loadPropertiesFile(tempDir, projFile);
assertTrue(props.getSourceRoot().endsWith(OConsts.DEFAULT_SOURCE + '/'));
assertTrue(props.getTargetRoot().endsWith(OConsts.DEFAULT_TARGET + '/'));
assertTrue(props.getDictRoot().endsWith(OConsts.DEFAULT_DICT + '/'));
assertTrue(props.getGlossaryRoot().endsWith(OConsts.DEFAULT_GLOSSARY + '/'));
assertTrue(props.getTMRoot().endsWith(OConsts.DEFAULT_TM + '/'));
}
private static String repeat(int n, String s) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < n; i++) {
sb.append(s);
}
return sb.toString();
}
}