Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / closure_compiler / runner / test / com / google / javascript / jscomp / ChromePassTest.java
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package com.google.javascript.jscomp;
6
7 /**
8  * Tests {@link ChromePass}.
9  */
10 public class ChromePassTest extends CompilerTestCase {
11
12     @Override
13     protected CompilerPass getProcessor(Compiler compiler) {
14       return new ChromePass(compiler);
15     }
16
17     @Override
18     protected int getNumRepetitions() {
19       // This pass isn't idempotent and only runs once.
20       return 1;
21     }
22
23     public void testCrDefineCreatesObjectsForQualifiedName() throws Exception {
24         test(
25             "cr.define('my.namespace.name', function() {\n" +
26             "  return {};\n" +
27             "});",
28             "var my = my || {};\n" +
29             "my.namespace = my.namespace || {};\n" +
30             "my.namespace.name = my.namespace.name || {};\n" +
31             "cr.define('my.namespace.name', function() {\n" +
32             "  return {};\n" +
33             "});");
34     }
35
36     public void testCrDefineAssignsExportedFunctionByQualifiedName() throws Exception {
37         test(
38             "cr.define('namespace', function() {\n" +
39             "  function internalStaticMethod() {\n" +
40             "    alert(42);\n" +
41             "  }\n" +
42             "  return {\n" +
43             "    externalStaticMethod: internalStaticMethod\n" +
44             "  };\n" +
45             "});",
46             "var namespace = namespace || {};\n" +
47             "cr.define('namespace', function() {\n" +
48             "  namespace.externalStaticMethod = function internalStaticMethod() {\n" +
49             "    alert(42);\n" +
50             "  }\n" +
51             "  return {\n" +
52             "    externalStaticMethod: namespace.externalStaticMethod\n" +
53             "  };\n" +
54             "});");
55     }
56
57     public void testCrDefineCopiesJSDocForExportedFunction() throws Exception {
58         test("cr.define('namespace', function() {\n" +
59             "  /** I'm function's JSDoc */\n" +
60             "  function internalStaticMethod() {\n" +
61             "    alert(42);\n" +
62             "  }\n" +
63             "  return {\n" +
64             "    externalStaticMethod: internalStaticMethod\n" +
65             "  };\n" +
66             "});",
67             "var namespace = namespace || {};\n" +
68             "cr.define('namespace', function() {\n" +
69             "  /** I'm function's JSDoc */\n" +
70             "  namespace.externalStaticMethod = function internalStaticMethod() {\n" +
71             "    alert(42);\n" +
72             "  }\n" +
73             "  return {\n" +
74             "    externalStaticMethod: namespace.externalStaticMethod\n" +
75             "  };\n" +
76             "});");
77     }
78
79     public void testCrDefineReassignsExportedVarByQualifiedName() throws Exception {
80         test(
81             "cr.define('namespace', function() {\n" +
82             "  var internalStaticMethod = function() {\n" +
83             "    alert(42);\n" +
84             "  }\n" +
85             "  return {\n" +
86             "    externalStaticMethod: internalStaticMethod\n" +
87             "  };\n" +
88             "});",
89             "var namespace = namespace || {};\n" +
90             "cr.define('namespace', function() {\n" +
91             "  namespace.externalStaticMethod = function() {\n" +
92             "    alert(42);\n" +
93             "  }\n" +
94             "  return {\n" +
95             "    externalStaticMethod: namespace.externalStaticMethod\n" +
96             "  };\n" +
97             "});");
98     }
99
100     public void testCrDefineExportsVarsWithoutAssignment() throws Exception {
101         test(
102             "cr.define('namespace', function() {\n" +
103             "  var a;\n" +
104             "  return {\n" +
105             "    a: a\n" +
106             "  };\n" +
107             "});\n",
108             "var namespace = namespace || {};\n" +
109             "cr.define('namespace', function() {\n" +
110             "  namespace.a;\n" +
111             "  return {\n" +
112             "    a: namespace.a\n" +
113             "  };\n" +
114             "});\n");
115     }
116
117     public void testCrDefineExportsVarsWithoutAssignmentWithJSDoc() throws Exception {
118         test(
119             "cr.define('namespace', function() {\n" +
120             "  /** @type {number} */\n" +
121             "  var a;\n" +
122             "  return {\n" +
123             "    a: a\n" +
124             "  };\n" +
125             "});\n",
126             "var namespace = namespace || {};\n" +
127             "cr.define('namespace', function() {\n" +
128             "  /** @type {number} */\n" +
129             "  namespace.a;\n" +
130             "  return {\n" +
131             "    a: namespace.a\n" +
132             "  };\n" +
133             "});\n");
134     }
135
136     public void testCrDefineCopiesJSDocForExportedVariable() throws Exception {
137         test(
138             "cr.define('namespace', function() {\n" +
139             "  /** I'm function's JSDoc */\n" +
140             "  var internalStaticMethod = function() {\n" +
141             "    alert(42);\n" +
142             "  }\n" +
143             "  return {\n" +
144             "    externalStaticMethod: internalStaticMethod\n" +
145             "  };\n" +
146             "});",
147             "var namespace = namespace || {};\n" +
148             "cr.define('namespace', function() {\n" +
149             "  /** I'm function's JSDoc */\n" +
150             "  namespace.externalStaticMethod = function() {\n" +
151             "    alert(42);\n" +
152             "  }\n" +
153             "  return {\n" +
154             "    externalStaticMethod: namespace.externalStaticMethod\n" +
155             "  };\n" +
156             "});");
157     }
158
159     public void testCrDefineDoesNothingWithNonExportedFunction() throws Exception {
160         test(
161             "cr.define('namespace', function() {\n" +
162             "  function internalStaticMethod() {\n" +
163             "    alert(42);\n" +
164             "  }\n" +
165             "  return {};\n" +
166             "});",
167             "var namespace = namespace || {};\n" +
168             "cr.define('namespace', function() {\n" +
169             "  function internalStaticMethod() {\n" +
170             "    alert(42);\n" +
171             "  }\n" +
172             "  return {};\n" +
173             "});");
174     }
175
176     public void testCrDefineDoesNothingWithNonExportedVar() throws Exception {
177         test(
178             "cr.define('namespace', function() {\n" +
179             "  var a;\n" +
180             "  var b;\n" +
181             "  return {\n" +
182             "    a: a\n" +
183             "  };\n" +
184             "});\n",
185             "var namespace = namespace || {};\n" +
186             "cr.define('namespace', function() {\n" +
187             "  namespace.a;\n" +
188             "  var b;\n" +
189             "  return {\n" +
190             "    a: namespace.a\n" +
191             "  };\n" +
192             "});\n");
193     }
194
195     public void testCrDefineDoesNothingWithExportedNotAName() throws Exception {
196         test(
197             "cr.define('namespace', function() {\n" +
198             "  return {\n" +
199             "    a: 42\n" +
200             "  };\n" +
201             "});\n",
202             "var namespace = namespace || {};\n" +
203             "cr.define('namespace', function() {\n" +
204             "  return {\n" +
205             "    a: 42\n" +
206             "  };\n" +
207             "});\n");
208     }
209
210     public void testCrDefineChangesReferenceToExportedFunction() throws Exception {
211         test(
212             "cr.define('namespace', function() {\n" +
213             "  function internalStaticMethod() {\n" +
214             "    alert(42);\n" +
215             "  }\n" +
216             "  function letsUseIt() {\n" +
217             "    internalStaticMethod();\n" +
218             "  }\n" +
219             "  return {\n" +
220             "    externalStaticMethod: internalStaticMethod\n" +
221             "  };\n" +
222             "});",
223             "var namespace = namespace || {};\n" +
224             "cr.define('namespace', function() {\n" +
225             "  namespace.externalStaticMethod = function internalStaticMethod() {\n" +
226             "    alert(42);\n" +
227             "  }\n" +
228             "  function letsUseIt() {\n" +
229             "    namespace.externalStaticMethod();\n" +
230             "  }\n" +
231             "  return {\n" +
232             "    externalStaticMethod: namespace.externalStaticMethod\n" +
233             "  };\n" +
234             "});");
235     }
236
237     public void testCrDefineWrongNumberOfArguments() throws Exception {
238         test("cr.define('namespace', function() { return {}; }, 'invalid argument')\n",
239             null, ChromePass.CR_DEFINE_WRONG_NUMBER_OF_ARGUMENTS);
240     }
241
242     public void testCrDefineInvalidFirstArgument() throws Exception {
243         test("cr.define(42, function() { return {}; })\n",
244             null, ChromePass.CR_DEFINE_INVALID_FIRST_ARGUMENT);
245     }
246
247     public void testCrDefineInvalidSecondArgument() throws Exception {
248         test("cr.define('namespace', 42)\n",
249             null, ChromePass.CR_DEFINE_INVALID_SECOND_ARGUMENT);
250     }
251
252     public void testCrDefineInvalidReturnInFunction() throws Exception {
253         test("cr.define('namespace', function() {})\n",
254             null, ChromePass.CR_DEFINE_INVALID_RETURN_IN_FUNCTION);
255     }
256
257     public void testObjectDefinePropertyDefinesUnquotedProperty() throws Exception {
258         test(
259             "Object.defineProperty(a.b, 'c', {});",
260             "Object.defineProperty(a.b, 'c', {});\n" +
261             "/** @type {?} */\n" +
262             "a.b.c;");
263     }
264
265     public void testCrDefinePropertyDefinesUnquotedPropertyWithStringTypeForPropertyKindAttr()
266             throws Exception {
267         test(
268             "cr.defineProperty(a.prototype, 'c', cr.PropertyKind.ATTR);",
269             "cr.defineProperty(a.prototype, 'c', cr.PropertyKind.ATTR);\n" +
270             "/** @type {string} */\n" +
271             "a.prototype.c;");
272     }
273
274     public void testCrDefinePropertyDefinesUnquotedPropertyWithBooleanTypeForPropertyKindBoolAttr()
275             throws Exception {
276         test(
277             "cr.defineProperty(a.prototype, 'c', cr.PropertyKind.BOOL_ATTR);",
278             "cr.defineProperty(a.prototype, 'c', cr.PropertyKind.BOOL_ATTR);\n" +
279             "/** @type {boolean} */\n" +
280             "a.prototype.c;");
281     }
282
283     public void testCrDefinePropertyDefinesUnquotedPropertyWithAnyTypeForPropertyKindJs()
284             throws Exception {
285         test(
286             "cr.defineProperty(a.prototype, 'c', cr.PropertyKind.JS);",
287             "cr.defineProperty(a.prototype, 'c', cr.PropertyKind.JS);\n" +
288             "/** @type {?} */\n" +
289             "a.prototype.c;");
290     }
291
292     public void testCrDefinePropertyCalledWithouthThirdArgumentMeansCrPropertyKindJs()
293             throws Exception {
294         test(
295             "cr.defineProperty(a.prototype, 'c');",
296             "cr.defineProperty(a.prototype, 'c');\n" +
297             "/** @type {?} */\n" +
298             "a.prototype.c;");
299     }
300
301     public void testCrDefinePropertyDefinesUnquotedPropertyOnPrototypeWhenFunctionIsPassed()
302             throws Exception {
303         test(
304             "cr.defineProperty(a, 'c', cr.PropertyKind.JS);",
305             "cr.defineProperty(a, 'c', cr.PropertyKind.JS);\n" +
306             "/** @type {?} */\n" +
307             "a.prototype.c;");
308     }
309
310     public void testCrDefinePropertyInvalidPropertyKind()
311             throws Exception {
312         test(
313             "cr.defineProperty(a.b, 'c', cr.PropertyKind.INEXISTENT_KIND);",
314             null, ChromePass.CR_DEFINE_PROPERTY_INVALID_PROPERTY_KIND);
315     }
316
317     public void testCrExportPath() throws Exception {
318         test(
319             "cr.exportPath('a.b.c');",
320             "var a = a || {};\n" +
321             "a.b = a.b || {};\n" +
322             "a.b.c = a.b.c || {};\n" +
323             "cr.exportPath('a.b.c');");
324     }
325
326     public void testCrDefineCreatesEveryObjectOnlyOnce() throws Exception {
327         test(
328             "cr.define('a.b.c.d', function() {\n" +
329             "  return {};\n" +
330             "});\n" +
331             "cr.define('a.b.e.f', function() {\n" +
332             "  return {};\n" +
333             "});",
334             "var a = a || {};\n" +
335             "a.b = a.b || {};\n" +
336             "a.b.c = a.b.c || {};\n" +
337             "a.b.c.d = a.b.c.d || {};\n" +
338             "cr.define('a.b.c.d', function() {\n" +
339             "  return {};\n" +
340             "});\n" +
341             "a.b.e = a.b.e || {};\n" +
342             "a.b.e.f = a.b.e.f || {};\n" +
343             "cr.define('a.b.e.f', function() {\n" +
344             "  return {};\n" +
345             "});");
346     }
347
348     public void testCrDefineAndCrExportPathCreateEveryObjectOnlyOnce() throws Exception {
349         test(
350             "cr.exportPath('a.b.c.d');\n" +
351             "cr.define('a.b.e.f', function() {\n" +
352             "  return {};\n" +
353             "});",
354             "var a = a || {};\n" +
355             "a.b = a.b || {};\n" +
356             "a.b.c = a.b.c || {};\n" +
357             "a.b.c.d = a.b.c.d || {};\n" +
358             "cr.exportPath('a.b.c.d');\n" +
359             "a.b.e = a.b.e || {};\n" +
360             "a.b.e.f = a.b.e.f || {};\n" +
361             "cr.define('a.b.e.f', function() {\n" +
362             "  return {};\n" +
363             "});");
364     }
365
366     public void testCrDefineDoesntRedefineCrVar() throws Exception {
367         test(
368             "cr.define('cr.ui', function() {\n" +
369             "  return {};\n" +
370             "});",
371             "cr.ui = cr.ui || {};\n" +
372             "cr.define('cr.ui', function() {\n" +
373             "  return {};\n" +
374             "});");
375     }
376
377     public void testCrExportPathInvalidNumberOfArguments() throws Exception {
378         test("cr.exportPath();", null, ChromePass.CR_EXPORT_PATH_WRONG_NUMBER_OF_ARGUMENTS);
379     }
380
381     public void testCrMakePublicWorksOnOneMethodDefinedInPrototypeObject() throws Exception {
382         test(
383             "/** @constructor */\n" +
384             "function Class() {};\n" +
385             "\n" +
386             "Class.prototype = {\n" +
387             "  /** @return {number} */\n" +
388             "  method_: function() { return 42; }\n" +
389             "};\n" +
390             "\n" +
391             "cr.makePublic(Class, ['method']);",
392             "/** @constructor */\n" +
393             "function Class() {};\n" +
394             "\n" +
395             "Class.prototype = {\n" +
396             "  /** @return {number} */\n" +
397             "  method_: function() { return 42; }\n" +
398             "};\n" +
399             "\n" +
400             "/** @return {number} */\n" +
401             "Class.method;\n" +
402             "\n" +
403             "cr.makePublic(Class, ['method']);");
404     }
405
406     public void testCrMakePublicWorksOnTwoMethods() throws Exception {
407         test(
408             "/** @constructor */\n" +
409             "function Class() {}\n" +
410             "\n" +
411             "Class.prototype = {\n" +
412             "  /** @return {number} */\n" +
413             "  m1_: function() { return 42; },\n" +
414             "\n" +
415             "  /** @return {string} */\n" +
416             "  m2_: function() { return ''; }\n" +
417             "};\n" +
418             "\n" +
419             "cr.makePublic(Class, ['m1', 'm2']);",
420             "/** @constructor */\n" +
421             "function Class() {}\n" +
422             "\n" +
423             "Class.prototype = {\n" +
424             "  /** @return {number} */\n" +
425             "  m1_: function() { return 42; },\n" +
426             "\n" +
427             "  /** @return {string} */\n" +
428             "  m2_: function() { return ''; }\n" +
429             "}\n" +
430             "\n" +
431             "/** @return {number} */\n" +
432             "Class.m1;\n" +
433             "\n" +
434             "/** @return {string} */\n" +
435             "Class.m2;\n" +
436             "\n" +
437             "cr.makePublic(Class, ['m1', 'm2']);");
438     }
439
440     public void testCrMakePublicRequiresMethodsToHaveJSDoc() throws Exception {
441         test("/** @constructor */\n" +
442             "function Class() {}\n" +
443             "\n" +
444             "Class.prototype = {\n" +
445             "  method_: function() {}\n" +
446             "}\n" +
447             "\n" +
448             "cr.makePublic(Class, ['method']);", null, ChromePass.CR_MAKE_PUBLIC_HAS_NO_JSDOC);
449     }
450
451     public void testCrMakePublicDoesNothingWithMethodsNotInAPI() throws Exception {
452         test(
453             "/** @constructor */\n" +
454             "function Class() {}\n" +
455             "\n" +
456             "Class.prototype = {\n" +
457             "  method_: function() {}\n" +
458             "}\n" +
459             "\n" +
460             "cr.makePublic(Class, []);",
461             "/** @constructor */\n" +
462             "function Class() {}\n" +
463             "\n" +
464             "Class.prototype = {\n" +
465             "  method_: function() {}\n" +
466             "}\n" +
467             "\n" +
468             "cr.makePublic(Class, []);");
469     }
470
471     public void testCrMakePublicRequiresExportedMethodToBeDeclared() throws Exception {
472         test(
473             "/** @constructor */\n" +
474             "function Class() {}\n" +
475             "\n" +
476             "Class.prototype = {\n" +
477             "}\n" +
478             "\n" +
479             "cr.makePublic(Class, ['method']);", null,
480             ChromePass.CR_MAKE_PUBLIC_MISSED_DECLARATION);
481     }
482
483     public void testCrMakePublicWorksOnOneMethodDefinedDirectlyOnPrototype() throws Exception {
484         test(
485             "/** @constructor */\n" +
486             "function Class() {}\n" +
487             "\n" +
488             "/** @return {number} */\n" +
489             "Class.prototype.method_ = function() {};\n" +
490             "\n" +
491             "cr.makePublic(Class, ['method']);",
492             "/** @constructor */\n" +
493             "function Class() {}\n" +
494             "\n" +
495             "/** @return {number} */\n" +
496             "Class.prototype.method_ = function() {};\n" +
497             "\n" +
498             "/** @return {number} */\n" +
499             "Class.method;\n" +
500             "\n" +
501             "cr.makePublic(Class, ['method']);");
502     }
503
504     public void testCrMakePublicWorksOnDummyDeclaration() throws Exception {
505         test(
506             "/** @constructor */\n" +
507             "function Class() {}\n" +
508             "\n" +
509             "/** @return {number} */\n" +
510             "Class.prototype.method_;\n" +
511             "\n" +
512             "cr.makePublic(Class, ['method']);",
513             "/** @constructor */\n" +
514             "function Class() {}\n" +
515             "\n" +
516             "/** @return {number} */\n" +
517             "Class.prototype.method_;\n" +
518             "\n" +
519             "/** @return {number} */\n" +
520             "Class.method;\n" +
521             "\n" +
522             "cr.makePublic(Class, ['method']);");
523     }
524
525     public void testCrMakePublicReportsInvalidSecondArgumentMissing() throws Exception {
526         test(
527             "cr.makePublic(Class);", null,
528             ChromePass.CR_MAKE_PUBLIC_INVALID_SECOND_ARGUMENT);
529     }
530
531     public void testCrMakePublicReportsInvalidSecondArgumentNotAnArray() throws Exception {
532         test(
533             "cr.makePublic(Class, 42);", null,
534             ChromePass.CR_MAKE_PUBLIC_INVALID_SECOND_ARGUMENT);
535     }
536
537     public void testCrMakePublicReportsInvalidSecondArgumentArrayWithNotAString() throws Exception {
538         test(
539             "cr.makePublic(Class, [42]);", null,
540             ChromePass.CR_MAKE_PUBLIC_INVALID_SECOND_ARGUMENT);
541     }
542
543 }