forked from qt-creator/qt-creator
debugger: add auto tests for QList
This commit is contained in:
@@ -888,10 +888,13 @@ static inline void dumpStdWStringValue(QDumper &d, const std::wstring &str)
|
||||
}
|
||||
|
||||
// Tell the calling routine whether a global "childnumchild" attribute makes sense
|
||||
enum InnerValueResult { InnerValueNotHandled,
|
||||
InnerValueChildrenSpecified,
|
||||
InnerValueNoFurtherChildren,
|
||||
InnerValueFurtherChildren };
|
||||
enum InnerValueResult
|
||||
{
|
||||
InnerValueNotHandled,
|
||||
InnerValueChildrenSpecified,
|
||||
InnerValueNoFurtherChildren,
|
||||
InnerValueFurtherChildren
|
||||
};
|
||||
|
||||
static inline void dumpChildNumChildren(QDumper &d, InnerValueResult innerValueResult)
|
||||
{
|
||||
@@ -909,12 +912,39 @@ static inline void dumpChildNumChildren(QDumper &d, InnerValueResult innerValueR
|
||||
}
|
||||
|
||||
// Called by templates, so, not static.
|
||||
static void qDumpInnerQCharValue(QDumper &d, QChar c, const char *field)
|
||||
{
|
||||
char buf[30];
|
||||
sprintf(buf, "'?', ucs=%d", c.unicode());
|
||||
if (c.isPrint() && c.unicode() < 127)
|
||||
buf[1] = char(c.unicode());
|
||||
d.putCommaIfNeeded();
|
||||
d.putItem(field, buf);
|
||||
d.putItem("numchild", 0);
|
||||
}
|
||||
|
||||
static void qDumpInnerCharValue(QDumper &d, char c, const char *field)
|
||||
{
|
||||
char buf[30];
|
||||
sprintf(buf, "'?', ascii=%d", c);
|
||||
if (QChar(c).isPrint() && c < 127)
|
||||
buf[1] = c;
|
||||
d.putCommaIfNeeded();
|
||||
d.putItem(field, buf);
|
||||
d.putItem("numchild", 0);
|
||||
}
|
||||
|
||||
InnerValueResult qDumpInnerValueHelper(QDumper &d, const char *type, const void *addr,
|
||||
const char *field = "value")
|
||||
{
|
||||
char buf[30];
|
||||
type = stripNamespace(type);
|
||||
switch (type[1]) {
|
||||
case 'h':
|
||||
if (isEqual(type, "char")) {
|
||||
qDumpInnerCharValue(d, *(char *)addr, field);
|
||||
return InnerValueNoFurtherChildren;
|
||||
}
|
||||
return InnerValueNotHandled;
|
||||
case 'l':
|
||||
if (isEqual(type, "float"))
|
||||
{ d.putItem(field, *(float*)addr); return InnerValueNoFurtherChildren; }
|
||||
@@ -924,12 +954,12 @@ InnerValueResult qDumpInnerValueHelper(QDumper &d, const char *type, const void
|
||||
d.putItem(field, *(int*)addr);
|
||||
return InnerValueNoFurtherChildren;
|
||||
}
|
||||
if (isEqual(type, "unsigned")) {
|
||||
if (isEqual(type, "unsigned") || isEqual(type, "unsigned int")) {
|
||||
d.putItem(field, *(unsigned int*)addr);
|
||||
return InnerValueNoFurtherChildren;
|
||||
}
|
||||
if (isEqual(type, "unsigned int")) {
|
||||
d.putItem(field, *(unsigned int*)addr);
|
||||
if (isEqual(type, "unsigned char")) {
|
||||
qDumpInnerCharValue(d, *(char *)addr, field);
|
||||
return InnerValueNoFurtherChildren;
|
||||
}
|
||||
if (isEqual(type, "unsigned long")) {
|
||||
@@ -973,13 +1003,7 @@ InnerValueResult qDumpInnerValueHelper(QDumper &d, const char *type, const void
|
||||
return InnerValueNotHandled;
|
||||
case 'C':
|
||||
if (isEqual(type, "QChar")) {
|
||||
d.putCommaIfNeeded();
|
||||
QChar c = *(QChar *)addr;
|
||||
sprintf(buf, "'?', ucs=%d", c.unicode());
|
||||
if (c.isPrint() && c.unicode() < 127)
|
||||
buf[1] = char(c.unicode());
|
||||
d.putItem(field, buf);
|
||||
d.putItem("numchild", 0);
|
||||
qDumpInnerQCharValue(d, *(QChar*)addr, field);
|
||||
return InnerValueNoFurtherChildren;
|
||||
}
|
||||
return InnerValueNotHandled;
|
||||
@@ -1014,8 +1038,8 @@ InnerValueResult qDumpInnerValueHelper(QDumper &d, const char *type, const void
|
||||
case 'S':
|
||||
if (isEqual(type, "QString")) {
|
||||
d.putCommaIfNeeded();
|
||||
d.put(field).put("encoded=\"2\"");
|
||||
d.putItem(field, *(QString*)addr);
|
||||
d.put(',').put(field).put("encoded=\"2\"");
|
||||
return InnerValueNoFurtherChildren;
|
||||
}
|
||||
return InnerValueNotHandled;
|
||||
@@ -1200,9 +1224,9 @@ static void qDumpQByteArray(QDumper &d)
|
||||
d.putItem("valueencoded", "1");
|
||||
d.putItem("type", NS"QByteArray");
|
||||
d.putItem("numchild", ba.size());
|
||||
d.putItem("childtype", "char");
|
||||
d.putItem("childnumchild", "0");
|
||||
if (d.dumpChildren) {
|
||||
d.putItem("childtype", "char");
|
||||
d.putItem("childnumchild", "0");
|
||||
d.beginChildren();
|
||||
char buf[20];
|
||||
for (int i = 0; i != ba.size(); ++i) {
|
||||
@@ -1221,13 +1245,7 @@ static void qDumpQByteArray(QDumper &d)
|
||||
|
||||
static void qDumpQChar(QDumper &d)
|
||||
{
|
||||
QChar c = *(QChar *)d.data;
|
||||
char buf[100];
|
||||
sprintf(buf, "'?', ucs=%d", c.unicode());
|
||||
if (c.isPrint() && c.unicode() < 127)
|
||||
buf[1] = char(c.unicode());
|
||||
d.putItem("value", buf);
|
||||
d.putItem("numchild", 0);
|
||||
qDumpInnerQCharValue(d, *reinterpret_cast<const QChar *>(d.data), "value");
|
||||
d.disarm();
|
||||
}
|
||||
|
||||
@@ -1628,9 +1646,8 @@ static void qDumpQList(QDumper &d)
|
||||
d.putItemCount("value", n);
|
||||
d.putItem("valuedisabled", "true");
|
||||
d.putItem("numchild", n);
|
||||
d.putItem("childtype", d.innertype);
|
||||
InnerValueResult innerValueResult = InnerValueChildrenSpecified;
|
||||
if (d.dumpChildren) {
|
||||
InnerValueResult innerValueResult = InnerValueChildrenSpecified;
|
||||
unsigned innerSize = d.extraInt[0];
|
||||
bool innerTypeIsPointer = isPointerType(d.innertype);
|
||||
QByteArray strippedInnerType = stripPointerType(d.innertype);
|
||||
@@ -1678,8 +1695,8 @@ static void qDumpQList(QDumper &d)
|
||||
if (n < nn)
|
||||
d.putEllipsis();
|
||||
d.endChildren();
|
||||
dumpChildNumChildren(d, innerValueResult);
|
||||
}
|
||||
dumpChildNumChildren(d, innerValueResult);
|
||||
d.disarm();
|
||||
}
|
||||
|
||||
@@ -1697,7 +1714,6 @@ static void qDumpQLinkedList(QDumper &d)
|
||||
d.putItemCount("value", n);
|
||||
d.putItem("valuedisabled", "true");
|
||||
d.putItem("numchild", n);
|
||||
d.putItem("childtype", d.innertype);
|
||||
InnerValueResult innerValueResult = InnerValueChildrenSpecified;
|
||||
if (d.dumpChildren) {
|
||||
//unsigned innerSize = d.extraInt[0];
|
||||
@@ -1973,21 +1989,33 @@ static void qDumpQObject(QDumper &d)
|
||||
d.beginChildren();
|
||||
d.beginHash();
|
||||
d.putItem("name", "properties");
|
||||
d.putItem("addr", d.data);
|
||||
// using 'addr' does not work as 'exp' is recreated as
|
||||
// (type *)addr, and here we have different 'types':
|
||||
// QObject vs QObjectPropertyList!
|
||||
//d.putItem("addr", d.data);
|
||||
d.beginItem("exp");
|
||||
d.put("*(class "NSX"QObject"NSY"*)").put(d.data);
|
||||
d.endItem();
|
||||
d.putItem("type", NS"QObjectPropertyList");
|
||||
d.putItemCount("value", mo->propertyCount());
|
||||
d.putItem("numchild", mo->propertyCount());
|
||||
d.endHash();
|
||||
d.beginHash();
|
||||
d.putItem("name", "signals");
|
||||
d.putItem("addr", d.data);
|
||||
//d.putItem("addr", d.data);
|
||||
d.beginItem("exp");
|
||||
d.put("*(class "NSX"QObject"NSY"*)").put(d.data);
|
||||
d.endItem();
|
||||
d.putItem("type", NS"QObjectSignalList");
|
||||
d.putItemCount("value", signalCount);
|
||||
d.putItem("numchild", signalCount);
|
||||
d.endHash();
|
||||
d.beginHash();
|
||||
d.putItem("name", "slots");
|
||||
d.putItem("addr", d.data);
|
||||
//d.putItem("addr", d.data);
|
||||
d.beginItem("exp");
|
||||
d.put("*(class "NSX"QObject"NSY"*)").put(d.data);
|
||||
d.endItem();
|
||||
d.putItem("type", NS"QObjectSlotList");
|
||||
d.putItemCount("value", slotCount);
|
||||
d.putItem("numchild", slotCount);
|
||||
@@ -1996,7 +2024,10 @@ static void qDumpQObject(QDumper &d)
|
||||
if (!objectChildren.empty()) {
|
||||
d.beginHash();
|
||||
d.putItem("name", "children");
|
||||
d.putItem("addr", d.data);
|
||||
//d.putItem("addr", d.data);
|
||||
d.beginItem("exp");
|
||||
d.put("*(class "NSX"QObject"NSY"*)").put(d.data);
|
||||
d.endItem();
|
||||
d.putItem("type", NS"QObjectChildList");
|
||||
d.putItemCount("value", objectChildren.size());
|
||||
d.putItem("numchild", objectChildren.size());
|
||||
@@ -2316,9 +2347,9 @@ static void qDumpQObjectMethodList(QDumper &d)
|
||||
d.putItem("addr", "<synthetic>");
|
||||
d.putItem("type", NS"QObjectMethodList");
|
||||
d.putItem("numchild", mo->methodCount());
|
||||
d.putItem("childtype", "QMetaMethod::Method");
|
||||
d.putItem("childnumchild", "0");
|
||||
if (d.dumpChildren) {
|
||||
d.putItem("childtype", "QMetaMethod::Method");
|
||||
d.putItem("childnumchild", "0");
|
||||
d.beginChildren();
|
||||
for (int i = 0; i != mo->methodCount(); ++i) {
|
||||
const QMetaMethod & method = mo->method(i);
|
||||
@@ -2731,9 +2762,9 @@ static void qDumpQStringList(QDumper &d)
|
||||
d.putItemCount("value", n);
|
||||
d.putItem("valuedisabled", "true");
|
||||
d.putItem("numchild", n);
|
||||
d.putItem("childtype", NS"QString");
|
||||
d.putItem("childnumchild", "0");
|
||||
if (d.dumpChildren) {
|
||||
d.putItem("childtype", NS"QString");
|
||||
d.putItem("childnumchild", "0");
|
||||
if (n > 1000)
|
||||
n = 1000;
|
||||
d.beginChildren();
|
||||
@@ -3048,8 +3079,8 @@ static void qDumpStdSetHelper(QDumper &d)
|
||||
d.putItem("numchild", nn);
|
||||
d.putItem("valueoffset", d.extraInt[0]);
|
||||
|
||||
InnerValueResult innerValueResult = InnerValueChildrenSpecified;
|
||||
if (d.dumpChildren) {
|
||||
InnerValueResult innerValueResult = InnerValueChildrenSpecified;
|
||||
int valueOffset = 0; // d.extraInt[0];
|
||||
QByteArray strippedInnerType = stripPointerType(d.innertype);
|
||||
const char *stripped =
|
||||
@@ -3071,8 +3102,8 @@ static void qDumpStdSetHelper(QDumper &d)
|
||||
if (it != set.end())
|
||||
d.putEllipsis();
|
||||
d.endChildren();
|
||||
dumpChildNumChildren(d, innerValueResult);
|
||||
}
|
||||
dumpChildNumChildren(d, innerValueResult);
|
||||
d.disarm();
|
||||
}
|
||||
|
||||
@@ -3159,8 +3190,8 @@ static void qDumpStdVector(QDumper &d)
|
||||
d.putItemCount("value", n);
|
||||
d.putItem("valuedisabled", "true");
|
||||
d.putItem("numchild", n);
|
||||
InnerValueResult innerValueResult = InnerValueChildrenSpecified;
|
||||
if (d.dumpChildren) {
|
||||
InnerValueResult innerValueResult = InnerValueChildrenSpecified;
|
||||
unsigned innersize = d.extraInt[0];
|
||||
QByteArray strippedInnerType = stripPointerType(d.innertype);
|
||||
const char *stripped =
|
||||
@@ -3178,8 +3209,8 @@ static void qDumpStdVector(QDumper &d)
|
||||
if (n < nn)
|
||||
d.putEllipsis();
|
||||
d.endChildren();
|
||||
dumpChildNumChildren(d, innerValueResult);
|
||||
}
|
||||
dumpChildNumChildren(d, innerValueResult);
|
||||
d.disarm();
|
||||
}
|
||||
|
||||
|
||||
@@ -75,6 +75,16 @@ static const char jsont1[] =
|
||||
"{\"Size\":100564,\"UID\":0,\"GID\":0,\"Permissions\":33261,"
|
||||
"\"ATime\":1242370878000,\"MTime\":1239154689000}";
|
||||
|
||||
struct Int3 {
|
||||
Int3() { i1 = 42; i2 = 43; i3 = 44; }
|
||||
int i1, i2, i3;
|
||||
};
|
||||
|
||||
struct QString3 {
|
||||
QString3() { s1 = "a"; s2 = "b"; s3 = "c"; }
|
||||
QString s1, s2, s3;
|
||||
};
|
||||
|
||||
class tst_Debugger : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -114,6 +124,7 @@ private slots:
|
||||
|
||||
void dumperCompatibility();
|
||||
void dumpQHash();
|
||||
void dumpQList();
|
||||
void dumpQObject();
|
||||
void dumpQString();
|
||||
void dumpQVariant();
|
||||
@@ -388,6 +399,76 @@ void tst_Debugger::dumpQHash()
|
||||
hash.insert("!", QList<int>() << 1 << 2);
|
||||
}
|
||||
|
||||
void tst_Debugger::dumpQList()
|
||||
{
|
||||
QList<int> ilist;
|
||||
testDumper("value='<0 items>',valuedisabled='true',numchild='0',"
|
||||
"internal='1',childtype='int',children=[]",
|
||||
&ilist, NS"QList", true, "int");
|
||||
ilist.append(1);
|
||||
ilist.append(2);
|
||||
testDumper("value='<2 items>',valuedisabled='true',numchild='2',"
|
||||
"internal='1',childtype='int',children=["
|
||||
"{name='0',addr='" + str(&ilist.at(0)) + "',value='1'},"
|
||||
"{name='1',addr='" + str(&ilist.at(1)) + "',value='2'}],"
|
||||
"childnumchild='0'",
|
||||
&ilist, NS"QList", true, "int");
|
||||
|
||||
QList<char> clist;
|
||||
testDumper("value='<0 items>',valuedisabled='true',numchild='0',"
|
||||
"internal='1',childtype='char',children=[]",
|
||||
&clist, NS"QList", true, "char");
|
||||
clist.append('a');
|
||||
clist.append('b');
|
||||
testDumper("value='<2 items>',valuedisabled='true',numchild='2',"
|
||||
"internal='1',childtype='char',children=["
|
||||
"{name='0',addr='" + str(&clist.at(0)) + "',"
|
||||
"value=''a', ascii=97',numchild='0'},"
|
||||
"{name='1',addr='" + str(&clist.at(1)) + "',"
|
||||
"value=''b', ascii=98',numchild='0'}],"
|
||||
"childnumchild='0'",
|
||||
&clist, NS"QList", true, "char");
|
||||
|
||||
QList<QString> slist;
|
||||
testDumper("value='<0 items>',valuedisabled='true',numchild='0',"
|
||||
"internal='1',childtype='QString',children=[]",
|
||||
&slist, NS"QList", true, "QString");
|
||||
slist.append("a");
|
||||
slist.append("b");
|
||||
testDumper("value='<2 items>',valuedisabled='true',numchild='2',"
|
||||
"internal='1',childtype='QString',children=["
|
||||
"{name='0',addr='" + str(&slist.at(0)) + "',"
|
||||
"value='YQA=',valueencoded='2'},"
|
||||
"{name='1',addr='" + str(&slist.at(1)) + "',"
|
||||
"value='YgA=',valueencoded='2'}],"
|
||||
"childnumchild='0'",
|
||||
&slist, NS"QList", true, "QString");
|
||||
|
||||
QList<Int3> i3list;
|
||||
testDumper("value='<0 items>',valuedisabled='true',numchild='0',"
|
||||
"internal='0',childtype='Int3',children=[]",
|
||||
&i3list, NS"QList", true, "Int3");
|
||||
i3list.append(Int3());
|
||||
i3list.append(Int3());
|
||||
testDumper("value='<2 items>',valuedisabled='true',numchild='2',"
|
||||
"internal='0',childtype='Int3',children=["
|
||||
"{name='0',addr='" + str(&i3list.at(0)) + "'},"
|
||||
"{name='1',addr='" + str(&i3list.at(1)) + "'}]",
|
||||
&i3list, NS"QList", true, "Int3");
|
||||
|
||||
QList<QString3> s3list;
|
||||
testDumper("value='<0 items>',valuedisabled='true',numchild='0',"
|
||||
"internal='0',childtype='QString3',children=[]",
|
||||
&s3list, NS"QList", true, "QString3");
|
||||
s3list.append(QString3());
|
||||
s3list.append(QString3());
|
||||
testDumper("value='<2 items>',valuedisabled='true',numchild='2',"
|
||||
"internal='0',childtype='QString3',children=["
|
||||
"{name='0',addr='" + str(&s3list.at(0)) + "'},"
|
||||
"{name='1',addr='" + str(&s3list.at(1)) + "'}]",
|
||||
&s3list, NS"QList", true, "QString3");
|
||||
}
|
||||
|
||||
void tst_Debugger::dumpQObject()
|
||||
{
|
||||
QObject parent;
|
||||
@@ -402,7 +483,7 @@ void tst_Debugger::dumpQObject()
|
||||
"value='<2 items>',numchild='2'},"
|
||||
"{name='slots',exp='*(class '$T'*)$A',type='$TSlotList',"
|
||||
"value='<2 items>',numchild='2'},"
|
||||
"{name='parent',value='0x0',type='$T *'},"
|
||||
"{name='parent',value='0x0',type='$T *',numchild='0'},"
|
||||
"{name='className',value='QObject',type='',numchild='0'}]",
|
||||
&parent, NS"QObject", true);
|
||||
/*
|
||||
@@ -432,7 +513,7 @@ void tst_Debugger::dumpQObject()
|
||||
"value='<2 items>',numchild='2'},"
|
||||
"{name='parent',addr='" + str(&parent) + "',"
|
||||
"value='QQAgAFAAYQByAGUAbgB0AA==',valueencoded='2',type='$T',"
|
||||
"displayedtype='QObject'},"
|
||||
"displayedtype='QObject',numchild='1'},"
|
||||
"{name='className',value='QObject',type='',numchild='0'}]";
|
||||
testDumper(ba, &child, NS"QObject", true);
|
||||
QObject::connect(&child, SIGNAL(destroyed()), qApp, SLOT(quit()));
|
||||
|
||||
@@ -999,12 +999,35 @@ void testQVectorOfQList()
|
||||
}
|
||||
|
||||
|
||||
class Goo
|
||||
{
|
||||
public:
|
||||
Goo(const QString& str, const int n) :
|
||||
str_(str), n_(n)
|
||||
{
|
||||
}
|
||||
private:
|
||||
QString str_;
|
||||
int n_;
|
||||
};
|
||||
|
||||
typedef QList<Goo> GooList;
|
||||
|
||||
void testNoArgumentName(int i, int, int k)
|
||||
{
|
||||
GooList list;
|
||||
list.append(Goo("Hello", 1));
|
||||
list.append(Goo("World", 2));
|
||||
|
||||
QList<Goo> list2;
|
||||
list2.append(Goo("Hello", 1));
|
||||
list2.append(Goo("World", 2));
|
||||
|
||||
i = 1000;
|
||||
k = 2000;
|
||||
++k;
|
||||
++k;
|
||||
|
||||
}
|
||||
|
||||
void foo() {}
|
||||
|
||||
Reference in New Issue
Block a user