aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/test/java/com
diff options
context:
space:
mode:
authorGravatar ajmichael <ajmichael@google.com>2017-03-29 18:34:24 +0000
committerGravatar Philipp Wollermann <philwo@google.com>2017-03-31 17:06:19 +0200
commit115ea10fe907b80ea11ad7db6f50657ecc2c18cb (patch)
tree7c1eb2cb4bdefc22b52b9c09f4ab8cea7f8ee88e /src/test/java/com
parent8611e28f44af54680b3caa0a16e5efc9003dfdc9 (diff)
Move more Android tools' tests into Bazel.
RELNOTES: None PiperOrigin-RevId: 151602497
Diffstat (limited to 'src/test/java/com')
-rw-r--r--src/test/java/com/google/devtools/build/android/BUILD74
-rw-r--r--src/test/java/com/google/devtools/build/android/DensitySpecificManifestProcessorTest.java255
-rw-r--r--src/test/java/com/google/devtools/build/android/DependencyAndroidDataTest.java166
-rw-r--r--src/test/java/com/google/devtools/build/android/SerializedAndroidDataTest.java113
-rw-r--r--src/test/java/com/google/devtools/build/android/SplitConfigurationFilterTest.java327
-rw-r--r--src/test/java/com/google/devtools/build/android/UnvalidatedAndroidDataTest.java104
-rw-r--r--src/test/java/com/google/devtools/build/android/UnvalidatedAndroidDirectoriesTest.java81
7 files changed, 1120 insertions, 0 deletions
diff --git a/src/test/java/com/google/devtools/build/android/BUILD b/src/test/java/com/google/devtools/build/android/BUILD
index edc97011db..76c476f865 100644
--- a/src/test/java/com/google/devtools/build/android/BUILD
+++ b/src/test/java/com/google/devtools/build/android/BUILD
@@ -78,6 +78,31 @@ java_test(
)
java_test(
+ name = "DensitySpecificManifestProcessorTest",
+ srcs = ["DensitySpecificManifestProcessorTest.java"],
+ tags = ["no_windows"], # Test asserts forward slashes in android data xml files.
+ deps = [
+ "//src/tools/android/java/com/google/devtools/build/android:android_builder_lib",
+ "//third_party:guava",
+ "//third_party:jimfs",
+ "//third_party:junit4",
+ "//third_party:truth",
+ ],
+)
+
+java_test(
+ name = "DependencyAndroidDataTest",
+ srcs = ["DependencyAndroidDataTest.java"],
+ deps = [
+ "//src/tools/android/java/com/google/devtools/build/android:android_builder_lib",
+ "//third_party:guava",
+ "//third_party:jimfs",
+ "//third_party:junit4",
+ "//third_party:truth",
+ ],
+)
+
+java_test(
name = "ParsedAndroidDataTest",
srcs = ["ParsedAndroidDataTest.java"],
tags = ["manual"], # Fails due to https://github.com/bazelbuild/bazel/issues/2709
@@ -92,6 +117,55 @@ java_test(
],
)
+java_test(
+ name = "SerializedAndroidDataTest",
+ srcs = ["SerializedAndroidDataTest.java"],
+ deps = [
+ "//src/tools/android/java/com/google/devtools/build/android:android_builder_lib",
+ "//third_party:guava",
+ "//third_party:jimfs",
+ "//third_party:junit4",
+ "//third_party:truth",
+ ],
+)
+
+java_test(
+ name = "SplitConfigurationFilterTest",
+ srcs = ["SplitConfigurationFilterTest.java"],
+ deps = [
+ "//src/tools/android/java/com/google/devtools/build/android:android_builder_lib",
+ "//third_party:guava",
+ "//third_party:guava-testlib",
+ "//third_party:jsr305",
+ "//third_party:junit4",
+ "//third_party:truth",
+ ],
+)
+
+java_test(
+ name = "UnvalidatedAndroidDataTest",
+ srcs = ["UnvalidatedAndroidDataTest.java"],
+ deps = [
+ "//src/tools/android/java/com/google/devtools/build/android:android_builder_lib",
+ "//third_party:guava",
+ "//third_party:jimfs",
+ "//third_party:junit4",
+ "//third_party:truth",
+ ],
+)
+
+java_test(
+ name = "UnvalidatedAndroidDirectoriesTest",
+ srcs = ["UnvalidatedAndroidDirectoriesTest.java"],
+ deps = [
+ "//src/tools/android/java/com/google/devtools/build/android:android_builder_lib",
+ "//third_party:guava",
+ "//third_party:jimfs",
+ "//third_party:junit4",
+ "//third_party:truth",
+ ],
+)
+
java_library(
name = "test_utils",
testonly = 1,
diff --git a/src/test/java/com/google/devtools/build/android/DensitySpecificManifestProcessorTest.java b/src/test/java/com/google/devtools/build/android/DensitySpecificManifestProcessorTest.java
new file mode 100644
index 0000000000..9d02a28ef8
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/android/DensitySpecificManifestProcessorTest.java
@@ -0,0 +1,255 @@
+// Copyright 2017 The Bazel Authors. All rights reserved.
+//
+// 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 com.google.devtools.build.android;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.devtools.build.android.DensitySpecificManifestProcessor.PLAY_STORE_SUPPORTED_DENSITIES;
+import static com.google.devtools.build.android.DensitySpecificManifestProcessor.SCREEN_SIZES;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableList;
+import com.google.common.jimfs.Jimfs;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.FileSystem;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/** Tests for {@link DensitySpecificManifestProcessor}. */
+@RunWith(JUnit4.class)
+public class DensitySpecificManifestProcessorTest {
+
+ private FileSystem fs;
+ private Path tmp;
+
+ @Test public void testNoDensities() throws Exception {
+ Path manifest = createManifest("<?xml version=\"1.0\" encoding=\"utf-8\"?>",
+ "<manifest xmlns:android='http://schemas.android.com/apk/res/android'",
+ " package='com.google.test'>",
+ "</manifest>");
+ Path modified = new DensitySpecificManifestProcessor(ImmutableList.<String>of(),
+ tmp.resolve("manifest-filtered/AndroidManifest.xml")).process(manifest);
+ assertEquals(manifest, modified);
+ }
+
+ @Test public void testSingleDensity() throws Exception {
+ ImmutableList<String> densities = ImmutableList.of("xhdpi");
+ Path manifest = createManifest("<?xml version=\"1.0\" encoding=\"utf-8\"?>",
+ "<manifest xmlns:android='http://schemas.android.com/apk/res/android'",
+ " package='com.google.test'>",
+ "</manifest>");
+ Path modified = new DensitySpecificManifestProcessor(densities,
+ tmp.resolve("manifest-filtered/AndroidManifest.xml")).process(manifest);
+ assertNotNull(modified);
+ checkModification(modified, densities);
+ }
+
+ @Test public void test280Density() throws Exception {
+ ImmutableList<String> densities = ImmutableList.of("280dpi");
+ Path manifest = createManifest("<?xml version=\"1.0\" encoding=\"utf-8\"?>",
+ "<manifest xmlns:android='http://schemas.android.com/apk/res/android'",
+ " package='com.google.test'>",
+ "</manifest>");
+ Path modified = new DensitySpecificManifestProcessor(densities,
+ tmp.resolve("manifest-filtered/AndroidManifest.xml")).process(manifest);
+ assertNotNull(modified);
+ checkModification(modified, densities);
+ }
+
+ @Test public void testMultipleDensities() throws Exception {
+ ImmutableList<String> densities = ImmutableList.of("xhdpi", "xxhdpi", "560dpi", "xxxhdpi");
+ Path manifest = createManifest("<?xml version=\"1.0\" encoding=\"utf-8\"?>",
+ "<manifest xmlns:android='http://schemas.android.com/apk/res/android'",
+ " package='com.google.test'>",
+ "</manifest>");
+ Path modified = new DensitySpecificManifestProcessor(densities,
+ tmp.resolve("manifest-filtered/AndroidManifest.xml")).process(manifest);
+ assertNotNull(modified);
+ checkModification(modified, densities);
+ }
+
+ @Test public void omitCompatibleScreensIfDensityUnsupported() throws Exception {
+ ImmutableList<String> densities = ImmutableList.of("xhdpi", "340dpi", "xxhdpi");
+ Path manifest = createManifest("<?xml version=\"1.0\" encoding=\"utf-8\"?>",
+ "<manifest xmlns:android='http://schemas.android.com/apk/res/android'",
+ " package='com.google.test'>",
+ "</manifest>");
+ Path modified = new DensitySpecificManifestProcessor(densities,
+ tmp.resolve("manifest-filtered/AndroidManifest.xml")).process(manifest);
+ assertNotNull(modified);
+ checkCompatibleScreensOmitted(modified);
+ }
+
+ @Test public void testExistingCompatibleScreens() throws Exception {
+ ImmutableList<String> densities = ImmutableList.of("xhdpi");
+ Path manifest = createManifest("<?xml version=\"1.0\" encoding=\"utf-8\"?>",
+ "<manifest xmlns:android='http://schemas.android.com/apk/res/android'",
+ " package='com.google.test'>",
+ "<compatible-screens>",
+ "</compatible-screens>",
+ "</manifest>");
+ Path modified = new DensitySpecificManifestProcessor(densities,
+ tmp.resolve("manifest-filtered/AndroidManifest.xml")).process(manifest);
+ assertNotNull(modified);
+ checkModification(modified, densities);
+ }
+
+ @Test public void testExistingSupersetCompatibleScreens() throws Exception {
+ ImmutableList<String> densities = ImmutableList.of("ldpi");
+ Path manifest = createManifest("<?xml version=\"1.0\" encoding=\"utf-8\"?>",
+ "<manifest xmlns:android='http://schemas.android.com/apk/res/android'",
+ " package='com.google.test'>",
+ "<compatible-screens>",
+ " <screen android:screenSize='small' android:screenDensity='ldpi' />",
+ " <screen android:screenSize='normal' android:screenDensity='ldpi' />",
+ " <screen android:screenSize='large' android:screenDensity='ldpi' />",
+ " <screen android:screenSize='xlarge' android:screenDensity='ldpi' />",
+ " <screen android:screenSize='small' android:screenDensity='480' />",
+ " <screen android:screenSize='normal' android:screenDensity='480' />",
+ " <screen android:screenSize='large' android:screenDensity='480' />",
+ " <screen android:screenSize='xlarge' android:screenDensity='480' />",
+ "</compatible-screens>",
+ "</manifest>");
+ Path modified = new DensitySpecificManifestProcessor(densities,
+ tmp.resolve("manifest-filtered/AndroidManifest.xml")).process(manifest);
+ assertNotNull(modified);
+ checkModification(modified, ImmutableList.<String>of("ldpi", "xxhdpi"));
+ }
+
+ @Test public void testMalformedManifest() throws Exception {
+ Path manifest = createManifest("<?xml version=\"1.0\" encoding=\"utf-8\"?>",
+ "<manifest xmlns:android='http://schemas.android.com/apk/res/android'",
+ " package='com.google.test'>",
+ "</manifest>",
+ "<manifest xmlns:android='http://schemas.android.com/apk/res/android'",
+ " package='com.google.test'>",
+ "</manifest>");
+ try {
+ new DensitySpecificManifestProcessor(ImmutableList.of("xhdpi"),
+ tmp.resolve("manifest-filtered/AndroidManifest.xml")).process(manifest);
+ fail();
+ } catch (ManifestProcessingException e) {
+ assertThat(e).hasMessageThat().contains("must be well-formed");
+ }
+ }
+
+ @Test public void testNoManifest() throws Exception {
+ Path manifest = createManifest("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
+ try {
+ new DensitySpecificManifestProcessor(ImmutableList.of("xhdpi"),
+ tmp.resolve("manifest-filtered/AndroidManifest.xml")).process(manifest);
+ fail();
+ } catch (ManifestProcessingException e) {
+ assertThat(e).hasMessageThat().contains("Premature end of file.");
+ }
+ }
+
+ @Test public void testNestedManifest() throws Exception {
+ Path manifest = createManifest("<?xml version=\"1.0\" encoding=\"utf-8\"?>",
+ "<manifest xmlns:android='http://schemas.android.com/apk/res/android'",
+ " package='com.google.test'>",
+ " <manifest xmlns:android='http://schemas.android.com/apk/res/android'",
+ " package='com.google.test'>",
+ " </manifest>",
+ "</manifest>");
+ try {
+ new DensitySpecificManifestProcessor(ImmutableList.of("xhdpi"),
+ tmp.resolve("manifest-filtered/AndroidManifest.xml")).process(manifest);
+ fail();
+ } catch (ManifestProcessingException e) {
+ assertThat(e).hasMessageThat().contains("does not contain exactly one <manifest>");
+ }
+ }
+
+ @Before
+ public void setUpEnvironment() throws Exception {
+ fs = Jimfs.newFileSystem();
+ tmp = fs.getPath("/tmp");
+ Files.createDirectory(tmp);
+ }
+
+ @After
+ public void cleanUpEnvironment() throws Exception {
+ fs.close();
+ }
+
+ private Path createManifest(String... lines) throws IOException {
+ final Path path = tmp.resolve("AndroidManifest.xml");
+ Files.createDirectories(path.getParent());
+ Files.deleteIfExists(path);
+ BufferedWriter writer = Files.newBufferedWriter(path, StandardCharsets.UTF_8);
+ writer.write(Joiner.on("\n").join(lines));
+ writer.close();
+ return path;
+ }
+
+ private void checkModification(Path manifest, List<String> densities) throws Exception {
+ Set<String> sizeDensities = new HashSet<>();
+ for (String density : densities) {
+ for (String screenSize : SCREEN_SIZES) {
+ sizeDensities.add(screenSize
+ + PLAY_STORE_SUPPORTED_DENSITIES.get(density));
+ }
+ }
+
+ DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ Document doc = db.parse(Files.newInputStream(manifest));
+ NodeList compatibleScreensNodes = doc.getElementsByTagName("compatible-screens");
+ assertEquals(1, compatibleScreensNodes.getLength());
+ Node compatibleScreens = compatibleScreensNodes.item(0);
+ NodeList screens = doc.getElementsByTagName("screen");
+ assertEquals(densities.size() * SCREEN_SIZES.size(),
+ screens.getLength());
+ for (int i = 0; i < screens.getLength(); i++) {
+ Node s = screens.item(i);
+ assertTrue(s.getParentNode().isSameNode(compatibleScreens));
+ if (s.getNodeType() == Node.ELEMENT_NODE) {
+ Element screen = (Element) s;
+ assertTrue(sizeDensities.remove(
+ screen.getAttribute("android:screenSize")
+ + screen.getAttribute("android:screenDensity")));
+ }
+ }
+ assertThat(sizeDensities).isEmpty();
+ }
+
+ private void checkCompatibleScreensOmitted(Path manifest) throws Exception {
+ DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ Document doc = db.parse(Files.newInputStream(manifest));
+ NodeList compatibleScreensNodes = doc.getElementsByTagName("compatible-screens");
+ assertEquals(0, compatibleScreensNodes.getLength());
+ NodeList screens = doc.getElementsByTagName("screen");
+ assertEquals(0, screens.getLength());
+ }
+
+}
diff --git a/src/test/java/com/google/devtools/build/android/DependencyAndroidDataTest.java b/src/test/java/com/google/devtools/build/android/DependencyAndroidDataTest.java
new file mode 100644
index 0000000000..2026aafb09
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/android/DependencyAndroidDataTest.java
@@ -0,0 +1,166 @@
+// Copyright 2017 The Bazel Authors. All rights reserved.
+//
+// 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 com.google.devtools.build.android;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.jimfs.Jimfs;
+import com.google.common.truth.Truth;
+import java.nio.file.FileSystem;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Tests for the {@link DependencyAndroidData}.
+ */
+@RunWith(JUnit4.class)
+public class DependencyAndroidDataTest {
+ private FileSystem fileSystem;
+ private Path root;
+ private Path rTxt;
+ private Path manifest;
+ private Path res;
+ private Path otherRes;
+ private Path assets;
+ private Path otherAssets;
+ private Path symbols;
+
+ @Before public void setUp() throws Exception {
+ fileSystem = Jimfs.newFileSystem();
+ root = Files.createDirectories(fileSystem.getPath(""));
+ rTxt = Files.createFile(root.resolve("r.txt"));
+ symbols = Files.createFile(root.resolve("symbols.bin"));
+ manifest = Files.createFile(root.resolve("AndroidManifest.xml"));
+ res = Files.createDirectories(root.resolve("res"));
+ otherRes = Files.createDirectories(root.resolve("otherres"));
+ assets = Files.createDirectories(root.resolve("assets"));
+ otherAssets = Files.createDirectories(root.resolve("otherassets"));
+ }
+
+ @Test public void flagFullParse() throws Exception{
+ Truth.assertThat(
+ DependencyAndroidData.valueOf(
+ "res#otherres:assets#otherassets:AndroidManifest.xml:r.txt:symbols.bin", fileSystem)
+ ).isEqualTo(
+ new DependencyAndroidData(ImmutableList.of(res, otherRes),
+ ImmutableList.of(assets, otherAssets),
+ manifest,
+ rTxt,
+ symbols));
+ }
+
+ @Test public void flagParseWithNoSymbolsFile() throws Exception{
+ Truth.assertThat(
+ DependencyAndroidData.valueOf(
+ "res#otherres:assets#otherassets:AndroidManifest.xml:r.txt:", fileSystem)
+ ).isEqualTo(
+ new DependencyAndroidData(ImmutableList.of(res, otherRes),
+ ImmutableList.of(assets, otherAssets),
+ manifest,
+ rTxt,
+ null));
+ }
+
+ @Test public void flagParseOmittedSymbolsFile() throws Exception{
+ Truth.assertThat(
+ DependencyAndroidData.valueOf(
+ "res#otherres:assets#otherassets:AndroidManifest.xml:r.txt", fileSystem)
+ ).isEqualTo(
+ new DependencyAndroidData(ImmutableList.of(res, otherRes),
+ ImmutableList.of(assets, otherAssets),
+ manifest,
+ rTxt,
+ null));
+ }
+
+ @Test public void flagParseWithEmptyResources() throws Exception{
+ Truth.assertThat(
+ DependencyAndroidData.valueOf(
+ ":assets:AndroidManifest.xml:r.txt:symbols.bin", fileSystem)
+ ).isEqualTo(
+ new DependencyAndroidData(ImmutableList.<Path>of(),
+ ImmutableList.of(assets),
+ manifest,
+ rTxt,
+ symbols));
+ }
+
+ @Test public void flagParseWithEmptyAssets() throws Exception{
+ Truth.assertThat(
+ DependencyAndroidData.valueOf(
+ "res::AndroidManifest.xml:r.txt:symbols.bin", fileSystem)
+ ).isEqualTo(
+ new DependencyAndroidData(ImmutableList.of(res),
+ ImmutableList.<Path>of(),
+ manifest,
+ rTxt,
+ symbols));
+ }
+
+ @Test public void flagParseWithEmptyResourcesAndAssets() throws Exception{
+ Truth.assertThat(
+ DependencyAndroidData.valueOf(
+ "::AndroidManifest.xml:r.txt:symbols.bin", fileSystem)
+ ).isEqualTo(
+ new DependencyAndroidData(ImmutableList.<Path>of(),
+ ImmutableList.<Path>of(),
+ manifest,
+ rTxt,
+ symbols));
+ }
+
+ @Test public void flagNoManifestFails() {
+ try {
+ DependencyAndroidData.valueOf(":::r.txt", fileSystem);
+ Assert.fail("expected exception for bad flag format");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ @Test public void flagMissingManifestFails() {
+ try {
+ DependencyAndroidData.valueOf("::Manifest.xml:r.txt:symbols.bin", fileSystem);
+ Assert.fail("expected exception for bad flag format");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ @Test public void flagNoRTxtFails() {
+ try {
+ DependencyAndroidData.valueOf("::AndroidManifest.xml:", fileSystem);
+ Assert.fail("expected exception for bad flag format");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ @Test public void flagMissingRTxtFails() {
+ try {
+ DependencyAndroidData.valueOf("::Manifest.xml:missing_file", fileSystem);
+ Assert.fail("expected exception for bad flag format");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ @Test public void flagMissingSymbolsFails() {
+ try {
+ DependencyAndroidData.valueOf("::Manifest.xml:r.txt:missing_file", fileSystem);
+ Assert.fail("expected exception for bad flag format");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+}
diff --git a/src/test/java/com/google/devtools/build/android/SerializedAndroidDataTest.java b/src/test/java/com/google/devtools/build/android/SerializedAndroidDataTest.java
new file mode 100644
index 0000000000..c40f90438c
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/android/SerializedAndroidDataTest.java
@@ -0,0 +1,113 @@
+// Copyright 2017 The Bazel Authors. All rights reserved.
+//
+// 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 com.google.devtools.build.android;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.jimfs.Jimfs;
+import com.google.common.truth.Truth;
+import java.nio.file.FileSystem;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Tests for the {@link SerializedAndroidData}. */
+@RunWith(JUnit4.class)
+public class SerializedAndroidDataTest {
+ private FileSystem fileSystem;
+ private Path res;
+ private Path otherRes;
+ private Path assets;
+ private Path otherAssets;
+ private String label;
+ private Path symbols;
+
+ @Before
+ public void setUp() throws Exception {
+ fileSystem = Jimfs.newFileSystem();
+ Path root = Files.createDirectories(fileSystem.getPath(""));
+ symbols = Files.createFile(root.resolve("symbols.bin"));
+ res = Files.createDirectories(root.resolve("res"));
+ otherRes = Files.createDirectories(root.resolve("otherres"));
+ assets = Files.createDirectories(root.resolve("assets"));
+ otherAssets = Files.createDirectories(root.resolve("otherassets"));
+ label = "//some_target/foo:foo";
+ }
+
+ @Test
+ public void flagFullParse() throws Exception {
+ Truth.assertThat(
+ SerializedAndroidData.valueOf(
+ "res#otherres;assets#otherassets;//some_target/foo:foo;symbols.bin", fileSystem))
+ .isEqualTo(
+ new SerializedAndroidData(
+ ImmutableList.of(res, otherRes),
+ ImmutableList.of(assets, otherAssets),
+ label,
+ symbols));
+ }
+
+ @Test
+ public void flagParseWithNoSymbolsFile() throws Exception {
+ Truth.assertThat(
+ SerializedAndroidData.valueOf(
+ "res#otherres;assets#otherassets;//some_target/foo:foo;", fileSystem))
+ .isEqualTo(
+ new SerializedAndroidData(
+ ImmutableList.of(res, otherRes),
+ ImmutableList.of(assets, otherAssets),
+ label,
+ null));
+ }
+
+ @Test
+ public void flagParseWithEmptyResources() throws Exception {
+ Truth.assertThat(
+ SerializedAndroidData.valueOf(
+ ";assets;//some_target/foo:foo;symbols.bin", fileSystem))
+ .isEqualTo(
+ new SerializedAndroidData(
+ ImmutableList.<Path>of(), ImmutableList.of(assets), label, symbols));
+ }
+
+ @Test
+ public void flagParseWithEmptyAssets() throws Exception {
+ Truth.assertThat(
+ SerializedAndroidData.valueOf("res;;//some_target/foo:foo;symbols.bin", fileSystem))
+ .isEqualTo(
+ new SerializedAndroidData(
+ ImmutableList.of(res), ImmutableList.<Path>of(), label, symbols));
+ }
+
+ @Test
+ public void flagParseWithEmptyResourcesAndAssets() throws Exception {
+ Truth.assertThat(
+ SerializedAndroidData.valueOf(";;//some_target/foo:foo;symbols.bin", fileSystem))
+ .isEqualTo(
+ new SerializedAndroidData(
+ ImmutableList.<Path>of(), ImmutableList.<Path>of(), label, symbols));
+ }
+
+ @Test
+ public void flagNoLabelFails() {
+ try {
+ SerializedAndroidData.valueOf(";;symbols.bin", fileSystem);
+ Assert.fail("expected exception for bad flag format");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+}
diff --git a/src/test/java/com/google/devtools/build/android/SplitConfigurationFilterTest.java b/src/test/java/com/google/devtools/build/android/SplitConfigurationFilterTest.java
new file mode 100644
index 0000000000..db55ac1e68
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/android/SplitConfigurationFilterTest.java
@@ -0,0 +1,327 @@
+// Copyright 2017 The Bazel Authors. All rights reserved.
+//
+// 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 com.google.devtools.build.android;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+import static com.google.devtools.build.android.SplitConfigurationFilter.mapFilenamesToSplitFlags;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.testing.EqualsTester;
+import com.google.common.truth.BooleanSubject;
+import com.google.devtools.build.android.SplitConfigurationFilter.ResourceConfiguration;
+import com.google.devtools.build.android.SplitConfigurationFilter.UnrecognizedSplitsException;
+import javax.annotation.CheckReturnValue;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Tests for {@link SplitConfigurationFilter}. */
+@RunWith(JUnit4.class)
+public final class SplitConfigurationFilterTest {
+
+ @Test
+ public void mapFilenamesToSplitFlagsShouldReturnEmptyMapForEmptyInput()
+ throws UnrecognizedSplitsException {
+ assertThat(mapFilenamesToSplitFlags(ImmutableList.<String>of(), ImmutableList.<String>of()))
+ .isEmpty();
+ }
+
+ @Test
+ public void mapFilenamesToSplitFlagsShouldMatchIdenticalFilenames()
+ throws UnrecognizedSplitsException {
+ assertThat(mapFilenamesToSplitFlags(ImmutableList.of("en"), ImmutableList.of("en")))
+ .containsExactly("en", "en");
+ assertThat(mapFilenamesToSplitFlags(ImmutableList.of("fr-v7"), ImmutableList.of("fr-v7")))
+ .containsExactly("fr-v7", "fr-v7");
+ assertThat(mapFilenamesToSplitFlags(ImmutableList.of("en_fr-v7"), ImmutableList.of("en,fr-v7")))
+ .containsExactly("en_fr-v7", "en_fr-v7");
+ assertThat(
+ mapFilenamesToSplitFlags(
+ ImmutableList.of("en", "fr-v7"), ImmutableList.of("en", "fr-v7")))
+ .containsExactly("en", "en", "fr-v7", "fr-v7");
+ assertThat(
+ mapFilenamesToSplitFlags(
+ ImmutableList.of("fr-v4", "fr-v7"), ImmutableList.of("fr-v4", "fr-v7")))
+ .containsExactly("fr-v4", "fr-v4", "fr-v7", "fr-v7");
+ }
+
+ @Test
+ public void mapFilenamesToSplitFlagsShouldMatchReorderedFilenames()
+ throws UnrecognizedSplitsException {
+ assertThat(mapFilenamesToSplitFlags(ImmutableList.of("en_fr_ja"), ImmutableList.of("ja,fr,en")))
+ .containsExactly("en_fr_ja", "ja_fr_en");
+ assertThat(
+ mapFilenamesToSplitFlags(
+ ImmutableList.of("zu_12key", "zu"), ImmutableList.of("12key,zu", "zu")))
+ .containsExactly("zu_12key", "12key_zu", "zu", "zu");
+ assertThat(
+ mapFilenamesToSplitFlags(
+ ImmutableList.of("land_car", "round_port"),
+ ImmutableList.of("car,land", "port,round")))
+ .containsExactly("land_car", "car_land", "round_port", "port_round");
+ }
+
+ @Test
+ public void mapFilenamesToSplitFlagsShouldMatchVersionUpgradedFilenames()
+ throws UnrecognizedSplitsException {
+ assertThat(mapFilenamesToSplitFlags(ImmutableList.of("round-v23"), ImmutableList.of("round")))
+ .containsExactly("round-v23", "round");
+ assertThat(
+ mapFilenamesToSplitFlags(
+ ImmutableList.of("watch-v20", "watch-v23"), ImmutableList.of("watch", "watch-v23")))
+ .containsExactly("watch-v20", "watch", "watch-v23", "watch-v23");
+ }
+
+ @Test
+ public void equivalentFiltersShouldMatchFilterFromFilename() {
+ // identical inputs (barring commas -> underscores) should naturally match
+ assertMatchesFilterFromFilename("abc-def", "abc-def").isTrue();
+ assertMatchesFilterFromFilename("abc-def-v5,ghi,jkl-lmno", "abc-def-v5_ghi_jkl-lmno").isTrue();
+ // anything that results in matching sets should work, so case should be ignored
+ assertMatchesFilterFromFilename("abc-dEF", "aBC-def").isTrue();
+ assertMatchesFilterFromFilename("aBC-def", "abc-dEF").isTrue();
+ // additionally, order of elements in the set should be ignored
+ assertMatchesFilterFromFilename("abc,def", "def_abc").isTrue();
+ assertMatchesFilterFromFilename("def,abc", "abc_def").isTrue();
+ }
+
+ @Test
+ public void matchingSpecifiersShouldMatchFilterFromFilenameWhenVersionsAreHigherNotWhenLower() {
+ // different (higher) versions, but same specifiers and same order
+ assertMatchesFilterFromFilename("x-v5,y-v6", "x-v7_y-v9").isTrue();
+ assertMatchesFilterFromFilename("x-v7,y-v9", "x-v5_y-v6").isFalse();
+ // order of sorted set changes but matching specifiers still match and filename version > flag
+ assertMatchesFilterFromFilename("x-v3,y-v6", "x-v23_y-v9").isTrue();
+ assertMatchesFilterFromFilename("x-v23,y-v9", "x-v3_y-v6").isFalse();
+ // specifier sets of multiple configs are the same
+ assertMatchesFilterFromFilename("x-v3,x-v17", "x-v3_x-v17").isTrue();
+ assertMatchesFilterFromFilename("x-v3,x-v17", "x-v17_x-v3").isTrue();
+ assertMatchesFilterFromFilename("x-v17,x-v3", "x-v17_x-v3").isTrue();
+ assertMatchesFilterFromFilename("x-v17,x-v3", "x-v3_x-v17").isTrue();
+ // specifier sets are the same, but one of them got a version bump
+ assertMatchesFilterFromFilename("x-v3,x-v17", "x-v14_x-v17").isTrue();
+ assertMatchesFilterFromFilename("x-v14,x-v17", "x-v3_x-v17").isFalse();
+ }
+
+ @Test
+ public void nonMatchingSpecifiersShouldNotMatchFilterFromFilename() {
+ // completely disjoint specifier sets
+ assertMatchesFilterFromFilename("x,y,z", "a_b_c").isFalse();
+ assertMatchesFilterFromFilename("a,b,c", "x_y_z").isFalse();
+ // different number of specifier sets, which otherwise match
+ assertMatchesFilterFromFilename("x,y,z", "x_y").isFalse();
+ assertMatchesFilterFromFilename("x,y", "x_y_z").isFalse();
+ // same number of specifiers with one non-match
+ assertMatchesFilterFromFilename("x,y,z", "a_y_z").isFalse();
+ assertMatchesFilterFromFilename("a,b,c", "a_b_z").isFalse();
+ }
+
+ @CheckReturnValue
+ private BooleanSubject assertMatchesFilterFromFilename(String flagFilter, String filenameFilter) {
+ return assertWithMessage(
+ "The split flag '%s' would be a match for a filename containing '%s'",
+ flagFilter, filenameFilter)
+ .that(
+ SplitConfigurationFilter.fromSplitFlag(flagFilter)
+ .matchesFilterFromFilename(
+ SplitConfigurationFilter.fromFilenameSuffix(filenameFilter)));
+ }
+
+ @Test
+ public void splitConfigurationFilterShouldBeOrderedByConfigsThenFilename() {
+ assertThat(
+ ImmutableList.of(
+ // If all else is equal, break ties via filename (case does matter here)
+ SplitConfigurationFilter.fromFilenameSuffix("A"),
+ SplitConfigurationFilter.fromFilenameSuffix("a"),
+ // In filters with the same number of configs, the highest version wins
+ SplitConfigurationFilter.fromFilenameSuffix("d-v5_e-v5_f-v5"),
+ SplitConfigurationFilter.fromFilenameSuffix("a_b_c-v6"),
+ // It doesn't matter where in the input order that version is
+ SplitConfigurationFilter.fromFilenameSuffix("a-v7_b_c"),
+ // Specifiers break ties on number of configs + highest version
+ SplitConfigurationFilter.fromFilenameSuffix("d-v7_b_c"),
+ // Second highest version breaks ties (etc.)
+ SplitConfigurationFilter.fromFilenameSuffix("b-v2_d-v7_c"),
+ // Order doesn't matter but it does change the filename, hence sort order
+ SplitConfigurationFilter.fromFilenameSuffix("d-v7_b-v2_c"),
+ // Number of configs is the main criterion, so more sets of configs means later sort
+ SplitConfigurationFilter.fromFilenameSuffix("a_b_c_d_e_f_g_h_i_j_k_l_m")))
+ .isStrictlyOrdered();
+
+ // if they are actually equal, they will compare equal
+ assertThat(SplitConfigurationFilter.fromFilenameSuffix("c-v13"))
+ .isEquivalentAccordingToCompareTo(SplitConfigurationFilter.fromFilenameSuffix("c-v13"));
+
+ // if the only difference is split flag vs. filename suffix they will compare equal
+ assertThat(SplitConfigurationFilter.fromSplitFlag("split,split"))
+ .isEquivalentAccordingToCompareTo(
+ SplitConfigurationFilter.fromFilenameSuffix("split_split"));
+ }
+
+ @Test
+ public void splitConfigurationFilterEqualsShouldPassEqualsTester() {
+ new EqualsTester()
+ .addEqualityGroup(
+ // base example
+ SplitConfigurationFilter.fromFilenameSuffix("abc-def_ghi_jkl"),
+ // identical clone
+ SplitConfigurationFilter.fromFilenameSuffix("abc-def_ghi_jkl"),
+ // commas are converted for split flags, the result is equal
+ SplitConfigurationFilter.fromSplitFlag("abc-def,ghi,jkl"))
+ .addEqualityGroup(
+ // case matters for filenames
+ SplitConfigurationFilter.fromFilenameSuffix("aBC-dEF_ghi_jkl"))
+ .addEqualityGroup(
+ // different filename producing equal set (elements parse the same) is still different
+ SplitConfigurationFilter.fromFilenameSuffix("abc-def-v0_ghi_jkl"))
+ .addEqualityGroup(
+ // different filename producing equal set (input order is different) is still different
+ SplitConfigurationFilter.fromFilenameSuffix("ghi_abc-def_jkl"))
+ .addEqualityGroup(
+ // totally different set is also very clearly different
+ SplitConfigurationFilter.fromFilenameSuffix("some-other_specifiers"))
+ .testEquals();
+ }
+
+ @Test
+ public void equalInputsShouldMatchConfigurationFromFilename() {
+ // identical inputs should naturally match
+ assertMatchesConfigurationFromFilename("abc-def", "abc-def").isTrue();
+ assertMatchesConfigurationFromFilename("abc-def-v5", "abc-def-v5").isTrue();
+ // case should be ignored
+ assertMatchesConfigurationFromFilename("abc-dEF", "aBC-def").isTrue();
+ assertMatchesConfigurationFromFilename("aBC-def", "abc-dEF").isTrue();
+ // wildcards should be ignored
+ assertMatchesConfigurationFromFilename("any-abc-def", "abc-any-def").isTrue();
+ assertMatchesConfigurationFromFilename("abc-any-def", "any-abc-def").isTrue();
+ // v0 should be ignored
+ assertMatchesConfigurationFromFilename("abc-def", "abc-def-v0").isTrue();
+ assertMatchesConfigurationFromFilename("abc-def-v0", "abc-def").isTrue();
+ }
+
+ @Test
+ public void higherVersionSameSpecifiersShouldMatchConfigurationFromFilename() {
+ // any version is higher than the default v0
+ assertMatchesConfigurationFromFilename("abc-def", "abc-def-v1").isTrue();
+ assertMatchesConfigurationFromFilename("abc-def-v1", "abc-def").isFalse();
+ // same deal for explicit v0
+ assertMatchesConfigurationFromFilename("abc-def-v0", "abc-def-v1").isTrue();
+ assertMatchesConfigurationFromFilename("abc-def-v1", "abc-def-v0").isFalse();
+ // higher versions are better of course
+ assertMatchesConfigurationFromFilename("abc-def-v1", "abc-def-v999").isTrue();
+ assertMatchesConfigurationFromFilename("abc-def-v999", "abc-def-v1").isFalse();
+ }
+
+ @Test
+ public void nonMatchingSpecifiersShouldNotMatchConfigurationFromFilename() {
+ // same version
+ assertMatchesConfigurationFromFilename("abc", "ghi").isFalse();
+ assertMatchesConfigurationFromFilename("abc-v0", "ghi-v0").isFalse();
+ assertMatchesConfigurationFromFilename("abc-v15", "ghi-v15").isFalse();
+ // different version
+ assertMatchesConfigurationFromFilename("abc", "ghi-v15").isFalse();
+ assertMatchesConfigurationFromFilename("abc-v0", "ghi-v15").isFalse();
+ assertMatchesConfigurationFromFilename("abc-v15", "ghi-v19").isFalse();
+ }
+
+ @CheckReturnValue
+ private BooleanSubject assertMatchesConfigurationFromFilename(
+ String flagConfiguration, String fileConfiguration) {
+ return assertWithMessage(
+ "The split flag '%s' would be a match for a filename containing '%s'",
+ flagConfiguration, fileConfiguration)
+ .that(
+ ResourceConfiguration.fromString(flagConfiguration)
+ .matchesConfigurationFromFilename(
+ ResourceConfiguration.fromString(fileConfiguration)));
+ }
+
+ @Test
+ public void resourceConfigurationShouldBeOrderedByApiVersionThenSpecifiers() {
+ assertThat(
+ ImmutableList.of(
+ // -v0 and no -v0 sort equal given the same specifiers, so it's a tie
+ ResourceConfiguration.fromString("a"),
+ // version ties are broken based on lexicographic string ordering
+ ResourceConfiguration.fromString("b-v0"),
+ // string ordering ignores case of the specifiers
+ ResourceConfiguration.fromString("Z"),
+ // higher API versions sort later regardless of the specifiers
+ ResourceConfiguration.fromString("z-v6"),
+ ResourceConfiguration.fromString("b-v13"),
+ // wildcards ("any") are ignored when considering specifier order
+ ResourceConfiguration.fromString("any-c-v13")))
+ .isStrictlyOrdered();
+
+ // if they are actually equal, they will compare equal
+ assertThat(ResourceConfiguration.fromString("c-v13"))
+ .isEquivalentAccordingToCompareTo(ResourceConfiguration.fromString("c-v13"));
+
+ // if the only difference is wildcards they will compare equal
+ assertThat(ResourceConfiguration.fromString("any-c-v13"))
+ .isEquivalentAccordingToCompareTo(ResourceConfiguration.fromString("c-v13"));
+
+ // if the only difference is specifying (or not specifying) -v0 they will compare equal
+ assertThat(ResourceConfiguration.fromString("a-v0"))
+ .isEquivalentAccordingToCompareTo(ResourceConfiguration.fromString("a"));
+
+ // if the only difference is case they will compare equal
+ assertThat(ResourceConfiguration.fromString("z"))
+ .isEquivalentAccordingToCompareTo(ResourceConfiguration.fromString("Z"));
+ }
+
+ @Test
+ public void resourceConfigurationShouldPassEqualsTester() {
+ new EqualsTester()
+ .addEqualityGroup(
+ // base example
+ ResourceConfiguration.fromString("abc-def"),
+ // identical clone
+ ResourceConfiguration.fromString("abc-def"),
+ // case doesn't matter
+ ResourceConfiguration.fromString("aBC-dEF"),
+ // absent version code is equivalent to -v0
+ ResourceConfiguration.fromString("abc-def-v0"),
+ // skip "any"
+ ResourceConfiguration.fromString("any-abc-any-def-any"))
+ .addEqualityGroup(
+ // order matters
+ ResourceConfiguration.fromString("def-abc"))
+ .addEqualityGroup(
+ // empty segments are not collapsed
+ ResourceConfiguration.fromString("abc---def"))
+ .addEqualityGroup(
+ // different version codes are parsed but result in a non-equal instance
+ ResourceConfiguration.fromString("abc-def-v15"))
+ .addEqualityGroup(
+ // two configurations with version codes must also have EQUAL version codes
+ ResourceConfiguration.fromString("abc-def-v12"))
+ .addEqualityGroup(
+ // empty strings are equal
+ ResourceConfiguration.fromString(""),
+ // yes, even if they have a v0
+ ResourceConfiguration.fromString("v0"),
+ // or if there are some wildcards which will collapse to nothing
+ ResourceConfiguration.fromString("any"),
+ ResourceConfiguration.fromString("any-v0"),
+ ResourceConfiguration.fromString("any-any-any"),
+ ResourceConfiguration.fromString("any-any-any-v0"))
+ .addEqualityGroup(
+ // not if the version is nonzero though
+ ResourceConfiguration.fromString("v15"), ResourceConfiguration.fromString("any-v15"))
+ .testEquals();
+ }
+}
diff --git a/src/test/java/com/google/devtools/build/android/UnvalidatedAndroidDataTest.java b/src/test/java/com/google/devtools/build/android/UnvalidatedAndroidDataTest.java
new file mode 100644
index 0000000000..0ee7b25b4f
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/android/UnvalidatedAndroidDataTest.java
@@ -0,0 +1,104 @@
+// Copyright 2017 The Bazel Authors. All rights reserved.
+//
+// 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 com.google.devtools.build.android;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.jimfs.Jimfs;
+import com.google.common.truth.Truth;
+import java.nio.file.FileSystem;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Tests for {@link UnvalidatedAndroidData}. */
+@RunWith(JUnit4.class)
+public class UnvalidatedAndroidDataTest {
+ private FileSystem fileSystem;
+ private Path root;
+ private Path manifest;
+ private Path res;
+ private Path otherRes;
+ private Path assets;
+ private Path otherAssets;
+
+ @Before public void setUp() throws Exception {
+ fileSystem = Jimfs.newFileSystem();
+ root = fileSystem.getPath("");
+ manifest = Files.createFile(root.resolve("AndroidManifest.xml"));
+ res = Files.createDirectories(root.resolve("res"));
+ otherRes = Files.createDirectories(root.resolve("otherres"));
+ assets = Files.createDirectories(root.resolve("assets"));
+ otherAssets = Files.createDirectories(root.resolve("otherassets"));
+ }
+
+ @Test public void flagFullParse() throws Exception {
+ Truth.assertThat(
+ UnvalidatedAndroidData.valueOf(
+ "res#otherres:assets#otherassets:AndroidManifest.xml", fileSystem)
+ ).isEqualTo(
+ new UnvalidatedAndroidData(ImmutableList.of(res, otherRes),
+ ImmutableList.of(assets, otherAssets),
+ manifest));
+ }
+
+ @Test public void flagParseWithEmptyResources() throws Exception {
+ Truth.assertThat(
+ UnvalidatedAndroidData.valueOf(
+ ":assets:AndroidManifest.xml", fileSystem)
+ ).isEqualTo(
+ new UnvalidatedAndroidData(ImmutableList.<Path>of(),
+ ImmutableList.of(assets),
+ manifest));
+ }
+
+ @Test public void flagParseWithEmptyAssets() throws Exception {
+ Truth.assertThat(
+ UnvalidatedAndroidData.valueOf(
+ "res::AndroidManifest.xml", fileSystem)
+ ).isEqualTo(
+ new UnvalidatedAndroidData(ImmutableList.of(res),
+ ImmutableList.<Path>of(),
+ manifest));
+ }
+
+ @Test public void flagParseWithEmptyResourcesAndAssets() throws Exception {
+ Truth.assertThat(
+ UnvalidatedAndroidData.valueOf(
+ "::AndroidManifest.xml", fileSystem)
+ ).isEqualTo(
+ new UnvalidatedAndroidData(ImmutableList.<Path>of(),
+ ImmutableList.<Path>of(),
+ manifest));
+ }
+
+ @Test public void flagNoManifestFails() {
+ try {
+ UnvalidatedAndroidData.valueOf("::", fileSystem);
+ Assert.fail("expected exception for bad flag format");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ @Test public void flagMissingManifestFails() {
+ try {
+ UnvalidatedAndroidData.valueOf("::Manifest.xml", fileSystem);
+ Assert.fail("expected exception for bad flag format");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+}
diff --git a/src/test/java/com/google/devtools/build/android/UnvalidatedAndroidDirectoriesTest.java b/src/test/java/com/google/devtools/build/android/UnvalidatedAndroidDirectoriesTest.java
new file mode 100644
index 0000000000..1d70d81915
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/android/UnvalidatedAndroidDirectoriesTest.java
@@ -0,0 +1,81 @@
+// Copyright 2017 The Bazel Authors. All rights reserved.
+//
+// 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 com.google.devtools.build.android;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.jimfs.Jimfs;
+import com.google.common.truth.Truth;
+import java.nio.file.FileSystem;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Tests for {@link UnvalidatedAndroidDirectories}. */
+@RunWith(JUnit4.class)
+public class UnvalidatedAndroidDirectoriesTest {
+ private FileSystem fileSystem;
+ private Path res;
+ private Path otherRes;
+ private Path assets;
+ private Path otherAssets;
+
+ @Before public void setUp() throws Exception {
+ fileSystem = Jimfs.newFileSystem();
+ Path root = fileSystem.getPath("");
+ res = Files.createDirectories(root.resolve("res"));
+ otherRes = Files.createDirectories(root.resolve("otherres"));
+ assets = Files.createDirectories(root.resolve("assets"));
+ otherAssets = Files.createDirectories(root.resolve("otherassets"));
+ }
+
+ @Test public void flagFullParse() throws Exception {
+ Truth.assertThat(
+ UnvalidatedAndroidDirectories.valueOf(
+ "res#otherres:assets#otherassets", fileSystem)
+ ).isEqualTo(
+ new UnvalidatedAndroidDirectories(ImmutableList.of(res, otherRes),
+ ImmutableList.of(assets, otherAssets)));
+ }
+
+ @Test public void flagParseWithEmptyAssets() throws Exception {
+ Truth.assertThat(
+ UnvalidatedAndroidDirectories.valueOf(
+ "res:", fileSystem)
+ ).isEqualTo(
+ new UnvalidatedAndroidDirectories(ImmutableList.of(res),
+ ImmutableList.<Path>of()));
+ }
+
+ @Test public void flagParseWithEmptyResources() throws Exception {
+ Truth.assertThat(
+ UnvalidatedAndroidDirectories.valueOf(
+ ":assets", fileSystem)
+ ).isEqualTo(
+ new UnvalidatedAndroidDirectories(ImmutableList.<Path>of(),
+ ImmutableList.of(assets)));
+ }
+
+ @Test public void flagParseWithEmptyResourcesAndAssets() throws Exception {
+ Truth.assertThat(
+ UnvalidatedAndroidDirectories.valueOf(
+ ":", fileSystem)
+ ).isEqualTo(
+ new UnvalidatedAndroidDirectories(ImmutableList.<Path>of(),
+ ImmutableList.<Path>of()));
+ }
+
+}