/* * Copyright 2011 The Closure Compiler Authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.javascript.jscomp; /** * Tests for {@link ExpandJqueryAliases} */ public class ExpandJqueryAliasesTest extends CompilerTestCase { private JqueryCodingConvention conv = new JqueryCodingConvention(); final DiagnosticType NAME_ERROR = ExpandJqueryAliases.JQUERY_UNABLE_TO_EXPAND_INVALID_NAME_ERROR; final DiagnosticType INVALID_LIT_ERROR = ExpandJqueryAliases.JQUERY_UNABLE_TO_EXPAND_INVALID_LIT_ERROR; final DiagnosticType USELESS_EACH_ERROR = ExpandJqueryAliases.JQUERY_USELESS_EACH_EXPANSION; public ExpandJqueryAliasesTest() {} @Override protected CompilerPass getProcessor(Compiler compiler) { compiler.options.setCodingConvention(conv); return new ExpandJqueryAliases(compiler); } public void testJqueryFnAliasExpansion() { String setupCode = "var jQuery={};jQuery.fn=jQuery.prototype;"; testSame(setupCode); test(setupCode + "jQuery.fn.foo='bar';", setupCode + "jQuery.prototype.foo='bar';"); test(setupCode + "jQuerySub.fn.foo='bar';", setupCode + "jQuerySub.prototype.foo='bar';"); } public void testJqueryExtendExpansion() { String setupCode = "var jQuery={},obj2={};"; // test for extend call that should not be expanded - no arguments testSame(setupCode + "jQuery.extend()"); // test for extend call that should not be expanded - empty argument // this statement has no effect in actual code testSame(setupCode + "jQuery.extend({})"); // test single argument call - should assign to the jQuery namespace test(setupCode + "jQuery.extend({a:'test'})", setupCode + "{jQuery.a = 'test';}"); // test expansion when extending the jQuery prototype test(setupCode + "jQuery.fn=jQuery.prototype;" + "jQuery.fn.extend({a:'test', b:'test2'});", setupCode + "jQuery.fn=jQuery.prototype;" + "{jQuery.prototype.a = 'test'; jQuery.prototype.b = 'test2';}"); // Expand the extension of obj2 test(setupCode + "jQuery.extend(obj2, {a:'test', b:'test2'});", setupCode + "{obj2=obj2||{}; obj2.a='test'; obj2.b='test2';}"); // Expand the jQuery namespace - 2 argument call // Must ensure that the first argument is defined test(setupCode + "jQuery.extend(jQuery,{a:'test', b:'test2'});", setupCode + "{jQuery = jQuery || {}; jQuery.a = 'test';" + "jQuery.b = 'test2';}"); // Test extend call where first argument includes a method call testSame(setupCode+"obj2.meth=function() { return { a:{} }; };" + "jQuery.extend(obj2.meth().a, {a: 'test'});"); } public void testJqueryExpandedEachExpansion() { String setupCode = "var jQuery={};" + "jQuery.expandedEach=function(vals, callback){};"; testSame(setupCode); // Test expansion with object literal test(setupCode + "jQuery.expandedEach({'a': 1, 'b': 2, 'c': 8}," + "function(key, val) { var a = key; jQuery[key] = val; });", setupCode + "(function(){ var a = 'a'; jQuery.a = 1 })();" + "(function(){ var a = 'b'; jQuery.b = 2 })();" + "(function(){ var a = 'c'; jQuery.c = 8 })();"); // Test expansion with array literal // For array literals, the key parameter will be the element index number // and the value parameter will be the string literal. In this case, the // string literal value should become a property name. test(setupCode + "jQuery.expandedEach(['a', 'b', 'c']," + "function(key, val){ jQuery[val] = key; });", setupCode + "(function(){ jQuery.a = 0; })();" + "(function(){ jQuery.b = 1; })();" + "(function(){ jQuery.c = 2 })();"); // Test expansion with object literal using 'this' keyword test(setupCode + "jQuery.expandedEach({'a': 1, 'b': 2, 'c': 8}," + "function(key, val) { var a = key; jQuery[key] = this; });", setupCode + "(function(){ var a = 'a'; jQuery.a = 1 })();" + "(function(){ var a = 'b'; jQuery.b = 2 })();" + "(function(){ var a = 'c'; jQuery.c = 8 })();"); // Test expansion with array literal using 'this' keyword test(setupCode + "jQuery.expandedEach(['a', 'b', 'c']," + "function(key, val){ jQuery[this] = key; });", setupCode + "(function(){ jQuery.a = 0; })();" + "(function(){ jQuery.b = 1; })();" + "(function(){ jQuery.c = 2 })();"); // test nested function using argument name to shadow callback name test(setupCode + "jQuery.expandedEach(['a'], function(key,val) {" + "jQuery[val] = key; (function(key) { jQuery[key] = 1;})('test'); })", setupCode + "(function(){ jQuery.a = 0;" + "(function(key){ jQuery[key] = 1})('test') })()"); // test nested function using var name to shadow callback name test(setupCode + "jQuery.expandedEach(['a'], function(key,val) {" + "jQuery[val] = key; (function(key) { var val = 2;" + "jQuery[key] = val;})('test');})", setupCode + "(function(){" + "jQuery.a=0;" + "(function(key){var val = 2; jQuery[key] = val;})('test')})()"); // test nested function using function name to shadow callback name test(setupCode + "jQuery.expandedEach(['a'], function(key,val) {" + "jQuery[val] = key; (function(key1) {" + "function key() {}; key();" + "})('test');})", setupCode + "(function(){" + "jQuery.a=0;(function(key1) {" + "function key() {}; key(); })('test')})()"); // test using return val test(setupCode + "alert(jQuery.expandedEach(['a']," + "function(key,val) { jQuery[val] = key;})[0])", setupCode + "alert((function(){" + "(function(){ jQuery.a = 0;})(); return ['a']})()[0]);"); // Loop object is a variable. Test that warning is raised. testSame(setupCode + "var a = ['a'];" + "jQuery.expandedEach(a, function(key,val){ jQuery[key]=val; })", INVALID_LIT_ERROR); // Invalid property name. Test that warning is raised. testSame(setupCode + "var obj2={};" + "jQuery.expandedEach(['foo','bar'], function(i, name) {" + "obj2[ '[object ' + name + ']' ] = 'a';});", NAME_ERROR, true); // Useless expansion (key not used). Test that warning is raised. testSame(setupCode + "var obj2={};" + "jQuery.expandedEach(['foo','bar'], function(i, name) {" + "obj2[i] = 1;});", USELESS_EACH_ERROR, false); } }