| 140 | |
| 141 | template<typename CustomTestFunction = NoopTestFunction> |
| 142 | void executeCompletionTest(const ReferencedTopDUContext& top, const CompletionItems& expectedCompletionItems, |
| 143 | const ClangCodeCompletionContext::ContextFilters& filters = NoMacroOrBuiltin, |
| 144 | CustomTestFunction customTestFunction = {}) |
| 145 | { |
| 146 | DUChainReadLocker lock; |
| 147 | QVERIFY(top); |
| 148 | QVERIFY(top->ast()); |
| 149 | const ParseSessionData::Ptr sessionData(dynamic_cast<ParseSessionData*>(top->ast().data())); |
| 150 | QVERIFY(sessionData); |
| 151 | lock.unlock(); |
| 152 | // TODO: We should not need to pass 'session' to the context, should just use the base class ctor |
| 153 | auto context = createContext(top, sessionData, expectedCompletionItems.position); |
| 154 | context->setFilters(filters); |
| 155 | lock.lock(); |
| 156 | |
| 157 | auto tester = ClangCodeCompletionItemTester(context); |
| 158 | |
| 159 | int previousMatchQuality = 10; |
| 160 | for(const auto& declarationName : expectedCompletionItems.declarationItems){ |
| 161 | const auto declarationItem = tester.findItem(declarationName); |
| 162 | QVERIFY(declarationItem); |
| 163 | QVERIFY(declarationItem->declaration()); |
| 164 | |
| 165 | auto matchQuality = tester.itemData(declarationItem, KTextEditor::CodeCompletionModel::Name, KTextEditor::CodeCompletionModel::MatchQuality).toInt(); |
| 166 | QVERIFY(matchQuality <= previousMatchQuality); |
| 167 | previousMatchQuality = matchQuality; |
| 168 | } |
| 169 | |
| 170 | tester.names.sort(); |
| 171 | QEXPECT_FAIL("look-ahead function primary type argument", "No API in LibClang to determine expected code completion type", Continue); |
| 172 | QEXPECT_FAIL("look-ahead template parameter substitution", "No parameters substitution so far", Continue); |
| 173 | #if CINDEX_VERSION_MINOR < 30 |
| 174 | QEXPECT_FAIL("look-ahead auto item", "Auto type, like many other types, is not exposed through LibClang. We assign DelayedType to it instead of IdentifiedType", Continue); |
| 175 | #endif |
| 176 | if (QTest::currentTestFunction() == QByteArrayLiteral("testImplementAfterEdit") && expectedCompletionItems.position.line() == 3) { |
| 177 | QEXPECT_FAIL("", "TU is not properly updated after edit", Continue); |
| 178 | } |
| 179 | if (QTest::currentTestFunction() == QByteArrayLiteral("testClangCodeCompletion")) { |
| 180 | QEXPECT_FAIL("look-ahead pointer", "self-assignment isn't done anymore, so we don't find any suitable type anymore", Continue); |
| 181 | |
| 182 | if (QVersionNumber::fromString(ClangHelpers::clangVersion()) >= QVersionNumber(9, 0, 0)) { |
| 183 | QEXPECT_FAIL("enum-case", "quite a lot of unrelated cruft is suggested, needs to be fixed upstream", Continue); |
| 184 | } |
| 185 | } |
| 186 | if (tester.names.size() != expectedCompletionItems.completions.size()) { |
| 187 | qDebug() << "different results:\nactual:" << tester.names << "\nexpected:" << expectedCompletionItems.completions; |
| 188 | } |
| 189 | QCOMPARE(tester.names, expectedCompletionItems.completions); |
| 190 | |
| 191 | lock.unlock(); // customTestFunction should lock appropriately |
| 192 | customTestFunction(tester); |
| 193 | } |
| 194 | |
| 195 | template<typename CustomTestFunction = NoopTestFunction> |
| 196 | void executeCompletionTest(const QString& code, const CompletionItems& expectedCompletionItems, |
no test coverage detected