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.
5 package com.google.javascript.jscomp;
8 * Tests {@link ChromePass}.
10 public class ChromePassTest extends CompilerTestCase {
13 protected CompilerPass getProcessor(Compiler compiler) {
14 return new ChromePass(compiler);
18 protected int getNumRepetitions() {
19 // This pass isn't idempotent and only runs once.
23 public void testCrDefineCreatesObjectsForQualifiedName() throws Exception {
25 "cr.define('my.namespace.name', function() {\n" +
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" +
36 public void testCrDefineAssignsExportedFunctionByQualifiedName() throws Exception {
38 "cr.define('namespace', function() {\n" +
39 " function internalStaticMethod() {\n" +
43 " externalStaticMethod: internalStaticMethod\n" +
46 "var namespace = namespace || {};\n" +
47 "cr.define('namespace', function() {\n" +
48 " namespace.externalStaticMethod = function internalStaticMethod() {\n" +
52 " externalStaticMethod: namespace.externalStaticMethod\n" +
57 public void testCrDefineCopiesJSDocForExportedFunction() throws Exception {
58 test("cr.define('namespace', function() {\n" +
59 " /** I'm function's JSDoc */\n" +
60 " function internalStaticMethod() {\n" +
64 " externalStaticMethod: internalStaticMethod\n" +
67 "var namespace = namespace || {};\n" +
68 "cr.define('namespace', function() {\n" +
69 " /** I'm function's JSDoc */\n" +
70 " namespace.externalStaticMethod = function internalStaticMethod() {\n" +
74 " externalStaticMethod: namespace.externalStaticMethod\n" +
79 public void testCrDefineReassignsExportedFunctionByQualifiedName() throws Exception {
81 "cr.define('namespace', function() {\n" +
82 " var internalStaticMethod = function() {\n" +
86 " externalStaticMethod: internalStaticMethod\n" +
89 "var namespace = namespace || {};\n" +
90 "cr.define('namespace', function() {\n" +
91 " namespace.externalStaticMethod = function() {\n" +
95 " externalStaticMethod: namespace.externalStaticMethod\n" +
100 public void testCrDefineCopiesJSDocForExportedVariable() throws Exception {
102 "cr.define('namespace', function() {\n" +
103 " /** I'm function's JSDoc */\n" +
104 " var internalStaticMethod = function() {\n" +
108 " externalStaticMethod: internalStaticMethod\n" +
111 "var namespace = namespace || {};\n" +
112 "cr.define('namespace', function() {\n" +
113 " /** I'm function's JSDoc */\n" +
114 " namespace.externalStaticMethod = function() {\n" +
118 " externalStaticMethod: namespace.externalStaticMethod\n" +
123 public void testCrDefineDoesNothingWithNonExportedFunction() throws Exception {
125 "cr.define('namespace', function() {\n" +
126 " function internalStaticMethod() {\n" +
131 "var namespace = namespace || {};\n" +
132 "cr.define('namespace', function() {\n" +
133 " function internalStaticMethod() {\n" +
140 public void testCrDefineChangesReferenceToExportedFunction() throws Exception {
142 "cr.define('namespace', function() {\n" +
143 " function internalStaticMethod() {\n" +
146 " function letsUseIt() {\n" +
147 " internalStaticMethod();\n" +
150 " externalStaticMethod: internalStaticMethod\n" +
153 "var namespace = namespace || {};\n" +
154 "cr.define('namespace', function() {\n" +
155 " namespace.externalStaticMethod = function internalStaticMethod() {\n" +
158 " function letsUseIt() {\n" +
159 " namespace.externalStaticMethod();\n" +
162 " externalStaticMethod: namespace.externalStaticMethod\n" +
167 public void testCrDefineWrongNumberOfArguments() throws Exception {
168 test("cr.define('namespace', function() { return {}; }, 'invalid argument')\n",
169 null, ChromePass.CR_DEFINE_WRONG_NUMBER_OF_ARGUMENTS);
172 public void testCrDefineInvalidFirstArgument() throws Exception {
173 test("cr.define(42, function() { return {}; })\n",
174 null, ChromePass.CR_DEFINE_INVALID_FIRST_ARGUMENT);
177 public void testCrDefineInvalidSecondArgument() throws Exception {
178 test("cr.define('namespace', 42)\n",
179 null, ChromePass.CR_DEFINE_INVALID_SECOND_ARGUMENT);
182 public void testCrDefineInvalidReturnInFunction() throws Exception {
183 test("cr.define('namespace', function() {})\n",
184 null, ChromePass.CR_DEFINE_INVALID_RETURN_IN_FUNCTION);
187 public void testObjectDefinePropertyDefinesUnquotedProperty() throws Exception {
189 "Object.defineProperty(a.b, 'c', {});",
190 "Object.defineProperty(a.b, 'c', {});\n" +
191 "/** @type {?} */\n" +
195 public void testCrDefinePropertyDefinesUnquotedPropertyWithStringTypeForPropertyKindAttr()
198 "cr.defineProperty(a.prototype, 'c', cr.PropertyKind.ATTR);",
199 "cr.defineProperty(a.prototype, 'c', cr.PropertyKind.ATTR);\n" +
200 "/** @type {string} */\n" +
204 public void testCrDefinePropertyDefinesUnquotedPropertyWithBooleanTypeForPropertyKindBoolAttr()
207 "cr.defineProperty(a.prototype, 'c', cr.PropertyKind.BOOL_ATTR);",
208 "cr.defineProperty(a.prototype, 'c', cr.PropertyKind.BOOL_ATTR);\n" +
209 "/** @type {boolean} */\n" +
213 public void testCrDefinePropertyDefinesUnquotedPropertyWithAnyTypeForPropertyKindJs()
216 "cr.defineProperty(a.prototype, 'c', cr.PropertyKind.JS);",
217 "cr.defineProperty(a.prototype, 'c', cr.PropertyKind.JS);\n" +
218 "/** @type {?} */\n" +
222 public void testCrDefinePropertyCalledWithouthThirdArgumentMeansCrPropertyKindJs()
225 "cr.defineProperty(a.prototype, 'c');",
226 "cr.defineProperty(a.prototype, 'c');\n" +
227 "/** @type {?} */\n" +
231 public void testCrDefinePropertyDefinesUnquotedPropertyOnPrototypeWhenFunctionIsPassed()
234 "cr.defineProperty(a, 'c', cr.PropertyKind.JS);",
235 "cr.defineProperty(a, 'c', cr.PropertyKind.JS);\n" +
236 "/** @type {?} */\n" +
240 public void testCrDefinePropertyInvalidPropertyKind()
243 "cr.defineProperty(a.b, 'c', cr.PropertyKind.INEXISTENT_KIND);",
244 null, ChromePass.CR_DEFINE_PROPERTY_INVALID_PROPERTY_KIND);
247 public void testCrExportPath() throws Exception {
249 "cr.exportPath('a.b.c');",
250 "var a = a || {};\n" +
251 "a.b = a.b || {};\n" +
252 "a.b.c = a.b.c || {};\n" +
253 "cr.exportPath('a.b.c');");
256 public void testCrDefineCreatesEveryObjectOnlyOnce() throws Exception {
258 "cr.define('a.b.c.d', function() {\n" +
261 "cr.define('a.b.e.f', function() {\n" +
264 "var a = a || {};\n" +
265 "a.b = a.b || {};\n" +
266 "a.b.c = a.b.c || {};\n" +
267 "a.b.c.d = a.b.c.d || {};\n" +
268 "cr.define('a.b.c.d', function() {\n" +
271 "a.b.e = a.b.e || {};\n" +
272 "a.b.e.f = a.b.e.f || {};\n" +
273 "cr.define('a.b.e.f', function() {\n" +
278 public void testCrDefineAndCrExportPathCreateEveryObjectOnlyOnce() throws Exception {
280 "cr.exportPath('a.b.c.d');\n" +
281 "cr.define('a.b.e.f', function() {\n" +
284 "var a = a || {};\n" +
285 "a.b = a.b || {};\n" +
286 "a.b.c = a.b.c || {};\n" +
287 "a.b.c.d = a.b.c.d || {};\n" +
288 "cr.exportPath('a.b.c.d');\n" +
289 "a.b.e = a.b.e || {};\n" +
290 "a.b.e.f = a.b.e.f || {};\n" +
291 "cr.define('a.b.e.f', function() {\n" +
296 public void testCrDefineDoesntRedefineCrVar() throws Exception {
298 "cr.define('cr.ui', function() {\n" +
301 "cr.ui = cr.ui || {};\n" +
302 "cr.define('cr.ui', function() {\n" +
307 public void testCrExportPathInvalidNumberOfArguments() throws Exception {
308 test("cr.exportPath();", null, ChromePass.CR_EXPORT_PATH_WRONG_NUMBER_OF_ARGUMENTS);