kate-deft/src/plumb/test_plumbmsg.cpp

114 lines
3.8 KiB
C++

/*
* SPDX-License-Identifier: LGPL-2.0-or-later
*
* Unit tests for the plumb message codec. The golden bytes are taken verbatim
* from a live plan9port plumber on the edit port (captured during design), so
* these tests pin our pack/unpack to the real wire format, not to a guess.
*/
#include "plumbmsg.h"
#include <QObject>
#include <QTest>
using namespace deft;
class TestPlumbMsg : public QObject
{
Q_OBJECT
private Q_SLOTS:
void unpackEditFileWithAddr();
void unpackEditUrlEmptyAddr();
void packRoundTrip();
void attrQuotingRoundTrip();
void attrDoubledQuote();
void shortNdataTolerated();
};
// Golden message #1 (file:line -> edit): captured bytes were
// "plumb\nedit\n/tmp\ntext\naddr=2\n18\n/tmp/plumbtest.txt"
void TestPlumbMsg::unpackEditFileWithAddr()
{
const QByteArray buf = QByteArrayLiteral(
"plumb\nedit\n/tmp\ntext\naddr=2\n18\n/tmp/plumbtest.txt");
PlumbMsg m;
QVERIFY(PlumbMsg::unpack(buf, &m));
QCOMPARE(m.src, QStringLiteral("plumb"));
QCOMPARE(m.dst, QStringLiteral("edit"));
QCOMPARE(m.wdir, QStringLiteral("/tmp"));
QCOMPARE(m.type, QStringLiteral("text"));
QCOMPARE(m.lookup(QStringLiteral("addr")), QStringLiteral("2"));
QCOMPARE(QString::fromUtf8(m.data), QStringLiteral("/tmp/plumbtest.txt"));
}
// Golden message #2 (url -> edit, empty addr): captured bytes were
// "plumb\nedit\n/tmp\ntext\n\n19\nhttps://example.com"
void TestPlumbMsg::unpackEditUrlEmptyAddr()
{
const QByteArray buf = QByteArrayLiteral(
"plumb\nedit\n/tmp\ntext\n\n19\nhttps://example.com");
PlumbMsg m;
QVERIFY(PlumbMsg::unpack(buf, &m));
QVERIFY(m.attr.isEmpty());
QCOMPARE(m.lookup(QStringLiteral("addr")), QString());
QCOMPARE(QString::fromUtf8(m.data), QStringLiteral("https://example.com"));
}
void TestPlumbMsg::packRoundTrip()
{
PlumbMsg m;
m.src = QStringLiteral("kate");
m.dst = QString();
m.wdir = QStringLiteral("/home/user/proj");
m.type = QStringLiteral("text");
m.setAttr(QStringLiteral("addr"), QStringLiteral("42"));
m.data = QByteArrayLiteral("main.cpp");
const QByteArray packed = m.pack();
// Header shape: six '\n'-terminated lines then data with no trailing \n.
QCOMPARE(packed, QByteArrayLiteral(
"kate\n\n/home/user/proj\ntext\naddr=42\n8\nmain.cpp"));
PlumbMsg back;
QVERIFY(PlumbMsg::unpack(packed, &back));
QCOMPARE(back.src, m.src);
QCOMPARE(back.dst, m.dst);
QCOMPARE(back.wdir, m.wdir);
QCOMPARE(back.type, m.type);
QCOMPARE(back.lookup(QStringLiteral("addr")), QStringLiteral("42"));
QCOMPARE(back.data, m.data);
}
void TestPlumbMsg::attrQuotingRoundTrip()
{
// A value with a space must be single-quoted on the wire.
QList<PlumbAttr> attr{{QStringLiteral("click"), QStringLiteral("1 2")}};
const QByteArray packed = packPlumbAttr(attr);
QCOMPARE(packed, QByteArrayLiteral("click='1 2'"));
const QList<PlumbAttr> back = unpackPlumbAttr(packed);
QCOMPARE(back, attr);
}
void TestPlumbMsg::attrDoubledQuote()
{
// A literal ' is doubled inside quotes.
QList<PlumbAttr> attr{{QStringLiteral("x"), QStringLiteral("a'b c")}};
const QByteArray packed = packPlumbAttr(attr);
QCOMPARE(packed, QByteArrayLiteral("x='a''b c'"));
const QList<PlumbAttr> back = unpackPlumbAttr(packed);
QCOMPARE(back.size(), 1);
QCOMPARE(back.first().value, QStringLiteral("a'b c"));
}
void TestPlumbMsg::shortNdataTolerated()
{
// libplumb clamps ndata to the actual trailing bytes; a wrong count still
// yields the real data (mirrors plumbunpackpartial behaviour).
const QByteArray buf = QByteArrayLiteral("s\nd\nw\ntext\n\n999\nhello");
PlumbMsg m;
QVERIFY(PlumbMsg::unpack(buf, &m));
QCOMPARE(QString::fromUtf8(m.data), QStringLiteral("hello"));
}
QTEST_MAIN(TestPlumbMsg)
#include "test_plumbmsg.moc"