/* ptrnt - print labels on linux Copyright (C) 2025 Moritz Martinius This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "cli/CliParser.hpp" namespace ptprnt::cli { class CliParserTest : public ::testing::Test { protected: void SetUp() override { parser = std::make_unique("Test Application", "v1.0.0"); } void TearDown() override { parser.reset(); } // Helper to convert vector of strings to argc/argv std::vector makeArgv(const std::vector& args) { argv_storage.clear(); argv_storage.reserve(args.size()); for (const auto& arg : args) { argv_storage.push_back(const_cast(arg.c_str())); } return argv_storage; } std::unique_ptr parser; std::vector argv_storage; }; // Test: Constructor TEST_F(CliParserTest, Constructor) { EXPECT_NO_THROW(CliParser("App", "v1.0")); } // Test: Parse with no arguments TEST_F(CliParserTest, ParseNoArguments) { std::vector args = {"ptprnt"}; auto argv = makeArgv(args); int result = parser->parse(args.size(), argv.data()); EXPECT_EQ(result, 0); const auto& options = parser->getOptions(); EXPECT_FALSE(options.verbose); EXPECT_FALSE(options.trace); EXPECT_FALSE(options.listDrivers); EXPECT_EQ(options.printerSelection, "auto"); EXPECT_TRUE(options.commands.empty()); } // Test: Parse verbose flag TEST_F(CliParserTest, ParseVerboseShort) { std::vector args = {"ptprnt", "-v"}; auto argv = makeArgv(args); int result = parser->parse(args.size(), argv.data()); EXPECT_EQ(result, 0); EXPECT_TRUE(parser->getOptions().verbose); } TEST_F(CliParserTest, ParseVerboseLong) { std::vector args = {"ptprnt", "--verbose"}; auto argv = makeArgv(args); int result = parser->parse(args.size(), argv.data()); EXPECT_EQ(result, 0); EXPECT_TRUE(parser->getOptions().verbose); } // Test: Parse trace flag TEST_F(CliParserTest, ParseTrace) { std::vector args = {"ptprnt", "--trace"}; auto argv = makeArgv(args); int result = parser->parse(args.size(), argv.data()); EXPECT_EQ(result, 0); EXPECT_TRUE(parser->getOptions().trace); } // Test: Parse list drivers flag TEST_F(CliParserTest, ParseListDrivers) { std::vector args = {"ptprnt", "--list-all-drivers"}; auto argv = makeArgv(args); int result = parser->parse(args.size(), argv.data()); EXPECT_EQ(result, 0); EXPECT_TRUE(parser->getOptions().listDrivers); } // Test: Parse printer selection short TEST_F(CliParserTest, ParsePrinterShort) { std::vector args = {"ptprnt", "-p", "P700"}; auto argv = makeArgv(args); int result = parser->parse(args.size(), argv.data()); EXPECT_EQ(result, 0); EXPECT_EQ(parser->getOptions().printerSelection, "P700"); } // Test: Parse printer selection long TEST_F(CliParserTest, ParsePrinterLong) { std::vector args = {"ptprnt", "--printer", "FakePrinter"}; auto argv = makeArgv(args); int result = parser->parse(args.size(), argv.data()); EXPECT_EQ(result, 0); EXPECT_EQ(parser->getOptions().printerSelection, "FakePrinter"); } // Test: Parse single text TEST_F(CliParserTest, ParseSingleText) { std::vector args = {"ptprnt", "-t", "Hello"}; auto argv = makeArgv(args); int result = parser->parse(args.size(), argv.data()); EXPECT_EQ(result, 0); const auto& commands = parser->getOptions().commands; ASSERT_EQ(commands.size(), 1); EXPECT_EQ(commands[0].first, CommandType::Text); EXPECT_EQ(commands[0].second, "Hello"); } // Test: Parse multiple texts TEST_F(CliParserTest, ParseMultipleTexts) { std::vector args = {"ptprnt", "-t", "Hello", "-t", "World"}; auto argv = makeArgv(args); int result = parser->parse(args.size(), argv.data()); EXPECT_EQ(result, 0); const auto& commands = parser->getOptions().commands; ASSERT_EQ(commands.size(), 2); EXPECT_EQ(commands[0].first, CommandType::Text); EXPECT_EQ(commands[0].second, "Hello"); EXPECT_EQ(commands[1].first, CommandType::Text); EXPECT_EQ(commands[1].second, "World"); } // Test: Parse font TEST_F(CliParserTest, ParseFont) { std::vector args = {"ptprnt", "-f", "monospace", "-t", "Test"}; auto argv = makeArgv(args); int result = parser->parse(args.size(), argv.data()); EXPECT_EQ(result, 0); const auto& commands = parser->getOptions().commands; ASSERT_EQ(commands.size(), 2); EXPECT_EQ(commands[0].first, CommandType::Font); EXPECT_EQ(commands[0].second, "monospace"); } // Test: Parse font size TEST_F(CliParserTest, ParseFontSize) { std::vector args = {"ptprnt", "-s", "48", "-t", "Large"}; auto argv = makeArgv(args); int result = parser->parse(args.size(), argv.data()); EXPECT_EQ(result, 0); const auto& commands = parser->getOptions().commands; ASSERT_GE(commands.size(), 1); EXPECT_EQ(commands[0].first, CommandType::FontSize); EXPECT_EQ(commands[0].second, "48"); } // Test: Parse horizontal alignment TEST_F(CliParserTest, ParseHAlign) { std::vector args = {"ptprnt", "--halign", "center", "-t", "Centered"}; auto argv = makeArgv(args); int result = parser->parse(args.size(), argv.data()); EXPECT_EQ(result, 0); const auto& commands = parser->getOptions().commands; ASSERT_GE(commands.size(), 1); EXPECT_EQ(commands[0].first, CommandType::HAlign); EXPECT_EQ(commands[0].second, "center"); } // Test: Parse vertical alignment TEST_F(CliParserTest, ParseVAlign) { std::vector args = {"ptprnt", "--valign", "top", "-t", "Top"}; auto argv = makeArgv(args); int result = parser->parse(args.size(), argv.data()); EXPECT_EQ(result, 0); const auto& commands = parser->getOptions().commands; ASSERT_GE(commands.size(), 1); EXPECT_EQ(commands[0].first, CommandType::VAlign); EXPECT_EQ(commands[0].second, "top"); } // Test: Parse new label flag TEST_F(CliParserTest, ParseNewLabel) { std::vector args = {"ptprnt", "-t", "First", "--new", "-t", "Second"}; auto argv = makeArgv(args); int result = parser->parse(args.size(), argv.data()); EXPECT_EQ(result, 0); const auto& commands = parser->getOptions().commands; ASSERT_EQ(commands.size(), 3); EXPECT_EQ(commands[0].first, CommandType::Text); EXPECT_EQ(commands[1].first, CommandType::NewLabel); EXPECT_EQ(commands[2].first, CommandType::Text); } // Test: Parse complex command sequence TEST_F(CliParserTest, ParseComplexSequence) { std::vector args = { "ptprnt", "-f", "serif", "-s", "24", "--halign", "center", "--valign", "middle", "-t", "Title", "--new", "-f", "monospace", "-s", "16", "-t", "Body" }; auto argv = makeArgv(args); int result = parser->parse(args.size(), argv.data()); EXPECT_EQ(result, 0); const auto& commands = parser->getOptions().commands; ASSERT_EQ(commands.size(), 9); // Verify order is preserved EXPECT_EQ(commands[0].first, CommandType::Font); EXPECT_EQ(commands[1].first, CommandType::FontSize); EXPECT_EQ(commands[2].first, CommandType::HAlign); EXPECT_EQ(commands[3].first, CommandType::VAlign); EXPECT_EQ(commands[4].first, CommandType::Text); EXPECT_EQ(commands[5].first, CommandType::NewLabel); EXPECT_EQ(commands[6].first, CommandType::Font); EXPECT_EQ(commands[7].first, CommandType::FontSize); EXPECT_EQ(commands[8].first, CommandType::Text); } // Test: Parse with verbose and printer options TEST_F(CliParserTest, ParseCombinedOptions) { std::vector args = { "ptprnt", "-v", "--trace", "-p", "P700", "-t", "Test" }; auto argv = makeArgv(args); int result = parser->parse(args.size(), argv.data()); EXPECT_EQ(result, 0); EXPECT_TRUE(parser->getOptions().verbose); EXPECT_TRUE(parser->getOptions().trace); EXPECT_EQ(parser->getOptions().printerSelection, "P700"); EXPECT_FALSE(parser->getOptions().commands.empty()); } // Test: Parse help flag (should return 1) TEST_F(CliParserTest, ParseHelp) { std::vector args = {"ptprnt", "-h"}; auto argv = makeArgv(args); int result = parser->parse(args.size(), argv.data()); EXPECT_EQ(result, 1); // Signal clean exit } TEST_F(CliParserTest, ParseHelpLong) { std::vector args = {"ptprnt", "--help"}; auto argv = makeArgv(args); int result = parser->parse(args.size(), argv.data()); EXPECT_EQ(result, 1); // Signal clean exit } // Test: Parse version flag (should return 1) TEST_F(CliParserTest, ParseVersion) { std::vector args = {"ptprnt", "-V"}; auto argv = makeArgv(args); int result = parser->parse(args.size(), argv.data()); EXPECT_EQ(result, 1); // Signal clean exit } TEST_F(CliParserTest, ParseVersionLong) { std::vector args = {"ptprnt", "--version"}; auto argv = makeArgv(args); int result = parser->parse(args.size(), argv.data()); EXPECT_EQ(result, 1); // Signal clean exit } // Test: Parse invalid option (should return -1) TEST_F(CliParserTest, ParseInvalidOption) { std::vector args = {"ptprnt", "--invalid-option"}; auto argv = makeArgv(args); int result = parser->parse(args.size(), argv.data()); EXPECT_EQ(result, -1); // Signal error } // Test: Default printer selection is "auto" TEST_F(CliParserTest, DefaultPrinterSelection) { std::vector args = {"ptprnt", "-t", "Test"}; auto argv = makeArgv(args); parser->parse(args.size(), argv.data()); EXPECT_EQ(parser->getOptions().printerSelection, "auto"); } // Test: Long text with spaces TEST_F(CliParserTest, ParseTextWithSpaces) { std::vector args = {"ptprnt", "-t", "Hello World"}; auto argv = makeArgv(args); int result = parser->parse(args.size(), argv.data()); EXPECT_EQ(result, 0); const auto& commands = parser->getOptions().commands; ASSERT_EQ(commands.size(), 1); EXPECT_EQ(commands[0].second, "Hello World"); } } // namespace ptprnt::cli