Changeset View
Changeset View
Standalone View
Standalone View
plugins/clang/tests/test_codecompletion.cpp
Show First 20 Lines • Show All 1105 Lines • ▼ Show 20 Line(s) | 1092 | { | |||
---|---|---|---|---|---|
1106 | const auto tester = ClangCodeCompletionItemTester(context); | 1106 | const auto tester = ClangCodeCompletionItemTester(context); | ||
1107 | 1107 | | |||
1108 | QCOMPARE(tester.items.size(), 4); | 1108 | QCOMPARE(tester.items.size(), 4); | ||
1109 | auto item = tester.findItem(QStringLiteral("var")); | 1109 | auto item = tester.findItem(QStringLiteral("var")); | ||
1110 | VERIFY(item); | 1110 | VERIFY(item); | ||
1111 | QCOMPARE(item->declaration()->range().start, CursorInRevision(1, 14)); | 1111 | QCOMPARE(item->declaration()->range().start, CursorInRevision(1, 14)); | ||
1112 | } | 1112 | } | ||
1113 | 1113 | | |||
1114 | struct HintItem | ||||
1115 | { | ||||
1116 | QString hint; | ||||
1117 | bool hasDeclaration; | ||||
1118 | bool operator==(const HintItem& rhs) const | ||||
1119 | { | ||||
1120 | return std::tie(hint, hasDeclaration) == std::tie(rhs.hint, rhs.hasDeclaration); | ||||
1121 | } | ||||
1122 | bool operator<(const HintItem& rhs) const | ||||
1123 | { | ||||
1124 | return std::tie(hint, hasDeclaration) < std::tie(rhs.hint, rhs.hasDeclaration); | ||||
1125 | } | ||||
1126 | QByteArray toString() const | ||||
1127 | { | ||||
1128 | return "HintItem(" + hint.toUtf8() + ", " + (hasDeclaration ? "true" : "false") + ')'; | ||||
1129 | } | ||||
1130 | }; | ||||
1131 | Q_DECLARE_METATYPE(HintItem); | ||||
1132 | using HintItemList = QVector<HintItem>; | ||||
1133 | namespace QTest { | ||||
1134 | template<> | ||||
1135 | char *toString(const HintItem& hint) | ||||
1136 | { | ||||
1137 | return qstrdup(hint.toString()); | ||||
1138 | } | ||||
1139 | template<> | ||||
kfunk: Uhm, I thought there's a generic `char *QTest::toString(const QVector<T>)` helper. But indeed… | |||||
mwolff: I also thought that would be the case - odd, isn't it? | |||||
1140 | char *toString(const HintItemList& hints) | ||||
1141 | { | ||||
1142 | QByteArray ba = "HintItemList("; | ||||
1143 | for (int i = 0, c = hints.size(); i < c; ++i) { | ||||
1144 | ba += hints[i].toString(); | ||||
1145 | if (i == c - 1) { | ||||
1146 | ba += ')'; | ||||
1147 | } else { | ||||
1148 | ba += ", "; | ||||
1149 | } | ||||
1150 | } | ||||
1151 | return qstrdup(ba.constData()); | ||||
1152 | } | ||||
1153 | } | ||||
1154 | | ||||
1114 | void TestCodeCompletion::testArgumentHintCompletion() | 1155 | void TestCodeCompletion::testArgumentHintCompletion() | ||
1115 | { | 1156 | { | ||
1116 | QFETCH(QString, code); | 1157 | QFETCH(QString, code); | ||
1117 | QFETCH(CompletionItems, expectedItems); | 1158 | QFETCH(CompletionItems, expectedItems); | ||
1118 | QFETCH(QStringList, hints); | 1159 | QFETCH(HintItemList, hints); | ||
1119 | 1160 | | |||
1120 | executeCompletionTest(code, expectedItems, NoMacroOrBuiltin, [&](const ClangCodeCompletionItemTester& tester) { | 1161 | executeCompletionTest(code, expectedItems, NoMacroOrBuiltin, [&](const ClangCodeCompletionItemTester& tester) { | ||
1121 | QStringList actualHints; | 1162 | HintItemList actualHints; | ||
1122 | for (const auto& item : tester.items) { | 1163 | for (const auto& item : tester.items) { | ||
1123 | if (item->argumentHintDepth() == 1) { | 1164 | if (item->argumentHintDepth() == 1) { | ||
1124 | actualHints << tester.itemData(item).toString() + tester.itemData(item, KTextEditor:: CodeCompletionModel::Arguments).toString(); | 1165 | actualHints << HintItem{ | ||
1166 | tester.itemData(item).toString() + tester.itemData(item, KTextEditor:: CodeCompletionModel::Arguments).toString(), | ||||
1167 | item->declaration() | ||||
1168 | }; | ||||
1125 | } | 1169 | } | ||
1126 | } | 1170 | } | ||
1127 | actualHints.sort(); | 1171 | std::sort(hints.begin(), hints.end()); | ||
1128 | hints.sort(); | 1172 | std::sort(actualHints.begin(), actualHints.end()); | ||
1173 | QEXPECT_FAIL("member function", "clang_getCompletionParent returns nothing, thus decl lookup fails", Continue); | ||||
1174 | QEXPECT_FAIL("namespaced function", "clang_getCompletionParent returns nothing, thus decl lookup fails", Continue); | ||||
1175 | QEXPECT_FAIL("constructor", "clang_getCompletionParent returns nothing, thus decl lookup fails", Continue); | ||||
1176 | QEXPECT_FAIL("namespaced constructor", "clang_getCompletionParent returns nothing, thus decl lookup fails", Continue); | ||||
1129 | QCOMPARE(actualHints, hints); | 1177 | QCOMPARE(actualHints, hints); | ||
1130 | }); | 1178 | }); | ||
1131 | } | 1179 | } | ||
1132 | 1180 | | |||
1133 | void TestCodeCompletion::testArgumentHintCompletion_data() | 1181 | void TestCodeCompletion::testArgumentHintCompletion_data() | ||
1134 | { | 1182 | { | ||
1135 | #if CINDEX_VERSION_MINOR < 30 | 1183 | #if CINDEX_VERSION_MINOR < 30 | ||
1136 | QSKIP("You need at least LibClang 3.7"); | 1184 | QSKIP("You need at least LibClang 3.7"); | ||
1137 | #endif | 1185 | #endif | ||
1186 | qRegisterMetaType<HintItemList>("HintItemList"); | ||||
1138 | 1187 | | |||
1139 | QTest::addColumn<QString>("code"); | 1188 | QTest::addColumn<QString>("code"); | ||
1140 | QTest::addColumn<CompletionItems>("expectedItems"); | 1189 | QTest::addColumn<CompletionItems>("expectedItems"); | ||
1141 | QTest::addColumn<QStringList>("hints"); | 1190 | QTest::addColumn<HintItemList>("hints"); | ||
1142 | 1191 | | |||
1143 | QTest::newRow("global function") | 1192 | QTest::newRow("global function") | ||
1144 | << "void foo(int);\n" | 1193 | << "void foo(int);\n" | ||
1145 | "int main() { \nfoo( " | 1194 | "int main() { \nfoo( " | ||
1146 | << CompletionItems{{2,4}, { | 1195 | << CompletionItems{{2,4}, { | ||
1147 | "foo", "foo", | 1196 | "foo", "foo", | ||
1148 | "main" | 1197 | "main" | ||
1149 | }} | 1198 | }} | ||
1150 | << QStringList{"foo(int)"}; | 1199 | << HintItemList{{"foo(int)", true}}; | ||
1200 | | ||||
1201 | QTest::newRow("namespaced function") | ||||
1202 | << "namespace ns { void foo(int); }\n" | ||||
1203 | "int main() { \nns::foo( " | ||||
1204 | << CompletionItems{{2,4}, { | ||||
1205 | "foo" | ||||
1206 | }} | ||||
1207 | << HintItemList{{"foo(int)", true}}; | ||||
1151 | 1208 | | |||
1152 | QTest::newRow("member function") | 1209 | QTest::newRow("member function") | ||
1153 | << "struct Struct{ void foo(int);}\n" | 1210 | << "struct Struct{ void foo(int);}\n" | ||
1154 | "int main() {Struct s; \ns.foo( " | 1211 | "int main() {Struct s; \ns.foo( " | ||
1155 | << CompletionItems{{2,6}, { | 1212 | << CompletionItems{{2,6}, { | ||
1156 | "Struct", "foo", | 1213 | "Struct", "foo", | ||
1157 | "main", "s" | 1214 | "main", "s" | ||
1158 | }} | 1215 | }} | ||
1159 | << QStringList{"foo(int)"}; | 1216 | << HintItemList{{"foo(int)", true}}; | ||
1160 | 1217 | | |||
1161 | QTest::newRow("template function") | 1218 | QTest::newRow("template function") | ||
1162 | << "template <typename T> void foo(T);\n" | 1219 | << "template <typename T> void foo(T);\n" | ||
1163 | "int main() { \nfoo( " | 1220 | "int main() { \nfoo( " | ||
1164 | << CompletionItems{{2,6}, { | 1221 | << CompletionItems{{2,6}, { | ||
1165 | "foo", "foo", | 1222 | "foo", "foo", | ||
1166 | "main" | 1223 | "main" | ||
1167 | }} | 1224 | }} | ||
1168 | << QStringList{"foo(T)"}; | 1225 | << HintItemList{{"foo(T)", true}}; | ||
1169 | 1226 | | |||
1170 | QTest::newRow("overloaded functions") | 1227 | QTest::newRow("overloaded functions") | ||
1171 | << "void foo(int); void foo(int, double)\n" | 1228 | << "void foo(int); void foo(int, double)\n" | ||
1172 | "int main() { \nfoo( " | 1229 | "int main() { \nfoo( " | ||
1173 | << CompletionItems{{2,6}, { | 1230 | << CompletionItems{{2,6}, { | ||
1174 | "foo", "foo", "foo", "foo", | 1231 | "foo", "foo", "foo", "foo", | ||
1175 | "main" | 1232 | "main" | ||
1176 | }} | 1233 | }} | ||
1177 | << QStringList{"foo(int)", "foo(int, double)"}; | 1234 | << HintItemList{ | ||
1235 | {"foo(int)", true}, | ||||
1236 | {"foo(int, double)", true} | ||||
1237 | }; | ||||
1178 | 1238 | | |||
1179 | QTest::newRow("overloaded functions2") | 1239 | QTest::newRow("overloaded functions2") | ||
1180 | << "void foo(int); void foo(int, double)\n" | 1240 | << "void foo(int); void foo(int, double)\n" | ||
1181 | "int main() { foo(1,\n " | 1241 | "int main() { foo(1,\n " | ||
1182 | << CompletionItems{{2,1}, { | 1242 | << CompletionItems{{2,1}, { | ||
1183 | "foo", "foo", "foo", | 1243 | "foo", "foo", "foo", | ||
1184 | "main" | 1244 | "main" | ||
1185 | }} | 1245 | }} | ||
1186 | << QStringList{"foo(int, double)"}; | 1246 | << HintItemList{{"foo(int, double)", true}}; | ||
1187 | 1247 | | |||
1188 | QTest::newRow("constructor") | 1248 | QTest::newRow("constructor") | ||
1189 | << "struct foo { foo(int); foo(int, double); }\n" | 1249 | << "struct foo { foo(int); foo(int, double); }\n" | ||
1190 | "int main() { foo f(\n " | 1250 | "int main() { foo f(\n " | ||
1191 | << CompletionItems{{2,1}, { | 1251 | << CompletionItems{{2,1}, { | ||
1192 | "f", "foo", "foo", "foo", "foo", "foo", | 1252 | "f", "foo", "foo", "foo", "foo", "foo", | ||
1193 | "main" | 1253 | "main" | ||
1194 | }} | 1254 | }} | ||
1195 | << QStringList{"foo(int)", "foo(int, double)", "foo(foo &&)", "foo(const foo &)"}; | 1255 | << HintItemList{ | ||
1256 | {"foo(int)", true}, | ||||
1257 | {"foo(int, double)", true}, | ||||
1258 | {"foo(foo &&)", false}, | ||||
1259 | {"foo(const foo &)", false} | ||||
1260 | }; | ||||
1196 | 1261 | | |||
1197 | QTest::newRow("constructor2") | 1262 | QTest::newRow("constructor2") | ||
1198 | << "struct foo { foo(int); foo(int, double); }\n" | 1263 | << "struct foo { foo(int); foo(int, double); }\n" | ||
1199 | "int main() { foo f(1,\n " | 1264 | "int main() { foo f(1,\n " | ||
1200 | << CompletionItems{{2,1}, { | 1265 | << CompletionItems{{2,1}, { | ||
1201 | "f", "foo", "foo", | 1266 | "f", "foo", "foo", | ||
1202 | "main" | 1267 | "main" | ||
1203 | }} | 1268 | }} | ||
1204 | << QStringList{"foo(int, double)"}; | 1269 | << HintItemList{ | ||
1270 | {"foo(int, double)", true} | ||||
1271 | }; | ||||
1272 | | ||||
1273 | QTest::newRow("namespaced constructor") | ||||
1274 | << "namespace ns { struct foo { foo(int); foo(int, double); } }\n" | ||||
1275 | "int main() { ns::foo f(\n " | ||||
1276 | << CompletionItems{{2,1}, { | ||||
1277 | "f", "foo", "foo", "foo", "foo", | ||||
1278 | "main", "ns" | ||||
1279 | }} | ||||
1280 | << HintItemList{ | ||||
1281 | {"foo(int)", true}, | ||||
1282 | {"foo(int, double)", true}, | ||||
1283 | {"foo(ns::foo &&)", false}, | ||||
1284 | {"foo(const ns::foo &)", false} | ||||
1285 | }; | ||||
1205 | } | 1286 | } | ||
1206 | 1287 | | |||
1207 | void TestCodeCompletion::testArgumentHintCompletionDefaultParameters() | 1288 | void TestCodeCompletion::testArgumentHintCompletionDefaultParameters() | ||
1208 | { | 1289 | { | ||
1209 | #if CINDEX_VERSION_MINOR < 30 | 1290 | #if CINDEX_VERSION_MINOR < 30 | ||
1210 | QSKIP("You need at least LibClang 3.7"); | 1291 | QSKIP("You need at least LibClang 3.7"); | ||
1211 | #endif | 1292 | #endif | ||
1212 | 1293 | | |||
▲ Show 20 Lines • Show All 85 Lines • Show Last 20 Lines |
Uhm, I thought there's a generic char *QTest::toString(const QVector<T>) helper. But indeed there isn't.