diff options
Diffstat (limited to 'contexts/data/lib/closure-library/closure/goog/module/modulemanager_test.html')
-rw-r--r-- | contexts/data/lib/closure-library/closure/goog/module/modulemanager_test.html | 2024 |
1 files changed, 0 insertions, 2024 deletions
diff --git a/contexts/data/lib/closure-library/closure/goog/module/modulemanager_test.html b/contexts/data/lib/closure-library/closure/goog/module/modulemanager_test.html deleted file mode 100644 index f1b4aec..0000000 --- a/contexts/data/lib/closure-library/closure/goog/module/modulemanager_test.html +++ /dev/null @@ -1,2024 +0,0 @@ -<!DOCTYPE html> -<html> -<!-- -Copyright 2008 The Closure Library Authors. All Rights Reserved. - -Use of this source code is governed by the Apache License, Version 2.0. -See the COPYING file for details. ---> -<!-- ---> -<head> -<meta http-equiv="X-UA-Compatible" content="IE=edge"> -<title>Closure Unit Tests - goog.module.ModuleManager</title> -<script src="../base.js"></script> -<script> - goog.require('goog.array'); - goog.require('goog.functions'); - goog.require('goog.module.BaseModule'); - goog.require('goog.module.ModuleManager'); - goog.require('goog.module.ModuleManager.CallbackType'); - goog.require('goog.module.ModuleManager.FailureType'); - goog.require('goog.testing'); - goog.require('goog.testing.MockClock'); - goog.require('goog.testing.jsunit'); - goog.require('goog.testing.recordFunction'); -</script> -</head> -<body> -<script> - var clock; - - function setUpPage() { - clock = new goog.testing.MockClock(true); - } - - function tearDownPage() { - clock.dispose(); - } - - function getModuleManager(infoMap) { - var mm = new goog.module.ModuleManager(); - mm.setAllModuleInfo(infoMap); - - mm.isModuleLoaded = function(id) { - return this.getModuleInfo(id).isLoaded(); - } - return mm; - } - - function createSuccessfulBatchLoader(moduleMgr) { - return { - loadModules: function(ids, moduleInfoMap, opt_successFn, opt_errFn, - opt_timeoutFn) { - setTimeout(goog.bind(this.onLoad, this, ids.concat(), 0), 5); - }, - onLoad: function(ids, idxLoaded) { - moduleMgr.beforeLoadModuleCode(ids[idxLoaded]); - moduleMgr.setLoaded(ids[idxLoaded]); - moduleMgr.afterLoadModuleCode(ids[idxLoaded]); - var idx = idxLoaded + 1; - if (idx < ids.length) { - setTimeout(goog.bind(this.onLoad, this, ids, idx), 2); - } - }}; - } - - function createSuccessfulNonBatchLoader(moduleMgr) { - return { - loadModules: function(ids, moduleInfoMap, opt_successFn, opt_errFn, - opt_timeoutFn) { - setTimeout(function() { - moduleMgr.beforeLoadModuleCode(ids[0]); - moduleMgr.setLoaded(ids[0]); - moduleMgr.afterLoadModuleCode(ids[0]); - if (opt_successFn) { - opt_successFn(); - } - }, 5); - }}; - } - - function createUnsuccessfulLoader(moduleMgr, status) { - return { - loadModules: function(ids, moduleInfoMap, opt_successFn, opt_errFn, - opt_timeoutFn) { - moduleMgr.beforeLoadModuleCode(ids[0]); - setTimeout(function() { opt_errFn(status); }, 5); - }}; - } - - function createTimeoutLoader(moduleMgr, status) { - return { - loadModules: function(ids, moduleInfoMap, opt_successFn, opt_errFn, - opt_timeoutFn) { - setTimeout(function() { opt_timeoutFn(status); }, 5); - }}; - } - - /** - * Tests loading a module under different conditions i.e. unloaded - * module, already loaded module, module loaded through user initiated - * actions, synchronous callback for a module that has been already - * loaded. Test both batch and non-batch loaders. - */ - function testExecOnLoad() { - var mm = getModuleManager({'a': [], 'b': [], 'c': []}); - mm.setLoader(createSuccessfulNonBatchLoader(mm)); - execOnLoad_(mm); - - mm = getModuleManager({'a': [], 'b': [], 'c': []}); - mm.setLoader(createSuccessfulBatchLoader(mm)); - mm.setBatchModeEnabled(true); - execOnLoad_(mm); - } - - /** - * Tests execOnLoad with the specified module manager. - * @param {goog.module.ModuleManager} mm The module manager. - */ - function execOnLoad_(mm) { - // When module is unloaded, execOnLoad is async. - var execCalled1 = false; - mm.execOnLoad('a', function() { execCalled1 = true; }); - assertFalse('module "a" should not be loaded', mm.isModuleLoaded('a')); - assertTrue('module "a" should be loading', mm.isModuleLoading('a')); - assertFalse('execCalled1 should not be set yet', execCalled1); - assertTrue('ModuleManager should be active', mm.isActive()); - assertFalse( - 'ModuleManager should not be user active', mm.isUserActive()); - clock.tick(5); - assertTrue('module "a" should be loaded', mm.isModuleLoaded('a')); - assertFalse( - 'module "a" should not be loading', mm.isModuleLoading('a')); - assertTrue('execCalled1 should be set', execCalled1); - assertFalse('ModuleManager should not be active', mm.isActive()); - assertFalse( - 'ModuleManager should not be user active', mm.isUserActive()); - - // When module is already loaded, execOnLoad is still async unless - // specified otherwise. - var execCalled2 = false; - mm.execOnLoad('a', function() { execCalled2 = true; }); - assertTrue('module "a" should be loaded', mm.isModuleLoaded('a')); - assertFalse( - 'module "a" should not be loading', mm.isModuleLoading('a')); - assertFalse('execCalled2 should not be set yet', execCalled2); - clock.tick(5); - assertTrue('execCalled2 should be set', execCalled2); - - // When module is unloaded, execOnLoad is async (user active). - var execCalled5 = false; - mm.execOnLoad('c', - function() { execCalled5 = true; }, null, null, true); - assertFalse('module "c" should not be loaded', mm.isModuleLoaded('c')); - assertTrue('module "c" should be loading', mm.isModuleLoading('c')); - assertFalse('execCalled1 should not be set yet', execCalled5); - assertTrue('ModuleManager should be active', mm.isActive()); - assertTrue('ModuleManager should be user active', mm.isUserActive()); - clock.tick(5); - assertTrue('module "c" should be loaded', mm.isModuleLoaded('c')); - assertFalse( - 'module "c" should not be loading', mm.isModuleLoading('c')); - assertTrue('execCalled1 should be set', execCalled5); - assertFalse('ModuleManager should not be active', mm.isActive()); - assertFalse( - 'ModuleManager should not be user active', mm.isUserActive()); - - // When module is already loaded, execOnLoad is still synchronous when - // so specified - var execCalled6 = false; - mm.execOnLoad('c', function() { execCalled6 = true; }, - undefined, undefined, undefined, true); - assertTrue('module "c" should be loaded', mm.isModuleLoaded('c')); - assertFalse( - 'module "c" should not be loading', mm.isModuleLoading('c')); - assertTrue('execCalled6 should be set', execCalled6); - clock.tick(5); - assertTrue('execCalled6 should still be set', execCalled6); - - } - - /** - * Test aborting the callback called on module load. - */ - function testExecOnLoadAbort() { - var mm = getModuleManager({'a': [], 'b': [], 'c': []}); - mm.setLoader(createSuccessfulNonBatchLoader(mm)); - - // When module is unloaded and abort is called, module still gets - // loaded, but callback is cancelled. - var execCalled1 = false; - var callback1 = mm.execOnLoad('b', function() { execCalled1 = true; }); - callback1.abort(); - clock.tick(5); - assertTrue('module "b" should be loaded', mm.isModuleLoaded('b')); - assertFalse('execCalled3 should not be set', execCalled1); - - // When module is already loaded, execOnLoad is still async, so calling - // abort should still cancel the callback. - var execCalled2 = false; - var callback2 = mm.execOnLoad('a', function() { execCalled2 = true; }); - callback2.abort(); - clock.tick(5); - assertFalse('execCalled2 should not be set', execCalled2); - } - - /** - * Test preloading modules and ensure that the before load, after load - * and set load called are called only once per module. - */ - function testExecOnLoadWhilePreloadingAndViceVersa() { - var mm = getModuleManager({'c': [], 'd': []}); - mm.setLoader(createSuccessfulNonBatchLoader(mm)); - execOnLoadWhilePreloadingAndViceVersa_(mm); - - mm = getModuleManager({'c': [], 'd': []}); - mm.setLoader(createSuccessfulBatchLoader(mm)); - mm.setBatchModeEnabled(true); - execOnLoadWhilePreloadingAndViceVersa_(mm); - } - - /** - * Perform tests with the specified module manager. - * @param {goog.module.ModuleManager} mm The module manager. - */ - function execOnLoadWhilePreloadingAndViceVersa_(mm) { - var mm = getModuleManager({'c': [], 'd': []}); - mm.setLoader(createSuccessfulNonBatchLoader(mm)); - - var origSetLoaded = mm.setLoaded; - var calls = [0, 0, 0]; - mm.beforeLoadModuleCode = function(id) { - calls[0]++; - }; - mm.setLoaded = function(id) { - calls[1]++; - origSetLoaded.call(mm, id); - }; - mm.afterLoadModuleCode = function(id) { - calls[2]++; - }; - - mm.preloadModule('c', 2); - assertFalse( - 'module "c" should not be loading yet', mm.isModuleLoading('c')); - clock.tick(2); - assertTrue( - 'module "c" should now be loading', mm.isModuleLoading('c')); - mm.execOnLoad('c', function() {}); - assertTrue( - 'module "c" should still be loading', mm.isModuleLoading('c')); - clock.tick(5); - assertFalse( - 'module "c" should be done loading', mm.isModuleLoading('c')); - assertEquals( - 'beforeLoad should only be called once for "c"', 1, calls[0]); - assertEquals( - 'setLoaded should only be called once for "c"', 1, calls[1]); - assertEquals( - 'afterLoad should only be called once for "c"', 1, calls[2]); - - mm.execOnLoad('d', function() {}); - assertTrue( - 'module "d" should now be loading', mm.isModuleLoading('d')); - mm.preloadModule('d', 2); - clock.tick(5); - assertFalse( - 'module "d" should be done loading', mm.isModuleLoading('d')); - assertTrue( - 'module "d" should now be loaded', mm.isModuleLoaded('d')); - assertEquals( - 'beforeLoad should only be called once for "d"', 2, calls[0]); - assertEquals( - 'setLoaded should only be called once for "d"', 2, calls[1]); - assertEquals( - 'afterLoad should only be called once for "d"', 2, calls[2]); - } - - /** - * Tests that multiple callbacks on the same module don't cause - * confusion about the active state after the module is finally loaded. - */ - function testUserInitiatedExecOnLoadEventuallyLeavesManagerIdle() { - var mm = getModuleManager({'c': [], 'd': []}); - mm.setLoader(createSuccessfulNonBatchLoader(mm)); - - var calledBack1 = false; - var calledBack2 = false; - - mm.execOnLoad( - 'c', - function() { - calledBack1 = true; - }, - undefined, - undefined, - true); - mm.execOnLoad( - 'c', - function() { - calledBack2 = true; - }, - undefined, - undefined, - true); - mm.load('c'); - - assertTrue( - 'Manager should be active while waiting for load', mm.isUserActive()); - - clock.tick(5); - - assertTrue('First callback should be called', calledBack1); - assertTrue('Second callback should be called', calledBack2); - assertFalse( - 'Manager should be inactive after loading is complete', - mm.isUserActive()); - } - - /** - * Tests loading a module by requesting a Deferred object. - */ - function testLoad() { - var mm = getModuleManager({'a': [], 'b': [], 'c': []}); - mm.setLoader(createSuccessfulNonBatchLoader(mm)); - - var calledBack = false; - var error = null; - - var d = mm.load('a'); - d.addCallback(function(ctx) { - calledBack = true; - }); - d.addErrback(function(err) { - error = err; - }); - - assertFalse(calledBack); - assertNull(error); - assertFalse(mm.isUserActive()); - - clock.tick(5); - - assertTrue(calledBack); - assertNull(error); - } - - /** - * Tests loading multiple modules by requesting a Deferred object. - */ - function testLoadMultiple() { - var mm = getModuleManager({'a': [], 'b': [], 'c': []}); - mm.setBatchModeEnabled(true); - mm.setLoader(createSuccessfulBatchLoader(mm)); - - var calledBack = false; - var error = null; - var calledBack2 = false; - var error2 = null; - - var dMap = mm.loadMultiple(['a', 'b']); - dMap['a'].addCallback(function(ctx) { - calledBack = true; - }); - dMap['a'].addErrback(function(err) { - error = err; - }); - dMap['b'].addCallback(function(ctx) { - calledBack2 = true; - }); - dMap['b'].addErrback(function(err) { - error2 = err; - }); - - assertFalse(calledBack); - assertFalse(calledBack2); - - clock.tick(5); - assertTrue(calledBack); - assertFalse(calledBack2); - assertTrue('module "a" should be loaded', mm.isModuleLoaded('a')); - assertFalse('module "b" should not be loaded', mm.isModuleLoaded('b')); - assertFalse('module "c" should not be loaded', mm.isModuleLoaded('c')); - - clock.tick(2); - - assertTrue(calledBack); - assertTrue(calledBack2); - assertTrue('module "a" should be loaded', mm.isModuleLoaded('a')); - assertTrue('module "b" should be loaded', mm.isModuleLoaded('b')); - assertFalse('module "c" should not be loaded', mm.isModuleLoaded('c')); - assertNull(error); - assertNull(error2); - } - - /** - * Tests loading multiple modules with deps by requesting a Deferred object. - */ - function testLoadMultipleWithDeps() { - var mm = getModuleManager({'a': [], 'b': ['c'], 'c': []}); - mm.setBatchModeEnabled(true); - mm.setLoader(createSuccessfulBatchLoader(mm)); - - var calledBack = false; - var error = null; - var calledBack2 = false; - var error2 = null; - - var dMap = mm.loadMultiple(['a', 'b']); - dMap['a'].addCallback(function(ctx) { - calledBack = true; - }); - dMap['a'].addErrback(function(err) { - error = err; - }); - dMap['b'].addCallback(function(ctx) { - calledBack2 = true; - }); - dMap['b'].addErrback(function(err) { - error2 = err; - }); - - assertFalse(calledBack); - assertFalse(calledBack2); - - clock.tick(5); - assertTrue(calledBack); - assertFalse(calledBack2); - assertTrue('module "a" should be loaded', mm.isModuleLoaded('a')); - assertFalse('module "b" should not be loaded', mm.isModuleLoaded('b')); - assertFalse('module "c" should not be loaded', mm.isModuleLoaded('c')); - - clock.tick(2); - - assertFalse(calledBack2); - assertTrue('module "a" should be loaded', mm.isModuleLoaded('a')); - assertFalse('module "b" should not be loaded', mm.isModuleLoaded('b')); - assertTrue('module "c" should be loaded', mm.isModuleLoaded('c')); - - clock.tick(2); - - assertTrue(calledBack2); - assertTrue('module "a" should be loaded', mm.isModuleLoaded('a')); - assertTrue('module "b" should be loaded', mm.isModuleLoaded('b')); - assertTrue('module "c" should be loaded', mm.isModuleLoaded('c')); - assertNull(error); - assertNull(error2); - } - - /** - * Tests loading multiple modules by requesting a Deferred object when - * a server error occurs. - */ - function testLoadMultipleWithErrors() { - var mm = getModuleManager({'a': [], 'b': [], 'c': []}); - mm.setBatchModeEnabled(true); - mm.setLoader(createUnsuccessfulLoader(mm, 500)); - - var calledBack = false; - var error = null; - var calledBack2 = false; - var error2 = null; - var calledBack3 = false; - var error3 = null; - - var dMap = mm.loadMultiple(['a', 'b', 'c']); - dMap['a'].addCallback(function(ctx) { - calledBack = true; - }); - dMap['a'].addErrback(function(err) { - error = err; - }); - dMap['b'].addCallback(function(ctx) { - calledBack2 = true; - }); - dMap['b'].addErrback(function(err) { - error2 = err; - }); - dMap['c'].addCallback(function(ctx) { - calledBack3 = true; - }); - dMap['c'].addErrback(function(err) { - error3 = err; - }); - - assertFalse(calledBack); - assertFalse(calledBack2); - assertFalse(calledBack3); - - clock.tick(4); - - // A module request is now underway using the unsuccessful loader. - // We substitute a successful loader for future module load requests. - mm.setLoader(createSuccessfulBatchLoader(mm)); - - clock.tick(1); - - assertFalse(calledBack); - assertFalse(calledBack2); - assertFalse(calledBack3); - assertFalse('module "a" should not be loaded', mm.isModuleLoaded('a')); - assertFalse('module "b" should not be loaded', mm.isModuleLoaded('b')); - assertFalse('module "c" should not be loaded', mm.isModuleLoaded('c')); - - // Retry should happen after a backoff - clock.tick(5 + mm.getBackOff_()); - - assertTrue(calledBack); - assertFalse(calledBack2); - assertFalse(calledBack3); - assertTrue('module "a" should be loaded', mm.isModuleLoaded('a')); - assertFalse('module "b" should not be loaded', mm.isModuleLoaded('b')); - assertFalse('module "c" should not be loaded', mm.isModuleLoaded('c')); - - clock.tick(2); - assertTrue(calledBack2); - assertFalse(calledBack3); - assertTrue('module "b" should be loaded', mm.isModuleLoaded('b')); - assertFalse('module "c" should not be loaded', mm.isModuleLoaded('c')); - - clock.tick(2); - assertTrue(calledBack3); - assertTrue('module "c" should be loaded', mm.isModuleLoaded('c')); - - assertNull(error); - assertNull(error2); - assertNull(error3); - } - - /** - * Tests loading multiple modules by requesting a Deferred object when - * consecutive server error occur and the loader falls back to serial - * loads. - */ - function testLoadMultipleWithErrorsFallbackOnSerial() { - var mm = getModuleManager({'a': [], 'b': [], 'c': []}); - mm.setBatchModeEnabled(true); - mm.setLoader(createUnsuccessfulLoader(mm, 500)); - - var calledBack = false; - var error = null; - var calledBack2 = false; - var error2 = null; - var calledBack3 = false; - var error3 = null; - - var dMap = mm.loadMultiple(['a', 'b', 'c']); - dMap['a'].addCallback(function(ctx) { - calledBack = true; - }); - dMap['a'].addErrback(function(err) { - error = err; - }); - dMap['b'].addCallback(function(ctx) { - calledBack2 = true; - }); - dMap['b'].addErrback(function(err) { - error2 = err; - }); - dMap['c'].addCallback(function(ctx) { - calledBack3 = true; - }); - dMap['c'].addErrback(function(err) { - error3 = err; - }); - - assertFalse(calledBack); - assertFalse(calledBack2); - assertFalse(calledBack3); - - clock.tick(5); - - assertFalse(calledBack); - assertFalse(calledBack2); - assertFalse(calledBack3); - assertFalse('module "a" should not be loaded', mm.isModuleLoaded('a')); - assertFalse('module "b" should not be loaded', mm.isModuleLoaded('b')); - assertFalse('module "c" should not be loaded', mm.isModuleLoaded('c')); - - // Retry should happen and fail after a backoff - clock.tick(5 + mm.getBackOff_()); - assertFalse(calledBack); - assertFalse(calledBack2); - assertFalse(calledBack3); - assertFalse('module "a" should not be loaded', mm.isModuleLoaded('a')); - assertFalse('module "b" should not be loaded', mm.isModuleLoaded('b')); - assertFalse('module "c" should not be loaded', mm.isModuleLoaded('c')); - - // A second retry should happen after a backoff - clock.tick(4 + mm.getBackOff_()); - // The second retry is now underway using the unsuccessful loader. - // We substitute a successful loader for future module load requests. - mm.setLoader(createSuccessfulBatchLoader(mm)); - - clock.tick(1); - - // A second retry should fail now - assertFalse(calledBack); - assertFalse(calledBack2); - assertFalse(calledBack3); - assertFalse('module "a" should not be loaded', mm.isModuleLoaded('a')); - assertFalse('module "b" should not be loaded', mm.isModuleLoaded('b')); - assertFalse('module "c" should not be loaded', mm.isModuleLoaded('c')); - - // Each module should be loaded individually now, each taking 5 ticks - - clock.tick(5); - assertTrue(calledBack); - assertFalse(calledBack2); - assertFalse(calledBack3); - assertTrue('module "a" should be loaded', mm.isModuleLoaded('a')); - assertFalse('module "b" should not be loaded', mm.isModuleLoaded('b')); - assertFalse('module "c" should not be loaded', mm.isModuleLoaded('c')); - - clock.tick(5); - assertTrue(calledBack2); - assertFalse(calledBack3); - assertTrue('module "b" should be loaded', mm.isModuleLoaded('b')); - assertFalse('module "c" should not be loaded', mm.isModuleLoaded('c')); - - clock.tick(5); - assertTrue(calledBack3); - assertTrue('module "c" should be loaded', mm.isModuleLoaded('c')); - - assertNull(error); - assertNull(error2); - assertNull(error3); - } - - /** - * Tests loading a module by user action by requesting a Deferred object. - */ - function testLoadForUser() { - var mm = getModuleManager({'a': [], 'b': [], 'c': []}); - mm.setLoader(createSuccessfulNonBatchLoader(mm)); - - var calledBack = false; - var error = null; - - var d = mm.load('a', true); - d.addCallback(function(ctx) { - calledBack = true; - }); - d.addErrback(function(err) { - error = err; - }); - - assertFalse(calledBack); - assertNull(error); - assertTrue(mm.isUserActive()); - - clock.tick(5); - - assertTrue(calledBack); - assertNull(error); - } - - /** - * Tests that preloading a module calls back the deferred object. - */ - function testPreloadDeferredWhenNotLoaded() { - var mm = getModuleManager({'a': []}); - mm.setLoader(createSuccessfulNonBatchLoader(mm)); - - var calledBack = false; - - var d = mm.preloadModule('a');; - d.addCallback(function(ctx) { - calledBack = true; - }); - - // First load should take five ticks. - assertFalse('module "a" should not be loaded yet', calledBack); - clock.tick(5); - assertTrue('module "a" should be loaded', calledBack); - } - - /** - * Tests preloading an already loaded module. - */ - function testPreloadDeferredWhenLoaded() { - var mm = getModuleManager({'a': []}); - mm.setLoader(createSuccessfulNonBatchLoader(mm)); - - var calledBack = false; - - mm.preloadModule('a'); - clock.tick(5); - - var d = mm.preloadModule('a');; - d.addCallback(function(ctx) { - calledBack = true; - }); - - // Module is already loaded, should be called back after the setTimeout - // in preloadModule. - assertFalse('deferred for module "a" should not be called yet', calledBack); - clock.tick(1); - assertTrue('module "a" should be loaded', calledBack); - } - - - /** - * Tests preloading a module that is currently loading. - */ - function testPreloadDeferredWhenLoading() { - var mm = getModuleManager({'a': []}); - mm.setLoader(createSuccessfulNonBatchLoader(mm)); - - mm.preloadModule('a'); - clock.tick(1); - - // 'b' is in the middle of loading, should get called back when it's done. - var calledBack = false; - var d = mm.preloadModule('a');; - d.addCallback(function(ctx) { - calledBack = true; - }); - - assertFalse('module "a" should not be loaded yet', calledBack); - clock.tick(4); - assertTrue('module "a" should be loaded', calledBack); - } - - /** - * Tests that load doesn't trigger another load if a module is already - * preloading. - */ - function testLoadWhenPreloading() { - var mm = getModuleManager({'a': [], 'b': [], 'c': []}); - mm.setLoader(createSuccessfulNonBatchLoader(mm)); - - var origSetLoaded = mm.setLoaded; - var calls = [0, 0, 0]; - mm.beforeLoadModuleCode = function(id) { - calls[0]++; - }; - mm.setLoaded = function(id) { - calls[1]++; - origSetLoaded.call(mm, id); - }; - mm.afterLoadModuleCode = function(id) { - calls[2]++; - }; - - var calledBack = false; - var error = null; - - mm.preloadModule('c', 2); - assertFalse( - 'module "c" should not be loading yet', mm.isModuleLoading('c')); - clock.tick(2); - assertTrue( - 'module "c" should now be loading', mm.isModuleLoading('c')); - - var d = mm.load('c'); - d.addCallback(function(ctx) { - calledBack = true; - }); - d.addErrback(function(err) { - error = err; - }); - - assertTrue( - 'module "c" should still be loading', mm.isModuleLoading('c')); - clock.tick(5); - assertFalse( - 'module "c" should be done loading', mm.isModuleLoading('c')); - assertEquals( - 'beforeLoad should only be called once for "c"', 1, calls[0]); - assertEquals( - 'setLoaded should only be called once for "c"', 1, calls[1]); - assertEquals( - 'afterLoad should only be called once for "c"', 1, calls[2]); - - assertTrue(calledBack); - assertNull(error); - } - - /** - * Tests that load doesn't trigger another load if a module is already - * preloading. - */ - function testLoadMultipleWhenPreloading() { - var mm = getModuleManager({'a': [], 'b': ['d'], 'c': [], 'd': []}); - mm.setLoader(createSuccessfulBatchLoader(mm)); - mm.setBatchModeEnabled(true); - - var origSetLoaded = mm.setLoaded; - var calls = {'a': [0, 0, 0], 'b': [0, 0, 0], - 'c': [0, 0, 0], 'd': [0, 0, 0]}; - mm.beforeLoadModuleCode = function(id) { - calls[id][0]++; - }; - mm.setLoaded = function(id) { - calls[id][1]++; - origSetLoaded.call(mm, id); - }; - mm.afterLoadModuleCode = function(id) { - calls[id][2]++; - }; - - var calledBack = false; - var error = null; - var calledBack2 = false; - var error2 = null; - var calledBack3 = false; - var error3 = null; - - mm.preloadModule('c', 2); - mm.preloadModule('d', 3); - assertFalse( - 'module "c" should not be loading yet', mm.isModuleLoading('c')); - assertFalse( - 'module "d" should not be loading yet', mm.isModuleLoading('d')); - clock.tick(2); - assertTrue( - 'module "c" should now be loading', mm.isModuleLoading('c')); - clock.tick(1); - assertTrue( - 'module "d" should now be loading', mm.isModuleLoading('d')); - - var dMap = mm.loadMultiple(['a', 'b', 'c']); - dMap['a'].addCallback(function(ctx) { - calledBack = true; - }); - dMap['a'].addErrback(function(err) { - error = err; - }); - dMap['b'].addCallback(function(ctx) { - calledBack2 = true; - }); - dMap['b'].addErrback(function(err) { - error2 = err; - }); - dMap['c'].addCallback(function(ctx) { - calledBack3 = true; - }); - dMap['c'].addErrback(function(err) { - error3 = err; - }); - - assertTrue( - 'module "a" should be loading', mm.isModuleLoading('a')); - assertTrue( - 'module "b" should be loading', mm.isModuleLoading('b')); - assertTrue( - 'module "c" should still be loading', mm.isModuleLoading('c')); - clock.tick(4); - assertTrue(calledBack3); - - assertFalse( - 'module "c" should be done loading', mm.isModuleLoading('c')); - assertTrue( - 'module "d" should still be loading', mm.isModuleLoading('d')); - clock.tick(5); - assertFalse( - 'module "d" should be done loading', mm.isModuleLoading('d')); - - assertFalse(calledBack); - assertFalse(calledBack2); - assertTrue( - 'module "a" should still be loading', mm.isModuleLoading('a')); - assertTrue( - 'module "b" should still be loading', mm.isModuleLoading('b')); - clock.tick(7); - - assertTrue(calledBack); - assertTrue(calledBack2); - assertFalse( - 'module "a" should be done loading', mm.isModuleLoading('a')); - assertFalse( - 'module "b" should be done loading', mm.isModuleLoading('b')); - - assertEquals( - 'beforeLoad should only be called once for "a"', 1, calls['a'][0]); - assertEquals( - 'setLoaded should only be called once for "a"', 1, calls['a'][1]); - assertEquals( - 'afterLoad should only be called once for "a"', 1, calls['a'][2]); - assertEquals( - 'beforeLoad should only be called once for "b"', 1, calls['b'][0]); - assertEquals( - 'setLoaded should only be called once for "b"', 1, calls['b'][1]); - assertEquals( - 'afterLoad should only be called once for "b"', 1, calls['b'][2]); - assertEquals( - 'beforeLoad should only be called once for "c"', 1, calls['c'][0]); - assertEquals( - 'setLoaded should only be called once for "c"', 1, calls['c'][1]); - assertEquals( - 'afterLoad should only be called once for "c"', 1, calls['c'][2]); - assertEquals( - 'beforeLoad should only be called once for "d"', 1, calls['d'][0]); - assertEquals( - 'setLoaded should only be called once for "d"', 1, calls['d'][1]); - assertEquals( - 'afterLoad should only be called once for "d"', 1, calls['d'][2]); - - assertNull(error); - assertNull(error2); - assertNull(error3); - } - -/** - * Tests that the deferred is still called when loadMultiple loads modules - * that are already preloading. - */ - function testLoadMultipleWhenPreloadingSameModules() { - var mm = getModuleManager({'a': [], 'b': ['d'], 'c': [], 'd': []}); - mm.setLoader(createSuccessfulBatchLoader(mm)); - mm.setBatchModeEnabled(true); - - var origSetLoaded = mm.setLoaded; - var calls = {'c': [0, 0, 0], 'd': [0, 0, 0]}; - mm.beforeLoadModuleCode = function(id) { - calls[id][0]++; - }; - mm.setLoaded = function(id) { - calls[id][1]++; - origSetLoaded.call(mm, id); - }; - mm.afterLoadModuleCode = function(id) { - calls[id][2]++; - }; - - var calledBack = false; - var error = null; - var calledBack2 = false; - var error2 = null; - - mm.preloadModule('c', 2); - mm.preloadModule('d', 3); - assertFalse( - 'module "c" should not be loading yet', mm.isModuleLoading('c')); - assertFalse( - 'module "d" should not be loading yet', mm.isModuleLoading('d')); - clock.tick(2); - assertTrue( - 'module "c" should now be loading', mm.isModuleLoading('c')); - clock.tick(1); - assertTrue( - 'module "d" should now be loading', mm.isModuleLoading('d')); - - var dMap = mm.loadMultiple(['c', 'd']); - dMap['c'].addCallback(function(ctx) { - calledBack = true; - }); - dMap['c'].addErrback(function(err) { - error = err; - }); - dMap['d'].addCallback(function(ctx) { - calledBack2 = true; - }); - dMap['d'].addErrback(function(err) { - error2 = err; - }); - - assertTrue( - 'module "c" should still be loading', mm.isModuleLoading('c')); - clock.tick(4); - assertFalse( - 'module "c" should be done loading', mm.isModuleLoading('c')); - assertTrue( - 'module "d" should still be loading', mm.isModuleLoading('d')); - clock.tick(5); - assertFalse( - 'module "d" should be done loading', mm.isModuleLoading('d')); - - assertTrue(calledBack); - assertTrue(calledBack2); - - assertEquals( - 'beforeLoad should only be called once for "c"', 1, calls['c'][0]); - assertEquals( - 'setLoaded should only be called once for "c"', 1, calls['c'][1]); - assertEquals( - 'afterLoad should only be called once for "c"', 1, calls['c'][2]); - assertEquals( - 'beforeLoad should only be called once for "d"', 1, calls['d'][0]); - assertEquals( - 'setLoaded should only be called once for "d"', 1, calls['d'][1]); - assertEquals( - 'afterLoad should only be called once for "d"', 1, calls['d'][2]); - - assertNull(error); - assertNull(error2); - } - - /** - * Tests loading a module via load when the module is already - * loaded. The deferred's callback should be called immediately. - */ - function testLoadWhenLoaded() { - var mm = getModuleManager({'a': [], 'b': [], 'c': []}); - mm.setLoader(createSuccessfulNonBatchLoader(mm)); - - var calledBack = false; - var error = null; - - mm.preloadModule('b', 2); - clock.tick(10); - - assertFalse( - 'module "b" should be done loading', mm.isModuleLoading('b')); - - var d = mm.load('b'); - d.addCallback(function(ctx) { - calledBack = true; - }); - d.addErrback(function(err) { - error = err; - }); - - assertTrue(calledBack); - assertNull(error); - } - - /** - * Tests that the deferred's errbacks are called if the module fails to load. - */ - function testLoadWithFailingModule() { - var mm = getModuleManager({'a': [], 'b': [], 'c': []}); - mm.setLoader(createUnsuccessfulLoader(mm, 401)); - mm.registerCallback(goog.module.ModuleManager.CallbackType.ERROR, - function(callbackType, id, cause) { - assertEquals('Failure cause was not as expected', - goog.module.ModuleManager.FailureType.UNAUTHORIZED, - cause); - firedLoadFailed = true; - }); - var calledBack = false; - var error = null; - - var d = mm.load('a'); - d.addCallback(function(ctx) { - calledBack = true; - }); - d.addErrback(function(err) { - error = err; - }); - - assertFalse(calledBack); - assertNull(error); - - clock.tick(500); - - assertFalse(calledBack); - - // NOTE: Deferred always calls errbacks with an Error object. For now the - // module manager just passes the FailureType which gets set as the Error - // object's message. - assertEquals('Failure cause was not as expected', - goog.module.ModuleManager.FailureType.UNAUTHORIZED, - Number(error.message)); - } - - /** - * Tests that the deferred's errbacks are called if a module fails to load. - */ - function testLoadMultipleWithFailingModule() { - var mm = getModuleManager({'a': [], 'b': [], 'c': []}); - mm.setLoader(createUnsuccessfulLoader(mm, 401)); - mm.setBatchModeEnabled(true); - mm.registerCallback(goog.module.ModuleManager.CallbackType.ERROR, - function(callbackType, id, cause) { - assertEquals('Failure cause was not as expected', - goog.module.ModuleManager.FailureType.UNAUTHORIZED, - cause); - }); - var calledBack11 = false; - var error11 = null; - var calledBack12 = false; - var error12 = null; - var calledBack21 = false; - var error21 = null; - var calledBack22 = false; - var error22 = null; - - var dMap = mm.loadMultiple(['a', 'b']); - dMap['a'].addCallback(function(ctx) { - calledBack11 = true; - }); - dMap['a'].addErrback(function(err) { - error11 = err; - }); - dMap['b'].addCallback(function(ctx) { - calledBack12 = true; - }); - dMap['b'].addErrback(function(err) { - error12 = err; - }); - - var dMap2 = mm.loadMultiple(['b', 'c']); - dMap2['b'].addCallback(function(ctx) { - calledBack21 = true; - }); - dMap2['b'].addErrback(function(err) { - error21 = err; - }); - dMap2['c'].addCallback(function(ctx) { - calledBack22 = true; - }); - dMap2['c'].addErrback(function(err) { - error22 = err; - }); - - assertFalse(calledBack11); - assertFalse(calledBack12); - assertFalse(calledBack21); - assertFalse(calledBack22); - assertNull(error11); - assertNull(error12); - assertNull(error21); - assertNull(error22); - - clock.tick(5); - - assertFalse(calledBack11); - assertFalse(calledBack12); - assertFalse(calledBack21); - assertFalse(calledBack22); - - // NOTE: Deferred always calls errbacks with an Error object. For now the - // module manager just passes the FailureType which gets set as the Error - // object's message. - assertEquals('Failure cause was not as expected', - goog.module.ModuleManager.FailureType.UNAUTHORIZED, - Number(error11.message)); - assertEquals('Failure cause was not as expected', - goog.module.ModuleManager.FailureType.UNAUTHORIZED, - Number(error12.message)); - - // The first deferred of the second load should be called since it asks for - // one of the failed modules. - assertEquals('Failure cause was not as expected', - goog.module.ModuleManager.FailureType.UNAUTHORIZED, - Number(error21.message)); - - // The last deferred should be dropped so it is neither called back nor an - // error. - assertFalse(calledBack22); - assertNull(error22); - } - - /** - * Tests that the right dependencies are cancelled on a loadMultiple failure. - */ - function testLoadMultipleWithFailingModuleDependencies() { - var mm = getModuleManager( - {'a': [], 'b': [], 'c': ['b'], 'd': ['c'], 'e': []}); - mm.setLoader(createUnsuccessfulLoader(mm, 401)); - mm.setBatchModeEnabled(true); - var cancelledIds = []; - - mm.registerCallback(goog.module.ModuleManager.CallbackType.ERROR, - function(callbackType, id, cause) { - assertEquals('Failure cause was not as expected', - goog.module.ModuleManager.FailureType.UNAUTHORIZED, - cause); - cancelledIds.push(id); - }); - var calledBack11 = false; - var error11 = null; - var calledBack12 = false; - var error12 = null; - var calledBack21 = false; - var error21 = null; - var calledBack22 = false; - var error22 = null; - var calledBack23 = false; - var error23 = null; - - var dMap = mm.loadMultiple(['a', 'b']); - dMap['a'].addCallback(function(ctx) { - calledBack11 = true; - }); - dMap['a'].addErrback(function(err) { - error11 = err; - }); - dMap['b'].addCallback(function(ctx) { - calledBack12 = true; - }); - dMap['b'].addErrback(function(err) { - error12 = err; - }); - - var dMap2 = mm.loadMultiple(['c', 'd', 'e']); - dMap2['c'].addCallback(function(ctx) { - calledBack21 = true; - }); - dMap2['c'].addErrback(function(err) { - error21 = err; - }); - dMap2['d'].addCallback(function(ctx) { - calledBack22 = true; - }); - dMap2['d'].addErrback(function(err) { - error22 = err; - }); - dMap2['e'].addCallback(function(ctx) { - calledBack23 = true; - }); - dMap2['e'].addErrback(function(err) { - error23 = err; - }); - - assertFalse(calledBack11); - assertFalse(calledBack12); - assertFalse(calledBack21); - assertFalse(calledBack22); - assertFalse(calledBack23); - assertNull(error11); - assertNull(error12); - assertNull(error21); - assertNull(error22); - assertNull(error23); - - clock.tick(5); - - assertFalse(calledBack11); - assertFalse(calledBack12); - assertFalse(calledBack21); - assertFalse(calledBack22); - assertFalse(calledBack23); - - // NOTE: Deferred always calls errbacks with an Error object. For now the - // module manager just passes the FailureType which gets set as the Error - // object's message. - assertEquals('Failure cause was not as expected', - goog.module.ModuleManager.FailureType.UNAUTHORIZED, - Number(error11.message)); - assertEquals('Failure cause was not as expected', - goog.module.ModuleManager.FailureType.UNAUTHORIZED, - Number(error12.message)); - - // Check that among the failed modules, 'c' and 'd' are also cancelled - // due to dependencies. - assertTrue(goog.array.equals(['a', 'b', 'c', 'd'], cancelledIds.sort())); - } - - /** - * Tests that when loading multiple modules, the input array is not modified - * when it has duplicates. - */ - function testLoadMultipleWithDuplicates() { - var mm = getModuleManager({'a': [], 'b': []}); - mm.setBatchModeEnabled(true); - mm.setLoader(createSuccessfulBatchLoader(mm)); - - var listWithDuplicates = ['a', 'a', 'b']; - mm.loadMultiple(listWithDuplicates); - assertArrayEquals('loadMultiple should not modify its input', - ['a', 'a', 'b'], listWithDuplicates); - } - - /** - * Test loading dependencies transitively. - */ - function testLoadingDepsInNonBatchMode1() { - var mm = getModuleManager({ - 'i': [], - 'j': [], - 'k': ['j'], - 'l': ['i','j','k']}); - mm.setLoader(createSuccessfulNonBatchLoader(mm)); - - mm.preloadModule('j'); - clock.tick(5); - assertTrue('module "j" should be loaded', mm.isModuleLoaded('j')); - assertFalse( - 'module "i" should not be loaded (1)', mm.isModuleLoaded('i')); - assertFalse( - 'module "k" should not be loaded (1)', mm.isModuleLoaded('k')); - assertFalse( - 'module "l" should not be loaded (1)', mm.isModuleLoaded('l')); - - // When loading a module in non-batch mode, its dependencies should be - // requested independently, and in dependency order. - mm.preloadModule('l'); - clock.tick(5); - assertTrue('module "i" should be loaded', mm.isModuleLoaded('i')); - assertFalse( - 'module "k" should not be loaded (2)', mm.isModuleLoaded('k')); - assertFalse( - 'module "l" should not be loaded (2)', mm.isModuleLoaded('l')); - clock.tick(5); - assertTrue('module "k" should be loaded', mm.isModuleLoaded('k')); - assertFalse( - 'module "l" should not be loaded (3)', mm.isModuleLoaded('l')); - clock.tick(5); - assertTrue( - 'module "l" should be loaded', mm.isModuleLoaded('l')); - } - - /** - * Test loading dependencies transitively and in dependency order. - */ - function testLoadingDepsInNonBatchMode2() { - var mm = getModuleManager({ - 'h': [], - 'i': ['h'], - 'j': ['i'], - 'k': ['j'], - 'l': ['i','j','k'], - 'm': ['l']}); - mm.setLoader(createSuccessfulNonBatchLoader(mm)); - - // When loading a module in non-batch mode, its dependencies should be - // requested independently, and in dependency order. The order in this - // case should be h,i,j,k,l,m. - mm.preloadModule('m'); - clock.tick(5); - assertTrue('module "h" should be loaded', mm.isModuleLoaded('h')); - assertFalse( - 'module "i" should not be loaded (1)', mm.isModuleLoaded('i')); - assertFalse( - 'module "j" should not be loaded (1)', mm.isModuleLoaded('j')); - assertFalse( - 'module "k" should not be loaded (1)', mm.isModuleLoaded('k')); - assertFalse( - 'module "l" should not be loaded (1)', mm.isModuleLoaded('l')); - assertFalse( - 'module "m" should not be loaded (1)', mm.isModuleLoaded('m')); - - clock.tick(5); - assertTrue('module "i" should be loaded', mm.isModuleLoaded('i')); - assertFalse( - 'module "j" should not be loaded (2)', mm.isModuleLoaded('j')); - assertFalse( - 'module "k" should not be loaded (2)', mm.isModuleLoaded('k')); - assertFalse( - 'module "l" should not be loaded (2)', mm.isModuleLoaded('l')); - assertFalse( - 'module "m" should not be loaded (2)', mm.isModuleLoaded('m')); - - clock.tick(5); - assertTrue('module "j" should be loaded', mm.isModuleLoaded('j')); - assertFalse( - 'module "k" should not be loaded (3)', mm.isModuleLoaded('k')); - assertFalse( - 'module "l" should not be loaded (3)', mm.isModuleLoaded('l')); - assertFalse( - 'module "m" should not be loaded (3)', mm.isModuleLoaded('m')); - - clock.tick(5); - assertTrue('module "k" should be loaded', mm.isModuleLoaded('k')); - assertFalse( - 'module "l" should not be loaded (4)', mm.isModuleLoaded('l')); - assertFalse( - 'module "m" should not be loaded (4)', mm.isModuleLoaded('m')); - - clock.tick(5); - assertTrue('module "l" should be loaded', mm.isModuleLoaded('l')); - assertFalse( - 'module "m" should not be loaded (5)', mm.isModuleLoaded('m')); - - clock.tick(5); - assertTrue('module "m" should be loaded', mm.isModuleLoaded('m')); - } - - function testLoadingDepsInBatchMode() { - var mm = getModuleManager({ - 'e': [], - 'f': [], - 'g': ['f'], - 'h': ['e','f','g']}); - mm.setLoader(createSuccessfulBatchLoader(mm)); - mm.setBatchModeEnabled(true); - - mm.preloadModule('f'); - clock.tick(5); - assertTrue('module "f" should be loaded', mm.isModuleLoaded('f')); - assertFalse( - 'module "e" should not be loaded (1)', mm.isModuleLoaded('e')); - assertFalse( - 'module "g" should not be loaded (1)', mm.isModuleLoaded('g')); - assertFalse( - 'module "h" should not be loaded (1)', mm.isModuleLoaded('h')); - - // When loading a module in batch mode, its not-yet-loaded dependencies - // should be requested at the same time, and in dependency order. - mm.preloadModule('h'); - clock.tick(5); - assertTrue('module "e" should be loaded', mm.isModuleLoaded('e')); - assertFalse( - 'module "g" should not be loaded (2)', mm.isModuleLoaded('g')); - assertFalse( - 'module "h" should not be loaded (2)', mm.isModuleLoaded('h')); - clock.tick(2); - assertTrue( - 'module "g" should be loaded', mm.isModuleLoaded('g')); - assertFalse( - 'module "h" should not be loaded (3)', mm.isModuleLoaded('h')); - clock.tick(2); - assertTrue( - 'module "h" should be loaded', mm.isModuleLoaded('h')); - } - - /** - * Test unauthorized errors while loading modules. - */ - function testUnauthorizedLoading() { - var mm = getModuleManager({ - 'm': [], - 'n': [], - 'o': ['n']}); - mm.setLoader(createUnsuccessfulLoader(mm, 401)); - - // Callback checks for an unauthorized error - var firedLoadFailed = false; - mm.registerCallback(goog.module.ModuleManager.CallbackType.ERROR, - function(callbackType, id, cause) { - assertEquals('Failure cause was not as expected', - goog.module.ModuleManager.FailureType.UNAUTHORIZED, - cause); - firedLoadFailed = true; - }); - mm.execOnLoad('o', function() {}); - assertTrue('module "o" should be loading', mm.isModuleLoading('o')); - assertTrue('module "n" should be loading', mm.isModuleLoading('n')); - clock.tick(5); - assertTrue( - 'should have called unauthorized module callback', firedLoadFailed); - assertFalse( - 'module "o" should not be loaded', mm.isModuleLoaded('o')); - assertFalse( - 'module "o" should not be loading', mm.isModuleLoading('o')); - assertFalse( - 'module "n" should not be loaded', mm.isModuleLoaded('n')); - assertFalse( - 'module "n" should not be loading', mm.isModuleLoading('n')); - } - - /** - * Test error loading modules which are retried. - */ - function testErrorLoadingModule() { - var mm = getModuleManager({ - 'p': ['q'], - 'q': [], - 'r': ['q','p']}); - mm.setLoader(createUnsuccessfulLoader(mm, 500)); - - mm.preloadModule('r'); - clock.tick(4); - - // A module request is now underway using the unsuccessful loader. - // We substitute a successful loader for future module load requests. - mm.setLoader(createSuccessfulNonBatchLoader(mm)); - clock.tick(1); - assertFalse( - 'module "q" should not be loaded (1)', mm.isModuleLoaded('q')); - assertFalse( - 'module "p" should not be loaded (1)', mm.isModuleLoaded('p')); - assertFalse( - 'module "r" should not be loaded (1)', mm.isModuleLoaded('r')); - - // Failed loads are automatically retried after a backOff. - clock.tick(5 + mm.getBackOff_()); - assertTrue('module "q" should be loaded', mm.isModuleLoaded('q')); - assertFalse( - 'module "p" should not be loaded (2)', mm.isModuleLoaded('p')); - assertFalse( - 'module "r" should not be loaded (2)', mm.isModuleLoaded('r')); - - // A successful load decrements the backOff. - clock.tick(5); - assertTrue('module "p" should be loaded', mm.isModuleLoaded('p')); - assertFalse( - 'module "r" should not be loaded (3)', mm.isModuleLoaded('r')); - clock.tick(5); - assertTrue( - 'module "r" should be loaded', mm.isModuleLoaded('r')); - } - - /** - * Test consecutive errors in loading modules. - */ - function testConsecutiveErrors() { - var mm = getModuleManager({'s': []}); - mm.setLoader(createUnsuccessfulLoader(mm, 500)); - - // Register an error callback for consecutive failures. - var firedLoadFailed = false; - mm.registerCallback(goog.module.ModuleManager.CallbackType.ERROR, - function(callbackType, id, cause) { - assertEquals('Failure cause was not as expected', - goog.module.ModuleManager.FailureType.CONSECUTIVE_FAILURES, - cause); - firedLoadFailed = true; - }); - - mm.preloadModule('s'); - assertFalse( - 'module "s" should not be loaded (0)', mm.isModuleLoaded('s')); - - // Fail twice. - for (var i = 0; i < 2; i++) { - clock.tick(5 + mm.getBackOff_()); - assertFalse( - 'module "s" should not be loaded (1)', mm.isModuleLoaded('s')); - assertFalse( - 'should not fire failed callback (1)', firedLoadFailed); - } - - // Fail a third time and check that the callback is fired. - clock.tick(5 + mm.getBackOff_()); - assertFalse( - 'module "s" should not be loaded (2)', mm.isModuleLoaded('s')); - assertTrue( - 'should have fired failed callback', firedLoadFailed); - - // Check that it doesn't attempt to load the module anymore after it has - // failed. - var triedLoad = false; - mm.setLoader({ - loadModules: function(ids, moduleInfoMap, opt_successFn, opt_errFn) { - triedLoad = true; - }}); - - // Also reset the failed callback flag and make sure it isn't called - // again. - firedLoadFailed = false; - clock.tick(10 + mm.getBackOff_()); - assertFalse( - 'module "s" should not be loaded (3)', mm.isModuleLoaded('s')); - assertFalse('No more loads should have been tried', triedLoad); - assertFalse('The load failed callback should be fired only once', - firedLoadFailed); - } - - /** - * Test loading errors due to old code. - */ - function testOldCodeGoneError() { - var mm = getModuleManager({'s': []}); - mm.setLoader(createUnsuccessfulLoader(mm, 410)); - - // Callback checks for an old code failure - var firedLoadFailed = false; - mm.registerCallback(goog.module.ModuleManager.CallbackType.ERROR, - function(callbackType, id, cause) { - assertEquals('Failure cause was not as expected', - goog.module.ModuleManager.FailureType.OLD_CODE_GONE, - cause); - firedLoadFailed = true; - }); - - mm.preloadModule('s', 0); - assertFalse( - 'module "s" should not be loaded (0)', mm.isModuleLoaded('s')); - clock.tick(5); - assertFalse( - 'module "s" should not be loaded (1)', mm.isModuleLoaded('s')); - assertTrue( - 'should have called old code gone callback', firedLoadFailed); - } - - /** - * Test timeout. - */ - function testTimeout() { - var mm = getModuleManager({'s': []}); - mm.setLoader(createTimeoutLoader(mm)); - - // Callback checks for timeout - var firedTimeout = false; - mm.registerCallback(goog.module.ModuleManager.CallbackType.ERROR, - function(callbackType, id, cause) { - assertEquals('Failure cause was not as expected', - goog.module.ModuleManager.FailureType.TIMEOUT, - cause); - firedTimeout = true; - }); - - mm.preloadModule('s', 0); - assertFalse( - 'module "s" should not be loaded (0)', mm.isModuleLoaded('s')); - clock.tick(5); - assertFalse( - 'module "s" should not be loaded (1)', mm.isModuleLoaded('s')); - assertTrue( - 'should have called timeout callback', firedTimeout); - } - - /** - * Tests that an error during execOnLoad will trigger the error callback. - */ - function testExecOnLoadError() { - // Expect two callbacks, each of which will be called with callback type - // ERROR, the right module id and failure type INIT_ERROR. - var errorCallback1 = goog.testing.createFunctionMock('callback1'); - errorCallback1(goog.module.ModuleManager.CallbackType.ERROR, 'b', - goog.module.ModuleManager.FailureType.INIT_ERROR); - - var errorCallback2 = goog.testing.createFunctionMock('callback2'); - errorCallback2(goog.module.ModuleManager.CallbackType.ERROR, 'b', - goog.module.ModuleManager.FailureType.INIT_ERROR); - - errorCallback1.$replay(); - errorCallback2.$replay(); - - var mm = new goog.module.ModuleManager(); - mm.setLoader(createSuccessfulNonBatchLoader(mm)); - - // Register the first callback before setting the module info map. - mm.registerCallback(goog.module.ModuleManager.CallbackType.ERROR, - errorCallback1); - - mm.setAllModuleInfo({'a': [], 'b': [], 'c': []}); - - // Register the second callback after setting the module info map. - mm.registerCallback(goog.module.ModuleManager.CallbackType.ERROR, - errorCallback2); - - var execOnLoadBCalled = false; - mm.execOnLoad('b', function() { - execOnLoadBCalled = true; - throw new Error(); - }); - - clock.tick(5); - - assertTrue('execOnLoad should have been called on module b.', - execOnLoadBCalled); - errorCallback1.$verify(); - errorCallback2.$verify(); - } - - /** - * Tests that an error during execOnLoad will trigger the error callback. - * Uses setAllModuleInfoString rather than setAllModuleInfo. - */ - function testExecOnLoadErrorModuleInfoString() { - // Expect a callback to be called with callback type ERROR, the right module - // id and failure type INIT_ERROR. - var errorCallback = goog.testing.createFunctionMock('callback'); - errorCallback(goog.module.ModuleManager.CallbackType.ERROR, 'b', - goog.module.ModuleManager.FailureType.INIT_ERROR); - - errorCallback.$replay(); - - var mm = new goog.module.ModuleManager(); - mm.setLoader(createSuccessfulNonBatchLoader(mm)); - - // Register the first callback before setting the module info map. - mm.registerCallback(goog.module.ModuleManager.CallbackType.ERROR, - errorCallback); - - mm.setAllModuleInfoString('a/b/c'); - - var execOnLoadBCalled = false; - mm.execOnLoad('b', function() { - execOnLoadBCalled = true; - throw new Error(); - }); - - clock.tick(5); - - assertTrue('execOnLoad should have been called on module b.', - execOnLoadBCalled); - errorCallback.$verify(); - } - - /** - * Make sure ModuleInfo objects in moduleInfoMap_ get disposed. - */ - function testDispose() { - var mm = getModuleManager({'a': [], 'b': [], 'c': []}); - - var moduleInfoA = mm.getModuleInfo('a'); - assertNotNull(moduleInfoA); - var moduleInfoB = mm.getModuleInfo('b'); - assertNotNull(moduleInfoB); - var moduleInfoC = mm.getModuleInfo('c'); - assertNotNull(moduleInfoC); - - mm.dispose(); - assertTrue(moduleInfoA.isDisposed()); - assertTrue(moduleInfoB.isDisposed()); - assertTrue(moduleInfoC.isDisposed()); - } - - function testDependencyOrderingWithSimpleDeps() { - var mm = getModuleManager({ - 'a': ['b', 'c'], - 'b': ['d'], - 'c': ['e', 'f'], - 'd': [], - 'e': [], - 'f': [] - }); - var ids = mm.getNotYetLoadedTransitiveDepIds_('a'); - assertDependencyOrder(ids, mm); - assertArrayEquals(['d', 'e', 'f', 'b', 'c', 'a'], ids); - } - - function testDependencyOrderingWithCommonDepsInDeps() { - // Tests to make sure that if dependencies of the root are loaded before - // their common dependencies. - var mm = getModuleManager({ - 'a': ['b', 'c'], - 'b': ['d'], - 'c': ['d'], - 'd': [] - }); - var ids = mm.getNotYetLoadedTransitiveDepIds_('a'); - assertDependencyOrder(ids, mm); - assertArrayEquals(['d', 'b', 'c', 'a'], ids); - } - - function testDependencyOrderingWithCommonDepsInRoot1() { - // Tests the case where a dependency of the root depends on another - // dependency of the root. Irregardless of ordering in the root's - // deps. - var mm = getModuleManager({ - 'a': ['b', 'c'], - 'b': ['c'], - 'c': [] - }); - var ids = mm.getNotYetLoadedTransitiveDepIds_('a'); - assertDependencyOrder(ids, mm); - assertArrayEquals(['c', 'b', 'a'], ids); - } - - function testDependencyOrderingWithCommonDepsInRoot2() { - // Tests the case where a dependency of the root depends on another - // dependency of the root. Irregardless of ordering in the root's - // deps. - var mm = getModuleManager({ - 'a': ['b', 'c'], - 'b': [], - 'c': ['b'] - }); - var ids = mm.getNotYetLoadedTransitiveDepIds_('a'); - assertDependencyOrder(ids, mm); - assertArrayEquals(['b', 'c', 'a'], ids); - } - - function testDependencyOrderingWithGmailExample() { - // Real dependency graph taken from gmail. - var mm = getModuleManager({ - 's': ['dp', 'ml', 'md'], - 'dp': ['a'], - 'ml': ['ld', 'm'], - 'ld': ['a'], - 'm': ['ad', 'mh', 'n'], - 'md': ['mh', 'ld'], - 'a': [], - 'mh': [], - 'ad': [], - 'n': [] - }); - - mm.setLoaded('a'); - mm.setLoaded('m'); - mm.setLoaded('n'); - mm.setLoaded('ad'); - mm.setLoaded('mh'); - - var ids = mm.getNotYetLoadedTransitiveDepIds_('s'); - assertDependencyOrder(ids, mm); - assertArrayEquals(['ld', 'dp', 'ml', 'md', 's'], ids); - } - - function assertDependencyOrder(list, mm) { - var seen = {}; - for (var i = 0; i < list.length; i++) { - var id = list[i]; - seen[id] = true; - var deps = mm.getModuleInfo(id).getDependencies(); - for (var j = 0; j < deps.length; j++) { - var dep = deps[j]; - assertTrue('Unresolved dependency [' + dep + '] for [' + id + '].', - seen[dep] || mm.getModuleInfo(dep).isLoaded()); - } - } - } - - function testRegisterInitializationCallback() { - var initCalled = 0; - var mm = getModuleManager({'a': [], 'b': [], 'c': []}); - mm.setLoader(createSuccessfulNonBatchLoaderWithRegisterInitCallback(mm, - function() { - ++initCalled; - })); - execOnLoad_(mm); - // execOnLoad_ loads modules a and c - assertTrue(initCalled == 2); - } - - function createSuccessfulNonBatchLoaderWithRegisterInitCallback( - moduleMgr, fn) { - return { - loadModules: function(ids, moduleInfoMap, opt_successFn, opt_errFn, - opt_timeoutFn) { - moduleMgr.beforeLoadModuleCode(ids[0]); - moduleMgr.registerInitializationCallback(fn); - setTimeout(function() { - moduleMgr.setLoaded(ids[0]); - moduleMgr.afterLoadModuleCode(ids[0]); - if (opt_successFn) { - opt_successFn(); - } - }, 5); - }}; - } - - function testSetModuleConstructor() { - var initCalled = 0; - var mm = getModuleManager({'a': [], 'b': [], 'c': []}); - var info = { - 'a': { ctor: AModule, count: 0 }, - 'b': { ctor: BModule, count: 0 }, - 'c': { ctor: CModule, count: 0 } - }; - function AModule() { - ++info['a'].count; - goog.module.BaseModule.call(this); - } - goog.inherits(AModule, goog.module.BaseModule); - function BModule() { - ++info['b'].count; - goog.module.BaseModule.call(this); - } - goog.inherits(BModule, goog.module.BaseModule); - function CModule() { - ++info['c'].count; - goog.module.BaseModule.call(this); - } - goog.inherits(CModule, goog.module.BaseModule); - - mm.setLoader(createSuccessfulNonBatchLoaderWithConstructor(mm, info)); - execOnLoad_(mm); - assertTrue(info['a'].count == 1); - assertTrue(info['b'].count == 0); - assertTrue(info['c'].count == 1); - assertTrue(mm.getModuleInfo('a').getModule() instanceof AModule); - assertTrue(mm.getModuleInfo('c').getModule() instanceof CModule); - } - - /** - * Tests that a call to load the loading module during module initialization - * doesn't trigger a second load. - */ - function testLoadWhenInitializing() { - var mm = getModuleManager({'a': []}); - mm.setLoader(createSuccessfulNonBatchLoader(mm)); - - var info = { - 'a': { ctor: AModule, count: 0 } - }; - function AModule() { - ++info['a'].count; - goog.module.BaseModule.call(this); - } - goog.inherits(AModule, goog.module.BaseModule); - AModule.prototype.initialize = function() { - mm.load('a'); - }; - mm.setLoader(createSuccessfulNonBatchLoaderWithConstructor(mm, info)); - mm.preloadModule('a'); - clock.tick(5); - assertEquals(info['a'].count, 1); - } - - function testErrorInEarlyCallback() { - var errback = goog.testing.recordFunction(); - var callback = goog.testing.recordFunction(); - var mm = getModuleManager({'a': [], 'b': ['a']}); - mm.getModuleInfo('a').registerEarlyCallback(goog.functions.error('error')); - mm.getModuleInfo('a').registerCallback(callback); - mm.getModuleInfo('a').registerErrback(errback); - - mm.setLoader(createSuccessfulNonBatchLoaderWithConstructor( - mm, createModulesFor('a', 'b'))); - mm.preloadModule('b'); - clock.tick(5); - - assertEquals(0, callback.getCallCount()); - assertEquals(1, errback.getCallCount()); - assertEquals(goog.module.ModuleManager.FailureType.INIT_ERROR, - errback.getLastCall().getArguments()[0]); - assertTrue(mm.getModuleInfo('a').isLoaded()); - assertFalse(mm.getModuleInfo('b').isLoaded()); - - clock.tick(5); - assertTrue(mm.getModuleInfo('b').isLoaded()); - } - - function testErrorInNormalCallback() { - var earlyCallback = goog.testing.recordFunction(); - var errback = goog.testing.recordFunction(); - var mm = getModuleManager({'a': [], 'b': ['a']}); - mm.getModuleInfo('a').registerEarlyCallback(earlyCallback); - mm.getModuleInfo('a').registerEarlyCallback(goog.functions.error('error')); - mm.getModuleInfo('a').registerErrback(errback); - - mm.setLoader(createSuccessfulNonBatchLoaderWithConstructor( - mm, createModulesFor('a', 'b'))); - mm.preloadModule('b'); - clock.tick(10); - - assertEquals(1, errback.getCallCount()); - assertEquals(goog.module.ModuleManager.FailureType.INIT_ERROR, - errback.getLastCall().getArguments()[0]); - assertTrue(mm.getModuleInfo('a').isLoaded()); - assertTrue(mm.getModuleInfo('b').isLoaded()); - } - - function testErrorInErrback() { - var mm = getModuleManager({'a': [], 'b': ['a']}); - mm.getModuleInfo('a').registerCallback(goog.functions.error('error1')); - mm.getModuleInfo('a').registerErrback(goog.functions.error('error2')); - - mm.setLoader(createSuccessfulNonBatchLoaderWithConstructor( - mm, createModulesFor('a', 'b'))); - mm.preloadModule('a'); - var e = assertThrows(function() { - clock.tick(10); - }); - assertContains('Module errback failure', e.message); - if (!goog.userAgent.IE) { - assertContains('error2', e.message); - } - - assertTrue(mm.getModuleInfo('a').isLoaded()); - } - - function createModulesFor(var_args) { - var result = {}; - for (var i = 0; i < arguments.length; i++) { - var key = arguments[i]; - result[key] = {ctor: goog.module.BaseModule}; - } - return result; - } - - function createSuccessfulNonBatchLoaderWithConstructor(moduleMgr, info) { - return { - loadModules: function(ids, moduleInfoMap, opt_successFn, opt_errFn, - opt_timeoutFn) { - setTimeout(function() { - moduleMgr.beforeLoadModuleCode(ids[0]); - moduleMgr.setModuleConstructor(info[ids[0]].ctor); - moduleMgr.setLoaded(ids[0]); - moduleMgr.afterLoadModuleCode(ids[0]); - if (opt_successFn) { - opt_successFn(); - } - }, 5); - }}; - } - - function testInitCallbackInBaseModule() { - var mm = new goog.module.ModuleManager(); - var called = false; - var context; - mm.registerInitializationCallback(function(mcontext) { - called = true; - context = mcontext; - }); - mm.setAllModuleInfo({'a': [], 'b': ['a']}); - assertTrue('Base initialization not called', called); - assertNull('Context should still be null', context); - - var mm = new goog.module.ModuleManager(); - called = false; - mm.registerInitializationCallback(function(mcontext) { - called = true; - context = mcontext; - }); - var appContext = {}; - mm.setModuleContext(appContext); - assertTrue('Base initialization not called after setModuleContext', called); - assertEquals('Did not receive module context', appContext, context); - } - - function testSetAllModuleInfoString() { - var info = 'base/one:0/two:0/three:0,1,2/four:0,3/five:'; - var mm = new goog.module.ModuleManager(); - mm.setAllModuleInfoString(info); - - assertNotNull('Base should exist', mm.getModuleInfo('base')); - assertNotNull('One should exist', mm.getModuleInfo('one')); - assertNotNull('Two should exist', mm.getModuleInfo('two')); - assertNotNull('Three should exist', mm.getModuleInfo('three')); - assertNotNull('Four should exist', mm.getModuleInfo('four')); - assertNotNull('Five should exist', mm.getModuleInfo('five')); - - assertArrayEquals(['base', 'one', 'two'], - mm.getModuleInfo('three').getDependencies()); - assertArrayEquals(['base', 'three'], - mm.getModuleInfo('four').getDependencies()); - assertArrayEquals([], - mm.getModuleInfo('five').getDependencies()); - } - - function testSetAllModuleInfoStringWithEmptyString() { - var mm = new goog.module.ModuleManager(); - var called = false; - var context; - mm.registerInitializationCallback(function(mcontext) { - called = true; - context = mcontext; - }); - mm.setAllModuleInfoString(''); - assertTrue('Initialization not called', called); - } - - function testBackOffAmounts() { - var mm = new goog.module.ModuleManager(); - assertEquals(0, mm.getBackOff_()); - - mm.consecutiveFailures_++; - assertEquals(5000, mm.getBackOff_()); - - mm.consecutiveFailures_++; - assertEquals(20000, mm.getBackOff_()); - } -</script> -</body> -</html> |