/* HeliDB -- A simple database for Java, http://www.helidb.org
* Copyright (C) 2008, 2009 Karl Gustafsson
*
* This file is a part of HeliDB.
*
* HeliDB 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.
*
* HeliDB 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.helidb.doc;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileManager;
import javax.tools.ToolProvider;
import org.entityfs.Directory;
import org.entityfs.support.exception.FileSystemException;
import org.entityfs.support.util.TwoObjects;
import org.entityfs.util.FileReadableFile;
import org.entityfs.util.FileSystems;
import org.entityfs.util.Files;
import org.entityfs.util.IteratorDeleter;
import org.entityfs.util.lang.EntityClassLoader;
import org.helidb.test.support.FileSupport;
import org.junit.Test;
public abstract class AbstractExamplesTest
{
private static final String METHOD_TEST_CODE_PREFIX = "public class HeliDBDocTest {";
private static final String METHOD_TEST_METHOD_PREFIX = "public Object runTest(Object[] args) throws Exception {";
private static final String METHOD_TEST_CODE_SUFFIX = "}}";
/*
* private static final String CLASS_TEST_CODE_PREFIX = "public class
* EFSDocTest {"; private static final String CLASS_TEST_CODE_SUFFIX = "}";
*/
private static final List<TwoObjects<String, String>> DEFAULT_REPLACES = new ArrayList<TwoObjects<String, String>>();
static
{
// Add replaces for HTML entities
DEFAULT_REPLACES.add(new TwoObjects<String, String>("<", "<"));
DEFAULT_REPLACES.add(new TwoObjects<String, String>(">", ">"));
DEFAULT_REPLACES.add(new TwoObjects<String, String>("&", "&"));
}
protected String escapeBackslashes(String s)
{
// Replace one backslash with four, needed when inserting backspaced
// strings into scripts. The rest is escaping...
return s.replaceAll("\\\\", "\\\\\\\\\\\\\\\\");
}
protected String runReplaces(String s, List<TwoObjects<String, String>> replaces)
{
if (replaces == null)
{
replaces = new ArrayList<TwoObjects<String, String>>();
}
replaces.addAll(0, DEFAULT_REPLACES);
for (TwoObjects<String, String> rep : replaces)
{
s = s.replaceAll("\\Q" + rep.getFirst() + "\\E", rep.getSecond());
}
return s;
}
protected void compileClass(String className, String s, Directory targetDir)
{
JavaCompiler jc = ToolProvider.getSystemJavaCompiler();
if (jc == null)
{
throw new FileSystemException("No java compiler in the current Java. This must be run on a JDK rather on a JRE");
}
JavaFileManager fm = new TestClassFileManager<JavaFileManager>(jc.getStandardFileManager(null, null, null), targetDir, Thread.currentThread().getContextClassLoader());
if (!jc.getTask(null, fm, null, null, null, Collections.singletonList(new JavaSourceFromString(className, s))).call().booleanValue())
{
System.out.println(s);
fail();
}
}
protected Object runExampleTest(String s, Object[] args, Directory targetDir) throws IOException
{
compileClass("HeliDBDocTest", s, targetDir);
ClassLoader cl = new EntityClassLoader(targetDir.getFileSystem().getLogAdapterHolder(), Thread.currentThread().getContextClassLoader(), Collections.singletonList(targetDir));
try
{
Class<?> c = cl.loadClass("HeliDBDocTest");
Object o = c.newInstance();
return c.getMethod("runTest", new Class[] { Object[].class }).invoke(o, new Object[] { args });
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
private Object runExampleTest(String s, Object[] args) throws IOException
{
File targetD = FileSupport.createTempDirectory();
Directory targetDir = FileSystems.getEntityForDirectory(targetD, false);
try
{
return runExampleTest(s, args, targetDir);
}
finally
{
new IteratorDeleter(targetDir).delete();
targetDir.getFileSystem().close();
assertTrue(targetD.delete());
}
}
protected File getDocFile(String path)
{
String docBasePath = System.getProperty("helidb.docBasePath");
if (docBasePath == null)
{
throw new RuntimeException("The system property helidb.docBasePath must be set to point to the root of the documentation *source* directory HeliDB_doc");
}
return new File(docBasePath + File.separator + path);
}
protected Object runExampleMethodTest(String testFile, String codePrefix, String codeSuffix, String otherCode, Object[] args, List<TwoObjects<String, String>> replaces, Directory targetDir) throws IOException
{
return runExampleTest(METHOD_TEST_CODE_PREFIX + (otherCode != null ? otherCode : "") + METHOD_TEST_METHOD_PREFIX + (codePrefix != null ? codePrefix : "") + runReplaces(Files.readTextFile(new FileReadableFile(getDocFile(testFile))), replaces) + (codeSuffix != null ? codeSuffix : "") + METHOD_TEST_CODE_SUFFIX, args, targetDir);
}
protected Object runExampleMethodTest(String testFile, String codePrefix, String codeSuffix, String otherCode, Object[] args, List<TwoObjects<String, String>> replaces) throws IOException
{
return runExampleTest(METHOD_TEST_CODE_PREFIX + (otherCode != null ? otherCode : "") + METHOD_TEST_METHOD_PREFIX + (codePrefix != null ? codePrefix : "") + runReplaces(Files.readTextFile(new FileReadableFile(getDocFile(testFile))), replaces) + (codeSuffix != null ? codeSuffix : "") + METHOD_TEST_CODE_SUFFIX, args);
}
@Test
public void testEscapeBackslashes()
{
assertEquals("\\\\\\\\", escapeBackslashes("\\"));
}
}