Commit 48dcc26d authored by hjk's avatar hjk
Browse files

fakevim: work on autotests

parent 3e38a059
......@@ -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)
#define checkText(cmd, wanted) \
do { \
send(cmd); \
checkContents(wanted); \
int p = (wanted).indexOf('$'); \
QCOMPARE(m_editor.textCursor().position(), p); \
} while (0)
#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)
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;
}
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 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)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment