ConfigurationParser_test.cpp revision b102727771b9ac3d28d4f9b0a4a54b98bd1af958
174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer/*
274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer * Copyright (C) 2017 The Android Open Source Project
374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer *
474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer * Licensed under the Apache License, Version 2.0 (the "License");
574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer * you may not use this file except in compliance with the License.
674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer * You may obtain a copy of the License at
774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer *
874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer *      http://www.apache.org/licenses/LICENSE-2.0
974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer *
1074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer * Unless required by applicable law or agreed to in writing, software
1174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer * distributed under the License is distributed on an "AS IS" BASIS,
1274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer * See the License for the specific language governing permissions and
1474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer * limitations under the License.
1574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer */
1674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
1774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer#include "configuration/ConfigurationParser.h"
1874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
1974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer#include <string>
2074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
2174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer#include <gmock/gmock.h>
2274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer#include <gtest/gtest.h>
2374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
2474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer#include "androidfw/ResourceTypes.h"
2574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
2674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer#include "test/Test.h"
2774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer#include "xml/XmlDom.h"
2874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
2974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmernamespace aapt {
3074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmernamespace {
3174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
3274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmerusing android::ResTable_config;
3374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmerusing configuration::Abi;
3474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmerusing configuration::AndroidSdk;
3574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmerusing configuration::Configuration;
3674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmerusing configuration::DeviceFeature;
3774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmerusing configuration::GlTexture;
3874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmerusing configuration::Locale;
3974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmerusing configuration::AndroidManifest;
4074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmerusing testing::ElementsAre;
4174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmerusing xml::Element;
4274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmerusing xml::NodeCast;
4374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
4474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmerconstexpr const char* kValidConfig = R"(<?xml version="1.0" encoding="utf-8" ?>
4574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer<post-process xmlns="http://schemas.android.com/tools/aapt">
4674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  <groups>
4774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    <abi-group label="arm">
4874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <abi>armeabi-v7a</abi>
4974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <abi>arm64-v8a</abi>
5074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    </abi-group>
5174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    <abi-group label="other">
5274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <abi>x86</abi>
5374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <abi>mips</abi>
5474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    </abi-group>
5574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    <screen-density-group label="large">
5674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <screen-density>xhdpi</screen-density>
5774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <screen-density>xxhdpi</screen-density>
5874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <screen-density>xxxhdpi</screen-density>
5974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    </screen-density-group>
6074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    <screen-density-group label="alldpi">
6174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <screen-density>ldpi</screen-density>
6274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <screen-density>mdpi</screen-density>
6374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <screen-density>hdpi</screen-density>
6474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <screen-density>xhdpi</screen-density>
6574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <screen-density>xxhdpi</screen-density>
6674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <screen-density>xxxhdpi</screen-density>
6774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    </screen-density-group>
6874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    <locale-group label="europe">
6974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <locale lang="en"/>
7074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <locale lang="es"/>
7174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <locale lang="fr"/>
7274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <locale lang="de"/>
7374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    </locale-group>
7474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    <locale-group label="north-america">
7574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <locale lang="en"/>
7674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <locale lang="es" region="MX"/>
7774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <locale lang="fr" region="CA"/>
7874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    </locale-group>
7974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    <locale-group label="all">
8074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <locale/>
8174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    </locale-group>
8274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    <android-sdk-group label="19">
8374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <android-sdk
8474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer          minSdkVersion="19"
8574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer          targetSdkVersion="24"
8674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer          maxSdkVersion="25">
8774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        <manifest>
8874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer          <!--- manifest additions here XSLT? TODO -->
8974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        </manifest>
9074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      </android-sdk>
9174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    </android-sdk-group>
9274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    <gl-texture-group label="dxt1">
9374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <gl-texture name="GL_EXT_texture_compression_dxt1">
9474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        <texture-path>assets/dxt1/*</texture-path>
9574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      </gl-texture>
9674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    </gl-texture-group>
9774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    <device-feature-group label="low-latency">
9874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <supports-feature>android.hardware.audio.low_latency</supports-feature>
9974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    </device-feature-group>
10074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  </groups>
10174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  <artifacts>
10274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    <artifact-format>
10374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      ${base}.${abi}.${screen-density}.${locale}.${sdk}.${gl}.${feature}.release
10474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    </artifact-format>
10574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    <artifact
10674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        name="art1"
10774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        abi-group="arm"
10874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        screen-density-group="large"
10974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        locale-group="europe"
11074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        android-sdk-group="19"
11174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        gl-texture-group="dxt1"
11274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        device-feature-group="low-latency"/>
11374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    <artifact
11474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        name="art2"
11574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        abi-group="other"
11674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        screen-density-group="alldpi"
11774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        locale-group="north-america"
11874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        android-sdk-group="19"
11974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        gl-texture-group="dxt1"
12074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        device-feature-group="low-latency"/>
12174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  </artifacts>
12274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer</post-process>
12374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer)";
12474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
12574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmerclass ConfigurationParserTest : public ConfigurationParser, public ::testing::Test {
12674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer public:
12774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ConfigurationParserTest() : ConfigurationParser("") {}
12874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
12974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer protected:
13074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  StdErrDiagnostics diag_;
13174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer};
13274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
133b102727771b9ac3d28d4f9b0a4a54b98bd1af958Shane FarmerTEST_F(ConfigurationParserTest, ForPath_NoFile) {
134b102727771b9ac3d28d4f9b0a4a54b98bd1af958Shane Farmer  auto result = ConfigurationParser::ForPath("./does_not_exist.xml");
135b102727771b9ac3d28d4f9b0a4a54b98bd1af958Shane Farmer  EXPECT_FALSE(result);
136b102727771b9ac3d28d4f9b0a4a54b98bd1af958Shane Farmer}
137b102727771b9ac3d28d4f9b0a4a54b98bd1af958Shane Farmer
13874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane FarmerTEST_F(ConfigurationParserTest, ValidateFile) {
13974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  auto parser = ConfigurationParser::ForContents(kValidConfig).WithDiagnostics(&diag_);
14074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  auto result = parser.Parse();
14174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_TRUE(result);
14274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  Configuration& value = result.value();
14374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  EXPECT_EQ(2ul, value.artifacts.size());
14474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_TRUE(value.artifact_format);
14574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  EXPECT_EQ(
14674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      "${base}.${abi}.${screen-density}.${locale}.${sdk}.${gl}.${feature}.release",
14774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      value.artifact_format.value()
14874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  );
14974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
15074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  EXPECT_EQ(2ul, value.abi_groups.size());
15174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  EXPECT_EQ(2ul, value.abi_groups["arm"].size());
15274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  EXPECT_EQ(2ul, value.abi_groups["other"].size());
15374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
15474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  EXPECT_EQ(2ul, value.screen_density_groups.size());
15574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  EXPECT_EQ(3ul, value.screen_density_groups["large"].size());
15674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  EXPECT_EQ(6ul, value.screen_density_groups["alldpi"].size());
15774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
15874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  EXPECT_EQ(3ul, value.locale_groups.size());
15974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  EXPECT_EQ(4ul, value.locale_groups["europe"].size());
16074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  EXPECT_EQ(3ul, value.locale_groups["north-america"].size());
16174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  EXPECT_EQ(1ul, value.locale_groups["all"].size());
16274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
16374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  EXPECT_EQ(1ul, value.android_sdk_groups.size());
16474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  EXPECT_EQ(1ul, value.android_sdk_groups["19"].size());
16574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
16674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  EXPECT_EQ(1ul, value.gl_texture_groups.size());
16774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  EXPECT_EQ(1ul, value.gl_texture_groups["dxt1"].size());
16874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
16974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  EXPECT_EQ(1ul, value.device_feature_groups.size());
17074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  EXPECT_EQ(1ul, value.device_feature_groups["low-latency"].size());
17174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer}
17274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
17374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane FarmerTEST_F(ConfigurationParserTest, InvalidNamespace) {
17474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  constexpr const char* invalid_ns = R"(<?xml version="1.0" encoding="utf-8" ?>
17574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  <post-process xmlns="http://schemas.android.com/tools/another-unknown-tool" />)";
17674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
17774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  auto result = ConfigurationParser::ForContents(invalid_ns).Parse();
17874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_FALSE(result);
17974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer}
18074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
18174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane FarmerTEST_F(ConfigurationParserTest, ArtifactAction) {
18274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  static constexpr const char* xml = R"xml(
18374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    <artifact
18474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        abi-group="arm"
18574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        screen-density-group="large"
18674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        locale-group="europe"
18774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        android-sdk-group="19"
18874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        gl-texture-group="dxt1"
18974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        device-feature-group="low-latency"/>)xml";
19074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
19174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  auto doc = test::BuildXmlDom(xml);
19274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
19374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  Configuration config;
19474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  bool ok = artifact_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
19574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_TRUE(ok);
19674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
19774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  EXPECT_EQ(1ul, config.artifacts.size());
19874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
19974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  auto& artifact = config.artifacts.begin()->second;
20074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  EXPECT_EQ("", artifact.name); // TODO: make this fail.
20174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  EXPECT_EQ("arm", artifact.abi_group.value());
20274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  EXPECT_EQ("large", artifact.screen_density_group.value());
20374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  EXPECT_EQ("europe", artifact.locale_group.value());
20474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  EXPECT_EQ("19", artifact.android_sdk_group.value());
20574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  EXPECT_EQ("dxt1", artifact.gl_texture_group.value());
20674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  EXPECT_EQ("low-latency", artifact.device_feature_group.value());
20774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer}
20874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
20974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane FarmerTEST_F(ConfigurationParserTest, ArtifactFormatAction) {
21074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  static constexpr const char* xml = R"xml(
21174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    <artifact-format>
21274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      ${base}.${abi}.${screen-density}.${locale}.${sdk}.${gl}.${feature}.release
21374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    </artifact-format>)xml";
21474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
21574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  auto doc = test::BuildXmlDom(xml);
21674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
21774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  Configuration config;
21874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  bool ok = artifact_format_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
21974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_TRUE(ok);
22074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_TRUE(config.artifact_format);
22174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  EXPECT_EQ(
22274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      "${base}.${abi}.${screen-density}.${locale}.${sdk}.${gl}.${feature}.release",
22374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      static_cast<std::string>(config.artifact_format.value())
22474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  );
22574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer}
22674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
22774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane FarmerTEST_F(ConfigurationParserTest, AbiGroupAction) {
22874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  static constexpr const char* xml = R"xml(
22974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    <abi-group label="arm">
23074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <!-- First comment. -->
23174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <abi>
23274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        armeabi-v7a
23374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      </abi>
23474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <!-- Another comment. -->
23574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <abi>arm64-v8a</abi>
23674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    </abi-group>)xml";
23774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
23874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  auto doc = test::BuildXmlDom(xml);
23974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
24074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  Configuration config;
24174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  bool ok = abi_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
24274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_TRUE(ok);
24374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
24474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  EXPECT_EQ(1ul, config.abi_groups.size());
24574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_EQ(1u, config.abi_groups.count("arm"));
24674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
24774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  auto& out = config.abi_groups["arm"];
24874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_THAT(out, ElementsAre(Abi::kArmV7a, Abi::kArm64V8a));
24974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer}
25074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
25174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane FarmerTEST_F(ConfigurationParserTest, ScreenDensityGroupAction) {
25274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  static constexpr const char* xml = R"xml(
25374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    <screen-density-group label="large">
25474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <screen-density>xhdpi</screen-density>
25574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <screen-density>
25674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        xxhdpi
25774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      </screen-density>
25874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <screen-density>xxxhdpi</screen-density>
25974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    </screen-density-group>)xml";
26074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
26174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  auto doc = test::BuildXmlDom(xml);
26274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
26374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  Configuration config;
26474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  bool ok =
26574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      screen_density_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
26674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_TRUE(ok);
26774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
26874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  EXPECT_EQ(1ul, config.screen_density_groups.size());
26974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_EQ(1u, config.screen_density_groups.count("large"));
27074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
27174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ConfigDescription xhdpi;
27274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  xhdpi.density = ResTable_config::DENSITY_XHIGH;
27374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ConfigDescription xxhdpi;
27474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  xxhdpi.density = ResTable_config::DENSITY_XXHIGH;
27574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ConfigDescription xxxhdpi;
27674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  xxxhdpi.density = ResTable_config::DENSITY_XXXHIGH;
27774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
27874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  auto& out = config.screen_density_groups["large"];
27974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_THAT(out, ElementsAre(xhdpi, xxhdpi, xxxhdpi));
28074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer}
28174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
28274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane FarmerTEST_F(ConfigurationParserTest, LocaleGroupAction) {
28374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  static constexpr const char* xml = R"xml(
28474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    <locale-group label="europe">
28574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <locale lang="en"/>
28674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <locale lang="es"/>
28774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <locale lang="fr"/>
28874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <locale lang="de"/>
28974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    </locale-group>)xml";
29074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
29174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  auto doc = test::BuildXmlDom(xml);
29274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
29374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  Configuration config;
29474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  bool ok = locale_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
29574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_TRUE(ok);
29674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
29774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_EQ(1ul, config.locale_groups.size());
29874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_EQ(1u, config.locale_groups.count("europe"));
29974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
30074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  auto& out = config.locale_groups["europe"];
30174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
30274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  Locale en;
30374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  en.lang = std::string("en");
30474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  Locale es;
30574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  es.lang = std::string("es");
30674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  Locale fr;
30774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  fr.lang = std::string("fr");
30874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  Locale de;
30974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  de.lang = std::string("de");
31074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
31174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_THAT(out, ElementsAre(en, es, fr, de));
31274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer}
31374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
31474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane FarmerTEST_F(ConfigurationParserTest, AndroidSdkGroupAction) {
31574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  static constexpr const char* xml = R"xml(
31674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    <android-sdk-group label="19">
31774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <android-sdk
31874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer          minSdkVersion="19"
31974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer          targetSdkVersion="24"
32074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer          maxSdkVersion="25">
32174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        <manifest>
32274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer          <!--- manifest additions here XSLT? TODO -->
32374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        </manifest>
32474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      </android-sdk>
32574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    </android-sdk-group>)xml";
32674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
32774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  auto doc = test::BuildXmlDom(xml);
32874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
32974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  Configuration config;
33074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  bool ok = android_sdk_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
33174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_TRUE(ok);
33274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
33374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_EQ(1ul, config.android_sdk_groups.size());
33474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_EQ(1u, config.android_sdk_groups.count("19"));
33574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
33674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  auto& out = config.android_sdk_groups["19"];
33774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
33874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  AndroidSdk sdk;
33974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  sdk.min_sdk_version = std::string("19");
34074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  sdk.target_sdk_version = std::string("24");
34174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  sdk.max_sdk_version = std::string("25");
34274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  sdk.manifest = AndroidManifest();
34374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
34474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_EQ(1ul, out.size());
34574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_EQ(sdk, out[0]);
34674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer}
34774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
34874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane FarmerTEST_F(ConfigurationParserTest, GlTextureGroupAction) {
34974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  static constexpr const char* xml = R"xml(
35074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    <gl-texture-group label="dxt1">
35174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <gl-texture name="GL_EXT_texture_compression_dxt1">
35274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        <texture-path>assets/dxt1/main/*</texture-path>
35374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        <texture-path>
35474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer          assets/dxt1/test/*
35574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        </texture-path>
35674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      </gl-texture>
35774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    </gl-texture-group>)xml";
35874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
35974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  auto doc = test::BuildXmlDom(xml);
36074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
36174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  Configuration config;
36274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  bool ok = gl_texture_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
36374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_TRUE(ok);
36474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
36574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  EXPECT_EQ(1ul, config.gl_texture_groups.size());
36674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_EQ(1u, config.gl_texture_groups.count("dxt1"));
36774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
36874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  auto& out = config.gl_texture_groups["dxt1"];
36974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
37074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  GlTexture texture{
37174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      std::string("GL_EXT_texture_compression_dxt1"),
37274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      {"assets/dxt1/main/*", "assets/dxt1/test/*"}
37374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  };
37474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
37574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_EQ(1ul, out.size());
37674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_EQ(texture, out[0]);
37774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer}
37874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
37974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane FarmerTEST_F(ConfigurationParserTest, DeviceFeatureGroupAction) {
38074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  static constexpr const char* xml = R"xml(
38174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    <device-feature-group label="low-latency">
38274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <supports-feature>android.hardware.audio.low_latency</supports-feature>
38374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <supports-feature>
38474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        android.hardware.audio.pro
38574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      </supports-feature>
38674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    </device-feature-group>)xml";
38774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
38874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  auto doc = test::BuildXmlDom(xml);
38974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
39074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  Configuration config;
39174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  bool ok
39274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      = device_feature_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
39374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_TRUE(ok);
39474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
39574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  EXPECT_EQ(1ul, config.device_feature_groups.size());
39674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_EQ(1u, config.device_feature_groups.count("low-latency"));
39774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
39874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  auto& out = config.device_feature_groups["low-latency"];
39974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
40074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  DeviceFeature low_latency = "android.hardware.audio.low_latency";
40174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  DeviceFeature pro = "android.hardware.audio.pro";
40274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_THAT(out, ElementsAre(low_latency, pro));
40374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer}
40474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
40574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer}  // namespace
40674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer}  // namespace aapt
407