argument parser: use CLI11 and add unit tests

CLI11 is one of the most commonly use argument parser in OpenBMC. It can
save ~150 lines of codes in this project.

We are hitting argument related bugs that not covered in unit tests.
This test adds a test for argument parsing.

Tested: QEMU IPMI/Redfish worked.

Signed-off-by: Nan Zhou <nanzhoumails@gmail.com>
Change-Id: Ib409c7e6a82ad31049f2da3e32727ebdf185f0fc
diff --git a/test/argument_test.cpp b/test/argument_test.cpp
new file mode 100644
index 0000000..d55abfa
--- /dev/null
+++ b/test/argument_test.cpp
@@ -0,0 +1,111 @@
+#include "argument.hpp"
+
+#include <string>
+#include <vector>
+
+#include <gtest/gtest.h>
+
+namespace phosphor::certs
+{
+namespace
+{
+
+TEST(ProcessArguments, OnSuccessClientType)
+{
+    Arguments arguments;
+    std::vector<const char*> argv = {"binary",     "--type", "client",
+                                     "--endpoint", "abc",    "--path",
+                                     "def",        "--unit", "ghi"};
+    EXPECT_EQ(processArguments(argv.size(), argv.data(), arguments), 0);
+    EXPECT_EQ(arguments.typeStr, "client");
+    EXPECT_EQ(arguments.endpoint, "abc");
+    EXPECT_EQ(arguments.path, "def");
+    EXPECT_EQ(arguments.unit, "ghi");
+}
+
+TEST(ProcessArguments, OnSuccessServerType)
+{
+    Arguments arguments;
+    std::vector<const char*> argv = {"binary",     "--type", "server",
+                                     "--endpoint", "abc",    "--path",
+                                     "def",        "--unit", "ghi"};
+    EXPECT_EQ(processArguments(argv.size(), argv.data(), arguments), 0);
+    EXPECT_EQ(arguments.typeStr, "server");
+    EXPECT_EQ(arguments.endpoint, "abc");
+    EXPECT_EQ(arguments.path, "def");
+    EXPECT_EQ(arguments.unit, "ghi");
+}
+
+TEST(ProcessArguments, OnSuccessAuthorityType)
+{
+    Arguments arguments;
+    std::vector<const char*> argv = {"binary",     "--type", "authority",
+                                     "--endpoint", "abc",    "--path",
+                                     "def",        "--unit", "ghi"};
+    EXPECT_NO_THROW(processArguments(argv.size(), argv.data(), arguments));
+    EXPECT_EQ(arguments.typeStr, "authority");
+    EXPECT_EQ(arguments.endpoint, "abc");
+    EXPECT_EQ(arguments.path, "def");
+    EXPECT_EQ(arguments.unit, "ghi");
+}
+
+TEST(ProcessArguments, UnitIsOptional)
+{
+    Arguments arguments;
+    std::vector<const char*> argv = {"binary", "--type", "client", "--endpoint",
+                                     "abc",    "--path", "def"};
+    EXPECT_EQ(processArguments(argv.size(), argv.data(), arguments), 0);
+    EXPECT_EQ(arguments.typeStr, "client");
+    EXPECT_EQ(arguments.endpoint, "abc");
+    EXPECT_EQ(arguments.path, "def");
+    EXPECT_TRUE(arguments.unit.empty());
+}
+
+TEST(ProcessArguments, EmptyUnit)
+{
+    Arguments arguments;
+    std::vector<const char*> argv = {"binary",     "--type", "client",
+                                     "--endpoint", "abc",    "--path",
+                                     "def",        "--unit", ""};
+    EXPECT_EQ(processArguments(argv.size(), argv.data(), arguments), 0);
+    EXPECT_EQ(arguments.typeStr, "client");
+    EXPECT_EQ(arguments.endpoint, "abc");
+    EXPECT_EQ(arguments.path, "def");
+    EXPECT_TRUE(arguments.unit.empty());
+}
+
+TEST(Type, MissTypeThrows)
+{
+    Arguments arguments;
+    std::vector<const char*> argv = {"binary", "--endpoint", "abc", "--path",
+                                     "def",    "--unit",     "ghi"};
+    EXPECT_NE(processArguments(argv.size(), argv.data(), arguments), 0);
+}
+
+TEST(Type, WrongTypeThrows)
+{
+    Arguments arguments;
+    std::vector<const char*> argv = {"binary",     "--type", "no-supported",
+                                     "--endpoint", "abc",    "--path",
+                                     "def",        "--unit", "ghi"};
+    EXPECT_NE(processArguments(argv.size(), argv.data(), arguments), 0);
+}
+
+TEST(Endpoint, MissEndpointThrows)
+{
+    Arguments arguments;
+    std::vector<const char*> argv = {"binary", "--type", "client", "--path",
+                                     "def",    "--unit", "ghi"};
+    EXPECT_NE(processArguments(argv.size(), argv.data(), arguments), 0);
+}
+
+TEST(Path, MissPathThrows)
+{
+    Arguments arguments;
+    std::vector<const char*> argv = {"binary", "--type", "client", "--endpoint",
+                                     "abc",    "--unit", "ghi"};
+    EXPECT_NE(processArguments(argv.size(), argv.data(), arguments), 0);
+}
+} // namespace
+
+} // namespace phosphor::certs