114 lines
3.8 KiB
C++
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"
|