Create more unit tests for USB Devices and Printer Driver (#21)
All checks were successful
Build ptprnt / build (push) Successful in 2m59s
All checks were successful
Build ptprnt / build (push) Successful in 2m59s
Reviewed-on: #21
This commit was merged in pull request #21.
This commit is contained in:
374
tests/ptouch_print_test/ptouch_print_test.cpp
Normal file
374
tests/ptouch_print_test/ptouch_print_test.cpp
Normal file
@@ -0,0 +1,374 @@
|
||||
/*
|
||||
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
|
||||
Reference in New Issue
Block a user