All checks were successful
Build ptprnt / build (push) Successful in 2m59s
Reviewed-on: #21
375 lines
14 KiB
C++
375 lines
14 KiB
C++
/*
|
|
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 <https://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
#include <gmock/gmock.h>
|
|
#include <gtest/gtest.h>
|
|
|
|
#include "PtouchPrint.hpp"
|
|
#include "cli/interface/ICliParser.hpp"
|
|
#include "core/interface/IPrinterService.hpp"
|
|
#include "printers/interface/IPrinterDriver.hpp"
|
|
|
|
using ::testing::_;
|
|
using ::testing::NiceMock;
|
|
using ::testing::Return;
|
|
using ::testing::ReturnRef;
|
|
|
|
namespace ptprnt {
|
|
|
|
// Mock CLI Parser
|
|
class MockCliParser : public cli::ICliParser {
|
|
public:
|
|
MOCK_METHOD(int, parse, (int argc, char** argv), (override));
|
|
MOCK_METHOD(const cli::CliOptions&, getOptions, (), (const, override));
|
|
|
|
cli::CliOptions options;
|
|
};
|
|
|
|
// Mock Printer Service
|
|
class MockPrinterService : public core::IPrinterService {
|
|
public:
|
|
MOCK_METHOD(bool, initialize, (), (override));
|
|
MOCK_METHOD(std::vector<std::shared_ptr<IPrinterDriver>>, detectPrinters, (), (override));
|
|
MOCK_METHOD(std::shared_ptr<IPrinterDriver>, selectPrinter, (const std::string& selection), (override));
|
|
MOCK_METHOD(std::shared_ptr<IPrinterDriver>, getCurrentPrinter, (), (const, override));
|
|
MOCK_METHOD(bool, printLabel, (std::unique_ptr<graphics::ILabel> label), (override));
|
|
};
|
|
|
|
// Mock Printer Driver
|
|
class MockPrinterDriver : public IPrinterDriver {
|
|
public:
|
|
MOCK_METHOD(std::string_view, getDriverName, (), (override));
|
|
MOCK_METHOD(std::string_view, getName, (), (override));
|
|
MOCK_METHOD(libusbwrap::usbId, getUsbId, (), (override));
|
|
MOCK_METHOD(std::string_view, getVersion, (), (override));
|
|
MOCK_METHOD(PrinterInfo, getPrinterInfo, (), (override));
|
|
MOCK_METHOD(PrinterStatus, getPrinterStatus, (), (override));
|
|
MOCK_METHOD(bool, attachUsbDevice, (std::shared_ptr<libusbwrap::IUsbDevice> usbHndl), (override));
|
|
MOCK_METHOD(bool, detachUsbDevice, (), (override));
|
|
MOCK_METHOD(bool, printBitmap, (const graphics::Bitmap<graphics::ALPHA8>& bitmap), (override));
|
|
MOCK_METHOD(bool, printMonochromeData, (const graphics::MonochromeData& data), (override));
|
|
MOCK_METHOD(bool, printLabel, (std::unique_ptr<graphics::ILabel> label), (override));
|
|
MOCK_METHOD(bool, print, (), (override));
|
|
};
|
|
|
|
class PtouchPrintTest : public ::testing::Test {
|
|
protected:
|
|
void SetUp() override {
|
|
mockCliParser = std::make_unique<NiceMock<MockCliParser>>();
|
|
mockPrinterService = std::make_unique<NiceMock<MockPrinterService>>();
|
|
|
|
// Store raw pointers for setting expectations
|
|
cliParserPtr = mockCliParser.get();
|
|
printerServicePtr = mockPrinterService.get();
|
|
|
|
// Default behavior: parse succeeds and returns empty options
|
|
ON_CALL(*cliParserPtr, parse(_, _)).WillByDefault(Return(0));
|
|
ON_CALL(*cliParserPtr, getOptions()).WillByDefault(ReturnRef(cliParserPtr->options));
|
|
ON_CALL(*printerServicePtr, initialize()).WillByDefault(Return(true));
|
|
ON_CALL(*printerServicePtr, printLabel(_)).WillByDefault(Return(true));
|
|
}
|
|
|
|
void TearDown() override {}
|
|
|
|
std::unique_ptr<MockCliParser> mockCliParser;
|
|
std::unique_ptr<MockPrinterService> mockPrinterService;
|
|
MockCliParser* cliParserPtr;
|
|
MockPrinterService* printerServicePtr;
|
|
};
|
|
|
|
// Test: Constructor with default implementations
|
|
TEST_F(PtouchPrintTest, ConstructorDefault) {
|
|
EXPECT_NO_THROW(PtouchPrint app("v1.0.0"));
|
|
}
|
|
|
|
// Test: Constructor with custom implementations
|
|
TEST_F(PtouchPrintTest, ConstructorCustom) {
|
|
EXPECT_NO_THROW({
|
|
PtouchPrint app("v1.0.0", std::move(mockCliParser), std::move(mockPrinterService));
|
|
});
|
|
}
|
|
|
|
// Test: init with successful parse
|
|
TEST_F(PtouchPrintTest, InitSuccess) {
|
|
PtouchPrint app("v1.0.0", std::move(mockCliParser), std::move(mockPrinterService));
|
|
|
|
char* argv[] = {(char*)"ptprnt"};
|
|
int result = app.init(1, argv);
|
|
|
|
EXPECT_EQ(result, 0);
|
|
}
|
|
|
|
// Test: init with parse returning help (should return 1)
|
|
TEST_F(PtouchPrintTest, InitHelp) {
|
|
ON_CALL(*cliParserPtr, parse(_, _)).WillByDefault(Return(1));
|
|
|
|
PtouchPrint app("v1.0.0", std::move(mockCliParser), std::move(mockPrinterService));
|
|
|
|
char* argv[] = {(char*)"ptprnt", (char*)"-h"};
|
|
int result = app.init(2, argv);
|
|
|
|
EXPECT_EQ(result, 1); // Clean exit
|
|
}
|
|
|
|
// Test: init with parse error (should return -1)
|
|
TEST_F(PtouchPrintTest, InitParseError) {
|
|
ON_CALL(*cliParserPtr, parse(_, _)).WillByDefault(Return(-1));
|
|
|
|
PtouchPrint app("v1.0.0", std::move(mockCliParser), std::move(mockPrinterService));
|
|
|
|
char* argv[] = {(char*)"ptprnt", (char*)"--invalid"};
|
|
int result = app.init(2, argv);
|
|
|
|
EXPECT_EQ(result, -1); // Error
|
|
}
|
|
|
|
// Test: init with printer service initialization failure
|
|
TEST_F(PtouchPrintTest, InitPrinterServiceFailure) {
|
|
ON_CALL(*printerServicePtr, initialize()).WillByDefault(Return(false));
|
|
|
|
PtouchPrint app("v1.0.0", std::move(mockCliParser), std::move(mockPrinterService));
|
|
|
|
char* argv[] = {(char*)"ptprnt"};
|
|
int result = app.init(1, argv);
|
|
|
|
EXPECT_EQ(result, -1); // Error
|
|
}
|
|
|
|
// Test: run with list drivers option
|
|
TEST_F(PtouchPrintTest, RunListDrivers) {
|
|
cliParserPtr->options.listDrivers = true;
|
|
|
|
PtouchPrint app("v1.0.0", std::move(mockCliParser), std::move(mockPrinterService));
|
|
|
|
char* argv[] = {(char*)"ptprnt"};
|
|
app.init(1, argv);
|
|
|
|
int result = app.run();
|
|
|
|
EXPECT_EQ(result, 0);
|
|
}
|
|
|
|
// Test: run with no commands (should warn but succeed)
|
|
TEST_F(PtouchPrintTest, RunNoCommands) {
|
|
auto mockPrinter = std::make_shared<NiceMock<MockPrinterDriver>>();
|
|
PrinterStatus status{.tapeWidthMm = 12};
|
|
|
|
ON_CALL(*mockPrinter, getPrinterStatus()).WillByDefault(Return(status));
|
|
ON_CALL(*printerServicePtr, selectPrinter(_)).WillByDefault(Return(mockPrinter));
|
|
|
|
cliParserPtr->options.commands.clear();
|
|
|
|
PtouchPrint app("v1.0.0", std::move(mockCliParser), std::move(mockPrinterService));
|
|
|
|
char* argv[] = {(char*)"ptprnt"};
|
|
app.init(1, argv);
|
|
|
|
int result = app.run();
|
|
|
|
EXPECT_EQ(result, 0);
|
|
}
|
|
|
|
// Test: run with printer selection failure
|
|
TEST_F(PtouchPrintTest, RunPrinterSelectionFailure) {
|
|
ON_CALL(*printerServicePtr, selectPrinter(_)).WillByDefault(Return(nullptr));
|
|
|
|
cliParserPtr->options.commands.push_back({cli::CommandType::Text, "Test"});
|
|
|
|
PtouchPrint app("v1.0.0", std::move(mockCliParser), std::move(mockPrinterService));
|
|
|
|
char* argv[] = {(char*)"ptprnt"};
|
|
app.init(1, argv);
|
|
|
|
int result = app.run();
|
|
|
|
EXPECT_EQ(result, -1);
|
|
}
|
|
|
|
// Test: run with simple text command
|
|
TEST_F(PtouchPrintTest, RunSimpleText) {
|
|
auto mockPrinter = std::make_shared<NiceMock<MockPrinterDriver>>();
|
|
PrinterInfo info{.driverName = "Test", .name = "Test", .version = "v1.0", .usbId = {0, 0}, .pixelLines = 128};
|
|
PrinterStatus status{.tapeWidthMm = 12};
|
|
|
|
ON_CALL(*mockPrinter, getPrinterInfo()).WillByDefault(Return(info));
|
|
ON_CALL(*mockPrinter, getPrinterStatus()).WillByDefault(Return(status));
|
|
ON_CALL(*mockPrinter, printLabel(_)).WillByDefault(Return(true));
|
|
ON_CALL(*printerServicePtr, selectPrinter(_)).WillByDefault(Return(mockPrinter));
|
|
|
|
cliParserPtr->options.commands.push_back({cli::CommandType::Text, "Hello"});
|
|
|
|
PtouchPrint app("v1.0.0", std::move(mockCliParser), std::move(mockPrinterService));
|
|
|
|
char* argv[] = {(char*)"ptprnt"};
|
|
app.init(1, argv);
|
|
|
|
int result = app.run();
|
|
|
|
EXPECT_EQ(result, 0);
|
|
}
|
|
|
|
// Test: run with font and text commands
|
|
TEST_F(PtouchPrintTest, RunWithFormatting) {
|
|
auto mockPrinter = std::make_shared<NiceMock<MockPrinterDriver>>();
|
|
PrinterInfo info{.driverName = "Test", .name = "Test", .version = "v1.0", .usbId = {0, 0}, .pixelLines = 128};
|
|
PrinterStatus status{.tapeWidthMm = 12};
|
|
|
|
ON_CALL(*mockPrinter, getPrinterInfo()).WillByDefault(Return(info));
|
|
ON_CALL(*mockPrinter, getPrinterStatus()).WillByDefault(Return(status));
|
|
ON_CALL(*mockPrinter, printLabel(_)).WillByDefault(Return(true));
|
|
ON_CALL(*printerServicePtr, selectPrinter(_)).WillByDefault(Return(mockPrinter));
|
|
|
|
cliParserPtr->options.commands.push_back({cli::CommandType::Font, "monospace"});
|
|
cliParserPtr->options.commands.push_back({cli::CommandType::FontSize, "48"});
|
|
cliParserPtr->options.commands.push_back({cli::CommandType::Text, "Formatted"});
|
|
|
|
PtouchPrint app("v1.0.0", std::move(mockCliParser), std::move(mockPrinterService));
|
|
|
|
char* argv[] = {(char*)"ptprnt"};
|
|
app.init(1, argv);
|
|
|
|
int result = app.run();
|
|
|
|
EXPECT_EQ(result, 0);
|
|
}
|
|
|
|
// Test: run with alignment commands
|
|
TEST_F(PtouchPrintTest, RunWithAlignment) {
|
|
auto mockPrinter = std::make_shared<NiceMock<MockPrinterDriver>>();
|
|
PrinterInfo info{.driverName = "Test", .name = "Test", .version = "v1.0", .usbId = {0, 0}, .pixelLines = 128};
|
|
PrinterStatus status{.tapeWidthMm = 12};
|
|
|
|
ON_CALL(*mockPrinter, getPrinterInfo()).WillByDefault(Return(info));
|
|
ON_CALL(*mockPrinter, getPrinterStatus()).WillByDefault(Return(status));
|
|
ON_CALL(*mockPrinter, printLabel(_)).WillByDefault(Return(true));
|
|
ON_CALL(*printerServicePtr, selectPrinter(_)).WillByDefault(Return(mockPrinter));
|
|
|
|
cliParserPtr->options.commands.push_back({cli::CommandType::HAlign, "center"});
|
|
cliParserPtr->options.commands.push_back({cli::CommandType::VAlign, "middle"});
|
|
cliParserPtr->options.commands.push_back({cli::CommandType::Text, "Centered"});
|
|
|
|
PtouchPrint app("v1.0.0", std::move(mockCliParser), std::move(mockPrinterService));
|
|
|
|
char* argv[] = {(char*)"ptprnt"};
|
|
app.init(1, argv);
|
|
|
|
int result = app.run();
|
|
|
|
EXPECT_EQ(result, 0);
|
|
}
|
|
|
|
// Test: run with invalid alignment (should handle gracefully)
|
|
TEST_F(PtouchPrintTest, RunWithInvalidAlignment) {
|
|
auto mockPrinter = std::make_shared<NiceMock<MockPrinterDriver>>();
|
|
PrinterInfo info{.driverName = "Test", .name = "Test", .version = "v1.0", .usbId = {0, 0}, .pixelLines = 128};
|
|
PrinterStatus status{.tapeWidthMm = 12};
|
|
|
|
ON_CALL(*mockPrinter, getPrinterInfo()).WillByDefault(Return(info));
|
|
ON_CALL(*mockPrinter, getPrinterStatus()).WillByDefault(Return(status));
|
|
ON_CALL(*mockPrinter, printLabel(_)).WillByDefault(Return(true));
|
|
ON_CALL(*printerServicePtr, selectPrinter(_)).WillByDefault(Return(mockPrinter));
|
|
|
|
cliParserPtr->options.commands.push_back({cli::CommandType::HAlign, "invalid"});
|
|
cliParserPtr->options.commands.push_back({cli::CommandType::Text, "Test"});
|
|
|
|
PtouchPrint app("v1.0.0", std::move(mockCliParser), std::move(mockPrinterService));
|
|
|
|
char* argv[] = {(char*)"ptprnt"};
|
|
app.init(1, argv);
|
|
|
|
int result = app.run();
|
|
|
|
EXPECT_EQ(result, 0); // Should handle gracefully
|
|
}
|
|
|
|
// Test: run with new label command
|
|
TEST_F(PtouchPrintTest, RunWithNewLabel) {
|
|
auto mockPrinter = std::make_shared<NiceMock<MockPrinterDriver>>();
|
|
PrinterInfo info{.driverName = "Test", .name = "Test", .version = "v1.0", .usbId = {0, 0}, .pixelLines = 128};
|
|
PrinterStatus status{.tapeWidthMm = 12};
|
|
|
|
ON_CALL(*mockPrinter, getPrinterInfo()).WillByDefault(Return(info));
|
|
ON_CALL(*mockPrinter, getPrinterStatus()).WillByDefault(Return(status));
|
|
ON_CALL(*mockPrinter, printLabel(_)).WillByDefault(Return(true));
|
|
ON_CALL(*printerServicePtr, selectPrinter(_)).WillByDefault(Return(mockPrinter));
|
|
|
|
cliParserPtr->options.commands.push_back({cli::CommandType::Text, "First"});
|
|
cliParserPtr->options.commands.push_back({cli::CommandType::NewLabel, ""});
|
|
cliParserPtr->options.commands.push_back({cli::CommandType::Text, "Second"});
|
|
|
|
PtouchPrint app("v1.0.0", std::move(mockCliParser), std::move(mockPrinterService));
|
|
|
|
char* argv[] = {(char*)"ptprnt"};
|
|
app.init(1, argv);
|
|
|
|
int result = app.run();
|
|
|
|
EXPECT_EQ(result, 0);
|
|
}
|
|
|
|
// Test: run with verbose option
|
|
TEST_F(PtouchPrintTest, RunWithVerbose) {
|
|
auto mockPrinter = std::make_shared<NiceMock<MockPrinterDriver>>();
|
|
PrinterInfo info{.driverName = "Test", .name = "Test", .version = "v1.0", .usbId = {0, 0}, .pixelLines = 128};
|
|
PrinterStatus status{.tapeWidthMm = 12};
|
|
|
|
ON_CALL(*mockPrinter, getPrinterInfo()).WillByDefault(Return(info));
|
|
ON_CALL(*mockPrinter, getPrinterStatus()).WillByDefault(Return(status));
|
|
ON_CALL(*mockPrinter, printLabel(_)).WillByDefault(Return(true));
|
|
ON_CALL(*printerServicePtr, selectPrinter(_)).WillByDefault(Return(mockPrinter));
|
|
|
|
cliParserPtr->options.verbose = true;
|
|
cliParserPtr->options.commands.push_back({cli::CommandType::Text, "Test"});
|
|
|
|
PtouchPrint app("v1.0.0", std::move(mockCliParser), std::move(mockPrinterService));
|
|
|
|
char* argv[] = {(char*)"ptprnt"};
|
|
app.init(1, argv);
|
|
|
|
int result = app.run();
|
|
|
|
EXPECT_EQ(result, 0);
|
|
}
|
|
|
|
// Test: run with trace option
|
|
TEST_F(PtouchPrintTest, RunWithTrace) {
|
|
auto mockPrinter = std::make_shared<NiceMock<MockPrinterDriver>>();
|
|
PrinterInfo info{.driverName = "Test", .name = "Test", .version = "v1.0", .usbId = {0, 0}, .pixelLines = 128};
|
|
PrinterStatus status{.tapeWidthMm = 12};
|
|
|
|
ON_CALL(*mockPrinter, getPrinterInfo()).WillByDefault(Return(info));
|
|
ON_CALL(*mockPrinter, getPrinterStatus()).WillByDefault(Return(status));
|
|
ON_CALL(*mockPrinter, printLabel(_)).WillByDefault(Return(true));
|
|
ON_CALL(*printerServicePtr, selectPrinter(_)).WillByDefault(Return(mockPrinter));
|
|
|
|
cliParserPtr->options.trace = true;
|
|
cliParserPtr->options.commands.push_back({cli::CommandType::Text, "Test"});
|
|
|
|
PtouchPrint app("v1.0.0", std::move(mockCliParser), std::move(mockPrinterService));
|
|
|
|
char* argv[] = {(char*)"ptprnt"};
|
|
app.init(1, argv);
|
|
|
|
int result = app.run();
|
|
|
|
EXPECT_EQ(result, 0);
|
|
}
|
|
|
|
} // namespace ptprnt
|