forked from qt-creator/qt-creator
fakevim: work on autotests
This commit is contained in:
@@ -233,6 +233,8 @@ void GdbEngine::initializeConnections()
|
|||||||
|
|
||||||
connect(theDebuggerAction(ExpandStack), SIGNAL(triggered()),
|
connect(theDebuggerAction(ExpandStack), SIGNAL(triggered()),
|
||||||
this, SLOT(reloadFullStack()));
|
this, SLOT(reloadFullStack()));
|
||||||
|
connect(theDebuggerAction(MaximalStackDepth), SIGNAL(triggered()),
|
||||||
|
this, SLOT(reloadFullStack()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdbEngine::initializeVariables()
|
void GdbEngine::initializeVariables()
|
||||||
|
@@ -278,9 +278,9 @@ public:
|
|||||||
typedef QTextCursor::MoveMode MoveMode;
|
typedef QTextCursor::MoveMode MoveMode;
|
||||||
void moveToEndOfDocument() { m_tc.movePosition(EndOfDocument, MoveAnchor); }
|
void moveToEndOfDocument() { m_tc.movePosition(EndOfDocument, MoveAnchor); }
|
||||||
void moveToStartOfLine() { m_tc.movePosition(StartOfLine, MoveAnchor); }
|
void moveToStartOfLine() { m_tc.movePosition(StartOfLine, MoveAnchor); }
|
||||||
void moveToEndOfLine() { m_tc.movePosition(EndOfLine, MoveAnchor); }
|
void moveToEndOfLine();
|
||||||
void moveUp(int n = 1) { m_tc.movePosition(Up, MoveAnchor, n); }
|
void moveUp(int n = 1) { moveDown(-n); }
|
||||||
void moveDown(int n = 1) { m_tc.movePosition(Down, MoveAnchor, n); }
|
void moveDown(int n = 1); // { m_tc.movePosition(Down, MoveAnchor, n); }
|
||||||
void moveRight(int n = 1) { m_tc.movePosition(Right, MoveAnchor, n); }
|
void moveRight(int n = 1) { m_tc.movePosition(Right, MoveAnchor, n); }
|
||||||
void moveLeft(int n = 1) { m_tc.movePosition(Left, MoveAnchor, n); }
|
void moveLeft(int n = 1) { m_tc.movePosition(Left, MoveAnchor, n); }
|
||||||
void setAnchor() { m_anchor = m_tc.position(); }
|
void setAnchor() { m_anchor = m_tc.position(); }
|
||||||
@@ -289,7 +289,7 @@ public:
|
|||||||
|
|
||||||
void handleFfTt(int key);
|
void handleFfTt(int key);
|
||||||
|
|
||||||
// helper function for handleCommand. return 1 based line index.
|
// helper function for handleExCommand. return 1 based line index.
|
||||||
int readLineCode(QString &cmd);
|
int readLineCode(QString &cmd);
|
||||||
void selectRange(int beginLine, int endLine);
|
void selectRange(int beginLine, int endLine);
|
||||||
|
|
||||||
@@ -351,7 +351,7 @@ public:
|
|||||||
bool m_needMoreUndo;
|
bool m_needMoreUndo;
|
||||||
|
|
||||||
// extra data for '.'
|
// extra data for '.'
|
||||||
void replay(const QString &text);
|
void replay(const QString &text, int count);
|
||||||
QString m_dotCommand;
|
QString m_dotCommand;
|
||||||
bool m_inReplay; // true if we are executing a '.'
|
bool m_inReplay; // true if we are executing a '.'
|
||||||
|
|
||||||
@@ -411,10 +411,13 @@ QStringList FakeVimHandler::Private::m_commandHistory;
|
|||||||
FakeVimHandler::Private::Private(FakeVimHandler *parent, QWidget *widget)
|
FakeVimHandler::Private::Private(FakeVimHandler *parent, QWidget *widget)
|
||||||
{
|
{
|
||||||
q = parent;
|
q = parent;
|
||||||
|
|
||||||
m_textedit = qobject_cast<QTextEdit *>(widget);
|
m_textedit = qobject_cast<QTextEdit *>(widget);
|
||||||
m_plaintextedit = qobject_cast<QPlainTextEdit *>(widget);
|
m_plaintextedit = qobject_cast<QPlainTextEdit *>(widget);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FakeVimHandler::Private::init()
|
||||||
|
{
|
||||||
m_mode = CommandMode;
|
m_mode = CommandMode;
|
||||||
m_submode = NoSubMode;
|
m_submode = NoSubMode;
|
||||||
m_subsubmode = NoSubSubMode;
|
m_subsubmode = NoSubSubMode;
|
||||||
@@ -592,7 +595,6 @@ EventResult FakeVimHandler::Private::handleKey(int key, int unmodified,
|
|||||||
const QString &text)
|
const QString &text)
|
||||||
{
|
{
|
||||||
//qDebug() << "KEY: " << key << text << "POS: " << m_tc.position();
|
//qDebug() << "KEY: " << key << text << "POS: " << m_tc.position();
|
||||||
//qDebug() << "\nUNDO: " << m_undoStack << "\nREDO: " << m_redoStack;
|
|
||||||
if (m_mode == InsertMode)
|
if (m_mode == InsertMode)
|
||||||
return handleInsertMode(key, unmodified, text);
|
return handleInsertMode(key, unmodified, text);
|
||||||
if (m_mode == CommandMode)
|
if (m_mode == CommandMode)
|
||||||
@@ -603,6 +605,26 @@ EventResult FakeVimHandler::Private::handleKey(int key, int unmodified,
|
|||||||
return EventUnhandled;
|
return EventUnhandled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FakeVimHandler::Private::moveDown(int n)
|
||||||
|
{
|
||||||
|
// m_tc.movePosition(Down, MoveAnchor, n); does not work for "hidden"
|
||||||
|
// documents like in the autotests
|
||||||
|
const QTextBlock &block = m_tc.block();
|
||||||
|
const int col = m_tc.position() - block.position();
|
||||||
|
const int line = block.blockNumber();
|
||||||
|
const int pos = m_tc.document()->findBlockByNumber(line + n).position();
|
||||||
|
setPosition(pos + qMin(block.length(), col));
|
||||||
|
setPosition(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FakeVimHandler::Private::moveToEndOfLine()
|
||||||
|
{
|
||||||
|
// m_tc.movePosition(EndOfLine, MoveAnchor) does not work for "hidden"
|
||||||
|
// documents like in the autotests
|
||||||
|
const QTextBlock &block = m_tc.block();
|
||||||
|
setPosition(block.position() + block.length() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
void FakeVimHandler::Private::finishMovement(const QString &dotCommand)
|
void FakeVimHandler::Private::finishMovement(const QString &dotCommand)
|
||||||
{
|
{
|
||||||
//qDebug() << "ANCHOR: " << position() << anchor();
|
//qDebug() << "ANCHOR: " << position() << anchor();
|
||||||
@@ -1012,7 +1034,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
|||||||
qDebug() << "REPEATING" << m_dotCommand;
|
qDebug() << "REPEATING" << m_dotCommand;
|
||||||
QString savedCommand = m_dotCommand;
|
QString savedCommand = m_dotCommand;
|
||||||
m_dotCommand.clear();
|
m_dotCommand.clear();
|
||||||
replay(savedCommand);
|
replay(savedCommand, count());
|
||||||
enterCommandMode();
|
enterCommandMode();
|
||||||
m_dotCommand = savedCommand;
|
m_dotCommand = savedCommand;
|
||||||
} else if (key == '<' && m_visualMode == NoVisualMode) {
|
} else if (key == '<' && m_visualMode == NoVisualMode) {
|
||||||
@@ -1647,6 +1669,7 @@ void FakeVimHandler::Private::selectRange(int beginLine, int endLine)
|
|||||||
void FakeVimHandler::Private::handleCommand(const QString &cmd)
|
void FakeVimHandler::Private::handleCommand(const QString &cmd)
|
||||||
{
|
{
|
||||||
m_tc = EDITOR(textCursor());
|
m_tc = EDITOR(textCursor());
|
||||||
|
init();
|
||||||
handleExCommand(cmd);
|
handleExCommand(cmd);
|
||||||
EDITOR(setTextCursor(m_tc));
|
EDITOR(setTextCursor(m_tc));
|
||||||
}
|
}
|
||||||
@@ -1780,7 +1803,8 @@ void FakeVimHandler::Private::handleExCommand(const QString &cmd0)
|
|||||||
updateMiniBuffer();
|
updateMiniBuffer();
|
||||||
} else if (reNormal.indexIn(cmd) != -1) { // :normal
|
} else if (reNormal.indexIn(cmd) != -1) { // :normal
|
||||||
enterCommandMode();
|
enterCommandMode();
|
||||||
replay(reNormal.cap(3));
|
//qDebug() << "REPLAY: " << reNormal.cap(3);
|
||||||
|
replay(reNormal.cap(3), 1);
|
||||||
} else if (reSet.indexIn(cmd) != -1) { // :set
|
} else if (reSet.indexIn(cmd) != -1) { // :set
|
||||||
showBlackMessage(QString());
|
showBlackMessage(QString());
|
||||||
QString arg = reSet.cap(2);
|
QString arg = reSet.cap(2);
|
||||||
@@ -2353,11 +2377,11 @@ void FakeVimHandler::Private::handleStartOfLine()
|
|||||||
moveToFirstNonBlankOnLine();
|
moveToFirstNonBlankOnLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeVimHandler::Private::replay(const QString &command)
|
void FakeVimHandler::Private::replay(const QString &command, int n)
|
||||||
{
|
{
|
||||||
//qDebug() << "REPLAY: " << command;
|
//qDebug() << "REPLAY: " << command;
|
||||||
m_inReplay = true;
|
m_inReplay = true;
|
||||||
for (int i = count(); --i >= 0; )
|
for (int i = n; --i >= 0; )
|
||||||
foreach (QChar c, command)
|
foreach (QChar c, command)
|
||||||
handleKey(c.unicode(), c.unicode(), QString(c));
|
handleKey(c.unicode(), c.unicode(), QString(c));
|
||||||
m_inReplay = false;
|
m_inReplay = false;
|
||||||
|
@@ -45,31 +45,35 @@ class tst_FakeVim : public QObject
|
|||||||
public:
|
public:
|
||||||
tst_FakeVim();
|
tst_FakeVim();
|
||||||
|
|
||||||
void setup();
|
|
||||||
void send(const QString &command); // send a normal command
|
|
||||||
void sendEx(const QString &command); // send an ex command
|
|
||||||
|
|
||||||
QString cleaned(QString wanted) { wanted.remove('$'); return wanted; }
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void changeStatusData(const QString &info) { m_statusData = info; }
|
void changeStatusData(const QString &info) { m_statusData = info; }
|
||||||
void changeStatusMessage(const QString &info) { m_statusMessage = info; }
|
void changeStatusMessage(const QString &info) { m_statusMessage = info; }
|
||||||
void changeExtraInformation(const QString &info) { m_infoMessage = info; }
|
void changeExtraInformation(const QString &info) { m_infoMessage = info; }
|
||||||
|
|
||||||
public:
|
|
||||||
QString m_statusMessage;
|
|
||||||
QString m_statusData;
|
|
||||||
QString m_infoMessage;
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void commandI();
|
void commandI();
|
||||||
void commandDollar();
|
void commandDollar();
|
||||||
|
void commandDown();
|
||||||
|
void commandUp();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void setup();
|
||||||
|
void send(const QString &command); // send a normal command
|
||||||
|
void sendEx(const QString &command); // send an ex command
|
||||||
|
|
||||||
|
bool checkContentsHelper(QString expected, const char* file, int line);
|
||||||
|
bool checkHelper(bool isExCommand, QString cmd, QString expected,
|
||||||
|
const char* file, int line);
|
||||||
|
QString insertCursor(const QString &needle0);
|
||||||
|
|
||||||
QPlainTextEdit m_editor;
|
QPlainTextEdit m_editor;
|
||||||
FakeVimHandler m_handler;
|
FakeVimHandler m_handler;
|
||||||
QList<QTextEdit::ExtraSelection> m_selection;
|
QList<QTextEdit::ExtraSelection> m_selection;
|
||||||
|
|
||||||
|
QString m_statusMessage;
|
||||||
|
QString m_statusData;
|
||||||
|
QString m_infoMessage;
|
||||||
|
|
||||||
static const QString lines;
|
static const QString lines;
|
||||||
static const QString escape;
|
static const QString escape;
|
||||||
};
|
};
|
||||||
@@ -91,7 +95,6 @@ const QString tst_FakeVim::escape = QChar(27);
|
|||||||
tst_FakeVim::tst_FakeVim()
|
tst_FakeVim::tst_FakeVim()
|
||||||
: m_handler(&m_editor, this)
|
: m_handler(&m_editor, this)
|
||||||
{
|
{
|
||||||
|
|
||||||
QObject::connect(&m_handler, SIGNAL(commandBufferChanged(QString)),
|
QObject::connect(&m_handler, SIGNAL(commandBufferChanged(QString)),
|
||||||
this, SLOT(changeStatusMessage(QString)));
|
this, SLOT(changeStatusMessage(QString)));
|
||||||
QObject::connect(&m_handler, SIGNAL(extraInformationChanged(QString)),
|
QObject::connect(&m_handler, SIGNAL(extraInformationChanged(QString)),
|
||||||
@@ -106,6 +109,12 @@ void tst_FakeVim::setup()
|
|||||||
m_statusData.clear();
|
m_statusData.clear();
|
||||||
m_infoMessage.clear();
|
m_infoMessage.clear();
|
||||||
m_editor.setPlainText(lines);
|
m_editor.setPlainText(lines);
|
||||||
|
QTextCursor tc = m_editor.textCursor();
|
||||||
|
tc.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor);
|
||||||
|
m_editor.setTextCursor(tc);
|
||||||
|
m_editor.setPlainText(lines);
|
||||||
|
//m_editor.show();
|
||||||
|
//qApp->exec();
|
||||||
QCOMPARE(m_editor.toPlainText(), lines);
|
QCOMPARE(m_editor.toPlainText(), lines);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,75 +128,118 @@ void tst_FakeVim::sendEx(const QString &command)
|
|||||||
m_handler.handleCommand(command);
|
m_handler.handleCommand(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define checkContents(wanted) \
|
bool tst_FakeVim::checkContentsHelper(QString want, const char* file, int line)
|
||||||
do { QString want = cleaned(wanted); \
|
{
|
||||||
QString got = m_editor.toPlainText(); \
|
QString got = m_editor.toPlainText();
|
||||||
QStringList wantlist = want.split('\n'); \
|
int pos = m_editor.textCursor().position();
|
||||||
QStringList gotlist = got.split('\n'); \
|
got = got.left(pos) + "@" + got.mid(pos);
|
||||||
QCOMPARE(gotlist.size(), wantlist.size()); \
|
QStringList wantlist = want.split('\n');
|
||||||
for (int i = 0; i < wantlist.size() && i < gotlist.size(); ++i) { \
|
QStringList gotlist = got.split('\n');
|
||||||
QString g = QString("line %1: %2").arg(i + 1).arg(gotlist.at(i)); \
|
if (!QTest::qCompare(gotlist.size(), wantlist.size(), "", "", file, line)) {
|
||||||
QString w = QString("line %1: %2").arg(i + 1).arg(wantlist.at(i)); \
|
qDebug() << "WANT: " << want;
|
||||||
QCOMPARE(g, w); \
|
qDebug() << "GOT: " << got;
|
||||||
} \
|
return false;
|
||||||
} while (0)
|
}
|
||||||
|
for (int i = 0; i < wantlist.size() && i < gotlist.size(); ++i) {
|
||||||
|
QString g = QString("line %1: %2").arg(i + 1).arg(gotlist.at(i));
|
||||||
|
QString w = QString("line %1: %2").arg(i + 1).arg(wantlist.at(i));
|
||||||
|
if (!QTest::qCompare(g, w, "", "", file, line)) {
|
||||||
|
qDebug() << "WANT: " << want;
|
||||||
|
qDebug() << "GOT: " << got;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#define checkText(cmd, wanted) \
|
bool tst_FakeVim::checkHelper(bool ex, QString cmd, QString expected,
|
||||||
do { \
|
const char *file, int line)
|
||||||
send(cmd); \
|
{
|
||||||
checkContents(wanted); \
|
if (ex)
|
||||||
int p = (wanted).indexOf('$'); \
|
sendEx(cmd);
|
||||||
QCOMPARE(m_editor.textCursor().position(), p); \
|
else
|
||||||
} while (0)
|
send(cmd);
|
||||||
|
return checkContentsHelper(expected, file, line);
|
||||||
|
}
|
||||||
|
|
||||||
#define checkTextEx(cmd, wanted) \
|
|
||||||
do { \
|
|
||||||
sendEx(cmd); \
|
|
||||||
checkContents(wanted); \
|
|
||||||
int p = (wanted).indexOf('$'); \
|
|
||||||
QCOMPARE(m_editor.textCursor().position(), p); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define checkPosition(cmd, pos) \
|
#define checkContents(expected) \
|
||||||
do { \
|
do { if (!checkContentsHelper(expected, __FILE__, __LINE__)) return; } while (0)
|
||||||
send(cmd); \
|
|
||||||
QCOMPARE(m_editor.textCursor().position(), pos); \
|
// Runs a "normal" command and checks the result.
|
||||||
} while (0)
|
// Cursor position is marked by a '@' in the expected contents.
|
||||||
|
#define check(cmd, expected) \
|
||||||
|
do { if (!checkHelper(false, cmd, expected, __FILE__, __LINE__)) \
|
||||||
|
return; } while (0)
|
||||||
|
|
||||||
|
// Runs an ex command and checks the result.
|
||||||
|
// Cursor position is marked by a '@' in the expected contents.
|
||||||
|
#define checkEx(cmd, expected) \
|
||||||
|
do { if (!checkHelper(true, cmd, expected, __FILE__, __LINE__)) \
|
||||||
|
return; } while (0)
|
||||||
|
|
||||||
|
QString tst_FakeVim::insertCursor(const QString &needle0)
|
||||||
|
{
|
||||||
|
QString needle = needle0;
|
||||||
|
needle.remove('@');
|
||||||
|
QString lines0 = lines;
|
||||||
|
lines0.replace(needle, needle0);
|
||||||
|
//qDebug() << "LINES: " << lines0;
|
||||||
|
return lines0;
|
||||||
|
}
|
||||||
|
|
||||||
void tst_FakeVim::commandI()
|
void tst_FakeVim::commandI()
|
||||||
{
|
{
|
||||||
|
return;
|
||||||
setup();
|
setup();
|
||||||
|
|
||||||
// empty insertion at start of document
|
// empty insertion at start of document
|
||||||
checkText("i" + escape, "$" + lines);
|
check("i" + escape, "@" + lines);
|
||||||
checkText("u", "$" + lines);
|
check("u", "@" + lines);
|
||||||
|
|
||||||
// small insertion at start of document
|
// small insertion at start of document
|
||||||
checkText("ix" + escape, "$x" + lines);
|
check("ix" + escape, "@x" + lines);
|
||||||
checkText("u", "$" + lines);
|
check("u", "@" + lines);
|
||||||
|
|
||||||
// small insertion at start of document
|
// small insertion at start of document
|
||||||
checkText("ixxx" + escape, "xx$x" + lines);
|
check("ixxx" + escape, "xx@x" + lines);
|
||||||
checkText("u", "$" + lines);
|
check("u", "@" + lines);
|
||||||
|
|
||||||
// combine insertions
|
// combine insertions
|
||||||
checkText("ia" + escape, "$a" + lines);
|
check("ia" + escape, "@a" + lines);
|
||||||
checkText("ibx" + escape, "b$xa" + lines);
|
check("ibx" + escape, "b@xa" + lines);
|
||||||
checkText("icyy" + escape, "bcy$yxa" + lines);
|
check("icyy" + escape, "bcy@yxa" + lines);
|
||||||
checkText("u", "b$xa" + lines);
|
check("u", "b@xa" + lines);
|
||||||
checkText("u", "$a" + lines); // undo broken
|
check("u", "@a" + lines); // undo broken
|
||||||
checkTextEx("redo", "b$xa" + lines);
|
checkEx("redo", "b@xa" + lines);
|
||||||
checkText("u", "$a" + lines);
|
check("u", "@a" + lines);
|
||||||
checkText("u", "$" + lines);
|
check("u", "@" + lines);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_FakeVim::commandDollar()
|
void tst_FakeVim::commandDollar()
|
||||||
{
|
{
|
||||||
setup();
|
setup();
|
||||||
checkPosition("$", 0);
|
check("j$", insertCursor("<QtCore>@"));
|
||||||
checkPosition("j", 2);
|
//check("j", insertCursor("<QtGui>@"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_FakeVim::commandDown()
|
||||||
|
{
|
||||||
|
setup();
|
||||||
|
check("j", insertCursor("@#include <QtCore"));
|
||||||
|
check("3j", insertCursor("@int main"));
|
||||||
|
check("4j", insertCursor("@ return app.exec()"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_FakeVim::commandUp()
|
||||||
|
{
|
||||||
|
setup();
|
||||||
|
check("j", insertCursor("@#include <QtCore"));
|
||||||
|
check("3j", insertCursor("@int main"));
|
||||||
|
check("4j", insertCursor("@ return app.exec()"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
QTEST_MAIN(tst_FakeVim)
|
QTEST_MAIN(tst_FakeVim)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user