/*
* Copyright 2014-present Facebook, Inc.
*
* 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.facebook.buck.android.aapt;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import com.facebook.buck.android.aapt.MiniAapt.ResourceParseException;
import com.facebook.buck.android.aapt.RDotTxtEntry.IdType;
import com.facebook.buck.android.aapt.RDotTxtEntry.RType;
import com.facebook.buck.event.DefaultBuckEventBus;
import com.facebook.buck.model.BuildId;
import com.facebook.buck.rules.BuildRuleResolver;
import com.facebook.buck.rules.DefaultTargetNodeToBuildRuleTransformer;
import com.facebook.buck.rules.FakeSourcePath;
import com.facebook.buck.rules.SourcePathResolver;
import com.facebook.buck.rules.SourcePathRuleFinder;
import com.facebook.buck.rules.TargetGraph;
import com.facebook.buck.testutil.FakeProjectFilesystem;
import com.facebook.buck.timing.FakeClock;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import org.hamcrest.core.IsEqual;
import org.hamcrest.junit.ExpectedException;
import org.junit.Rule;
import org.junit.Test;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Set;
import javax.xml.xpath.XPathExpressionException;
public class MiniAaptTest {
private static final ImmutableList<String> RESOURCES =
ImmutableList.<String>builder()
.add(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>",
"<LinearLayout>",
"<Button android:id=\"@+id/button1\" ",
"android:layout_toLeftOf=\"@id/button2\" ",
"android:text=\"@string/text\" />",
"<Button android:id=\"@+id/button3\" ",
"style:attribute=\"@style/Buck.Theme\" ",
"android:background=\"@drawable/some_image\" />",
"<TextView tools:showIn=\"@layout/some_layout\" android:id=\"@id/android:empty\" />",
"</LinearLayout>")
.build();
private final FakeProjectFilesystem filesystem = new FakeProjectFilesystem();
private final SourcePathResolver resolver =
new SourcePathResolver(
new SourcePathRuleFinder(
new BuildRuleResolver(
TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer())));
@Rule
public ExpectedException thrown = ExpectedException.none();
@Test
public void testFindingResourceIdsInXml()
throws IOException, XPathExpressionException, ResourceParseException {
filesystem.writeLinesToPath(RESOURCES, Paths.get("resource.xml"));
MiniAapt aapt =
new MiniAapt(
resolver,
filesystem,
new FakeSourcePath(filesystem, "res"),
Paths.get("R.txt"),
ImmutableSet.of());
ImmutableSet.Builder<RDotTxtEntry> references = ImmutableSet.builder();
aapt.processXmlFile(filesystem, Paths.get("resource.xml"), references);
Set<RDotTxtEntry> definitions = aapt.getResourceCollector().getResources();
assertEquals(
definitions,
ImmutableSet.<RDotTxtEntry>of(
new FakeRDotTxtEntry(IdType.INT, RType.ID, "button1"),
new FakeRDotTxtEntry(IdType.INT, RType.ID, "button3")));
assertEquals(
references.build(),
ImmutableSet.<RDotTxtEntry>of(
new FakeRDotTxtEntry(IdType.INT, RType.DRAWABLE, "some_image"),
new FakeRDotTxtEntry(IdType.INT, RType.STRING, "text"),
new FakeRDotTxtEntry(IdType.INT, RType.STYLE, "Buck_Theme"),
new FakeRDotTxtEntry(IdType.INT, RType.ID, "button2")));
}
@Test
public void testParsingFilesUnderValuesDirectory() throws IOException, ResourceParseException {
ImmutableList<String> lines =
ImmutableList.<String>builder()
.add(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>",
"<resources>",
"<string name=\"hello\">Hello, <xliff:g id=\"name\">%s</xliff:g>!</string>",
"<plurals name=\"people\">",
" <item quantity=\"zero\">ignore1</item>",
" <item quantity=\"many\">ignore2</item>",
"</plurals>",
"<skip />",
"<integer name=\"number\">100</integer>",
"<dimen name=\"dimension\">100sp</dimen>",
"<declare-styleable name=\"MyNiceView\">",
" <attr name=\"titleText\" />",
" <attr name=\"subtitleText\" format=\"string\" />",
" <attr name=\"complexAttr\">",
" <enum name=\"shouldBeIgnored\" value=\"0\" />",
" <enum name=\"alsoIgnore\" value=\"1\" />",
" <flag name=\"uselessFlag\" value=\"0x00\" />",
" </attr>",
" <attr name=\"android:layout_gravity\" />",
" <item name=\"should_be_ignored\" />",
"</declare-styleable>",
"<eat-comment />",
"<item type=\"id\" name=\"some_id\" />",
"<style name=\"Widget.Theme\">",
" <item name=\"ignoreMe\" />",
"</style>",
"</resources>")
.build();
filesystem.writeLinesToPath(lines, Paths.get("values.xml"));
MiniAapt aapt =
new MiniAapt(
resolver,
filesystem,
new FakeSourcePath(filesystem, "res"),
Paths.get("R.txt"),
ImmutableSet.of());
aapt.processValuesFile(filesystem, Paths.get("values.xml"));
Set<RDotTxtEntry> definitions = aapt.getResourceCollector().getResources();
assertEquals(
definitions,
ImmutableSet.<RDotTxtEntry>of(
new FakeRDotTxtEntry(IdType.INT, RType.STRING, "hello"),
new FakeRDotTxtEntry(IdType.INT, RType.PLURALS, "people"),
new FakeRDotTxtEntry(IdType.INT, RType.INTEGER, "number"),
new FakeRDotTxtEntry(IdType.INT, RType.DIMEN, "dimension"),
new FakeRDotTxtEntry(IdType.INT_ARRAY, RType.STYLEABLE, "MyNiceView"),
new FakeRDotTxtEntry(IdType.INT, RType.STYLEABLE, "MyNiceView_titleText"),
new FakeRDotTxtEntry(IdType.INT, RType.STYLEABLE, "MyNiceView_subtitleText"),
new FakeRDotTxtEntry(IdType.INT, RType.STYLEABLE, "MyNiceView_complexAttr"),
new FakeRDotTxtEntry(IdType.INT, RType.STYLEABLE, "MyNiceView_android_layout_gravity"),
new FakeRDotTxtEntry(IdType.INT, RType.ATTR, "titleText"),
new FakeRDotTxtEntry(IdType.INT, RType.ATTR, "subtitleText"),
new FakeRDotTxtEntry(IdType.INT, RType.ATTR, "complexAttr"),
new FakeRDotTxtEntry(IdType.INT, RType.ID, "some_id"),
new FakeRDotTxtEntry(IdType.INT, RType.STYLE, "Widget_Theme")));
boolean foundElement = false;
for (RDotTxtEntry definition : definitions) {
if (definition.name.equals("MyNiceView")) {
assertEquals("{ 0x7f060001,0x7f060002,0x7f060003,0x7f060004 }", definition.idValue);
foundElement = true;
}
}
assertTrue(foundElement);
}
@Test
public void testParentIsSet() throws IOException, ResourceParseException {
ImmutableList<String> lines =
ImmutableList.<String>builder()
.add(
"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" +
"<resources>\n" +
" <attr name=\"justAttr\"/>\n" +
" <declare-styleable name=\"MyLayout\">\n" +
" <attr name=\"myAttr\"/>\n" +
" <attr name=\"myAttr2\"/>\n" +
" </declare-styleable>\n" +
" <declare-styleable name=\"MyLayout_Layout\">\n" +
" <attr name=\"android:text\"/>\n" +
" <attr name=\"android:color\"/>\n" +
" </declare-styleable>\n" +
"</resources>")
.build();
filesystem.writeLinesToPath(lines, Paths.get("values.xml"));
MiniAapt aapt =
new MiniAapt(
resolver,
filesystem,
new FakeSourcePath(filesystem, "res"),
Paths.get("R.txt"),
ImmutableSet.of());
aapt.processValuesFile(filesystem, Paths.get("values.xml"));
Set<RDotTxtEntry> definitions = aapt.getResourceCollector().getResources();
assertThat(definitions.size(), equalTo(9));
for (RDotTxtEntry entry : definitions) {
switch (entry.name) {
case "justAttr":
assertEquals("justAttr", entry.parent);
break;
case "MyLayout":
assertEquals("MyLayout", entry.parent);
break;
case "MyLayout_myAttr":
assertEquals("MyLayout", entry.parent);
break;
case "MyLayout_myAttr2":
assertEquals("MyLayout", entry.parent);
break;
case "MyLayout_Layout":
assertEquals("MyLayout_Layout", entry.parent);
break;
case "MyLayout_Layout_android_text":
assertEquals("MyLayout_Layout", entry.parent);
break;
case "MyLayout_Layout_android_color":
assertEquals("MyLayout_Layout", entry.parent);
break;
case "myAttr":
assertEquals("myAttr", entry.parent);
break;
case "myAttr2":
assertEquals("myAttr2", entry.parent);
break;
default:
fail("Unexpected entry: " + entry.name);
}
}
}
@Test
public void testParsingValuesExcludedFromResMap() throws IOException, ResourceParseException {
ImmutableList<String> lines =
ImmutableList.<String>builder()
.add(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>",
"<resources exclude-from-buck-resource-map=\"true\">",
"<string name=\"hello\">Hello, <xliff:g id=\"name\">%s</xliff:g>!</string>",
"</resources>")
.build();
filesystem.writeLinesToPath(lines, Paths.get("values.xml"));
MiniAapt aapt =
new MiniAapt(
resolver,
filesystem,
new FakeSourcePath(filesystem, "res"),
Paths.get("R.txt"),
ImmutableSet.of());
aapt.processValuesFile(filesystem, Paths.get("values.xml"));
Set<RDotTxtEntry> definitions = aapt.getResourceCollector().getResources();
assertTrue(definitions.isEmpty());
}
@Test
public void testParsingValuesNotExcludedFromResMap() throws IOException, ResourceParseException {
ImmutableList<String> lines =
ImmutableList.<String>builder()
.add(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>",
"<resources exclude-from-buck-resource-map=\"false\">",
"<string name=\"hello\">Hello, <xliff:g id=\"name\">%s</xliff:g>!</string>",
"</resources>")
.build();
filesystem.writeLinesToPath(lines, Paths.get("values.xml"));
MiniAapt aapt =
new MiniAapt(
resolver,
filesystem,
new FakeSourcePath(filesystem, "res"),
Paths.get("R.txt"),
ImmutableSet.of());
aapt.processValuesFile(filesystem, Paths.get("values.xml"));
Set<RDotTxtEntry> definitions = aapt.getResourceCollector().getResources();
assertEquals(
definitions,
ImmutableSet.<RDotTxtEntry>of(new FakeRDotTxtEntry(IdType.INT, RType.STRING, "hello")));
}
@Test
public void testParsingAndroidDrawables() throws IOException, ResourceParseException {
ImmutableList<String> lines =
ImmutableList.<String>builder()
.add(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>",
"<bitmap xmlns:android=\"http://schemas.android.com/apk/res/android\">",
" xmlns:fbui=\"http://schemas.android.com/apk/res-auto\"",
" android:src=\"@drawable/other_bitmap\"",
" >",
"</bitmap>")
.build();
filesystem.writeLinesToPath(lines, Paths.get("android_drawable.xml"));
MiniAapt aapt =
new MiniAapt(
resolver,
filesystem,
new FakeSourcePath(filesystem, "res"),
Paths.get("R.txt"),
ImmutableSet.of());
aapt.processDrawables(filesystem, Paths.get("android_drawable.xml"));
Set<RDotTxtEntry> definitions = aapt.getResourceCollector().getResources();
assertThat(
definitions,
IsEqual.equalToObject(
ImmutableSet.<RDotTxtEntry>of(
new FakeRDotTxtEntry(IdType.INT, RType.DRAWABLE, "android_drawable"))));
}
@Test
public void testParsingCustomDrawables() throws IOException, ResourceParseException {
ImmutableList<String> lines =
ImmutableList.<String>builder()
.add(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>",
"<app-network xmlns:android=\"http://schemas.android.com/apk/res/android\">",
" xmlns:fbui=\"http://schemas.android.com/apk/res-auto\"",
" fbui:imageUri=\"http://facebook.com\"",
" android:width=\"128px\"",
" android:height=\"128px\"",
" fbui:density=\"160\"",
" >",
"</app-network>")
.build();
filesystem.writeLinesToPath(lines, Paths.get("custom_drawable.xml"));
MiniAapt aapt =
new MiniAapt(
resolver,
filesystem,
new FakeSourcePath(filesystem, "res"),
Paths.get("R.txt"),
ImmutableSet.of());
aapt.processDrawables(filesystem, Paths.get("custom_drawable.xml"));
Set<RDotTxtEntry> definitions = aapt.getResourceCollector().getResources();
assertThat(
definitions,
IsEqual.equalToObject(
ImmutableSet.<RDotTxtEntry>of(
new FakeRDotTxtEntry(
IdType.INT,
RType.DRAWABLE,
"custom_drawable",
RDotTxtEntry.CustomDrawableType.CUSTOM))));
}
@Test
public void testParsingGrayscaleImage() throws IOException, ResourceParseException {
ImmutableList<String> lines = ImmutableList.<String>builder().add("").build();
filesystem.writeLinesToPath(lines, Paths.get("fbui_tomato.png"));
MiniAapt aapt =
new MiniAapt(
resolver,
filesystem,
new FakeSourcePath(filesystem, "res"),
Paths.get("R.txt"),
ImmutableSet.of(),
/* resourceUnion */ false,
/* isGrayscaleImageProcessingEnabled */ true);
aapt.processDrawables(filesystem, Paths.get("fbui_tomato.g.png"));
Set<RDotTxtEntry> definitions = aapt.getResourceCollector().getResources();
assertThat(
definitions,
IsEqual.equalToObject(
ImmutableSet.<RDotTxtEntry>of(
new FakeRDotTxtEntry(
IdType.INT,
RType.DRAWABLE,
"fbui_tomato",
RDotTxtEntry.CustomDrawableType.GRAYSCALE_IMAGE))));
}
@Test(expected = ResourceParseException.class)
public void testInvalidResourceType() throws IOException, ResourceParseException {
ImmutableList<String> lines =
ImmutableList.<String>builder()
.add(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>",
"<resources>",
"<resourcetype name=\"number\">100</resourcetype>",
"</resources>")
.build();
filesystem.writeLinesToPath(lines, Paths.get("values.xml"));
MiniAapt aapt =
new MiniAapt(
resolver,
filesystem,
new FakeSourcePath(filesystem, "res"),
Paths.get("R.txt"),
ImmutableSet.of());
aapt.processValuesFile(filesystem, Paths.get("values.xml"));
}
@Test(expected = ResourceParseException.class)
public void testInvalidItemResource() throws IOException, ResourceParseException {
ImmutableList<String> lines =
ImmutableList.<String>builder()
.add(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>",
"<resources>",
"<item name=\"number\">100</item>",
"</resources>")
.build();
filesystem.writeLinesToPath(lines, Paths.get("values.xml"));
MiniAapt aapt =
new MiniAapt(
resolver,
filesystem,
new FakeSourcePath(filesystem, "res"),
Paths.get("R.txt"),
ImmutableSet.of());
aapt.processValuesFile(filesystem, Paths.get("values.xml"));
}
@Test
public void testInvalidDefinition() throws XPathExpressionException, IOException {
ImmutableList<String> lines =
ImmutableList.<String>builder()
.add(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>",
"<LinearLayout>",
"<Button android:id=\"@+string/button1\" ",
"android:layout_toLeftOf=\"@id/button2\" ",
"android:text=\"@string/text\" />",
"</LinearLayout>")
.build();
Path resource = Paths.get("resource.xml");
filesystem.writeLinesToPath(lines, resource);
MiniAapt aapt =
new MiniAapt(
resolver,
filesystem,
new FakeSourcePath(filesystem, "res"),
Paths.get("R.txt"),
ImmutableSet.of());
try {
aapt.processXmlFile(filesystem, resource, ImmutableSet.builder());
fail("MiniAapt should throw parsing '@+string/button1'");
} catch (ResourceParseException e) {
assertThat(e.getMessage(), containsString("Invalid definition of a resource"));
}
}
@Test
public void testInvalidReference() throws IOException, XPathExpressionException {
ImmutableList<String> lines =
ImmutableList.<String>builder()
.add(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>",
"<LinearLayout>",
"<Button android:id=\"@+id/button1\" ",
"android:layout_toLeftOf=\"@someresource/button2\" ",
"android:text=\"@string/text\" />",
"</LinearLayout>")
.build();
Path resource = Paths.get("resource.xml");
filesystem.writeLinesToPath(lines, resource);
MiniAapt aapt =
new MiniAapt(
resolver,
filesystem,
new FakeSourcePath(filesystem, "res"),
Paths.get("R.txt"),
ImmutableSet.of());
try {
aapt.processXmlFile(filesystem, resource, ImmutableSet.builder());
fail("MiniAapt should throw parsing '@someresource/button2'");
} catch (ResourceParseException e) {
assertThat(e.getMessage(), containsString("Invalid reference '@someresource/button2'"));
}
}
@Test
public void testMissingNameAttribute() throws IOException, ResourceParseException {
thrown.expect(ResourceParseException.class);
thrown.expectMessage("Error: expected a 'name' attribute in node 'string' with value 'Howdy!'");
ImmutableList<String> lines =
ImmutableList.<String>builder()
.add(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>",
"<resources>",
"<string notname=\"hello\">Howdy!</string>",
"</resources>")
.build();
filesystem.writeLinesToPath(lines, Paths.get("values.xml"));
MiniAapt aapt =
new MiniAapt(
resolver,
filesystem,
new FakeSourcePath(filesystem, "res"),
Paths.get("R.txt"),
ImmutableSet.of());
aapt.processValuesFile(filesystem, Paths.get("values.xml"));
}
@Test
public void testVerifyReferences()
throws IOException, XPathExpressionException, ResourceParseException {
filesystem.writeLinesToPath(RESOURCES, Paths.get("resource.xml"));
ImmutableList<String> rDotTxt =
ImmutableList.of(
"int string text 0x07010001",
"int style Buck_Theme 0x07020001",
"int id button2 0x07030001");
Path depRTxt = Paths.get("dep/R.txt");
filesystem.writeLinesToPath(rDotTxt, depRTxt);
MiniAapt aapt =
new MiniAapt(
resolver,
filesystem,
new FakeSourcePath(filesystem, "res"),
Paths.get("R.txt"),
ImmutableSet.of(depRTxt));
ImmutableSet.Builder<RDotTxtEntry> references = ImmutableSet.builder();
aapt.processXmlFile(filesystem, Paths.get("resource.xml"), references);
Set<RDotTxtEntry> missing = aapt.verifyReferences(filesystem, references.build());
assertEquals(
ImmutableSet.<RDotTxtEntry>of(
new FakeRDotTxtEntry(IdType.INT, RType.DRAWABLE, "some_image")),
missing);
}
@Test
public void testInvalidNodeId()
throws IOException, XPathExpressionException, ResourceParseException {
thrown.expect(ResourceParseException.class);
thrown.expectMessage("Invalid definition of a resource: '@button2'");
ImmutableList<String> lines =
ImmutableList.<String>builder()
.add(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>",
"<LinearLayout>",
"<Button android:id=\"@+id/button1\" ",
"android:layout_toLeftOf=\"@button2\" />",
"</LinearLayout>")
.build();
Path resource = Paths.get("resource.xml");
filesystem.writeLinesToPath(lines, resource);
MiniAapt aapt =
new MiniAapt(
resolver,
filesystem,
new FakeSourcePath(filesystem, "res"),
Paths.get("R.txt"),
ImmutableSet.of());
aapt.processXmlFile(filesystem, resource, ImmutableSet.builder());
}
@Test
public void testProcessFileNamesInDirectory() throws IOException, ResourceParseException {
filesystem.touch(Paths.get("res/drawable/icon.png"));
filesystem.touch(Paths.get("res/drawable/another_icon.png.orig"));
filesystem.touch(Paths.get("res/drawable-ldpi/nine_patch.9.png"));
filesystem.touch(Paths.get("res/drawable-ldpi/.DS_Store"));
filesystem.touch(Paths.get("res/transition-v19/some_transition.xml"));
filesystem.writeContentsToPath(
"<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+ "<resources>"
+ "<bool name=\"v\">false</bool>"
+ "</resources>",
Paths.get("res/values/value.xml~"));
MiniAapt aapt =
new MiniAapt(
resolver,
filesystem,
new FakeSourcePath(filesystem, "res"),
Paths.get("R.txt"),
ImmutableSet.of());
aapt.processFileNamesInDirectory(filesystem, Paths.get("res/drawable"));
aapt.processFileNamesInDirectory(filesystem, Paths.get("res/drawable-ldpi"));
aapt.processFileNamesInDirectory(filesystem, Paths.get("res/transition-v19"));
aapt.processValues(
filesystem,
new DefaultBuckEventBus(new FakeClock(0), new BuildId("")),
Paths.get("res/values"));
assertEquals(
ImmutableSet.<RDotTxtEntry>of(
new FakeRDotTxtEntry(IdType.INT, RType.DRAWABLE, "icon"),
new FakeRDotTxtEntry(IdType.INT, RType.DRAWABLE, "nine_patch"),
new FakeRDotTxtEntry(IdType.INT, RType.TRANSITION, "some_transition")),
aapt.getResourceCollector().getResources());
}
@Test
public void testDotSeparatedResourceNames()
throws IOException, XPathExpressionException, ResourceParseException {
ImmutableList<String> lines =
ImmutableList.<String>builder()
.add(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>",
"<LinearLayout>",
"<Button android:id=\"@+id/button1\" ",
"android:text=\"@string/com.buckbuild.taskname\" />",
"</LinearLayout>")
.build();
Path resource = Paths.get("resource.xml");
filesystem.writeLinesToPath(lines, resource);
MiniAapt aapt =
new MiniAapt(
resolver,
filesystem,
new FakeSourcePath(filesystem, "res"),
Paths.get("R.txt"),
ImmutableSet.of());
ImmutableSet.Builder<RDotTxtEntry> references = ImmutableSet.builder();
aapt.processXmlFile(filesystem, Paths.get("resource.xml"), references);
assertEquals(
references.build(),
ImmutableSet.<RDotTxtEntry>of(
new FakeRDotTxtEntry(IdType.INT, RType.STRING, "com_buckbuild_taskname")));
}
@Test
public void testUnionResources()
throws IOException, XPathExpressionException, ResourceParseException {
ImmutableList<String> lines =
ImmutableList.<String>builder()
.add(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>",
"<resources>",
"<string name=\"buck_string_1\">buck text 1 original</string>",
"<id name=\"buck_id_1\"/>",
"<style name=\"Buck.Style.1\">",
" <item name=\"ignoreMe\" />",
"</style>",
"<declare-styleable name=\"Buck_Styleable_1\">",
" <attr name=\"attr1_1\" />",
" <attr name=\"attr1_2\" format=\"string\" />",
" <attr name=\"attr1_3\" />",
"</declare-styleable>",
"</resources>")
.build();
filesystem.writeLinesToPath(lines, Paths.get("values.xml"));
ImmutableList<String> rDotTxt =
ImmutableList.of(
"int string buck_string_1 0x07010001",
"int string buck_string_2 0x07010002",
"int id buck_id_2 0x07020002",
"int style Buck_Style_2 0x07030002",
"int[] styleable Buck_Styleable_2 { 0x07040001,0x07040002,0x07040003 }",
"int styleable Buck_Styleable_2_attr2_1 0",
"int styleable Buck_Styleable_2_attr2_2 1",
"int styleable Buck_Styleable_2_attr2_3 2",
"int attr attr2_1 0x07050001",
"int attr attr2_2 0x07050002",
"int attr attr2_3 0x07050003");
Path depRTxt = Paths.get("dep/R.txt");
filesystem.writeLinesToPath(rDotTxt, depRTxt);
MiniAapt aapt =
new MiniAapt(
resolver,
filesystem,
new FakeSourcePath(filesystem, "res"),
Paths.get("R.txt"),
ImmutableSet.of(depRTxt),
/* resourceUnion */ true,
/* isGrayscaleImageProcessingEnabled */ false);
aapt.processValuesFile(filesystem, Paths.get("values.xml"));
aapt.resourceUnion();
Set<RDotTxtEntry> resources = aapt.getResourceCollector().getResources();
assertEquals(
ImmutableSet.<RDotTxtEntry>of(
new FakeRDotTxtEntry(IdType.INT, RType.STRING, "buck_string_1"),
new FakeRDotTxtEntry(IdType.INT, RType.ID, "buck_id_1"),
new FakeRDotTxtEntry(IdType.INT, RType.STYLE, "Buck_Style_1"),
new FakeRDotTxtEntry(IdType.INT_ARRAY, RType.STYLEABLE, "Buck_Styleable_1"),
new FakeRDotTxtEntry(IdType.INT, RType.STYLEABLE, "Buck_Styleable_1_attr1_1"),
new FakeRDotTxtEntry(IdType.INT, RType.STYLEABLE, "Buck_Styleable_1_attr1_2"),
new FakeRDotTxtEntry(IdType.INT, RType.STYLEABLE, "Buck_Styleable_1_attr1_3"),
new FakeRDotTxtEntry(IdType.INT, RType.ATTR, "attr1_1"),
new FakeRDotTxtEntry(IdType.INT, RType.ATTR, "attr1_2"),
new FakeRDotTxtEntry(IdType.INT, RType.ATTR, "attr1_3"),
new FakeRDotTxtEntry(IdType.INT, RType.STRING, "buck_string_2"),
new FakeRDotTxtEntry(IdType.INT, RType.ID, "buck_id_2"),
new FakeRDotTxtEntry(IdType.INT, RType.STYLE, "Buck_Style_2"),
new FakeRDotTxtEntry(IdType.INT_ARRAY, RType.STYLEABLE, "Buck_Styleable_2"),
new FakeRDotTxtEntry(IdType.INT, RType.STYLEABLE, "Buck_Styleable_2_attr2_1"),
new FakeRDotTxtEntry(IdType.INT, RType.STYLEABLE, "Buck_Styleable_2_attr2_2"),
new FakeRDotTxtEntry(IdType.INT, RType.STYLEABLE, "Buck_Styleable_2_attr2_3"),
new FakeRDotTxtEntry(IdType.INT, RType.ATTR, "attr2_1"),
new FakeRDotTxtEntry(IdType.INT, RType.ATTR, "attr2_2"),
new FakeRDotTxtEntry(IdType.INT, RType.ATTR, "attr2_3")),
resources);
}
}