blob: e75256166ab4642f09c793b26f892798d7d70f6f [file]
// Copyright 2026 The GN 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 <string>
#include <string_view>
#include <vector>
#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "gn/commands.h"
#include "gn/setup.h"
#include "gn/switches.h"
#include "gn/target.h"
#include "gn/test_with_scheduler.h"
#include "gn/test_with_scope.h"
#include "util/test/test.h"
TEST(Suggest, ResolveModuleName) {
TestWithScope setup_scope;
SourceDir current_dir("//");
Label default_toolchain(SourceDir("//toolchain/"), "default");
Err err;
Target target(setup_scope.settings(), Label(SourceDir("//foo/"), "bar"));
target.set_module_name("my_module");
std::vector<const Target*> all_targets = {&target};
{
auto [results, ok] = commands::ResolveSuggestionToTarget(
setup_scope.build_settings(), all_targets, default_toolchain,
"my_module");
std::vector<std::pair<const Target*, commands::ApiScope>> expected = {
{&target, commands::ApiScope::kPublic}};
EXPECT_EQ(expected, results);
EXPECT_TRUE(ok);
}
// Test resolving module name "my_module_Private"
{
auto [results, ok] = commands::ResolveSuggestionToTarget(
setup_scope.build_settings(), all_targets, default_toolchain,
"my_module_Private");
std::vector<std::pair<const Target*, commands::ApiScope>> expected = {
{&target, commands::ApiScope::kPrivate}};
EXPECT_EQ(expected, results);
EXPECT_TRUE(ok);
}
}
TEST(Suggest, ResolveTargetName) {
TestWithScope setup_scope;
SourceDir current_dir("//");
Label default_toolchain = setup_scope.toolchain()->label();
Err err;
Target target(
setup_scope.settings(),
Label(SourceDir("//"), "hello", setup_scope.toolchain()->label().dir(),
setup_scope.toolchain()->label().name()));
Target target_gcc(
setup_scope.settings(),
Label(SourceDir("//"), "hello", SourceDir("//build/toolchain/"), "gcc"));
std::vector<const Target*> all_targets = {&target, &target_gcc};
// Test resolving "//:hello"
auto [results_label, ok_label] = commands::ResolveSuggestionToTarget(
setup_scope.build_settings(), all_targets,
setup_scope.toolchain()->label(), "//:hello");
std::vector<std::pair<const Target*, commands::ApiScope>> expected_label = {
{&target, commands::ApiScope::kPublic}};
EXPECT_EQ(expected_label, results_label);
EXPECT_TRUE(ok_label);
// Test resolving "//:hello(//build/toolchain:gcc)"
auto [results_toolchain, ok_toolchain] = commands::ResolveSuggestionToTarget(
setup_scope.build_settings(), all_targets, default_toolchain,
"//:hello(//build/toolchain:gcc)");
std::vector<std::pair<const Target*, commands::ApiScope>> expected_toolchain =
{{&target_gcc, commands::ApiScope::kPublic}};
EXPECT_EQ(expected_toolchain, results_toolchain);
EXPECT_TRUE(ok_toolchain);
}
TEST(Suggest, ResolveFileName) {
TestWithScope setup_scope;
SourceDir current_dir("//");
Label default_toolchain = setup_scope.toolchain()->label();
Label current_toolchain(SourceDir("//build/toolchain/"), "gcc");
Label secondary_toolchain(SourceDir("//build/toolchain/"), "clang");
Err err;
// Follow standard practice to create temporary directories in tests.
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
base::FilePath root_dir = temp_dir.GetPath();
setup_scope.build_settings()->SetRootPath(root_dir);
base::WriteFile(root_dir.AppendASCII("public.h"), "", 0);
base::WriteFile(root_dir.AppendASCII("private.h"), "", 0);
base::WriteFile(root_dir.AppendASCII("implicit_public.h"), "", 0);
base::WriteFile(root_dir.AppendASCII("no_target.h"), "", 0);
base::WriteFile(root_dir.AppendASCII("simple.h"), "", 0);
base::WriteFile(root_dir.AppendASCII("default_toolchain.h"), "", 0);
base::WriteFile(root_dir.AppendASCII("secondary_toolchain.h"), "", 0);
Target explicit_target(
setup_scope.settings(),
Label(SourceDir("//"), "explicit", current_toolchain.dir(),
current_toolchain.name()));
explicit_target.set_all_headers_public(false);
explicit_target.sources().push_back(SourceFile("//private.h"));
explicit_target.public_headers().push_back(SourceFile("//public.h"));
explicit_target.public_headers().push_back(
SourceFile("//nonexistent_file.h"));
Target implicit_target(
setup_scope.settings(),
Label(SourceDir("//"), "implicit", default_toolchain.dir(),
default_toolchain.name()));
implicit_target.set_all_headers_public(true);
implicit_target.sources().push_back(SourceFile("//implicit_public.h"));
implicit_target.sources().push_back(SourceFile("//private.cc"));
Target simple_default(
setup_scope.settings(),
Label(SourceDir("//"), "simple", default_toolchain.dir(),
default_toolchain.name()));
simple_default.public_headers().push_back(SourceFile("//public.h"));
simple_default.public_headers().push_back(
SourceFile("//default_toolchain.h"));
Target simple_secondary(
setup_scope.settings(),
Label(SourceDir("//"), "simple", secondary_toolchain.dir(),
secondary_toolchain.name()));
simple_secondary.public_headers().push_back(SourceFile("//public.h"));
simple_secondary.public_headers().push_back(
SourceFile("//default_toolchain.h"));
simple_secondary.public_headers().push_back(
SourceFile("//secondary_toolchain.h"));
std::vector<const Target*> all_targets = {&explicit_target, &implicit_target,
&simple_default, &simple_secondary};
{
auto [results, ok] = commands::ResolveSuggestionToTarget(
setup_scope.build_settings(), all_targets, current_toolchain,
"//public.h");
std::vector<std::pair<const Target*, commands::ApiScope>> expected = {
{&explicit_target, commands::ApiScope::kPublic}};
EXPECT_TRUE(ok);
EXPECT_EQ(expected, results);
}
{
auto [results, ok] = commands::ResolveSuggestionToTarget(
setup_scope.build_settings(), all_targets, current_toolchain,
"../../private.h");
std::vector<std::pair<const Target*, commands::ApiScope>> expected = {
{&explicit_target, commands::ApiScope::kPrivate}};
EXPECT_TRUE(ok);
EXPECT_EQ(expected, results);
}
{
auto [results, ok] = commands::ResolveSuggestionToTarget(
setup_scope.build_settings(), all_targets, current_toolchain,
"//implicit_public.h");
std::vector<std::pair<const Target*, commands::ApiScope>> expected = {
{&implicit_target, commands::ApiScope::kPublic}};
EXPECT_TRUE(ok);
EXPECT_EQ(expected, results);
}
{
auto [results, ok] = commands::ResolveSuggestionToTarget(
setup_scope.build_settings(), all_targets, current_toolchain,
"nonexistent_file.h");
EXPECT_FALSE(ok);
}
{
auto [results, ok] = commands::ResolveSuggestionToTarget(
setup_scope.build_settings(), all_targets, current_toolchain,
"//no_target.h");
std::vector<std::pair<const Target*, commands::ApiScope>> expected_targets;
EXPECT_TRUE(ok);
EXPECT_EQ(expected_targets, results);
}
{
auto [results, ok] = commands::ResolveSuggestionToTarget(
setup_scope.build_settings(), all_targets, current_toolchain,
"//default_toolchain.h");
std::vector<std::pair<const Target*, commands::ApiScope>> expected_targets =
{
{&simple_secondary, commands::ApiScope::kPublic},
{&simple_default, commands::ApiScope::kPublic},
};
EXPECT_TRUE(ok);
EXPECT_EQ(expected_targets, results);
}
{
auto [results, ok] = commands::ResolveSuggestionToTarget(
setup_scope.build_settings(), all_targets, current_toolchain,
"//secondary_toolchain.h");
std::vector<std::pair<const Target*, commands::ApiScope>> expected_targets =
{{{&simple_secondary, commands::ApiScope::kPublic}}};
EXPECT_TRUE(ok);
EXPECT_EQ(expected_targets, results);
}
}