Commit ef591791 authored by Nikolai Kosjar's avatar Nikolai Kosjar

CppTools: Tests: Refactor / Clean up cppcompletion_test.cpp

* Open the files in the cpp editor, so preprocessing will take place
* Remove duplicated code
* Fix coding styles issues

Change-Id: Ic8bffcbc5a4ac5aca76bc55880d33c3b55f0944c
Reviewed-by: default avatarFawzi Mohamed <fawzi.mohamed@digia.com>
parent 197d4a15
......@@ -29,6 +29,7 @@
#include "cpptoolsplugin.h"
#include "cppcompletionassist.h"
#include "cppmodelmanager.h"
#include <texteditor/plaintexteditor.h>
#include <texteditor/codeassist/iassistproposal.h>
......@@ -50,102 +51,128 @@ using namespace CppTools::Internal;
using namespace TextEditor;
using namespace Core;
struct TestData
{
QByteArray srcText;
int pos;
Snapshot snapshot;
BaseTextEditorWidget *editor;
QTextDocument *doc;
};
class CompletionTestCase
{
public:
CompletionTestCase(const QByteArray &sourceText, const QByteArray &textToInsert = QByteArray())
: position(-1), editorWidget(0), textDocument(0), editor(0),
cmm(CppModelManager::instance())
{
source = sourceText;
position = source.indexOf('@');
QVERIFY(position != -1);
source[position] = ' ';
// Write source to file
const QString fileName = QDir::tempPath() + QLatin1String("/file.h");
Utils::FileSaver srcSaver(fileName);
srcSaver.write(source);
srcSaver.finalize();
// Open in editor
editor = EditorManager::openEditor(fileName);
QVERIFY(editor);
editorWidget = qobject_cast<TextEditor::BaseTextEditorWidget *>(editor->widget());
QVERIFY(editorWidget);
textDocument = editorWidget->document();
// Get Document
while (!cmm->snapshot().contains(fileName))
QCoreApplication::processEvents();
Document::Ptr document = cmm->snapshot().document(fileName);
snapshot.insert(document);
if (!textToInsert.isEmpty())
insertText(textToInsert);
}
static QStringList getCompletions(TestData &data, bool *replaceAccessOperator = 0)
{
QStringList completions;
~CompletionTestCase()
{
EditorManager::instance()->closeEditors(QList<IEditor*>() << editor,
/*askAboutModifiedEditors=*/ false);
cmm->GC();
QVERIFY(cmm->snapshot().isEmpty());
}
CppCompletionAssistInterface *ai = new CppCompletionAssistInterface(data.editor->document(), data.pos,
data.editor->editorDocument()->fileName(), ExplicitlyInvoked,
data.snapshot, QStringList(), QStringList());
CppCompletionAssistProcessor processor;
IAssistProposal *proposal = processor.perform(ai);
if (!proposal)
return completions;
IAssistProposalModel *model = proposal->model();
if (!model)
return completions;
CppAssistProposalModel *listmodel = dynamic_cast<CppAssistProposalModel *>(model);
if (!listmodel)
return completions;
QStringList getCompletions(bool *replaceAccessOperator = 0) const
{
QStringList completions;
CppCompletionAssistInterface *ai
= new CppCompletionAssistInterface(editorWidget->document(), position,
editorWidget->editorDocument()->fileName(),
ExplicitlyInvoked, snapshot,
QStringList(), QStringList());
CppCompletionAssistProcessor processor;
IAssistProposal *proposal = processor.perform(ai);
if (!proposal)
return completions;
IAssistProposalModel *model = proposal->model();
if (!model)
return completions;
CppAssistProposalModel *listmodel = dynamic_cast<CppAssistProposalModel *>(model);
if (!listmodel)
return completions;
for (int i = 0; i < listmodel->size(); ++i)
completions << listmodel->text(i);
if (replaceAccessOperator)
*replaceAccessOperator = listmodel->m_replaceDotForArrow;
for (int i = 0; i < listmodel->size(); ++i)
completions << listmodel->text(i);
return completions;
}
if (replaceAccessOperator)
*replaceAccessOperator = listmodel->m_replaceDotForArrow;
void insertText(const QByteArray &text)
{
Utils::ChangeSet change;
change.insert(position, QLatin1String(text));
QTextCursor cursor(textDocument);
change.apply(&cursor);
position += text.length();
}
return completions;
}
private:
QByteArray source;
int position;
Snapshot snapshot;
BaseTextEditorWidget *editorWidget;
QTextDocument *textDocument;
IEditor *editor;
static void setup(TestData *data)
{
data->pos = data->srcText.indexOf('@');
QVERIFY(data->pos != -1);
data->srcText[data->pos] = ' ';
Document::Ptr src = Document::create(QDir::tempPath() + QLatin1String("/file.h"));
Utils::FileSaver srcSaver(src->fileName());
srcSaver.write(data->srcText);
srcSaver.finalize();
src->setUtf8Source(data->srcText);
src->parse();
src->check();
data->snapshot.insert(src);
data->editor = new PlainTextEditorWidget(0);
QString error;
data->editor->open(&error, src->fileName(), src->fileName());
data->doc = data->editor->document();
}
CppModelManager *cmm;
};
void CppToolsPlugin::test_completion_forward_declarations_present()
{
TestData data;
data.srcText = "\n"
"class Foo\n"
"{\n"
" struct Bar;\n"
" int i;\n"
"};\n"
"\n"
"struct Foo::Bar \n"
"{\n"
" Bar() {}\n"
"};\n"
"\n"
"@\n"
"// padding so we get the scope right\n";
setup(&data);
Utils::ChangeSet change;
change.insert(data.pos, QLatin1String("Foo::Bar::"));
QTextCursor cursor(data.doc);
change.apply(&cursor);
data.pos += 10;
const QByteArray source =
"\n"
"class Foo\n"
"{\n"
" struct Bar;\n"
" int i;\n"
"};\n"
"\n"
"struct Foo::Bar \n"
"{\n"
" Bar() {}\n"
"};\n"
"\n"
"@\n"
"// padding so we get the scope right\n";
CompletionTestCase test(source, "Foo::Bar::");
QStringList expected;
expected.append(QLatin1String("Bar"));
QStringList completions = getCompletions(data);
const QStringList completions = test.getCompletions();
QCOMPARE(completions, expected);
}
void CppToolsPlugin::test_completion_inside_parentheses_c_style_conversion()
{
TestData data;
data.srcText = "\n"
const QByteArray source = "\n"
"class Base\n"
"{\n"
" int i_base;\n"
......@@ -163,30 +190,19 @@ void CppToolsPlugin::test_completion_inside_parentheses_c_style_conversion()
" @\n"
"}\n"
;
CompletionTestCase test(source, "((Derived *)b)->");
setup(&data);
Utils::ChangeSet change;
QString txt = QLatin1String("((Derived *)b)->");
change.insert(data.pos, txt);
QTextCursor cursor(data.doc);
change.apply(&cursor);
data.pos += txt.length();
QStringList completions = getCompletions(data);
const QStringList completions = test.getCompletions();
QCOMPARE(completions.size(), 4);
QVERIFY(completions.contains(QLatin1String("Derived")));
QVERIFY(completions.contains(QLatin1String("Base")));
QVERIFY(completions.contains(QLatin1String("i_derived")));
QVERIFY(completions.contains(QLatin1String("i_base")));
}
void CppToolsPlugin::test_completion_inside_parentheses_cast_operator_conversion()
{
TestData data;
data.srcText = "\n"
const QByteArray source = "\n"
"class Base\n"
"{\n"
" int i_base;\n"
......@@ -204,18 +220,9 @@ void CppToolsPlugin::test_completion_inside_parentheses_cast_operator_conversion
" @\n"
"}\n"
;
CompletionTestCase test(source, "(static_cast<Derived *>(b))->");
setup(&data);
Utils::ChangeSet change;
QString txt = QLatin1String("(static_cast<Derived *>(b))->");
change.insert(data.pos, txt);
QTextCursor cursor(data.doc);
change.apply(&cursor);
data.pos += txt.length();
QStringList completions = getCompletions(data);
const QStringList completions = test.getCompletions();
QCOMPARE(completions.size(), 4);
QVERIFY(completions.contains(QLatin1String("Derived")));
QVERIFY(completions.contains(QLatin1String("Base")));
......@@ -225,8 +232,7 @@ void CppToolsPlugin::test_completion_inside_parentheses_cast_operator_conversion
void CppToolsPlugin::test_completion_basic_1()
{
TestData data;
data.srcText = "\n"
const QByteArray source = "\n"
"class Foo\n"
"{\n"
" void foo();\n"
......@@ -238,25 +244,18 @@ void CppToolsPlugin::test_completion_basic_1()
" @\n"
" // padding so we get the scope right\n"
"}";
CompletionTestCase test(source);
setup(&data);
QStringList basicCompletions = getCompletions(data);
QStringList basicCompletions = test.getCompletions();
QVERIFY(!basicCompletions.contains(QLatin1String("foo")));
QVERIFY(!basicCompletions.contains(QLatin1String("m")));
QVERIFY(basicCompletions.contains(QLatin1String("Foo")));
QVERIFY(basicCompletions.contains(QLatin1String("func")));
QVERIFY(basicCompletions.contains(QLatin1String("f")));
Utils::ChangeSet change;
change.insert(data.pos, QLatin1String("f."));
QTextCursor cursor(data.doc);
change.apply(&cursor);
data.pos += 2;
QStringList memberCompletions = getCompletions(data);
test.insertText("f.");
QStringList memberCompletions = test.getCompletions();
QVERIFY(memberCompletions.contains(QLatin1String("foo")));
QVERIFY(memberCompletions.contains(QLatin1String("m")));
QVERIFY(!memberCompletions.contains(QLatin1String("func")));
......@@ -265,8 +264,7 @@ void CppToolsPlugin::test_completion_basic_1()
void CppToolsPlugin::test_completion_template_1()
{
TestData data;
data.srcText = "\n"
const QByteArray source = "\n"
"template <class T>\n"
"class Foo\n"
"{\n"
......@@ -280,17 +278,9 @@ void CppToolsPlugin::test_completion_template_1()
" @\n"
" // padding so we get the scope right\n"
"}";
CompletionTestCase test(source, "Foo::");
setup(&data);
Utils::ChangeSet change;
change.insert(data.pos, QLatin1String("Foo::"));
QTextCursor cursor(data.doc);
change.apply(&cursor);
data.pos += 5;
QStringList completions = getCompletions(data);
const QStringList completions = test.getCompletions();
QVERIFY(completions.contains(QLatin1String("Type")));
QVERIFY(completions.contains(QLatin1String("foo")));
QVERIFY(completions.contains(QLatin1String("m")));
......@@ -301,8 +291,7 @@ void CppToolsPlugin::test_completion_template_1()
void CppToolsPlugin::test_completion_template_2()
{
TestData data;
data.srcText = "\n"
const QByteArray source = "\n"
"template <class T>\n"
"struct List\n"
"{\n"
......@@ -316,18 +305,9 @@ void CppToolsPlugin::test_completion_template_2()
" @\n"
" // padding so we get the scope right\n"
"}";
CompletionTestCase test(source, "l.at(0).");
setup(&data);
Utils::ChangeSet change;
QString txt = QLatin1String("l.at(0).");
change.insert(data.pos, txt);
QTextCursor cursor(data.doc);
change.apply(&cursor);
data.pos += txt.length();
QStringList completions = getCompletions(data);
const QStringList completions = test.getCompletions();
QCOMPARE(completions.size(), 3);
QVERIFY(completions.contains(QLatin1String("Tupple")));
QVERIFY(completions.contains(QLatin1String("a")));
......@@ -336,8 +316,7 @@ void CppToolsPlugin::test_completion_template_2()
void CppToolsPlugin::test_completion_template_3()
{
TestData data;
data.srcText = "\n"
const QByteArray source = "\n"
"template <class T>\n"
"struct List\n"
"{\n"
......@@ -351,18 +330,9 @@ void CppToolsPlugin::test_completion_template_3()
" @\n"
" // padding so we get the scope right\n"
"}";
CompletionTestCase test(source, "l.t.");
setup(&data);
Utils::ChangeSet change;
QString txt = QLatin1String("l.t.");
change.insert(data.pos, txt);
QTextCursor cursor(data.doc);
change.apply(&cursor);
data.pos += txt.length();
QStringList completions = getCompletions(data);
const QStringList completions = test.getCompletions();
QCOMPARE(completions.size(), 3);
QVERIFY(completions.contains(QLatin1String("Tupple")));
QVERIFY(completions.contains(QLatin1String("a")));
......@@ -371,8 +341,7 @@ void CppToolsPlugin::test_completion_template_3()
void CppToolsPlugin::test_completion_template_4()
{
TestData data;
data.srcText = "\n"
const QByteArray source = "\n"
"template <class T>\n"
"struct List\n"
"{\n"
......@@ -387,18 +356,9 @@ void CppToolsPlugin::test_completion_template_4()
" @\n"
" // padding so we get the scope right\n"
"}";
CompletionTestCase test(source, "l.u.");
setup(&data);
Utils::ChangeSet change;
QString txt = QLatin1String("l.u.");
change.insert(data.pos, txt);
QTextCursor cursor(data.doc);
change.apply(&cursor);
data.pos += txt.length();
QStringList completions = getCompletions(data);
const QStringList completions = test.getCompletions();
QCOMPARE(completions.size(), 3);
QVERIFY(completions.contains(QLatin1String("Tupple")));
QVERIFY(completions.contains(QLatin1String("a")));
......@@ -407,8 +367,7 @@ void CppToolsPlugin::test_completion_template_4()
void CppToolsPlugin::test_completion_template_5()
{
TestData data;
data.srcText = "\n"
const QByteArray source = "\n"
"template <class T>\n"
"struct List\n"
"{\n"
......@@ -423,18 +382,9 @@ void CppToolsPlugin::test_completion_template_5()
" @\n"
" // padding so we get the scope right\n"
"}";
CompletionTestCase test(source, "l.u.");
setup(&data);
Utils::ChangeSet change;
QString txt = QLatin1String("l.u.");
change.insert(data.pos, txt);
QTextCursor cursor(data.doc);
change.apply(&cursor);
data.pos += txt.length();
QStringList completions = getCompletions(data);
const QStringList completions = test.getCompletions();
QCOMPARE(completions.size(), 3);
QVERIFY(completions.contains(QLatin1String("Tupple")));
QVERIFY(completions.contains(QLatin1String("a")));
......@@ -443,8 +393,7 @@ void CppToolsPlugin::test_completion_template_5()
void CppToolsPlugin::test_completion_template_6()
{
TestData data;
data.srcText = "\n"
const QByteArray source = "\n"
"class Item\n"
"{\n"
" int i;\n"
......@@ -463,28 +412,17 @@ void CppToolsPlugin::test_completion_template_6()
"ItemContainer container;\n"
"@\n"
;
CompletionTestCase test(source, "container.get().");
setup(&data);
Utils::ChangeSet change;
QString txt = QLatin1String("container.get().");
change.insert(data.pos, txt);
QTextCursor cursor(data.doc);
change.apply(&cursor);
data.pos += txt.length();
QStringList completions = getCompletions(data);
const QStringList completions = test.getCompletions();
QCOMPARE(completions.size(), 2);
QVERIFY(completions.contains(QLatin1String("Item")));
QVERIFY(completions.contains(QLatin1String("i")));
}
void CppToolsPlugin::test_completion_template_7()
{
TestData data;
data.srcText = "\n"
const QByteArray source = "\n"
"struct Test\n"
"{\n"
" int i;\n"
......@@ -506,18 +444,9 @@ void CppToolsPlugin::test_completion_template_7()
"TemplateClass<Test> p(new Test);\n"
"@\n"
;
CompletionTestCase test(source, "p->");
setup(&data);
Utils::ChangeSet change;
QString txt = QLatin1String("p->");
change.insert(data.pos, txt);
QTextCursor cursor(data.doc);
change.apply(&cursor);
data.pos += txt.length();
QStringList completions = getCompletions(data);
const QStringList completions = test.getCompletions();
QCOMPARE(completions.size(), 2);
QVERIFY(completions.contains(QLatin1String("Test")));
QVERIFY(completions.contains(QLatin1String("i")));
......@@ -525,8 +454,7 @@ void CppToolsPlugin::test_completion_template_7()
void CppToolsPlugin::test_completion_type_of_pointer_is_typedef()
{
TestData data;
data.srcText = "\n"
const QByteArray source = "\n"
"typedef struct Foo\n"
"{\n"
" int foo;\n"
......@@ -534,18 +462,9 @@ void CppToolsPlugin::test_completion_type_of_pointer_is_typedef()
"Foo *bar;\n"
"@\n"
;
CompletionTestCase test(source, "bar->");
setup(&data);
Utils::ChangeSet change;
QString txt = QLatin1String("bar->");
change.insert(data.pos, txt);
QTextCursor cursor(data.doc);
change.apply(&cursor);
data.pos += txt.length();
QStringList completions = getCompletions(data);
const QStringList completions = test.getCompletions();
QCOMPARE(completions.size(), 2);
QVERIFY(completions.contains(QLatin1String("Foo")));
QVERIFY(completions.contains(QLatin1String("foo")));
......@@ -553,8 +472,7 @@ void CppToolsPlugin::test_completion_type_of_pointer_is_typedef()
void CppToolsPlugin::test_completion_instantiate_full_specialization()
{
TestData data;
data.srcText = "\n"
const QByteArray source = "\n"
"template<typename T>\n"
"struct Template\n"
"{\n"
......@@ -570,18 +488,9 @@ void CppToolsPlugin::test_completion_instantiate_full_specialization()
"Template<char> templateChar;\n"
"@\n"
;
CompletionTestCase test(source, "templateChar.");
setup(&data);
Utils::ChangeSet change;
QString txt = QLatin1String("templateChar.");
change.insert(data.pos, txt);
QTextCursor cursor(data.doc);
change.apply(&cursor);
data.pos += txt.length();
QStringList completions = getCompletions(data);
const QStringList completions = test.getCompletions();
QCOMPARE(completions.size(), 2);
QVERIFY(completions.contains(QLatin1String("Template")));
QVERIFY(completions.contains(QLatin1String("templateChar_i")));
......@@ -592,17 +501,9 @@ void CppToolsPlugin::test_completion()
QFETCH(QByteArray, code);
QFETCH(QStringList, expectedCompletions);
TestData data;
data.srcText = code;
setup(&data);
CompletionTestCase test(code, "c.");
Utils::ChangeSet change;
change.insert(data.pos, QLatin1String("c."));
QTextCursor cursor(data.doc);
change.apply(&cursor);
data.pos += 2;
QStringList actualCompletions = getCompletions(data);
QStringList actualCompletions = test.getCompletions();
actualCompletions.sort();
expectedCompletions.sort();
......@@ -637,7 +538,6 @@ void CppToolsPlugin::test_completion_template_as_base_data()
completions.append(QLatin1String("otherMember"));
QTest::newRow("case: base as template directly") << code << completions;
completions.clear();
code = "\n"
"class Data { int dataMember; };\n"
......@@ -657,7 +557,6 @@ void CppToolsPlugin::test_completion_template_as_base_data()
completions.append(QLatin1String("moreMember"));
QTest::newRow("case: base as class template") << code << completions;