1/*
2 * Copyright 2017 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
17package androidx.webkit.internal.codegen;
18
19import static org.junit.Assert.assertEquals;
20
21import androidx.webkit.internal.codegen.representations.ClassRepr;
22import androidx.webkit.internal.codegen.representations.MethodRepr;
23
24import com.android.tools.lint.LintCoreProjectEnvironment;
25
26import com.intellij.psi.PsiClass;
27import com.intellij.psi.PsiFile;
28import com.intellij.psi.PsiJavaFile;
29import com.squareup.javapoet.JavaFile;
30
31import org.junit.After;
32import org.junit.Before;
33import org.junit.Ignore;
34import org.junit.Test;
35import org.junit.runner.RunWith;
36import org.junit.runners.JUnit4;
37
38import java.util.Arrays;
39
40@RunWith(JUnit4.class)
41public class BoundaryInterfaceTest {
42    private LintCoreProjectEnvironment mProjectEnv;
43
44    @Before
45    public void setUp() throws Exception {
46        mProjectEnv = PsiProjectSetup.sProjectEnvironment;
47        // Add files required to resolve dependencies in the tests in this class. This is needed for
48        // example to identify a class as being an android.webkit class (and turn it into an
49        // InvocationHandler).
50        mProjectEnv.registerPaths(Arrays.asList(TestUtils.getTestDepsDir()));
51    }
52
53    @After
54    public void tearDown() throws Exception {
55    }
56
57    @Test
58    public void testSingleClassAndMethod() {
59        testBoundaryInterfaceGeneration("SingleClassAndMethod");
60    }
61
62    @Ignore
63    @Test public void testWebkitReturnTypeGeneratesInvocationHandler() {
64        testBoundaryInterfaceGeneration("WebKitTypeAsMethodParameter");
65    }
66
67    @Ignore
68    @Test public void testWebkitMethodParameterTypeGeneratesInvocationHandler() {
69        testBoundaryInterfaceGeneration("WebKitTypeAsMethodReturn");
70    }
71
72    /**
73     * Ensures methods are filtered correctly so only explicitly added methods are added to the
74     * boundary interface.
75     */
76    @Test public void testFilterMethods() {
77        PsiFile inputFile =
78                TestUtils.getTestFile(mProjectEnv.getProject(), "FilterMethods");
79        PsiClass psiClass = TestUtils.getSingleClassFromFile(inputFile);
80        MethodRepr method2 =
81                MethodRepr.fromPsiMethod(psiClass.findMethodsByName("method2", false)[0]);
82        ClassRepr classRepr = new ClassRepr(Arrays.asList(method2), psiClass);
83        JavaFile actualBoundaryInterface = BoundaryGeneration.createBoundaryInterface(classRepr);
84        assertBoundaryInterfaceCorrect(psiClass.getName(), actualBoundaryInterface);
85    }
86
87    // TODO(gsennton) add test case including a (static) inner class which should create a
88    // separate boundary interface file.
89
90    /**
91     * Generates a boundary interface from the test-file with name {@param className}.java, and
92     * compares the result to the test-file {@param className}BoundaryInterface.java.
93     */
94    private void testBoundaryInterfaceGeneration(String className) {
95        PsiFile inputFile = TestUtils.getTestFile(mProjectEnv.getProject(), className);
96        ClassRepr classRepr = ClassRepr.fromPsiClass(TestUtils.getSingleClassFromFile(inputFile));
97
98        JavaFile actualBoundaryInterface = BoundaryGeneration.createBoundaryInterface(classRepr);
99        assertBoundaryInterfaceCorrect(className, actualBoundaryInterface);
100    }
101
102    private void assertBoundaryInterfaceCorrect(String className,
103            JavaFile actualBoundaryInterface) {
104        PsiJavaFile expectedBoundaryFile = TestUtils.getExpectedTestFile(mProjectEnv.getProject(),
105                className + "BoundaryInterface");
106        assertEquals(expectedBoundaryFile.getText(), actualBoundaryInterface.toString());
107    }
108}
109