mirror of
https://github.com/NohamR/Reclass.git
synced 2026-05-10 19:59:21 +00:00
Add type selector popup, view root switching, and new type creation
- Type selector chevron [▸] on command row opens searchable popup - Popup lists all root structs with filter, keyboard nav, side-triangle indicator - Selecting a type switches the editor view via setViewRootId - "Create new type" inserts a new root struct with no name - Command row displays the active view root's name - Tests for chevron detection, span compatibility, view switching, undo
This commit is contained in:
361
tests/test_rendered_view.cpp
Normal file
361
tests/test_rendered_view.cpp
Normal file
@@ -0,0 +1,361 @@
|
||||
#include <QtTest/QTest>
|
||||
#include <QApplication>
|
||||
#include <Qsci/qsciscintilla.h>
|
||||
#include <Qsci/qsciscintillabase.h>
|
||||
#include <Qsci/qscilexercpp.h>
|
||||
#include <QColor>
|
||||
#include <QFont>
|
||||
|
||||
#include "core.h"
|
||||
#include "generator.h"
|
||||
|
||||
// Raw Scintilla message IDs not exposed by QsciScintillaBase wrapper
|
||||
static constexpr int SCI_GETSELBACK = 2477;
|
||||
static constexpr int SCI_GETSELFORE = 2476;
|
||||
|
||||
// ── Helper: extract BGR long from QColor (Scintilla stores colors as 0x00BBGGRR) ──
|
||||
|
||||
static long toBGR(const QColor& c) {
|
||||
return (long)c.red() | ((long)c.green() << 8) | ((long)c.blue() << 16);
|
||||
}
|
||||
|
||||
// ── Replicates MainWindow::setupRenderedSci so the test stays in sync ──
|
||||
|
||||
static void setupRenderedSci(QsciScintilla* sci) {
|
||||
QFont f("Consolas", 12);
|
||||
f.setFixedPitch(true);
|
||||
|
||||
sci->setFont(f);
|
||||
sci->setReadOnly(false);
|
||||
sci->setWrapMode(QsciScintilla::WrapNone);
|
||||
sci->setTabWidth(4);
|
||||
sci->setIndentationsUseTabs(false);
|
||||
sci->SendScintilla(QsciScintillaBase::SCI_SETEXTRAASCENT, (long)2);
|
||||
sci->SendScintilla(QsciScintillaBase::SCI_SETEXTRADESCENT, (long)2);
|
||||
|
||||
// Line number margin
|
||||
sci->setMarginType(0, QsciScintilla::NumberMargin);
|
||||
sci->setMarginWidth(0, "00000");
|
||||
sci->setMarginsBackgroundColor(QColor("#252526"));
|
||||
sci->setMarginsForegroundColor(QColor("#858585"));
|
||||
sci->setMarginsFont(f);
|
||||
|
||||
sci->setMarginWidth(1, 0);
|
||||
sci->setMarginWidth(2, 0);
|
||||
|
||||
// Lexer FIRST — setLexer() resets caret/selection/paper colors
|
||||
auto* lexer = new QsciLexerCPP(sci);
|
||||
lexer->setFont(f);
|
||||
lexer->setColor(QColor("#569cd6"), QsciLexerCPP::Keyword);
|
||||
lexer->setColor(QColor("#569cd6"), QsciLexerCPP::KeywordSet2);
|
||||
lexer->setColor(QColor("#b5cea8"), QsciLexerCPP::Number);
|
||||
lexer->setColor(QColor("#ce9178"), QsciLexerCPP::DoubleQuotedString);
|
||||
lexer->setColor(QColor("#ce9178"), QsciLexerCPP::SingleQuotedString);
|
||||
lexer->setColor(QColor("#6a9955"), QsciLexerCPP::Comment);
|
||||
lexer->setColor(QColor("#6a9955"), QsciLexerCPP::CommentLine);
|
||||
lexer->setColor(QColor("#6a9955"), QsciLexerCPP::CommentDoc);
|
||||
lexer->setColor(QColor("#d4d4d4"), QsciLexerCPP::Default);
|
||||
lexer->setColor(QColor("#d4d4d4"), QsciLexerCPP::Identifier);
|
||||
lexer->setColor(QColor("#c586c0"), QsciLexerCPP::PreProcessor);
|
||||
lexer->setColor(QColor("#d4d4d4"), QsciLexerCPP::Operator);
|
||||
for (int i = 0; i <= 127; i++) {
|
||||
lexer->setPaper(QColor("#1e1e1e"), i);
|
||||
lexer->setFont(f, i);
|
||||
}
|
||||
sci->setLexer(lexer);
|
||||
sci->setBraceMatching(QsciScintilla::NoBraceMatch);
|
||||
|
||||
// Colors AFTER setLexer() — the lexer resets these on attach
|
||||
sci->setPaper(QColor("#1e1e1e"));
|
||||
sci->setColor(QColor("#d4d4d4"));
|
||||
sci->setCaretForegroundColor(QColor("#d4d4d4"));
|
||||
sci->setCaretLineVisible(true);
|
||||
sci->setCaretLineBackgroundColor(QColor(43, 43, 43));
|
||||
sci->setSelectionBackgroundColor(QColor("#264f78"));
|
||||
sci->setSelectionForegroundColor(QColor("#d4d4d4"));
|
||||
}
|
||||
|
||||
// ── Test tree helper ──
|
||||
|
||||
static rcx::NodeTree makeTestTree() {
|
||||
rcx::NodeTree tree;
|
||||
rcx::Node root;
|
||||
root.kind = rcx::NodeKind::Struct;
|
||||
root.name = "TestStruct";
|
||||
root.structTypeName = "TestStruct";
|
||||
root.parentId = 0;
|
||||
root.offset = 0;
|
||||
int ri = tree.addNode(root);
|
||||
uint64_t rootId = tree.nodes[ri].id;
|
||||
|
||||
rcx::Node f1;
|
||||
f1.kind = rcx::NodeKind::Int32;
|
||||
f1.name = "health";
|
||||
f1.parentId = rootId;
|
||||
f1.offset = 0;
|
||||
tree.addNode(f1);
|
||||
|
||||
rcx::Node f2;
|
||||
f2.kind = rcx::NodeKind::Float;
|
||||
f2.name = "speed";
|
||||
f2.parentId = rootId;
|
||||
f2.offset = 4;
|
||||
tree.addNode(f2);
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
||||
// ── Test class ──
|
||||
|
||||
class TestRenderedView : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
|
||||
// ── Verify caret line background is NOT yellow after setup ──
|
||||
|
||||
void testCaretLineBackgroundNotYellow() {
|
||||
QsciScintilla sci;
|
||||
setupRenderedSci(&sci);
|
||||
sci.show();
|
||||
sci.setText("struct Foo {\n int x;\n};\n");
|
||||
QTest::qWait(50);
|
||||
|
||||
long bgr = sci.SendScintilla(QsciScintillaBase::SCI_GETCARETLINEBACK);
|
||||
long expected = toBGR(QColor(43, 43, 43));
|
||||
|
||||
// Yellow would be 0x00FFFF or similar high-value — ours should be dark
|
||||
long yellow = toBGR(QColor(255, 255, 0));
|
||||
QVERIFY2(bgr != yellow,
|
||||
qPrintable(QString("Caret line is yellow (0x%1), expected dark (0x%2)")
|
||||
.arg(bgr, 6, 16, QChar('0'))
|
||||
.arg(expected, 6, 16, QChar('0'))));
|
||||
QCOMPARE(bgr, expected);
|
||||
}
|
||||
|
||||
// ── Verify caret line is enabled ──
|
||||
|
||||
void testCaretLineEnabled() {
|
||||
QsciScintilla sci;
|
||||
setupRenderedSci(&sci);
|
||||
|
||||
long visible = sci.SendScintilla(QsciScintillaBase::SCI_GETCARETLINEVISIBLE);
|
||||
QCOMPARE(visible, (long)1);
|
||||
}
|
||||
|
||||
// ── Verify editor background (paper) is dark ──
|
||||
|
||||
void testPaperColor() {
|
||||
QsciScintilla sci;
|
||||
setupRenderedSci(&sci);
|
||||
|
||||
// Query default style background via Scintilla
|
||||
long bgr = sci.SendScintilla(QsciScintillaBase::SCI_STYLEGETBACK,
|
||||
(unsigned long)0 /*STYLE_DEFAULT*/);
|
||||
long expected = toBGR(QColor("#1e1e1e"));
|
||||
QCOMPARE(bgr, expected);
|
||||
}
|
||||
|
||||
// ── Verify caret (cursor) foreground color ──
|
||||
|
||||
void testCaretForegroundColor() {
|
||||
QsciScintilla sci;
|
||||
setupRenderedSci(&sci);
|
||||
|
||||
long bgr = sci.SendScintilla(QsciScintillaBase::SCI_GETCARETFORE);
|
||||
long expected = toBGR(QColor("#d4d4d4"));
|
||||
QCOMPARE(bgr, expected);
|
||||
}
|
||||
|
||||
// ── Verify selection colors are set (no direct Scintilla getter, but we can
|
||||
// verify they survive a round-trip through the SCI_SETSEL* messages by
|
||||
// checking the element colour API introduced in Scintilla 5.x) ──
|
||||
|
||||
void testSelectionColorsApplied() {
|
||||
QsciScintilla sci;
|
||||
setupRenderedSci(&sci);
|
||||
sci.show();
|
||||
sci.setText("int x = 42;\n");
|
||||
QTest::qWait(50);
|
||||
|
||||
// Select text and verify rendering doesn't crash
|
||||
sci.SendScintilla(QsciScintillaBase::SCI_SETSEL, (unsigned long)0, (long)3);
|
||||
QTest::qWait(50);
|
||||
|
||||
// SCI_GETELEMENTCOLOUR (element 10 = SC_ELEMENT_SELECTION_BACK) returns
|
||||
// the selection back colour on Scintilla >= 5.2. If not available, fall
|
||||
// back to verifying the calls didn't throw and caret line is still correct.
|
||||
constexpr int SCI_GETELEMENTCOLOUR = 2753;
|
||||
constexpr int SC_ELEMENT_SELECTION_BACK = 10;
|
||||
|
||||
long selBack = sci.SendScintilla(SCI_GETELEMENTCOLOUR,
|
||||
(unsigned long)SC_ELEMENT_SELECTION_BACK);
|
||||
if (selBack != 0) {
|
||||
// Scintilla 5.x: colour stored as 0xAABBGGRR (with alpha in high byte)
|
||||
long bgrMask = selBack & 0x00FFFFFF;
|
||||
long expected = toBGR(QColor("#264f78"));
|
||||
QCOMPARE(bgrMask, expected);
|
||||
} else {
|
||||
// Older Scintilla: just verify caret line is still correct as a proxy
|
||||
long caretBg = sci.SendScintilla(QsciScintillaBase::SCI_GETCARETLINEBACK);
|
||||
long expected = toBGR(QColor(43, 43, 43));
|
||||
QCOMPARE(caretBg, expected);
|
||||
}
|
||||
}
|
||||
|
||||
// ── Verify lexer keyword color is VS Code blue, not default ──
|
||||
|
||||
void testKeywordColor() {
|
||||
QsciScintilla sci;
|
||||
setupRenderedSci(&sci);
|
||||
|
||||
auto* lexer = qobject_cast<QsciLexerCPP*>(sci.lexer());
|
||||
QVERIFY(lexer != nullptr);
|
||||
|
||||
QColor kw = lexer->color(QsciLexerCPP::Keyword);
|
||||
QCOMPARE(kw, QColor("#569cd6"));
|
||||
}
|
||||
|
||||
// ── Verify comment color is VS Code green ──
|
||||
|
||||
void testCommentColor() {
|
||||
QsciScintilla sci;
|
||||
setupRenderedSci(&sci);
|
||||
|
||||
auto* lexer = qobject_cast<QsciLexerCPP*>(sci.lexer());
|
||||
QVERIFY(lexer != nullptr);
|
||||
|
||||
QCOMPARE(lexer->color(QsciLexerCPP::Comment), QColor("#6a9955"));
|
||||
QCOMPARE(lexer->color(QsciLexerCPP::CommentLine), QColor("#6a9955"));
|
||||
}
|
||||
|
||||
// ── Verify number color is VS Code light green ──
|
||||
|
||||
void testNumberColor() {
|
||||
QsciScintilla sci;
|
||||
setupRenderedSci(&sci);
|
||||
|
||||
auto* lexer = qobject_cast<QsciLexerCPP*>(sci.lexer());
|
||||
QVERIFY(lexer != nullptr);
|
||||
|
||||
QCOMPARE(lexer->color(QsciLexerCPP::Number), QColor("#b5cea8"));
|
||||
}
|
||||
|
||||
// ── Verify string color is VS Code orange ──
|
||||
|
||||
void testStringColor() {
|
||||
QsciScintilla sci;
|
||||
setupRenderedSci(&sci);
|
||||
|
||||
auto* lexer = qobject_cast<QsciLexerCPP*>(sci.lexer());
|
||||
QVERIFY(lexer != nullptr);
|
||||
|
||||
QCOMPARE(lexer->color(QsciLexerCPP::DoubleQuotedString), QColor("#ce9178"));
|
||||
QCOMPARE(lexer->color(QsciLexerCPP::SingleQuotedString), QColor("#ce9178"));
|
||||
}
|
||||
|
||||
// ── Verify preprocessor color is VS Code purple ──
|
||||
|
||||
void testPreprocessorColor() {
|
||||
QsciScintilla sci;
|
||||
setupRenderedSci(&sci);
|
||||
|
||||
auto* lexer = qobject_cast<QsciLexerCPP*>(sci.lexer());
|
||||
QVERIFY(lexer != nullptr);
|
||||
|
||||
QCOMPARE(lexer->color(QsciLexerCPP::PreProcessor), QColor("#c586c0"));
|
||||
}
|
||||
|
||||
// ── Verify default/identifier text color ──
|
||||
|
||||
void testDefaultTextColor() {
|
||||
QsciScintilla sci;
|
||||
setupRenderedSci(&sci);
|
||||
|
||||
auto* lexer = qobject_cast<QsciLexerCPP*>(sci.lexer());
|
||||
QVERIFY(lexer != nullptr);
|
||||
|
||||
QCOMPARE(lexer->color(QsciLexerCPP::Default), QColor("#d4d4d4"));
|
||||
QCOMPARE(lexer->color(QsciLexerCPP::Identifier), QColor("#d4d4d4"));
|
||||
QCOMPARE(lexer->color(QsciLexerCPP::Operator), QColor("#d4d4d4"));
|
||||
}
|
||||
|
||||
// ── Verify all 128 lexer styles have dark paper ──
|
||||
|
||||
void testAllStylesHaveDarkPaper() {
|
||||
QsciScintilla sci;
|
||||
setupRenderedSci(&sci);
|
||||
|
||||
auto* lexer = qobject_cast<QsciLexerCPP*>(sci.lexer());
|
||||
QVERIFY(lexer != nullptr);
|
||||
|
||||
QColor expected("#1e1e1e");
|
||||
for (int i = 0; i <= 127; i++) {
|
||||
QColor paper = lexer->paper(i);
|
||||
QVERIFY2(paper == expected,
|
||||
qPrintable(QString("Style %1 paper is %2, expected %3")
|
||||
.arg(i).arg(paper.name()).arg(expected.name())));
|
||||
}
|
||||
}
|
||||
|
||||
// ── Verify margin colors match dark theme ──
|
||||
|
||||
void testMarginColors() {
|
||||
QsciScintilla sci;
|
||||
setupRenderedSci(&sci);
|
||||
|
||||
// Query margin background via Scintilla (style 33 = STYLE_LINENUMBER)
|
||||
long marginBg = sci.SendScintilla(QsciScintillaBase::SCI_STYLEGETBACK,
|
||||
(unsigned long)33);
|
||||
long expectedBg = toBGR(QColor("#252526"));
|
||||
QCOMPARE(marginBg, expectedBg);
|
||||
|
||||
long marginFg = sci.SendScintilla(QsciScintillaBase::SCI_STYLEGETFORE,
|
||||
(unsigned long)33);
|
||||
long expectedFg = toBGR(QColor("#858585"));
|
||||
QCOMPARE(marginFg, expectedFg);
|
||||
}
|
||||
|
||||
// ── End-to-end: generate C++ and load into rendered view ──
|
||||
|
||||
void testGeneratedCodeInRenderedView() {
|
||||
auto tree = makeTestTree();
|
||||
uint64_t rootId = tree.nodes[0].id;
|
||||
QString code = rcx::renderCpp(tree, rootId);
|
||||
|
||||
// Verify generated code has no pragma pack / cstdint
|
||||
QVERIFY(!code.contains("#pragma pack"));
|
||||
QVERIFY(!code.contains("#include <cstdint>"));
|
||||
QVERIFY(code.contains("#pragma once"));
|
||||
QVERIFY(code.contains("struct TestStruct {"));
|
||||
|
||||
// Load into rendered sci and verify colors survive
|
||||
QsciScintilla sci;
|
||||
setupRenderedSci(&sci);
|
||||
sci.show();
|
||||
sci.setText(code);
|
||||
QTest::qWait(100);
|
||||
|
||||
// Caret line must still be dark after text load
|
||||
long caretBg = sci.SendScintilla(QsciScintillaBase::SCI_GETCARETLINEBACK);
|
||||
long expected = toBGR(QColor(43, 43, 43));
|
||||
QCOMPARE(caretBg, expected);
|
||||
|
||||
// Paper must still be dark
|
||||
long paperBg = sci.SendScintilla(QsciScintillaBase::SCI_STYLEGETBACK,
|
||||
(unsigned long)0);
|
||||
QCOMPARE(paperBg, toBGR(QColor("#1e1e1e")));
|
||||
}
|
||||
|
||||
// ── Verify brace matching is disabled ──
|
||||
|
||||
void testBraceMatchDisabled() {
|
||||
QsciScintilla sci;
|
||||
setupRenderedSci(&sci);
|
||||
|
||||
QCOMPARE(sci.braceMatching(), QsciScintilla::NoBraceMatch);
|
||||
}
|
||||
};
|
||||
|
||||
QTEST_MAIN(TestRenderedView)
|
||||
#include "test_rendered_view.moc"
|
||||
Reference in New Issue
Block a user