QString makeFunction(FunctionModelItem function, const QString preFix = QString()) { QString fullName; fullName += function->type().toString(); fullName += " "; fullName += preFix; fullName += function->name(); ArgumentList arguments = function->arguments(); QStringList args; for (int i = 0; i < arguments.count(); ++i) { QString arg = arguments[i]->name(); if (arg.isEmpty()) arg = QString("arg%1").arg(i); QString theargs = arguments[i]->type().toString() + " " + arg; if (arguments[i]->defaultValue()) theargs += " = " + arguments[i]->defaultValueExpression(); args += theargs; } fullName += "(" + args.join(", ") + ")"; if (function->isConstant()) fullName += " const"; if (function->isStatic()) fullName = "static " + fullName; return fullName; }
void doFunction(FunctionModelItem &item) { cout << "("; doType(item->type()); cout << " " << item->name().toStdString(); QListIterator<ArgumentModelItem> ai(item->arguments()); while(ai.hasNext()) { cout << " "; ArgumentModelItem item = ai.next(); doArgument(item); } cout << ")"; }
foreach (FunctionModelItem fun, functions) { if (done.contains(fun->name())) continue; // data function out << endl; QStringList fetchMeType; QStringList fetchMeName; ArgumentList arguments = fun->arguments(); for (int i = 0; i < arguments.count(); ++i) { QString type = arguments[i]->type().toString(); type = type.mid(0, type.indexOf(' ')); QString name = arguments[i]->name(); if (arguments[i]->type().indirections()) { type = "int"; name = name + "Count"; } fetchMeType << type; fetchMeName << name; } if (fun->type().toString() != "void") { QString returnType = fun->type().toString(); fetchMeType << returnType; fetchMeName << fun->name(); } if (fetchMeType.isEmpty()) { fetchMeType << "int"; fetchMeName << "foo"; } QStringList knownTypes; knownTypes << "int" << "qreal" << "bool" << "QString" << "QRectF" << "QPointF" << "QPixmap" << "QFont" << "QUrl" << "uint" << "QImage" << "QStringList"; bool knowAllTypes = true; for (int i = 0; i < fetchMeType.count(); ++i) { if (!knownTypes.contains(fetchMeType[i])) { if (!declared.contains(fetchMeType[i])) { out << "Q_DECLARE_METATYPE(" << fetchMeType[i] << ")" << endl; declared.append(fetchMeType[i]); } knowAllTypes = false; } } out << QString("void %1::%2_data()\n{").arg(tstClassName).arg(fun->name()) << endl; if (!knowAllTypes) out << "#if 0" << endl; for (int i = 0; i < fetchMeType.count(); ++i) out << indent << QString("QTest::addColumn<%1>(\"%2\");").arg(fetchMeType[i]).arg(fetchMeName[i]) << endl; bool stubbed = false; // fill out the most common cases if (fetchMeType.count() == 1 && fetchMeType[0] == "bool") { out << indent << "QTest::newRow(\"true\") << true;" << endl; out << indent << "QTest::newRow(\"false\") << false;" << endl; stubbed = true; } if (fetchMeType.count() == 1 && fetchMeType[0] == "QString") { out << indent << "QTest::newRow(\"null\") << QString();" << endl; out << indent << "QTest::newRow(\"foo\") << QString(\"foo\");" << endl; stubbed = true; } if (fetchMeType.count() == 1 && fetchMeType[0] == "int") { out << indent << "QTest::newRow(\"0\") << 0;" << endl; out << indent << "QTest::newRow(\"-1\") << -1;" << endl; stubbed = true; } if (!stubbed) { out << indent << "QTest::newRow(\"null\")"; for (int i = 0; i < fetchMeType.count(); ++i) { out << " << "; if (fetchMeType[i] == "int") out << "0"; else if (fetchMeType[i] == "qreal") out << "0.0"; else if (fetchMeType[i] == "bool") out << "false"; else if (fetchMeType[i] == "QString") out << "QString()"; else out << fetchMeType[i] << "()"; } out << ";" << endl; } if (!knowAllTypes) out << "#endif" << endl; out << "}" << endl; out << endl; out << "// " << convertAccessPolicy(fun->accessPolicy()) << " " << makeFunction(fun) << endl; out << QString("void %1::%2()").arg(tstClassName).arg(fun->name()) << endl; out << "{" << endl; { out << "#if 0" << endl; for (int i = 0; i < fetchMeType.count(); ++i) out << indent << QString("QFETCH(%1, %2);").arg(fetchMeType[i]).arg(fetchMeName[i]) << endl; out << endl; out << indent << "Sub" << className << " " << shortName << ";" << endl; // any possible spies that the class emits // ### check spy args // ### properties out << endl; int spies = 0; for(int i = 0; i < functions.count(); ++i) { FunctionModelItem funt = functions[i]; if (funt->functionType() == CodeModel::Signal) { ArgumentList arguments = funt->arguments(); QStringList args; for (int i = 0; i < arguments.count(); ++i) { args += arguments[i]->type().toString(); } out << indent << QString("QSignalSpy spy%1(&%2, SIGNAL(%3(%4)));").arg(spies++).arg(shortName).arg(funt->name()).arg(args.join(", ")) << endl; } } if (spies > 0) out << endl; bool returnsSomething = (fun->type().toString() != "void"); out << indent; if (returnsSomething) out << "QCOMPARE("; out << shortName << "."; if (fun->accessPolicy() == CodeModel::Protected) out << "call_"; out << fun->name(); out << "("; QStringList args; for (int i = 0; i < arguments.count(); ++i) args.append(arguments[i]->name()); out << args.join(", "); out << ")"; if (returnsSomething) { out << ", " << fun->name() << ")"; } out << ";" << endl; if (spies > 0) out << endl; spies = 0; for(int i = 0; i < functions.count(); ++i) { FunctionModelItem funt = functions[i]; if (funt->functionType() == CodeModel::Signal) { out << indent << QString("QCOMPARE(spy\%1.count(), 0);").arg(spies++) << endl; } } /* // any classes that can be used to check if (!fun->isConstant()) { out << endl; out << indent << "// This function isn't const so you should be able to do comparisons on all the const functions." << endl; for(int i = 0; i < functions.count(); ++i) { FunctionModelItem funt = functions[i]; if (funt->type().toString() != "void") out << indent << "// QCOMPARE(foo." << funt->name() << "(), something);" << endl; } } */ out << "#endif" << endl; out << indent << "QSKIP(\"Test is not implemented.\", SkipAll);" << endl; } out << "}" << endl; done.append(fun->name()); }