aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorSemih Yavuz <semih.yavuz@qt.io>2025-11-19 18:19:30 +0100
committerSemih Yavuz <semih.yavuz@qt.io>2025-12-01 10:11:56 +0100
commit49f14263cd587282f77b0fac761de74483e52485 (patch)
tree8f48690db2671ade962faee6bfeb64ab2745c28d /tests
parent7df340dac1ad0f1acd3d4d023705345ad740c3be (diff)
shift highlights: adapt lsp highlighting request to shiftingHEADdev
Implement Utils::shiftHighlights to apply diffs to cached highlights. Fallback to shifted highlights when DOM is invalid to avoid recompute. Refactor handlers to use shifted tokens and update result IDs and cache. Add unit tests and invalid fixtures covering deletions and partial edits. Task-number: QTBUG-140645 Change-Id: Ic230af0e3d995e85959beee3dfa37a987843c119 Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/qmlls/modules/tst_qmlls_modules.cpp16
-rw-r--r--tests/auto/qmlls/utils/data/highlights/highlightsShift.qml8
-rw-r--r--tests/auto/qmlls/utils/data/highlights/highlightsShift_consoleLog.qml8
-rw-r--r--tests/auto/qmlls/utils/data/highlights/highlightsShift_withComments.qml11
-rw-r--r--tests/auto/qmlls/utils/data/highlights/invalid/highlightsShift_consoleLog_del.qml8
-rw-r--r--tests/auto/qmlls/utils/data/highlights/invalid/highlightsShift_del1.qml8
-rw-r--r--tests/auto/qmlls/utils/data/highlights/invalid/highlightsShift_del2.qml8
-rw-r--r--tests/auto/qmlls/utils/data/highlights/invalid/highlightsShift_del3.qml8
-rw-r--r--tests/auto/qmlls/utils/data/highlights/invalid/highlightsShift_del4.qml6
-rw-r--r--tests/auto/qmlls/utils/data/highlights/invalid/highlightsShift_del5.qml7
-rw-r--r--tests/auto/qmlls/utils/data/highlights/invalid/highlightsShift_del6.qml6
-rw-r--r--tests/auto/qmlls/utils/data/highlights/invalid/highlightsShift_withComments_del.qml5
-rw-r--r--tests/auto/qmlls/utils/tst_qmlls_highlighting.cpp285
-rw-r--r--tests/auto/qmlls/utils/tst_qmlls_highlighting.h2
14 files changed, 362 insertions, 24 deletions
diff --git a/tests/auto/qmlls/modules/tst_qmlls_modules.cpp b/tests/auto/qmlls/modules/tst_qmlls_modules.cpp
index 7ad4b4447e..533fccfe62 100644
--- a/tests/auto/qmlls/modules/tst_qmlls_modules.cpp
+++ b/tests/auto/qmlls/modules/tst_qmlls_modules.cpp
@@ -1945,8 +1945,8 @@ void tst_qmlls_modules::semanticHighlightingFull()
{
QFETCH(QString, filePath);
const auto item = fileObject(testFile(filePath));
- QmlHighlighting::HighlightsContainer highlights;
- const auto expectedData = QmlHighlighting::Utils::collectTokens(item, std::nullopt);
+ QmlHighlighting::HighlightsContainer highlights = QmlHighlighting::Utils::visitTokens(item, std::nullopt);
+ const auto expectedData = QmlHighlighting::Utils::encodeSemanticTokens(highlights);
const auto uri = openFile(filePath);
QVERIFY(uri);
@@ -1988,13 +1988,13 @@ void tst_qmlls_modules::semanticHighlightingRange()
QFETCH(QLspSpecification::Range, range);
const auto item = fileObject(testFile(filePath));
- QmlHighlighting::HighlightsContainer highlights;
const auto qmlFile = item.as<QQmlJS::Dom::QmlFile>();
const auto code = qmlFile->code();
const int startOffset = int(QQmlLSUtils::textOffsetFrom(code, range.start.line, range.end.character));
const int endOffset = int(QQmlLSUtils::textOffsetFrom(code, range.end.line, range.end.character));
- const auto expectedData = QmlHighlighting::Utils::collectTokens(
+ QmlHighlighting::HighlightsContainer highlights = QmlHighlighting::Utils::visitTokens(
item, QmlHighlighting::HighlightsRange{ startOffset, endOffset });
+ const auto expectedData = QmlHighlighting::Utils::encodeSemanticTokens(highlights);
const auto uri = openFile(filePath);
QVERIFY(uri);
@@ -2039,8 +2039,12 @@ void tst_qmlls_modules::semanticHighlightingDelta()
const auto fileItem = fileObject(testFile(filePath));
const auto deltaFileItem = fileObject(testFile(deltaFilePath));
- auto fullDocumentSemanticTokensData = QmlHighlighting::Utils::collectTokens(fileItem, std::nullopt);
- auto editedDocumentSemanticTokensData = QmlHighlighting::Utils::collectTokens(deltaFileItem, std::nullopt);
+ const auto fullDocumentSemanticTokens = QmlHighlighting::Utils::visitTokens(fileItem, std::nullopt);
+ const auto editedDocumentSemanticTokens = QmlHighlighting::Utils::visitTokens(deltaFileItem, std::nullopt);
+ auto fullDocumentSemanticTokensData =
+ QmlHighlighting::Utils::encodeSemanticTokens(fullDocumentSemanticTokens);
+ auto editedDocumentSemanticTokensData =
+ QmlHighlighting::Utils::encodeSemanticTokens(editedDocumentSemanticTokens);
const auto expectedEdits = QmlHighlighting::Utils::computeDiff(
fullDocumentSemanticTokensData, editedDocumentSemanticTokensData);
diff --git a/tests/auto/qmlls/utils/data/highlights/highlightsShift.qml b/tests/auto/qmlls/utils/data/highlights/highlightsShift.qml
new file mode 100644
index 0000000000..df4ffc69da
--- /dev/null
+++ b/tests/auto/qmlls/utils/data/highlights/highlightsShift.qml
@@ -0,0 +1,8 @@
+import QtQuick
+Item {
+ width: 100
+ Rectangle {
+ width: 100
+ height: 100
+ }
+}
diff --git a/tests/auto/qmlls/utils/data/highlights/highlightsShift_consoleLog.qml b/tests/auto/qmlls/utils/data/highlights/highlightsShift_consoleLog.qml
new file mode 100644
index 0000000000..b717634689
--- /dev/null
+++ b/tests/auto/qmlls/utils/data/highlights/highlightsShift_consoleLog.qml
@@ -0,0 +1,8 @@
+import QtQuick
+
+HasEnumAndAttachedType {
+ property var enumValue: 1
+ Component.onCompleted: {
+ console.log(enumValue)
+ }
+}
diff --git a/tests/auto/qmlls/utils/data/highlights/highlightsShift_withComments.qml b/tests/auto/qmlls/utils/data/highlights/highlightsShift_withComments.qml
new file mode 100644
index 0000000000..fddac941f6
--- /dev/null
+++ b/tests/auto/qmlls/utils/data/highlights/highlightsShift_withComments.qml
@@ -0,0 +1,11 @@
+import QtQuick
+
+HasEnumAndAttachedType {
+ property var enumValue: 1
+ Component.onCompleted: {
+ console.log(enumValue)
+ }
+}
+
+// This is a comment line
+// Another comment line \ No newline at end of file
diff --git a/tests/auto/qmlls/utils/data/highlights/invalid/highlightsShift_consoleLog_del.qml b/tests/auto/qmlls/utils/data/highlights/invalid/highlightsShift_consoleLog_del.qml
new file mode 100644
index 0000000000..63ace4b663
--- /dev/null
+++ b/tests/auto/qmlls/utils/data/highlights/invalid/highlightsShift_consoleLog_del.qml
@@ -0,0 +1,8 @@
+import QtQuick
+
+HasEnumAndAttachedType {
+ property var enumValue: 1
+ Component.onCompleted:
+ console.log(enumValue)
+ }
+}
diff --git a/tests/auto/qmlls/utils/data/highlights/invalid/highlightsShift_del1.qml b/tests/auto/qmlls/utils/data/highlights/invalid/highlightsShift_del1.qml
new file mode 100644
index 0000000000..ee722b9ce7
--- /dev/null
+++ b/tests/auto/qmlls/utils/data/highlights/invalid/highlightsShift_del1.qml
@@ -0,0 +1,8 @@
+imQuick
+Item {
+ width: 100
+ Rectangle {
+ width: 100
+ height: 100
+ }
+}
diff --git a/tests/auto/qmlls/utils/data/highlights/invalid/highlightsShift_del2.qml b/tests/auto/qmlls/utils/data/highlights/invalid/highlightsShift_del2.qml
new file mode 100644
index 0000000000..c81451e306
--- /dev/null
+++ b/tests/auto/qmlls/utils/data/highlights/invalid/highlightsShift_del2.qml
@@ -0,0 +1,8 @@
+import QtQuick
+Ite
+ width: 100
+ Rectangle {
+ width: 100
+ height: 100
+ }
+}
diff --git a/tests/auto/qmlls/utils/data/highlights/invalid/highlightsShift_del3.qml b/tests/auto/qmlls/utils/data/highlights/invalid/highlightsShift_del3.qml
new file mode 100644
index 0000000000..7e93d458d3
--- /dev/null
+++ b/tests/auto/qmlls/utils/data/highlights/invalid/highlightsShift_del3.qml
@@ -0,0 +1,8 @@
+ QtQuick
+Item {
+ width: 100
+ Rectangle {
+ width: 100
+ height: 100
+ }
+}
diff --git a/tests/auto/qmlls/utils/data/highlights/invalid/highlightsShift_del4.qml b/tests/auto/qmlls/utils/data/highlights/invalid/highlightsShift_del4.qml
new file mode 100644
index 0000000000..8e8e7f0475
--- /dev/null
+++ b/tests/auto/qmlls/utils/data/highlights/invalid/highlightsShift_del4.qml
@@ -0,0 +1,6 @@
+import QtQuick
+Item {
+ width: 100
+ Rectangle {
+
+}
diff --git a/tests/auto/qmlls/utils/data/highlights/invalid/highlightsShift_del5.qml b/tests/auto/qmlls/utils/data/highlights/invalid/highlightsShift_del5.qml
new file mode 100644
index 0000000000..9cf4c3804a
--- /dev/null
+++ b/tests/auto/qmlls/utils/data/highlights/invalid/highlightsShift_del5.qml
@@ -0,0 +1,7 @@
+import QtQuick
+Item {
+ width: 100
+ Rectangle
+height: 100
+ }
+}
diff --git a/tests/auto/qmlls/utils/data/highlights/invalid/highlightsShift_del6.qml b/tests/auto/qmlls/utils/data/highlights/invalid/highlightsShift_del6.qml
new file mode 100644
index 0000000000..5437541542
--- /dev/null
+++ b/tests/auto/qmlls/utils/data/highlights/invalid/highlightsShift_del6.qml
@@ -0,0 +1,6 @@
+import QtQuick
+Item {
+ width: 100th: 100
+ height: 100
+ }
+}
diff --git a/tests/auto/qmlls/utils/data/highlights/invalid/highlightsShift_withComments_del.qml b/tests/auto/qmlls/utils/data/highlights/invalid/highlightsShift_withComments_del.qml
new file mode 100644
index 0000000000..4bccec2ebe
--- /dev/null
+++ b/tests/auto/qmlls/utils/data/highlights/invalid/highlightsShift_withComments_del.qml
@@ -0,0 +1,5 @@
+import QtQuick
+
+
+// This is a comment line
+// Another comment line \ No newline at end of file
diff --git a/tests/auto/qmlls/utils/tst_qmlls_highlighting.cpp b/tests/auto/qmlls/utils/tst_qmlls_highlighting.cpp
index 6dae204bb0..49fe4e8c87 100644
--- a/tests/auto/qmlls/utils/tst_qmlls_highlighting.cpp
+++ b/tests/auto/qmlls/utils/tst_qmlls_highlighting.cpp
@@ -991,28 +991,28 @@ void tst_qmlls_highlighting::computeDiff()
}
}
-void tst_qmlls_highlighting::enumCrash()
+static QQmlJS::Dom::DomItem fileObject(const QString &filePath)
{
using namespace QQmlJS::Dom;
- const auto fileObject = [](const QString &filePath) {
- QFile f(filePath);
- DomItem file;
- if (!f.open(QIODevice::ReadOnly | QIODevice::Text))
- return file;
- QString code = f.readAll();
-
- QStringList dirs = { QLibraryInfo::path(QLibraryInfo::Qml2ImportsPath) };
- auto envPtr = DomEnvironment::create(
- dirs, QQmlJS::Dom::DomEnvironment::Option::SingleThreaded, Extended);
- envPtr->loadBuiltins();
- envPtr->loadFile(FileToLoad::fromMemory(envPtr, filePath, code),
- [&file](Path, const DomItem &, const DomItem &newIt) {
- file = newIt.fileObject();
- });
- envPtr->loadPendingDependencies();
+ QFile f(filePath);
+ DomItem file;
+ if (!f.open(QIODevice::ReadOnly | QIODevice::Text))
return file;
- };
+ QString code = f.readAll();
+
+ QStringList dirs = { QLibraryInfo::path(QLibraryInfo::Qml2ImportsPath) };
+ auto envPtr = DomEnvironment::create(dirs, QQmlJS::Dom::DomEnvironment::Option::SingleThreaded,
+ Extended);
+ envPtr->loadBuiltins();
+ envPtr->loadFile(
+ FileToLoad::fromMemory(envPtr, filePath, code),
+ [&file](Path, const DomItem &, const DomItem &newIt) { file = newIt.fileObject(); });
+ envPtr->loadPendingDependencies();
+ return file;
+};
+void tst_qmlls_highlighting::enumCrash()
+{
const auto filePath = m_highlightingDataDir + "/enums_qtbug.qml";
const auto fileItem = fileObject(filePath);
@@ -1021,4 +1021,253 @@ void tst_qmlls_highlighting::enumCrash()
QVERIFY(!highlights.isEmpty());
}
+void tst_qmlls_highlighting::shiftHighlights_data()
+{
+ QTest::addColumn<QmlHighlighting::HighlightsContainer>("lastValidHighlights");
+ QTest::addColumn<QString>("lastValidCode");
+ QTest::addColumn<QString>("currentCode");
+ QTest::addColumn<QmlHighlighting::HighlightsContainer>("expectedHighlights");
+
+ const auto filePath = m_highlightingDataDir + "/highlightsShift.qml";
+ const auto fileItem = fileObject(filePath);
+ const auto originalHighlights = QmlHighlighting::Utils::visitTokens(fileItem, std::nullopt);
+ const QString lastValidCode = fileItem.ownerAs<QQmlJS::Dom::QmlFile>()->code();
+
+ const auto editedCode = [&](const QString &file) -> QString {
+ const auto editedPath = m_highlightingDataDir + file;
+ QFile editedFile(editedPath);
+ if (!editedFile.open(QIODevice::ReadOnly | QIODevice::Text))
+ return QString();
+ return editedFile.readAll();
+ };
+
+ // delete port Qt from import QtQuick
+ // Expect highlights are the same as the originals except Item token.
+ {
+ const QString currentCode = editedCode("/invalid/highlightsShift_del1.qml");
+
+ QmlHighlighting::HighlightsContainer expectedHighlights = originalHighlights;
+ expectedHighlights.remove(0);
+ expectedHighlights.remove(7);
+ const auto im = QQmlJS::SourceLocation(0, 2, 1, 1); // 'im' location
+ expectedHighlights[im.offset] =
+ HighlightToken(im, QmlHighlightKind::QmlKeyword, QmlHighlightModifier::None);
+ const auto quick = QQmlJS::SourceLocation(3, 5, 1, 3); // 'Quick' location
+ expectedHighlights[quick.offset] =
+ HighlightToken(quick, QmlHighlightKind::QmlImportId, QmlHighlightModifier::None);
+
+ QTest::addRow("modify-line-without-lineshift-from-lhs-rhs")
+ << originalHighlights << lastValidCode << currentCode << expectedHighlights;
+ }
+ // modify Item { into Ite
+ // Expect highlights are the same as the originals except Item token.
+ {
+ const QString currentCode = editedCode("/invalid/highlightsShift_del2.qml");
+
+ QmlHighlighting::HighlightsContainer expectedHighlights = originalHighlights;
+ const auto itemNewLoc = QQmlJS::SourceLocation(15, 3, 2, 1); // 'Ite' location
+ expectedHighlights[itemNewLoc.offset] =
+ HighlightToken(itemNewLoc, QmlHighlightKind::QmlType, QmlHighlightModifier::None);
+
+ QTest::addRow("modify-line-without-lineshift-from-rhs")
+ << originalHighlights << lastValidCode << currentCode << expectedHighlights;
+ }
+ // delete "import" from import QtQuick
+ // Expect highlights are the same as the originals QtQuick token should shift.
+ // and import should be gone.
+ {
+ const QString currentCode = editedCode("/invalid/highlightsShift_del3.qml");
+
+ QmlHighlighting::HighlightsContainer expectedHighlights = originalHighlights;
+ // remove import QtQuick
+ expectedHighlights.remove(0);
+ expectedHighlights.remove(7);
+ // insert QtQuick
+ const auto qtquickNewLoc = QQmlJS::SourceLocation(1, 7, 1, 2);
+ expectedHighlights[qtquickNewLoc.offset] = HighlightToken(
+ qtquickNewLoc, QmlHighlightKind::QmlImportId, QmlHighlightModifier::None);
+
+ QTest::addRow("modify-line-without-lineshift-from-lhs")
+ << originalHighlights << lastValidCode << currentCode << expectedHighlights;
+ }
+
+ // delete inner content of Rectangle, leave it in invalid state
+ {
+ const QString currentCode = editedCode("/invalid/highlightsShift_del4.qml");
+
+ QmlHighlighting::HighlightsContainer expectedHighlights = originalHighlights;
+ // remove Rectangle content tokens
+ expectedHighlights.remove(61); // width
+ expectedHighlights.remove(68); // 100
+ expectedHighlights.remove(80); // height
+ expectedHighlights.remove(88); // 100
+
+ QTest::addRow("delete-multiline-no-shift")
+ << originalHighlights << lastValidCode << currentCode << expectedHighlights;
+ }
+ // delete width content of Rectangle, height should line shift up
+ {
+ const QString currentCode = editedCode("/invalid/highlightsShift_del5.qml");
+
+ QmlHighlighting::HighlightsContainer expectedHighlights = originalHighlights;
+ // remove Rectangle content tokens
+ expectedHighlights.remove(61); // width
+ expectedHighlights.remove(68); // 100
+
+ // height should line shift up, and shifts column
+ auto heightToken = expectedHighlights.take(80);
+ expectedHighlights.remove(80);
+ heightToken.loc.startLine = 5;
+ heightToken.loc.startColumn = 1;
+ heightToken.loc.offset = 51;
+ expectedHighlights[heightToken.loc.offset] = heightToken;
+
+ auto numberToken = expectedHighlights.take(88);
+ expectedHighlights.remove(88);
+ numberToken.loc.startLine = 5;
+ numberToken.loc.startColumn = 9;
+ numberToken.loc.offset = 59;
+ expectedHighlights[numberToken.loc.offset] = numberToken;
+ QTest::addRow("delete-multiline-line-column-shift")
+ << originalHighlights << lastValidCode << currentCode << expectedHighlights;
+ }
+ // delete width content of Rectangle, height should line shift up, Rectangle should be erased
+ // th: 100 part of width should line up and start at the end of upper line
+ {
+ const QString currentCode = editedCode("/invalid/highlightsShift_del6.qml");
+
+ QmlHighlighting::HighlightsContainer expectedHighlights = originalHighlights;
+ // remove Rectangle content tokens
+ expectedHighlights.remove(41); // Rectangle
+
+ // width
+ auto widthToken = expectedHighlights.take(61);
+ expectedHighlights.remove(61);
+ widthToken.loc.startLine = 3;
+ widthToken.loc.startColumn = 15;
+ widthToken.loc.offset = 36;
+ widthToken.loc.length = 2; // th part remained
+ expectedHighlights[widthToken.loc.offset] = widthToken;
+ // 100
+ auto numberToken = expectedHighlights.take(68);
+ expectedHighlights.remove(68);
+ numberToken.loc.startLine = 3;
+ numberToken.loc.startColumn = 19;
+ numberToken.loc.offset = 40;
+ expectedHighlights[numberToken.loc.offset] = numberToken;
+ // height should line shift up
+ auto heightToken = expectedHighlights.take(80);
+ expectedHighlights.remove(80);
+ heightToken.loc.startLine = 4;
+ heightToken.loc.startColumn = 9;
+ heightToken.loc.offset = 52;
+ expectedHighlights[heightToken.loc.offset] = heightToken;
+
+ auto heightNumber = expectedHighlights.take(88);
+ expectedHighlights.remove(88);
+ heightNumber.loc.startLine = 4;
+ heightNumber.loc.startColumn = 17;
+ heightNumber.loc.offset = 60;
+ expectedHighlights[heightNumber.loc.offset] = heightNumber;
+
+ QTest::addRow("delete-multiline-line-column-shift-2")
+ << originalHighlights << lastValidCode << currentCode << expectedHighlights;
+ }
+ { // manual testing find: console.log(element)
+ const auto filePath = m_highlightingDataDir + "/highlightsShift_consoleLog.qml";
+ const auto fileItem = fileObject(filePath);
+ const auto highlights = QmlHighlighting::Utils::visitTokens(fileItem, std::nullopt);
+ const QString validCode = fileItem.ownerAs<QQmlJS::Dom::QmlFile>()->code();
+ const QString currentCode = editedCode("/invalid/highlightsShift_consoleLog_del.qml");
+
+ QmlHighlighting::HighlightsContainer expectedHighlights = highlights;
+ // console
+ auto consoleToken = expectedHighlights.take(108);
+ expectedHighlights.remove(108);
+ consoleToken.loc.offset = 107;
+ expectedHighlights[consoleToken.loc.offset] = consoleToken;
+ // log
+ auto logToken = expectedHighlights.take(116);
+ expectedHighlights.remove(116);
+ logToken.loc.offset = 115;
+ expectedHighlights[logToken.loc.offset] = logToken;
+ // enumValue
+ auto enumValueToken = expectedHighlights.take(120);
+ expectedHighlights.remove(120);
+ enumValueToken.loc.offset = 119;
+ expectedHighlights[enumValueToken.loc.offset] = enumValueToken;
+
+ QTest::addRow("delete-shift-console-log")
+ << highlights << validCode << currentCode << expectedHighlights;
+ }
+ { // manual testing find: comments after deletion
+ const auto filePath = m_highlightingDataDir + "/highlightsShift_withComments.qml";
+ const auto fileItem = fileObject(filePath);
+ const auto highlights = QmlHighlighting::Utils::visitTokens(fileItem, std::nullopt);
+ const QString validCode = fileItem.ownerAs<QQmlJS::Dom::QmlFile>()->code();
+ const QString currentCode = editedCode("/invalid/highlightsShift_withComments_del.qml");
+
+ QmlHighlighting::HighlightsContainer expectedHighlights;
+ // import
+ expectedHighlights[0] = highlights[0];
+ // QtQuick
+ expectedHighlights[7] = highlights[7];
+ // commentline 1
+ auto commentLine1 = QmlHighlighting::HighlightToken(
+ QQmlJS::SourceLocation(17, 25, 4, 1),
+ QmlHighlightKind::Comment, QmlHighlightModifier::None);
+ expectedHighlights[commentLine1.loc.offset] = commentLine1;
+ // commentline 2
+ auto commentLine2 = QmlHighlighting::HighlightToken(
+ QQmlJS::SourceLocation(43, 23, 5, 1),
+ QmlHighlightKind::Comment, QmlHighlightModifier::None);
+ expectedHighlights[commentLine2.loc.offset] = commentLine2;
+
+ QTest::addRow("delete-shift-comments-after-deletion")
+ << highlights << validCode << currentCode << expectedHighlights;
+ }
+}
+
+void tst_qmlls_highlighting::shiftHighlights()
+{
+ QFETCH(QmlHighlighting::HighlightsContainer, lastValidHighlights);
+ QFETCH(QString, lastValidCode);
+ QFETCH(QString, currentCode);
+ QFETCH(QmlHighlighting::HighlightsContainer, expectedHighlights);
+
+ HighlightsContainer actualHighlights =
+ QmlHighlighting::Utils::shiftHighlights(lastValidHighlights, lastValidCode, currentCode);
+ [&] {
+ const auto actualEncoded = QmlHighlighting::Utils::encodeSemanticTokens(
+ actualHighlights, QmlHighlighting::HighlightingMode::Default);
+ const auto expectedEncoded = QmlHighlighting::Utils::encodeSemanticTokens(
+ expectedHighlights, QmlHighlighting::HighlightingMode::Default);
+ QCOMPARE(actualEncoded, expectedEncoded);
+ }();
+
+ if (QTest::currentTestFailed()) {
+ auto [actual, expected] =
+ std::mismatch(actualHighlights.begin(), actualHighlights.end(),
+ expectedHighlights.begin(), expectedHighlights.end());
+
+ if (actual != actualHighlights.end() && expected != expectedHighlights.end()) {
+
+ const auto msg = [](const QString &title, int actualValue, int expectedValue) {
+ return QString("%1 : [Actual %2, Expected %3]")
+ .arg(title)
+ .arg(actualValue)
+ .arg(expectedValue);
+ };
+ qDebug() << msg("Offset", actual->loc.offset, expected->loc.offset);
+ qDebug() << msg("Length", actual->loc.length, expected->loc.length);
+ qDebug() << msg("StartLine", actual->loc.startLine, expected->loc.startLine);
+ qDebug() << msg("StartColumn", actual->loc.startColumn, expected->loc.startColumn);
+ qDebug() << msg("Kind", static_cast<int>(actual->kind),
+ static_cast<int>(expected->kind));
+ qDebug() << msg("Modifiers", static_cast<int>(actual->modifiers),
+ static_cast<int>(expected->modifiers));
+ }
+ }
+}
+
QTEST_MAIN(tst_qmlls_highlighting)
diff --git a/tests/auto/qmlls/utils/tst_qmlls_highlighting.h b/tests/auto/qmlls/utils/tst_qmlls_highlighting.h
index 42a0344a65..f7dc03ac00 100644
--- a/tests/auto/qmlls/utils/tst_qmlls_highlighting.h
+++ b/tests/auto/qmlls/utils/tst_qmlls_highlighting.h
@@ -32,6 +32,8 @@ private slots:
void computeDiff();
void enumCrash();
+ void shiftHighlights_data();
+ void shiftHighlights();
private:
QString m_highlightingDataDir;