~pyside/pyside/apiextractor

« back to all changes in this revision

Viewing changes to tests/testconversionruletag.cpp

  • Committer: Hugo Parente Lima
  • Author(s): Marcelo Lira
  • Date: 2012-03-09 22:10:19 UTC
  • Revision ID: git-v1:35ab8b8e722b73a3a3ed9312379f6ab849252e19
Added improved functionality for the 'conversion-rule' tag.

It works for primitive, container and value types. Object types doesn't
have conversion rules because they can not have implicit conversions,
and the regular conversion is always the same (get C++ object held on
Python wrapper, and finding/creating a Python wrapper to a C++ pointer).

Unit tests were added.
Documentation was updated.

Reviewed by Luciano Wolf <luciano.wolf@openbossa.org>
Reviewed by Renato Araújo <renato.filho@openbossa.org>

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
#include <QFile>
28
28
#include <QTemporaryFile>
29
29
 
30
 
void TestConversionRuleTag::testConversionRuleTag()
 
30
void TestConversionRuleTag::testConversionRuleTagWithFile()
31
31
{
32
32
    // temp file used later
33
33
    const char conversionData[] = "Hi! I'm a conversion rule.";
38
38
 
39
39
    const char cppCode[] = "struct A {};";
40
40
    QString xmlCode = "\
41
 
    <typesystem package=\"Foo\">\
 
41
    <typesystem package='Foo'>\
42
42
        <value-type name='A'>\
43
43
            <conversion-rule file='"+ file.fileName() +"' />\
44
44
        </value-type>\
52
52
    QCOMPARE(typeEntry->conversionRule(), QString(conversionData));
53
53
}
54
54
 
 
55
void TestConversionRuleTag::testConversionRuleTagReplace()
 
56
{
 
57
    const char cppCode[] = "\
 
58
    struct A {\
 
59
        A();\
 
60
        A(const char*, int);\
 
61
    };\
 
62
    struct B {\
 
63
        A createA();\
 
64
    };\
 
65
    ";
 
66
    const char* xmlCode = "\
 
67
    <typesystem package='Foo'>\
 
68
        <primitive-type name='int'/>\
 
69
        <primitive-type name='char'/>\
 
70
        <primitive-type name='A'>\
 
71
            <conversion-rule>\
 
72
                <native-to-target>\
 
73
                DoThis();\
 
74
                return ConvertFromCppToPython(%IN);\
 
75
                </native-to-target>\
 
76
                <target-to-native>\
 
77
                    <add-conversion type='TargetNone' check='%IN == Target_None'>\
 
78
                    DoThat();\
 
79
                    DoSomething();\
 
80
                    %OUT = A();\
 
81
                    </add-conversion>\
 
82
                    <add-conversion type='B' check='CheckIfInputObjectIsB(%IN)'>\
 
83
                    %OUT = %IN.createA();\
 
84
                    </add-conversion>\
 
85
                    <add-conversion type='String' check='String_Check(%IN)'>\
 
86
                    %OUT = new A(String_AsString(%IN), String_GetSize(%IN));\
 
87
                    </add-conversion>\
 
88
                </target-to-native>\
 
89
            </conversion-rule>\
 
90
        </primitive-type>\
 
91
        <value-type name='B'/>\
 
92
    </typesystem>";
 
93
 
 
94
    TestUtil t(cppCode, xmlCode);
 
95
    TypeDatabase* typeDb = TypeDatabase::instance();
 
96
    PrimitiveTypeEntry* typeA = typeDb->findPrimitiveType("A");
 
97
    QVERIFY(typeA);
 
98
 
 
99
    CustomConversion* conversion = typeA->customConversion();
 
100
    QVERIFY(conversion);
 
101
 
 
102
    QCOMPARE(typeA, conversion->ownerType());
 
103
    QCOMPARE(conversion->nativeToTargetConversion().trimmed(), QString("DoThis();                return ConvertFromCppToPython(%IN);"));
 
104
 
 
105
    QVERIFY(conversion->replaceOriginalTargetToNativeConversions());
 
106
    QVERIFY(conversion->hasTargetToNativeConversions());
 
107
    QCOMPARE(conversion->targetToNativeConversions().size(), 3);
 
108
 
 
109
    CustomConversion::TargetToNativeConversion* toNative = conversion->targetToNativeConversions().at(0);
 
110
    QVERIFY(toNative);
 
111
    QCOMPARE(toNative->sourceTypeName(), QString("TargetNone"));
 
112
    QVERIFY(toNative->isCustomType());
 
113
    QCOMPARE(toNative->sourceType(), (const TypeEntry*)0);
 
114
    QCOMPARE(toNative->sourceTypeCheck(), QString("%IN == Target_None"));
 
115
    QCOMPARE(toNative->conversion().trimmed(), QString("DoThat();                    DoSomething();                    %OUT = A();"));
 
116
 
 
117
    toNative = conversion->targetToNativeConversions().at(1);
 
118
    QVERIFY(toNative);
 
119
    QCOMPARE(toNative->sourceTypeName(), QString("B"));
 
120
    QVERIFY(!toNative->isCustomType());
 
121
    TypeEntry* typeB = typeDb->findType("B");
 
122
    QVERIFY(typeB);
 
123
    QCOMPARE(toNative->sourceType(), typeB);
 
124
    QCOMPARE(toNative->sourceTypeCheck(), QString("CheckIfInputObjectIsB(%IN)"));
 
125
    QCOMPARE(toNative->conversion().trimmed(), QString("%OUT = %IN.createA();"));
 
126
 
 
127
    toNative = conversion->targetToNativeConversions().at(2);
 
128
    QVERIFY(toNative);
 
129
    QCOMPARE(toNative->sourceTypeName(), QString("String"));
 
130
    QVERIFY(toNative->isCustomType());
 
131
    QCOMPARE(toNative->sourceType(), (const TypeEntry*)0);
 
132
    QCOMPARE(toNative->sourceTypeCheck(), QString("String_Check(%IN)"));
 
133
    QCOMPARE(toNative->conversion().trimmed(), QString("%OUT = new A(String_AsString(%IN), String_GetSize(%IN));"));
 
134
}
 
135
 
 
136
void TestConversionRuleTag::testConversionRuleTagAdd()
 
137
{
 
138
    const char cppCode[] = "\
 
139
    struct Date {\
 
140
        Date();\
 
141
        Date(int, int, int);\
 
142
    };\
 
143
    ";
 
144
    const char* xmlCode = "\
 
145
    <typesystem package='Foo'>\
 
146
        <primitive-type name='int'/>\
 
147
        <value-type name='Date'>\
 
148
            <conversion-rule>\
 
149
                <target-to-native replace='no'>\
 
150
                    <add-conversion type='TargetDate' check='TargetDate_Check(%IN)'>\
 
151
                    if (!TargetDateTimeAPI) TargetDateTime_IMPORT;\
 
152
                    %OUT = new Date(TargetDate_Day(%IN), TargetDate_Month(%IN), TargetDate_Year(%IN));\
 
153
                    </add-conversion>\
 
154
                </target-to-native>\
 
155
            </conversion-rule>\
 
156
        </value-type>\
 
157
    </typesystem>";
 
158
 
 
159
    TestUtil t(cppCode, xmlCode);
 
160
    AbstractMetaClass* classA = t.builder()->classes().findClass("Date");
 
161
    QVERIFY(classA);
 
162
 
 
163
    CustomConversion* conversion = classA->typeEntry()->customConversion();
 
164
    QVERIFY(conversion);
 
165
 
 
166
    QCOMPARE(conversion->nativeToTargetConversion(), QString());
 
167
 
 
168
    QVERIFY(!conversion->replaceOriginalTargetToNativeConversions());
 
169
    QVERIFY(conversion->hasTargetToNativeConversions());
 
170
    QCOMPARE(conversion->targetToNativeConversions().size(), 1);
 
171
 
 
172
    CustomConversion::TargetToNativeConversion* toNative = conversion->targetToNativeConversions().first();
 
173
    QVERIFY(toNative);
 
174
    QCOMPARE(toNative->sourceTypeName(), QString("TargetDate"));
 
175
    QVERIFY(toNative->isCustomType());
 
176
    QCOMPARE(toNative->sourceType(), (const TypeEntry*)0);
 
177
    QCOMPARE(toNative->sourceTypeCheck(), QString("TargetDate_Check(%IN)"));
 
178
    QCOMPARE(toNative->conversion().trimmed(), QString("if (!TargetDateTimeAPI) TargetDateTime_IMPORT;                    %OUT = new Date(TargetDate_Day(%IN), TargetDate_Month(%IN), TargetDate_Year(%IN));"));
 
179
}
 
180
 
 
181
void TestConversionRuleTag::testConversionRuleTagWithInsertTemplate()
 
182
{
 
183
    const char cppCode[] = "struct A {};";
 
184
    const char* xmlCode = "\
 
185
    <typesystem package='Foo'>\
 
186
        <primitive-type name='int'/>\
 
187
        <template name='native_to_target'>\
 
188
        return ConvertFromCppToPython(%IN);\
 
189
        </template>\
 
190
        <template name='target_to_native'>\
 
191
        %OUT = %IN.createA();\
 
192
        </template>\
 
193
        <primitive-type name='A'>\
 
194
            <conversion-rule>\
 
195
                <native-to-target>\
 
196
                    <insert-template name='native_to_target'/>\
 
197
                </native-to-target>\
 
198
                <target-to-native>\
 
199
                    <add-conversion type='TargetType'>\
 
200
                        <insert-template name='target_to_native'/>\
 
201
                    </add-conversion>\
 
202
                </target-to-native>\
 
203
            </conversion-rule>\
 
204
        </primitive-type>\
 
205
    </typesystem>";
 
206
 
 
207
    TestUtil t(cppCode, xmlCode);
 
208
    TypeDatabase* typeDb = TypeDatabase::instance();
 
209
    PrimitiveTypeEntry* typeA = typeDb->findPrimitiveType("A");
 
210
    QVERIFY(typeA);
 
211
 
 
212
    CustomConversion* conversion = typeA->customConversion();
 
213
    QVERIFY(conversion);
 
214
 
 
215
    QCOMPARE(typeA, conversion->ownerType());
 
216
    QCOMPARE(conversion->nativeToTargetConversion().trimmed(),
 
217
             QString("// TEMPLATE - native_to_target - START        return ConvertFromCppToPython(%IN);        // TEMPLATE - native_to_target - END"));
 
218
 
 
219
    QVERIFY(conversion->hasTargetToNativeConversions());
 
220
    QCOMPARE(conversion->targetToNativeConversions().size(), 1);
 
221
 
 
222
    CustomConversion::TargetToNativeConversion* toNative = conversion->targetToNativeConversions().first();
 
223
    QVERIFY(toNative);
 
224
    QCOMPARE(toNative->conversion().trimmed(),
 
225
             QString("// TEMPLATE - target_to_native - START        %OUT = %IN.createA();        // TEMPLATE - target_to_native - END"));
 
226
}
 
227
 
55
228
QTEST_APPLESS_MAIN(TestConversionRuleTag)
56
229
 
57
230
#include "testconversionruletag.moc"