2009-02-25 09:15:00 +01:00
|
|
|
/**************************************************************************
|
2008-12-27 12:24:50 +01:00
|
|
|
**
|
|
|
|
|
** This file is part of Qt Creator
|
|
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
2008-12-27 12:24:50 +01:00
|
|
|
**
|
|
|
|
|
** Contact: Qt Software Information (qt-info@nokia.com)
|
|
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** Commercial Usage
|
2008-12-27 12:24:50 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
|
|
|
|
** accordance with the Qt Commercial License Agreement provided with the
|
|
|
|
|
** Software or, alternatively, in accordance with the terms contained in
|
|
|
|
|
** a written agreement between you and Nokia.
|
2008-12-27 12:24:50 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** GNU Lesser General Public License Usage
|
2008-12-27 12:24:50 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
|
|
|
|
** General Public License version 2.1 as published by the Free Software
|
|
|
|
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
|
|
|
|
** packaging of this file. Please review the following information to
|
|
|
|
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
|
|
|
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
2008-12-27 12:24:50 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** If you are unsure which license is appropriate for your use, please
|
|
|
|
|
** contact the sales department at qt-sales@nokia.com.
|
2008-12-27 12:24:50 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
**************************************************************************/
|
2008-12-27 12:24:50 +01:00
|
|
|
|
2009-04-06 09:55:57 +02:00
|
|
|
#include "fakevimhandler.h"
|
2008-12-27 12:24:50 +01:00
|
|
|
|
|
|
|
|
#include <QtCore/QSet>
|
2009-04-09 13:48:59 +02:00
|
|
|
|
|
|
|
|
#include <QtGui/QTextEdit>
|
2009-04-06 10:58:48 +02:00
|
|
|
#include <QtGui/QPlainTextEdit>
|
|
|
|
|
|
|
|
|
|
#include <QtTest/QtTest>
|
|
|
|
|
|
|
|
|
|
using namespace FakeVim;
|
|
|
|
|
using namespace FakeVim::Internal;
|
|
|
|
|
|
2009-04-09 14:43:04 +02:00
|
|
|
#define EDITOR(s) (m_textedit ? m_textedit->s : m_plaintextedit->s)
|
2008-12-27 12:24:50 +01:00
|
|
|
|
|
|
|
|
class tst_FakeVim : public QObject
|
|
|
|
|
{
|
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
2009-04-06 10:58:48 +02:00
|
|
|
public:
|
2009-04-09 14:43:04 +02:00
|
|
|
tst_FakeVim(bool);
|
|
|
|
|
~tst_FakeVim();
|
2009-04-06 10:58:48 +02:00
|
|
|
|
|
|
|
|
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; }
|
|
|
|
|
|
2008-12-27 12:24:50 +01:00
|
|
|
private slots:
|
2009-04-06 10:58:48 +02:00
|
|
|
void commandDollar();
|
2009-04-08 16:05:24 +02:00
|
|
|
void commandDown();
|
2009-04-09 16:20:49 +02:00
|
|
|
void commandLeft();
|
|
|
|
|
void commandRight();
|
|
|
|
|
void commandI();
|
2009-04-08 16:05:24 +02:00
|
|
|
void commandUp();
|
2009-04-09 16:20:49 +02:00
|
|
|
void commandW();
|
2009-04-06 10:58:48 +02:00
|
|
|
|
|
|
|
|
private:
|
2009-04-08 16:05:24 +02:00
|
|
|
void setup();
|
2009-04-09 15:44:51 +02:00
|
|
|
void send(const QString &command) { sendEx("normal " + command); }
|
2009-04-08 16:05:24 +02:00
|
|
|
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);
|
|
|
|
|
|
2009-04-09 14:43:04 +02:00
|
|
|
QTextEdit *m_textedit;
|
|
|
|
|
QPlainTextEdit *m_plaintextedit;
|
|
|
|
|
FakeVimHandler *m_handler;
|
2009-04-06 10:58:48 +02:00
|
|
|
QList<QTextEdit::ExtraSelection> m_selection;
|
|
|
|
|
|
2009-04-08 16:05:24 +02:00
|
|
|
QString m_statusMessage;
|
|
|
|
|
QString m_statusData;
|
|
|
|
|
QString m_infoMessage;
|
|
|
|
|
|
2009-04-06 10:58:48 +02:00
|
|
|
static const QString lines;
|
|
|
|
|
static const QString escape;
|
2008-12-27 12:24:50 +01:00
|
|
|
};
|
|
|
|
|
|
2009-04-06 10:58:48 +02:00
|
|
|
const QString tst_FakeVim::lines =
|
2009-04-09 15:44:51 +02:00
|
|
|
/* 0 1 2 3 4 */
|
|
|
|
|
/* 0123456789012345678901234567890123457890 */
|
2009-04-06 10:58:48 +02:00
|
|
|
"\n"
|
|
|
|
|
"#include <QtCore>\n"
|
|
|
|
|
"#include <QtGui>\n"
|
|
|
|
|
"\n"
|
|
|
|
|
"int main(int argc, char *argv[])\n"
|
|
|
|
|
"{\n"
|
|
|
|
|
" QApplication app(argc, argv);\n"
|
|
|
|
|
"\n"
|
|
|
|
|
" return app.exec();\n"
|
|
|
|
|
"}\n";
|
|
|
|
|
|
|
|
|
|
const QString tst_FakeVim::escape = QChar(27);
|
|
|
|
|
|
2009-04-09 14:43:04 +02:00
|
|
|
tst_FakeVim::tst_FakeVim(bool usePlainTextEdit)
|
2009-04-06 10:58:48 +02:00
|
|
|
{
|
2009-04-09 14:43:04 +02:00
|
|
|
if (usePlainTextEdit) {
|
|
|
|
|
m_textedit = 0;
|
|
|
|
|
m_plaintextedit = new QPlainTextEdit;
|
|
|
|
|
} else {
|
|
|
|
|
m_textedit = new QTextEdit;
|
|
|
|
|
m_plaintextedit = 0;
|
|
|
|
|
}
|
2009-04-09 15:44:51 +02:00
|
|
|
m_handler = 0;
|
2009-04-06 10:58:48 +02:00
|
|
|
}
|
|
|
|
|
|
2009-04-09 14:43:04 +02:00
|
|
|
tst_FakeVim::~tst_FakeVim()
|
|
|
|
|
{
|
|
|
|
|
delete m_handler;
|
|
|
|
|
delete m_textedit;
|
|
|
|
|
delete m_plaintextedit;
|
|
|
|
|
}
|
|
|
|
|
|
2009-04-06 10:58:48 +02:00
|
|
|
void tst_FakeVim::setup()
|
|
|
|
|
{
|
2009-04-09 15:44:51 +02:00
|
|
|
delete m_handler;
|
|
|
|
|
m_handler = 0;
|
2009-04-06 10:58:48 +02:00
|
|
|
m_statusMessage.clear();
|
|
|
|
|
m_statusData.clear();
|
|
|
|
|
m_infoMessage.clear();
|
2009-04-09 14:43:04 +02:00
|
|
|
if (m_textedit) {
|
|
|
|
|
m_textedit->setPlainText(lines);
|
|
|
|
|
QTextCursor tc = m_textedit->textCursor();
|
|
|
|
|
tc.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor);
|
|
|
|
|
m_textedit->setTextCursor(tc);
|
|
|
|
|
m_textedit->setPlainText(lines);
|
2009-04-09 15:44:51 +02:00
|
|
|
m_handler = new FakeVimHandler(m_textedit);
|
2009-04-09 14:43:04 +02:00
|
|
|
} else {
|
|
|
|
|
m_plaintextedit->setPlainText(lines);
|
|
|
|
|
QTextCursor tc = m_plaintextedit->textCursor();
|
|
|
|
|
tc.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor);
|
|
|
|
|
m_plaintextedit->setTextCursor(tc);
|
|
|
|
|
m_plaintextedit->setPlainText(lines);
|
2009-04-09 15:44:51 +02:00
|
|
|
m_handler = new FakeVimHandler(m_plaintextedit);
|
2009-04-09 14:43:04 +02:00
|
|
|
}
|
2009-04-06 10:58:48 +02:00
|
|
|
|
2009-04-09 15:44:51 +02:00
|
|
|
QObject::connect(m_handler, SIGNAL(commandBufferChanged(QString)),
|
|
|
|
|
this, SLOT(changeStatusMessage(QString)));
|
|
|
|
|
QObject::connect(m_handler, SIGNAL(extraInformationChanged(QString)),
|
|
|
|
|
this, SLOT(changeExtraInformation(QString)));
|
|
|
|
|
QObject::connect(m_handler, SIGNAL(statusDataChanged(QString)),
|
|
|
|
|
this, SLOT(changeStatusData(QString)));
|
|
|
|
|
|
|
|
|
|
QCOMPARE(EDITOR(toPlainText()), lines);
|
2009-04-06 10:58:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void tst_FakeVim::sendEx(const QString &command)
|
|
|
|
|
{
|
2009-04-09 15:44:51 +02:00
|
|
|
if (m_handler)
|
|
|
|
|
m_handler->handleCommand(command);
|
|
|
|
|
else
|
|
|
|
|
qDebug() << "NO HANDLER YET";
|
2009-04-06 10:58:48 +02:00
|
|
|
}
|
|
|
|
|
|
2009-04-08 16:05:24 +02:00
|
|
|
bool tst_FakeVim::checkContentsHelper(QString want, const char* file, int line)
|
|
|
|
|
{
|
2009-04-09 14:43:04 +02:00
|
|
|
QString got = EDITOR(toPlainText());
|
|
|
|
|
int pos = EDITOR(textCursor().position());
|
2009-04-08 16:05:24 +02:00
|
|
|
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)
|
|
|
|
|
|
2009-04-09 16:20:49 +02:00
|
|
|
#define move(cmd, expected) \
|
|
|
|
|
do { if (!checkHelper(false, cmd, insertCursor(expected), __FILE__, __LINE__)) \
|
|
|
|
|
return; } while (0)
|
|
|
|
|
|
2009-04-08 16:05:24 +02:00
|
|
|
// 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;
|
2009-04-09 15:44:51 +02:00
|
|
|
int pos = lines0.indexOf(needle);
|
|
|
|
|
lines0.replace(pos, needle.size(), needle0);
|
2009-04-08 16:05:24 +02:00
|
|
|
return lines0;
|
|
|
|
|
}
|
2009-04-06 10:58:48 +02:00
|
|
|
|
|
|
|
|
void tst_FakeVim::commandI()
|
|
|
|
|
{
|
|
|
|
|
setup();
|
|
|
|
|
|
|
|
|
|
// empty insertion at start of document
|
2009-04-08 16:05:24 +02:00
|
|
|
check("i" + escape, "@" + lines);
|
|
|
|
|
check("u", "@" + lines);
|
2009-04-06 10:58:48 +02:00
|
|
|
|
|
|
|
|
// small insertion at start of document
|
2009-04-08 16:05:24 +02:00
|
|
|
check("ix" + escape, "@x" + lines);
|
|
|
|
|
check("u", "@" + lines);
|
2009-04-06 10:58:48 +02:00
|
|
|
|
|
|
|
|
// small insertion at start of document
|
2009-04-08 16:05:24 +02:00
|
|
|
check("ixxx" + escape, "xx@x" + lines);
|
|
|
|
|
check("u", "@" + lines);
|
2009-04-06 10:58:48 +02:00
|
|
|
|
2009-04-09 16:20:49 +02:00
|
|
|
return;
|
2009-04-09 15:44:51 +02:00
|
|
|
|
2009-04-06 10:58:48 +02:00
|
|
|
// combine insertions
|
2009-04-08 16:05:24 +02:00
|
|
|
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);
|
2009-04-06 10:58:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void tst_FakeVim::commandDollar()
|
|
|
|
|
{
|
|
|
|
|
setup();
|
2009-04-09 16:20:49 +02:00
|
|
|
move("j$", "<QtCore>@");
|
|
|
|
|
move("j$", "<QtGui>@");
|
|
|
|
|
move("2j", ")@");
|
2009-04-08 16:05:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void tst_FakeVim::commandDown()
|
|
|
|
|
{
|
|
|
|
|
setup();
|
2009-04-09 16:20:49 +02:00
|
|
|
move("j", "@#include <QtCore");
|
|
|
|
|
move("3j", "@int main");
|
|
|
|
|
move("4j", "@ return app.exec()");
|
2009-04-06 10:58:48 +02:00
|
|
|
}
|
|
|
|
|
|
2009-04-08 16:05:24 +02:00
|
|
|
void tst_FakeVim::commandUp()
|
|
|
|
|
{
|
|
|
|
|
setup();
|
2009-04-09 16:20:49 +02:00
|
|
|
move("j", "@#include <QtCore");
|
|
|
|
|
move("3j", "@int main");
|
|
|
|
|
move("4j", "@ return app.exec()");
|
2009-04-08 16:05:24 +02:00
|
|
|
}
|
|
|
|
|
|
2009-04-09 16:20:49 +02:00
|
|
|
void tst_FakeVim::commandRight()
|
|
|
|
|
{
|
|
|
|
|
setup();
|
|
|
|
|
move("4j", "@int main");
|
|
|
|
|
move("l", "i@nt main");
|
|
|
|
|
move("3l", "int @main");
|
|
|
|
|
move("50l", "argv[])@");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void tst_FakeVim::commandLeft()
|
|
|
|
|
{
|
|
|
|
|
setup();
|
|
|
|
|
move("4j", "@int main");
|
|
|
|
|
move("h", "@int main"); // no move over left border
|
|
|
|
|
move("$", "argv[])@");
|
|
|
|
|
move("h", "argv[]@)");
|
|
|
|
|
move("3h", "arg@v[])");
|
|
|
|
|
move("50h", "@int main");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void tst_FakeVim::commandW()
|
|
|
|
|
{
|
|
|
|
|
setup();
|
|
|
|
|
move("w", "@#include <QtCore");
|
|
|
|
|
move("w", "#@include <QtCore");
|
|
|
|
|
move("w", "#include @<QtCore");
|
|
|
|
|
move("3w", "@#include <QtGui");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2009-04-09 15:44:51 +02:00
|
|
|
/*
|
|
|
|
|
#include <QtCore>
|
|
|
|
|
#include <QtGui>
|
|
|
|
|
|
|
|
|
|
int main(int argc, char *argv[])
|
|
|
|
|
{
|
|
|
|
|
QApplication app(argc, argv);
|
|
|
|
|
|
|
|
|
|
return app.exec();
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
|
2009-04-09 14:43:04 +02:00
|
|
|
int main(int argc, char *argv[]) \
|
|
|
|
|
{
|
|
|
|
|
int res = 0;
|
|
|
|
|
QApplication app(argc, argv); \
|
2009-04-09 15:44:51 +02:00
|
|
|
|
|
|
|
|
// Test with QPlainTextEdit.
|
2009-04-09 14:43:04 +02:00
|
|
|
tst_FakeVim plaintextedit(true);
|
|
|
|
|
res += QTest::qExec(&plaintextedit, argc, argv);
|
2009-04-09 15:44:51 +02:00
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
// Test with QTextEdit, too.
|
2009-04-09 14:43:04 +02:00
|
|
|
tst_FakeVim textedit(false);
|
|
|
|
|
res += QTest::qExec(&textedit, argc, argv);
|
2009-04-09 15:44:51 +02:00
|
|
|
#endif
|
|
|
|
|
|
2009-04-09 14:43:04 +02:00
|
|
|
return res;
|
|
|
|
|
}
|
2009-04-08 16:05:24 +02:00
|
|
|
|
2008-12-27 12:24:50 +01:00
|
|
|
|
|
|
|
|
#include "main.moc"
|