19064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar/*
29064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar * Copyright (C) 2015 The Android Open Source Project
39064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar *
49064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar * Licensed under the Apache License, Version 2.0 (the "License");
59064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar * you may not use this file except in compliance with the License.
69064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar * You may obtain a copy of the License at
79064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar *
89064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar *      http://www.apache.org/licenses/LICENSE-2.0
99064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar *
109064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar * Unless required by applicable law or agreed to in writing, software
119064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar * distributed under the License is distributed on an "AS IS" BASIS,
129064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar * See the License for the specific language governing permissions and
149064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar * limitations under the License.
159064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar */
169064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar
179064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyarpackage android.databinding.compilationTest;
189064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar
199064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar
20ddeffcc2d89275528b2001836da2795b14ea7909Yigit Boyarimport org.apache.commons.io.FileUtils;
21ddeffcc2d89275528b2001836da2795b14ea7909Yigit Boyarimport org.apache.commons.io.filefilter.PrefixFileFilter;
22ddeffcc2d89275528b2001836da2795b14ea7909Yigit Boyarimport org.apache.commons.io.filefilter.SuffixFileFilter;
239064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyarimport org.apache.commons.lang3.StringUtils;
249064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyarimport org.junit.Test;
259064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar
26731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyarimport android.databinding.tool.processing.ErrorMessages;
27731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyarimport android.databinding.tool.processing.ScopedErrorReport;
28731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyarimport android.databinding.tool.processing.ScopedException;
29731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyarimport android.databinding.tool.store.Location;
30731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar
318b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyarimport java.io.File;
329064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyarimport java.io.IOException;
339064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyarimport java.net.URISyntaxException;
34ddeffcc2d89275528b2001836da2795b14ea7909Yigit Boyarimport java.util.Collection;
35731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyarimport java.util.List;
369064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar
379064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyarimport static org.junit.Assert.assertEquals;
389064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyarimport static org.junit.Assert.assertNotEquals;
39731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyarimport static org.junit.Assert.assertNotNull;
409064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyarimport static org.junit.Assert.assertTrue;
41731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyarimport static org.junit.Assert.fail;
429064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar
43fd8342a51a96282df315cd27055ba539e89a8c9eYigit Boyar@SuppressWarnings("ThrowableResultOfMethodCallIgnored")
449064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyarpublic class SimpleCompilationTest extends BaseCompilationTest {
459064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar
469064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar    @Test
479064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar    public void listTasks() throws IOException, URISyntaxException, InterruptedException {
489064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar        prepareProject();
499064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar        CompilationResult result = runGradle("tasks");
509064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar        assertEquals(0, result.resultCode);
519064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar        assertTrue("there should not be any errors", StringUtils.isEmpty(result.error));
529064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar        assertTrue("Test sanity, empty project tasks",
539064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar                result.resultContainsText("All tasks runnable from root project"));
549064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar    }
559064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar
569064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar    @Test
579064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar    public void testEmptyCompilation() throws IOException, URISyntaxException, InterruptedException {
589064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar        prepareProject();
599064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar        CompilationResult result = runGradle("assembleDebug");
6024bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar        assertEquals(result.error, 0, result.resultCode);
61ddeffcc2d89275528b2001836da2795b14ea7909Yigit Boyar        assertTrue("there should not be any errors " + result.error,
62ddeffcc2d89275528b2001836da2795b14ea7909Yigit Boyar                StringUtils.isEmpty(result.error));
639064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar        assertTrue("Test sanity, should compile fine",
649064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar                result.resultContainsText("BUILD SUCCESSFUL"));
659064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar    }
669064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar
67ddeffcc2d89275528b2001836da2795b14ea7909Yigit Boyar    @Test
68ddeffcc2d89275528b2001836da2795b14ea7909Yigit Boyar    public void testMultipleConfigs() throws IOException, URISyntaxException, InterruptedException {
69ddeffcc2d89275528b2001836da2795b14ea7909Yigit Boyar        prepareProject();
70ddeffcc2d89275528b2001836da2795b14ea7909Yigit Boyar        copyResourceTo("/layout/basic_layout.xml",
71ddeffcc2d89275528b2001836da2795b14ea7909Yigit Boyar                "/app/src/main/res/layout/main.xml");
72ddeffcc2d89275528b2001836da2795b14ea7909Yigit Boyar        copyResourceTo("/layout/basic_layout.xml",
73ddeffcc2d89275528b2001836da2795b14ea7909Yigit Boyar                "/app/src/main/res/layout-sw100dp/main.xml");
74ddeffcc2d89275528b2001836da2795b14ea7909Yigit Boyar        CompilationResult result = runGradle("assembleDebug");
75ddeffcc2d89275528b2001836da2795b14ea7909Yigit Boyar        assertEquals(result.error, 0, result.resultCode);
769784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar        File debugOut = new File(testFolder,
779784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar                "app/build/intermediates/data-binding-layout-out/debug");
78ddeffcc2d89275528b2001836da2795b14ea7909Yigit Boyar        Collection<File> layoutFiles = FileUtils.listFiles(debugOut, new SuffixFileFilter(".xml"),
79ddeffcc2d89275528b2001836da2795b14ea7909Yigit Boyar                new PrefixFileFilter("layout"));
80ddeffcc2d89275528b2001836da2795b14ea7909Yigit Boyar        assertTrue("test sanity", layoutFiles.size() > 1);
81ddeffcc2d89275528b2001836da2795b14ea7909Yigit Boyar        for (File layout : layoutFiles) {
829784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar            final String contents = FileUtils.readFileToString(layout);
83ddeffcc2d89275528b2001836da2795b14ea7909Yigit Boyar            if (layout.getParent().contains("sw100")) {
84ddeffcc2d89275528b2001836da2795b14ea7909Yigit Boyar                assertTrue("File has wrong tag:" + layout.getPath(),
859784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar                        contents.indexOf("android:tag=\"layout-sw100dp/main_0\"") > 0);
86ddeffcc2d89275528b2001836da2795b14ea7909Yigit Boyar            } else {
879784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar                assertTrue("File has wrong tag:" + layout.getPath() + "\n" + contents,
889784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar                        contents.indexOf("android:tag=\"layout/main_0\"")
89ddeffcc2d89275528b2001836da2795b14ea7909Yigit Boyar                                > 0);
90ddeffcc2d89275528b2001836da2795b14ea7909Yigit Boyar            }
91ddeffcc2d89275528b2001836da2795b14ea7909Yigit Boyar        }
92ddeffcc2d89275528b2001836da2795b14ea7909Yigit Boyar    }
93ddeffcc2d89275528b2001836da2795b14ea7909Yigit Boyar
94731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar    private ScopedException singleFileErrorTest(String resource, String targetFile,
95731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar            String expectedExtract, String errorMessage)
96731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar            throws IOException, URISyntaxException, InterruptedException {
97731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar        prepareProject();
98731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar        copyResourceTo(resource, targetFile);
99731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar        CompilationResult result = runGradle("assembleDebug");
100731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar        assertNotEquals(0, result.resultCode);
101731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar        ScopedException scopedException = result.getBindingException();
102aafbe5a2394ff9826201cca97d3298a9f355e311Yigit Boyar        assertNotNull(result.error, scopedException);
103731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar        ScopedErrorReport report = scopedException.getScopedErrorReport();
104731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar        assertNotNull(report);
105731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar        assertEquals(1, report.getLocations().size());
106731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar        Location loc = report.getLocations().get(0);
107731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar        if (expectedExtract != null) {
108731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar            String extract = extract(targetFile, loc);
109731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar            assertEquals(expectedExtract, extract);
110731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar        }
111731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar        final File errorFile = new File(report.getFilePath());
112731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar        assertTrue(errorFile.exists());
113731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar        assertEquals(new File(testFolder, targetFile).getCanonicalFile(),
114731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar                errorFile.getCanonicalFile());
115731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar        if (errorMessage != null) {
116731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar            assertEquals(errorMessage, scopedException.getBareMessage());
117731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar        }
118731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar        return scopedException;
119731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar    }
120731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar
1219064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar    @Test
122731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar    public void testMultipleExceptionsInDifferentFiles()
123731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar            throws IOException, URISyntaxException, InterruptedException {
1249064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar        prepareProject();
1253e3bf43a2e11fb433b43558e2e05255edfa5b6a8George Mount        copyResourceTo("/layout/undefined_variable_binding.xml",
1263e3bf43a2e11fb433b43558e2e05255edfa5b6a8George Mount                "/app/src/main/res/layout/broken.xml");
127731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar        copyResourceTo("/layout/invalid_setter_binding.xml",
128731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar                "/app/src/main/res/layout/invalid_setter.xml");
1299064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar        CompilationResult result = runGradle("assembleDebug");
13024bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar        assertNotEquals(result.output, 0, result.resultCode);
131731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar        List<ScopedException> bindingExceptions = result.getBindingExceptions();
13224bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar        assertEquals(result.error, 2, bindingExceptions.size());
133731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar        File broken = new File(testFolder, "/app/src/main/res/layout/broken.xml");
134731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar        File invalidSetter = new File(testFolder, "/app/src/main/res/layout/invalid_setter.xml");
135731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar        for (ScopedException exception : bindingExceptions) {
136731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar            ScopedErrorReport report = exception.getScopedErrorReport();
137731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar            final File errorFile = new File(report.getFilePath());
138731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar            String message = null;
139731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar            String expectedErrorFile = null;
140731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar            if (errorFile.getCanonicalPath().equals(broken.getCanonicalPath())) {
141731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar                message = String.format(ErrorMessages.UNDEFINED_VARIABLE, "myVariable");
142731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar                expectedErrorFile = "/app/src/main/res/layout/broken.xml";
143731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar            } else if (errorFile.getCanonicalPath().equals(invalidSetter.getCanonicalPath())) {
144731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar                message = String.format(ErrorMessages.CANNOT_FIND_SETTER_CALL, "android:textx",
145731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar                        String.class.getCanonicalName());
146731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar                expectedErrorFile = "/app/src/main/res/layout/invalid_setter.xml";
147731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar            } else {
148731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar                fail("unexpected exception " + exception.getBareMessage());
149731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar            }
150731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar            assertEquals(1, report.getLocations().size());
151731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar            Location loc = report.getLocations().get(0);
152731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar            String extract = extract(expectedErrorFile, loc);
153731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar            assertEquals("myVariable", extract);
154731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar            assertEquals(message, exception.getBareMessage());
155731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar        }
156731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar    }
157731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar
158731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar    @Test
159fd8342a51a96282df315cd27055ba539e89a8c9eYigit Boyar    public void testBadSyntax() throws IOException, URISyntaxException, InterruptedException {
160fd8342a51a96282df315cd27055ba539e89a8c9eYigit Boyar        singleFileErrorTest("/layout/layout_with_bad_syntax.xml",
161fd8342a51a96282df315cd27055ba539e89a8c9eYigit Boyar                "/app/src/main/res/layout/broken.xml",
162fd8342a51a96282df315cd27055ba539e89a8c9eYigit Boyar                "myVar.length())",
163fd8342a51a96282df315cd27055ba539e89a8c9eYigit Boyar                String.format(ErrorMessages.SYNTAX_ERROR,
164fd8342a51a96282df315cd27055ba539e89a8c9eYigit Boyar                        "extraneous input ')' expecting {<EOF>, ',', '.', '[', '+', '-', '*', '/', "
165fd8342a51a96282df315cd27055ba539e89a8c9eYigit Boyar                                + "'%', '<<', '>>>', '>>', '<=', '>=', '>', '<', 'instanceof', "
166fd8342a51a96282df315cd27055ba539e89a8c9eYigit Boyar                                + "'==', '!=', '&', '^', '|', '&&', '||', '?', '??'}"));
167fd8342a51a96282df315cd27055ba539e89a8c9eYigit Boyar    }
168fd8342a51a96282df315cd27055ba539e89a8c9eYigit Boyar
169fd8342a51a96282df315cd27055ba539e89a8c9eYigit Boyar    @Test
170fd8342a51a96282df315cd27055ba539e89a8c9eYigit Boyar    public void testBrokenSyntax() throws IOException, URISyntaxException, InterruptedException {
171fd8342a51a96282df315cd27055ba539e89a8c9eYigit Boyar        singleFileErrorTest("/layout/layout_with_completely_broken_syntax.xml",
172fd8342a51a96282df315cd27055ba539e89a8c9eYigit Boyar                "/app/src/main/res/layout/broken.xml",
173fd8342a51a96282df315cd27055ba539e89a8c9eYigit Boyar                "new String()",
174fd8342a51a96282df315cd27055ba539e89a8c9eYigit Boyar                String.format(ErrorMessages.SYNTAX_ERROR,
175fd8342a51a96282df315cd27055ba539e89a8c9eYigit Boyar                        "mismatched input 'String' expecting {<EOF>, ',', '.', '[', '+', '-', '*', "
176fd8342a51a96282df315cd27055ba539e89a8c9eYigit Boyar                                + "'/', '%', '<<', '>>>', '>>', '<=', '>=', '>', '<', 'instanceof',"
177fd8342a51a96282df315cd27055ba539e89a8c9eYigit Boyar                                + " '==', '!=', '&', '^', '|', '&&', '||', '?', '??'}"));
178fd8342a51a96282df315cd27055ba539e89a8c9eYigit Boyar    }
179fd8342a51a96282df315cd27055ba539e89a8c9eYigit Boyar
180fd8342a51a96282df315cd27055ba539e89a8c9eYigit Boyar    @Test
181731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar    public void testUndefinedVariable() throws IOException, URISyntaxException,
182731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar            InterruptedException {
183731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar        ScopedException ex = singleFileErrorTest("/layout/undefined_variable_binding.xml",
184731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar                "/app/src/main/res/layout/broken.xml", "myVariable",
185731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar                String.format(ErrorMessages.UNDEFINED_VARIABLE, "myVariable"));
186731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar    }
187731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar
188731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar    @Test
189731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar    public void testInvalidSetterBinding() throws IOException, URISyntaxException,
190731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar            InterruptedException {
191731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar        prepareProject();
192731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar        ScopedException ex = singleFileErrorTest("/layout/invalid_setter_binding.xml",
193731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar                "/app/src/main/res/layout/invalid_setter.xml", "myVariable",
194731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar                String.format(ErrorMessages.CANNOT_FIND_SETTER_CALL, "android:textx",
195731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar                        String.class.getCanonicalName()));
196731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar    }
197731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar
198731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar    @Test
19992a428505b9102bc0560d2d5be1768da097909c2George Mount    public void testRootTag() throws IOException, URISyntaxException,
20092a428505b9102bc0560d2d5be1768da097909c2George Mount            InterruptedException {
20192a428505b9102bc0560d2d5be1768da097909c2George Mount        prepareProject();
20292a428505b9102bc0560d2d5be1768da097909c2George Mount        copyResourceTo("/layout/root_tag.xml", "/app/src/main/res/layout/root_tag.xml");
20392a428505b9102bc0560d2d5be1768da097909c2George Mount        CompilationResult result = runGradle("assembleDebug");
20492a428505b9102bc0560d2d5be1768da097909c2George Mount        assertNotEquals(0, result.resultCode);
20592a428505b9102bc0560d2d5be1768da097909c2George Mount        assertNotNull(result.error);
20692a428505b9102bc0560d2d5be1768da097909c2George Mount        final String expected = String.format(ErrorMessages.ROOT_TAG_NOT_SUPPORTED, "hello");
20792a428505b9102bc0560d2d5be1768da097909c2George Mount        assertTrue(result.error.contains(expected));
20892a428505b9102bc0560d2d5be1768da097909c2George Mount    }
20992a428505b9102bc0560d2d5be1768da097909c2George Mount
21092a428505b9102bc0560d2d5be1768da097909c2George Mount    @Test
211731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar    public void testInvalidVariableType() throws IOException, URISyntaxException,
212731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar            InterruptedException {
213731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar        prepareProject();
214731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar        ScopedException ex = singleFileErrorTest("/layout/invalid_variable_type.xml",
215731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar                "/app/src/main/res/layout/invalid_variable.xml", "myVariable",
216731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar                String.format(ErrorMessages.CANNOT_RESOLVE_TYPE, "myVariable~"));
2179064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar    }
2188b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar
2198b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar    @Test
2208b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar    public void testSingleModule() throws IOException, URISyntaxException, InterruptedException {
2218b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar        prepareApp(toMap(KEY_DEPENDENCIES, "compile project(':module1')",
2228b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar                KEY_SETTINGS_INCLUDES, "include ':app'\ninclude ':module1'"));
2238b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar        prepareModule("module1", "com.example.module1", toMap());
2248b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar        copyResourceTo("/layout/basic_layout.xml", "/module1/src/main/res/layout/module_layout.xml");
2258b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar        copyResourceTo("/layout/basic_layout.xml", "/app/src/main/res/layout/app_layout.xml");
2268b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar        CompilationResult result = runGradle("assembleDebug");
2278b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar        assertEquals(result.error, 0, result.resultCode);
22889e50f43810ee32d8fc8ea359cd8e0ca4e9c8de4Yigit Boyar    }
22989e50f43810ee32d8fc8ea359cd8e0ca4e9c8de4Yigit Boyar
23089e50f43810ee32d8fc8ea359cd8e0ca4e9c8de4Yigit Boyar    @Test
23189e50f43810ee32d8fc8ea359cd8e0ca4e9c8de4Yigit Boyar    public void testModuleDependencyChange() throws IOException, URISyntaxException,
23289e50f43810ee32d8fc8ea359cd8e0ca4e9c8de4Yigit Boyar            InterruptedException {
23389e50f43810ee32d8fc8ea359cd8e0ca4e9c8de4Yigit Boyar        prepareApp(toMap(KEY_DEPENDENCIES, "compile project(':module1')",
23489e50f43810ee32d8fc8ea359cd8e0ca4e9c8de4Yigit Boyar                KEY_SETTINGS_INCLUDES, "include ':app'\ninclude ':module1'"));
23589e50f43810ee32d8fc8ea359cd8e0ca4e9c8de4Yigit Boyar        prepareModule("module1", "com.example.module1", toMap(
23689e50f43810ee32d8fc8ea359cd8e0ca4e9c8de4Yigit Boyar                KEY_DEPENDENCIES, "compile 'com.android.support:appcompat-v7:23.1.1'"
23789e50f43810ee32d8fc8ea359cd8e0ca4e9c8de4Yigit Boyar        ));
23889e50f43810ee32d8fc8ea359cd8e0ca4e9c8de4Yigit Boyar        copyResourceTo("/layout/basic_layout.xml", "/module1/src/main/res/layout/module_layout.xml");
23989e50f43810ee32d8fc8ea359cd8e0ca4e9c8de4Yigit Boyar        copyResourceTo("/layout/basic_layout.xml", "/app/src/main/res/layout/app_layout.xml");
24089e50f43810ee32d8fc8ea359cd8e0ca4e9c8de4Yigit Boyar        CompilationResult result = runGradle("assembleDebug");
24189e50f43810ee32d8fc8ea359cd8e0ca4e9c8de4Yigit Boyar        assertEquals(result.error, 0, result.resultCode);
24289e50f43810ee32d8fc8ea359cd8e0ca4e9c8de4Yigit Boyar        File moduleFolder = new File(testFolder, "module1");
24389e50f43810ee32d8fc8ea359cd8e0ca4e9c8de4Yigit Boyar        copyResourceTo("/module_build.gradle", new File(moduleFolder, "build.gradle"),
24489e50f43810ee32d8fc8ea359cd8e0ca4e9c8de4Yigit Boyar                toMap());
24589e50f43810ee32d8fc8ea359cd8e0ca4e9c8de4Yigit Boyar        result = runGradle("assembleDebug");
24689e50f43810ee32d8fc8ea359cd8e0ca4e9c8de4Yigit Boyar        assertEquals(result.error, 0, result.resultCode);
2478b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar    }
2488b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar
2498b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar    @Test
2508b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar    public void testTwoLevelDependency() throws IOException, URISyntaxException, InterruptedException {
2518b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar        prepareApp(toMap(KEY_DEPENDENCIES, "compile project(':module1')",
2528b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar                KEY_SETTINGS_INCLUDES, "include ':app'\ninclude ':module1'\n"
2538b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar                        + "include ':module2'"));
2548b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar        prepareModule("module1", "com.example.module1", toMap(KEY_DEPENDENCIES,
2558b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar                "compile project(':module2')"));
2568b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar        prepareModule("module2", "com.example.module2", toMap());
2573e3bf43a2e11fb433b43558e2e05255edfa5b6a8George Mount        copyResourceTo("/layout/basic_layout.xml",
2583e3bf43a2e11fb433b43558e2e05255edfa5b6a8George Mount                "/module2/src/main/res/layout/module2_layout.xml");
2598b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar        copyResourceTo("/layout/basic_layout.xml", "/module1/src/main/res/layout/module1_layout.xml");
2608b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar        copyResourceTo("/layout/basic_layout.xml", "/app/src/main/res/layout/app_layout.xml");
2618b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar        CompilationResult result = runGradle("assembleDebug");
2628b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar        assertEquals(result.error, 0, result.resultCode);
2638b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar    }
2643e3bf43a2e11fb433b43558e2e05255edfa5b6a8George Mount
2653e3bf43a2e11fb433b43558e2e05255edfa5b6a8George Mount    @Test
2663e3bf43a2e11fb433b43558e2e05255edfa5b6a8George Mount    public void testIncludeInMerge() throws Throwable {
2673e3bf43a2e11fb433b43558e2e05255edfa5b6a8George Mount        prepareProject();
2683e3bf43a2e11fb433b43558e2e05255edfa5b6a8George Mount        copyResourceTo("/layout/merge_include.xml", "/app/src/main/res/layout/merge_include.xml");
2693e3bf43a2e11fb433b43558e2e05255edfa5b6a8George Mount        CompilationResult result = runGradle("assembleDebug");
2703e3bf43a2e11fb433b43558e2e05255edfa5b6a8George Mount        assertNotEquals(0, result.resultCode);
271731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar        List<ScopedException> errors = ScopedException.extractErrors(result.error);
272731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar        assertEquals(result.error, 1, errors.size());
273731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar        final ScopedException ex = errors.get(0);
274731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar        final ScopedErrorReport report = ex.getScopedErrorReport();
275731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar        final File errorFile = new File(report.getFilePath());
276731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar        assertTrue(errorFile.exists());
277731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar        assertEquals(
278731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar                new File(testFolder, "/app/src/main/res/layout/merge_include.xml")
279731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar                        .getCanonicalFile(),
280731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar                errorFile.getCanonicalFile());
281731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar        assertEquals("Merge shouldn't support includes as root. Error message was '" + result.error,
282731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar                ErrorMessages.INCLUDE_INSIDE_MERGE, ex.getBareMessage());
2833e3bf43a2e11fb433b43558e2e05255edfa5b6a8George Mount    }
2849064a1dd60eb8c2f9d2ed705b36bb5f0b1629771Yigit Boyar}
285