2026-02-21 01:40:19 +00:00
|
|
|
/*
|
|
|
|
|
* Copyright (c) 2026 Ember
|
|
|
|
|
*
|
|
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
|
*/
|
|
|
|
|
|
2026-03-29 00:38:21 +00:00
|
|
|
#include <commands/Commands.h>
|
2026-02-21 01:40:19 +00:00
|
|
|
#include <gtest/gtest.h>
|
|
|
|
|
#include <array>
|
|
|
|
|
#include <ranges>
|
|
|
|
|
|
|
|
|
|
using namespace ember;
|
|
|
|
|
|
|
|
|
|
class Registry : public ::testing::Test {
|
|
|
|
|
public:
|
|
|
|
|
virtual void SetUp() {
|
2026-03-29 00:38:21 +00:00
|
|
|
registry = commands::create("root");
|
|
|
|
|
|
|
|
|
|
auto cmd = registry->insert("root")
|
2026-02-21 01:40:19 +00:00
|
|
|
->description("root command")
|
2026-03-20 19:05:55 +00:00
|
|
|
->argument<std::string>("arg1")
|
|
|
|
|
->argument<std::string>("arg2")
|
2026-03-21 21:42:37 +00:00
|
|
|
->argument<std::uint32_t>("arg3", commands::optional)
|
2026-02-21 01:40:19 +00:00
|
|
|
->handler([&](auto /*args*/) {
|
|
|
|
|
success = true;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
cmd->insert("root_nested_1");
|
|
|
|
|
cmd->insert("root_nested_2")
|
|
|
|
|
->insert("root_nested_2_1");
|
|
|
|
|
|
2026-03-29 00:38:21 +00:00
|
|
|
registry->insert("root_1"); // error: unavailable
|
|
|
|
|
registry->insert("root_2")->insert("root_2_1"); // error: subcommands only
|
2026-02-21 01:40:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual void TearDown() {}
|
|
|
|
|
|
2026-03-29 00:38:21 +00:00
|
|
|
std::shared_ptr<commands::Command> registry;
|
2026-02-21 01:40:19 +00:00
|
|
|
bool success = false;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
using Commands = Registry;
|
|
|
|
|
|
|
|
|
|
TEST_F(Registry, ParseInput) {
|
|
|
|
|
const auto input = "Lorem ipsum dolor sit amet";
|
2026-03-29 00:38:21 +00:00
|
|
|
const auto tokens = commands::parse_input(input);
|
2026-02-21 01:40:19 +00:00
|
|
|
|
|
|
|
|
const std::array<std::string_view, 5> expected {
|
|
|
|
|
"Lorem", "ipsum", "dolor", "sit", "amet"
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(tokens.size(), expected.size());
|
|
|
|
|
|
|
|
|
|
for(auto [t, e] : std::views::zip(tokens, expected)) {
|
|
|
|
|
ASSERT_EQ(t, e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(Registry, ParseQuotedInput) {
|
|
|
|
|
const auto input = R"(Lorem "ipsum dolor" sit amet)";
|
2026-03-29 00:38:21 +00:00
|
|
|
const auto tokens = commands::parse_input(input);
|
2026-02-21 01:40:19 +00:00
|
|
|
|
|
|
|
|
const std::array<std::string_view, 4> expected {
|
|
|
|
|
"Lorem", "ipsum dolor", "sit", "amet"
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(tokens.size(), expected.size());
|
|
|
|
|
|
|
|
|
|
for(auto [t, e] : std::views::zip(tokens, expected)) {
|
|
|
|
|
ASSERT_EQ(t, e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(Registry, ParseEscapeQuotedInput) {
|
|
|
|
|
const auto input = R"("Hello, "\"world!"\")";
|
2026-03-29 00:38:21 +00:00
|
|
|
const auto tokens = commands::parse_input(input);
|
2026-02-21 01:40:19 +00:00
|
|
|
|
|
|
|
|
const std::array<std::string_view, 1> expected {
|
|
|
|
|
R"(Hello, "world!")"
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(tokens.size(), expected.size());
|
|
|
|
|
|
|
|
|
|
for(auto [t, e] : std::views::zip(tokens, expected)) {
|
|
|
|
|
ASSERT_EQ(t, e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(Registry, ParseBadEscapedInput) {
|
2026-03-29 00:38:21 +00:00
|
|
|
const std::string_view input = R"("Hello, \world")";
|
|
|
|
|
ASSERT_THROW(commands::parse_input(input), commands::parse_error);
|
2026-02-21 01:40:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(Registry, AddCommand) {
|
2026-03-29 00:38:21 +00:00
|
|
|
registry->insert("test")
|
2026-02-21 01:40:19 +00:00
|
|
|
->description("test_description");
|
|
|
|
|
|
2026-03-29 00:38:21 +00:00
|
|
|
const auto input = commands::parse_input("test");
|
|
|
|
|
ASSERT_NE(registry->find(input).command, nullptr);
|
2026-02-21 01:40:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(Registry, EraseCommand) {
|
2026-03-29 00:38:21 +00:00
|
|
|
ASSERT_TRUE(registry->erase("root"));
|
|
|
|
|
ASSERT_EQ(registry->find("root").command, nullptr);
|
2026-02-21 01:40:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(Registry, EraseNotFoundCommand) {
|
2026-03-29 00:38:21 +00:00
|
|
|
ASSERT_FALSE(registry->erase("fake_command"));
|
2026-02-21 01:40:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(Registry, SearchSubcommands) {
|
2026-03-29 00:38:21 +00:00
|
|
|
const auto result = registry->find("root root_nested_1 root_nested_2");
|
2026-02-21 01:40:19 +00:00
|
|
|
ASSERT_TRUE(result.command);
|
|
|
|
|
ASSERT_EQ(result.depth, 2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(Registry, Autocomplete) {
|
2026-03-29 00:38:21 +00:00
|
|
|
const auto result = registry->autocomplete("r");
|
2026-02-21 01:40:19 +00:00
|
|
|
ASSERT_EQ(result.substring, "root ");
|
|
|
|
|
ASSERT_EQ(result.records.size(), 3);
|
|
|
|
|
ASSERT_EQ(result.records.front().name, "root");
|
|
|
|
|
ASSERT_EQ(result.records.front().desc, "root command");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(Registry, AutocompleteSubcommands) {
|
2026-04-01 23:01:00 +01:00
|
|
|
const auto result = registry->autocomplete("root r");
|
2026-02-21 01:40:19 +00:00
|
|
|
ASSERT_EQ(result.substring, "root root_nested_");
|
|
|
|
|
ASSERT_EQ(result.records.size(), 2);
|
|
|
|
|
ASSERT_EQ(result.records.front().name, "root_nested_1");
|
|
|
|
|
ASSERT_EQ(result.records.back().name, "root_nested_2");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(Registry, AutocompleteNestedSubcommand) {
|
2026-04-01 23:01:00 +01:00
|
|
|
const auto result = registry->autocomplete("root root_nested_2 r");
|
2026-02-21 01:40:19 +00:00
|
|
|
ASSERT_EQ(result.substring, "root root_nested_2 root_nested_2_1");
|
|
|
|
|
ASSERT_EQ(result.records.size(), 1);
|
|
|
|
|
ASSERT_EQ(result.records.front().name, "root_nested_2_1");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(Registry, SearchNoMatch) {
|
2026-03-29 00:38:21 +00:00
|
|
|
const auto result = registry->autocomplete("foo");
|
2026-02-21 01:40:19 +00:00
|
|
|
ASSERT_TRUE(result.substring.empty());
|
|
|
|
|
ASSERT_TRUE(result.records.empty());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(Registry, PathFragment) {
|
2026-03-29 00:38:21 +00:00
|
|
|
const auto tokens = commands::parse_input("root root_nested_2 root_nested_2_1");
|
2026-02-21 01:40:19 +00:00
|
|
|
ASSERT_EQ(commands::path_fragment(tokens, 0), "");
|
|
|
|
|
ASSERT_EQ(commands::path_fragment(tokens, 1), "root");
|
|
|
|
|
ASSERT_EQ(commands::path_fragment(tokens, 2), "root root_nested_2");
|
|
|
|
|
ASSERT_EQ(commands::path_fragment(tokens, 3), "root root_nested_2 root_nested_2_1");
|
|
|
|
|
ASSERT_EQ(commands::path_fragment(tokens, 4), "");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(Commands, InsertCommand) {
|
2026-03-29 00:38:21 +00:00
|
|
|
auto cmd = registry->find("root").command;
|
2026-02-21 01:40:19 +00:00
|
|
|
cmd->insert("subcommand")->description("It's a subcommand");
|
|
|
|
|
auto subcommands = cmd->commands();
|
|
|
|
|
ASSERT_EQ(subcommands.size(), 3);
|
|
|
|
|
ASSERT_EQ(subcommands.contains("subcommand"), 1);
|
|
|
|
|
ASSERT_EQ(subcommands["subcommand"]->description(), "It's a subcommand");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(Commands, EraseCommand) {
|
2026-03-29 00:38:21 +00:00
|
|
|
auto cmd = registry->find("root").command;
|
2026-02-21 01:40:19 +00:00
|
|
|
cmd->erase("root_nested_1");
|
|
|
|
|
ASSERT_FALSE(cmd->commands().contains("root_nested_1"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(Commands, ClearCommands) {
|
2026-03-29 00:38:21 +00:00
|
|
|
auto cmd = registry->find("root").command;
|
2026-02-21 01:40:19 +00:00
|
|
|
cmd->clear_commands();
|
|
|
|
|
ASSERT_TRUE(cmd->commands().empty());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(Commands, UpdateDescription) {
|
2026-03-29 00:38:21 +00:00
|
|
|
auto cmd = registry->find("root").command;
|
2026-02-21 01:40:19 +00:00
|
|
|
ASSERT_EQ(cmd->description(), "root command");
|
|
|
|
|
cmd->description("New description!");
|
|
|
|
|
ASSERT_EQ(cmd->description(), "New description!");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(Commands, ArgumentCount) {
|
2026-03-29 00:38:21 +00:00
|
|
|
auto cmd = registry->find("root").command;
|
2026-02-21 01:40:19 +00:00
|
|
|
ASSERT_EQ(cmd->argument_count(), 3);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(Commands, AddArgument) {
|
2026-03-29 00:38:21 +00:00
|
|
|
auto cmd = registry->find("root").command;
|
2026-03-21 21:42:37 +00:00
|
|
|
cmd->argument<char>("arg4", commands::optional);
|
2026-02-21 01:40:19 +00:00
|
|
|
ASSERT_EQ(cmd->argument_count(), 4);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(Commands, AddArgumentOutOfOrder) {
|
2026-03-29 00:38:21 +00:00
|
|
|
auto cmd = registry->find("root").command;
|
2026-03-20 19:05:55 +00:00
|
|
|
ASSERT_THROW(cmd->argument<char>("arg4"), std::invalid_argument);
|
2026-02-21 01:40:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(Commands, EraseInsertArgument) {
|
2026-03-29 00:38:21 +00:00
|
|
|
auto cmd = registry->find("root").command;
|
2026-02-21 01:40:19 +00:00
|
|
|
ASSERT_TRUE(cmd->erase_argument("arg3"));
|
2026-03-20 19:05:55 +00:00
|
|
|
cmd->argument<char>("arg3");
|
2026-02-21 01:40:19 +00:00
|
|
|
ASSERT_EQ(cmd->argument_count(), 3);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(Commands, EraseArgument) {
|
2026-03-29 00:38:21 +00:00
|
|
|
auto cmd = registry->find("root").command;
|
2026-02-21 01:40:19 +00:00
|
|
|
ASSERT_TRUE(cmd->erase_argument("arg1"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(Commands, EraseNotFoundArgument) {
|
2026-03-29 00:38:21 +00:00
|
|
|
auto cmd = registry->find("root").command;
|
2026-02-21 01:40:19 +00:00
|
|
|
ASSERT_FALSE(cmd->erase_argument("fake_arg1"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(Commands, ClearArguments) {
|
2026-03-29 00:38:21 +00:00
|
|
|
auto cmd = registry->find("root").command;
|
2026-02-21 01:40:19 +00:00
|
|
|
cmd->clear_arguments();
|
|
|
|
|
ASSERT_TRUE(cmd->arguments().empty());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(Commands, ExecuteNoHandler) {
|
2026-03-29 00:38:21 +00:00
|
|
|
auto cmd = registry->find("root_1").command;
|
2026-02-21 01:40:19 +00:00
|
|
|
ASSERT_EQ(cmd->execute(), commands::Result::unavailable);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(Commands, Execute_InvalidTypes) {
|
2026-03-29 00:38:21 +00:00
|
|
|
auto cmd = registry->find("root").command;
|
2026-02-21 01:40:19 +00:00
|
|
|
|
2026-03-20 19:05:55 +00:00
|
|
|
std::array<std::any, 3> args {
|
2026-02-21 01:40:19 +00:00
|
|
|
"Are you sure that's the point, Doctor?",
|
|
|
|
|
"Of course. What else could it be?",
|
|
|
|
|
"That you should never tell the same lie twice."
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(cmd->execute(args), commands::Result::invalid_types);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(Commands, Execute_SubcommandsOnly) {
|
2026-03-29 00:38:21 +00:00
|
|
|
auto cmd = registry->find("root_2").command;
|
2026-02-21 01:40:19 +00:00
|
|
|
ASSERT_EQ(cmd->execute(), commands::Result::subcommands);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(Commands, Execute_MissingArgsEmpty) {
|
2026-03-29 00:38:21 +00:00
|
|
|
auto cmd = registry->find("root").command;
|
2026-02-21 01:40:19 +00:00
|
|
|
ASSERT_EQ(cmd->execute(), commands::Result::missing_args);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(Commands, Execute_TooManyArgs) {
|
2026-03-29 00:38:21 +00:00
|
|
|
auto cmd = registry->find("root").command;
|
2026-02-21 01:40:19 +00:00
|
|
|
|
2026-03-20 19:05:55 +00:00
|
|
|
std::array<std::any, 4> args {
|
2026-02-21 01:40:19 +00:00
|
|
|
"The", "quick", "brown", "fox"
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(cmd->execute(args), commands::Result::too_many_args);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(Commands, Execute_MissingArgs) {
|
2026-03-29 00:38:21 +00:00
|
|
|
auto cmd = registry->find("root").command;
|
2026-02-21 01:40:19 +00:00
|
|
|
|
2026-03-20 19:05:55 +00:00
|
|
|
std::array<std::any, 1> args {
|
2026-02-21 01:40:19 +00:00
|
|
|
"jumped",
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(cmd->execute(), commands::Result::missing_args);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(Commands, Execute_RequiredArgs_Success) {
|
2026-03-29 00:38:21 +00:00
|
|
|
auto cmd = registry->find("root").command;
|
2026-02-21 01:40:19 +00:00
|
|
|
|
2026-03-20 19:05:55 +00:00
|
|
|
std::array<std::any, 2> args {
|
|
|
|
|
std::string("over"), std::string("the"),
|
2026-02-21 01:40:19 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(cmd->execute(args), commands::Result::success);
|
|
|
|
|
ASSERT_TRUE(success);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(Commands, Execute_OptionalArgs_Success) {
|
2026-03-29 00:38:21 +00:00
|
|
|
auto cmd = registry->find("root").command;
|
2026-02-21 01:40:19 +00:00
|
|
|
|
2026-03-20 19:05:55 +00:00
|
|
|
std::array<std::any, 3> args {
|
|
|
|
|
std::string("lazy"), std::string("dog"), std::uint32_t(42)
|
2026-02-21 01:40:19 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(cmd->execute(args), commands::Result::success);
|
|
|
|
|
ASSERT_TRUE(success);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(Commands, Execute_AllArgTypes_Success) {
|
2026-03-29 00:38:21 +00:00
|
|
|
auto cmd = registry->find("root").command;
|
2026-02-21 01:40:19 +00:00
|
|
|
cmd->clear_arguments();
|
|
|
|
|
|
2026-03-20 19:05:55 +00:00
|
|
|
struct UserData {
|
2026-02-27 01:24:45 +00:00
|
|
|
int foo;
|
|
|
|
|
float bar;
|
2026-03-20 19:05:55 +00:00
|
|
|
} data{};
|
|
|
|
|
|
|
|
|
|
cmd->argument<std::string>("arg1")
|
|
|
|
|
->argument<char>("arg2")
|
|
|
|
|
->argument<double>("arg3")
|
|
|
|
|
->argument<float>("arg4")
|
|
|
|
|
->argument<std::int16_t>("arg5")
|
|
|
|
|
->argument<std::int32_t>("arg6")
|
|
|
|
|
->argument<std::int64_t>("arg7")
|
|
|
|
|
->argument<std::int8_t>("arg8")
|
|
|
|
|
->argument<std::uint16_t>("arg9")
|
|
|
|
|
->argument<std::uint32_t>("arg10")
|
|
|
|
|
->argument<std::uint64_t>("arg11")
|
|
|
|
|
->argument<std::uint8_t>("arg12")
|
|
|
|
|
->argument<UserData>("arg13");
|
|
|
|
|
|
|
|
|
|
std::array<std::any, 13> args {
|
|
|
|
|
std::string("Hello, world"), 'c', 1.0, 1.0f,
|
2026-02-21 01:40:19 +00:00
|
|
|
std::int16_t(0), std::int32_t(0), std::int64_t(0), std::int8_t(0),
|
2026-02-27 01:24:45 +00:00
|
|
|
std::uint16_t(0), std::uint32_t(0), std::uint64_t(0), std::uint8_t(0),
|
2026-03-20 19:05:55 +00:00
|
|
|
data
|
2026-02-21 01:40:19 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(cmd->execute(args), commands::Result::success);
|
|
|
|
|
ASSERT_TRUE(success);
|
2026-02-27 01:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2026-02-27 01:45:01 +00:00
|
|
|
TEST_F(Commands, CommandFlags) {
|
2026-03-29 00:38:21 +00:00
|
|
|
auto command = registry->insert("test")
|
2026-02-27 01:45:01 +00:00
|
|
|
->flags({ 42, 117 });
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(command->flags().custom, 42);
|
|
|
|
|
ASSERT_EQ(command->flags().security, 117);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(Commands, CommandFlagsUpdate) {
|
2026-03-29 00:38:21 +00:00
|
|
|
auto command = registry->insert("test")
|
2026-02-27 01:45:01 +00:00
|
|
|
->flags({ 42, 117 });
|
|
|
|
|
|
|
|
|
|
command->flags({ 0xB105F00D, 0x8BADF00D });
|
|
|
|
|
ASSERT_EQ(command->flags().custom, 0xB105F00D);
|
|
|
|
|
ASSERT_EQ(command->flags().security, 0x8BADF00D);
|
2026-04-07 10:03:56 +01:00
|
|
|
}
|
|
|
|
|
|
2026-04-07 20:36:39 +01:00
|
|
|
TEST_F(Commands, ScopedCommandInsertReset) {
|
|
|
|
|
auto command = registry->scoped_insert("scoped_test");
|
|
|
|
|
auto result = registry->find("scoped_test");
|
|
|
|
|
ASSERT_TRUE(result.command);
|
|
|
|
|
command.reset();
|
|
|
|
|
result = registry->find("scoped_test");
|
|
|
|
|
ASSERT_FALSE(result.command);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(Commands, ScopedSubcommandInsertReset) {
|
|
|
|
|
auto command = registry->scoped_insert("scoped_test");
|
|
|
|
|
command->insert("scoped_subcommand");
|
|
|
|
|
auto result = registry->find("scoped_test scoped_subcommand");
|
|
|
|
|
ASSERT_TRUE(result.command);
|
|
|
|
|
command.reset();
|
|
|
|
|
result = registry->find("scoped_test scoped_subcommand");
|
|
|
|
|
ASSERT_FALSE(result.command);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(Commands, ScopedCommandPtrInsertReset) {
|
|
|
|
|
auto root = commands::create("foo");
|
|
|
|
|
root->insert("bar");
|
|
|
|
|
auto scoped = registry->scoped_insert(root);
|
|
|
|
|
auto result = registry->find("foo bar");
|
|
|
|
|
ASSERT_TRUE(result.command);
|
|
|
|
|
scoped.reset();
|
|
|
|
|
result = registry->find("foo bar");
|
|
|
|
|
ASSERT_FALSE(result.command);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(Commands, ScopedCommandRAIIScope) {
|
|
|
|
|
auto root = commands::create("foo");
|
|
|
|
|
root->insert("bar");
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
auto scoped = registry->scoped_insert(root);
|
|
|
|
|
auto result = registry->find("foo bar");
|
|
|
|
|
ASSERT_TRUE(result.command);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto result = registry->find("foo bar");
|
|
|
|
|
ASSERT_FALSE(result.command);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(Commands, ScopedCommandRelease) {
|
|
|
|
|
auto root = commands::create("foo");
|
|
|
|
|
root->insert("bar");
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
auto scoped = registry->scoped_insert(root);
|
|
|
|
|
auto result = registry->find("foo bar");
|
|
|
|
|
ASSERT_TRUE(result.command);
|
|
|
|
|
scoped.release(); // not a leak, just downgrades to non-scoped
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto result = registry->find("foo bar");
|
|
|
|
|
ASSERT_TRUE(result.command);
|
2026-02-21 01:40:19 +00:00
|
|
|
}
|