| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- //
- // action_test.cpp
- // program_args-test
- //
- // Created by Sam Jaffe on 2/13/22.
- //
- #include "program_args/arguments.h"
- #include "xcode_gtest_helper.h"
- using testing::NotNull;
- namespace program {
- struct ArgumentTestHelper {
- template <typename Impl> static int main(Impl const & args) {
- return args.invoke();
- }
- };
- }
- template <typename T, size_t N> static T parse(char const * const (&argv)[N]) {
- return T(N, argv);
- }
- program::detail::Any g_action;
- template <typename Arg, typename... Args>
- int typed_main(Arg const &arg, Args const &...args) {
- auto const &last = std::get<sizeof...(Args)>(std::forward_as_tuple(arg, args...));
- g_action = program::detail::Any(&last);
- return 0;
- }
- struct Checkout : program::Arguments<Checkout> {
- using Arguments::Arguments;
- std::string commitish = argument(0, "commit-ish");
- };
- struct Commit : program::Arguments<Commit> {
- using Arguments::Arguments;
- std::string message = option("message", 'm');
- };
- class Push : public program::Arguments<Push> {
- public:
- using Arguments::Arguments;
- std::string remote = argument(0, "repository") = PROGRAM_DEFER(_remote());
- private:
- std::string _remote() const;
- };
- struct SetUrl : program::Arguments<SetUrl> {
- using Arguments::Arguments;
- bool push = flag("push") = false;
- std::string name = argument(0, "name");
- std::string new_url = argument(1, "newurl");
- std::string old_url = argument(2, "oldurl") = "";
- };
- struct Show : program::Arguments<Show> {
- using Arguments::Arguments;
- bool use_cached = flag('n') = false;
- };
- struct Remote : public program::Arguments<Remote> {
- PROGRAM_ARGS_INVOKE_WITH_DEFAULT(show, show, set_url);
- bool verbose = flag('v') = false;
- SetUrl set_url = action("set-url");
- Show show = action("show");
- };
- struct Bad1 : program::Arguments<Bad1> {
- using Arguments::Arguments;
- Commit commit = action("commit");
- std::string arg0 = argument(0, "arg0");
- };
- struct Bad2 : program::Arguments<Bad2> {
- using Arguments::Arguments;
- std::string arg0 = argument(0, "arg0");
- Commit commit = action("commit");
- };
- struct Git : program::Arguments<Git> {
- PROGRAM_ARGS_INVOKE(commit, checkout, push, remote);
- std::string pwd = option('C');
- bool verbose = flag("verbose", 'v');
- Commit commit = action("commit");
- Checkout checkout = action("checkout");
- Push push = action("push");
- Remote remote = action("remote");
- };
- struct GitPlug : program::Arguments<GitPlug> {
- PROGRAM_ARGS_INVOKE_WITH_DEFAULT(*this, commit, checkout);
- Commit commit = action("commit");
- Checkout checkout = action("checkout");
- };
- std::string Push::_remote() const {
- if (Git const * git = Arguments::parent<Git>()) { return git->pwd; }
- return "";
- }
- TEST(ActionTest, CannotMixActionAndArgument) {
- EXPECT_THROW(Bad1(), program::ArgumentMixingError);
- EXPECT_THROW(Bad2(), program::ArgumentMixingError);
- }
- TEST(ActionTest, CanRunWithMultipleActions) { EXPECT_NO_THROW(Git()); }
- TEST(ActionTest, ActionIsRouted) {
- Git git = parse<Git>({"", "-v", "commit", "-m", "this is a message"});
- EXPECT_THAT(git.commit.message, "this is a message");
- }
- TEST(ActionTest, CanDiveIntoTypedMain) {
- Git git = parse<Git>({"", "-v", "commit", "-m", "this is a message"});
- program::ArgumentTestHelper::main(git);
- EXPECT_THAT(g_action.get<Commit>(), NotNull());
- }
- TEST(ActionTest, CanFetchParentInfo) {
- Git git = parse<Git>({"", "-C", "./submodules/X", "push"});
- EXPECT_THAT(git.push.remote, "./submodules/X");
- }
- TEST(ActionTest, ReturnsFailureOnNoAction) {
- Git git = parse<Git>({""});
- EXPECT_THAT(program::ArgumentTestHelper::main(git), 1);
- }
- TEST(ActionTest, CanRecursivelyPerformActions) {
- Git git = parse<Git>({"", "remote", "-v", "show", "-n"});
- EXPECT_TRUE(git.remote.verbose);
- EXPECT_TRUE(git.remote.show.use_cached);
- program::ArgumentTestHelper::main(git);
- EXPECT_THAT(g_action.get<Show>(), NotNull());
- }
- TEST(ActionTest, CanStoreDefaultAction) {
- Git git = parse<Git>({"", "remote"});
- program::ArgumentTestHelper::main(git);
- EXPECT_THAT(g_action.get<Show>(), NotNull());
- }
- TEST(ActionTest, DefaultActionCanBeSelf) {
- GitPlug git = parse<GitPlug>({""});
- program::ArgumentTestHelper::main(git);
- EXPECT_THAT(g_action.get<GitPlug>(), NotNull());
- }
|