blob: ffdfcd87e9d9410ae714b579a0b1291366820793 [file] [log] [blame]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "gn/rust_project_writer_helpers.h"
#include "base/strings/string_util.h"
#include "gn/filesystem_utils.h"
#include "gn/string_output_buffer.h"
#include "gn/test_with_scheduler.h"
#include "gn/test_with_scope.h"
#include "util/build_config.h"
#include "util/test/test.h"
static void ExpectEqOrShowDiff(const char* expected,
const std::string& actual) {
if (expected != actual) {
printf("\nExpected: >>>\n%s<<<\n", expected);
printf(" Actual: >>>\n%s<<<\n", actual.c_str());
}
EXPECT_EQ(expected, actual);
}
using RustProjectWriterHelper = TestWithScheduler;
TEST_F(RustProjectWriterHelper, WriteCrates) {
TestWithScope setup;
CrateList crates;
Crate dep = Crate(SourceFile("/root/tortoise/lib.rs"), std::nullopt, 0,
"//tortoise:bar", "2015");
Crate target = Crate(SourceFile("/root/hare/lib.rs"),
OutputFile("gendir/hare/"), 1, "//hare:bar", "2015");
target.AddDependency(0, "tortoise");
target.AddConfigItem("unix");
target.AddConfigItem("feature=\"test\"");
crates.push_back(dep);
crates.push_back(target);
std::ostringstream stream;
WriteCrates(setup.build_settings(), crates, stream);
std::string out = stream.str();
#if defined(OS_WIN)
base::ReplaceSubstringsAfterOffset(&out, 0, "\r\n", "\n");
#endif
const char expected_json[] =
"{\n"
" \"crates\": [\n"
" {\n"
" \"crate_id\": 0,\n"
" \"root_module\": \"/root/tortoise/lib.rs\",\n"
" \"label\": \"//tortoise:bar\",\n"
" \"source\": {\n"
" \"include_dirs\": [\n"
" \"/root/tortoise/\"\n"
" ],\n"
" \"exclude_dirs\": []\n"
" },\n"
" \"deps\": [\n"
" ],\n"
" \"edition\": \"2015\",\n"
" \"cfg\": [\n"
" ]\n"
" },\n"
" {\n"
" \"crate_id\": 1,\n"
" \"root_module\": \"/root/hare/lib.rs\",\n"
" \"label\": \"//hare:bar\",\n"
" \"source\": {\n"
" \"include_dirs\": [\n"
" \"/root/hare/\",\n"
" \"out/Debug/gendir/hare/\"\n"
" ],\n"
" \"exclude_dirs\": []\n"
" },\n"
" \"deps\": [\n"
" {\n"
" \"crate\": 0,\n"
" \"name\": \"tortoise\"\n"
" }\n"
" ],\n"
" \"edition\": \"2015\",\n"
" \"cfg\": [\n"
" \"unix\",\n"
" \"feature=\\\"test\\\"\"\n"
" ]\n"
" }\n"
" ]\n"
"}\n";
ExpectEqOrShowDiff(expected_json, out);
}
TEST_F(RustProjectWriterHelper, SysrootDepsAreCorrect) {
TestWithScope setup;
setup.build_settings()->SetRootPath(UTF8ToFilePath("/root"));
SysrootIndexMap sysroot_lookup;
CrateList crates;
AddSysroot(setup.build_settings(), "sysroot", sysroot_lookup, crates);
std::ostringstream stream;
WriteCrates(setup.build_settings(), crates, stream);
std::string out = stream.str();
#if defined(OS_WIN)
base::ReplaceSubstringsAfterOffset(&out, 0, "\r\n", "\n");
#endif
const char expected_json[] =
"{\n"
" \"crates\": [\n"
" {\n"
" \"crate_id\": 0,\n"
" \"root_module\": "
"\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/core/src/"
"lib.rs\",\n"
" \"label\": \"core\",\n"
" \"source\": {\n"
" \"include_dirs\": [\n"
" "
"\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/core/src/\"\n"
" ],\n"
" \"exclude_dirs\": []\n"
" },\n"
" \"deps\": [\n"
" ],\n"
" \"edition\": \"2018\",\n"
" \"cfg\": [\n"
" \"debug_assertions\"\n"
" ]\n"
" },\n"
" {\n"
" \"crate_id\": 1,\n"
" \"root_module\": "
"\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/alloc/src/"
"lib.rs\",\n"
" \"label\": \"alloc\",\n"
" \"source\": {\n"
" \"include_dirs\": [\n"
" "
"\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/alloc/src/\"\n"
" ],\n"
" \"exclude_dirs\": []\n"
" },\n"
" \"deps\": [\n"
" {\n"
" \"crate\": 0,\n"
" \"name\": \"core\"\n"
" }\n"
" ],\n"
" \"edition\": \"2018\",\n"
" \"cfg\": [\n"
" \"debug_assertions\"\n"
" ]\n"
" },\n"
" {\n"
" \"crate_id\": 2,\n"
" \"root_module\": "
"\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/panic_abort/src/"
"lib.rs\",\n"
" \"label\": \"panic_abort\",\n"
" \"source\": {\n"
" \"include_dirs\": [\n"
" "
"\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/panic_abort/src/"
"\"\n"
" ],\n"
" \"exclude_dirs\": []\n"
" },\n"
" \"deps\": [\n"
" ],\n"
" \"edition\": \"2018\",\n"
" \"cfg\": [\n"
" \"debug_assertions\"\n"
" ]\n"
" },\n"
" {\n"
" \"crate_id\": 3,\n"
" \"root_module\": "
"\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/unwind/src/"
"lib.rs\",\n"
" \"label\": \"unwind\",\n"
" \"source\": {\n"
" \"include_dirs\": [\n"
" "
"\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/unwind/src/\"\n"
" ],\n"
" \"exclude_dirs\": []\n"
" },\n"
" \"deps\": [\n"
" ],\n"
" \"edition\": \"2018\",\n"
" \"cfg\": [\n"
" \"debug_assertions\"\n"
" ]\n"
" },\n"
" {\n"
" \"crate_id\": 4,\n"
" \"root_module\": "
"\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/std/src/"
"lib.rs\",\n"
" \"label\": \"std\",\n"
" \"source\": {\n"
" \"include_dirs\": [\n"
" "
"\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/std/src/\"\n"
" ],\n"
" \"exclude_dirs\": []\n"
" },\n"
" \"deps\": [\n"
" {\n"
" \"crate\": 1,\n"
" \"name\": \"alloc\"\n"
" },\n"
" {\n"
" \"crate\": 0,\n"
" \"name\": \"core\"\n"
" },\n"
" {\n"
" \"crate\": 2,\n"
" \"name\": \"panic_abort\"\n"
" },\n"
" {\n"
" \"crate\": 3,\n"
" \"name\": \"unwind\"\n"
" }\n"
" ],\n"
" \"edition\": \"2018\",\n"
" \"cfg\": [\n"
" \"debug_assertions\"\n"
" ]\n"
" },\n"
" {\n"
" \"crate_id\": 5,\n"
" \"root_module\": "
"\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/panic_unwind/src/"
"lib.rs\",\n"
" \"label\": \"panic_unwind\",\n"
" \"source\": {\n"
" \"include_dirs\": [\n"
" "
"\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/panic_unwind/src/"
"\"\n"
" ],\n"
" \"exclude_dirs\": []\n"
" },\n"
" \"deps\": [\n"
" ],\n"
" \"edition\": \"2018\",\n"
" \"cfg\": [\n"
" \"debug_assertions\"\n"
" ]\n"
" },\n"
" {\n"
" \"crate_id\": 6,\n"
" \"root_module\": "
"\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/proc_macro/src/"
"lib.rs\",\n"
" \"label\": \"proc_macro\",\n"
" \"source\": {\n"
" \"include_dirs\": [\n"
" "
"\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/proc_macro/src/"
"\"\n"
" ],\n"
" \"exclude_dirs\": []\n"
" },\n"
" \"deps\": [\n"
" ],\n"
" \"edition\": \"2018\",\n"
" \"cfg\": [\n"
" \"debug_assertions\"\n"
" ]\n"
" },\n"
" {\n"
" \"crate_id\": 7,\n"
" \"root_module\": "
"\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/test/src/"
"lib.rs\",\n"
" \"label\": \"test\",\n"
" \"source\": {\n"
" \"include_dirs\": [\n"
" "
"\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/test/src/\"\n"
" ],\n"
" \"exclude_dirs\": []\n"
" },\n"
" \"deps\": [\n"
" ],\n"
" \"edition\": \"2018\",\n"
" \"cfg\": [\n"
" \"debug_assertions\"\n"
" ]\n"
" }\n"
" ]\n"
"}\n";
ExpectEqOrShowDiff(expected_json, out);
}
TEST_F(RustProjectWriterHelper, ExtractCompilerTargetTupleSimple) {
TestWithScope setup;
Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
target.set_output_type(Target::RUST_LIBRARY);
target.visibility().SetPublic();
SourceFile lib("//foo/lib.rs");
target.sources().push_back(lib);
target.source_types_used().Set(SourceFile::SOURCE_RS);
target.rust_values().set_crate_root(lib);
target.rust_values().crate_name() = "foo";
target.config_values().rustflags().push_back("--cfg=feature=\"foo_enabled\"");
target.config_values().rustflags().push_back("--target");
target.config_values().rustflags().push_back("x86-someos");
target.config_values().rustflags().push_back("--edition=2018");
auto args = ExtractCompilerArgs(&target);
std::optional<std::string> result = FindArgValue("--target", args);
auto expected = std::optional<std::string>{"x86-someos"};
EXPECT_EQ(expected, result);
}
TEST_F(RustProjectWriterHelper, ExtractCompilerTargetTupleMissing) {
TestWithScope setup;
Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
target.set_output_type(Target::RUST_LIBRARY);
target.visibility().SetPublic();
SourceFile lib("//foo/lib.rs");
target.sources().push_back(lib);
target.source_types_used().Set(SourceFile::SOURCE_RS);
target.rust_values().set_crate_root(lib);
target.rust_values().crate_name() = "foo";
target.config_values().rustflags().push_back(
"--cfg=featur4e=\"foo_enabled\"");
target.config_values().rustflags().push_back("x86-someos");
target.config_values().rustflags().push_back("--edition=2018");
auto args = ExtractCompilerArgs(&target);
std::optional<std::string> result = FindArgValue("--target", args);
auto expected = std::nullopt;
EXPECT_EQ(expected, result);
}
TEST_F(RustProjectWriterHelper, ExtractCompilerTargetTupleDontFallOffEnd) {
TestWithScope setup;
Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
target.set_output_type(Target::RUST_LIBRARY);
target.visibility().SetPublic();
SourceFile lib("//foo/lib.rs");
target.sources().push_back(lib);
target.source_types_used().Set(SourceFile::SOURCE_RS);
target.rust_values().set_crate_root(lib);
target.rust_values().crate_name() = "foo";
target.config_values().rustflags().push_back("--cfg=feature=\"foo_enabled\"");
target.config_values().rustflags().push_back("--edition=2018");
target.config_values().rustflags().push_back("--target");
auto args = ExtractCompilerArgs(&target);
std::optional<std::string> result = FindArgValue("--target", args);
auto expected = std::nullopt;
EXPECT_EQ(expected, result);
}
TEST_F(RustProjectWriterHelper, ExtractFirstArgValueWithPrefixMissing) {
TestWithScope setup;
Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
target.set_output_type(Target::RUST_LIBRARY);
target.visibility().SetPublic();
SourceFile lib("//foo/lib.rs");
target.sources().push_back(lib);
target.source_types_used().Set(SourceFile::SOURCE_RS);
target.rust_values().set_crate_root(lib);
target.rust_values().crate_name() = "foo";
target.config_values().rustflags().push_back("--cfg=feature=\"foo_enabled\"");
target.config_values().rustflags().push_back("--edition=2018");
target.config_values().rustflags().push_back("--target");
auto args = ExtractCompilerArgs(&target);
std::optional<std::string> result =
FindArgValueAfterPrefix("--missing", args);
auto expected = std::nullopt;
EXPECT_EQ(expected, result);
}
TEST_F(RustProjectWriterHelper, ExtractFirstArgValueWithPrefix) {
TestWithScope setup;
Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
target.set_output_type(Target::RUST_LIBRARY);
target.visibility().SetPublic();
SourceFile lib("//foo/lib.rs");
target.sources().push_back(lib);
target.source_types_used().Set(SourceFile::SOURCE_RS);
target.rust_values().set_crate_root(lib);
target.rust_values().crate_name() = "foo";
target.config_values().rustflags().push_back("--cfg=feature=\"foo_enabled\"");
target.config_values().rustflags().push_back("--edition=2018");
target.config_values().rustflags().push_back("--target");
auto args = ExtractCompilerArgs(&target);
std::optional<std::string> result =
FindArgValueAfterPrefix("--edition=", args);
auto expected = std::optional<std::string>{"2018"};
EXPECT_EQ(expected, result);
}
TEST_F(RustProjectWriterHelper, ExtractAllArgValueWithPrefix) {
TestWithScope setup;
Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
target.set_output_type(Target::RUST_LIBRARY);
target.visibility().SetPublic();
SourceFile lib("//foo/lib.rs");
target.sources().push_back(lib);
target.source_types_used().Set(SourceFile::SOURCE_RS);
target.rust_values().set_crate_root(lib);
target.rust_values().crate_name() = "foo";
target.config_values().rustflags().push_back("--cfg=feature=\"foo_enabled\"");
target.config_values().rustflags().push_back("--edition=2018");
target.config_values().rustflags().push_back("--cfg=feature=\"bar_enabled\"");
target.config_values().rustflags().push_back("--target");
auto args = ExtractCompilerArgs(&target);
std::vector<std::string> result = FindAllArgValuesAfterPrefix("--cfg=", args);
std::vector<std::string> expected = {"feature=\"foo_enabled\"",
"feature=\"bar_enabled\""};
EXPECT_EQ(expected, result);
}