upload android base code part1
This commit is contained in:
parent
e02f198e2d
commit
0a1de6c4b3
48159 changed files with 9071466 additions and 0 deletions
|
@ -0,0 +1,26 @@
|
|||
apply plugin: 'java'
|
||||
|
||||
sourceCompatibility = 1.6
|
||||
version = '1.0'
|
||||
|
||||
dependencies {
|
||||
testCompile 'junit:junit:4.12'
|
||||
testCompile 'org.apache.commons:commons-lang3:3.3.2'
|
||||
testCompile 'commons-io:commons-io:2.4'
|
||||
testCompile 'commons-codec:commons-codec:1.10'
|
||||
testCompile project(':dataBinding:compilerCommon')
|
||||
testCompile project(':dataBinding:compiler')
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
tasks['test'].systemProperties['useReleaseVersion'] = dataBindingConfig.inReleaseBuild ? 'true' : 'false'
|
||||
tasks['test'].systemProperties['addRemoteRepos'] = dataBindingConfig.addRemoteRepos ? 'true' : 'false'
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
test {
|
||||
java {
|
||||
srcDirs += "${project.rootProject.getProjectDir().getAbsolutePath()}/compiler/src/test/java/android/databinding/tool/reflection/java"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,287 @@
|
|||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.databinding.compilationTest;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.rules.TestName;
|
||||
|
||||
import android.databinding.tool.store.Location;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
|
||||
public class BaseCompilationTest {
|
||||
|
||||
private static final String PRINT_ENCODED_ERRORS_PROPERTY
|
||||
= "android.injected.invoked.from.ide";
|
||||
@Rule
|
||||
public TestName name = new TestName();
|
||||
static Pattern VARIABLES = Pattern.compile("!@\\{([A-Za-z0-9_-]*)}");
|
||||
|
||||
public static final String KEY_MANIFEST_PACKAGE = "PACKAGE";
|
||||
public static final String KEY_DEPENDENCIES = "DEPENDENCIES";
|
||||
public static final String KEY_SETTINGS_INCLUDES = "SETTINGS_INCLUDES";
|
||||
public static final String DEFAULT_APP_PACKAGE = "com.android.databinding.compilationTest.test";
|
||||
public static final String KEY_CLASS_NAME = "CLASSNAME";
|
||||
public static final String KEY_CLASS_TYPE = "CLASSTYPE";
|
||||
public static final String KEY_IMPORT_TYPE = "IMPORTTYPE";
|
||||
public static final String KEY_INCLUDE_ID = "INCLUDEID";
|
||||
public static final String KEY_VIEW_ID = "VIEWID";
|
||||
|
||||
protected final File testFolder = new File("./build/build-test");
|
||||
|
||||
protected void copyResourceTo(String name, String path) throws IOException {
|
||||
copyResourceTo(name, new File(testFolder, path));
|
||||
}
|
||||
|
||||
protected void copyResourceTo(String name, String path, Map<String, String> replacements)
|
||||
throws IOException {
|
||||
copyResourceTo(name, new File(testFolder, path), replacements);
|
||||
}
|
||||
|
||||
protected void copyResourceDirectory(String name, String targetPath)
|
||||
throws URISyntaxException, IOException {
|
||||
URL dir = getClass().getResource(name);
|
||||
assertNotNull(dir);
|
||||
assertEquals("file", dir.getProtocol());
|
||||
File folder = new File(dir.toURI());
|
||||
assertTrue(folder.isDirectory());
|
||||
File target = new File(testFolder, targetPath);
|
||||
int len = folder.getAbsolutePath().length() + 1;
|
||||
for (File item : FileUtils.listFiles(folder, null, true)) {
|
||||
if (item.getAbsolutePath().equals(folder.getAbsolutePath())) {
|
||||
continue;
|
||||
}
|
||||
String resourcePath = item.getAbsolutePath().substring(len);
|
||||
|
||||
copyResourceTo(name + "/" + resourcePath, new File(target, resourcePath));
|
||||
}
|
||||
}
|
||||
|
||||
@Before
|
||||
public void clear() throws IOException {
|
||||
if (testFolder.exists()) {
|
||||
FileUtils.forceDelete(testFolder);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the text in the given location from the the at the given application path.
|
||||
*
|
||||
* @param pathInApp The path, relative to the root of the application under test
|
||||
* @param location The location to extract
|
||||
* @return The string that is contained in the given location
|
||||
* @throws IOException If file is invalid.
|
||||
*/
|
||||
protected String extract(String pathInApp, Location location) throws IOException {
|
||||
File file = new File(testFolder, pathInApp);
|
||||
assertTrue(file.exists());
|
||||
StringBuilder result = new StringBuilder();
|
||||
List<String> lines = FileUtils.readLines(file);
|
||||
for (int i = location.startLine; i <= location.endLine; i++) {
|
||||
if (i > location.startLine) {
|
||||
result.append("\n");
|
||||
}
|
||||
String line = lines.get(i);
|
||||
int start = 0;
|
||||
if (i == location.startLine) {
|
||||
start = location.startOffset;
|
||||
}
|
||||
int end = line.length() - 1; // inclusive
|
||||
if (i == location.endLine) {
|
||||
end = location.endOffset;
|
||||
}
|
||||
result.append(line.substring(start, end + 1));
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
protected void copyResourceTo(String name, File targetFile) throws IOException {
|
||||
File directory = targetFile.getParentFile();
|
||||
FileUtils.forceMkdir(directory);
|
||||
InputStream contents = getClass().getResourceAsStream(name);
|
||||
FileOutputStream fos = new FileOutputStream(targetFile);
|
||||
IOUtils.copy(contents, fos);
|
||||
IOUtils.closeQuietly(fos);
|
||||
IOUtils.closeQuietly(contents);
|
||||
}
|
||||
|
||||
protected static Map<String, String> toMap(String... keysAndValues) {
|
||||
assertEquals(0, keysAndValues.length % 2);
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
for (int i = 0; i < keysAndValues.length; i += 2) {
|
||||
map.put(keysAndValues[i], keysAndValues[i + 1]);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
protected void copyResourceTo(String name, File targetFile, Map<String, String> replacements)
|
||||
throws IOException {
|
||||
if (replacements.isEmpty()) {
|
||||
copyResourceTo(name, targetFile);
|
||||
}
|
||||
InputStream inputStream = getClass().getResourceAsStream(name);
|
||||
final String contents = IOUtils.toString(inputStream);
|
||||
IOUtils.closeQuietly(inputStream);
|
||||
|
||||
StringBuilder out = new StringBuilder(contents.length());
|
||||
final Matcher matcher = VARIABLES.matcher(contents);
|
||||
int location = 0;
|
||||
while (matcher.find()) {
|
||||
int start = matcher.start();
|
||||
if (start > location) {
|
||||
out.append(contents, location, start);
|
||||
}
|
||||
final String key = matcher.group(1);
|
||||
final String replacement = replacements.get(key);
|
||||
if (replacement != null) {
|
||||
out.append(replacement);
|
||||
}
|
||||
location = matcher.end();
|
||||
}
|
||||
if (location < contents.length()) {
|
||||
out.append(contents, location, contents.length());
|
||||
}
|
||||
|
||||
FileUtils.writeStringToFile(targetFile, out.toString());
|
||||
}
|
||||
|
||||
protected void prepareProject() throws IOException, URISyntaxException {
|
||||
prepareApp(null);
|
||||
}
|
||||
|
||||
private Map<String, String> addDefaults(Map<String, String> map) {
|
||||
if (map == null) {
|
||||
map = new HashMap<String, String>();
|
||||
}
|
||||
if (!map.containsKey(KEY_MANIFEST_PACKAGE)) {
|
||||
map.put(KEY_MANIFEST_PACKAGE, DEFAULT_APP_PACKAGE);
|
||||
}
|
||||
if (!map.containsKey(KEY_SETTINGS_INCLUDES)) {
|
||||
map.put(KEY_SETTINGS_INCLUDES, "include ':app'");
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
protected void prepareApp(Map<String, String> replacements) throws IOException,
|
||||
URISyntaxException {
|
||||
replacements = addDefaults(replacements);
|
||||
// how to get build folder, pass from gradle somehow ?
|
||||
FileUtils.forceMkdir(testFolder);
|
||||
copyResourceTo("/AndroidManifest.xml",
|
||||
new File(testFolder, "app/src/main/AndroidManifest.xml"), replacements);
|
||||
copyResourceTo("/project_build.gradle", new File(testFolder, "build.gradle"), replacements);
|
||||
copyResourceTo("/app_build.gradle", new File(testFolder, "app/build.gradle"), replacements);
|
||||
copyResourceTo("/settings.gradle", new File(testFolder, "settings.gradle"), replacements);
|
||||
File localProperties = new File("../local.properties");
|
||||
if (localProperties.exists()) {
|
||||
FileUtils.copyFile(localProperties, new File(testFolder, "local.properties"));
|
||||
}
|
||||
FileUtils.copyFile(new File("../propLoader.gradle"),
|
||||
new File(testFolder, "propLoaderClone.gradle"));
|
||||
FileUtils.copyFile(new File("../gradlew"), new File(testFolder, "gradlew"));
|
||||
FileUtils.copyDirectory(new File("../gradle"), new File(testFolder, "gradle"));
|
||||
}
|
||||
|
||||
protected void prepareModule(String moduleName, String packageName,
|
||||
Map<String, String> replacements) throws IOException, URISyntaxException {
|
||||
replacements = addDefaults(replacements);
|
||||
replacements.put(KEY_MANIFEST_PACKAGE, packageName);
|
||||
File moduleFolder = new File(testFolder, moduleName);
|
||||
if (moduleFolder.exists()) {
|
||||
FileUtils.forceDelete(moduleFolder);
|
||||
}
|
||||
FileUtils.forceMkdir(moduleFolder);
|
||||
copyResourceTo("/AndroidManifest.xml",
|
||||
new File(moduleFolder, "src/main/AndroidManifest.xml"), replacements);
|
||||
copyResourceTo("/module_build.gradle", new File(moduleFolder, "build.gradle"),
|
||||
replacements);
|
||||
}
|
||||
|
||||
protected CompilationResult runGradle(String... params)
|
||||
throws IOException, InterruptedException {
|
||||
setExecutable();
|
||||
File pathToExecutable = new File(testFolder, "gradlew");
|
||||
List<String> args = new ArrayList<String>();
|
||||
args.add(pathToExecutable.getAbsolutePath());
|
||||
args.add("-P" + PRINT_ENCODED_ERRORS_PROPERTY + "=true");
|
||||
if ("true".equals(System.getProperties().getProperty("useReleaseVersion", "false"))) {
|
||||
args.add("-PuseReleaseVersion=true");
|
||||
}
|
||||
if ("true".equals(System.getProperties().getProperty("addRemoteRepos", "false"))) {
|
||||
args.add("-PaddRemoteRepos=true");
|
||||
}
|
||||
args.add("--project-cache-dir");
|
||||
args.add(new File("../.caches/", name.getMethodName()).getAbsolutePath());
|
||||
Collections.addAll(args, params);
|
||||
ProcessBuilder builder = new ProcessBuilder(args);
|
||||
builder.environment().putAll(System.getenv());
|
||||
String javaHome = System.getProperty("java.home");
|
||||
if (StringUtils.isNotBlank(javaHome)) {
|
||||
builder.environment().put("JAVA_HOME", javaHome);
|
||||
}
|
||||
builder.directory(testFolder);
|
||||
Process process = builder.start();
|
||||
String output = collect(process.getInputStream());
|
||||
String error = collect(process.getErrorStream());
|
||||
int result = process.waitFor();
|
||||
return new CompilationResult(result, output, error);
|
||||
}
|
||||
|
||||
private void setExecutable() throws IOException {
|
||||
File gw = new File(testFolder, "gradlew");
|
||||
gw.setExecutable(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this instead of IO utils so that we can easily log the output when necessary
|
||||
*/
|
||||
private static String collect(InputStream stream) throws IOException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String line;
|
||||
final BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
|
||||
while ((line = reader.readLine()) != null) {
|
||||
sb.append(line).append("\n");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.databinding.compilationTest;
|
||||
|
||||
import android.databinding.tool.processing.ScopedErrorReport;
|
||||
import android.databinding.tool.processing.ScopedException;
|
||||
import android.databinding.tool.util.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class CompilationResult {
|
||||
public final int resultCode;
|
||||
public final String output;
|
||||
public final String error;
|
||||
|
||||
public CompilationResult(int resultCode, String output, String error) {
|
||||
this.resultCode = resultCode;
|
||||
this.output = output;
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
public boolean resultContainsText(String text) {
|
||||
return resultCode == 0 && output.indexOf(text) > 0;
|
||||
}
|
||||
|
||||
public boolean errorContainsText(String text) {
|
||||
return resultCode != 0 && error.indexOf(text) > 0;
|
||||
}
|
||||
|
||||
public ScopedException getBindingException() {
|
||||
List<ScopedException> errors = ScopedException.extractErrors(error);
|
||||
if (errors.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
assertEquals(error, 1, errors.size());
|
||||
return errors.get(0);
|
||||
}
|
||||
|
||||
public List<String> getBindingWarnings() {
|
||||
List<String> warnings = new ArrayList<String>();
|
||||
for (String line : error.split(StringUtils.LINE_SEPARATOR)) {
|
||||
if (line.startsWith("warning:")) {
|
||||
warnings.add(line.substring("warning:".length()));
|
||||
}
|
||||
}
|
||||
return warnings;
|
||||
}
|
||||
|
||||
public List<ScopedException> getBindingExceptions() {
|
||||
return ScopedException.extractErrors(error);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,252 @@
|
|||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.databinding.compilationTest;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import android.databinding.tool.processing.ErrorMessages;
|
||||
import android.databinding.tool.processing.ScopedErrorReport;
|
||||
import android.databinding.tool.processing.ScopedException;
|
||||
import android.databinding.tool.store.Location;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
public class MultiLayoutVerificationTest extends BaseCompilationTest {
|
||||
@Test
|
||||
public void testMultipleLayoutFilesWithNameMismatch()
|
||||
throws IOException, URISyntaxException, InterruptedException {
|
||||
prepareProject();
|
||||
copyResourceTo("/layout/layout_with_class_name.xml",
|
||||
"/app/src/main/res/layout/with_class_name.xml", toMap(KEY_CLASS_NAME,
|
||||
"AClassName"));
|
||||
copyResourceTo("/layout/layout_with_class_name.xml",
|
||||
"/app/src/main/res/layout-land/with_class_name.xml", toMap(KEY_CLASS_NAME,
|
||||
"SomeOtherClassName"));
|
||||
CompilationResult result = runGradle("assembleDebug");
|
||||
assertNotEquals(result.output, 0, result.resultCode);
|
||||
List<ScopedException> exceptions = result.getBindingExceptions();
|
||||
assertEquals(result.error, 2, exceptions.size());
|
||||
boolean foundNormal = false;
|
||||
boolean foundLandscape = false;
|
||||
for (ScopedException exception : exceptions) {
|
||||
ScopedErrorReport report = exception.getScopedErrorReport();
|
||||
assertNotNull(report);
|
||||
File file = new File(report.getFilePath());
|
||||
assertTrue(file.exists());
|
||||
assertEquals(1, report.getLocations().size());
|
||||
Location location = report.getLocations().get(0);
|
||||
String name = file.getParentFile().getName();
|
||||
if ("layout".equals(name)) {
|
||||
assertEquals(new File(testFolder,
|
||||
"/app/src/main/res/layout/with_class_name.xml")
|
||||
.getCanonicalFile(), file.getCanonicalFile());
|
||||
String extract = extract("/app/src/main/res/layout/with_class_name.xml",
|
||||
location);
|
||||
assertEquals(extract, "AClassName");
|
||||
assertEquals(String.format(
|
||||
ErrorMessages.MULTI_CONFIG_LAYOUT_CLASS_NAME_MISMATCH,
|
||||
DEFAULT_APP_PACKAGE + ".databinding.AClassName",
|
||||
"layout/with_class_name"), exception.getBareMessage());
|
||||
foundNormal = true;
|
||||
} else if ("layout-land".equals(name)) {
|
||||
assertEquals(new File(testFolder,
|
||||
"/app/src/main/res/layout-land/with_class_name.xml")
|
||||
.getCanonicalFile(), file.getCanonicalFile());
|
||||
String extract = extract("/app/src/main/res/layout-land/with_class_name.xml",
|
||||
location);
|
||||
assertEquals("SomeOtherClassName", extract);
|
||||
assertEquals(String.format(
|
||||
ErrorMessages.MULTI_CONFIG_LAYOUT_CLASS_NAME_MISMATCH,
|
||||
DEFAULT_APP_PACKAGE + ".databinding.SomeOtherClassName",
|
||||
"layout-land/with_class_name"), exception.getBareMessage());
|
||||
foundLandscape = true;
|
||||
} else {
|
||||
fail("unexpected error file");
|
||||
}
|
||||
}
|
||||
assertTrue("should find default config error\n" + result.error, foundNormal);
|
||||
assertTrue("should find landscape error\n" + result.error, foundLandscape);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleLayoutFilesVariableMismatch()
|
||||
throws IOException, URISyntaxException, InterruptedException {
|
||||
prepareProject();
|
||||
copyResourceTo("/layout/layout_with_variable_type.xml",
|
||||
"/app/src/main/res/layout/layout_with_variable_type.xml", toMap(KEY_CLASS_TYPE,
|
||||
"String"));
|
||||
copyResourceTo("/layout/layout_with_variable_type.xml",
|
||||
"/app/src/main/res/layout-land/layout_with_variable_type.xml", toMap(KEY_CLASS_TYPE,
|
||||
"CharSequence"));
|
||||
CompilationResult result = runGradle("assembleDebug");
|
||||
assertNotEquals(result.output, 0, result.resultCode);
|
||||
List<ScopedException> exceptions = result.getBindingExceptions();
|
||||
assertEquals(result.error, 2, exceptions.size());
|
||||
boolean foundNormal = false;
|
||||
boolean foundLandscape = false;
|
||||
for (ScopedException exception : exceptions) {
|
||||
ScopedErrorReport report = exception.getScopedErrorReport();
|
||||
assertNotNull(report);
|
||||
File file = new File(report.getFilePath());
|
||||
assertTrue(file.exists());
|
||||
assertEquals(result.error, 1, report.getLocations().size());
|
||||
Location location = report.getLocations().get(0);
|
||||
// validated in switch
|
||||
String name = file.getParentFile().getName();
|
||||
String config = name;
|
||||
String type = "???";
|
||||
if ("layout".equals(name)) {
|
||||
type = "String";
|
||||
foundNormal = true;
|
||||
} else if ("layout-land".equals(name)) {
|
||||
type = "CharSequence";
|
||||
foundLandscape = true;
|
||||
} else {
|
||||
fail("unexpected error file");
|
||||
}
|
||||
assertEquals(new File(testFolder,
|
||||
"/app/src/main/res/" + config + "/layout_with_variable_type.xml")
|
||||
.getCanonicalFile(), file.getCanonicalFile());
|
||||
String extract = extract("/app/src/main/res/" + config +
|
||||
"/layout_with_variable_type.xml", location);
|
||||
assertEquals(extract, "<variable name=\"myVariable\" type=\"" + type + "\"/>");
|
||||
assertEquals(String.format(
|
||||
ErrorMessages.MULTI_CONFIG_VARIABLE_TYPE_MISMATCH,
|
||||
"myVariable", type,
|
||||
config + "/layout_with_variable_type"), exception.getBareMessage());
|
||||
}
|
||||
assertTrue(result.error, foundNormal);
|
||||
assertTrue(result.error, foundLandscape);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleLayoutFilesImportMismatch()
|
||||
throws IOException, URISyntaxException, InterruptedException {
|
||||
prepareProject();
|
||||
String typeNormal = "java.util.List";
|
||||
String typeLand = "java.util.Map";
|
||||
copyResourceTo("/layout/layout_with_import_type.xml",
|
||||
"/app/src/main/res/layout/layout_with_import_type.xml", toMap(KEY_IMPORT_TYPE,
|
||||
typeNormal));
|
||||
copyResourceTo("/layout/layout_with_import_type.xml",
|
||||
"/app/src/main/res/layout-land/layout_with_import_type.xml", toMap(KEY_IMPORT_TYPE,
|
||||
typeLand));
|
||||
CompilationResult result = runGradle("assembleDebug");
|
||||
assertNotEquals(result.output, 0, result.resultCode);
|
||||
List<ScopedException> exceptions = result.getBindingExceptions();
|
||||
assertEquals(result.error, 2, exceptions.size());
|
||||
boolean foundNormal = false;
|
||||
boolean foundLandscape = false;
|
||||
for (ScopedException exception : exceptions) {
|
||||
ScopedErrorReport report = exception.getScopedErrorReport();
|
||||
assertNotNull(report);
|
||||
File file = new File(report.getFilePath());
|
||||
assertTrue(file.exists());
|
||||
assertEquals(result.error, 1, report.getLocations().size());
|
||||
Location location = report.getLocations().get(0);
|
||||
// validated in switch
|
||||
String name = file.getParentFile().getName();
|
||||
String config = name;
|
||||
String type = "???";
|
||||
if ("layout".equals(name)) {
|
||||
type = typeNormal;
|
||||
foundNormal = true;
|
||||
} else if ("layout-land".equals(name)) {
|
||||
type = typeLand;
|
||||
foundLandscape = true;
|
||||
} else {
|
||||
fail("unexpected error file");
|
||||
}
|
||||
assertEquals(new File(testFolder,
|
||||
"/app/src/main/res/" + config + "/layout_with_import_type.xml")
|
||||
.getCanonicalFile(), file.getCanonicalFile());
|
||||
String extract = extract("/app/src/main/res/" + config + "/layout_with_import_type.xml",
|
||||
location);
|
||||
assertEquals(extract, "<import alias=\"Blah\" type=\"" + type + "\"/>");
|
||||
assertEquals(String.format(
|
||||
ErrorMessages.MULTI_CONFIG_IMPORT_TYPE_MISMATCH,
|
||||
"Blah", type,
|
||||
config + "/layout_with_import_type"), exception.getBareMessage());
|
||||
}
|
||||
assertTrue(result.error, foundNormal);
|
||||
assertTrue(result.error, foundLandscape);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSameIdInIncludeAndView()
|
||||
throws IOException, URISyntaxException, InterruptedException {
|
||||
prepareProject();
|
||||
copyResourceTo("/layout/basic_layout.xml",
|
||||
"/app/src/main/res/layout/basic_layout.xml");
|
||||
copyResourceTo("/layout/layout_with_include.xml",
|
||||
"/app/src/main/res/layout/foo.xml", toMap(KEY_INCLUDE_ID, "sharedId"));
|
||||
copyResourceTo("/layout/layout_with_view_id.xml",
|
||||
"/app/src/main/res/layout-land/foo.xml", toMap(KEY_VIEW_ID, "sharedId"));
|
||||
CompilationResult result = runGradle("assembleDebug");
|
||||
assertNotEquals(result.output, 0, result.resultCode);
|
||||
List<ScopedException> exceptions = result.getBindingExceptions();
|
||||
|
||||
boolean foundNormal = false;
|
||||
boolean foundLandscape = false;
|
||||
for (ScopedException exception : exceptions) {
|
||||
ScopedErrorReport report = exception.getScopedErrorReport();
|
||||
assertNotNull(report);
|
||||
if (exception.getMessage().startsWith("Cannot find the setter")) {
|
||||
continue;
|
||||
}
|
||||
File file = new File(report.getFilePath());
|
||||
assertTrue(file.exists());
|
||||
assertEquals(result.error, 1, report.getLocations().size());
|
||||
Location location = report.getLocations().get(0);
|
||||
// validated in switch
|
||||
String config = file.getParentFile().getName();
|
||||
if ("layout".equals(config)) {
|
||||
String extract = extract("/app/src/main/res/" + config + "/foo.xml", location);
|
||||
assertEquals(extract, "<include layout=\"@layout/basic_layout\" "
|
||||
+ "android:id=\"@+id/sharedId\" bind:myVariable=\"@{myVariable}\"/>");
|
||||
foundNormal = true;
|
||||
} else if ("layout-land".equals(config)) {
|
||||
String extract = extract("/app/src/main/res/" + config + "/foo.xml", location);
|
||||
assertEquals(extract, "<TextView android:layout_width=\"wrap_content\" "
|
||||
+ "android:layout_height=\"wrap_content\" android:id=\"@+id/sharedId\" "
|
||||
+ "android:text=\"@{myVariable}\"/>");
|
||||
foundLandscape = true;
|
||||
} else {
|
||||
fail("unexpected error file");
|
||||
}
|
||||
assertEquals(new File(testFolder,
|
||||
"/app/src/main/res/" + config + "/foo.xml").getCanonicalFile(),
|
||||
file.getCanonicalFile());
|
||||
assertEquals(String.format(
|
||||
ErrorMessages.MULTI_CONFIG_ID_USED_AS_IMPORT, "@+id/sharedId"),
|
||||
exception.getBareMessage());
|
||||
}
|
||||
assertTrue(result.error, foundNormal);
|
||||
assertTrue(result.error, foundLandscape);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,402 @@
|
|||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.databinding.compilationTest;
|
||||
|
||||
import android.databinding.tool.CompilerChef;
|
||||
import android.databinding.tool.processing.ErrorMessages;
|
||||
import android.databinding.tool.processing.ScopedErrorReport;
|
||||
import android.databinding.tool.processing.ScopedException;
|
||||
import android.databinding.tool.reflection.InjectedClass;
|
||||
import android.databinding.tool.reflection.ModelClass;
|
||||
import android.databinding.tool.reflection.ModelMethod;
|
||||
import android.databinding.tool.reflection.java.JavaAnalyzer;
|
||||
import android.databinding.tool.store.Location;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.io.filefilter.PrefixFileFilter;
|
||||
import org.apache.commons.io.filefilter.SuffixFileFilter;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.jar.JarOutputStream;
|
||||
import java.util.jar.Manifest;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
@SuppressWarnings("ThrowableResultOfMethodCallIgnored")
|
||||
public class SimpleCompilationTest extends BaseCompilationTest {
|
||||
|
||||
@Test
|
||||
public void listTasks() throws IOException, URISyntaxException, InterruptedException {
|
||||
prepareProject();
|
||||
CompilationResult result = runGradle("tasks");
|
||||
assertEquals(0, result.resultCode);
|
||||
assertTrue("there should not be any errors", StringUtils.isEmpty(result.error));
|
||||
assertTrue("Test sanity, empty project tasks",
|
||||
result.resultContainsText("All tasks runnable from root project"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmptyCompilation() throws IOException, URISyntaxException, InterruptedException {
|
||||
prepareProject();
|
||||
CompilationResult result = runGradle("assembleDebug");
|
||||
assertEquals(result.error, 0, result.resultCode);
|
||||
assertTrue("there should not be any errors " + result.error,
|
||||
StringUtils.isEmpty(result.error));
|
||||
assertTrue("Test sanity, should compile fine",
|
||||
result.resultContainsText("BUILD SUCCESSFUL"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleConfigs() throws IOException, URISyntaxException, InterruptedException {
|
||||
prepareProject();
|
||||
copyResourceTo("/layout/basic_layout.xml",
|
||||
"/app/src/main/res/layout/main.xml");
|
||||
copyResourceTo("/layout/basic_layout.xml",
|
||||
"/app/src/main/res/layout-sw100dp/main.xml");
|
||||
CompilationResult result = runGradle("assembleDebug");
|
||||
assertEquals(result.error, 0, result.resultCode);
|
||||
File debugOut = new File(testFolder,
|
||||
"app/build/intermediates/data-binding-layout-out/debug");
|
||||
Collection<File> layoutFiles = FileUtils.listFiles(debugOut, new SuffixFileFilter(".xml"),
|
||||
new PrefixFileFilter("layout"));
|
||||
assertTrue("test sanity", layoutFiles.size() > 1);
|
||||
for (File layout : layoutFiles) {
|
||||
final String contents = FileUtils.readFileToString(layout);
|
||||
if (layout.getParent().contains("sw100")) {
|
||||
assertTrue("File has wrong tag:" + layout.getPath(),
|
||||
contents.indexOf("android:tag=\"layout-sw100dp/main_0\"") > 0);
|
||||
} else {
|
||||
assertTrue("File has wrong tag:" + layout.getPath() + "\n" + contents,
|
||||
contents.indexOf("android:tag=\"layout/main_0\"")
|
||||
> 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ScopedException singleFileErrorTest(String resource, String targetFile,
|
||||
String expectedExtract, String errorMessage)
|
||||
throws IOException, URISyntaxException, InterruptedException {
|
||||
prepareProject();
|
||||
copyResourceTo(resource, targetFile);
|
||||
CompilationResult result = runGradle("assembleDebug");
|
||||
assertNotEquals(0, result.resultCode);
|
||||
ScopedException scopedException = result.getBindingException();
|
||||
assertNotNull(result.error, scopedException);
|
||||
ScopedErrorReport report = scopedException.getScopedErrorReport();
|
||||
assertNotNull(report);
|
||||
assertEquals(1, report.getLocations().size());
|
||||
Location loc = report.getLocations().get(0);
|
||||
if (expectedExtract != null) {
|
||||
String extract = extract(targetFile, loc);
|
||||
assertEquals(expectedExtract, extract);
|
||||
}
|
||||
final File errorFile = new File(report.getFilePath());
|
||||
assertTrue(errorFile.exists());
|
||||
assertEquals(new File(testFolder, targetFile).getCanonicalFile(),
|
||||
errorFile.getCanonicalFile());
|
||||
if (errorMessage != null) {
|
||||
assertEquals(errorMessage, scopedException.getBareMessage());
|
||||
}
|
||||
return scopedException;
|
||||
}
|
||||
|
||||
private void singleFileWarningTest(String resource, String targetFile,
|
||||
String expectedMessage)
|
||||
throws IOException, URISyntaxException, InterruptedException {
|
||||
prepareProject();
|
||||
copyResourceTo(resource, targetFile);
|
||||
CompilationResult result = runGradle("assembleDebug");
|
||||
assertEquals(0, result.resultCode);
|
||||
final List<String> warnings = result.getBindingWarnings();
|
||||
boolean found = false;
|
||||
for (String warning : warnings) {
|
||||
found |= warning.contains(expectedMessage);
|
||||
}
|
||||
assertTrue(Joiner.on("\n").join(warnings),found);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleExceptionsInDifferentFiles()
|
||||
throws IOException, URISyntaxException, InterruptedException {
|
||||
prepareProject();
|
||||
copyResourceTo("/layout/undefined_variable_binding.xml",
|
||||
"/app/src/main/res/layout/broken.xml");
|
||||
copyResourceTo("/layout/invalid_setter_binding.xml",
|
||||
"/app/src/main/res/layout/invalid_setter.xml");
|
||||
CompilationResult result = runGradle("assembleDebug");
|
||||
assertNotEquals(result.output, 0, result.resultCode);
|
||||
List<ScopedException> bindingExceptions = result.getBindingExceptions();
|
||||
assertEquals(result.error, 2, bindingExceptions.size());
|
||||
File broken = new File(testFolder, "/app/src/main/res/layout/broken.xml");
|
||||
File invalidSetter = new File(testFolder, "/app/src/main/res/layout/invalid_setter.xml");
|
||||
for (ScopedException exception : bindingExceptions) {
|
||||
ScopedErrorReport report = exception.getScopedErrorReport();
|
||||
final File errorFile = new File(report.getFilePath());
|
||||
String message = null;
|
||||
String expectedErrorFile = null;
|
||||
if (errorFile.getCanonicalPath().equals(broken.getCanonicalPath())) {
|
||||
message = String.format(ErrorMessages.UNDEFINED_VARIABLE, "myVariable");
|
||||
expectedErrorFile = "/app/src/main/res/layout/broken.xml";
|
||||
} else if (errorFile.getCanonicalPath().equals(invalidSetter.getCanonicalPath())) {
|
||||
message = String.format(ErrorMessages.CANNOT_FIND_SETTER_CALL, "android:textx",
|
||||
String.class.getCanonicalName(), "android.widget.TextView");
|
||||
expectedErrorFile = "/app/src/main/res/layout/invalid_setter.xml";
|
||||
} else {
|
||||
fail("unexpected exception " + exception.getBareMessage());
|
||||
}
|
||||
assertEquals(1, report.getLocations().size());
|
||||
Location loc = report.getLocations().get(0);
|
||||
String extract = extract(expectedErrorFile, loc);
|
||||
assertEquals("myVariable", extract);
|
||||
assertEquals(message, exception.getBareMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBadSyntax() throws IOException, URISyntaxException, InterruptedException {
|
||||
singleFileErrorTest("/layout/layout_with_bad_syntax.xml",
|
||||
"/app/src/main/res/layout/broken.xml",
|
||||
"myVar.length())",
|
||||
String.format(ErrorMessages.SYNTAX_ERROR,
|
||||
"extraneous input ')' expecting {<EOF>, ',', '.', '::', '[', '+', '-', " +
|
||||
"'*', '/', '%', '<<', '>>>', '>>', '<=', '>=', '>', '<', " +
|
||||
"'instanceof', '==', '!=', '&', '^', '|', '&&', '||', '?', '??'}"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBrokenSyntax() throws IOException, URISyntaxException, InterruptedException {
|
||||
singleFileErrorTest("/layout/layout_with_completely_broken_syntax.xml",
|
||||
"/app/src/main/res/layout/broken.xml",
|
||||
"new String()",
|
||||
String.format(ErrorMessages.SYNTAX_ERROR,
|
||||
"mismatched input 'String' expecting {<EOF>, ',', '.', '::', '[', '+', " +
|
||||
"'-', '*', '/', '%', '<<', '>>>', '>>', '<=', '>=', '>', '<', " +
|
||||
"'instanceof', '==', '!=', '&', '^', '|', '&&', '||', '?', '??'}"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUndefinedVariable() throws IOException, URISyntaxException,
|
||||
InterruptedException {
|
||||
ScopedException ex = singleFileErrorTest("/layout/undefined_variable_binding.xml",
|
||||
"/app/src/main/res/layout/broken.xml", "myVariable",
|
||||
String.format(ErrorMessages.UNDEFINED_VARIABLE, "myVariable"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidSetterBinding() throws IOException, URISyntaxException,
|
||||
InterruptedException {
|
||||
prepareProject();
|
||||
ScopedException ex = singleFileErrorTest("/layout/invalid_setter_binding.xml",
|
||||
"/app/src/main/res/layout/invalid_setter.xml", "myVariable",
|
||||
String.format(ErrorMessages.CANNOT_FIND_SETTER_CALL, "android:textx",
|
||||
String.class.getCanonicalName(), "android.widget.TextView"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCallbackArgumentCountMismatch() throws Throwable {
|
||||
singleFileErrorTest("/layout/layout_with_missing_callback_args.xml",
|
||||
"/app/src/main/res/layout/broken.xml",
|
||||
"(seekBar, progress) -> obj.length()",
|
||||
String.format(ErrorMessages.CALLBACK_ARGUMENT_COUNT_MISMATCH,
|
||||
"android.databinding.adapters.SeekBarBindingAdapter.OnProgressChanged",
|
||||
"onProgressChanged", 3, 2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDuplicateCallbackArgument() throws Throwable {
|
||||
singleFileErrorTest("/layout/layout_with_duplicate_callback_identifier.xml",
|
||||
"/app/src/main/res/layout/broken.xml",
|
||||
"(seekBar, progress, progress) -> obj.length()",
|
||||
String.format(ErrorMessages.DUPLICATE_CALLBACK_ARGUMENT,
|
||||
"progress"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConflictWithVariableName() throws Throwable {
|
||||
singleFileWarningTest("/layout/layout_with_same_name_for_var_and_callback.xml",
|
||||
"/app/src/main/res/layout/broken.xml",
|
||||
String.format(ErrorMessages.CALLBACK_VARIABLE_NAME_CLASH,
|
||||
"myVar", "myVar", "String"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRootTag() throws IOException, URISyntaxException,
|
||||
InterruptedException {
|
||||
prepareProject();
|
||||
copyResourceTo("/layout/root_tag.xml", "/app/src/main/res/layout/root_tag.xml");
|
||||
CompilationResult result = runGradle("assembleDebug");
|
||||
assertNotEquals(0, result.resultCode);
|
||||
assertNotNull(result.error);
|
||||
final String expected = String.format(ErrorMessages.ROOT_TAG_NOT_SUPPORTED, "hello");
|
||||
assertTrue(result.error.contains(expected));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidVariableType() throws IOException, URISyntaxException,
|
||||
InterruptedException {
|
||||
prepareProject();
|
||||
ScopedException ex = singleFileErrorTest("/layout/invalid_variable_type.xml",
|
||||
"/app/src/main/res/layout/invalid_variable.xml", "myVariable",
|
||||
String.format(ErrorMessages.CANNOT_RESOLVE_TYPE, "myVariable"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingleModule() throws IOException, URISyntaxException, InterruptedException {
|
||||
prepareApp(toMap(KEY_DEPENDENCIES, "compile project(':module1')",
|
||||
KEY_SETTINGS_INCLUDES, "include ':app'\ninclude ':module1'"));
|
||||
prepareModule("module1", "com.example.module1", toMap());
|
||||
copyResourceTo("/layout/basic_layout.xml", "/module1/src/main/res/layout/module_layout.xml");
|
||||
copyResourceTo("/layout/basic_layout.xml", "/app/src/main/res/layout/app_layout.xml");
|
||||
CompilationResult result = runGradle("assembleDebug");
|
||||
assertEquals(result.error, 0, result.resultCode);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testModuleDependencyChange() throws IOException, URISyntaxException,
|
||||
InterruptedException {
|
||||
prepareApp(toMap(KEY_DEPENDENCIES, "compile project(':module1')",
|
||||
KEY_SETTINGS_INCLUDES, "include ':app'\ninclude ':module1'"));
|
||||
prepareModule("module1", "com.example.module1", toMap(
|
||||
KEY_DEPENDENCIES, "compile 'com.android.support:appcompat-v7:23.1.1'"
|
||||
));
|
||||
copyResourceTo("/layout/basic_layout.xml", "/module1/src/main/res/layout/module_layout.xml");
|
||||
copyResourceTo("/layout/basic_layout.xml", "/app/src/main/res/layout/app_layout.xml");
|
||||
CompilationResult result = runGradle("assembleDebug");
|
||||
assertEquals(result.error, 0, result.resultCode);
|
||||
File moduleFolder = new File(testFolder, "module1");
|
||||
copyResourceTo("/module_build.gradle", new File(moduleFolder, "build.gradle"),
|
||||
toMap());
|
||||
result = runGradle("assembleDebug");
|
||||
assertEquals(result.error, 0, result.resultCode);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTwoLevelDependency() throws IOException, URISyntaxException, InterruptedException {
|
||||
prepareApp(toMap(KEY_DEPENDENCIES, "compile project(':module1')",
|
||||
KEY_SETTINGS_INCLUDES, "include ':app'\ninclude ':module1'\n"
|
||||
+ "include ':module2'"));
|
||||
prepareModule("module1", "com.example.module1", toMap(KEY_DEPENDENCIES,
|
||||
"compile project(':module2')"));
|
||||
prepareModule("module2", "com.example.module2", toMap());
|
||||
copyResourceTo("/layout/basic_layout.xml",
|
||||
"/module2/src/main/res/layout/module2_layout.xml");
|
||||
copyResourceTo("/layout/basic_layout.xml", "/module1/src/main/res/layout/module1_layout.xml");
|
||||
copyResourceTo("/layout/basic_layout.xml", "/app/src/main/res/layout/app_layout.xml");
|
||||
CompilationResult result = runGradle("assembleDebug");
|
||||
assertEquals(result.error, 0, result.resultCode);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIncludeInMerge() throws Throwable {
|
||||
prepareProject();
|
||||
copyResourceTo("/layout/merge_include.xml", "/app/src/main/res/layout/merge_include.xml");
|
||||
CompilationResult result = runGradle("assembleDebug");
|
||||
assertNotEquals(0, result.resultCode);
|
||||
List<ScopedException> errors = ScopedException.extractErrors(result.error);
|
||||
assertEquals(result.error, 1, errors.size());
|
||||
final ScopedException ex = errors.get(0);
|
||||
final ScopedErrorReport report = ex.getScopedErrorReport();
|
||||
final File errorFile = new File(report.getFilePath());
|
||||
assertTrue(errorFile.exists());
|
||||
assertEquals(
|
||||
new File(testFolder, "/app/src/main/res/layout/merge_include.xml")
|
||||
.getCanonicalFile(),
|
||||
errorFile.getCanonicalFile());
|
||||
assertEquals("Merge shouldn't support includes as root. Error message was '" + result.error,
|
||||
ErrorMessages.INCLUDE_INSIDE_MERGE, ex.getBareMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAssignTwoWayEvent() throws Throwable {
|
||||
prepareProject();
|
||||
copyResourceTo("/layout/layout_with_two_way_event_attribute.xml",
|
||||
"/app/src/main/res/layout/layout_with_two_way_event_attribute.xml");
|
||||
CompilationResult result = runGradle("assembleDebug");
|
||||
assertNotEquals(0, result.resultCode);
|
||||
List<ScopedException> errors = ScopedException.extractErrors(result.error);
|
||||
assertEquals(result.error, 1, errors.size());
|
||||
final ScopedException ex = errors.get(0);
|
||||
final ScopedErrorReport report = ex.getScopedErrorReport();
|
||||
final File errorFile = new File(report.getFilePath());
|
||||
assertTrue(errorFile.exists());
|
||||
assertEquals(new File(testFolder,
|
||||
"/app/src/main/res/layout/layout_with_two_way_event_attribute.xml")
|
||||
.getCanonicalFile(),
|
||||
errorFile.getCanonicalFile());
|
||||
assertEquals("The attribute android:textAttrChanged is a two-way binding event attribute " +
|
||||
"and cannot be assigned.", ex.getBareMessage());
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecated")
|
||||
@Test
|
||||
public void testDynamicUtilMembers() throws Throwable {
|
||||
prepareProject();
|
||||
CompilationResult result = runGradle("assembleDebug");
|
||||
assertEquals(result.error, 0, result.resultCode);
|
||||
assertTrue("there should not be any errors " + result.error,
|
||||
StringUtils.isEmpty(result.error));
|
||||
assertTrue("Test sanity, should compile fine",
|
||||
result.resultContainsText("BUILD SUCCESSFUL"));
|
||||
File classFile = new File(testFolder,
|
||||
"app/build/intermediates/classes/debug/android/databinding/DynamicUtil.class");
|
||||
assertTrue(classFile.exists());
|
||||
|
||||
File root = new File(testFolder, "app/build/intermediates/classes/debug/");
|
||||
URL[] urls = new URL[] {root.toURL()};
|
||||
JavaAnalyzer.initForTests();
|
||||
JavaAnalyzer analyzer = (JavaAnalyzer) JavaAnalyzer.getInstance();
|
||||
ClassLoader classLoader = new URLClassLoader(urls, analyzer.getClassLoader());
|
||||
Class dynamicUtilClass = classLoader.loadClass("android.databinding.DynamicUtil");
|
||||
|
||||
InjectedClass injectedClass = CompilerChef.pushDynamicUtilToAnalyzer();
|
||||
|
||||
// test methods
|
||||
for (Method method : dynamicUtilClass.getMethods()) {
|
||||
// look for the method in the injected class
|
||||
ArrayList<ModelClass> args = new ArrayList<ModelClass>();
|
||||
for (Class<?> param : method.getParameterTypes()) {
|
||||
args.add(analyzer.findClass(param));
|
||||
}
|
||||
ModelMethod modelMethod = injectedClass.getMethod(
|
||||
method.getName(), args, Modifier.isStatic(method.getModifiers()), false);
|
||||
assertNotNull("Method " + method + " not found", modelMethod);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<!--
|
||||
Copyright (C) 2015 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="!@{PACKAGE}">
|
||||
|
||||
</manifest>
|
|
@ -0,0 +1,35 @@
|
|||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion dataBindingConfig.compileSdkVersion
|
||||
buildToolsVersion dataBindingConfig.buildToolsVersion
|
||||
dataBinding {
|
||||
enabled = true
|
||||
}
|
||||
defaultConfig {
|
||||
minSdkVersion 7
|
||||
targetSdkVersion 21
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
exclude 'META-INF/services/javax.annotation.processing.Processor'
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_6
|
||||
targetCompatibility JavaVersion.VERSION_1_6
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
compile "com.android.support:support-v4:+"
|
||||
!@{DEPENDENCIES}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2015 The Android Open Source Project
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:bind="http://schemas.android.com/apk/res-auto">
|
||||
<data>
|
||||
<variable name="myVar" type="String"/>
|
||||
</data>
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<!-- undefined variable -->
|
||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="@{myVar}"/>
|
||||
</LinearLayout>
|
||||
</layout>
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2015 The Android Open Source Project
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:bind="http://schemas.android.com/apk/res-auto">
|
||||
<data>
|
||||
<variable name="myVariable" type="String"/>
|
||||
</data>
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<!-- undefined variable -->
|
||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:id="@+id/outerTextView"
|
||||
android:textx="@{myVariable}"/>
|
||||
</LinearLayout>
|
||||
</layout>
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2015 The Android Open Source Project
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:bind="http://schemas.android.com/apk/res-auto">
|
||||
<data>
|
||||
<variable name="myVariable" type="Stringx"/>
|
||||
</data>
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<!-- undefined variable -->
|
||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:id="@+id/outerTextView"
|
||||
android:textx="@{myVariable}"/>
|
||||
</LinearLayout>
|
||||
</layout>
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2015 The Android Open Source Project
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:bind="http://schemas.android.com/apk/res-auto">
|
||||
<data>
|
||||
<variable name="myVar" type="String"/>
|
||||
</data>
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<!-- undefined variable -->
|
||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="@{myVar.length())}"/>
|
||||
</LinearLayout>
|
||||
</layout>
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2015 The Android Open Source Project
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:bind="http://schemas.android.com/apk/res-auto">
|
||||
<data class="!@{CLASSNAME}">
|
||||
<variable name="myVariable" type="String"/>
|
||||
</data>
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<!-- undefined variable -->
|
||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:id="@+id/outerTextView"
|
||||
android:text="@{myVariable}"/>
|
||||
</LinearLayout>
|
||||
</layout>
|
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2015 The Android Open Source Project
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<!-- undefined variable -->
|
||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="@{new String()}"/>
|
||||
</LinearLayout>
|
||||
</layout>
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2016 The Android Open Source Project
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:bind="http://schemas.android.com/apk/res-auto">
|
||||
<data>
|
||||
<variable name="myVar" type="String"/>
|
||||
</data>
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<!-- undefined variable -->
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:onProgressChanged="@{(seekBar, progress, progress) -> obj.length()}"/>
|
||||
</LinearLayout>
|
||||
</layout>
|
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2015 The Android Open Source Project
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:bind="http://schemas.android.com/apk/res-auto">
|
||||
<data>
|
||||
<variable name="myVariable" type="String"/>
|
||||
<import alias="Blah" type="!@{IMPORTTYPE}"/>
|
||||
</data>
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<!-- undefined variable -->
|
||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:id="@+id/outerTextView"
|
||||
android:text="@{myVariable}"/>
|
||||
</LinearLayout>
|
||||
</layout>
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2015 The Android Open Source Project
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:bind="http://schemas.android.com/apk/res-auto">
|
||||
<data>
|
||||
<variable name="myVariable" type="String"/>
|
||||
</data>
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<!-- undefined variable -->
|
||||
<include layout="@layout/basic_layout" android:id="@+id/!@{INCLUDEID}" bind:myVariable="@{myVariable}"/>
|
||||
</LinearLayout>
|
||||
</layout>
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2016 The Android Open Source Project
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:bind="http://schemas.android.com/apk/res-auto">
|
||||
<data>
|
||||
<variable name="myVar" type="String"/>
|
||||
</data>
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<!-- undefined variable -->
|
||||
<SeekBar android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:onProgressChanged="@{(seekBar, progress) -> obj.length()}"/>
|
||||
</LinearLayout>
|
||||
</layout>
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2016 The Android Open Source Project
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:bind="http://schemas.android.com/apk/res-auto">
|
||||
<data>
|
||||
<variable name="myVar" type="String"/>
|
||||
</data>
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<!-- undefined variable -->
|
||||
<SeekBar android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:onClick="@{(myVar) -> myVar.setVisibility(1)}"/>
|
||||
</LinearLayout>
|
||||
</layout>
|
|
@ -0,0 +1,35 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2015 The Android Open Source Project
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
>
|
||||
<data>
|
||||
<variable name="myVariable" type="String"/>
|
||||
<variable name="myEventListener" type="android.databinding.InverseBindingListener"/>
|
||||
</data>
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<!-- undefined variable -->
|
||||
<TextView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/textView"
|
||||
android:text="@{myVariable}"
|
||||
android:textAttrChanged="@{myEventListener}"/>
|
||||
</LinearLayout>
|
||||
</layout>
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2015 The Android Open Source Project
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:bind="http://schemas.android.com/apk/res-auto">
|
||||
<data>
|
||||
<variable name="myVariable" type="!@{CLASSTYPE}"/>
|
||||
</data>
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<!-- undefined variable -->
|
||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:id="@+id/outerTextView"
|
||||
android:text="@{myVariable}"/>
|
||||
</LinearLayout>
|
||||
</layout>
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2015 The Android Open Source Project
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:bind="http://schemas.android.com/apk/res-auto">
|
||||
<data>
|
||||
<variable name="myVariable" type="String"/>
|
||||
</data>
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<!-- undefined variable -->
|
||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/!@{VIEWID}" android:text="@{myVariable}"/>
|
||||
</LinearLayout>
|
||||
</layout>
|
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2015 The Android Open Source Project
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:bind="http://schemas.android.com/apk/res-auto">
|
||||
<data>
|
||||
<variable name="myVar" type="String"/>
|
||||
</data>
|
||||
<merge>
|
||||
<include layout="@layout/basic_layout"
|
||||
bind:myVar="@{myVar}"/>
|
||||
</merge>
|
||||
</layout>
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2015 The Android Open Source Project
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:bind="http://schemas.android.com/apk/res-auto">
|
||||
<data>
|
||||
<variable name="myVar" type="String"/>
|
||||
</data>
|
||||
<LinearLayout
|
||||
android:tag="hello"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<!-- undefined variable -->
|
||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="@{myVar}"/>
|
||||
</LinearLayout>
|
||||
</layout>
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2015 The Android Open Source Project
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:bind="http://schemas.android.com/apk/res-auto">
|
||||
<data>
|
||||
</data>
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<!-- undefined variable -->
|
||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:id="@+id/outerTextView"
|
||||
android:text="@{myVariable.stringValue}"/>
|
||||
</LinearLayout>
|
||||
</layout>
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
compileSdkVersion dataBindingConfig.compileSdkVersion
|
||||
buildToolsVersion dataBindingConfig.buildToolsVersion
|
||||
dataBinding {
|
||||
enabled = true
|
||||
}
|
||||
defaultConfig {
|
||||
minSdkVersion 7
|
||||
targetSdkVersion 21
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
exclude 'META-INF/services/javax.annotation.processing.Processor'
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_6
|
||||
targetCompatibility JavaVersion.VERSION_1_6
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
compile "com.android.support:support-v4:+"
|
||||
!@{DEPENDENCIES}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
buildscript {
|
||||
ext.dataBindingRootFolder = new File(project.projectDir, "../../..")
|
||||
apply from: "${project.projectDir}/propLoaderClone.gradle"
|
||||
ext.addRepos(repositories)
|
||||
dependencies {
|
||||
classpath "com.android.tools.build:gradle:${dataBindingConfig.androidPluginVersion}"
|
||||
}
|
||||
}
|
||||
|
||||
subprojects {
|
||||
apply plugin: 'maven'
|
||||
group = dataBindingConfig.group
|
||||
version = dataBindingConfig.version
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
jcenter()
|
||||
maven {
|
||||
url dataBindingConfig.mavenRepoDir
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
!@{SETTINGS_INCLUDES}
|
Loading…
Add table
Add a link
Reference in a new issue