diff --git a/include/Context.h b/include/Context.h index a284e01..0045929 100644 --- a/include/Context.h +++ b/include/Context.h @@ -9,6 +9,7 @@ struct Context { std::string topic; std::string message; std::string address; + std::string clientId; bool verbose; }; @@ -23,15 +24,16 @@ struct ParseResult { ParseResult parseContext(int argc, char *argv[]) noexcept; const std::string USAGE = R"( -Usage: mqtt pub [-v] -t -a
+Usage: mqtt pub [-v] -t -a
-c Options: - -t, --topic Specify the topic to publish to (required) - -a, --address
[:] address to connect to (required) - -v, --verbose Enable verbose output - -h, --help Show this help message + -t, --topic Specify the topic to publish to (required) + -a, --address
[:] address to connect to (required) + -c, --client-id Client identifier + -v, --verbose Enable verbose output + -h, --help Show this help message Example: - mqtt pub -t hello/topic -v -a 127.0.0.1:8883 '{"hello": "world"}' + mqtt pub -t hello/topic -v -a 127.0.0.1:8883 -c myclient '{"hello": "world"}' )"; }; // namespace MqttClient \ No newline at end of file diff --git a/src/Context.cpp b/src/Context.cpp index 8bc27c1..a5baf45 100644 --- a/src/Context.cpp +++ b/src/Context.cpp @@ -14,12 +14,13 @@ ParseResult parseContext(int argc, char *argv[]) noexcept { struct option opts[] = {{"topic", required_argument, 0, 't'}, {"address", required_argument, 0, 'a'}, + {"client-id", required_argument, 0, 'c'}, {"verbose", no_argument, 0, 'v'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}}; int opt; int optInd = 0; - while ((opt = getopt_long(argc, argv, "t:a:vh", opts, &optInd)) != -1) { + while ((opt = getopt_long(argc, argv, "t:a:c:vh", opts, &optInd)) != -1) { switch (opt) { case 't': context.topic = optarg; @@ -27,6 +28,9 @@ ParseResult parseContext(int argc, char *argv[]) noexcept { case 'a': context.address = optarg; break; + case 'c': + context.clientId = optarg; + break; case 'v': context.verbose = true; break; @@ -54,6 +58,11 @@ ParseResult parseContext(int argc, char *argv[]) noexcept { return {ParseResultCode::FAILURE, "Error: Address is required"}; } + if (context.clientId.empty()) { + // TODO more validations + return {ParseResultCode::FAILURE, "Error: Client id is required"}; + } + auto numMessages = argc - 1 - optind; if (numMessages == 0) { return {ParseResultCode::FAILURE, "Error: Message is required"}; diff --git a/src/main.cpp b/src/main.cpp index e5296f1..5839e08 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -26,6 +26,7 @@ int main(int argc, char *argv[]) { std::cout << "Context[command=" << context.command << ", topic=" << context.topic << ", address=" << context.address + << ", clientId=" << context.clientId << ", message=" << context.message << "]\n"; } diff --git a/test/ContextTest.cpp b/test/ContextTest.cpp index d5bd598..7d686ed 100644 --- a/test/ContextTest.cpp +++ b/test/ContextTest.cpp @@ -22,13 +22,13 @@ class ContextTest : public testing::Test { TEST_F(ContextTest, AllOpts) { auto res = parse({"mqtt", "pub", "-v", "-t", "topic", "-a", - "127.0.0.1:8883", "message"}); + "127.0.0.1:8883", "-c", "client", "message"}); EXPECT_EQ(ParseResultCode::SUCCESS, res.code); } TEST_F(ContextTest, RequiredOpts) { - auto res = parse( - {"mqtt", "pub", "-t", "topic", "-a", "127.0.0.1:8883", "message"}); + auto res = parse({"mqtt", "pub", "-t", "topic", "-a", "127.0.0.1:8883", + "-c", "client", "message"}); EXPECT_EQ(ParseResultCode::SUCCESS, res.code); } @@ -43,32 +43,48 @@ TEST_F(ContextTest, NoArgs) { } TEST_F(ContextTest, MissingMessage) { - auto res = parse({"mqtt", "pub", "-t", "topic", "-a", "127.0.0.1:8883"}); + auto res = parse( + {"mqtt", "pub", "-t", "topic", "-a", "127.0.0.1:8883", "-c", "client"}); EXPECT_EQ(ParseResultCode::FAILURE, res.code); } TEST_F(ContextTest, MissingTopic) { - auto res = parse({"mqtt", "pub", "-a", "127.0.0.1:8883", "message"}); + auto res = parse( + {"mqtt", "pub", "-a", "127.0.0.1:8883", "-c", "client", "message"}); EXPECT_EQ(ParseResultCode::FAILURE, res.code); } TEST_F(ContextTest, MissingTopicValue) { - auto res = parse({"mqtt", "pub", "-t", "-a", "127.0.0.1:8883", "message"}); + auto res = parse({"mqtt", "pub", "-t", "-a", "127.0.0.1:8883", "-c", + "client", "message"}); EXPECT_EQ(ParseResultCode::FAILURE, res.code); } TEST_F(ContextTest, MissingAddress) { - auto res = parse({"mqtt", "pub", "-t", "topic", "message"}); + auto res = parse({"mqtt", "pub", "-t", "topic", "-c", "client", "message"}); EXPECT_EQ(ParseResultCode::FAILURE, res.code); } TEST_F(ContextTest, MissingAddressValue) { - auto res = parse({"mqtt", "pub", "-t", "topic", "-a", "message"}); + auto res = + parse({"mqtt", "pub", "-t", "topic", "-a", "-c", "client", "message"}); EXPECT_EQ(ParseResultCode::FAILURE, res.code); } TEST_F(ContextTest, MultipleMessages) { auto res = parse({"mqtt", "pub", "-v", "-t", "topic", "-a", - "127.0.0.1:8883", "message", "message2"}); + "127.0.0.1:8883", "-c", "client", "message", "message2"}); + EXPECT_EQ(ParseResultCode::FAILURE, res.code); +} + +TEST_F(ContextTest, MissingClientId) { + auto res = parse({"mqtt", "pub", "-v", "-t", "topic", "-a", + "127.0.0.1:8883", "message"}); + EXPECT_EQ(ParseResultCode::FAILURE, res.code); +} + +TEST_F(ContextTest, MissingClientIdValue) { + auto res = parse({"mqtt", "pub", "-v", "-t", "topic", "-a", + "127.0.0.1:8883", "-c", "message"}); EXPECT_EQ(ParseResultCode::FAILURE, res.code); }