File indexing completed on 2024-04-21 15:33:21

0001 # -*- coding: utf-8 -*-
0002 #     Copyright 2009 Simon Edwards <simon@simonzone.com>
0003 #
0004 # This program is free software; you can redistribute it and/or modify
0005 # it under the terms of the GNU General Public License as published by
0006 # the Free Software Foundation; either version 2 of the License, or
0007 # (at your option) any later version.
0008 #
0009 # This program is distributed in the hope that it will be useful,
0010 # but WITHOUT ANY WARRANTY; without even the implied warranty of
0011 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0012 # GNU General Public License for more details.
0013 #
0014 # You should have received a copy of the GNU General Public License
0015 # along with this program; if not, write to the
0016 # Free Software Foundation, Inc.,
0017 # 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
0018 
0019 #
0020 # Unit tests for the Cpp to Sip transformer.
0021 #
0022 import unittest
0023 import cppparser
0024 import cppsymboldata
0025 import cpptosiptransformer
0026 import sipparser
0027 import sipsymboldata
0028 
0029 class TestCppToSipTransformer(unittest.TestCase):
0030     def setUp(self):
0031         pass
0032         
0033     def convert(self, cpptext, exportMacros=None, ignoreBases=None):
0034         parser = cppparser.CppParser()
0035         if exportMacros is not None:
0036             parser.bareMacros = exportMacros
0037             
0038         syms = cppsymboldata.SymbolData()
0039         scope = parser.parse(syms,cpptext)
0040         print("Cpp----------------------------------")
0041         print(scope.format())
0042         
0043         transformer = cpptosiptransformer.CppToSipTransformer()
0044         transformer.setExportMacros(exportMacros)
0045         transformer.setIgnoreBaseClasses(ignoreBases)
0046         
0047         sipsym = sipsymboldata.SymbolData()
0048         sipscope = transformer.convert(scope,sipsym)
0049         print("Sip----------------------------------")
0050         print(sipscope.format())
0051         return sipscope
0052         
0053     def annotate(self, siptext, rules):
0054         parser = sipparser.SipParser()
0055         syms = sipsymboldata.SymbolData()
0056         scope = parser.parse(syms,siptext)
0057         
0058         print("Sip----------------------------------")
0059         print(scope.format())
0060         annotator = cpptosiptransformer.SipAnnotator()
0061         annotator.setMethodAnnotationRules(rules)
0062         annotator.applyRules(scope)
0063         
0064         print("Sip output---------------------------")
0065         print(scope.format())
0066         
0067     def sanityCheck(self, siptext):
0068         parser = sipparser.SipParser()
0069         syms = sipsymboldata.SymbolData()
0070         scope = parser.parse(syms,siptext)
0071         
0072         cpptosiptransformer.SanityCheckSip(syms,[scope])
0073         print("Sip----------------------------------")
0074         print(scope.format())
0075         
0076     def expandClassNames(self, siptext):
0077         parser = sipparser.SipParser()
0078         syms = sipsymboldata.SymbolData()
0079         scope = parser.parse(syms,siptext)
0080         
0081         print("Sip----------------------------------")
0082         print(scope.format())
0083         cpptosiptransformer.ExpandClassNames(syms,scope)
0084         
0085         print("Sip output---------------------------")
0086         print(scope.format())        
0087         
0088     def testConstructor(self):
0089         self.convert("""
0090 #include <foo.h>
0091 class EXPORT_FOO Foo {
0092 public:
0093     Foo();
0094 };
0095 """,exportMacros=["EXPORT_FOO"])
0096 
0097     def testConstructor2(self):
0098         self.convert("""
0099 #include <foo.h>
0100 class EXPORT_FOO Foo {
0101 public:
0102     Foo();
0103 protected:
0104     Foo(int x);
0105    
0106 };
0107 """,exportMacros=["EXPORT_FOO"])
0108 
0109     def testClass(self):
0110         self.convert("""
0111 class Foo {
0112 public:
0113     Foo();
0114     int bar(int x);
0115 };
0116 """)
0117 
0118     def testClass2(self):
0119         self.convert("""
0120 class Foo : public Bar {
0121 public:
0122     Foo();
0123 };
0124 """)
0125 
0126     def testVariable(self):
0127         self.convert("""
0128 int bar;
0129 """)
0130 
0131     def testStaticVariable(self):
0132         self.convert("""
0133 static int staticBar;
0134 """)
0135 
0136     def testFunction(self):
0137         self.convert("""
0138 int FunctionBar();
0139 """)
0140 
0141     def testConstFunctions(self):
0142         self.convert("""
0143 KConfigGroup            group (const QByteArray& group);
0144 const KConfigGroup      group (const QByteArray& group);
0145 const KConfigGroup      group (const QByteArray& group) const;
0146 """)
0147 
0148 
0149 
0150     def testStaticFunction(self):
0151         self.convert("""
0152 static int StaticFunctionBar();
0153 """)
0154 
0155     def testNamespace(self):
0156         self.convert("""
0157 namespace FooSpace {
0158     int bar;
0159 }
0160 """)
0161     
0162     def testEnum(self):
0163         self.convert("""
0164 enum global {
0165     earth,
0166     orb,
0167     globe
0168 };
0169 """)
0170         
0171     def testEnumTypedef(self):
0172         self.convert("""
0173 typedef enum {
0174     earth,
0175     orb,
0176     globe
0177 } global;
0178 """)
0179 
0180     def testPrivate(self):
0181         self.convert("""
0182 class Foo {
0183 public:
0184     Foo();
0185     int bar();
0186     
0187 private:
0188     int barzor();
0189    
0190 };
0191 """)
0192 
0193     def testOperators(self):
0194         self.convert("""
0195 class Foo {
0196 public:
0197     Foo();
0198     int operator /(int div);
0199     
0200     int operator ++();
0201    
0202 };
0203 """)
0204 
0205     def testArgumentTypes(self):
0206         self.convert("""
0207 short int port;
0208 """)
0209 
0210     def testDefaultArgs(self):
0211         self.convert("""
0212 class Foo {
0213 public:
0214     int port(bool frazzle=true);
0215 };
0216 """)
0217 
0218     def testTypedef(self):
0219         self.convert("""
0220 typedef QFlags< SearchOption > SearchOptions;
0221 """)
0222 
0223     ###########################################################################
0224     def testAnnotate(self):
0225         self.annotate("""
0226 class Foo {
0227     public:
0228         Foo(QWidget *parent);
0229 };
0230 """,
0231         [cpptosiptransformer.MethodAnnotationRule("ctor","QWidget*","parent","Transfer")])
0232 
0233     def testIgnoreBases(self):
0234         self.convert("""
0235 
0236 class Foo : public Bar, public Zyzz {
0237    
0238 };
0239 """,ignoreBases=["Zyzz"])
0240 
0241     def testPrivateVars(self):
0242         self.convert("""
0243 class Statistics {
0244 private:
0245     StatisticsPrivate* d;
0246 };
0247 """)
0248 
0249     def testOpaqueClasses(self):
0250         self.convert("""
0251 class Statistics;
0252 """)
0253 
0254     def testNamespaces(self):
0255         self.convert("""
0256 namespace FooSpace {
0257     class Bar {
0258     };
0259     class Zyzz : public Bar {
0260     };
0261 }
0262 """)
0263 
0264     def testNestedTemplate(self):
0265         self.convert("""
0266 KBookmarkGroup addBookmarks(const QList< QPair<QString, QString>> & list);
0267 """)
0268 
0269     def testCTSCC(self):
0270         parser = sipparser.SipParser()
0271         syms = sipsymboldata.SymbolData()
0272         globalScope = parser.parse(syms,"""
0273 class QWidget {};
0274 class QObject {};
0275 class QBar : QWidget {};
0276 """,filename="qtcore.h")
0277         scope = parser.parse(syms,"""
0278 class KFoo {
0279 };
0280 class KFooSub : KFoo {
0281 };
0282 class KBarWidget : QBar {
0283 };
0284 
0285 class KBarWidgetSpecial : KBarWidget {
0286 
0287 };
0288 class KSteelBar : QBar {};
0289 class KBob : QObject {};
0290 """,filename="stuff.h")
0291         annotator = cpptosiptransformer.SipAnnotator()
0292         cpptosiptransformer.UpdateConvertToSubClassCodeDirectives(syms,[scope],["Zyzz"])
0293         
0294         print("Sip----------------------------------")
0295         print(scope.format())
0296 
0297     def testCTSCC2(self):
0298         parser = sipparser.SipParser()
0299         syms = sipsymboldata.SymbolData()
0300         globalScope = parser.parse(syms,"""
0301 class QWidget {};
0302 """)
0303         scope = parser.parse(syms,"""
0304 namespace FooSpace {
0305     class Foo : QWidget {
0306     };
0307 };
0308 """)
0309         annotator = cpptosiptransformer.SipAnnotator()
0310         cpptosiptransformer.UpdateConvertToSubClassCodeDirectives(syms,[scope],["Zyzz"])
0311         
0312         print("Sip----------------------------------")
0313         print(scope.format())
0314 
0315     def testClassNameExpand(self):
0316         self.expandClassNames("""
0317 namespace FooSpace {
0318     class Foo { };
0319     class Bar : Foo { };
0320 };
0321 """)
0322 
0323     def testClassNameExpand2(self):
0324         self.expandClassNames("""
0325 namespace FooSpace {
0326     class Foo { };
0327     class Bar {
0328         Foo doFooz(Foo inputFoo);
0329         Foo doFoozRef(Foo &inputFoo);
0330     };
0331 };
0332 """)
0333 
0334     def testClassNameExpandVars(self):
0335         self.expandClassNames("""
0336 namespace FooSpace {
0337     class Foo { };
0338     class Bar {
0339         static const Foo fodo;
0340         Foo doFooz(Foo inputFoo);
0341         Foo doFoozRef(Foo &inputFoo);
0342     };
0343 };
0344 """)
0345 
0346     def testSanityCheck(self):
0347         self.sanityCheck("""
0348 class Foo : QWidget {};
0349 """)
0350 
0351     def testSanityCheck2(self):
0352         self.sanityCheck("""
0353 void badFoo(int& bar);
0354 void goodFoo(int& bar /In/);
0355 """)
0356 
0357 
0358 if __name__ == '__main__':
0359     unittest.main()