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()),
|
||||
this, SLOT(reloadFullStack()));
|
||||
connect(theDebuggerAction(MaximalStackDepth), SIGNAL(triggered()),
|
||||
this, SLOT(reloadFullStack()));
|
||||
}
|
||||
|
||||
void GdbEngine::initializeVariables()
|
||||
|
@@ -278,9 +278,9 @@ public:
|
||||
typedef QTextCursor::MoveMode MoveMode;
|
||||
void moveToEndOfDocument() { m_tc.movePosition(EndOfDocument, MoveAnchor); }
|
||||
void moveToStartOfLine() { m_tc.movePosition(StartOfLine, MoveAnchor); }
|
||||
void moveToEndOfLine() { m_tc.movePosition(EndOfLine, MoveAnchor); }
|
||||
void moveUp(int n = 1) { m_tc.movePosition(Up, MoveAnchor, n); }
|
||||
void moveDown(int n = 1) { m_tc.movePosition(Down, MoveAnchor, n); }
|
||||
void moveToEndOfLine();
|
||||
void moveUp(int n = 1) { moveDown(-n); }
|
||||
void moveDown(int n = 1); // { m_tc.movePosition(Down, 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 setAnchor() { m_anchor = m_tc.position(); }
|
||||
@@ -289,7 +289,7 @@ public:
|
||||
|
||||
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);
|
||||
void selectRange(int beginLine, int endLine);
|
||||
|
||||
@@ -351,7 +351,7 @@ public:
|
||||
bool m_needMoreUndo;
|
||||
|
||||
// extra data for '.'
|
||||
void replay(const QString &text);
|
||||
void replay(const QString &text, int count);
|
||||
QString m_dotCommand;
|
||||
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)
|
||||
{
|
||||
q = parent;
|
||||
|
||||
m_textedit = qobject_cast<QTextEdit *>(widget);
|
||||
m_plaintextedit = qobject_cast<QPlainTextEdit *>(widget);
|
||||
init();
|
||||
}
|
||||
|
||||
void FakeVimHandler::Private::init()
|
||||
{
|
||||
m_mode = CommandMode;
|
||||
m_submode = NoSubMode;
|
||||
m_subsubmode = NoSubSubMode;
|
||||
@@ -592,7 +595,6 @@ EventResult FakeVimHandler::Private::handleKey(int key, int unmodified,
|
||||
const QString &text)
|
||||
{
|
||||
//qDebug() << "KEY: " << key << text << "POS: " << m_tc.position();
|
||||
//qDebug() << "\nUNDO: " << m_undoStack << "\nREDO: " << m_redoStack;
|
||||
if (m_mode == InsertMode)
|
||||
return handleInsertMode(key, unmodified, text);
|
||||
if (m_mode == CommandMode)
|
||||
@@ -603,6 +605,26 @@ EventResult FakeVimHandler::Private::handleKey(int key, int unmodified,
|
||||
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)
|
||||
{
|
||||
//qDebug() << "ANCHOR: " << position() << anchor();
|
||||
@@ -1012,7 +1034,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
qDebug() << "REPEATING" << m_dotCommand;
|
||||
QString savedCommand = m_dotCommand;
|
||||
m_dotCommand.clear();
|
||||
replay(savedCommand);
|
||||
replay(savedCommand, count());
|
||||
enterCommandMode();
|
||||
m_dotCommand = savedCommand;
|
||||
} 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)
|
||||
{
|
||||
m_tc = EDITOR(textCursor());
|
||||
init();
|
||||
handleExCommand(cmd);
|
||||
EDITOR(setTextCursor(m_tc));
|
||||
}
|
||||
@@ -1780,7 +1803,8 @@ void FakeVimHandler::Private::handleExCommand(const QString &cmd0)
|
||||
updateMiniBuffer();
|
||||
} else if (reNormal.indexIn(cmd) != -1) { // :normal
|
||||
enterCommandMode();
|
||||
replay(reNormal.cap(3));
|
||||
//qDebug() << "REPLAY: " << reNormal.cap(3);
|
||||
replay(reNormal.cap(3), 1);
|
||||
} else if (reSet.indexIn(cmd) != -1) { // :set
|
||||
showBlackMessage(QString());
|
||||
QString arg = reSet.cap(2);
|
||||
@@ -2353,11 +2377,11 @@ void FakeVimHandler::Private::handleStartOfLine()
|
||||
moveToFirstNonBlankOnLine();
|
||||
}
|
||||
|
||||
void FakeVimHandler::Private::replay(const QString &command)
|
||||
void FakeVimHandler::Private::replay(const QString &command, int n)
|
||||
{
|
||||
//qDebug() << "REPLAY: " << command;
|
||||
m_inReplay = true;
|
||||
for (int i = count(); --i >= 0; )
|
||||
for (int i = n; --i >= 0; )
|
||||
foreach (QChar c, command)
|
||||
handleKey(c.unicode(), c.unicode(), QString(c));
|
||||
m_inReplay = false;
|
||||
|
@@ -45,31 +45,35 @@ class tst_FakeVim : public QObject
|
||||
public:
|
||||
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:
|
||||
void changeStatusData(const QString &info) { m_statusData = info; }
|
||||
void changeStatusMessage(const QString &info) { m_statusMessage = info; }
|
||||
void changeExtraInformation(const QString &info) { m_infoMessage = info; }
|
||||
|
||||
public:
|
||||
QString m_statusMessage;
|
||||
QString m_statusData;
|
||||
QString m_infoMessage;
|
||||
|
||||
private slots:
|
||||
void commandI();
|
||||
void commandDollar();
|
||||
void commandDown();
|
||||
void commandUp();
|
||||
|
||||
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;
|
||||
FakeVimHandler m_handler;
|
||||
QList<QTextEdit::ExtraSelection> m_selection;
|
||||
|
||||
QString m_statusMessage;
|
||||
QString m_statusData;
|
||||
QString m_infoMessage;
|
||||
|
||||
static const QString lines;
|
||||
static const QString escape;
|
||||
};
|
||||
@@ -91,7 +95,6 @@ const QString tst_FakeVim::escape = QChar(27);
|
||||
tst_FakeVim::tst_FakeVim()
|
||||
: m_handler(&m_editor, this)
|
||||
{
|
||||
|
||||
QObject::connect(&m_handler, SIGNAL(commandBufferChanged(QString)),
|
||||
this, SLOT(changeStatusMessage(QString)));
|
||||
QObject::connect(&m_handler, SIGNAL(extraInformationChanged(QString)),
|
||||
@@ -106,6 +109,12 @@ void tst_FakeVim::setup()
|
||||
m_statusData.clear();
|
||||
m_infoMessage.clear();
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -119,75 +128,118 @@ void tst_FakeVim::sendEx(const QString &command)
|
||||
m_handler.handleCommand(command);
|
||||
}
|
||||
|
||||
#define checkContents(wanted) \
|
||||
do { QString want = cleaned(wanted); \
|
||||
QString got = m_editor.toPlainText(); \
|
||||
QStringList wantlist = want.split('\n'); \
|
||||
QStringList gotlist = got.split('\n'); \
|
||||
QCOMPARE(gotlist.size(), wantlist.size()); \
|
||||
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)); \
|
||||
QCOMPARE(g, w); \
|
||||
} \
|
||||
} while (0)
|
||||
bool tst_FakeVim::checkContentsHelper(QString want, const char* file, int line)
|
||||
{
|
||||
QString got = m_editor.toPlainText();
|
||||
int pos = m_editor.textCursor().position();
|
||||
got = got.left(pos) + "@" + got.mid(pos);
|
||||
QStringList wantlist = want.split('\n');
|
||||
QStringList gotlist = got.split('\n');
|
||||
if (!QTest::qCompare(gotlist.size(), wantlist.size(), "", "", file, line)) {
|
||||
qDebug() << "WANT: " << want;
|
||||
qDebug() << "GOT: " << got;
|
||||
return false;
|
||||
}
|
||||
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) \
|
||||
do { \
|
||||
send(cmd); \
|
||||
checkContents(wanted); \
|
||||
int p = (wanted).indexOf('$'); \
|
||||
QCOMPARE(m_editor.textCursor().position(), p); \
|
||||
} while (0)
|
||||
bool tst_FakeVim::checkHelper(bool ex, QString cmd, QString expected,
|
||||
const char *file, int line)
|
||||
{
|
||||
if (ex)
|
||||
sendEx(cmd);
|
||||
else
|
||||
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) \
|
||||
do { \
|
||||
send(cmd); \
|
||||
QCOMPARE(m_editor.textCursor().position(), pos); \
|
||||
} while (0)
|
||||
#define checkContents(expected) \
|
||||
do { if (!checkContentsHelper(expected, __FILE__, __LINE__)) return; } while (0)
|
||||
|
||||
// Runs a "normal" command and checks the result.
|
||||
// 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()
|
||||
{
|
||||
return;
|
||||
setup();
|
||||
|
||||
// empty insertion at start of document
|
||||
checkText("i" + escape, "$" + lines);
|
||||
checkText("u", "$" + lines);
|
||||
check("i" + escape, "@" + lines);
|
||||
check("u", "@" + lines);
|
||||
|
||||
// small insertion at start of document
|
||||
checkText("ix" + escape, "$x" + lines);
|
||||
checkText("u", "$" + lines);
|
||||
check("ix" + escape, "@x" + lines);
|
||||
check("u", "@" + lines);
|
||||
|
||||
// small insertion at start of document
|
||||
checkText("ixxx" + escape, "xx$x" + lines);
|
||||
checkText("u", "$" + lines);
|
||||
check("ixxx" + escape, "xx@x" + lines);
|
||||
check("u", "@" + lines);
|
||||
|
||||
// combine insertions
|
||||
checkText("ia" + escape, "$a" + lines);
|
||||
checkText("ibx" + escape, "b$xa" + lines);
|
||||
checkText("icyy" + escape, "bcy$yxa" + lines);
|
||||
checkText("u", "b$xa" + lines);
|
||||
checkText("u", "$a" + lines); // undo broken
|
||||
checkTextEx("redo", "b$xa" + lines);
|
||||
checkText("u", "$a" + lines);
|
||||
checkText("u", "$" + lines);
|
||||
check("ia" + escape, "@a" + lines);
|
||||
check("ibx" + escape, "b@xa" + lines);
|
||||
check("icyy" + escape, "bcy@yxa" + lines);
|
||||
check("u", "b@xa" + lines);
|
||||
check("u", "@a" + lines); // undo broken
|
||||
checkEx("redo", "b@xa" + lines);
|
||||
check("u", "@a" + lines);
|
||||
check("u", "@" + lines);
|
||||
}
|
||||
|
||||
void tst_FakeVim::commandDollar()
|
||||
{
|
||||
setup();
|
||||
checkPosition("$", 0);
|
||||
checkPosition("j", 2);
|
||||
check("j$", insertCursor("<QtCore>@"));
|
||||
//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)
|
||||
|
||||
|
Reference in New Issue
Block a user