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 19import org.junit.Test; 20 21import android.databinding.tool.processing.ErrorMessages; 22import android.databinding.tool.processing.ScopedErrorReport; 23import android.databinding.tool.processing.ScopedException; 24import android.databinding.tool.store.Location; 25 26import java.io.File; 27import java.io.IOException; 28import java.net.URISyntaxException; 29import java.util.List; 30 31import static org.junit.Assert.assertEquals; 32import static org.junit.Assert.assertNotEquals; 33import static org.junit.Assert.assertNotNull; 34import static org.junit.Assert.assertTrue; 35import static org.junit.Assert.fail; 36 37public class MultiLayoutVerificationTest extends BaseCompilationTest { 38 @Test 39 public void testMultipleLayoutFilesWithNameMismatch() 40 throws IOException, URISyntaxException, InterruptedException { 41 prepareProject(); 42 copyResourceTo("/layout/layout_with_class_name.xml", 43 "/app/src/main/res/layout/with_class_name.xml", toMap(KEY_CLASS_NAME, 44 "AClassName")); 45 copyResourceTo("/layout/layout_with_class_name.xml", 46 "/app/src/main/res/layout-land/with_class_name.xml", toMap(KEY_CLASS_NAME, 47 "SomeOtherClassName")); 48 CompilationResult result = runGradle("assembleDebug"); 49 assertNotEquals(result.output, 0, result.resultCode); 50 List<ScopedException> exceptions = result.getBindingExceptions(); 51 assertEquals(result.error, 2, exceptions.size()); 52 boolean foundNormal = false; 53 boolean foundLandscape = false; 54 for (ScopedException exception : exceptions) { 55 ScopedErrorReport report = exception.getScopedErrorReport(); 56 assertNotNull(report); 57 File file = new File(report.getFilePath()); 58 assertTrue(file.exists()); 59 assertEquals(1, report.getLocations().size()); 60 Location location = report.getLocations().get(0); 61 String name = file.getParentFile().getName(); 62 if ("layout".equals(name)) { 63 assertEquals(new File(testFolder, 64 "/app/src/main/res/layout/with_class_name.xml") 65 .getCanonicalFile(), file.getCanonicalFile()); 66 String extract = extract("/app/src/main/res/layout/with_class_name.xml", 67 location); 68 assertEquals(extract, "AClassName"); 69 assertEquals(String.format( 70 ErrorMessages.MULTI_CONFIG_LAYOUT_CLASS_NAME_MISMATCH, 71 DEFAULT_APP_PACKAGE + ".databinding.AClassName", 72 "layout/with_class_name"), exception.getBareMessage()); 73 foundNormal = true; 74 } else if ("layout-land".equals(name)) { 75 assertEquals(new File(testFolder, 76 "/app/src/main/res/layout-land/with_class_name.xml") 77 .getCanonicalFile(), file.getCanonicalFile()); 78 String extract = extract("/app/src/main/res/layout-land/with_class_name.xml", 79 location); 80 assertEquals("SomeOtherClassName", extract); 81 assertEquals(String.format( 82 ErrorMessages.MULTI_CONFIG_LAYOUT_CLASS_NAME_MISMATCH, 83 DEFAULT_APP_PACKAGE + ".databinding.SomeOtherClassName", 84 "layout-land/with_class_name"), exception.getBareMessage()); 85 foundLandscape = true; 86 } else { 87 fail("unexpected error file"); 88 } 89 } 90 assertTrue("should find default config error\n" + result.error, foundNormal); 91 assertTrue("should find landscape error\n" + result.error, foundLandscape); 92 } 93 94 @Test 95 public void testMultipleLayoutFilesVariableMismatch() 96 throws IOException, URISyntaxException, InterruptedException { 97 prepareProject(); 98 copyResourceTo("/layout/layout_with_variable_type.xml", 99 "/app/src/main/res/layout/layout_with_variable_type.xml", toMap(KEY_CLASS_TYPE, 100 "String")); 101 copyResourceTo("/layout/layout_with_variable_type.xml", 102 "/app/src/main/res/layout-land/layout_with_variable_type.xml", toMap(KEY_CLASS_TYPE, 103 "CharSequence")); 104 CompilationResult result = runGradle("assembleDebug"); 105 assertNotEquals(result.output, 0, result.resultCode); 106 List<ScopedException> exceptions = result.getBindingExceptions(); 107 assertEquals(result.error, 2, exceptions.size()); 108 boolean foundNormal = false; 109 boolean foundLandscape = false; 110 for (ScopedException exception : exceptions) { 111 ScopedErrorReport report = exception.getScopedErrorReport(); 112 assertNotNull(report); 113 File file = new File(report.getFilePath()); 114 assertTrue(file.exists()); 115 assertEquals(result.error, 1, report.getLocations().size()); 116 Location location = report.getLocations().get(0); 117 // validated in switch 118 String name = file.getParentFile().getName(); 119 String config = name; 120 String type = "???"; 121 if ("layout".equals(name)) { 122 type = "String"; 123 foundNormal = true; 124 } else if ("layout-land".equals(name)) { 125 type = "CharSequence"; 126 foundLandscape = true; 127 } else { 128 fail("unexpected error file"); 129 } 130 assertEquals(new File(testFolder, 131 "/app/src/main/res/" + config + "/layout_with_variable_type.xml") 132 .getCanonicalFile(), file.getCanonicalFile()); 133 String extract = extract("/app/src/main/res/" + config + 134 "/layout_with_variable_type.xml", location); 135 assertEquals(extract, "<variable name=\"myVariable\" type=\"" + type + "\"/>"); 136 assertEquals(String.format( 137 ErrorMessages.MULTI_CONFIG_VARIABLE_TYPE_MISMATCH, 138 "myVariable", type, 139 config + "/layout_with_variable_type"), exception.getBareMessage()); 140 } 141 assertTrue(result.error, foundNormal); 142 assertTrue(result.error, foundLandscape); 143 } 144 145 @Test 146 public void testMultipleLayoutFilesImportMismatch() 147 throws IOException, URISyntaxException, InterruptedException { 148 prepareProject(); 149 String typeNormal = "java.util.List"; 150 String typeLand = "java.util.Map"; 151 copyResourceTo("/layout/layout_with_import_type.xml", 152 "/app/src/main/res/layout/layout_with_import_type.xml", toMap(KEY_IMPORT_TYPE, 153 typeNormal)); 154 copyResourceTo("/layout/layout_with_import_type.xml", 155 "/app/src/main/res/layout-land/layout_with_import_type.xml", toMap(KEY_IMPORT_TYPE, 156 typeLand)); 157 CompilationResult result = runGradle("assembleDebug"); 158 assertNotEquals(result.output, 0, result.resultCode); 159 List<ScopedException> exceptions = result.getBindingExceptions(); 160 assertEquals(result.error, 2, exceptions.size()); 161 boolean foundNormal = false; 162 boolean foundLandscape = false; 163 for (ScopedException exception : exceptions) { 164 ScopedErrorReport report = exception.getScopedErrorReport(); 165 assertNotNull(report); 166 File file = new File(report.getFilePath()); 167 assertTrue(file.exists()); 168 assertEquals(result.error, 1, report.getLocations().size()); 169 Location location = report.getLocations().get(0); 170 // validated in switch 171 String name = file.getParentFile().getName(); 172 String config = name; 173 String type = "???"; 174 if ("layout".equals(name)) { 175 type = typeNormal; 176 foundNormal = true; 177 } else if ("layout-land".equals(name)) { 178 type = typeLand; 179 foundLandscape = true; 180 } else { 181 fail("unexpected error file"); 182 } 183 assertEquals(new File(testFolder, 184 "/app/src/main/res/" + config + "/layout_with_import_type.xml") 185 .getCanonicalFile(), file.getCanonicalFile()); 186 String extract = extract("/app/src/main/res/" + config + "/layout_with_import_type.xml", 187 location); 188 assertEquals(extract, "<import alias=\"Blah\" type=\"" + type + "\"/>"); 189 assertEquals(String.format( 190 ErrorMessages.MULTI_CONFIG_IMPORT_TYPE_MISMATCH, 191 "Blah", type, 192 config + "/layout_with_import_type"), exception.getBareMessage()); 193 } 194 assertTrue(result.error, foundNormal); 195 assertTrue(result.error, foundLandscape); 196 } 197 198 @Test 199 public void testSameIdInIncludeAndView() 200 throws IOException, URISyntaxException, InterruptedException { 201 prepareProject(); 202 copyResourceTo("/layout/basic_layout.xml", 203 "/app/src/main/res/layout/basic_layout.xml"); 204 copyResourceTo("/layout/layout_with_include.xml", 205 "/app/src/main/res/layout/foo.xml", toMap(KEY_INCLUDE_ID, "sharedId")); 206 copyResourceTo("/layout/layout_with_view_id.xml", 207 "/app/src/main/res/layout-land/foo.xml", toMap(KEY_VIEW_ID, "sharedId")); 208 CompilationResult result = runGradle("assembleDebug"); 209 assertNotEquals(result.output, 0, result.resultCode); 210 List<ScopedException> exceptions = result.getBindingExceptions(); 211 assertEquals(result.error, 2, exceptions.size()); 212 213 boolean foundNormal = false; 214 boolean foundLandscape = false; 215 for (ScopedException exception : exceptions) { 216 ScopedErrorReport report = exception.getScopedErrorReport(); 217 assertNotNull(report); 218 File file = new File(report.getFilePath()); 219 assertTrue(file.exists()); 220 assertEquals(result.error, 1, report.getLocations().size()); 221 Location location = report.getLocations().get(0); 222 // validated in switch 223 String config = file.getParentFile().getName(); 224 if ("layout".equals(config)) { 225 String extract = extract("/app/src/main/res/" + config + "/foo.xml", location); 226 assertEquals(extract, "<include layout=\"@layout/basic_layout\" " 227 + "android:id=\"@+id/sharedId\" bind:myVariable=\"@{myVariable}\"/>"); 228 foundNormal = true; 229 } else if ("layout-land".equals(config)) { 230 String extract = extract("/app/src/main/res/" + config + "/foo.xml", location); 231 assertEquals(extract, "<TextView android:layout_width=\"wrap_content\" " 232 + "android:layout_height=\"wrap_content\" android:id=\"@+id/sharedId\" " 233 + "android:text=\"@{myVariable}\"/>"); 234 foundLandscape = true; 235 } else { 236 fail("unexpected error file"); 237 } 238 assertEquals(new File(testFolder, 239 "/app/src/main/res/" + config + "/foo.xml").getCanonicalFile(), 240 file.getCanonicalFile()); 241 assertEquals(String.format( 242 ErrorMessages.MULTI_CONFIG_ID_USED_AS_IMPORT, "@+id/sharedId"), 243 exception.getBareMessage()); 244 } 245 assertTrue(result.error, foundNormal); 246 assertTrue(result.error, foundLandscape); 247 } 248 249 250} 251