// Copyright 2006 The Closure Library Authors. All Rights Reserved. // // 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. /** * @fileoverview Unit tests for Closure's base.js. */ goog.provide('goog.baseTest'); goog.setTestOnly('goog.baseTest'); goog.require('goog.Promise'); // Used to test dynamic loading works, see testRequire* goog.require('goog.Timer'); goog.require('goog.dom'); goog.require('goog.dom.TagName'); goog.require('goog.functions'); goog.require('goog.object'); goog.require('goog.test_module'); goog.require('goog.testing.PropertyReplacer'); goog.require('goog.testing.jsunit'); goog.require('goog.testing.recordFunction'); goog.require('goog.userAgent'); var earlyTestModuleGet = goog.module.get('goog.test_module'); /** * @param {?} name * @return {?} */ function getFramedVars(name) { var w = window.frames[name]; var doc = w.document; doc.open(); doc.write( ' in test files is correct. Escape the // / in here so that any such code does not affect it here. assertEquals('<\/script>', testModuleExports.CLOSING_SCRIPT_TAG); // Validate that the module exports object has not changed assertEquals(earlyTestModuleGet, testModuleExports); } // Validate the behavior of goog.module when used from traditional files. function testGoogLoadModuleByUrl() { if (goog.userAgent.IE && !goog.userAgent.isVersionOrHigher('10')) { // IE before 10 don't report an error. return; } stubs.set(goog, 'loadFileSync_', function(src) { return 'closure load file sync: ' + src; }); // "goog.loadModuleByUrl" is not a general purpose code loader, it can // not be used to late load code. var err = assertThrows('loadModuleFromUrl should not hide failures', function() { goog.loadModuleFromUrl('bogus url'); }); assertContains('Cannot write "bogus url" after document load', err.message); } function testModuleExportSealed() { if (goog.userAgent.IE && !goog.userAgent.isVersionOrHigher('9')) { // IE before 9 don't support sealing objects return; } goog.loadModule('goog.module("a.b.supplied"); exports.foo = {};'); var exports0 = goog.module.get('a.b.supplied'); assertTrue(Object.isSealed(exports0)); goog.loadModule('goog.module("a.b.object"); exports = {};'); var exports1 = goog.module.get('a.b.object'); assertTrue(Object.isSealed(exports1)); goog.loadModule('goog.module("a.b.fn"); exports = function() {};'); var exports2 = goog.module.get('a.b.fn'); assertFalse(Object.isSealed(exports2)); } function testWorkaroundSafari10EvalBug0() { // Validate the safari module loading workaround isn't triggered for // browsers we know it isn't needed. if (goog.userAgent.SAFARI) { return; } assertFalse(goog.useSafari10Workaround()); } function testWorkaroundSafari10EvalBug1() { assertEquals( '(function(){' + // no \n 'goog.module(\'foo\');\n' + '\n;})();\n', goog.workaroundSafari10EvalBug( 'goog.module(\'foo\');\n')); } function testWorkaroundSafari10EvalBug2() { assertEquals( '(function(){' + // no \n 'goog.module(\'foo\');\n' + 'alert("//# sourceMappingURL a.b.c.map")\n' + 'alert("//# sourceURL a.b.c.js")\n' + '\n;})();\n', goog.workaroundSafari10EvalBug( 'goog.module(\'foo\');\n' + 'alert("//# sourceMappingURL a.b.c.map")\n' + 'alert("//# sourceURL a.b.c.js")\n')); } function testGoogLoadModuleInSafari10() { try { eval('let es6 = 1'); } catch (e) { // If ES6 block scope syntax isn't supported, don't run the rest of the // test. return; } goog.loadModule( 'goog.module("a.safari.test");' + 'let x = true;' + 'function fn() { return x }' + 'exports.fn = fn;'); var exports = goog.module.get('a.safari.test'); // Safari 10 will throw an exception if the module being loaded is eval'd // without a containing function. assertNotThrows(exports.fn); } function testLoadFileSync() { var fileContents = goog.loadFileSync_('deps.js'); assertTrue( 'goog.loadFileSync_ returns string', typeof fileContents === 'string'); assertTrue('goog.loadFileSync_ string length > 0', fileContents.length > 0); stubs.set(goog.global, 'CLOSURE_LOAD_FILE_SYNC', function(src) { return 'closure load file sync: ' + src; }); assertEquals( 'goog.CLOSURE_LOAD_FILE_SYNC override', goog.loadFileSync_('test url'), 'closure load file sync: test url'); } function testNormalizePath1() { assertEquals('foo/path.js', goog.normalizePath_('./foo/./path.js')); assertEquals('foo/path.js', goog.normalizePath_('bar/../foo/path.js')); assertEquals('bar/path.js', goog.normalizePath_('bar/foo/../path.js')); assertEquals('path.js', goog.normalizePath_('bar/foo/../../path.js')); assertEquals('../foo/path.js', goog.normalizePath_('../foo/path.js')); assertEquals('../../foo/path.js', goog.normalizePath_('../../foo/path.js')); assertEquals('../path.js', goog.normalizePath_('../foo/../path.js')); assertEquals('../../path.js', goog.normalizePath_('../foo/../../path.js')); assertEquals('/../foo/path.js', goog.normalizePath_('/../foo/path.js')); assertEquals('/path.js', goog.normalizePath_('/foo/../path.js')); assertEquals('/foo/path.js', goog.normalizePath_('/./foo/path.js')); assertEquals('//../foo/path.js', goog.normalizePath_('//../foo/path.js')); assertEquals('//path.js', goog.normalizePath_('//foo/../path.js')); assertEquals('//foo/path.js', goog.normalizePath_('//./foo/path.js')); assertEquals('http://../x/y.js', goog.normalizePath_('http://../x/y.js')); assertEquals('http://path.js', goog.normalizePath_('http://foo/../path.js')); assertEquals('http://x/path.js', goog.normalizePath_('http://./x/path.js')); } function testGoogModuleNames() { // avoid usage checks var module = goog.module; function assertInvalidId(id) { var err = assertThrows(function() { module(id); }); assertEquals('Invalid module identifier', err.message); } function assertValidId(id) { // This is a cheesy check, but we validate that we don't get an invalid // namespace warning, but instead get a module isn't loaded correctly // error. var err = assertThrows(function() { module(id); }); assertTrue(err.message.indexOf('has been loaded incorrectly') != -1); } assertInvalidId('/somepath/module.js'); assertInvalidId('./module.js'); assertInvalidId('1'); assertValidId('a'); assertValidId('a.b'); assertValidId('a.b.c'); assertValidId('aB.Cd.eF'); assertValidId('a1.0E.Fg'); assertValidId('_'); assertValidId('$'); assertValidId('_$'); assertValidId('$_'); }