SimpleCompilationTest.java revision 92a428505b9102bc0560d2d5be1768da097909c2
1/*
2 * Copyright (C) 2015 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 android.databinding.compilationTest;
18
19
20import org.apache.commons.lang3.StringUtils;
21import org.junit.Test;
22
23import android.databinding.tool.processing.ErrorMessages;
24import android.databinding.tool.processing.ScopedErrorReport;
25import android.databinding.tool.processing.ScopedException;
26import android.databinding.tool.store.Location;
27
28import java.io.File;
29import java.io.IOException;
30import java.net.URISyntaxException;
31import java.util.List;
32
33import static org.junit.Assert.assertEquals;
34import static org.junit.Assert.assertNotEquals;
35import static org.junit.Assert.assertNotNull;
36import static org.junit.Assert.assertTrue;
37import static org.junit.Assert.fail;
38
39public class SimpleCompilationTest extends BaseCompilationTest {
40
41    @Test
42    public void listTasks() throws IOException, URISyntaxException, InterruptedException {
43        prepareProject();
44        CompilationResult result = runGradle("tasks");
45        assertEquals(0, result.resultCode);
46        assertTrue("there should not be any errors", StringUtils.isEmpty(result.error));
47        assertTrue("Test sanity, empty project tasks",
48                result.resultContainsText("All tasks runnable from root project"));
49    }
50
51    @Test
52    public void testEmptyCompilation() throws IOException, URISyntaxException, InterruptedException {
53        prepareProject();
54        CompilationResult result = runGradle("assembleDebug");
55        assertEquals(result.error, 0, result.resultCode);
56        assertTrue("there should not be any errors " + result.error, StringUtils.isEmpty(result.error));
57        assertTrue("Test sanity, should compile fine",
58                result.resultContainsText("BUILD SUCCESSFUL"));
59    }
60
61    private ScopedException singleFileErrorTest(String resource, String targetFile,
62            String expectedExtract, String errorMessage)
63            throws IOException, URISyntaxException, InterruptedException {
64        prepareProject();
65        copyResourceTo(resource, targetFile);
66        CompilationResult result = runGradle("assembleDebug");
67        assertNotEquals(0, result.resultCode);
68        ScopedException scopedException = result.getBindingException();
69        assertNotNull(result.error, scopedException);
70        ScopedErrorReport report = scopedException.getScopedErrorReport();
71        assertNotNull(report);
72        assertEquals(1, report.getLocations().size());
73        Location loc = report.getLocations().get(0);
74        if (expectedExtract != null) {
75            String extract = extract(targetFile, loc);
76            assertEquals(expectedExtract, extract);
77        }
78        final File errorFile = new File(report.getFilePath());
79        assertTrue(errorFile.exists());
80        assertEquals(new File(testFolder, targetFile).getCanonicalFile(),
81                errorFile.getCanonicalFile());
82        if (errorMessage != null) {
83            assertEquals(errorMessage, scopedException.getBareMessage());
84        }
85        return scopedException;
86    }
87
88    @Test
89    public void testMultipleExceptionsInDifferentFiles()
90            throws IOException, URISyntaxException, InterruptedException {
91        prepareProject();
92        copyResourceTo("/layout/undefined_variable_binding.xml",
93                "/app/src/main/res/layout/broken.xml");
94        copyResourceTo("/layout/invalid_setter_binding.xml",
95                "/app/src/main/res/layout/invalid_setter.xml");
96        CompilationResult result = runGradle("assembleDebug");
97        assertNotEquals(result.output, 0, result.resultCode);
98        List<ScopedException> bindingExceptions = result.getBindingExceptions();
99        assertEquals(result.error, 2, bindingExceptions.size());
100        File broken = new File(testFolder, "/app/src/main/res/layout/broken.xml");
101        File invalidSetter = new File(testFolder, "/app/src/main/res/layout/invalid_setter.xml");
102        for (ScopedException exception : bindingExceptions) {
103            ScopedErrorReport report = exception.getScopedErrorReport();
104            final File errorFile = new File(report.getFilePath());
105            String message = null;
106            String expectedErrorFile = null;
107            if (errorFile.getCanonicalPath().equals(broken.getCanonicalPath())) {
108                message = String.format(ErrorMessages.UNDEFINED_VARIABLE, "myVariable");
109                expectedErrorFile = "/app/src/main/res/layout/broken.xml";
110            } else if (errorFile.getCanonicalPath().equals(invalidSetter.getCanonicalPath())) {
111                message = String.format(ErrorMessages.CANNOT_FIND_SETTER_CALL, "android:textx",
112                        String.class.getCanonicalName());
113                expectedErrorFile = "/app/src/main/res/layout/invalid_setter.xml";
114            } else {
115                fail("unexpected exception " + exception.getBareMessage());
116            }
117            assertEquals(1, report.getLocations().size());
118            Location loc = report.getLocations().get(0);
119            String extract = extract(expectedErrorFile, loc);
120            assertEquals("myVariable", extract);
121            assertEquals(message, exception.getBareMessage());
122        }
123    }
124
125    @Test
126    public void testUndefinedVariable() throws IOException, URISyntaxException,
127            InterruptedException {
128        ScopedException ex = singleFileErrorTest("/layout/undefined_variable_binding.xml",
129                "/app/src/main/res/layout/broken.xml", "myVariable",
130                String.format(ErrorMessages.UNDEFINED_VARIABLE, "myVariable"));
131    }
132
133    @Test
134    public void testInvalidSetterBinding() throws IOException, URISyntaxException,
135            InterruptedException {
136        prepareProject();
137        ScopedException ex = singleFileErrorTest("/layout/invalid_setter_binding.xml",
138                "/app/src/main/res/layout/invalid_setter.xml", "myVariable",
139                String.format(ErrorMessages.CANNOT_FIND_SETTER_CALL, "android:textx",
140                        String.class.getCanonicalName()));
141    }
142
143    @Test
144    public void testRootTag() throws IOException, URISyntaxException,
145            InterruptedException {
146        prepareProject();
147        copyResourceTo("/layout/root_tag.xml", "/app/src/main/res/layout/root_tag.xml");
148        CompilationResult result = runGradle("assembleDebug");
149        assertNotEquals(0, result.resultCode);
150        assertNotNull(result.error);
151        final String expected = String.format(ErrorMessages.ROOT_TAG_NOT_SUPPORTED, "hello");
152        assertTrue(result.error.contains(expected));
153    }
154
155    @Test
156    public void testInvalidVariableType() throws IOException, URISyntaxException,
157            InterruptedException {
158        prepareProject();
159        ScopedException ex = singleFileErrorTest("/layout/invalid_variable_type.xml",
160                "/app/src/main/res/layout/invalid_variable.xml", "myVariable",
161                String.format(ErrorMessages.CANNOT_RESOLVE_TYPE, "myVariable~"));
162    }
163
164    @Test
165    public void testSingleModule() throws IOException, URISyntaxException, InterruptedException {
166        prepareApp(toMap(KEY_DEPENDENCIES, "compile project(':module1')",
167                KEY_SETTINGS_INCLUDES, "include ':app'\ninclude ':module1'"));
168        prepareModule("module1", "com.example.module1", toMap());
169        copyResourceTo("/layout/basic_layout.xml", "/module1/src/main/res/layout/module_layout.xml");
170        copyResourceTo("/layout/basic_layout.xml", "/app/src/main/res/layout/app_layout.xml");
171        CompilationResult result = runGradle("assembleDebug");
172        assertEquals(result.error, 0, result.resultCode);
173    }
174
175    @Test
176    public void testTwoLevelDependency() throws IOException, URISyntaxException, InterruptedException {
177        prepareApp(toMap(KEY_DEPENDENCIES, "compile project(':module1')",
178                KEY_SETTINGS_INCLUDES, "include ':app'\ninclude ':module1'\n"
179                        + "include ':module2'"));
180        prepareModule("module1", "com.example.module1", toMap(KEY_DEPENDENCIES,
181                "compile project(':module2')"));
182        prepareModule("module2", "com.example.module2", toMap());
183        copyResourceTo("/layout/basic_layout.xml",
184                "/module2/src/main/res/layout/module2_layout.xml");
185        copyResourceTo("/layout/basic_layout.xml", "/module1/src/main/res/layout/module1_layout.xml");
186        copyResourceTo("/layout/basic_layout.xml", "/app/src/main/res/layout/app_layout.xml");
187        CompilationResult result = runGradle("assembleDebug");
188        assertEquals(result.error, 0, result.resultCode);
189    }
190
191    @Test
192    public void testIncludeInMerge() throws Throwable {
193        prepareProject();
194        copyResourceTo("/layout/merge_include.xml", "/app/src/main/res/layout/merge_include.xml");
195        CompilationResult result = runGradle("assembleDebug");
196        assertNotEquals(0, result.resultCode);
197        List<ScopedException> errors = ScopedException.extractErrors(result.error);
198        assertEquals(result.error, 1, errors.size());
199        final ScopedException ex = errors.get(0);
200        final ScopedErrorReport report = ex.getScopedErrorReport();
201        final File errorFile = new File(report.getFilePath());
202        assertTrue(errorFile.exists());
203        assertEquals(
204                new File(testFolder, "/app/src/main/res/layout/merge_include.xml")
205                        .getCanonicalFile(),
206                errorFile.getCanonicalFile());
207        assertEquals("Merge shouldn't support includes as root. Error message was '" + result.error,
208                ErrorMessages.INCLUDE_INSIDE_MERGE, ex.getBareMessage());
209    }
210}
211