0f3a43ed83e8bd44408a53cbeb317e5029692aa5
[platform/framework/web/crosswalk-tizen.git] /
1 /*
2   Copyright (C) 2013 Yusuke Suzuki <utatane.tea@gmail.com>
3
4   Redistribution and use in source and binary forms, with or without
5   modification, are permitted provided that the following conditions are met:
6
7     * Redistributions of source code must retain the above copyright
8       notice, this list of conditions and the following disclaimer.
9     * Redistributions in binary form must reproduce the above copyright
10       notice, this list of conditions and the following disclaimer in the
11       documentation and/or other materials provided with the distribution.
12
13   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
14   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16   ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
17   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */
24 /*global require describe it*/
25 /*jslint node:true */
26 'use strict';
27
28 var fs = require('fs'),
29     path = require('path'),
30     root = path.join(path.dirname(fs.realpathSync(__filename)), '..'),
31     doctrine = require(root),
32     assert = require('assert');
33 require('should');
34
35 // tests for the stringify function.
36 // ensure that we can parse and then stringify and the results are identical
37 describe('stringify', function () {
38
39     function testStringify(text) {
40         it (text, function() {
41             var result = doctrine.parse("@param {" + text + "} name");
42             //    console.log("Parse Tree: " + JSON.stringify(result, null, " "));
43             var stringed = doctrine.type.stringify(result.tags[0].type, {compact:true});
44             stringed.should.equal(text);
45         });
46     }
47
48     // simple
49     testStringify("String");
50     testStringify("*");
51     testStringify("null");
52     testStringify("undefined");
53     testStringify("void");
54     //testStringify("?=");  // Failing
55
56     // rest
57     testStringify("...string");
58     testStringify("...[string]");
59     testStringify("...[[string]]");
60
61     // optional, nullable, nonnullable
62     testStringify("string=");
63     testStringify("?string");
64     testStringify("!string");
65     testStringify("!string=");
66
67     // type applications
68     testStringify("Array.<String>");
69     testStringify("Array.<String,Number>");
70
71     // union types
72     testStringify("()");
73     testStringify("(String|Number)");
74
75     // Arrays
76     testStringify("[String]");
77     testStringify("[String,Number]");
78     testStringify("[(String|Number)]");
79
80     // Record types
81     testStringify("{a}");
82     testStringify("{a:String}");
83     testStringify("{a:String,b}");
84     testStringify("{a:String,b:object}");
85     testStringify("{a:String,b:foo.bar.baz}");
86     testStringify("{a:(String|Number),b,c:Array.<String>}");
87     testStringify("...{a:(String|Number),b,c:Array.<String>}");
88     testStringify("{a:(String|Number),b,c:Array.<String>}=");
89
90     // fn types
91     testStringify("function(a)");
92     testStringify("function(a):String");
93     testStringify("function(a:number):String");
94     testStringify("function(a:number,b:Array.<(String|Number|Object)>):String");
95     testStringify("function(a:number,callback:function(a:Array.<(String|Number|Object)>):boolean):String");
96     testStringify("function(a:(string|number),this:string,new:true):function():number");
97     testStringify("function(a:(string|number),this:string,new:true):function(a:function(val):result):number");
98 });
99
100 describe('literals', function() {
101     it('NullableLiteral', function () {
102         doctrine.type.stringify({
103             type: doctrine.Syntax.NullableLiteral
104         }).should.equal('?');
105     });
106
107     it('AllLiteral', function () {
108         doctrine.type.stringify({
109             type: doctrine.Syntax.AllLiteral
110         }).should.equal('*');
111     });
112
113     it('NullLiteral', function () {
114         doctrine.type.stringify({
115             type: doctrine.Syntax.NullLiteral
116         }).should.equal('null');
117     });
118
119     it('UndefinedLiteral', function () {
120         doctrine.type.stringify({
121             type: doctrine.Syntax.UndefinedLiteral
122         }).should.equal('undefined');
123     });
124 });
125
126 describe('Expression', function () {
127     it('NameExpression', function () {
128         doctrine.type.stringify({
129             type: doctrine.Syntax.NameExpression,
130             name: 'this.is.valid'
131         }).should.equal('this.is.valid');
132
133         doctrine.type.stringify({
134             type: doctrine.Syntax.NameExpression,
135             name: 'String'
136         }).should.equal('String');
137     });
138
139     it('ArrayType', function () {
140         doctrine.type.stringify({
141             type: doctrine.Syntax.ArrayType,
142             elements: [{
143                 type: doctrine.Syntax.NameExpression,
144                 name: 'String'
145             }]
146         }).should.equal('[String]');
147
148         doctrine.type.stringify({
149             type: doctrine.Syntax.ArrayType,
150             elements: [{
151                 type: doctrine.Syntax.NameExpression,
152                 name: 'String'
153             }, {
154                 type: doctrine.Syntax.NameExpression,
155                 name: 'Number'
156             }]
157         }).should.equal('[String, Number]');
158
159         doctrine.type.stringify({
160             type: doctrine.Syntax.ArrayType,
161             elements: []
162         }).should.equal('[]');
163     });
164
165     it('RecordType', function () {
166         doctrine.type.stringify({
167             type: doctrine.Syntax.RecordType,
168             fields: [{
169                 type: doctrine.Syntax.FieldType,
170                 key: 'name',
171                 value: null
172             }]
173         }).should.equal('{name}');
174
175         doctrine.type.stringify({
176             type: doctrine.Syntax.RecordType,
177             fields: [{
178                 type: doctrine.Syntax.FieldType,
179                 key: 'name',
180                 value: {
181                     type: doctrine.Syntax.NameExpression,
182                     name: 'String'
183                 }
184             }]
185         }).should.equal('{name: String}');
186
187         doctrine.type.stringify({
188             type: doctrine.Syntax.RecordType,
189             fields: [{
190                 type: doctrine.Syntax.FieldType,
191                 key: 'string',
192                 value: {
193                     type: doctrine.Syntax.NameExpression,
194                     name: 'String'
195                 }
196             }, {
197                 type: doctrine.Syntax.FieldType,
198                 key: 'number',
199                 value: {
200                     type: doctrine.Syntax.NameExpression,
201                     name: 'Number'
202                 }
203             }]
204         }).should.equal('{string: String, number: Number}');
205
206         doctrine.type.stringify({
207             type: doctrine.Syntax.RecordType,
208             fields: []
209         }).should.equal('{}');
210     });
211
212     it('UnionType', function () {
213         doctrine.type.stringify({
214             type: doctrine.Syntax.UnionType,
215             elements: [{
216                 type: doctrine.Syntax.NameExpression,
217                 name: 'String'
218             }]
219         }).should.equal('(String)');
220
221         doctrine.type.stringify({
222             type: doctrine.Syntax.UnionType,
223             elements: [{
224                 type: doctrine.Syntax.NameExpression,
225                 name: 'String'
226             }, {
227                 type: doctrine.Syntax.NameExpression,
228                 name: 'Number'
229             }]
230         }).should.equal('(String|Number)');
231
232         doctrine.type.stringify({
233             type: doctrine.Syntax.UnionType,
234             elements: [{
235                 type: doctrine.Syntax.NameExpression,
236                 name: 'String'
237             }, {
238                 type: doctrine.Syntax.NameExpression,
239                 name: 'Number'
240             }]
241         }, { topLevel: true }).should.equal('String|Number');
242     });
243
244     it('RestType', function () {
245         doctrine.type.stringify({
246             type: doctrine.Syntax.RestType,
247             expression: {
248                 type: doctrine.Syntax.NameExpression,
249                 name: 'String'
250             }
251         }).should.equal('...String');
252     });
253
254     it('NonNullableType', function () {
255         doctrine.type.stringify({
256             type: doctrine.Syntax.NonNullableType,
257             expression: {
258                 type: doctrine.Syntax.NameExpression,
259                 name: 'String'
260             },
261             prefix: true
262         }).should.equal('!String');
263
264         doctrine.type.stringify({
265             type: doctrine.Syntax.NonNullableType,
266             expression: {
267                 type: doctrine.Syntax.NameExpression,
268                 name: 'String'
269             },
270             prefix: false
271         }).should.equal('String!');
272     });
273
274     it('OptionalType', function () {
275         doctrine.type.stringify({
276             type: doctrine.Syntax.OptionalType,
277             expression: {
278                 type: doctrine.Syntax.NameExpression,
279                 name: 'String'
280             }
281         }).should.equal('String=');
282     });
283
284     it('NullableType', function () {
285         doctrine.type.stringify({
286             type: doctrine.Syntax.NullableType,
287             expression: {
288                 type: doctrine.Syntax.NameExpression,
289                 name: 'String'
290             },
291             prefix: true
292         }).should.equal('?String');
293
294         doctrine.type.stringify({
295             type: doctrine.Syntax.NullableType,
296             expression: {
297                 type: doctrine.Syntax.NameExpression,
298                 name: 'String'
299             },
300             prefix: false
301         }).should.equal('String?');
302     });
303
304     it('TypeApplication', function () {
305         doctrine.type.stringify({
306             type: doctrine.Syntax.TypeApplication,
307             expression: {
308                 type: doctrine.Syntax.NameExpression,
309                 name: 'Array'
310             },
311             applications: [
312                 {
313                     type: doctrine.Syntax.NameExpression,
314                     name: 'String'
315                 }
316             ]
317         }).should.equal('Array.<String>');
318
319         doctrine.type.stringify({
320             type: doctrine.Syntax.TypeApplication,
321             expression: {
322                 type: doctrine.Syntax.NameExpression,
323                 name: 'Array'
324             },
325             applications: [
326                 {
327                     type: doctrine.Syntax.NameExpression,
328                     name: 'String'
329                 },
330                 {
331                     type: doctrine.Syntax.AllLiteral
332                 }
333             ]
334         }).should.equal('Array.<String, *>');
335     });
336 });
337
338 describe('Complex identity', function () {
339     it('Functions', function () {
340         var data01 = 'function (): void';
341         doctrine.type.stringify(
342             doctrine.type.parseType(data01)
343         ).should.equal(data01);
344
345         var data02 = 'function (): String';
346         doctrine.type.stringify(
347             doctrine.type.parseType(data02)
348         ).should.equal(data02);
349
350         var data03 = 'function (test: string): String';
351         doctrine.type.stringify(
352             doctrine.type.parseType(data03)
353         ).should.equal(data03);
354
355         var data04 = 'function (this: Date, test: String): String';
356         doctrine.type.stringify(
357             doctrine.type.parseType(data04)
358         ).should.equal(data04);
359
360         var data05 = 'function (this: Date, a: String, b: Number): String';
361         doctrine.type.stringify(
362             doctrine.type.parseType(data05)
363         ).should.equal(data05);
364
365         var data06 = 'function (this: Date, a: Array.<String, Number>, b: Number): String';
366         doctrine.type.stringify(
367             doctrine.type.parseType(data06)
368         ).should.equal(data06);
369
370         var data07 = 'function (new: Date, a: Array.<String, Number>, b: Number): HashMap.<String, Number>';
371         doctrine.type.stringify(
372             doctrine.type.parseType(data07)
373         ).should.equal(data07);
374
375         var data08 = 'function (new: Date, a: Array.<String, Number>, b: (Number|String|Date)): HashMap.<String, Number>';
376         doctrine.type.stringify(
377             doctrine.type.parseType(data08)
378         ).should.equal(data08);
379
380         var data09 = 'function (new: Date)';
381         doctrine.type.stringify(
382             doctrine.type.parseType(data09)
383         ).should.equal(data09);
384
385         var data10 = 'function (this: Date)';
386         doctrine.type.stringify(
387             doctrine.type.parseType(data10)
388         ).should.equal(data10);
389
390         var data11 = 'function (this: Date, ...list)';
391         doctrine.type.stringify(
392             doctrine.type.parseType(data11)
393         ).should.equal(data11);
394
395         var data11a = 'function (this: Date, test: String=)';
396         doctrine.type.stringify(
397             doctrine.type.parseType(data11a)
398         ).should.equal(data11a);
399
400         // raw ... are not supported
401 //        var data12 = 'function (this: Date, ...)';
402 //        doctrine.type.stringify(
403 //            doctrine.type.parseType(data12)
404 //        ).should.equal(data12);
405
406         var data12a = 'function (this: Date, ?=)';
407         doctrine.type.stringify(
408             doctrine.type.parseType(data12a)
409         ).should.equal(data12a);
410     });
411 });
412
413 /* vim: set sw=4 ts=4 et tw=80 : */