blob: b0b01962350616772e6abe2ef010efaae0a24894 [file] [log] [blame]
// Copyright 2020 The Chromium OS 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 "shill/cli/command.h"
#include <memory>
#include <string>
#include <utility>
#include <base/bind.h>
#include <base/callback.h>
#include <gtest/gtest.h>
namespace shill_cli {
namespace {
base::Callback<bool()> WrapHasRun(bool* has_run) {
return base::Bind(
[](bool* b) {
*b = true;
return true;
},
base::Unretained(has_run));
}
base::Callback<bool()> WrapPlainReturn(bool return_value) {
return base::Bind([](bool b) { return b; }, return_value);
}
} // namespace
class CommandTest : public testing::Test {
public:
CommandTest()
: has_top_run_(false),
cmd_("testcli", "Test command", WrapHasRun(&has_top_run_)) {}
bool Run(std::vector<std::string> args) {
return cmd_.Run(args.cbegin(), args.cend(), cmd_.full_name());
}
template <typename... Args>
void AddSubcommand(Command* parent_command, Args... args) {
parent_command->AddSubcommand(args...);
}
std::vector<std::string> GetPrefixedSubcommands() const {
return cmd_.GetPrefixedSubcommands();
}
protected:
bool has_top_run_;
Command cmd_;
};
TEST_F(CommandTest, RunTopWhenEmpty) {
EXPECT_TRUE(Run({}));
EXPECT_TRUE(has_top_run_);
}
TEST_F(CommandTest, FailOnUnknownCommand) {
EXPECT_FALSE(Run({"unknown"}));
EXPECT_FALSE(has_top_run_);
}
TEST_F(CommandTest, PrefixMatchCommand) {
bool has_run = false;
AddSubcommand(&cmd_, "device", "", WrapHasRun(&has_run));
EXPECT_TRUE(Run({"device"}));
EXPECT_TRUE(has_run);
EXPECT_FALSE(has_top_run_);
has_run = false;
EXPECT_TRUE(Run({"dev"}));
EXPECT_TRUE(has_run);
EXPECT_FALSE(has_top_run_);
has_run = false;
EXPECT_TRUE(Run({"d"}));
EXPECT_TRUE(has_run);
EXPECT_FALSE(has_top_run_);
}
TEST_F(CommandTest, FailOnPrefixMatchAmbiguity) {
bool has_run_device = false;
bool has_run_detect = false;
AddSubcommand(&cmd_, "device", "", WrapHasRun(&has_run_device));
AddSubcommand(&cmd_, "detect", "", WrapHasRun(&has_run_detect));
EXPECT_TRUE(Run({"device"}));
EXPECT_TRUE(has_run_device);
EXPECT_FALSE(has_run_detect);
EXPECT_FALSE(has_top_run_);
has_run_device = false;
EXPECT_TRUE(Run({"dev"}));
EXPECT_TRUE(has_run_device);
EXPECT_FALSE(has_run_detect);
EXPECT_FALSE(has_top_run_);
has_run_device = false;
EXPECT_FALSE(Run({"d"}));
EXPECT_FALSE(has_run_device);
EXPECT_FALSE(has_run_detect);
EXPECT_FALSE(has_top_run_);
}
TEST_F(CommandTest, PreventAmbiguousCommandDefinitions) {
AddSubcommand(&cmd_, "device", "", WrapPlainReturn(true));
ASSERT_DEATH(AddSubcommand(&cmd_, "devic", "", WrapPlainReturn(true)), ".*");
ASSERT_DEATH(AddSubcommand(&cmd_, "device", "", WrapPlainReturn(true)), ".*");
ASSERT_DEATH(AddSubcommand(&cmd_, "devicee", "", WrapPlainReturn(true)),
".*");
}
TEST_F(CommandTest, PrefixedSubcommandsEmpty) {
// Not quite empty because of the help subcommand.
EXPECT_EQ(GetPrefixedSubcommands(), std::vector<std::string>{"h[elp]"});
}
TEST_F(CommandTest, PrefixedSubcommandsNotEmpty) {
AddSubcommand(&cmd_, "test", "", WrapPlainReturn(true));
AddSubcommand(&cmd_, "device", "", WrapPlainReturn(true));
EXPECT_EQ(GetPrefixedSubcommands(),
std::vector<std::string>({"d[evice]", "h[elp]", "t[est]"}));
AddSubcommand(&cmd_, "detect", "", WrapPlainReturn(true));
EXPECT_EQ(
GetPrefixedSubcommands(),
std::vector<std::string>({"det[ect]", "dev[ice]", "h[elp]", "t[est]"}));
}
} // namespace shill_cli