2020-05-03 14:09:42 -03:00
|
|
|
|
|
|
|
|
#include "TMxpSendTagHandler.h"
|
2020-05-05 08:03:28 -03:00
|
|
|
#include "TMxpStubClient.h"
|
2026-03-21 13:45:49 -04:00
|
|
|
#include <QTest>
|
|
|
|
|
#include "TMxpProcessor.h"
|
|
|
|
|
#include "TMxpTagParser.h"
|
|
|
|
|
#include "TMxpTagProcessor.h"
|
2020-05-03 14:09:42 -03:00
|
|
|
|
|
|
|
|
class TMxpSendTagHandlerTest : public QObject {
|
2026-03-21 13:45:49 -04:00
|
|
|
Q_OBJECT
|
2020-05-03 14:09:42 -03:00
|
|
|
|
|
|
|
|
private:
|
2026-03-21 13:45:49 -04:00
|
|
|
QSharedPointer<MxpNode> parseNode(const QString &tagText) const {
|
|
|
|
|
auto nodes = TMxpTagParser::parseToMxpNodeList(tagText);
|
|
|
|
|
return !nodes.isEmpty() ? nodes.first() : nullptr;
|
|
|
|
|
}
|
2020-05-03 14:09:42 -03:00
|
|
|
|
|
|
|
|
private slots:
|
2026-03-21 13:45:49 -04:00
|
|
|
void testSendHrefUTF8FromMxpProcessor() {
|
|
|
|
|
// issue #4368
|
|
|
|
|
TMxpStubClient stub;
|
|
|
|
|
TMxpProcessor processor(&stub);
|
|
|
|
|
processor.setMode(MXP_MODE_CODE_LOCK_SECURE);
|
|
|
|
|
|
|
|
|
|
std::string input = "<SEND href=\"áéíóúñ\" >test link: áéíóúñ</SEND>";
|
|
|
|
|
for (char &ch : input) {
|
|
|
|
|
processor.processMxpInput(ch, true);
|
2020-05-05 08:03:28 -03:00
|
|
|
}
|
|
|
|
|
|
2026-03-21 13:45:49 -04:00
|
|
|
QCOMPARE(stub.mHrefs.size(), 1);
|
|
|
|
|
QCOMPARE(stub.mHrefs[0], "send([[áéíóúñ]])");
|
2020-05-03 14:09:42 -03:00
|
|
|
|
2026-03-21 13:45:49 -04:00
|
|
|
QCOMPARE(stub.mHints.size(), 1);
|
|
|
|
|
QCOMPARE(stub.mHints[0], "áéíóúñ");
|
|
|
|
|
}
|
2020-05-03 14:09:42 -03:00
|
|
|
|
2026-07-27 19:55:26 +02:00
|
|
|
// Attribute values must be decoded with the session encoding, not hardcoded
|
|
|
|
|
// UTF-8. On a Latin1 (ISO 8859-1) session, the href bytes "se\xF1or" are
|
|
|
|
|
// "señor" - decoding them as UTF-8 would corrupt the 0xF1 byte.
|
|
|
|
|
void testSendHrefNonUtf8FromMxpProcessor() {
|
|
|
|
|
TMxpStubClient stub;
|
|
|
|
|
stub.mEncoding = QByteArrayLiteral("ISO 8859-1");
|
|
|
|
|
TMxpProcessor processor(&stub);
|
|
|
|
|
processor.setMode(MXP_MODE_CODE_LOCK_SECURE);
|
|
|
|
|
|
|
|
|
|
std::string input = "<SEND href=\"se\xF1or\">link</SEND>";
|
|
|
|
|
for (char &ch : input) {
|
|
|
|
|
processor.processMxpInput(ch, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QCOMPARE(stub.mHrefs.size(), 1);
|
|
|
|
|
QCOMPARE(stub.mHrefs[0], "send([[señor]])");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// With no encoding negotiated yet (empty session encoding) attribute values
|
|
|
|
|
// must still decode as UTF-8, matching the historical default.
|
|
|
|
|
void testSendHrefEmptyEncodingDefaultsToUtf8() {
|
|
|
|
|
TMxpStubClient stub;
|
|
|
|
|
stub.mEncoding = QByteArray();
|
|
|
|
|
TMxpProcessor processor(&stub);
|
|
|
|
|
processor.setMode(MXP_MODE_CODE_LOCK_SECURE);
|
|
|
|
|
|
|
|
|
|
std::string input = "<SEND href=\"áéíóúñ\">link</SEND>";
|
|
|
|
|
for (char &ch : input) {
|
|
|
|
|
processor.processMxpInput(ch, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QCOMPARE(stub.mHrefs.size(), 1);
|
|
|
|
|
QCOMPARE(stub.mHrefs[0], "send([[áéíóúñ]])");
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-21 13:45:49 -04:00
|
|
|
void testSendHrefUTF8() {
|
|
|
|
|
// issue #4368
|
|
|
|
|
QString input = "<SEND href=\"áéíóúñ\" >test link: áéíóúñ</SEND>";
|
2020-05-03 14:09:42 -03:00
|
|
|
|
2026-03-21 13:45:49 -04:00
|
|
|
TMxpTagProcessor processor;
|
|
|
|
|
TMxpStubClient stub;
|
2020-05-03 14:09:42 -03:00
|
|
|
|
2026-03-21 13:45:49 -04:00
|
|
|
auto nodes = TMxpTagParser::parseToMxpNodeList(input, false);
|
|
|
|
|
QCOMPARE(nodes.size(), 3);
|
2026-04-25 21:17:42 +01:00
|
|
|
for (const auto &node : std::as_const(nodes)) {
|
2026-03-21 13:45:49 -04:00
|
|
|
processor.handleNode(processor, stub, node.get());
|
2020-05-03 14:09:42 -03:00
|
|
|
}
|
|
|
|
|
|
2026-03-21 13:45:49 -04:00
|
|
|
QCOMPARE(stub.mHrefs.size(), 1);
|
|
|
|
|
QCOMPARE(stub.mHrefs[0], "send([[áéíóúñ]])");
|
2023-05-28 21:39:46 +02:00
|
|
|
|
2026-03-21 13:45:49 -04:00
|
|
|
QCOMPARE(stub.mHints.size(), 1);
|
|
|
|
|
QCOMPARE(stub.mHints[0], "áéíóúñ");
|
|
|
|
|
}
|
2023-05-28 21:39:46 +02:00
|
|
|
|
2026-03-21 13:45:49 -04:00
|
|
|
void testStaticText() {
|
|
|
|
|
// <SEND "tell Zugg " PROMPT>Zugg</SEND>
|
|
|
|
|
TMxpStubContext ctx;
|
|
|
|
|
TMxpStubClient stub;
|
2023-05-28 21:39:46 +02:00
|
|
|
|
2026-03-21 13:45:49 -04:00
|
|
|
auto startTag = parseNode("<SEND \"tell Zugg \" PROMPT>");
|
|
|
|
|
auto endTag = parseNode("</SEND>");
|
|
|
|
|
QVERIFY(startTag);
|
|
|
|
|
QVERIFY(endTag);
|
2023-05-28 21:39:46 +02:00
|
|
|
|
2026-03-21 13:45:49 -04:00
|
|
|
TMxpSendTagHandler sendTagHandler;
|
|
|
|
|
TMxpTagHandler &tagHandler = sendTagHandler;
|
|
|
|
|
tagHandler.handleTag(ctx, stub, startTag->asStartTag());
|
|
|
|
|
tagHandler.handleContent("Zugg");
|
|
|
|
|
tagHandler.handleTag(ctx, stub, endTag->asEndTag());
|
2023-05-28 21:39:46 +02:00
|
|
|
|
2026-03-21 13:45:49 -04:00
|
|
|
QCOMPARE(stub.mHrefs.size(), 1);
|
|
|
|
|
QCOMPARE(stub.mHrefs[0], "printCmdLine([[tell Zugg ]])");
|
2023-05-28 21:39:46 +02:00
|
|
|
|
2026-03-21 13:45:49 -04:00
|
|
|
QCOMPARE(stub.mHints.size(), 1);
|
|
|
|
|
QCOMPARE(stub.mHints[0], "tell Zugg ");
|
|
|
|
|
}
|
2023-05-28 21:39:46 +02:00
|
|
|
|
2026-03-21 13:45:49 -04:00
|
|
|
void testSimpleSend() {
|
|
|
|
|
// <SEND>north</SEND>
|
|
|
|
|
TMxpStubContext ctx;
|
|
|
|
|
TMxpStubClient stub;
|
2023-05-28 21:39:46 +02:00
|
|
|
|
2026-03-21 13:45:49 -04:00
|
|
|
MxpStartTag startTag("SEND");
|
|
|
|
|
MxpEndTag endTag("SEND");
|
2023-05-28 21:39:46 +02:00
|
|
|
|
2026-03-21 13:45:49 -04:00
|
|
|
TMxpSendTagHandler sendTagHandler;
|
|
|
|
|
TMxpTagHandler &tagHandler = sendTagHandler;
|
2023-05-28 21:39:46 +02:00
|
|
|
|
2026-03-21 13:45:49 -04:00
|
|
|
tagHandler.handleTag(ctx, stub, &startTag);
|
|
|
|
|
tagHandler.handleContent("north");
|
|
|
|
|
tagHandler.handleTag(ctx, stub, &endTag);
|
2023-05-28 21:39:46 +02:00
|
|
|
|
2026-03-21 13:45:49 -04:00
|
|
|
QCOMPARE(stub.mHrefs.size(), 1);
|
|
|
|
|
QCOMPARE(stub.mHrefs[0], "send([[north]])");
|
2023-05-28 21:39:46 +02:00
|
|
|
|
2026-03-21 13:45:49 -04:00
|
|
|
QCOMPARE(stub.mHints.size(), 1);
|
|
|
|
|
QCOMPARE(stub.mHints[0], "north");
|
|
|
|
|
}
|
2023-05-28 21:39:46 +02:00
|
|
|
|
2026-03-21 13:45:49 -04:00
|
|
|
void testSendPrompt() {
|
|
|
|
|
// <SEND href="&text;" PROMPT>north</SEND>
|
|
|
|
|
TMxpStubContext ctx;
|
|
|
|
|
TMxpStubClient stub;
|
2023-05-28 21:39:46 +02:00
|
|
|
|
2026-03-21 13:45:49 -04:00
|
|
|
auto startTag = parseNode("<SEND href=\"&text;\" PROMPT>");
|
|
|
|
|
auto endTag = parseNode("</SEND>");
|
|
|
|
|
QVERIFY(startTag);
|
|
|
|
|
QVERIFY(endTag);
|
2023-05-28 21:39:46 +02:00
|
|
|
|
2026-03-21 13:45:49 -04:00
|
|
|
TMxpSendTagHandler sendTagHandler;
|
|
|
|
|
TMxpTagHandler &tagHandler = sendTagHandler;
|
|
|
|
|
tagHandler.handleTag(ctx, stub, startTag->asStartTag());
|
|
|
|
|
tagHandler.handleContent("north");
|
|
|
|
|
tagHandler.handleTag(ctx, stub, endTag->asEndTag());
|
2023-05-28 21:39:46 +02:00
|
|
|
|
2026-03-21 13:45:49 -04:00
|
|
|
QCOMPARE(stub.mHrefs.size(), 1);
|
|
|
|
|
QCOMPARE(stub.mHrefs[0], "printCmdLine([[north]])");
|
2020-06-15 16:49:00 -03:00
|
|
|
|
2026-03-21 13:45:49 -04:00
|
|
|
QCOMPARE(stub.mHints.size(), 1);
|
|
|
|
|
QCOMPARE(stub.mHints[0], "north");
|
|
|
|
|
}
|
Fix: MXP EXPIRE tag support and custom element attribute handling (#8431)
#### Brief overview of PR changes/additions
* **Add MXP EXPIRE tag support**: Implements the EXPIRE attribute for
MXP SEND tags, allowing servers to expire groups of links by name
* **Tooltip fix**: Fixed MXP link tooltips displaying "HREF" instead of
the actual link command when the EXPIRE attribute appears before the
HREF attribute in SEND tags
* **Custom element fix**: Fixed custom MXP elements to properly pass
through ALL attributes (EXPIRE, HREF, HINT, etc.) to their expanded tag
definitions
#### Motivation for adding to Mudlet
**EXPIRE tag support**: The MXP specification defines an EXPIRE
attribute that allows servers to tag groups of links and expire them all
at once (e.g., `<EXPIRE Exits>` expires all links tagged with
`EXPIRE="Exits"`). This is essential for dynamic content like room exits
that change as players move around.
**Tooltip fix**: Addresses reviewer feedback in PR #8383. When games
send MXP links like `<SEND EXPIRE="Exits" HREF="east">East</SEND>`, the
tooltip was incorrectly showing the literal text "HREF" instead of
"east" (the command that would be executed), making links confusing for
users.
**Custom element fix**: When servers define custom elements like
`<!ELEMENT Ex '<SEND>'>` and use them with attributes like `<Ex
EXPIRE="Exits" HREF="north">North</Ex>`, those attributes weren't being
passed through to the expanded SEND tag. This made custom elements less
functional than regular tags. Now all attributes are properly inherited.
#### Other info (issues closed, discussion etc)
- Related to PR #8383 (initial EXPIRE tag implementation discussion)
- Addresses @mfontani's comment about custom elements not passing
through EXPIRE attributes
- Added comprehensive unit tests:
- Tooltip attribute ordering tests in `TMxpSendTagHandlerTest`
- Custom element attribute pass-through test in
`TMxpCustomElementTagHandlerTest`
- All existing MXP tests continue to pass (100% success rate)
- Changes summary: 5 files changed, 101 insertions(+), 2 deletions(-)
2025-10-26 15:48:42 -04:00
|
|
|
|
2026-03-21 13:45:49 -04:00
|
|
|
void testSendHrefTextEntity() {
|
|
|
|
|
// Example from Age of Elements
|
|
|
|
|
QString input = "<send 'push &text;' HINT='push button'>button</send>";
|
Fix: MXP EXPIRE tag support and custom element attribute handling (#8431)
#### Brief overview of PR changes/additions
* **Add MXP EXPIRE tag support**: Implements the EXPIRE attribute for
MXP SEND tags, allowing servers to expire groups of links by name
* **Tooltip fix**: Fixed MXP link tooltips displaying "HREF" instead of
the actual link command when the EXPIRE attribute appears before the
HREF attribute in SEND tags
* **Custom element fix**: Fixed custom MXP elements to properly pass
through ALL attributes (EXPIRE, HREF, HINT, etc.) to their expanded tag
definitions
#### Motivation for adding to Mudlet
**EXPIRE tag support**: The MXP specification defines an EXPIRE
attribute that allows servers to tag groups of links and expire them all
at once (e.g., `<EXPIRE Exits>` expires all links tagged with
`EXPIRE="Exits"`). This is essential for dynamic content like room exits
that change as players move around.
**Tooltip fix**: Addresses reviewer feedback in PR #8383. When games
send MXP links like `<SEND EXPIRE="Exits" HREF="east">East</SEND>`, the
tooltip was incorrectly showing the literal text "HREF" instead of
"east" (the command that would be executed), making links confusing for
users.
**Custom element fix**: When servers define custom elements like
`<!ELEMENT Ex '<SEND>'>` and use them with attributes like `<Ex
EXPIRE="Exits" HREF="north">North</Ex>`, those attributes weren't being
passed through to the expanded SEND tag. This made custom elements less
functional than regular tags. Now all attributes are properly inherited.
#### Other info (issues closed, discussion etc)
- Related to PR #8383 (initial EXPIRE tag implementation discussion)
- Addresses @mfontani's comment about custom elements not passing
through EXPIRE attributes
- Added comprehensive unit tests:
- Tooltip attribute ordering tests in `TMxpSendTagHandlerTest`
- Custom element attribute pass-through test in
`TMxpCustomElementTagHandlerTest`
- All existing MXP tests continue to pass (100% success rate)
- Changes summary: 5 files changed, 101 insertions(+), 2 deletions(-)
2025-10-26 15:48:42 -04:00
|
|
|
|
2026-03-21 13:45:49 -04:00
|
|
|
TMxpTagProcessor processor;
|
|
|
|
|
TMxpStubClient stub;
|
Fix: MXP EXPIRE tag support and custom element attribute handling (#8431)
#### Brief overview of PR changes/additions
* **Add MXP EXPIRE tag support**: Implements the EXPIRE attribute for
MXP SEND tags, allowing servers to expire groups of links by name
* **Tooltip fix**: Fixed MXP link tooltips displaying "HREF" instead of
the actual link command when the EXPIRE attribute appears before the
HREF attribute in SEND tags
* **Custom element fix**: Fixed custom MXP elements to properly pass
through ALL attributes (EXPIRE, HREF, HINT, etc.) to their expanded tag
definitions
#### Motivation for adding to Mudlet
**EXPIRE tag support**: The MXP specification defines an EXPIRE
attribute that allows servers to tag groups of links and expire them all
at once (e.g., `<EXPIRE Exits>` expires all links tagged with
`EXPIRE="Exits"`). This is essential for dynamic content like room exits
that change as players move around.
**Tooltip fix**: Addresses reviewer feedback in PR #8383. When games
send MXP links like `<SEND EXPIRE="Exits" HREF="east">East</SEND>`, the
tooltip was incorrectly showing the literal text "HREF" instead of
"east" (the command that would be executed), making links confusing for
users.
**Custom element fix**: When servers define custom elements like
`<!ELEMENT Ex '<SEND>'>` and use them with attributes like `<Ex
EXPIRE="Exits" HREF="north">North</Ex>`, those attributes weren't being
passed through to the expanded SEND tag. This made custom elements less
functional than regular tags. Now all attributes are properly inherited.
#### Other info (issues closed, discussion etc)
- Related to PR #8383 (initial EXPIRE tag implementation discussion)
- Addresses @mfontani's comment about custom elements not passing
through EXPIRE attributes
- Added comprehensive unit tests:
- Tooltip attribute ordering tests in `TMxpSendTagHandlerTest`
- Custom element attribute pass-through test in
`TMxpCustomElementTagHandlerTest`
- All existing MXP tests continue to pass (100% success rate)
- Changes summary: 5 files changed, 101 insertions(+), 2 deletions(-)
2025-10-26 15:48:42 -04:00
|
|
|
|
2026-03-21 13:45:49 -04:00
|
|
|
auto nodes = TMxpTagParser::parseToMxpNodeList(input, false);
|
2026-04-25 21:17:42 +01:00
|
|
|
for (const auto &node : std::as_const(nodes)) {
|
2026-03-21 13:45:49 -04:00
|
|
|
processor.handleNode(processor, stub, node.get());
|
Fix: MXP EXPIRE tag support and custom element attribute handling (#8431)
#### Brief overview of PR changes/additions
* **Add MXP EXPIRE tag support**: Implements the EXPIRE attribute for
MXP SEND tags, allowing servers to expire groups of links by name
* **Tooltip fix**: Fixed MXP link tooltips displaying "HREF" instead of
the actual link command when the EXPIRE attribute appears before the
HREF attribute in SEND tags
* **Custom element fix**: Fixed custom MXP elements to properly pass
through ALL attributes (EXPIRE, HREF, HINT, etc.) to their expanded tag
definitions
#### Motivation for adding to Mudlet
**EXPIRE tag support**: The MXP specification defines an EXPIRE
attribute that allows servers to tag groups of links and expire them all
at once (e.g., `<EXPIRE Exits>` expires all links tagged with
`EXPIRE="Exits"`). This is essential for dynamic content like room exits
that change as players move around.
**Tooltip fix**: Addresses reviewer feedback in PR #8383. When games
send MXP links like `<SEND EXPIRE="Exits" HREF="east">East</SEND>`, the
tooltip was incorrectly showing the literal text "HREF" instead of
"east" (the command that would be executed), making links confusing for
users.
**Custom element fix**: When servers define custom elements like
`<!ELEMENT Ex '<SEND>'>` and use them with attributes like `<Ex
EXPIRE="Exits" HREF="north">North</Ex>`, those attributes weren't being
passed through to the expanded SEND tag. This made custom elements less
functional than regular tags. Now all attributes are properly inherited.
#### Other info (issues closed, discussion etc)
- Related to PR #8383 (initial EXPIRE tag implementation discussion)
- Addresses @mfontani's comment about custom elements not passing
through EXPIRE attributes
- Added comprehensive unit tests:
- Tooltip attribute ordering tests in `TMxpSendTagHandlerTest`
- Custom element attribute pass-through test in
`TMxpCustomElementTagHandlerTest`
- All existing MXP tests continue to pass (100% success rate)
- Changes summary: 5 files changed, 101 insertions(+), 2 deletions(-)
2025-10-26 15:48:42 -04:00
|
|
|
}
|
|
|
|
|
|
2026-03-21 13:45:49 -04:00
|
|
|
QCOMPARE(stub.mHrefs.size(), 1);
|
|
|
|
|
QCOMPARE(stub.mHrefs[0], "send([[push button]])");
|
Fix: MXP EXPIRE tag support and custom element attribute handling (#8431)
#### Brief overview of PR changes/additions
* **Add MXP EXPIRE tag support**: Implements the EXPIRE attribute for
MXP SEND tags, allowing servers to expire groups of links by name
* **Tooltip fix**: Fixed MXP link tooltips displaying "HREF" instead of
the actual link command when the EXPIRE attribute appears before the
HREF attribute in SEND tags
* **Custom element fix**: Fixed custom MXP elements to properly pass
through ALL attributes (EXPIRE, HREF, HINT, etc.) to their expanded tag
definitions
#### Motivation for adding to Mudlet
**EXPIRE tag support**: The MXP specification defines an EXPIRE
attribute that allows servers to tag groups of links and expire them all
at once (e.g., `<EXPIRE Exits>` expires all links tagged with
`EXPIRE="Exits"`). This is essential for dynamic content like room exits
that change as players move around.
**Tooltip fix**: Addresses reviewer feedback in PR #8383. When games
send MXP links like `<SEND EXPIRE="Exits" HREF="east">East</SEND>`, the
tooltip was incorrectly showing the literal text "HREF" instead of
"east" (the command that would be executed), making links confusing for
users.
**Custom element fix**: When servers define custom elements like
`<!ELEMENT Ex '<SEND>'>` and use them with attributes like `<Ex
EXPIRE="Exits" HREF="north">North</Ex>`, those attributes weren't being
passed through to the expanded SEND tag. This made custom elements less
functional than regular tags. Now all attributes are properly inherited.
#### Other info (issues closed, discussion etc)
- Related to PR #8383 (initial EXPIRE tag implementation discussion)
- Addresses @mfontani's comment about custom elements not passing
through EXPIRE attributes
- Added comprehensive unit tests:
- Tooltip attribute ordering tests in `TMxpSendTagHandlerTest`
- Custom element attribute pass-through test in
`TMxpCustomElementTagHandlerTest`
- All existing MXP tests continue to pass (100% success rate)
- Changes summary: 5 files changed, 101 insertions(+), 2 deletions(-)
2025-10-26 15:48:42 -04:00
|
|
|
|
2026-03-21 13:45:49 -04:00
|
|
|
QCOMPARE(stub.mHints.size(), 1);
|
|
|
|
|
QCOMPARE(stub.mHints[0], "push button");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void testResolvingEntity() {
|
|
|
|
|
TMxpStubContext ctx;
|
|
|
|
|
TMxpStubClient stub;
|
|
|
|
|
|
|
|
|
|
ctx.getEntityResolver().registerEntity("&charName;", "Gandalf");
|
|
|
|
|
|
|
|
|
|
auto startTag = parseNode("<SEND href=\"say I am &charName;\">");
|
|
|
|
|
auto endTag = parseNode("</SEND>");
|
|
|
|
|
QVERIFY(startTag);
|
|
|
|
|
QVERIFY(endTag);
|
|
|
|
|
|
|
|
|
|
TMxpSendTagHandler sendTagHandler;
|
|
|
|
|
TMxpTagHandler &tagHandler = sendTagHandler;
|
|
|
|
|
tagHandler.handleTag(ctx, stub, startTag->asStartTag());
|
|
|
|
|
tagHandler.handleContent("TAG CONTENT");
|
|
|
|
|
tagHandler.handleTag(ctx, stub, endTag->asEndTag());
|
|
|
|
|
|
|
|
|
|
QCOMPARE(stub.mHrefs.size(), 1);
|
|
|
|
|
QCOMPARE(stub.mHrefs[0], "send([[say I am Gandalf]])");
|
|
|
|
|
|
|
|
|
|
QCOMPARE(stub.mHints.size(), 1);
|
|
|
|
|
QCOMPARE(stub.mHints[0], "say I am Gandalf");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void testResolvingEntityWithPipe() {
|
|
|
|
|
TMxpStubContext ctx;
|
|
|
|
|
TMxpStubClient stub;
|
|
|
|
|
|
|
|
|
|
ctx.getEntityResolver().registerEntity("&frontHint;", "");
|
|
|
|
|
ctx.getEntityResolver().registerEntity("&frontHref;", "");
|
|
|
|
|
|
|
|
|
|
ctx.getEntityResolver().registerEntity("&backHints;", "");
|
|
|
|
|
ctx.getEntityResolver().registerEntity("&backHrefs;", "");
|
|
|
|
|
|
|
|
|
|
TMxpSendTagHandler sendTagHandler;
|
|
|
|
|
TMxpTagHandler &tagHandler = sendTagHandler;
|
|
|
|
|
|
|
|
|
|
// First check the SEND TAG with empty entities
|
|
|
|
|
auto startTag =
|
|
|
|
|
parseNode("<SEND href=\"&frontHref;look|say hello&backHrefs;\" "
|
|
|
|
|
"hint=\"&frontHint;LOOK AROUND|SAY HELLO&backHints;\">");
|
|
|
|
|
auto endTag = parseNode("</SEND>");
|
|
|
|
|
QVERIFY(startTag);
|
|
|
|
|
QVERIFY(endTag);
|
|
|
|
|
|
|
|
|
|
tagHandler.handleTag(ctx, stub, startTag->asStartTag());
|
|
|
|
|
tagHandler.handleContent("TAG CONTENT");
|
|
|
|
|
tagHandler.handleTag(ctx, stub, endTag->asEndTag());
|
|
|
|
|
|
|
|
|
|
QCOMPARE(stub.mHrefs.size(), 2);
|
|
|
|
|
QCOMPARE(stub.mHrefs[0], "send([[look]])");
|
|
|
|
|
QCOMPARE(stub.mHrefs[1], "send([[say hello]])");
|
|
|
|
|
|
|
|
|
|
QCOMPARE(stub.mHints.size(), 2);
|
|
|
|
|
QCOMPARE(stub.mHints[0], "LOOK AROUND");
|
|
|
|
|
QCOMPARE(stub.mHints[1], "SAY HELLO");
|
|
|
|
|
|
|
|
|
|
// Now add top menu entries
|
|
|
|
|
|
|
|
|
|
ctx.getEntityResolver().registerEntity("&frontHint;", "WHO IS ONLINE?|");
|
|
|
|
|
ctx.getEntityResolver().registerEntity("&frontHref;", "who|");
|
|
|
|
|
|
|
|
|
|
tagHandler.handleTag(ctx, stub, startTag->asStartTag());
|
|
|
|
|
tagHandler.handleContent("TAG CONTENT");
|
|
|
|
|
tagHandler.handleTag(ctx, stub, endTag->asEndTag());
|
|
|
|
|
|
|
|
|
|
QCOMPARE(stub.mHrefs.size(), 3);
|
|
|
|
|
QCOMPARE(stub.mHrefs[0], "send([[who]])");
|
|
|
|
|
QCOMPARE(stub.mHrefs[1], "send([[look]])");
|
|
|
|
|
QCOMPARE(stub.mHrefs[2], "send([[say hello]])");
|
|
|
|
|
|
|
|
|
|
QCOMPARE(stub.mHints.size(), 3);
|
|
|
|
|
QCOMPARE(stub.mHints[0], "WHO IS ONLINE?");
|
|
|
|
|
QCOMPARE(stub.mHints[1], "LOOK AROUND");
|
|
|
|
|
QCOMPARE(stub.mHints[2], "SAY HELLO");
|
|
|
|
|
|
|
|
|
|
// Finally add something to the end of the menu
|
|
|
|
|
|
|
|
|
|
ctx.getEntityResolver().registerEntity("&backHints;",
|
|
|
|
|
"|KNOCK AT THE DOOR|BREAK THE DOOR");
|
|
|
|
|
ctx.getEntityResolver().registerEntity("&backHrefs;",
|
|
|
|
|
"|knock at door|break door");
|
|
|
|
|
|
|
|
|
|
tagHandler.handleTag(ctx, stub, startTag->asStartTag());
|
|
|
|
|
tagHandler.handleContent("TAG CONTENT");
|
|
|
|
|
tagHandler.handleTag(ctx, stub, endTag->asEndTag());
|
|
|
|
|
|
|
|
|
|
QCOMPARE(stub.mHrefs.size(), 5);
|
|
|
|
|
QCOMPARE(stub.mHrefs[0], "send([[who]])");
|
|
|
|
|
QCOMPARE(stub.mHrefs[1], "send([[look]])");
|
|
|
|
|
QCOMPARE(stub.mHrefs[2], "send([[say hello]])");
|
|
|
|
|
QCOMPARE(stub.mHrefs[3], "send([[knock at door]])");
|
|
|
|
|
QCOMPARE(stub.mHrefs[4], "send([[break door]])");
|
|
|
|
|
|
|
|
|
|
QCOMPARE(stub.mHints.size(), 5);
|
|
|
|
|
QCOMPARE(stub.mHints[0], "WHO IS ONLINE?");
|
|
|
|
|
QCOMPARE(stub.mHints[1], "LOOK AROUND");
|
|
|
|
|
QCOMPARE(stub.mHints[2], "SAY HELLO");
|
|
|
|
|
QCOMPARE(stub.mHints[3], "KNOCK AT THE DOOR");
|
|
|
|
|
QCOMPARE(stub.mHints[4], "BREAK THE DOOR");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void testSendHrefHintMismatch() {
|
|
|
|
|
// Example from starmourn on WARES command from NPCs
|
|
|
|
|
// <SEND HREF="PROBE SUSPENDERS30901|BUY SUSPENDERS30901" hint="Click to see
|
|
|
|
|
// command menu">30901</SEND>
|
|
|
|
|
TMxpStubContext ctx;
|
|
|
|
|
TMxpStubClient stub;
|
|
|
|
|
|
|
|
|
|
auto startTag = parseNode(
|
|
|
|
|
R"(<SEND HREF="PROBE SUSPENDERS30901|BUY SUSPENDERS30901" hint="Click to see command menu">)");
|
|
|
|
|
auto endTag = parseNode("</SEND>");
|
|
|
|
|
QVERIFY(startTag);
|
|
|
|
|
QVERIFY(endTag);
|
|
|
|
|
|
|
|
|
|
TMxpSendTagHandler sendTagHandler;
|
|
|
|
|
TMxpTagHandler &tagHandler = sendTagHandler;
|
|
|
|
|
tagHandler.handleTag(ctx, stub, startTag->asStartTag());
|
|
|
|
|
tagHandler.handleContent("3091");
|
|
|
|
|
tagHandler.handleTag(ctx, stub, endTag->asEndTag());
|
|
|
|
|
|
|
|
|
|
QCOMPARE(stub.mHrefs.size(), 2);
|
|
|
|
|
QCOMPARE(stub.mHrefs[0], "send([[PROBE SUSPENDERS30901]])");
|
|
|
|
|
QCOMPARE(stub.mHrefs[1], "send([[BUY SUSPENDERS30901]])");
|
|
|
|
|
|
|
|
|
|
QCOMPARE(stub.mHints.size(), 2);
|
|
|
|
|
QCOMPARE(stub.mHints[0], "PROBE SUSPENDERS30901");
|
|
|
|
|
QCOMPARE(stub.mHints[1], "BUY SUSPENDERS30901");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void testSendExpireHref() {
|
|
|
|
|
// Test case for issue #8383
|
|
|
|
|
// When EXPIRE comes before HREF, the tooltip should show the HREF value,
|
|
|
|
|
// not the literal string "HREF" <SEND EXPIRE="Exits"
|
|
|
|
|
// HREF="east">East</SEND>
|
|
|
|
|
TMxpStubContext ctx;
|
|
|
|
|
TMxpStubClient stub;
|
|
|
|
|
|
|
|
|
|
auto startTag = parseNode(R"(<SEND EXPIRE="Exits" HREF="east">)");
|
|
|
|
|
auto endTag = parseNode("</SEND>");
|
|
|
|
|
QVERIFY(startTag);
|
|
|
|
|
QVERIFY(endTag);
|
|
|
|
|
|
|
|
|
|
TMxpSendTagHandler sendTagHandler;
|
|
|
|
|
TMxpTagHandler &tagHandler = sendTagHandler;
|
|
|
|
|
tagHandler.handleTag(ctx, stub, startTag->asStartTag());
|
|
|
|
|
tagHandler.handleContent("East");
|
|
|
|
|
tagHandler.handleTag(ctx, stub, endTag->asEndTag());
|
|
|
|
|
|
|
|
|
|
QCOMPARE(stub.mHrefs.size(), 1);
|
|
|
|
|
QCOMPARE(stub.mHrefs[0], "send([[east]])");
|
|
|
|
|
|
|
|
|
|
QCOMPARE(stub.mHints.size(), 1);
|
|
|
|
|
QCOMPARE(stub.mHints[0], "east"); // Should be "east", not "HREF"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void testSendExpireHrefWithoutHint() {
|
|
|
|
|
// Test case for standard order: HREF then EXPIRE
|
|
|
|
|
// <SEND HREF="west" EXPIRE="Exits">West</SEND>
|
|
|
|
|
TMxpStubContext ctx;
|
|
|
|
|
TMxpStubClient stub;
|
|
|
|
|
|
|
|
|
|
auto startTag = parseNode(R"(<SEND HREF="west" EXPIRE="Exits">)");
|
|
|
|
|
auto endTag = parseNode("</SEND>");
|
|
|
|
|
QVERIFY(startTag);
|
|
|
|
|
QVERIFY(endTag);
|
|
|
|
|
|
|
|
|
|
TMxpSendTagHandler sendTagHandler;
|
|
|
|
|
TMxpTagHandler &tagHandler = sendTagHandler;
|
|
|
|
|
tagHandler.handleTag(ctx, stub, startTag->asStartTag());
|
|
|
|
|
tagHandler.handleContent("West");
|
|
|
|
|
tagHandler.handleTag(ctx, stub, endTag->asEndTag());
|
|
|
|
|
|
|
|
|
|
QCOMPARE(stub.mHrefs.size(), 1);
|
|
|
|
|
QCOMPARE(stub.mHrefs[0], "send([[west]])");
|
|
|
|
|
|
|
|
|
|
QCOMPARE(stub.mHints.size(), 1);
|
|
|
|
|
QCOMPARE(stub.mHints[0], "west"); // Should be "west"
|
|
|
|
|
}
|
2020-05-03 14:09:42 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#include "TMxpSendTagHandlerTest.moc"
|
|
|
|
|
QTEST_MAIN(TMxpSendTagHandlerTest)
|