forked from qt-creator/qt-creator
QmlJS: Add 'reformat' action which regenerates the whole file.
Change-Id: I0aed6c6e197e122200d720eb9291a083095a6299 Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
This commit is contained in:
@@ -67,9 +67,11 @@ OTHER_FILES += \
|
|||||||
contains(QT, gui) {
|
contains(QT, gui) {
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
$$PWD/qmljsindenter.cpp \
|
$$PWD/qmljsindenter.cpp \
|
||||||
$$PWD/qmljscodeformatter.cpp
|
$$PWD/qmljscodeformatter.cpp \
|
||||||
|
$$PWD/qmljsreformatter.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
$$PWD/qmljsindenter.h \
|
$$PWD/qmljsindenter.h \
|
||||||
$$PWD/qmljscodeformatter.h
|
$$PWD/qmljscodeformatter.h \
|
||||||
|
$$PWD/qmljsreformatter.h
|
||||||
}
|
}
|
||||||
|
1265
src/libs/qmljs/qmljsreformatter.cpp
Normal file
1265
src/libs/qmljs/qmljsreformatter.cpp
Normal file
File diff suppressed because it is too large
Load Diff
44
src/libs/qmljs/qmljsreformatter.h
Normal file
44
src/libs/qmljs/qmljsreformatter.h
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (info@qt.nokia.com)
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Nokia gives you certain additional
|
||||||
|
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** Other Usage
|
||||||
|
**
|
||||||
|
** Alternatively, this file may be used in accordance with the terms and
|
||||||
|
** conditions contained in a signed written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** If you have questions regarding the use of this file, please contact
|
||||||
|
** Nokia at info@qt.nokia.com.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QMLJSREFORMATTER_H
|
||||||
|
#define QMLJSREFORMATTER_H
|
||||||
|
|
||||||
|
#include "qmljs_global.h"
|
||||||
|
|
||||||
|
#include "qmljsdocument.h"
|
||||||
|
|
||||||
|
namespace QmlJS {
|
||||||
|
QMLJS_EXPORT QString reformat(const Document::Ptr &doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // QMLJSREFORMATTER_H
|
@@ -1588,6 +1588,8 @@ void QmlJSTextEditorWidget::updateSemanticInfo(const SemanticInfo &semanticInfo)
|
|||||||
Core::EditorManager *editorManager = Core::EditorManager::instance();
|
Core::EditorManager *editorManager = Core::EditorManager::instance();
|
||||||
if (editorManager->currentEditor() == editor())
|
if (editorManager->currentEditor() == editor())
|
||||||
m_semanticHighlighter->rerun(m_semanticInfo.scopeChain());
|
m_semanticHighlighter->rerun(m_semanticInfo.scopeChain());
|
||||||
|
|
||||||
|
emit semanticInfoUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlJSTextEditorWidget::onRefactorMarkerClicked(const TextEditor::RefactorMarker &marker)
|
void QmlJSTextEditorWidget::onRefactorMarkerClicked(const TextEditor::RefactorMarker &marker)
|
||||||
|
@@ -182,6 +182,7 @@ public slots:
|
|||||||
signals:
|
signals:
|
||||||
void outlineModelIndexChanged(const QModelIndex &index);
|
void outlineModelIndexChanged(const QModelIndex &index);
|
||||||
void selectedElementsChanged(QList<int> offsets, const QString &wordAtCursor);
|
void selectedElementsChanged(QList<int> offsets, const QString &wordAtCursor);
|
||||||
|
void semanticInfoUpdated();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onDocumentUpdated(QmlJS::Document::Ptr doc);
|
void onDocumentUpdated(QmlJS::Document::Ptr doc);
|
||||||
|
@@ -55,6 +55,7 @@ const char FOLLOW_SYMBOL_UNDER_CURSOR[] = "QmlJSEditor.FollowSymbolUnderCursor";
|
|||||||
const char FIND_USAGES[] = "QmlJSEditor.FindUsages";
|
const char FIND_USAGES[] = "QmlJSEditor.FindUsages";
|
||||||
const char RENAME_USAGES[] = "QmlJSEditor.RenameUsages";
|
const char RENAME_USAGES[] = "QmlJSEditor.RenameUsages";
|
||||||
const char RUN_SEMANTIC_SCAN[] = "QmlJSEditor.RunSemanticScan";
|
const char RUN_SEMANTIC_SCAN[] = "QmlJSEditor.RunSemanticScan";
|
||||||
|
const char REFORMAT_FILE[] = "QmlJSEditor.ReformatFile";
|
||||||
const char SHOW_QT_QUICK_HELPER[] = "QmlJSEditor.ShowQtQuickHelper";
|
const char SHOW_QT_QUICK_HELPER[] = "QmlJSEditor.ShowQtQuickHelper";
|
||||||
|
|
||||||
const char TASK_CATEGORY_QML[] = "Task.Category.Qml";
|
const char TASK_CATEGORY_QML[] = "Task.Category.Qml";
|
||||||
|
@@ -49,6 +49,7 @@
|
|||||||
|
|
||||||
#include <qmljs/qmljsicons.h>
|
#include <qmljs/qmljsicons.h>
|
||||||
#include <qmljs/qmljsmodelmanagerinterface.h>
|
#include <qmljs/qmljsmodelmanagerinterface.h>
|
||||||
|
#include <qmljs/qmljsreformatter.h>
|
||||||
#include <qmljstools/qmljstoolsconstants.h>
|
#include <qmljstools/qmljstoolsconstants.h>
|
||||||
|
|
||||||
#include <qmldesigner/qmldesignerconstants.h>
|
#include <qmldesigner/qmldesignerconstants.h>
|
||||||
@@ -93,10 +94,11 @@ QmlJSEditorPlugin *QmlJSEditorPlugin::m_instance = 0;
|
|||||||
|
|
||||||
QmlJSEditorPlugin::QmlJSEditorPlugin() :
|
QmlJSEditorPlugin::QmlJSEditorPlugin() :
|
||||||
m_modelManager(0),
|
m_modelManager(0),
|
||||||
m_wizard(0),
|
|
||||||
m_editor(0),
|
m_editor(0),
|
||||||
m_actionHandler(0),
|
m_actionHandler(0),
|
||||||
m_quickFixAssistProvider(0)
|
m_quickFixAssistProvider(0),
|
||||||
|
m_reformatFileAction(0),
|
||||||
|
m_currentEditor(0)
|
||||||
{
|
{
|
||||||
m_instance = this;
|
m_instance = this;
|
||||||
}
|
}
|
||||||
@@ -205,6 +207,11 @@ bool QmlJSEditorPlugin::initialize(const QStringList & /*arguments*/, QString *e
|
|||||||
connect(semanticScan, SIGNAL(triggered()), this, SLOT(runSemanticScan()));
|
connect(semanticScan, SIGNAL(triggered()), this, SLOT(runSemanticScan()));
|
||||||
qmlToolsMenu->addAction(cmd);
|
qmlToolsMenu->addAction(cmd);
|
||||||
|
|
||||||
|
m_reformatFileAction = new QAction(tr("Reformat File"), this);
|
||||||
|
cmd = am->registerAction(m_reformatFileAction, Core::Id(Constants::REFORMAT_FILE), globalContext);
|
||||||
|
connect(m_reformatFileAction, SIGNAL(triggered()), this, SLOT(reformatFile()));
|
||||||
|
qmlToolsMenu->addAction(cmd);
|
||||||
|
|
||||||
QAction *showQuickToolbar = new QAction(tr("Show Qt Quick Toolbar"), this);
|
QAction *showQuickToolbar = new QAction(tr("Show Qt Quick Toolbar"), this);
|
||||||
cmd = am->registerAction(showQuickToolbar, Constants::SHOW_QT_QUICK_HELPER, context);
|
cmd = am->registerAction(showQuickToolbar, Constants::SHOW_QT_QUICK_HELPER, context);
|
||||||
#ifdef Q_WS_MACX
|
#ifdef Q_WS_MACX
|
||||||
@@ -300,6 +307,20 @@ void QmlJSEditorPlugin::renameUsages()
|
|||||||
editor->renameUsages();
|
editor->renameUsages();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QmlJSEditorPlugin::reformatFile()
|
||||||
|
{
|
||||||
|
Core::EditorManager *em = Core::EditorManager::instance();
|
||||||
|
if (QmlJSTextEditorWidget *editor = qobject_cast<QmlJSTextEditorWidget*>(em->currentEditor()->widget())) {
|
||||||
|
QTC_ASSERT(!editor->isOutdated(), return);
|
||||||
|
|
||||||
|
const QString &newText = QmlJS::reformat(editor->semanticInfo().document);
|
||||||
|
QTextCursor tc(editor->textCursor());
|
||||||
|
tc.movePosition(QTextCursor::Start);
|
||||||
|
tc.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
|
||||||
|
tc.insertText(newText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void QmlJSEditorPlugin::showContextPane()
|
void QmlJSEditorPlugin::showContextPane()
|
||||||
{
|
{
|
||||||
Core::EditorManager *em = Core::EditorManager::instance();
|
Core::EditorManager *em = Core::EditorManager::instance();
|
||||||
@@ -327,11 +348,23 @@ QmlJSQuickFixAssistProvider *QmlJSEditorPlugin::quickFixAssistProvider() const
|
|||||||
|
|
||||||
void QmlJSEditorPlugin::currentEditorChanged(Core::IEditor *editor)
|
void QmlJSEditorPlugin::currentEditorChanged(Core::IEditor *editor)
|
||||||
{
|
{
|
||||||
if (! editor)
|
QmlJSTextEditorWidget *newTextEditor = 0;
|
||||||
return;
|
if (editor)
|
||||||
|
newTextEditor = qobject_cast<QmlJSTextEditorWidget *>(editor->widget());
|
||||||
|
|
||||||
else if (QmlJSTextEditorWidget *textEditor = qobject_cast<QmlJSTextEditorWidget *>(editor->widget())) {
|
if (m_currentEditor) {
|
||||||
textEditor->forceReparse();
|
disconnect(m_currentEditor.data(), SIGNAL(contentsChanged()),
|
||||||
|
this, SLOT(checkCurrentEditorSemanticInfoUpToDate()));
|
||||||
|
disconnect(m_currentEditor.data(), SIGNAL(semanticInfoUpdated()),
|
||||||
|
this, SLOT(checkCurrentEditorSemanticInfoUpToDate()));
|
||||||
|
}
|
||||||
|
m_currentEditor = newTextEditor;
|
||||||
|
if (newTextEditor) {
|
||||||
|
connect(newTextEditor, SIGNAL(contentsChanged()),
|
||||||
|
this, SLOT(checkCurrentEditorSemanticInfoUpToDate()));
|
||||||
|
connect(newTextEditor, SIGNAL(semanticInfoUpdated()),
|
||||||
|
this, SLOT(checkCurrentEditorSemanticInfoUpToDate()));
|
||||||
|
newTextEditor->forceReparse();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -343,4 +376,10 @@ void QmlJSEditorPlugin::runSemanticScan()
|
|||||||
hub->popup(false);
|
hub->popup(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QmlJSEditorPlugin::checkCurrentEditorSemanticInfoUpToDate()
|
||||||
|
{
|
||||||
|
const bool semanticInfoUpToDate = m_currentEditor && !m_currentEditor->isOutdated();
|
||||||
|
m_reformatFileAction->setEnabled(semanticInfoUpToDate);
|
||||||
|
}
|
||||||
|
|
||||||
Q_EXPORT_PLUGIN(QmlJSEditorPlugin)
|
Q_EXPORT_PLUGIN(QmlJSEditorPlugin)
|
||||||
|
@@ -95,11 +95,13 @@ public Q_SLOTS:
|
|||||||
void followSymbolUnderCursor();
|
void followSymbolUnderCursor();
|
||||||
void findUsages();
|
void findUsages();
|
||||||
void renameUsages();
|
void renameUsages();
|
||||||
|
void reformatFile();
|
||||||
void showContextPane();
|
void showContextPane();
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void currentEditorChanged(Core::IEditor *editor);
|
void currentEditorChanged(Core::IEditor *editor);
|
||||||
void runSemanticScan();
|
void runSemanticScan();
|
||||||
|
void checkCurrentEditorSemanticInfoUpToDate();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Core::Command *addToolAction(QAction *a, Core::ActionManager *am, Core::Context &context, const Core::Id &id,
|
Core::Command *addToolAction(QAction *a, Core::ActionManager *am, Core::Context &context, const Core::Id &id,
|
||||||
@@ -107,18 +109,15 @@ private:
|
|||||||
|
|
||||||
static QmlJSEditorPlugin *m_instance;
|
static QmlJSEditorPlugin *m_instance;
|
||||||
|
|
||||||
QAction *m_actionPreview;
|
|
||||||
QmlJSPreviewRunner *m_previewRunner;
|
|
||||||
|
|
||||||
QmlJS::ModelManagerInterface *m_modelManager;
|
QmlJS::ModelManagerInterface *m_modelManager;
|
||||||
QmlFileWizard *m_wizard;
|
|
||||||
QmlJSEditorFactory *m_editor;
|
QmlJSEditorFactory *m_editor;
|
||||||
TextEditor::TextEditorActionHandler *m_actionHandler;
|
TextEditor::TextEditorActionHandler *m_actionHandler;
|
||||||
|
|
||||||
QmlJSQuickFixAssistProvider *m_quickFixAssistProvider;
|
QmlJSQuickFixAssistProvider *m_quickFixAssistProvider;
|
||||||
|
|
||||||
QPointer<TextEditor::ITextEditor> m_currentTextEditable;
|
|
||||||
QmlTaskManager *m_qmlTaskManager;
|
QmlTaskManager *m_qmlTaskManager;
|
||||||
|
|
||||||
|
QAction *m_reformatFileAction;
|
||||||
|
|
||||||
|
QPointer<QmlJSTextEditorWidget> m_currentEditor;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -3,4 +3,5 @@ TEMPLATE = subdirs
|
|||||||
SUBDIRS += qmldesigner \
|
SUBDIRS += qmldesigner \
|
||||||
qmleditor \
|
qmleditor \
|
||||||
qmlprojectmanager \
|
qmlprojectmanager \
|
||||||
codemodel
|
codemodel \
|
||||||
|
reformatter
|
||||||
|
57
tests/auto/qml/reformatter/jssyntax.js
Normal file
57
tests/auto/qml/reformatter/jssyntax.js
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
var x
|
||||||
|
var y = 12
|
||||||
|
|
||||||
|
function foo(a, b) {
|
||||||
|
x = 15
|
||||||
|
x += 4
|
||||||
|
}
|
||||||
|
|
||||||
|
var foo =
|
||||||
|
function (a, b) {}
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
for (var a = 1; a < 5; ++a) {
|
||||||
|
switch (a) {
|
||||||
|
case 1:
|
||||||
|
++a
|
||||||
|
break
|
||||||
|
case 2:
|
||||||
|
a += 2
|
||||||
|
foo()
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
case 3:
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var x in a) {
|
||||||
|
print(a[x])
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
a = x
|
||||||
|
x *= a
|
||||||
|
} while (a < x)
|
||||||
|
|
||||||
|
try {
|
||||||
|
Math.sqrt(a)
|
||||||
|
} catch (e) {
|
||||||
|
Math.sqrt(a)
|
||||||
|
} finally {
|
||||||
|
Math.sqrt(a)
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Math.sqrt(a)
|
||||||
|
} finally {
|
||||||
|
Math.sqrt(a)
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Math.sqrt(a)
|
||||||
|
} catch (e) {
|
||||||
|
Math.sqrt(a)
|
||||||
|
}
|
||||||
|
}
|
45
tests/auto/qml/reformatter/qmlsyntax.qml
Normal file
45
tests/auto/qml/reformatter/qmlsyntax.qml
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
// imports
|
||||||
|
import QtQuick 2.0
|
||||||
|
import Qt.labs.particles 1.0 as Part
|
||||||
|
import "/usr" as Foo
|
||||||
|
import "." 1.0
|
||||||
|
|
||||||
|
Text {
|
||||||
|
// properties
|
||||||
|
property int foo
|
||||||
|
property alias bar: x
|
||||||
|
property list<QtObject> pro
|
||||||
|
default property int def
|
||||||
|
|
||||||
|
// script binding
|
||||||
|
x: x + y
|
||||||
|
|
||||||
|
// object bindings
|
||||||
|
Rectangle on font.family {
|
||||||
|
x: x
|
||||||
|
}
|
||||||
|
anchors.bottom: AnchorAnimation {
|
||||||
|
running: true
|
||||||
|
}
|
||||||
|
|
||||||
|
// array binding
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: x
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: y
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
// nested with qualified id
|
||||||
|
Part.ParticleMotion {
|
||||||
|
id: foo
|
||||||
|
}
|
||||||
|
|
||||||
|
// functions
|
||||||
|
function foo(a, b) {}
|
||||||
|
function foo(a, b) {
|
||||||
|
x = a + 12 * b
|
||||||
|
}
|
||||||
|
}
|
12
tests/auto/qml/reformatter/reformatter.pro
Normal file
12
tests/auto/qml/reformatter/reformatter.pro
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
include(../../qttest.pri)
|
||||||
|
|
||||||
|
DEFINES+=QTCREATORDIR=\\\"$$IDE_SOURCE_TREE\\\"
|
||||||
|
DEFINES+=TESTSRCDIR=\\\"$$PWD\\\"
|
||||||
|
|
||||||
|
include($$IDE_SOURCE_TREE/src/libs/utils/utils.pri)
|
||||||
|
include($$IDE_SOURCE_TREE/src/libs/qmljs/qmljs.pri)
|
||||||
|
|
||||||
|
TARGET = tst_reformatter
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
tst_reformatter.cpp
|
119
tests/auto/qml/reformatter/tst_reformatter.cpp
Normal file
119
tests/auto/qml/reformatter/tst_reformatter.cpp
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (info@qt.nokia.com)
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Nokia gives you certain additional
|
||||||
|
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** Other Usage
|
||||||
|
**
|
||||||
|
** Alternatively, this file may be used in accordance with the terms and
|
||||||
|
** conditions contained in a signed written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** If you have questions regarding the use of this file, please contact
|
||||||
|
** Nokia at info@qt.nokia.com.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include <QScopedPointer>
|
||||||
|
#include <QLatin1String>
|
||||||
|
#include <QGraphicsObject>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QSettings>
|
||||||
|
#include <QFileInfo>
|
||||||
|
|
||||||
|
#include <qmljs/qmljsdocument.h>
|
||||||
|
#include <qmljs/qmljsreformatter.h>
|
||||||
|
#include <qmljs/parser/qmljsast_p.h>
|
||||||
|
|
||||||
|
#include <QtTest>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
using namespace QmlJS;
|
||||||
|
using namespace QmlJS::AST;
|
||||||
|
|
||||||
|
class tst_Reformatter : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
tst_Reformatter();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void test();
|
||||||
|
void test_data();
|
||||||
|
};
|
||||||
|
|
||||||
|
tst_Reformatter::tst_Reformatter()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#define QCOMPARE_NOEXIT(actual, expected) \
|
||||||
|
QTest::qCompare(actual, expected, #actual, #expected, __FILE__, __LINE__)
|
||||||
|
|
||||||
|
void tst_Reformatter::test_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QString>("path");
|
||||||
|
|
||||||
|
QDirIterator it(TESTSRCDIR, QStringList() << QLatin1String("*.qml") << QLatin1String("*.js"), QDir::Files);
|
||||||
|
while (it.hasNext()) {
|
||||||
|
const QString fileName = it.next();
|
||||||
|
QTest::newRow(fileName.toLatin1()) << it.filePath();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_Reformatter::test()
|
||||||
|
{
|
||||||
|
QFETCH(QString, path);
|
||||||
|
|
||||||
|
Document::Ptr doc = Document::create(path, Document::guessLanguageFromSuffix(path));
|
||||||
|
QFile file(doc->fileName());
|
||||||
|
file.open(QFile::ReadOnly | QFile::Text);
|
||||||
|
QString source = QString::fromUtf8(file.readAll());
|
||||||
|
doc->setSource(source);
|
||||||
|
file.close();
|
||||||
|
doc->parse();
|
||||||
|
|
||||||
|
QVERIFY(!doc->source().isEmpty());
|
||||||
|
QVERIFY(doc->diagnosticMessages().isEmpty());
|
||||||
|
|
||||||
|
QString rewritten = reformat(doc);
|
||||||
|
|
||||||
|
QStringList sourceLines = source.split(QLatin1Char('\n'));
|
||||||
|
QStringList newLines = rewritten.split(QLatin1Char('\n'));
|
||||||
|
|
||||||
|
// compare line by line
|
||||||
|
int commonLines = qMin(newLines.size(), sourceLines.size());
|
||||||
|
for (int i = 0; i < commonLines; ++i) {
|
||||||
|
// names intentional to make 'Actual (sourceLine): ...\nExpected (newLinee): ...' line up
|
||||||
|
const QString &sourceLine = sourceLines.at(i);
|
||||||
|
const QString &newLinee = newLines.at(i);
|
||||||
|
if (sourceLine.trimmed().isEmpty() && newLinee.trimmed().isEmpty())
|
||||||
|
continue;
|
||||||
|
bool fail = !QCOMPARE_NOEXIT(sourceLine, newLinee);
|
||||||
|
if (fail) {
|
||||||
|
qDebug() << "in line" << (i + 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QCOMPARE(sourceLines.size(), newLines.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
QTEST_MAIN(tst_Reformatter);
|
||||||
|
|
||||||
|
#include "tst_reformatter.moc"
|
Reference in New Issue
Block a user