Merge "Change help test generation to use clearsilver templates just like the rest of the system. This should more easily allow customization of the generated output."
This commit is contained in:
@@ -22,30 +22,11 @@ LOCAL_JAR_MANIFEST := ../etc/manifest.txt
|
|||||||
LOCAL_JAVA_LIBRARIES := \
|
LOCAL_JAVA_LIBRARIES := \
|
||||||
ddmlib \
|
ddmlib \
|
||||||
jython \
|
jython \
|
||||||
xmlwriter \
|
guavalib \
|
||||||
guavalib
|
clearsilver
|
||||||
|
LOCAL_SHARED_LIBRARIES := libclearsilver-jni
|
||||||
|
LOCAL_JAVA_RESOURCE_DIRS := resources
|
||||||
|
|
||||||
LOCAL_MODULE := monkeyrunner
|
LOCAL_MODULE := monkeyrunner
|
||||||
|
|
||||||
include $(BUILD_HOST_JAVA_LIBRARY)
|
include $(BUILD_HOST_JAVA_LIBRARY)
|
||||||
|
|
||||||
# Build ext.jar
|
|
||||||
# ============================================================
|
|
||||||
|
|
||||||
ext_dirs := ../../../../external/xmlwriter/src
|
|
||||||
|
|
||||||
ext_src_files := $(call all-java-files-under,$(ext_dirs))
|
|
||||||
|
|
||||||
# ==== the library =========================================
|
|
||||||
include $(CLEAR_VARS)
|
|
||||||
|
|
||||||
LOCAL_SRC_FILES := $(ext_src_files)
|
|
||||||
|
|
||||||
LOCAL_NO_STANDARD_LIBRARIES := true
|
|
||||||
#LOCAL_JAVA_LIBRARIES := core
|
|
||||||
#LOCAL_STATIC_JAVA_LIBRARIES := libgoogleclient
|
|
||||||
|
|
||||||
LOCAL_MODULE := xmlwriter
|
|
||||||
|
|
||||||
include $(BUILD_HOST_JAVA_LIBRARY)
|
|
||||||
|
|||||||
@@ -198,8 +198,10 @@ public abstract class MonkeyImage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@MonkeyRunnerExported(doc = "Compare this image to the other image.",
|
@MonkeyRunnerExported(doc = "Compare this image to the other image.",
|
||||||
args = {"other"},
|
args = {"other", "percent"},
|
||||||
argDocs = {"The other image."},
|
argDocs = {"The other image.",
|
||||||
|
"A float from 0.0 to 1.0 indicating the percentage " +
|
||||||
|
"of pixels that need to be the same. Defaults to 1.0"},
|
||||||
returns = "True if they are the same image.")
|
returns = "True if they are the same image.")
|
||||||
public boolean sameAs(PyObject[] args, String[] kws) {
|
public boolean sameAs(PyObject[] args, String[] kws) {
|
||||||
ArgParser ap = JythonUtils.createArgParser(args, kws);
|
ArgParser ap = JythonUtils.createArgParser(args, kws);
|
||||||
@@ -208,6 +210,8 @@ public abstract class MonkeyImage {
|
|||||||
PyObject otherObject = ap.getPyObject(0);
|
PyObject otherObject = ap.getPyObject(0);
|
||||||
MonkeyImage other = (MonkeyImage) otherObject.__tojava__(MonkeyImage.class);
|
MonkeyImage other = (MonkeyImage) otherObject.__tojava__(MonkeyImage.class);
|
||||||
|
|
||||||
|
double percent = JythonUtils.getFloat(ap, 1, 1.0);
|
||||||
|
|
||||||
BufferedImage otherImage = other.getBufferedImage();
|
BufferedImage otherImage = other.getBufferedImage();
|
||||||
BufferedImage myImage = getBufferedImage();
|
BufferedImage myImage = getBufferedImage();
|
||||||
|
|
||||||
@@ -222,15 +226,21 @@ public abstract class MonkeyImage {
|
|||||||
int[] otherPixel = new int[1];
|
int[] otherPixel = new int[1];
|
||||||
int[] myPixel = new int[1];
|
int[] myPixel = new int[1];
|
||||||
|
|
||||||
|
int width = myImage.getWidth();
|
||||||
|
int height = myImage.getHeight();
|
||||||
|
|
||||||
|
int numDiffPixels = 0;
|
||||||
// Now, go through pixel-by-pixel and check that the images are the same;
|
// Now, go through pixel-by-pixel and check that the images are the same;
|
||||||
for (int y = 0; y < myImage.getHeight(); y++) {
|
for (int y = 0; y < height; y++) {
|
||||||
for (int x = 0; x < myImage.getWidth(); x++) {
|
for (int x = 0; x < width; x++) {
|
||||||
if (myImage.getRGB(x, y) != otherImage.getRGB(x, y)) {
|
if (myImage.getRGB(x, y) != otherImage.getRGB(x, y)) {
|
||||||
return false;
|
numDiffPixels++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
double numberPixels = (height * width);
|
||||||
|
double diffPercent = numDiffPixels / numberPixels;
|
||||||
|
return percent <= 1.0 - diffPercent;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class BufferedImageMonkeyImage extends MonkeyImage {
|
private static class BufferedImageMonkeyImage extends MonkeyImage {
|
||||||
|
|||||||
@@ -90,12 +90,16 @@ public class MonkeyRunner {
|
|||||||
|
|
||||||
@MonkeyRunnerExported(doc = "Simple help command to dump the MonkeyRunner supported " +
|
@MonkeyRunnerExported(doc = "Simple help command to dump the MonkeyRunner supported " +
|
||||||
"commands",
|
"commands",
|
||||||
|
args = { "format" },
|
||||||
|
argDocs = {"The format to return the help text in. (default is text)"},
|
||||||
returns = "The help text")
|
returns = "The help text")
|
||||||
public static String help(PyObject[] args, String[] kws) {
|
public static String help(PyObject[] args, String[] kws) {
|
||||||
ArgParser ap = JythonUtils.createArgParser(args, kws);
|
ArgParser ap = JythonUtils.createArgParser(args, kws);
|
||||||
Preconditions.checkNotNull(ap);
|
Preconditions.checkNotNull(ap);
|
||||||
|
|
||||||
return MonkeyRunnerHelp.helpString();
|
String format = ap.getString(0, "text");
|
||||||
|
|
||||||
|
return MonkeyRunnerHelp.helpString(format);
|
||||||
}
|
}
|
||||||
|
|
||||||
@MonkeyRunnerExported(doc = "Put up an alert dialog to inform the user of something that " +
|
@MonkeyRunnerExported(doc = "Put up an alert dialog to inform the user of something that " +
|
||||||
|
|||||||
@@ -19,15 +19,20 @@ import com.google.common.base.Predicate;
|
|||||||
import com.google.common.collect.Collections2;
|
import com.google.common.collect.Collections2;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
import com.google.common.io.Resources;
|
||||||
|
|
||||||
import com.android.monkeyrunner.doc.MonkeyRunnerExported;
|
import com.android.monkeyrunner.doc.MonkeyRunnerExported;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import org.clearsilver.CS;
|
||||||
import java.io.PrintStream;
|
import org.clearsilver.CSFileLoader;
|
||||||
|
import org.clearsilver.HDF;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Member;
|
import java.lang.reflect.Member;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -39,6 +44,18 @@ import java.util.Set;
|
|||||||
public final class MonkeyRunnerHelp {
|
public final class MonkeyRunnerHelp {
|
||||||
private MonkeyRunnerHelp() { }
|
private MonkeyRunnerHelp() { }
|
||||||
|
|
||||||
|
private static final String HELP = "help";
|
||||||
|
private static final String NAME = "name";
|
||||||
|
private static final String DOC = "doc";
|
||||||
|
private static final String ARGUMENT = "argument";
|
||||||
|
private static final String RETURNS = "returns";
|
||||||
|
private static final String TYPE = "type";
|
||||||
|
|
||||||
|
// Enum used to describe documented types.
|
||||||
|
private enum Type {
|
||||||
|
ENUM, FIELD, METHOD
|
||||||
|
}
|
||||||
|
|
||||||
private static void getAllExportedClasses(Set<Field> fields,
|
private static void getAllExportedClasses(Set<Field> fields,
|
||||||
Set<Method> methods,
|
Set<Method> methods,
|
||||||
Set<Constructor<?>> constructors,
|
Set<Constructor<?>> constructors,
|
||||||
@@ -120,13 +137,35 @@ public final class MonkeyRunnerHelp {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static String helpString() {
|
public static String helpString(String format) {
|
||||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
// Quick check for support formats
|
||||||
help(new PrintStream(os, true));
|
if ("html".equals(format) || "text".equals(format)) {
|
||||||
return os.toString();
|
HDF hdf = buildHelpHdf();
|
||||||
|
CS clearsilver = new CS(hdf);
|
||||||
|
// Set a custom file loader to load requested files from resources relative to this class.
|
||||||
|
clearsilver.setFileLoader(new CSFileLoader() {
|
||||||
|
public String load(HDF hdf, String filename) throws IOException {
|
||||||
|
return Resources.toString(Resources.getResource(MonkeyRunnerHelp.class, filename),
|
||||||
|
Charset.defaultCharset());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Load up the CS template file
|
||||||
|
clearsilver.parseFile(format.toLowerCase() + ".cs");
|
||||||
|
// And render the output
|
||||||
|
return clearsilver.render();
|
||||||
|
} else if ("hdf".equals(format)) {
|
||||||
|
HDF hdf = buildHelpHdf();
|
||||||
|
return hdf.writeString();
|
||||||
|
}
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void help(PrintStream out) {
|
private static HDF buildHelpHdf() {
|
||||||
|
HDF hdf = new HDF();
|
||||||
|
|
||||||
|
int outputItemCount = 0;
|
||||||
|
|
||||||
Set<Field> fields = Sets.newTreeSet(MEMBER_SORTER);
|
Set<Field> fields = Sets.newTreeSet(MEMBER_SORTER);
|
||||||
Set<Method> methods = Sets.newTreeSet(MEMBER_SORTER);
|
Set<Method> methods = Sets.newTreeSet(MEMBER_SORTER);
|
||||||
Set<Constructor<?>> constructors = Sets.newTreeSet(MEMBER_SORTER);
|
Set<Constructor<?>> constructors = Sets.newTreeSet(MEMBER_SORTER);
|
||||||
@@ -134,51 +173,54 @@ public final class MonkeyRunnerHelp {
|
|||||||
getAllExportedClasses(fields, methods, constructors, classes);
|
getAllExportedClasses(fields, methods, constructors, classes);
|
||||||
|
|
||||||
for (Class<?> clz : classes) {
|
for (Class<?> clz : classes) {
|
||||||
out.println(clz.getCanonicalName() + ":");
|
String prefix = HELP + "." + outputItemCount + ".";
|
||||||
|
|
||||||
|
hdf.setValue(prefix + NAME, clz.getCanonicalName());
|
||||||
MonkeyRunnerExported annotation = clz.getAnnotation(MonkeyRunnerExported.class);
|
MonkeyRunnerExported annotation = clz.getAnnotation(MonkeyRunnerExported.class);
|
||||||
out.println(" " + annotation.doc());
|
hdf.setValue(prefix + DOC, annotation.doc());
|
||||||
|
hdf.setValue(prefix + TYPE, Type.ENUM.name());
|
||||||
|
|
||||||
|
// Now go through the enumeration constants
|
||||||
Object[] constants = clz.getEnumConstants();
|
Object[] constants = clz.getEnumConstants();
|
||||||
String[] argDocs = annotation.argDocs();
|
String[] argDocs = annotation.argDocs();
|
||||||
if (constants.length > 0) {
|
if (constants.length > 0) {
|
||||||
out.println(" Values:");
|
|
||||||
for (int x = 0; x < constants.length; x++) {
|
for (int x = 0; x < constants.length; x++) {
|
||||||
Object constant = constants[x];
|
String argPrefix = prefix + ARGUMENT + "." + x + ".";
|
||||||
StringBuilder sb = new StringBuilder();
|
hdf.setValue(argPrefix + NAME, constants[x].toString());
|
||||||
sb.append(" ").append(constant);
|
|
||||||
if (argDocs.length > x) {
|
if (argDocs.length > x) {
|
||||||
sb.append(" - ").append(argDocs[x]);
|
hdf.setValue(argPrefix + DOC, argDocs[x]);
|
||||||
}
|
}
|
||||||
|
|
||||||
out.println(sb.toString());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out.println();
|
outputItemCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Method m : methods) {
|
for (Method m : methods) {
|
||||||
|
String prefix = HELP + "." + outputItemCount + ".";
|
||||||
|
|
||||||
MonkeyRunnerExported annotation = m.getAnnotation(MonkeyRunnerExported.class);
|
MonkeyRunnerExported annotation = m.getAnnotation(MonkeyRunnerExported.class);
|
||||||
String className = m.getDeclaringClass().getCanonicalName();
|
String className = m.getDeclaringClass().getCanonicalName();
|
||||||
String methodName = className + "." + m.getName();
|
String methodName = className + "." + m.getName();
|
||||||
out.println(methodName + ":");
|
hdf.setValue(prefix + NAME, methodName);
|
||||||
out.println(" " + annotation.doc());
|
hdf.setValue(prefix + DOC, annotation.doc());
|
||||||
if (annotation.args().length > 0) {
|
if (annotation.args().length > 0) {
|
||||||
out.println(" Args:");
|
|
||||||
String[] argDocs = annotation.argDocs();
|
String[] argDocs = annotation.argDocs();
|
||||||
String[] aargs = annotation.args();
|
String[] aargs = annotation.args();
|
||||||
for (int x = 0; x < aargs.length; x++) {
|
for (int x = 0; x < aargs.length; x++) {
|
||||||
StringBuilder sb = new StringBuilder();
|
String argPrefix = prefix + ARGUMENT + "." + x + ".";
|
||||||
sb.append(" ").append(aargs[x]);
|
|
||||||
|
hdf.setValue(argPrefix + NAME, aargs[x]);
|
||||||
if (argDocs.length > x) {
|
if (argDocs.length > x) {
|
||||||
sb.append(" - ").append(argDocs[x]);
|
hdf.setValue(argPrefix + DOC, argDocs[x]);
|
||||||
}
|
}
|
||||||
out.println(sb.toString());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!"".equals(annotation.returns())) {
|
if (!"".equals(annotation.returns())) {
|
||||||
out.println(" Returns:");
|
hdf.setValue(prefix + RETURNS, annotation.returns());
|
||||||
out.println(" " + annotation.returns());
|
|
||||||
}
|
}
|
||||||
out.println();
|
outputItemCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return hdf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import org.python.core.Py;
|
|||||||
import org.python.core.PyException;
|
import org.python.core.PyException;
|
||||||
import org.python.core.PyObject;
|
import org.python.core.PyObject;
|
||||||
import org.python.util.InteractiveConsole;
|
import org.python.util.InteractiveConsole;
|
||||||
|
import org.python.util.JLineConsole;
|
||||||
import org.python.util.PythonInterpreter;
|
import org.python.util.PythonInterpreter;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -170,7 +171,7 @@ public class ScriptRunner {
|
|||||||
*/
|
*/
|
||||||
public static void console() {
|
public static void console() {
|
||||||
initPython();
|
initPython();
|
||||||
InteractiveConsole python = new InteractiveConsole();
|
InteractiveConsole python = new JLineConsole();
|
||||||
python.interact();
|
python.interact();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<h1>MonkeyRunner Help<h1>
|
||||||
|
<h2>Table of Contents</h2>
|
||||||
|
<ul>
|
||||||
|
<?cs each:item = help ?>
|
||||||
|
<li><a href="#<?cs name:item ?>"><?cs var:item.name ?></a></li>
|
||||||
|
<?cs /each ?>
|
||||||
|
</ul>
|
||||||
|
<?cs each:item = help ?>
|
||||||
|
<h2><a name="<?cs name:item ?>"><?cs var:item.name ?></a></h2>
|
||||||
|
<p><?cs var:item.doc ?></p>
|
||||||
|
<?cs if:subcount(item.argument) ?>
|
||||||
|
<h3>Args</h3>
|
||||||
|
<ul>
|
||||||
|
<?cs each:arg = item.argument ?>
|
||||||
|
<li><?cs var:arg.name ?> - <?cs var:arg.doc ?></li>
|
||||||
|
<?cs /each ?>
|
||||||
|
</ul>
|
||||||
|
<?cs /if ?>
|
||||||
|
<?cs /each ?>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
MonkeyRunner help
|
||||||
|
<?cs each:item = help ?>
|
||||||
|
<?cs var:item.name ?>
|
||||||
|
<?cs var:item.doc ?>
|
||||||
|
|
||||||
|
<?cs if:subcount(item.argument) ?> Args:<?cs each:arg = item.argument ?>
|
||||||
|
<?cs var:arg.name ?> - <?cs var:arg.doc ?><?cs /each ?>
|
||||||
|
<?cs /if ?><?cs /each ?>
|
||||||
Reference in New Issue
Block a user