comparison Resources/CodeGeneration/stonegentool_test.py @ 520:7a16fb9a4ba5 am-touch-events

merge bgo-commands-codegen
author Alain Mazy <alain@mazy.be>
date Tue, 12 Mar 2019 14:50:14 +0100
parents 1dbf2d9ed1e4
children b7fd0471281c
comparison
equal deleted inserted replaced
503:77e0eb83ff63 520:7a16fb9a4ba5
1 #
2 # 1 2 3 4 5 6 7 8
3 # 345678901234567890123456789012345678901234567890123456789012345678901234567890
4 #
5
6 from stonegentool import \
7 EatToken,SplitListOfTypes,ParseTemplateType,ProcessSchema, \
8 CheckSchemaSchema,LoadSchema,trim,ComputeRequiredDeclarationOrder, \
9 GetTemplatingDictFromSchemaFilename,MakeTemplate,MakeTemplateFromFile
10 import unittest
11 import os
12 import re
13 import pprint
14 from jinja2 import Template
15
16 def RemoveDateTimeLine(s : str):
17 # regex are non-multiline by default, and $ does NOT match the end of the line
18 s2 = re.sub(r"^// autogenerated by stonegentool on .*\n","",s)
19 return s2
20
21 class TestStonegentool(unittest.TestCase):
22 def test_EatToken_empty(self):
23 c = r""
24 a,b = EatToken(c)
25 self.assertEqual(a,r"")
26 self.assertEqual(b,r"")
27
28 def test_EatToken_simpleNonTemplate(self):
29 c = r"int32"
30 a,b = EatToken(c)
31 self.assertEqual(a,r"int32")
32 self.assertEqual(b,r"")
33
34 def test_EatToken_simpleTemplate(self):
35 c = r"vector<string>"
36 a,b = EatToken(c)
37 self.assertEqual(a,r"vector<string>")
38 self.assertEqual(b,r"")
39
40 def test_EatToken_complexTemplate(self):
41 c = r"vector<map<int64,string>>,vector<map<int32,string>>"
42 a,b = EatToken(c)
43 self.assertEqual(a,r"vector<map<int64,string>>")
44 self.assertEqual(b,r"vector<map<int32,string>>")
45
46 def test_EatToken_complexTemplates(self):
47 c = r"vector<map<vector<string>,map<int32,string>>>,map<int32,string>,map<map<int32,string>,string>"
48 a,b = EatToken(c)
49 self.assertEqual(a,r"vector<map<vector<string>,map<int32,string>>>")
50 self.assertEqual(b,r"map<int32,string>,map<map<int32,string>,string>")
51 a,b = EatToken(b)
52 self.assertEqual(a,r"map<int32,string>")
53 self.assertEqual(b,r"map<map<int32,string>,string>")
54
55 def test_SplitListOfTypes(self):
56 c = r"vector<map<vector<string>,map<int32,string>>>,map<int32,string>,map<map<int32,string>,string>"
57 lot = SplitListOfTypes(c)
58 self.assertEqual(3,len(lot))
59 self.assertEqual("vector<map<vector<string>,map<int32,string>>>",lot[0])
60 self.assertEqual("map<int32,string>",lot[1])
61 self.assertEqual("map<map<int32,string>,string>",lot[2])
62
63 def test_SplitListOfTypes_bogus(self):
64 c = r"vector<map<vector<string>,map<int32,string>>,map<int32,string>,map<map<int32,string>,string"
65 self.assertRaises(Exception,SplitListOfTypes,c) # the argument c must be passed to assertRaises, not as a normal call of SplitListOfTypes
66
67 def test_ParseTemplateType_true(self):
68 c = "map<vector<map<int,vector<string>>>,map<vector<int>,vector<string>>>"
69 (ok,a,b) = ParseTemplateType(c)
70 self.assertEqual(ok,True)
71 self.assertEqual(a,"map")
72 self.assertEqual(b,["vector<map<int,vector<string>>>","map<vector<int>,vector<string>>"])
73
74 (ok2,a2,b2) = ParseTemplateType(b[0])
75 self.assertEqual(ok2,True)
76 self.assertEqual(a2,"vector")
77 self.assertEqual(b2,["map<int,vector<string>>"])
78
79 (ok3,a3,b3) = ParseTemplateType(b[1])
80 self.assertEqual(ok3,True)
81 self.assertEqual(a3,"map")
82 self.assertEqual(b3,["vector<int>","vector<string>"])
83
84 (ok4,a4,b4) = ParseTemplateType(b2[0])
85 self.assertEqual(ok4,True)
86 self.assertEqual(a4,"map")
87 self.assertEqual(b4,["int","vector<string>"])
88
89 def test_ParseSchema(self):
90 fn = os.path.join(os.path.dirname(__file__), 'test_data', 'test1.yaml')
91 obj = LoadSchema(fn)
92 # we're happy if it does not crash :)
93 CheckSchemaSchema(obj)
94
95 def test_ComputeRequiredDeclarationOrder(self):
96 fn = os.path.join(os.path.dirname(__file__), 'test_data', 'test1.yaml')
97 obj = LoadSchema(fn)
98 genOrder: str = ComputeRequiredDeclarationOrder(obj)
99 self.assertEqual(5,len(genOrder))
100 self.assertEqual("A",genOrder[0])
101 self.assertEqual("B",genOrder[1])
102 self.assertEqual("C",genOrder[2])
103 self.assertEqual("Message1",genOrder[3])
104 self.assertEqual("Message2",genOrder[4])
105
106 # def test_GeneratePreambleEnumerationAndStructs(self):
107 # fn = os.path.join(os.path.dirname(__file__), 'test', 'test1.jsonc')
108 # obj = LoadSchema(fn)
109 # (_,genc,_) = ProcessSchema(obj)
110
111 def test_genEnums(self):
112 self.maxDiff = None
113 fn = os.path.join(os.path.dirname(__file__), 'test_data', 'test1.yaml')
114 obj = LoadSchema(fn)
115 genOrder: str = ComputeRequiredDeclarationOrder(obj)
116 processedSchema = ProcessSchema(obj, genOrder)
117 self.assertTrue('rootName' in processedSchema)
118
119 structs = {}
120 for v in processedSchema['structs']:
121 structs[v['name']] = v
122 enums = {}
123 for v in processedSchema['enums']:
124 enums[v['name']] = v
125
126 self.assertTrue('C' in structs)
127 self.assertTrue('someBs' in structs['C']['fields'])
128 self.assertTrue('CrispType' in enums)
129 self.assertTrue('Message1' in structs)
130 message1Struct = structs['Message1']
131 self.assertDictEqual(message1Struct,
132 {
133 'name':'Message1',
134 'fields': {
135 'a': 'int32',
136 'b': 'string',
137 'c': 'EnumMonth0',
138 'd': 'bool'
139 }
140 })
141
142 def test_GenerateTypeScriptEnums(self):
143 fn = os.path.join(os.path.dirname(__file__), 'test_data', 'test1.yaml')
144 tdico = GetTemplatingDictFromSchemaFilename(fn)
145 template = Template(""" // end of generic methods
146 {% for enum in enums%} export enum {{enum['name']}} {
147 {% for key in enum['fields']%} {{key}},
148 {%endfor%} };
149
150 {%endfor%}""")
151 renderedCode = template.render(**tdico)
152 renderedCodeRef = """ // end of generic methods
153 export enum MovieType {
154 RomCom,
155 Horror,
156 ScienceFiction,
157 Vegetables,
158 };
159
160 export enum CrispType {
161 SaltAndPepper,
162 CreamAndChives,
163 Paprika,
164 Barbecue,
165 };
166
167 """
168 self.assertEqual(renderedCodeRef,renderedCode)
169
170 def test_GenerateCplusplusEnums(self):
171 fn = os.path.join(os.path.dirname(__file__), 'test_data', 'test1.yaml')
172 tdico = GetTemplatingDictFromSchemaFilename(fn)
173 template = Template(""" // end of generic methods
174 {% for enum in enums%} enum {{enum['name']}} {
175 {% for key in enum['fields']%} {{key}},
176 {%endfor%} };
177
178 {%endfor%}""")
179 renderedCode = template.render(**tdico)
180 renderedCodeRef = """ // end of generic methods
181 enum MovieType {
182 RomCom,
183 Horror,
184 ScienceFiction,
185 Vegetables,
186 };
187
188 enum CrispType {
189 SaltAndPepper,
190 CreamAndChives,
191 Paprika,
192 Barbecue,
193 };
194
195 """
196 self.assertEqual(renderedCodeRef,renderedCode)
197
198 def test_generateTsStructType(self):
199 fn = os.path.join(os.path.dirname(__file__), 'test_data', 'test1.yaml')
200 tdico = GetTemplatingDictFromSchemaFilename(fn)
201 ref = """ export class Message1 {
202 a: number;
203 b: string;
204 c: EnumMonth0;
205 d: boolean;
206 public StoneSerialize(): string {
207 let container: object = {};
208 container['type'] = 'VsolStuff.Message1';
209 container['value'] = this;
210 return JSON.stringify(container);
211 }
212 };
213
214 export class Message2 {
215 toto: string;
216 tata: Message1[];
217 tutu: string[];
218 titi: Map<string, string>;
219 lulu: Map<string, Message1>;
220
221 constructor()
222 {
223 this.tata = new Array<Message1>();
224 this.tutu = new Array<string>();
225 this.titi = new Map<string, string>();
226 this.lulu = new Map<string, Message1>();
227 }
228
229 public StoneSerialize(): string {
230 let container: object = {};
231 container['type'] = 'VsolStuff.Message2';
232 container['value'] = this;
233 return JSON.stringify(container);
234 }
235 };
236
237 """
238 # template = MakeTemplate(""" // end of generic methods
239 # {% for struct in struct%} export class {{struct['name']}} {
240 # {% for key in struct['fields']%} {{key}}:{{struct['fields'][key]}},
241 # {% endfor %}
242 # constructor() {
243 # {% for key in struct['fields']%}
244 # {% if NeedsConstruction(struct['fields']['key'])}
245 # {{key}} = new {{CanonToTs(struct['fields']['key'])}};
246 # {% end if %}
247 # {% endfor %}
248 # }
249 # {% endfor %}
250 # public StoneSerialize(): string {
251 # let container: object = {};
252 # container['type'] = '{{rootName}}.{{struct['name']}}';
253 # container['value'] = this;
254 # return JSON.stringify(container);
255 # } };""")
256 template = MakeTemplate(""" // end of generic methods
257 {% for struct in structs%} export class {{struct['name']}} {
258 {% for key in struct['fields']%} {{key}}:{{CanonToTs(struct['fields'][key])}};
259 {% endfor %}
260 constructor() {
261 {% for key in struct['fields']%} this.{{key}} = new {{CanonToTs(struct['fields'][key])}}();
262 {% endfor %} }
263
264 public StoneSerialize(): string {
265 let container: object = {};
266 container['type'] = '{{rootName}}.{{struct['name']}}';
267 container['value'] = this;
268 return JSON.stringify(container);
269 }
270 };
271
272 {% endfor %}""")
273 renderedCode = template.render(**tdico)
274 renderedCodeRef = """ // end of generic methods
275 export class A {
276 someStrings:Array<string>;
277 someInts2:Array<number>;
278 movies:Array<MovieType>;
279
280 constructor() {
281 someStrings = new Array<string>();
282 someInts2 = new Array<number>();
283 movies = new Array<MovieType>();
284 }
285
286 public StoneSerialize(): string {
287 let container: object = {};
288 container['type'] = 'VsolMessages.A';
289 container['value'] = this;
290 return JSON.stringify(container);
291 }
292 };
293
294 export class B {
295 someAs:Array<A>;
296 someInts:Array<number>;
297
298 constructor() {
299 someAs = new Array<A>();
300 someInts = new Array<number>();
301 }
302
303 public StoneSerialize(): string {
304 let container: object = {};
305 container['type'] = 'VsolMessages.B';
306 container['value'] = this;
307 return JSON.stringify(container);
308 }
309 };
310
311 export class C {
312 someBs:Array<B>;
313 ddd:Array<string>;
314
315 constructor() {
316 someBs = new Array<B>();
317 ddd = new Array<string>();
318 }
319
320 public StoneSerialize(): string {
321 let container: object = {};
322 container['type'] = 'VsolMessages.C';
323 container['value'] = this;
324 return JSON.stringify(container);
325 }
326 };
327
328 export class Message1 {
329 a:number;
330 b:string;
331 c:EnumMonth0;
332 d:boolean;
333
334 constructor() {
335 a = new number();
336 b = new string();
337 c = new EnumMonth0();
338 d = new boolean();
339 }
340
341 public StoneSerialize(): string {
342 let container: object = {};
343 container['type'] = 'VsolMessages.Message1';
344 container['value'] = this;
345 return JSON.stringify(container);
346 }
347 };
348
349 export class Message2 {
350 toto:string;
351 tata:Array<Message1>;
352 tutu:Array<string>;
353 titi:Map<string, string>;
354 lulu:Map<string, Message1>;
355
356 constructor() {
357 toto = new string();
358 tata = new Array<Message1>();
359 tutu = new Array<string>();
360 titi = new Map<string, string>();
361 lulu = new Map<string, Message1>();
362 }
363
364 public StoneSerialize(): string {
365 let container: object = {};
366 container['type'] = 'VsolMessages.Message2';
367 container['value'] = this;
368 return JSON.stringify(container);
369 }
370 };
371
372 """
373 # print(renderedCode)
374 self.maxDiff = None
375 self.assertEqual(renderedCodeRef, renderedCode)
376
377 def test_generateWholeTsFile(self):
378 schemaFile = \
379 os.path.join(os.path.dirname(__file__), 'test_data', 'test1.yaml')
380 tdico = GetTemplatingDictFromSchemaFilename(schemaFile)
381 tsTemplateFile = \
382 os.path.join(os.path.dirname(__file__), 'template.in.ts.j2')
383 template = MakeTemplateFromFile(tsTemplateFile)
384 renderedCode = template.render(**tdico)
385 print(renderedCode)
386
387 def test_GenerateTypeScriptHandlerInterface(self):
388 pass
389
390 def test_GenerateCppHandlerInterface(self):
391 pass
392
393 def test_GenerateTypeScriptDispatcher(self):
394 pass
395
396 def test_GenerateCppDispatcher(self):
397 pass
398
399 # def test(self):
400 # s = 'hello world'
401 # self.assertEqual(s.split(), ['hello', 'world'])
402 # # check that s.split fails when the separator is not a string
403 # with self.assertRaises(TypeError):
404 # s.split(2)
405
406 if __name__ == '__main__':
407 unittest.main()
408