• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * 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, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  */
16 
17 package com.android.inputmethod.latin.dicttool;
18 
19 import com.android.inputmethod.latin.common.FileUtils;
20 import com.android.inputmethod.latin.makedict.BinaryDictDecoderEncoderTests;
21 import com.android.inputmethod.latin.makedict.BinaryDictEncoderFlattenTreeTests;
22 import com.android.inputmethod.latin.makedict.FusionDictionaryTest;
23 
24 import java.io.File;
25 import java.io.IOException;
26 import java.lang.reflect.Constructor;
27 import java.lang.reflect.InvocationTargetException;
28 import java.lang.reflect.Method;
29 import java.nio.file.Files;
30 import java.util.ArrayList;
31 
32 /**
33  * Dicttool command implementing self-tests.
34  */
35 public class Test extends Dicttool.Command {
getTmpDir()36     private static final String getTmpDir() {
37         try {
38             return Files.createTempDirectory("dicttool").toString();
39         } catch (IOException e) {
40             throw new RuntimeException("Can't get temporary directory", e);
41         }
42     }
43     private static final String TEST_TMP_DIR_BASE = getTmpDir();
44     public static final File TEST_TMP_DIR = new File(TEST_TMP_DIR_BASE);
45     public static final String COMMAND = "test";
46     private static final int DEFAULT_MAX_UNIGRAMS = 1500;
47     private long mSeed = System.currentTimeMillis();
48     private int mMaxUnigrams = DEFAULT_MAX_UNIGRAMS;
49 
50     private static final Class<?>[] sClassesToTest = {
51         BinaryDictOffdeviceUtilsTests.class,
52         FusionDictionaryTest.class,
53         BinaryDictDecoderEncoderTests.class,
54         BinaryDictEncoderFlattenTreeTests.class,
55     };
56     private ArrayList<Method> mAllTestMethods = new ArrayList<>();
57     private ArrayList<String> mUsedTestMethods = new ArrayList<>();
58 
Test()59     public Test() {
60         for (final Class<?> c : sClassesToTest) {
61             for (final Method m : c.getDeclaredMethods()) {
62                 if (m.getName().startsWith("test") && Void.TYPE == m.getReturnType()
63                         && 0 == m.getParameterTypes().length) {
64                     mAllTestMethods.add(m);
65                 }
66             }
67         }
68     }
69 
70     @Override
getHelp()71     public String getHelp() {
72         final StringBuilder s = new StringBuilder(
73                 "test [-s seed] [-m maxUnigrams] [-n] [testName...]\n"
74                 + "If seed is not specified, the current time is used.\n"
75                 + "If -n option is provided, do not delete temporary files in "
76                 + TEST_TMP_DIR_BASE + "/*.\n"
77                 + "Test list is:\n");
78         for (final Method m : mAllTestMethods) {
79             s.append("  ");
80             s.append(m.getName());
81             s.append("\n");
82         }
83         return s.toString();
84     }
85 
86     @Override
run()87     public void run() throws IllegalAccessException, InstantiationException,
88             InvocationTargetException {
89         int i = 0;
90         boolean deleteTmpDir = true;
91         while (i < mArgs.length) {
92             final String arg = mArgs[i++];
93             if ("-s".equals(arg)) {
94                 mSeed = Long.parseLong(mArgs[i++]);
95             } else if ("-m".equals(arg)) {
96                 mMaxUnigrams = Integer.parseInt(mArgs[i++]);
97             } else if ("-n".equals(arg)) {
98                 deleteTmpDir = false;
99             } else {
100                 mUsedTestMethods.add(arg);
101             }
102         }
103         try {
104             runChosenTests();
105         } finally {
106             if (deleteTmpDir) {
107                 FileUtils.deleteRecursively(TEST_TMP_DIR);
108             }
109         }
110     }
111 
runChosenTests()112     private void runChosenTests() throws IllegalAccessException, InstantiationException,
113             InvocationTargetException {
114         for (final Method m : mAllTestMethods) {
115             final Class<?> declaringClass = m.getDeclaringClass();
116             if (!mUsedTestMethods.isEmpty() && !mUsedTestMethods.contains(m.getName())) continue;
117             // Some of the test classes expose a two-argument constructor, taking a long as a
118             // seed for Random, and an int for a vocabulary size to test the dictionary with. They
119             // correspond respectively to the -s and -m numerical arguments to this command, which
120             // are stored in mSeed and mMaxUnigrams. If the two-arguments constructor is present,
121             // then invoke it; otherwise, invoke the default constructor.
122             Constructor<?> twoArgsConstructor = null;
123             try {
124                 twoArgsConstructor = declaringClass.getDeclaredConstructor(Long.TYPE, Integer.TYPE);
125             } catch (NoSuchMethodException e) {
126                 // No constructor with two args
127             }
128             final Object instance = null == twoArgsConstructor ? declaringClass.newInstance()
129                     : twoArgsConstructor.newInstance(mSeed, mMaxUnigrams);
130             m.invoke(instance);
131         }
132     }
133 }
134