Home | History | Annotate | Download | only in monkeyrunner
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package com.android.monkeyrunner;
     17 
     18 import com.google.common.base.Preconditions;
     19 import com.google.common.collect.Maps;
     20 
     21 import com.android.monkeyrunner.doc.MonkeyRunnerExported;
     22 
     23 import junit.framework.TestCase;
     24 
     25 import org.python.core.ArgParser;
     26 import org.python.core.ClassDictInit;
     27 import org.python.core.PyDictionary;
     28 import org.python.core.PyException;
     29 import org.python.core.PyObject;
     30 import org.python.core.PyString;
     31 
     32 import java.util.List;
     33 import java.util.Map;
     34 import java.util.Set;
     35 
     36 /**
     37  * Unit tests for the JythonUtils class.
     38  */
     39 public class JythonUtilsTest extends TestCase {
     40     private static final String PACKAGE_NAME = JythonUtilsTest.class.getPackage().getName();
     41     private static final String CLASS_NAME = JythonUtilsTest.class.getSimpleName();
     42     private static final String EXECUTABLE_PATH = "string";
     43 
     44     private static boolean called = false;
     45     private static double floatValue = 0.0;
     46     private static List<Object> listValue = null;
     47     private static Map<String, Object> mapValue;
     48 
     49     @MonkeyRunnerExported(doc = "", args = {"value"})
     50     public static void floatTest(PyObject[] args, String[] kws) {
     51         ArgParser ap = JythonUtils.createArgParser(args, kws);
     52         Preconditions.checkNotNull(ap);
     53         called = true;
     54 
     55         floatValue = JythonUtils.getFloat(ap, 0);
     56     }
     57 
     58     @MonkeyRunnerExported(doc = "", args = {"value"})
     59     public static void listTest(PyObject[] args, String[] kws) {
     60         ArgParser ap = JythonUtils.createArgParser(args, kws);
     61         Preconditions.checkNotNull(ap);
     62         called = true;
     63 
     64         listValue = JythonUtils.getList(ap, 0);
     65     }
     66 
     67     @MonkeyRunnerExported(doc = "", args = {"value"})
     68     public static void mapTest(PyObject[] args, String[] kws) {
     69         ArgParser ap = JythonUtils.createArgParser(args, kws);
     70         Preconditions.checkNotNull(ap);
     71         called = true;
     72 
     73         mapValue = JythonUtils.getMap(ap, 0);
     74     }
     75 
     76     @MonkeyRunnerExported(doc = "")
     77     public static PyDictionary convertMapTest(PyObject[] args, String[] kws) {
     78         Map<String, Object> map = Maps.newHashMap();
     79         map.put("string", "value");
     80         map.put("integer", 1);
     81         map.put("double", 3.14);
     82         return JythonUtils.convertMapToDict(map);
     83     }
     84 
     85     @Override
     86     protected void setUp() throws Exception {
     87         called = false;
     88         floatValue = 0.0;
     89     }
     90 
     91     private static PyObject call(String method) {
     92         return call(method, new String[]{ });
     93     }
     94     private static PyObject call(String method, String... args) {
     95         StringBuilder sb = new StringBuilder();
     96         sb.append("from ").append(PACKAGE_NAME);
     97         sb.append(" import ").append(CLASS_NAME).append("\n");
     98 
     99         // Exec line
    100         sb.append("result = ");
    101         sb.append(CLASS_NAME).append(".").append(method);
    102         sb.append("(");
    103         for (String arg : args) {
    104             sb.append(arg).append(",");
    105         }
    106         sb.append(")");
    107 
    108         return ScriptRunner.runStringAndGet(EXECUTABLE_PATH, sb.toString(), "result").get("result");
    109     }
    110 
    111     public void testSimpleCall() {
    112         call("floatTest", "0.0");
    113         assertTrue(called);
    114     }
    115 
    116     public void testMissingFloatArg() {
    117         try {
    118             call("floatTest");
    119         } catch(PyException e) {
    120             return;
    121         }
    122         fail("Should have thrown exception");
    123     }
    124 
    125     public void testBadFloatArgType() {
    126         try {
    127             call("floatTest", "\'foo\'");
    128         } catch(PyException e) {
    129             return;
    130         }
    131         fail("Should have thrown exception");
    132     }
    133 
    134     public void testFloatParse() {
    135         call("floatTest", "103.2");
    136         assertTrue(called);
    137         assertEquals(floatValue, 103.2);
    138     }
    139 
    140     public void testFloatParseInteger() {
    141         call("floatTest", "103");
    142         assertTrue(called);
    143         assertEquals(floatValue, 103.0);
    144     }
    145 
    146     public void testParseStringList() {
    147         call("listTest", "['a', 'b', 'c']");
    148         assertTrue(called);
    149         assertEquals(3, listValue.size());
    150         assertEquals("a", listValue.get(0));
    151         assertEquals("b", listValue.get(1));
    152         assertEquals("c", listValue.get(2));
    153     }
    154 
    155     public void testParseIntList() {
    156         call("listTest", "[1, 2, 3]");
    157         assertTrue(called);
    158         assertEquals(3, listValue.size());
    159         assertEquals(new Integer(1), listValue.get(0));
    160         assertEquals(new Integer(2), listValue.get(1));
    161         assertEquals(new Integer(3), listValue.get(2));
    162     }
    163 
    164     public void testParseMixedList() {
    165         call("listTest", "['a', 1, 3.14]");
    166         assertTrue(called);
    167         assertEquals(3, listValue.size());
    168         assertEquals("a", listValue.get(0));
    169         assertEquals(new Integer(1), listValue.get(1));
    170         assertEquals(new Double(3.14), listValue.get(2));
    171     }
    172 
    173     public void testParseOptionalList() {
    174         call("listTest");
    175         assertTrue(called);
    176         assertEquals(0, listValue.size());
    177     }
    178 
    179     public void testParsingNotAList() {
    180         try {
    181             call("listTest", "1.0");
    182         } catch (PyException e) {
    183             return;
    184         }
    185         fail("Should have thrown an exception");
    186     }
    187 
    188     public void testParseMap() {
    189         call("mapTest", "{'a': 0, 'b': 'bee', 3: 'cee'}");
    190         assertTrue(called);
    191         assertEquals(3, mapValue.size());
    192         assertEquals(new Integer(0), mapValue.get("a"));
    193         assertEquals("bee", mapValue.get("b"));
    194         // note: coerced key type
    195         assertEquals("cee", mapValue.get("3"));
    196     }
    197 
    198     public void testParsingNotAMap() {
    199         try {
    200             call("mapTest", "1.0");
    201         } catch (PyException e) {
    202             return;
    203         }
    204         fail("Should have thrown an exception");
    205     }
    206 
    207     public void testParseOptionalMap() {
    208         call("mapTest");
    209         assertTrue(called);
    210         assertEquals(0, mapValue.size());
    211     }
    212 
    213     public void testConvertMap() {
    214         PyDictionary result = (PyDictionary) call("convertMapTest");
    215         PyObject stringPyObject = result.__getitem__(new PyString("string"));
    216         String string = (String) stringPyObject.__tojava__(String.class);
    217         assertEquals("value", string);
    218 
    219         PyObject intPyObject = result.__getitem__(new PyString("integer"));
    220         int i = (Integer) intPyObject.__tojava__(Integer.class);
    221         assertEquals(i, 1);
    222 
    223         PyObject doublePyObject = result.__getitem__(new PyString("double"));
    224         double d = (Double) doublePyObject.__tojava__(Double.class);
    225         assertEquals(3.14, d);
    226     }
    227 
    228     /**
    229      * Base class to test overridden methods.
    230      */
    231     static class PythonMethodsClass extends PyObject implements ClassDictInit {
    232         public static void classDictInit(PyObject dict) {
    233             JythonUtils.convertDocAnnotationsForClass(PythonMethodsClass.class, dict);
    234         }
    235 
    236         @MonkeyRunnerExported(doc = "The first method.")
    237         public void firstMethod(PyObject[] args, String[] kws) {
    238         }
    239 
    240         @MonkeyRunnerExported(doc = "The second method.")
    241         public void secondMethod(PyObject[] args, String[] kws) {
    242         }
    243 
    244         public void unattributedMethod() {
    245         }
    246     }
    247 
    248     public void testGetPythonMethods() {
    249         Set<String> methods = JythonUtils.getMethodNames(PythonMethodsClass.class);
    250         assertEquals(2, methods.size());
    251         assertTrue(methods.contains("firstMethod"));
    252         assertTrue(methods.contains("secondMethod"));
    253 
    254         // Make sure it works on non-Jython objects.
    255         assertTrue(JythonUtils.getMethodNames(String.class).isEmpty());
    256     }
    257 }
    258