Fix failing Windows tests

Some tests were not written to run on Windows correctly. Compile also
has a bug that caused using the --zip flag to fail on Windows.
iswspace does count the non breaking space as Whiespace on Windows but
not on Unix based systems

Bug: 117156986
Change-Id: I999375162bdfdf86fb25992ee88e2962ab90b577
Test: aapt2_tests and wine aapt2_tests.exe
This commit is contained in:
Ryan Mitchell
2018-10-03 09:20:57 -07:00
parent 88f0f6c9b1
commit 0ce89734d1
11 changed files with 162 additions and 101 deletions

View File

@@ -38,6 +38,8 @@ using ::android::base::StringPrintf;
namespace aapt {
namespace ResourceUtils {
constexpr int32_t kNonBreakingSpace = 0xa0;
Maybe<ResourceName> ToResourceName(
const android::ResTable::resource_name& name_in) {
ResourceName name_out;
@@ -810,7 +812,7 @@ StringBuilder& StringBuilder::AppendText(const std::string& text, bool preserve_
Utf8Iterator iter(text);
while (iter.HasNext()) {
char32_t codepoint = iter.Next();
if (!preserve_spaces && !quote_ && iswspace(codepoint)) {
if (!preserve_spaces && !quote_ && codepoint != kNonBreakingSpace && iswspace(codepoint)) {
if (!last_codepoint_was_space_) {
// Emit a space if it's the first.
xml_string_.text += ' ';

View File

@@ -73,9 +73,9 @@ struct ResourcePathData {
};
// Resource file paths are expected to look like: [--/res/]type[-config]/name
static Maybe<ResourcePathData> ExtractResourcePathData(const std::string& path,
static Maybe<ResourcePathData> ExtractResourcePathData(const std::string& path, const char dir_sep,
std::string* out_error) {
std::vector<std::string> parts = util::Split(path, file::sDirSep);
std::vector<std::string> parts = util::Split(path, dir_sep);
if (parts.size() < 2) {
if (out_error) *out_error = "bad resource path";
return {};
@@ -656,7 +656,7 @@ int Compile(IAaptContext* context, io::IFileCollection* inputs, IArchiveWriter*
// Extract resource type information from the full path
std::string err_str;
ResourcePathData path_data;
if (auto maybe_path_data = ExtractResourcePathData(path, &err_str)) {
if (auto maybe_path_data = ExtractResourcePathData(path, inputs->GetDirSeparator(), &err_str)) {
path_data = maybe_path_data.value();
} else {
context->GetDiagnostics()->Error(DiagMessage(file->GetSource()) << err_str);
@@ -731,7 +731,7 @@ int CompileCommand::Action(const std::vector<std::string>& args) {
// Collect the resources files to compile
if (options_.res_dir && options_.res_zip) {
context.GetDiagnostics()->Error(DiagMessage()
<< "only one of --dir and --zip can be specified");
<< "only one of --dir and --zip can be specified");
return 1;
} else if (options_.res_dir) {
if (!args.empty()) {

View File

@@ -17,6 +17,9 @@
#include "Compile.h"
#include "android-base/file.h"
#include "android-base/stringprintf.h"
#include "android-base/utf8.h"
#include "io/StringStream.h"
#include "io/ZipArchive.h"
#include "java/AnnotationProcessor.h"
@@ -24,8 +27,20 @@
namespace aapt {
std::string BuildPath(std::vector<std::string> args) {
std::string out;
if (args.empty()) {
return out;
}
out = args[0];
for (int i = 1; i < args.size(); i++) {
file::AppendPath(&out, args[i]);
}
return out;
}
int TestCompile(const std::string& path, const std::string& outDir, bool legacy,
StdErrDiagnostics& diag) {
StdErrDiagnostics& diag) {
std::vector<android::StringPiece> args;
args.push_back(path);
args.push_back("-o");
@@ -39,95 +54,101 @@ int TestCompile(const std::string& path, const std::string& outDir, bool legacy,
TEST(CompilerTest, MultiplePeriods) {
StdErrDiagnostics diag;
std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
const std::string kResDir = android::base::Dirname(android::base::GetExecutablePath())
+ "/integration-tests/CompileTest/res";
const std::string kResDir = BuildPath({android::base::Dirname(android::base::GetExecutablePath()),
"integration-tests", "CompileTest", "res"});
// Resource files without periods in the file name should not throw errors
const std::string path0 = kResDir + "/values/values.xml";
const std::string path0_out = kResDir + "/values_values.arsc.flat";
remove(path0_out.c_str());
const std::string path0 = BuildPath({kResDir, "values", "values.xml"});
const std::string path0_out = BuildPath({kResDir, "values_values.arsc.flat"});
::android::base::utf8::unlink(path0_out.c_str());
ASSERT_EQ(TestCompile(path0, kResDir, /** legacy */ false, diag), 0);
ASSERT_EQ(remove(path0_out.c_str()), 0);
ASSERT_EQ(::android::base::utf8::unlink(path0_out.c_str()), 0);
ASSERT_EQ(TestCompile(path0, kResDir, /** legacy */ true, diag), 0);
ASSERT_EQ(remove(path0_out.c_str()), 0);
ASSERT_EQ(::android::base::utf8::unlink(path0_out.c_str()), 0);
const std::string path1 = kResDir + "/drawable/image.png";
const std::string path1_out = kResDir + "/drawable_image.png.flat";
remove(path1_out.c_str());
const std::string path1 = BuildPath({kResDir, "drawable", "image.png"});
const std::string path1_out = BuildPath({kResDir, "drawable_image.png.flat"});
::android::base::utf8::unlink(path1_out.c_str());
ASSERT_EQ(TestCompile(path1, kResDir, /** legacy */ false, diag), 0);
ASSERT_EQ(remove(path1_out.c_str()), 0);
ASSERT_EQ(::android::base::utf8::unlink(path1_out.c_str()), 0);
ASSERT_EQ(TestCompile(path1, kResDir, /** legacy */ true, diag), 0);
ASSERT_EQ(remove(path1_out.c_str()), 0);
ASSERT_EQ(::android::base::utf8::unlink(path1_out.c_str()), 0);
const std::string path2 = kResDir + "/drawable/image.9.png";
const std::string path2_out = kResDir + "/drawable_image.9.png.flat";
remove(path2_out.c_str());
const std::string path2 = BuildPath({kResDir, "drawable", "image.9.png"});
const std::string path2_out = BuildPath({kResDir, "drawable_image.9.png.flat"});
::android::base::utf8::unlink(path2_out.c_str());
ASSERT_EQ(TestCompile(path2, kResDir, /** legacy */ false, diag), 0);
ASSERT_EQ(remove(path2_out.c_str()), 0);
ASSERT_EQ(::android::base::utf8::unlink(path2_out.c_str()), 0);
ASSERT_EQ(TestCompile(path2, kResDir, /** legacy */ true, diag), 0);
ASSERT_EQ(remove(path2_out.c_str()), 0);
ASSERT_EQ(::android::base::utf8::unlink(path2_out.c_str()), 0);
// Resource files with periods in the file name should fail on non-legacy compilations
const std::string path3 = kResDir + "/values/values.all.xml";
const std::string path3_out = kResDir + "/values_values.all.arsc.flat";
remove(path3_out.c_str());
const std::string path3 = BuildPath({kResDir, "values", "values.all.xml"});
const std::string path3_out = BuildPath({kResDir, "values_values.all.arsc.flat"});
::android::base::utf8::unlink(path3_out.c_str());
ASSERT_NE(TestCompile(path3, kResDir, /** legacy */ false, diag), 0);
ASSERT_NE(remove(path3_out.c_str()), 0);
ASSERT_NE(::android::base::utf8::unlink(path3_out.c_str()), 0);
ASSERT_EQ(TestCompile(path3, kResDir, /** legacy */ true, diag), 0);
ASSERT_EQ(remove(path3_out.c_str()), 0);
ASSERT_EQ(::android::base::utf8::unlink(path3_out.c_str()), 0);
const std::string path4 = kResDir + "/drawable/image.small.png";
const std::string path4_out = (kResDir + std::string("/drawable_image.small.png.flat")).c_str();
remove(path4_out.c_str());
const std::string path4 = BuildPath({kResDir, "drawable", "image.small.png"});
const std::string path4_out = BuildPath({kResDir, "drawable_image.small.png.flat"});
::android::base::utf8::unlink(path4_out.c_str());
ASSERT_NE(TestCompile(path4, kResDir, /** legacy */ false, diag), 0);
ASSERT_NE(remove(path4_out.c_str()), 0);
ASSERT_NE(::android::base::utf8::unlink(path4_out.c_str()), 0);
ASSERT_EQ(TestCompile(path4, kResDir, /** legacy */ true, diag), 0);
ASSERT_EQ(remove(path4_out.c_str()), 0);
ASSERT_EQ(::android::base::utf8::unlink(path4_out.c_str()), 0);
const std::string path5 = kResDir + "/drawable/image.small.9.png";
const std::string path5_out = (kResDir + std::string("/drawable_image.small.9.png.flat")).c_str();
remove(path5_out.c_str());
const std::string path5 = BuildPath({kResDir, "drawable", "image.small.9.png"});
const std::string path5_out = BuildPath({kResDir, "drawable_image.small.9.png.flat"});
::android::base::utf8::unlink(path5_out.c_str());
ASSERT_NE(TestCompile(path5, kResDir, /** legacy */ false, diag), 0);
ASSERT_NE(remove(path5_out.c_str()), 0);
ASSERT_NE(::android::base::utf8::unlink(path5_out.c_str()), 0);
ASSERT_EQ(TestCompile(path5, kResDir, /** legacy */ true, diag), 0);
ASSERT_EQ(remove(path5_out.c_str()), 0);
ASSERT_EQ(::android::base::utf8::unlink(path5_out.c_str()), 0);
}
TEST(CompilerTest, DirInput) {
StdErrDiagnostics diag;
std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
const std::string kResDir = android::base::Dirname(android::base::GetExecutablePath())
+ "/integration-tests/CompileTest/DirInput/res";
const std::string kOutputFlata = android::base::Dirname(android::base::GetExecutablePath())
+ "/integration-tests/CompileTest/DirInput/compiled.flata";
remove(kOutputFlata.c_str());
const std::string kResDir = BuildPath({android::base::Dirname(android::base::GetExecutablePath()),
"integration-tests", "CompileTest", "DirInput", "res"});
const std::string kOutputFlata =
BuildPath({android::base::Dirname(android::base::GetExecutablePath()), "integration-tests",
"CompileTest", "DirInput", "compiled.flata"});
::android::base::utf8::unlink(kOutputFlata.c_str());
std::vector<android::StringPiece> args;
args.push_back("--dir");
args.push_back(kResDir);
args.push_back("-o");
args.push_back(kOutputFlata);
args.push_back("-v");
ASSERT_EQ(CompileCommand(&diag).Execute(args, &std::cerr), 0);
// Check for the presence of the compiled files
std::string err;
std::unique_ptr<io::ZipFileCollection> zip = io::ZipFileCollection::Create(kOutputFlata, &err);
ASSERT_NE(zip, nullptr) << err;
ASSERT_NE(zip->FindFile("drawable_image.png.flat"), nullptr);
ASSERT_NE(zip->FindFile("layout_layout.xml.flat"), nullptr);
ASSERT_NE(zip->FindFile("values_values.arsc.flat"), nullptr);
ASSERT_EQ(remove(kOutputFlata.c_str()), 0);
{
// Check for the presence of the compiled files
std::string err;
std::unique_ptr<io::ZipFileCollection> zip = io::ZipFileCollection::Create(kOutputFlata, &err);
ASSERT_NE(zip, nullptr) << err;
ASSERT_NE(zip->FindFile("drawable_image.png.flat"), nullptr);
ASSERT_NE(zip->FindFile("layout_layout.xml.flat"), nullptr);
ASSERT_NE(zip->FindFile("values_values.arsc.flat"), nullptr);
}
ASSERT_EQ(::android::base::utf8::unlink(kOutputFlata.c_str()), 0);
}
TEST(CompilerTest, ZipInput) {
StdErrDiagnostics diag;
std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
const std::string kResZip = android::base::Dirname(android::base::GetExecutablePath())
+ "/integration-tests/CompileTest/ZipInput/res.zip";
const std::string kOutputFlata = android::base::Dirname(android::base::GetExecutablePath())
+ "/integration-tests/CompileTest/ZipInput/compiled.flata";
remove(kOutputFlata.c_str());
const std::string kResZip =
BuildPath({android::base::Dirname(android::base::GetExecutablePath()), "integration-tests",
"CompileTest", "ZipInput", "res.zip"});
const std::string kOutputFlata =
BuildPath({android::base::Dirname(android::base::GetExecutablePath()), "integration-tests",
"CompileTest", "ZipInput", "compiled.flata"});
::android::base::utf8::unlink(kOutputFlata.c_str());
std::vector<android::StringPiece> args;
args.push_back("--zip");
@@ -136,14 +157,16 @@ TEST(CompilerTest, ZipInput) {
args.push_back(kOutputFlata);
ASSERT_EQ(CompileCommand(&diag).Execute(args, &std::cerr), 0);
// Check for the presence of the compiled files
std::string err;
std::unique_ptr<io::ZipFileCollection> zip = io::ZipFileCollection::Create(kOutputFlata, &err);
ASSERT_NE(zip, nullptr) << err;
ASSERT_NE(zip->FindFile("drawable_image.png.flat"), nullptr);
ASSERT_NE(zip->FindFile("layout_layout.xml.flat"), nullptr);
ASSERT_NE(zip->FindFile("values_values.arsc.flat"), nullptr);
ASSERT_EQ(remove(kOutputFlata.c_str()), 0);
{
// Check for the presence of the compiled files
std::string err;
std::unique_ptr<io::ZipFileCollection> zip = io::ZipFileCollection::Create(kOutputFlata, &err);
ASSERT_NE(zip, nullptr) << err;
ASSERT_NE(zip->FindFile("drawable_image.png.flat"), nullptr);
ASSERT_NE(zip->FindFile("layout_layout.xml.flat"), nullptr);
ASSERT_NE(zip->FindFile("values_values.arsc.flat"), nullptr);
}
ASSERT_EQ(::android::base::utf8::unlink(kOutputFlata.c_str()), 0);
}
} // namespace aapt
} // namespace aapt

View File

@@ -16,12 +16,22 @@
#include "Util.h"
#include "android-base/stringprintf.h"
#include "AppInfo.h"
#include "split/TableSplitter.h"
#include "test/Builders.h"
#include "test/Test.h"
#include "util/Files.h"
namespace aapt {
#ifdef _WIN32
#define CREATE_PATH(path) android::base::StringPrintf(";%s", path)
#else
#define CREATE_PATH(path) android::base::StringPrintf(":%s", path)
#endif
#define EXPECT_CONFIG_EQ(constraints, config) \
EXPECT_EQ(constraints.configs.size(), 1); \
EXPECT_EQ(*constraints.configs.begin(), config); \
@@ -89,7 +99,7 @@ TEST (UtilTest, LongVersionCodeUndefined) {
}
TEST (UtilTest, ParseSplitParameter) {
TEST (UtilTest, ParseSplitParameters) {
IDiagnostics* diagnostics = test::ContextBuilder().Build().get()->GetDiagnostics();
std::string path;
SplitConstraints constraints;
@@ -98,14 +108,14 @@ TEST (UtilTest, ParseSplitParameter) {
// ========== Test IMSI ==========
// mcc: 'mcc[0-9]{3}'
// mnc: 'mnc[0-9]{1,3}'
ASSERT_TRUE(ParseSplitParameter(":mcc310",
ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("mcc310"),
diagnostics, &path, &constraints));
expected_configuration = test::ConfigDescriptionBuilder()
.setMcc(0x0136)
.Build();
EXPECT_CONFIG_EQ(constraints, expected_configuration);
ASSERT_TRUE(ParseSplitParameter(":mcc310-mnc004",
ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("mcc310-mnc004"),
diagnostics, &path, &constraints));
expected_configuration = test::ConfigDescriptionBuilder()
.setMcc(0x0136)
@@ -113,7 +123,7 @@ TEST (UtilTest, ParseSplitParameter) {
.Build();
EXPECT_CONFIG_EQ(constraints, expected_configuration);
ASSERT_TRUE(ParseSplitParameter(":mcc310-mnc000",
ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("mcc310-mnc000"),
diagnostics, &path, &constraints));
expected_configuration = test::ConfigDescriptionBuilder()
.setMcc(0x0136)
@@ -124,14 +134,14 @@ TEST (UtilTest, ParseSplitParameter) {
// ========== Test LOCALE ==========
// locale: '[a-z]{2,3}(-r[a-z]{2})?'
// locale: 'b+[a-z]{2,3}(+[a-z[0-9]]{2})?'
ASSERT_TRUE(ParseSplitParameter(":es",
ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("es"),
diagnostics, &path, &constraints));
expected_configuration = test::ConfigDescriptionBuilder()
.setLanguage(0x6573)
.Build();
EXPECT_CONFIG_EQ(constraints, expected_configuration);
ASSERT_TRUE(ParseSplitParameter(":fr-rCA",
ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("fr-rCA"),
diagnostics, &path, &constraints));
expected_configuration = test::ConfigDescriptionBuilder()
.setLanguage(0x6672)
@@ -139,7 +149,7 @@ TEST (UtilTest, ParseSplitParameter) {
.Build();
EXPECT_CONFIG_EQ(constraints, expected_configuration);
ASSERT_TRUE(ParseSplitParameter(":b+es+419",
ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("b+es+419"),
diagnostics, &path, &constraints));
expected_configuration = test::ConfigDescriptionBuilder()
.setLanguage(0x6573)
@@ -151,21 +161,21 @@ TEST (UtilTest, ParseSplitParameter) {
// orientation: '(port|land|square)'
// touchscreen: '(notouch|stylus|finger)'
// density" '(anydpi|nodpi|ldpi|mdpi|tvdpi|hdpi|xhdpi|xxhdpi|xxxhdpi|[0-9]*dpi)'
ASSERT_TRUE(ParseSplitParameter(":square",
ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("square"),
diagnostics, &path, &constraints));
expected_configuration = test::ConfigDescriptionBuilder()
.setOrientation(0x03)
.Build();
EXPECT_CONFIG_EQ(constraints, expected_configuration);
ASSERT_TRUE(ParseSplitParameter(":stylus",
ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("stylus"),
diagnostics, &path, &constraints));
expected_configuration = test::ConfigDescriptionBuilder()
.setTouchscreen(0x02)
.Build();
EXPECT_CONFIG_EQ(constraints, expected_configuration);
ASSERT_TRUE(ParseSplitParameter(":xxxhdpi",
ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("xxxhdpi"),
diagnostics, &path, &constraints));
expected_configuration = test::ConfigDescriptionBuilder()
.setDensity(0x0280)
@@ -173,7 +183,7 @@ TEST (UtilTest, ParseSplitParameter) {
.Build();
EXPECT_CONFIG_EQ(constraints, expected_configuration);
ASSERT_TRUE(ParseSplitParameter(":land-xhdpi-finger",
ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("land-xhdpi-finger"),
diagnostics, &path, &constraints));
expected_configuration = test::ConfigDescriptionBuilder()
.setOrientation(0x02)
@@ -188,28 +198,28 @@ TEST (UtilTest, ParseSplitParameter) {
// navigation: '(nonav|dpad|trackball|wheel)'
// inputFlags: '(keysexposed|keyshidden|keyssoft)'
// inputFlags: '(navexposed|navhidden)'
ASSERT_TRUE(ParseSplitParameter(":qwerty",
ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("qwerty"),
diagnostics, &path, &constraints));
expected_configuration = test::ConfigDescriptionBuilder()
.setKeyboard(0x02)
.Build();
EXPECT_CONFIG_EQ(constraints, expected_configuration);
ASSERT_TRUE(ParseSplitParameter(":dpad",
ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("dpad"),
diagnostics, &path, &constraints));
expected_configuration = test::ConfigDescriptionBuilder()
.setNavigation(0x02)
.Build();
EXPECT_CONFIG_EQ(constraints, expected_configuration);
ASSERT_TRUE(ParseSplitParameter(":keyssoft-navhidden",
ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("keyssoft-navhidden"),
diagnostics, &path, &constraints));
expected_configuration = test::ConfigDescriptionBuilder()
.setInputFlags(0x0B)
.Build();
EXPECT_CONFIG_EQ(constraints, expected_configuration);
ASSERT_TRUE(ParseSplitParameter(":keyshidden-nokeys-navexposed-trackball",
ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("keyshidden-nokeys-navexposed-trackball"),
diagnostics, &path, &constraints));
expected_configuration = test::ConfigDescriptionBuilder()
.setKeyboard(0x01)
@@ -220,7 +230,7 @@ TEST (UtilTest, ParseSplitParameter) {
// ========== Test SCREEN_SIZE ==========
// screenWidth/screenHeight: '[0-9]+x[0-9]+'
ASSERT_TRUE(ParseSplitParameter(":1920x1080",
ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("1920x1080"),
diagnostics, &path, &constraints));
expected_configuration = test::ConfigDescriptionBuilder()
.setScreenWidth(0x0780)
@@ -238,14 +248,14 @@ TEST (UtilTest, ParseSplitParameter) {
// uiMode [type]: '(desk|car|television|appliance|watch|vrheadset)'
// uiMode [night]: '(night|notnight)'
// smallestScreenWidthDp: 'sw[0-9]dp'
ASSERT_TRUE(ParseSplitParameter(":ldrtl",
ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("ldrtl"),
diagnostics, &path, &constraints));
expected_configuration = test::ConfigDescriptionBuilder()
.setScreenLayout(0x80)
.Build();
EXPECT_CONFIG_EQ(constraints, expected_configuration);
ASSERT_TRUE(ParseSplitParameter(":small",
ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("small"),
diagnostics, &path, &constraints));
expected_configuration = test::ConfigDescriptionBuilder()
.setScreenLayout(0x01)
@@ -253,7 +263,7 @@ TEST (UtilTest, ParseSplitParameter) {
.Build();
EXPECT_CONFIG_EQ(constraints, expected_configuration);
ASSERT_TRUE(ParseSplitParameter(":notlong",
ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("notlong"),
diagnostics, &path, &constraints));
expected_configuration = test::ConfigDescriptionBuilder()
.setScreenLayout(0x10)
@@ -261,15 +271,15 @@ TEST (UtilTest, ParseSplitParameter) {
.Build();
EXPECT_CONFIG_EQ(constraints, expected_configuration);
ASSERT_TRUE(ParseSplitParameter(":ldltr-normal-long",
diagnostics, &path, &constraints));
ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("ldltr-normal-long"),
diagnostics, &path, &constraints));
expected_configuration = test::ConfigDescriptionBuilder()
.setScreenLayout(0x62)
.setSdkVersion(0x0004) // screenLayout (size|long) requires donut
.Build();
EXPECT_CONFIG_EQ(constraints, expected_configuration);
ASSERT_TRUE(ParseSplitParameter(":car",
ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("car"),
diagnostics, &path, &constraints));
expected_configuration = test::ConfigDescriptionBuilder()
.setUiMode(0x03)
@@ -277,7 +287,7 @@ TEST (UtilTest, ParseSplitParameter) {
.Build();
EXPECT_CONFIG_EQ(constraints, expected_configuration);
ASSERT_TRUE(ParseSplitParameter(":vrheadset",
ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("vrheadset"),
diagnostics, &path, &constraints));
expected_configuration = test::ConfigDescriptionBuilder()
.setUiMode(0x07)
@@ -285,7 +295,7 @@ TEST (UtilTest, ParseSplitParameter) {
.Build();
EXPECT_CONFIG_EQ(constraints, expected_configuration);
ASSERT_TRUE(ParseSplitParameter(":television-night",
ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("television-night"),
diagnostics, &path, &constraints));
expected_configuration = test::ConfigDescriptionBuilder()
.setUiMode(0x24)
@@ -293,7 +303,7 @@ TEST (UtilTest, ParseSplitParameter) {
.Build();
EXPECT_CONFIG_EQ(constraints, expected_configuration);
ASSERT_TRUE(ParseSplitParameter(":sw1920dp",
ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("sw1920dp"),
diagnostics, &path, &constraints));
expected_configuration = test::ConfigDescriptionBuilder()
.setSmallestScreenWidthDp(0x0780)
@@ -304,7 +314,7 @@ TEST (UtilTest, ParseSplitParameter) {
// ========== Test SCREEN_SIZE_DP ==========
// screenWidthDp: 'w[0-9]dp'
// screenHeightDp: 'h[0-9]dp'
ASSERT_TRUE(ParseSplitParameter(":w1920dp",
ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("w1920dp"),
diagnostics, &path, &constraints));
expected_configuration = test::ConfigDescriptionBuilder()
.setScreenWidthDp(0x0780)
@@ -312,7 +322,7 @@ TEST (UtilTest, ParseSplitParameter) {
.Build();
EXPECT_CONFIG_EQ(constraints, expected_configuration);
ASSERT_TRUE(ParseSplitParameter(":h1080dp",
ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("h1080dp"),
diagnostics, &path, &constraints));
expected_configuration = test::ConfigDescriptionBuilder()
.setScreenHeightDp(0x0438)
@@ -324,7 +334,7 @@ TEST (UtilTest, ParseSplitParameter) {
// screenLayout2: '(round|notround)'
// colorMode: '(widecg|nowidecg)'
// colorMode: '(highhdr|lowdr)'
ASSERT_TRUE(ParseSplitParameter(":round",
ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("round"),
diagnostics, &path, &constraints));
expected_configuration = test::ConfigDescriptionBuilder()
.setScreenLayout2(0x02)
@@ -332,7 +342,7 @@ TEST (UtilTest, ParseSplitParameter) {
.Build();
EXPECT_CONFIG_EQ(constraints, expected_configuration);
ASSERT_TRUE(ParseSplitParameter(":widecg-highdr",
ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("widecg-highdr"),
diagnostics, &path, &constraints));
expected_configuration = test::ConfigDescriptionBuilder()
.setColorMode(0x0A)
@@ -349,10 +359,10 @@ TEST (UtilTest, AdjustSplitConstraintsForMinSdk) {
std::string path;
test_constraints.push_back({});
ASSERT_TRUE(ParseSplitParameter(":v7",
ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("v7"),
diagnostics, &path, &test_constraints.back()));
test_constraints.push_back({});
ASSERT_TRUE(ParseSplitParameter(":xhdpi",
ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("xhdpi"),
diagnostics, &path, &test_constraints.back()));
EXPECT_EQ(test_constraints.size(), 2);
EXPECT_EQ(test_constraints[0].name, "v7");

View File

@@ -33,6 +33,7 @@ class MockFileCollection : public io::IFileCollection {
public:
MOCK_METHOD1(FindFile, io::IFile*(const StringPiece& path));
MOCK_METHOD0(Iterator, std::unique_ptr<io::IFileCollectionIterator>());
MOCK_METHOD0(GetDirSeparator, char());
};
TEST(ProtoSerializeTest, SerializeSinglePackage) {

View File

@@ -25,6 +25,7 @@
#include "Source.h"
#include "io/Data.h"
#include "util/Files.h"
#include "util/Util.h"
namespace aapt {
@@ -103,6 +104,7 @@ class IFileCollection {
virtual IFile* FindFile(const android::StringPiece& path) = 0;
virtual std::unique_ptr<IFileCollectionIterator> Iterator() = 0;
virtual char GetDirSeparator() = 0;
};
} // namespace io

View File

@@ -128,5 +128,9 @@ std::unique_ptr<IFileCollectionIterator> FileCollection::Iterator() {
return util::make_unique<FileCollectionIterator>(this);
}
char FileCollection::GetDirSeparator() {
return file::sDirSep;
}
} // namespace io
} // namespace aapt

View File

@@ -67,6 +67,7 @@ class FileCollection : public IFileCollection {
IFile* InsertFile(const android::StringPiece& path);
IFile* FindFile(const android::StringPiece& path) override;
std::unique_ptr<IFileCollectionIterator> Iterator() override;
char GetDirSeparator() override;
private:
DISALLOW_COPY_AND_ASSIGN(FileCollection);

View File

@@ -154,6 +154,13 @@ std::unique_ptr<IFileCollectionIterator> ZipFileCollection::Iterator() {
return util::make_unique<ZipFileCollectionIterator>(this);
}
char ZipFileCollection::GetDirSeparator() {
// According to the zip file specification, section 4.4.17.1:
// "All slashes MUST be forward slashes '/' as opposed to backwards slashes '\' for compatibility
// with Amiga and UNIX file systems etc."
return '/';
}
ZipFileCollection::~ZipFileCollection() {
if (handle_) {
CloseArchive(handle_);

View File

@@ -66,6 +66,7 @@ class ZipFileCollection : public IFileCollection {
io::IFile* FindFile(const android::StringPiece& path) override;
std::unique_ptr<IFileCollectionIterator> Iterator() override;
char GetDirSeparator() override;
~ZipFileCollection() override;

View File

@@ -18,11 +18,21 @@
#include <sstream>
#include "android-base/stringprintf.h"
#include "test/Test.h"
using ::android::base::StringPrintf;
namespace aapt {
namespace file {
#ifdef _WIN32
constexpr const char sTestDirSep = '\\';
#else
constexpr const char sTestDirSep = '/';
#endif
class FilesTest : public ::testing::Test {
public:
void SetUp() override {
@@ -42,16 +52,16 @@ TEST_F(FilesTest, AppendPath) {
}
TEST_F(FilesTest, AppendPathWithLeadingOrTrailingSeparators) {
std::string base = "hello/";
std::string base = StringPrintf("hello%c", sTestDirSep);
AppendPath(&base, "there");
EXPECT_EQ(expected_path_, base);
base = "hello";
AppendPath(&base, "/there");
AppendPath(&base, StringPrintf("%cthere", sTestDirSep));
EXPECT_EQ(expected_path_, base);
base = "hello/";
AppendPath(&base, "/there");
base = StringPrintf("hello%c", sTestDirSep);
AppendPath(&base, StringPrintf("%cthere", sTestDirSep));
EXPECT_EQ(expected_path_, base);
}