diff options
| author | Misko Hevery | 2012-01-12 11:06:10 -0800 | 
|---|---|---|
| committer | Misko Hevery | 2012-01-12 13:40:07 -0800 | 
| commit | d648d709f3edcac56132e9e2a84a0fc65f5b48ac (patch) | |
| tree | ac0ba5763838a4f4b880dc72f0cbcedc1b7abc05 | |
| parent | 9a8dbfef5151e8e92dc010a597b670e7687ebe9b (diff) | |
| download | angular.js-d648d709f3edcac56132e9e2a84a0fc65f5b48ac.tar.bz2 | |
refactor(module): strict separation between module-config / app-runtime
34 files changed, 927 insertions, 665 deletions
| diff --git a/docs/content/guide/dev_guide.services.injecting_controllers.ngdoc b/docs/content/guide/dev_guide.services.injecting_controllers.ngdoc index c01b04b1..e98eb5e0 100644 --- a/docs/content/guide/dev_guide.services.injecting_controllers.ngdoc +++ b/docs/content/guide/dev_guide.services.injecting_controllers.ngdoc @@ -31,8 +31,9 @@ myController.$inject = ['$location', '$log'];  <doc:example module="MyServiceModule">  <doc:source>  <script type="text/javascript"> -angular.module.MyServiceModule = ['$provide', function($provide){ -  $provide.factory('notify', ['$window', function(win) { +angular. + module('MyServiceModule', []). + factory('notify', ['$window', function(win) {      var msgs = [];      return function(msg) {        msgs.push(msg); @@ -42,7 +43,6 @@ angular.module.MyServiceModule = ['$provide', function($provide){        }      };    }]); -}];  function myController(notifyService) {    this.callNotify = function(msg) { diff --git a/docs/content/guide/dev_guide.services.managing_dependencies.ngdoc b/docs/content/guide/dev_guide.services.managing_dependencies.ngdoc index 5ca76654..43e5a4ae 100644 --- a/docs/content/guide/dev_guide.services.managing_dependencies.ngdoc +++ b/docs/content/guide/dev_guide.services.managing_dependencies.ngdoc @@ -53,7 +53,7 @@ provided by angular's web framework:    }    // get the main service to kick of the application -  angular.injector(batchLogModule).get('routeTemplateMonitor'); +  angular.injector([batchLogModule]).get('routeTemplateMonitor');  </pre>  Things to notice in this example: diff --git a/docs/content/guide/dev_guide.templates.filters.creating_filters.ngdoc b/docs/content/guide/dev_guide.templates.filters.creating_filters.ngdoc index a8fd2ce7..98b41411 100644 --- a/docs/content/guide/dev_guide.templates.filters.creating_filters.ngdoc +++ b/docs/content/guide/dev_guide.templates.filters.creating_filters.ngdoc @@ -19,8 +19,8 @@ text upper-case and assigns color.  <doc:example module="MyReverseModule">  <doc:source>  <script type="text/javascript"> -  angular.module.MyReverseModule = function ($filterProvider) { -    $filterProvider.register('reverse', function() { +  angular.module('MyReverseModule', []). +    filter('reverse', function() {        return function(input, uppercase) {          var out = "";          for (var i = 0; i < input.length; i++) { @@ -33,7 +33,6 @@ text upper-case and assigns color.          return out;        }      }); -  }    function Ctrl() {      this.greeting = 'hello'; diff --git a/docs/src/templates/doc_widgets.js b/docs/src/templates/doc_widgets.js index c130add8..db49088d 100644 --- a/docs/src/templates/doc_widgets.js +++ b/docs/src/templates/doc_widgets.js @@ -22,8 +22,9 @@      ' </body>\n' +      '</html>'; -  angular.widget('doc:example', ['$injector', '$element', function($injector, element){ -    this.descend(true); //compile the example code +  angular.widget('doc:example', ['$injector', '$browser', '$location', '$element', +                        function($injector,    $browser,   $location,   element){ +    this.descend(false); // do not compile the example code      var module = element.attr('module') || '';      //jQuery find() methods in this widget contain primitive selectors on purpose so that we can use @@ -38,30 +39,26 @@          jsfiddle = example.attr('jsfiddle') || true,          scenario = element.find('pre').eq(1); //doc-scenario -    var tabHtml = -      '<ul class="doc-example">'; +    var tabs = angular.element('<ul class="doc-example">');      // show source tab, if not disabled      if (showSource) { -      tabHtml += +      tabs.append(          '<li class="doc-example-heading"><h3>Source</h3></li>' +          '<li class="doc-example-source" ng:non-bindable>' +          jsFiddleButton(jsfiddle) + // may or may not have value -        '<pre class="brush: js; html-script: true; toolbar: false;"></pre></li>'; +        '<pre class="brush: js; html-script: true; toolbar: false;"></pre></li>');      }      // show live preview tab -    tabHtml += -        '<li class="doc-example-heading"><h3>Live Preview</h3></li>' + -        '<li class="doc-example-live">' + htmlSrc +'</li>'; +    var livePreviewTab; +    tabs.append('<li class="doc-example-heading"><h3>Live Preview</h3></li>'); +    tabs.append(livePreviewTab = angular.element('<li class="doc-example-live">' + htmlSrc +'</li>'));      // show scenario tab, if present      if (scenario.text()) { -      tabHtml += +      tabs.append(          '<li class="doc-example-heading"><h3>Scenario Test</h3></li>' + -        '<li class="doc-example-scenario"><pre class="brush: js">' + scenario.text() + '</pre></li>'; +        '<li class="doc-example-scenario"><pre class="brush: js">' + scenario.text() + '</pre></li>');      } -    tabHtml += -      '</ul>'; -    var tabs = angular.element(tabHtml);      tabs.find('li').eq(1).find('pre').text(        HTML_TEMPLATE. @@ -82,10 +79,23 @@        alert(e);      } -    if (module) { -      $injector.invoke(null, angular.module[module]); -    } +    return function() { +      var scope = this; +      var modules = [ +        'ng', +        function($provide) { +          $provide.value('$browser', $browser); +          $provide.value('$location', $location); +        } +      ]; +      module && modules.push(module); +      angular.bootstrap(livePreviewTab, modules).invoke(function($rootScope) { +        element.bind('$destroy', scope.$root.$watch(function() { +          $rootScope.$digest(); +        })); +      }); +    };      function jsFiddleButton(jsfiddle) {        var fixJsFiddleIssue132 = true; diff --git a/example/personalLog/test/personalLogSpec.js b/example/personalLog/test/personalLogSpec.js index 8c4ab291..9393e047 100644 --- a/example/personalLog/test/personalLogSpec.js +++ b/example/personalLog/test/personalLogSpec.js @@ -2,7 +2,7 @@ describe('example.personalLog.LogCtrl', function() {    var logCtrl;    function createNotesCtrl() { -    var injector = angular.injector('ng', 'ngMock'); +    var injector = angular.injector(['ng', 'ngMock']);      var scope = injector.get('$rootScope');      scope.$cookies = injector.get('$cookies');      return scope.$new(example.personalLog.LogCtrl); diff --git a/src/Angular.js b/src/Angular.js index 74443bd1..0f79d363 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -128,7 +128,7 @@ var $$scope           = '$scope',     </pre>   *   * @param {Object|Array} obj Object to iterate over. - * @param {function()} iterator Iterator function. + * @param {Function} iterator Iterator function.   * @param {Object=} context Object to become context (`this`) for the iterator function.   * @returns {Object|Array} Reference to `obj`.   */ @@ -897,12 +897,14 @@ function angularInit(element, bootstrap) {   *   * @param {Element} element DOM element which is the root of angular application.   * @param {Array<String,function>=} modules an array of module declarations. See: {@link angular.module modules} + * @param {angular.module.auta.$injector} the injector;   */  function bootstrap(element, modules) {    element = jqLite(element);    modules = modules || [];    modules.unshift('ng'); -  createInjector(modules).invoke(null, +  var injector = createInjector(modules); +  injector.invoke(      ['$rootScope', '$compile', '$injector', function(scope, compile, injector){        scope.$apply(function() {          element.data('$injector', injector); @@ -910,6 +912,7 @@ function bootstrap(element, modules) {        });      }]    ); +  return injector;  }  function bindJQuery() { diff --git a/src/AngularPublic.js b/src/AngularPublic.js index ef3d3ccb..4973f574 100644 --- a/src/AngularPublic.js +++ b/src/AngularPublic.js @@ -30,7 +30,7 @@ function publishExternalAPI(angular){      'equals': equals,      'element': jqLite,      'forEach': forEach, -    'injector': function(){ return createInjector(arguments); }, +    'injector': createInjector,      'noop':noop,      'bind':bind,      'toJson': toJson, @@ -58,8 +58,8 @@ function publishExternalAPI(angular){      angularModule('ngLocale', []).service('$locale', $LocaleProvider);    } -  angularModule('ng', ['ngLocale'], ['$provide', '$injector', -    function ngModule($provide, $injector) { +  angularModule('ng', ['ngLocale'], ['$provide', +    function ngModule($provide) {      // TODO(misko): temporary services to get the compiler working;        $provide.value('$textMarkup', angularTextMarkup);        $provide.value('$attrMarkup', angularAttrMarkup); diff --git a/src/Injector.js b/src/Injector.js index 8326d645..c9901513 100644 --- a/src/Injector.js +++ b/src/Injector.js @@ -10,7 +10,7 @@   * dependency injection (see {@link guide/dev_guide.di dependency injection}).   * - * @param {<string, function()>} modules... A list of module functions or their aliases. See + * @param {Array.<string|Function>} modules A list of module functions or their aliases. See   *        {@link angular.module}. The `ng` module must be explicitly added.   * @returns {function()} Injector function. See {@link angular.module.AUTO.$injector $injector}.   * @@ -18,11 +18,11 @@   * Typical usage   * <pre>   *   // create an injector - *   var $injector = angular.injector('ng'); + *   var $injector = angular.injector(['ng']);   *   *   // use the injector to kick of your application   *   // use the type inference to auto inject arguments, or use implicit injection - *   $injector.invoke(null, function($rootScope, $compile, $document){ + *   $injector.invoke(function($rootScope, $compile, $document){   *     $compile($document)($rootScope);   *     $rootScope.$digest();   *   }); @@ -113,14 +113,26 @@ function inferInjectionArgs(fn) {  /**   * @ngdoc method + * @name angular.module.AUTO.$injector#get + * @methodOf angular.module.AUTO.$injector + * + * @description + * Return an instance of the service. + * + * @param {string} name The name of the instance to retrieve. + * @return {*} The instance. + */ + +/** + * @ngdoc method   * @name angular.module.AUTO.$injector#invoke   * @methodOf angular.module.AUTO.$injector   *   * @description   * Invoke the method and supply the method arguments from the `$injector`.   * - * @param {Object} self The `this` for the invoked method. - * @param {function} fn The function to invoke. The function arguments come form the function annotation. + * @param {!function} fn The function to invoke. The function arguments come form the function annotation. + * @param {Object=} self The `this` for the invoked method.   * @param {Object=} locals Optional object. If preset then any argument names are read from this object first, before   *   the `$injector` is consulted.   * @return the value returned by the invoked `fn` function. @@ -238,29 +250,35 @@ function inferInjectionArgs(fn) {  function createInjector(modulesToLoad) { -  var cache = {}, -      providerSuffix = 'Provider', +  var providerSuffix = 'Provider',        path = [], -      $injector, -      loadedModules = new HashMap(); - -  value('$injector', $injector = { -    get: getService, -    invoke: invoke, -    instantiate: instantiate -  }); -  value('$provide', { -    service: supportObject(service), -    factory: supportObject(factory), -    value: supportObject(value), -    decorator: decorator -  }); +      loadedModules = new HashMap(), +      providerCache = { +        $provide: { +            service: supportObject(service), +            factory: supportObject(factory), +            value: supportObject(value), +            decorator: decorator +          } +      }, +      providerInjector = createInternalInjector(providerCache, function() { +        throw Error("Unknown provider: " + path.join(' <- ')); +      }), +      instanceCache = {}, +      instanceInjector = (instanceCache.$injector = +          createInternalInjector(instanceCache, function(servicename) { +            var provider = providerInjector.get(servicename + providerSuffix); +            return instanceInjector.invoke(provider.$get, provider); +          })); +    loadModules(modulesToLoad); -  return $injector; +  return instanceInjector;    //////////////////////////////////// +  // $provider +  ////////////////////////////////////    function supportObject(delegate) {      return function(key, value) { @@ -274,124 +292,146 @@ function createInjector(modulesToLoad) {    function service(name, provider) {      if (isFunction(provider)){ -      provider = instantiate(provider); +      provider = providerInjector.instantiate(provider);      }      if (!provider.$get) {        throw Error('Provider ' + name + ' must define $get factory method.');      } -    cache['#' + name + providerSuffix] = provider; +    providerCache[name + providerSuffix] = provider;    }    function factory(name, factoryFn) { service(name, { $get:factoryFn }); }    function value(name, value) { factory(name, valueFn(value)); } -  function decorator(name, decorFn) { -    var origProvider = cache['#' + name + providerSuffix]; -    if (!origProvider) throw Error("Can't find provider for: " + name); -    if (cache['#' + name]) throw Error("Service " + name + " already instantiated, can't decorate!"); -    var orig$get = origProvider.$get; +  function decorator(serviceName, decorFn) { +    var origProvider = providerInjector.get(serviceName + providerSuffix), +        orig$get = origProvider.$get; +      origProvider.$get = function() { -      var origInstance = $injector.invoke(origProvider, orig$get); -      return $injector.invoke(null, decorFn, {$delegate: origInstance}); +      var origInstance = instanceInjector.invoke(orig$get, origProvider); +      return instanceInjector.invoke(decorFn, null, {$delegate: origInstance});      };    } - -  function getService(value) { -    if (typeof value !== 'string') { -      throw Error('Service name expected'); -    } -    var instanceKey = '#' + value, -        instance = cache[instanceKey]; -    if (instance !== undefined || cache.hasOwnProperty(instanceKey)) { -      return instance; -    } -    try { -      path.unshift(value); -      var providerKey = instanceKey + providerSuffix, -          provider = cache[providerKey]; -      if (provider) { -        return cache[instanceKey] = invoke(provider, provider.$get); +  //////////////////////////////////// +  // Module Loading +  //////////////////////////////////// +  function loadModules(modulesToLoad){ +    forEach(modulesToLoad, function(module) { +      if (loadedModules.get(module)) return; +      loadedModules.put(module, true); +      if (isString(module)) { +        var moduleFn = angularModule(module); +        loadModules(moduleFn.requires); + +        try { +          for(var invokeQueue = moduleFn.invokeQueue, i = 0, ii = invokeQueue.length; i < ii; i++) { +            var invokeArgs = invokeQueue[i], +                provider = invokeArgs[0] == '$injector' +                    ? providerInjector +                    : providerInjector.get(invokeArgs[0]); + +            provider[invokeArgs[1]].apply(provider, invokeArgs[2]); +          } +        } catch (e) { +          if (e.message) e.message += ' from ' + module; +          throw e; +        } +      } else if (isFunction(module)) { +        try { +          providerInjector.invoke(module); +        } catch (e) { +          if (e.message) e.message += ' from ' + module; +          throw e; +        } +      } else if (isArray(module)) { +        try { +          providerInjector.invoke(module); +        } catch (e) { +          if (e.message) e.message += ' from ' + String(module[module.length - 1]); +          throw e; +        }        } else { -        throw Error("Unknown provider for '" + path.join("' <- '") + "'."); +        assertArgFn(module, 'module');        } -    } finally { -      path.shift(); -    } +    });    } -  function invoke(self, fn, locals){ -    var args = [], -        $inject, -        length, -        key; - -    if (typeof fn == 'function') { -      $inject = inferInjectionArgs(fn); -      length = $inject.length; -    } else { -      if (isArray(fn)) { -        $inject = fn; -        length = $inject.length; -        fn = $inject[--length]; -      } -      assertArgFn(fn, 'fn'); -    } +  //////////////////////////////////// +  // internal Injector +  //////////////////////////////////// -    while(length--) { -      key = $inject[length]; -      args.unshift( -        locals && locals.hasOwnProperty(key) -        ? locals[key] -        : getService($inject[length], path) -      ); -    } +  function createInternalInjector(cache, factory) { -    // Performance optimization: http://jsperf.com/apply-vs-call-vs-invoke -    switch (self ? -1 : args.length) { -      case  0: return fn(); -      case  1: return fn(args[0]); -      case  2: return fn(args[0], args[1]); -      case  3: return fn(args[0], args[1], args[2]); -      case  4: return fn(args[0], args[1], args[2], args[3]); -      case  5: return fn(args[0], args[1], args[2], args[3], args[4]); -      case  6: return fn(args[0], args[1], args[2], args[3], args[4], args[5]); -      case  7: return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); -      case  8: return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]); -      case  9: return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]); -      case 10: return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9]); -      default: return fn.apply(self, args); +    function getService(serviceName) { +      if (typeof serviceName !== 'string') { +        throw Error('Service name expected'); +      } +      if (cache.hasOwnProperty(serviceName)) { +        return cache[serviceName]; +      } else { +        try { +          path.unshift(serviceName); +          return cache[serviceName] = factory(serviceName); +        } finally { +          path.shift(); +        } +      }      } -  } -  function instantiate(Type, locals){ -    var Constructor = function(){}, -        instance; -    Constructor.prototype = Type.prototype; -    instance = new Constructor(); -    return invoke(instance, Type, locals) || instance; -  } +    function invoke(fn, self, locals){ +      var args = [], +          $injectAnnotation, +          $injectAnnotationIndex, +          key; -  function loadModules(modulesToLoad){ -    forEach(modulesToLoad, function(module) { -      if (loadedModules.get(module)) return; -      loadedModules.put(module, true); -      if (isString(module)) { -        module = angularModule(module); -        loadModules(module.requires); +      if (typeof fn == 'function') { +        $injectAnnotation = inferInjectionArgs(fn); +        $injectAnnotationIndex = $injectAnnotation.length; +      } else { +        if (isArray(fn)) { +          $injectAnnotation = fn; +          $injectAnnotationIndex = $injectAnnotation.length; +          fn = $injectAnnotation[--$injectAnnotationIndex]; +        } +        assertArgFn(fn, 'fn'); +      } -        for(var invokeQueue = module.invokeQueue, i = 0, ii = invokeQueue.length; i < ii; i++) { -          var invokeArgs = invokeQueue[i], -              service = getService(invokeArgs[0]); +      while($injectAnnotationIndex--) { +        key = $injectAnnotation[$injectAnnotationIndex]; +        args.unshift(locals && locals.hasOwnProperty(key) ? locals[key] : getService(key)); +      } -          service[invokeArgs[1]].apply(service, invokeArgs[2]); -        } -      } else if (isFunction(module) || isArray(module)) { -        invoke(null, module); -      } else { -        assertArgFn(module, 'module'); +      // Performance optimization: http://jsperf.com/apply-vs-call-vs-invoke +      switch (self ? -1 : args.length) { +        case  0: return fn(); +        case  1: return fn(args[0]); +        case  2: return fn(args[0], args[1]); +        case  3: return fn(args[0], args[1], args[2]); +        case  4: return fn(args[0], args[1], args[2], args[3]); +        case  5: return fn(args[0], args[1], args[2], args[3], args[4]); +        case  6: return fn(args[0], args[1], args[2], args[3], args[4], args[5]); +        case  7: return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); +        case  8: return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]); +        case  9: return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]); +        case 10: return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9]); +        default: return fn.apply(self, args);        } -    }); +    } + +    function instantiate(Type, locals){ +      var Constructor = function(){}, +          instance; +      Constructor.prototype = Type.prototype; +      instance = new Constructor(); +      return invoke(Type, instance, locals) || instance; +    } + +    return { +      invoke: invoke, +      instantiate: instantiate, +      get: getService +    };    }  } diff --git a/src/angular-mocks.js b/src/angular-mocks.js index f70731d3..d2dbb114 100644 --- a/src/angular-mocks.js +++ b/src/angular-mocks.js @@ -935,16 +935,56 @@ window.jstestdriver && (function(window) {   * @return a method   */  window.jasmine && (function(window) { -  window.inject = function () { + +  function getCurrentSpec() { +    return jasmine.getEnv().currentSpec; +  } + +  function isSpecRunning() { +    var spec = getCurrentSpec(); +    return spec && spec.queue.running; +  } + +  window.module = function() { +    var moduleFns = Array.prototype.slice.call(arguments, 0); +    var stack = Error('Declaration Location').stack; +    return isSpecRunning() ? workFn() : workFn; +    ///////////////////// +    function workFn() { +      var spec = getCurrentSpec(); +      if (spec.$injector) { +        throw Error('Injector already created, can not register a module!'); +      } else { +        var modules = spec.$modules || (spec.$modules = []); +        angular.forEach(moduleFns, function(module) { +          modules.push(module); +        }); +      } +    } +  }; +  window.inject = function() {      var blockFns = Array.prototype.slice.call(arguments, 0); -    return function() { -      var injector = this.$injector; +    var stack = Error('Declaration Location').stack; +    return isSpecRunning() ? workFn() : workFn; +    ///////////////////// +    function workFn() { +      var spec = getCurrentSpec(); +      var modules = spec.$modules || []; +      modules.unshift('ngMock'); +      modules.unshift('ng'); +      var injector = spec.$injector;        if (!injector) { -        injector = this.$injector = angular.injector('ng', 'ngMock'); +        injector = spec.$injector = angular.injector(modules);        } +      console.log('inject', modules)        for(var i = 0, ii = blockFns.length; i < ii; i++) { -        injector.invoke(this, blockFns[i]); +        try { +          injector.invoke(blockFns[i] || angular.noop, this); +        } catch (e) { +          if(e.stack) e.stack +=  '\n' + stack; +          throw e; +        }        } -    }; +    }    }  })(window); diff --git a/src/loader.js b/src/loader.js index ec30ad9a..3d5edd31 100644 --- a/src/loader.js +++ b/src/loader.js @@ -48,7 +48,7 @@ function setupModuleLoader(window) {       * Then you can load your module like this:       *       * <pre> -     * var injector = angular.injector('ng', 'MyModule') +     * var injector = angular.injector(['ng', 'MyModule'])       * </pre>       *       * @param {!string} name The name of the module to create or retrieve. @@ -67,13 +67,11 @@ function setupModuleLoader(window) {            throw Error('No module: ' + name);          } -        function init(fn) { -          invokeQueue.push(['$injector', 'invoke', [null, fn]]); -        } -          /** @type {!Array.<Array.<*>>} */          var invokeQueue = []; +        var init = invokeLater('$injector', 'invoke'); +          /** @type {angular.Module} */          var moduleInstance = {            /** diff --git a/src/scenario/Application.js b/src/scenario/Application.js index ba6bbea7..d3a70569 100644 --- a/src/scenario/Application.js +++ b/src/scenario/Application.js @@ -93,7 +93,7 @@ angular.scenario.Application.prototype.executeAction = function(action) {    angularInit($window.document, function(element) {      element = $window.angular.element(element);      var $injector = element.inheritedData('$injector'); -    $injector.invoke(null, function($browser){ +    $injector.invoke(function($browser){        $browser.notifyWhenNoOutstandingRequests(function() {          action.call(self, $window, _jQuery($window.document));        }); diff --git a/src/scenario/Runner.js b/src/scenario/Runner.js index aeb5196a..cfde1f64 100644 --- a/src/scenario/Runner.js +++ b/src/scenario/Runner.js @@ -163,7 +163,7 @@ angular.scenario.Runner.prototype.createSpecRunner_ = function(scope) {   */  angular.scenario.Runner.prototype.run = function(application) {    var self = this; -  var $root = angular.injector('ng').get('$rootScope'); +  var $root = angular.injector(['ng']).get('$rootScope');    angular.extend($root, this);    angular.forEach(angular.scenario.Runner.prototype, function(fn, name) {      $root[name] = angular.bind(self, fn); diff --git a/src/scenario/dsl.js b/src/scenario/dsl.js index 12cbdb21..bbe29948 100644 --- a/src/scenario/dsl.js +++ b/src/scenario/dsl.js @@ -103,25 +103,25 @@ angular.scenario.dsl('browser', function() {      api.url = function() {        return this.addFutureAction('$location.url()', function($window, $document, done) { -        done(null, $window.angular.injector('ng').get('$location').url()); +        done(null, $window.angular.injector(['ng']).get('$location').url());        });      };      api.path = function() {        return this.addFutureAction('$location.path()', function($window, $document, done) { -        done(null, $window.angular.injector('ng').get('$location').path()); +        done(null, $window.angular.injector(['ng']).get('$location').path());        });      };      api.search = function() {        return this.addFutureAction('$location.search()', function($window, $document, done) { -        done(null, $window.angular.injector('ng').get('$location').search()); +        done(null, $window.angular.injector(['ng']).get('$location').search());        });      };      api.hash = function() {        return this.addFutureAction('$location.hash()', function($window, $document, done) { -        done(null, $window.angular.injector('ng').get('$location').hash()); +        done(null, $window.angular.injector(['ng']).get('$location').hash());        });      }; diff --git a/src/service/compiler.js b/src/service/compiler.js index 8a0dca7d..727f7983 100644 --- a/src/service/compiler.js +++ b/src/service/compiler.js @@ -28,7 +28,7 @@ function $CompileProvider(){            forEach(this.linkFns, function(fn) {              try {                if (isArray(fn) || fn.$inject) { -                $injector.invoke(childScope, fn, locals); +                $injector.invoke(fn, childScope, locals);                } else {                  fn.call(childScope, element);                } @@ -97,7 +97,7 @@ function $CompileProvider(){         * that is a DOM clone of the original template.         *           <pre> -          angular.injector('ng').invoke(null, function($rootScope, $compile) { +          angular.injector(['ng']).invoke(function($rootScope, $compile) {              // Chose one:              // A: compile the entire window.document. @@ -143,8 +143,8 @@ function $CompileProvider(){         * - If you are not asking the linking function to clone the template, create the DOM element(s)         *   before you send them to the compiler and keep this reference around.         *   <pre> -       *     var $injector = angular.injector('ng'); -       *     var scope = $injector.invoke(null, function($rootScope, $compile){ +       *     var $injector = angular.injector(['ng']); +       *     var scope = $injector.invoke(function($rootScope, $compile){         *       var element = $compile('<p>{{total}}</p>')($rootScope);         *     });         *   </pre> @@ -277,7 +277,7 @@ function $CompileProvider(){              descend = false;              directives = false;              var parent = element.parent(); -            template.addLinkFn($injector.invoke(selfApi, widget, locals)); +            template.addLinkFn($injector.invoke(widget, selfApi, locals));              if (parent && parent[0]) {                element = jqLite(parent[0].childNodes[elementIndex]);              } @@ -310,7 +310,7 @@ function $CompileProvider(){                if (fn) {                  element.addClass('ng-directive');                  template.addLinkFn((isArray(fn) || fn.$inject) -                  ? $injector.invoke(selfApi, fn, {$value:value, $element: element}) +                  ? $injector.invoke(fn, selfApi, {$value:value, $element: element})                    : fn.call(selfApi, value, element));                }              }); diff --git a/src/service/scope.js b/src/service/scope.js index 2836b42e..a19bf83e 100644 --- a/src/service/scope.js +++ b/src/service/scope.js @@ -50,7 +50,7 @@ function $RootScopeProvider(){       *       * Here is a simple scope snippet to show how you can interact with the scope.       * <pre> -        angular.injector(function($rootScope) { +        angular.injector(['ng']).invoke(function($rootScope) {             var scope = $rootScope.$new();             scope.salutation = 'Hello';             scope.name = 'World'; @@ -168,7 +168,7 @@ function $RootScopeProvider(){            for(var key in ClassPrototype) {              child[key] = bind(child, ClassPrototype[key]);            } -          $injector.invoke(child, Class, curryArguments); +          $injector.invoke(Class, child, curryArguments);          }          return child;        }, diff --git a/test/AngularSpec.js b/test/AngularSpec.js index 55842acd..0ff0508f 100644 --- a/test/AngularSpec.js +++ b/test/AngularSpec.js @@ -346,18 +346,21 @@ describe('angular', function() {    describe('angular service', function() { -    it('should override services', inject(function($provide){ -      $provide.value('fake', 'old'); -      $provide.value('fake', 'new'); -    }, function(fake) { -      expect(fake).toEqual('new'); -    })); +    it('should override services', function() { +      module(function($provide){ +        $provide.value('fake', 'old'); +        $provide.value('fake', 'new'); +      }); +      inject(function(fake) { +        expect(fake).toEqual('new'); +      }); +    });      it('should inject dependencies specified by $inject and ignore function argument name', function() { -      expect(angular.injector(function($provide){ +      expect(angular.injector([function($provide){          $provide.factory('svc1', function() { return 'svc1'; });          $provide.factory('svc2', ['svc1', function(s) { return 'svc2-' + s; }]); -      }).get('svc2')).toEqual('svc2-svc1'); +      }]).get('svc2')).toEqual('svc2-svc1');      });    }); @@ -492,8 +495,7 @@ describe('angular', function() {    describe('bootstrap', function() {      it('should bootstrap app', function(){        var element = jqLite('<div>{{1+2}}</div>'); -      var injector; -      angular.bootstrap(element, [function($injector){ injector = $injector; }]); +      var injector = angular.bootstrap(element);        expect(injector).toBeDefined();        expect(element.data('$injector')).toBe(injector);        dealoc(element); diff --git a/test/BinderSpec.js b/test/BinderSpec.js index efe7215b..a94e5eb2 100644 --- a/test/BinderSpec.js +++ b/test/BinderSpec.js @@ -13,7 +13,7 @@ describe('Binder', function() {          content = jqLite(content);          $compile(content)($rootScope);          html = sortedHtml(content); -      }).call(this); +      });        return html;      };    }); @@ -229,11 +229,11 @@ describe('Binder', function() {      expect(element[0].childNodes.length - 1).toEqual(0);    })); -  it('IfTextBindingThrowsErrorDecorateTheSpan', inject( -    function($exceptionHandlerProvider){ +  it('IfTextBindingThrowsErrorDecorateTheSpan', function() { +    module(function($exceptionHandlerProvider){        $exceptionHandlerProvider.mode('log'); -    }, -    function($rootScope, $exceptionHandler, $compile) { +    }); +    inject(function($rootScope, $exceptionHandler, $compile) {        $compile('<div>{{error.throw()}}</div>', null, true)($rootScope);        var errorLogs = $exceptionHandler.errors; @@ -250,28 +250,31 @@ describe('Binder', function() {        $rootScope.error['throw'] = function() {return 'ok';};        $rootScope.$apply();        expect(errorLogs.length).toBe(0); -    }) -  ); +    }); +  }); -  it('IfAttrBindingThrowsErrorDecorateTheAttribute', inject(function($exceptionHandlerProvider){ -    $exceptionHandlerProvider.mode('log'); -  }, function($rootScope, $exceptionHandler, $compile) { -    $compile('<div attr="before {{error.throw()}} after"></div>', null, true)($rootScope); -    var errorLogs = $exceptionHandler.errors; -    var count = 0; +  it('IfAttrBindingThrowsErrorDecorateTheAttribute', function() { +    module(function($exceptionHandlerProvider){ +      $exceptionHandlerProvider.mode('log'); +    }); +    inject(function($rootScope, $exceptionHandler, $compile) { +      $compile('<div attr="before {{error.throw()}} after"></div>', null, true)($rootScope); +      var errorLogs = $exceptionHandler.errors; +      var count = 0; -    $rootScope.error = { +      $rootScope.error = {          'throw': function() {throw new Error('ErrorMsg' + (++count));} -    }; -    $rootScope.$apply(); -    expect(errorLogs.length).not.toEqual(0); -    expect(errorLogs.shift()).toMatch(/ErrorMsg1/); -    errorLogs.length = 0; +      }; +      $rootScope.$apply(); +      expect(errorLogs.length).not.toEqual(0); +      expect(errorLogs.shift()).toMatch(/ErrorMsg1/); +      errorLogs.length = 0; -    $rootScope.error['throw'] =  function() { return 'X';}; -    $rootScope.$apply(); -    expect(errorLogs.length).toMatch(0); -  })); +      $rootScope.error['throw'] =  function() { return 'X';}; +      $rootScope.$apply(); +      expect(errorLogs.length).toMatch(0); +    }); +  });    it('NestedRepeater', inject(function($rootScope, $compile) {      var element = $compile( @@ -395,19 +398,19 @@ describe('Binder', function() {      $rootScope.$apply();    })); -  it('ActionOnAHrefThrowsError', inject( -    function($exceptionHandlerProvider){ +  it('ActionOnAHrefThrowsError', function() { +    module(function($exceptionHandlerProvider){        $exceptionHandlerProvider.mode('log'); -    }, -    function($rootScope, $exceptionHandler, $compile) { +    }); +    inject(function($rootScope, $exceptionHandler, $compile) {        var input = $compile('<a ng:click="action()">Add Phone</a>')($rootScope);        $rootScope.action = function() {          throw new Error('MyError');        };        browserTrigger(input, 'click');        expect($exceptionHandler.errors[0]).toMatch(/MyError/); -    }) -  ); +    }); +  });    it('ShoulIgnoreVbNonBindable', inject(function($rootScope, $compile) {      var element = $compile( @@ -477,11 +480,11 @@ describe('Binder', function() {      assertChild(5, false);    })); -  it('ItShouldDisplayErrorWhenActionIsSyntacticlyIncorrect', inject( -    function($exceptionHandlerProvider){ +  it('ItShouldDisplayErrorWhenActionIsSyntacticlyIncorrect', function() { +    module(function($exceptionHandlerProvider){        $exceptionHandlerProvider.mode('log'); -    }, -    function($rootScope, $exceptionHandler, $log, $compile) { +    }); +    inject(function($rootScope, $exceptionHandler, $log, $compile) {        var element = $compile(          '<div>' +            '<input type="button" ng:click="greeting=\'ABC\'"/>' + @@ -498,8 +501,8 @@ describe('Binder', function() {        browserTrigger(second, 'click');        expect($exceptionHandler.errors[0]).          toMatchError(/Syntax Error: Token ':' not a primary expression/); -    }) -  ); +    }); +  });    it('ItShouldSelectTheCorrectRadioBox', inject(function($rootScope, $compile) {      var element = $compile( diff --git a/test/InjectorSpec.js b/test/InjectorSpec.js index 3eec169a..4817dc32 100644 --- a/test/InjectorSpec.js +++ b/test/InjectorSpec.js @@ -4,10 +4,12 @@ describe('injector', function() {    var providers;    var injector; -  beforeEach(inject(function($injector, $provide) { +  beforeEach(module(function($provide) {      providers = function(name, factory, annotations) {        $provide.factory(name, extend(factory, annotations||{}));      }; +  })); +  beforeEach(inject(function($injector){      injector = $injector;    })); @@ -57,7 +59,7 @@ describe('injector', function() {    it('should provide useful message if no provider', function() {      expect(function() {        injector.get('idontexist'); -    }).toThrow("Unknown provider for 'idontexist'."); +    }).toThrow("Unknown provider: idontexistProvider <- idontexist");    }); @@ -66,7 +68,7 @@ describe('injector', function() {      providers('b', function(a) {return 2;});      expect(function() {        injector.get('b'); -    }).toThrow("Unknown provider for 'idontexist' <- 'a' <- 'b'."); +    }).toThrow("Unknown provider: idontexistProvider <- idontexist <- a <- b");    }); @@ -88,13 +90,13 @@ describe('injector', function() {      it('should call function', function() {        fn.$inject = ['a', 'b', 'c', 'd']; -      injector.invoke({name:"this"}, fn,  {c:3, d:4}); +      injector.invoke(fn, {name:"this"},  {c:3, d:4});        expect(args).toEqual([{name:'this'}, 1, 2, 3, 4]);      });      it('should treat array as annotations', function() { -      injector.invoke({name:"this"}, ['a', 'b', 'c', 'd', fn], {c:3, d:4}); +      injector.invoke(['a', 'b', 'c', 'd', fn], {name:"this"}, {c:3, d:4});        expect(args).toEqual([{name:'this'}, 1, 2, 3, 4]);      }); @@ -102,16 +104,16 @@ describe('injector', function() {      it('should invoke the passed-in fn with all of the dependencies as arguments', function() {        providers('c', function() {return 3;});        providers('d', function() {return 4;}); -      expect(injector.invoke(null, ['a', 'b', 'c', 'd', fn])).toEqual(10); +      expect(injector.invoke(['a', 'b', 'c', 'd', fn])).toEqual(10);      });      it('should fail with errors if not function or array', function() {        expect(function() { -        injector.invoke({}, {}); +        injector.invoke({});        }).toThrow("Argument 'fn' is not a function, got Object");        expect(function() { -        injector.invoke({}, ['a', 123]); +        injector.invoke(['a', 123], {});        }).toThrow("Argument 'fn' is not a function, got number");      });    }); @@ -183,7 +185,7 @@ describe('injector', function() {        });      }, function(valueProvider, fnProvider, serviceProvider) {        log += valueProvider.$get() + fnProvider.$get() + serviceProvider.$get(); -    }]).invoke(null, function(value, fn, service) { +    }]).invoke(function(value, fn, service) {        log += '->' + value + fn + service;      });      expect(log).toEqual('value;function;service;->value;function;service;'); @@ -191,13 +193,12 @@ describe('injector', function() {    describe('module', function() { -    it('should provide $injector and $provide even when no module is requested', function() { +    it('should provide $injector even when no module is requested', function() {        var $provide,            $injector = createInjector([              angular.extend(function(p) { $provide = p; }, {$inject: ['$provide']})            ]);        expect($injector.get('$injector')).toBe($injector); -      expect($injector.get('$provide')).toBe($provide);      }); @@ -425,28 +426,6 @@ describe('injector', function() {            expect(log.join('; ')).              toBe('myDecoratedService:input,dependency1; myService:decInput; dec+origReturn');          }); - - -        it('should complain if the service to be decorated was already instantiated', function() { -          injector = createInjector([function($provide, $injector) { -            $provide.value('myService', function(val) { -              log.push('myService:' + val); -              return 'origReturn'; -            }); - -            $injector.get('myService'); - -            expect(function() { -              $provide.decorator('myService', function($delegate) { -                return function(val) { -                  log.push('myDecoratedService:' + val); -                  var origVal = $delegate('decInput'); -                  return 'dec+' + origVal; -                }; -              }); -            }).toThrow("Service myService already instantiated, can't decorate!"); -          }]); -        });        });      }); @@ -470,11 +449,27 @@ describe('injector', function() {        }); -      it('should handle no module alias', function() { +      it('should decorate the missing service error with module name', function() { +        angular.module('TestModule', [], function($injector) {});          expect(function() { -          createInjector([function(dontExist) { -          }], {}); -        }).toThrow("Unknown provider for 'dontExist'."); +          createInjector(['TestModule']); +        }).toThrow('Unknown provider: $injector from TestModule'); +      }); + + +      it('should decorate the missing service error with module function', function() { +        function myModule($injector){} +        expect(function() { +          createInjector([myModule]); +        }).toThrow('Unknown provider: $injector from ' + myModule); +      }); + + +      it('should decorate the missing service error with module array function', function() { +        function myModule($injector){} +        expect(function() { +          createInjector([['$injector', myModule]]); +        }).toThrow('Unknown provider: $injector from ' + myModule);        });      });    }); @@ -500,8 +495,8 @@ describe('injector', function() {      it('should call functions and infer arguments', function() { -      expect($injector.invoke(null, function(instance) { return instance; })).toBe(instance); -      expect($injector.invoke(null, function(instance) { return instance; })).toBe(instance); +      expect($injector.invoke(function(instance) { return instance; })).toBe(instance); +      expect($injector.invoke(function(instance) { return instance; })).toBe(instance);      });    }); @@ -518,52 +513,52 @@ describe('injector', function() {      it('should invoke method', function() { -      expect($injector.invoke(null, function(book, author) { +      expect($injector.invoke(function(book, author) {          return author + ':' + book;        })).toEqual('melville:moby'); -      expect($injector.invoke($injector, function(book, author) { +      expect($injector.invoke(function(book, author) {          expect(this).toEqual($injector); -        return author + ':' + book;})).toEqual('melville:moby'); +        return author + ':' + book;}, $injector)).toEqual('melville:moby');      });      it('should invoke method with locals', function() { -      expect($injector.invoke(null, function(book, author) { +      expect($injector.invoke(function(book, author) {          return author + ':' + book;        })).toEqual('melville:moby'); -      expect($injector.invoke($injector, +      expect($injector.invoke(          function(book, author, chapter) {            expect(this).toEqual($injector);            return author + ':' + book + '-' + chapter; -        }, {author:'m', chapter:'ch1'})).toEqual('m:moby-ch1'); +        }, $injector, {author:'m', chapter:'ch1'})).toEqual('m:moby-ch1');      });      it('should invoke method which is annotated', function() { -      expect($injector.invoke(null, extend(function(b, a) { +      expect($injector.invoke(extend(function(b, a) {          return a + ':' + b        }, {$inject:['book', 'author']}))).toEqual('melville:moby'); -      expect($injector.invoke($injector, extend(function(b, a) { +      expect($injector.invoke(extend(function(b, a) {          expect(this).toEqual($injector);          return a + ':' + b; -      }, {$inject:['book', 'author']}))).toEqual('melville:moby'); +      }, {$inject:['book', 'author']}), $injector)).toEqual('melville:moby');      });      it('should invoke method which is an array of annotation', function() { -      expect($injector.invoke(null, function(book, author) { +      expect($injector.invoke(function(book, author) {          return author + ':' + book;        })).toEqual('melville:moby'); -      expect($injector.invoke($injector, function(book, author) { +      expect($injector.invoke(function(book, author) {          expect(this).toEqual($injector);          return author + ':' + book; -      })).toEqual('melville:moby'); +      }, $injector)).toEqual('melville:moby');      });      it('should throw usefull error on wrong argument type]', function() {        expect(function() { -        $injector.invoke(null, {}); +        $injector.invoke({});        }).toThrow("Argument 'fn' is not a function, got Object");      });    }); @@ -610,4 +605,33 @@ describe('injector', function() {        }).toThrow('MyError');      });    }); + +  describe('protection modes', function() { +    it('should prevent provider lookup in app', function() { +      var  $injector = createInjector([function($provide) { +        $provide.value('name', 'angular'); +      }]); +      expect(function() { +        $injector.get('nameProvider'); +      }).toThrow("Unknown provider: nameProviderProvider <- nameProvider"); +    }); + + +    it('should prevent provider configuration in app', function() { +      var  $injector = createInjector([]); +      expect(function() { +        $injector.get('$provide').value('a', 'b'); +      }).toThrow("Unknown provider: $provideProvider <- $provide"); +    }); + + +    it('should prevent instance lookup in module', function() { +      function instanceLookupInModule(name) { throw Error('FAIL'); } +      expect(function() { +        createInjector([function($provide) { +          $provide.value('name', 'angular') +        }, instanceLookupInModule]); +      }).toThrow('Unknown provider: name from ' + String(instanceLookupInModule)); +    }); +  });  }); diff --git a/test/angular-mocksSpec.js b/test/angular-mocksSpec.js index fbdd3b91..153c2e33 100644 --- a/test/angular-mocksSpec.js +++ b/test/angular-mocksSpec.js @@ -302,7 +302,7 @@ describe('ngMock', function() {      })); -    it('should log exceptions', inject(function($exceptionHandlerProvider){ +    it('should log exceptions', module(function($exceptionHandlerProvider){        $exceptionHandlerProvider.mode('log');        var $exceptionHandler = $exceptionHandlerProvider.$get();        $exceptionHandler('MyError'); @@ -310,7 +310,7 @@ describe('ngMock', function() {      })); -    it('should thorw on wrong argument', inject(function($exceptionHandlerProvider) { +    it('should throw on wrong argument', module(function($exceptionHandlerProvider) {        expect(function() {          $exceptionHandlerProvider.mode('XXX');        }).toThrow("Unknown mode 'XXX', only 'log'/'rethrow' modes are allowed!"); @@ -348,32 +348,83 @@ describe('ngMock', function() {      });    }); -  describe('jasmine inject', function(){ -    it('should call invoke', function(){ -      var count = 0; -      function fn1(){ -        expect(this).toBe(self); -        count++; -      } -      function fn2(){ -        expect(this).toBe(self); -        count++; -      } -      var fn = inject(fn1, fn2); -      var self = { -        $injector: { -          invoke: function(self, fn) { fn.call(self); } -        } -      }; +  describe('jasmine module and inject', function(){ +    var log; + +    beforeEach(function(){ +      log = ''; +    }); + +    describe('module', function() { +      describe('in DSL', function() { +        it('should load module', module(function() { +          log += 'module'; +        })); + +        afterEach(function() { +          inject(); +          expect(log).toEqual('module'); +        }); +      }); + + +      describe('inline in test', function() { +        it('should load module', function() { +          module(function() { +            log += 'module'; +          }); +          inject(); +        }); + +        afterEach(function() { +          expect(log).toEqual('module'); +        }); +      }); +    }); + +    describe('inject', function() { +      describe('in DSL', function() { +        it('should load module', inject(function() { +          log += 'inject'; +        })); -      fn.call(self); -      expect(count).toBe(2); +        afterEach(function() { +          expect(log).toEqual('inject'); +        }); +      }); + + +      describe('inline in test', function() { +        it('should load module', function() { +          inject(function() { +            log += 'inject'; +          }); +        }); + +        afterEach(function() { +          expect(log).toEqual('inject'); +        }); +      }); + +      describe('module with inject', function() { +        beforeEach(module(function(){ +          log += 'module;'; +        })); + +        it('should inject', inject(function() { +          log += 'inject;'; +        })); + +        afterEach(function() { +          expect(log).toEqual('module;inject;') +        }); +      });      });    });    describe('$httpBackend', function() { -    var hb, callback; +    var hb, callback, realBackendSpy;      beforeEach(inject(function($httpBackend) {        callback = jasmine.createSpy('callback'); @@ -832,13 +883,17 @@ describe('ngMockE2E', function() {    describe('$httpBackend', function() {      var hb, realHttpBackend, callback; -    beforeEach(inject(function($provide, $injector) { -      callback = jasmine.createSpy('callback'); -      realHttpBackend = jasmine.createSpy('real $httpBackend'); -      $provide.value('$httpBackend', realHttpBackend); -      $provide.decorator('$httpBackend', angular.mock.e2e.$httpBackendDecorator); -      hb = $injector.get('$httpBackend'); -    })); +    beforeEach(function() { +      module(function($provide) { +        callback = jasmine.createSpy('callback'); +        realHttpBackend = jasmine.createSpy('real $httpBackend'); +        $provide.value('$httpBackend', realHttpBackend); +        $provide.decorator('$httpBackend', angular.mock.e2e.$httpBackendDecorator); +      }); +      inject(function($injector) { +        hb = $injector.get('$httpBackend'); +      }); +    });      describe('passThrough()', function() { diff --git a/test/directivesSpec.js b/test/directivesSpec.js index ffb6d57c..1825dc49 100644 --- a/test/directivesSpec.js +++ b/test/directivesSpec.js @@ -2,6 +2,12 @@  describe("directive", function() { +  var $filterProvider; + +  beforeEach(module(['$filterProvider', function(provider){ +    $filterProvider = provider; +  }])); +    it("should ng:init", inject(function($rootScope, $compile) {      var element = $compile('<div ng:init="a=123"></div>')($rootScope);      expect($rootScope.a).toEqual(123); @@ -41,7 +47,7 @@ describe("directive", function() {        expect(lowercase(element.html())).toEqual('<div onclick="">hello</div>');      })); -    it('should set element element', inject(function($rootScope, $compile, $filterProvider) { +    it('should set element element', inject(function($rootScope, $compile) {        $filterProvider.register('myElement', valueFn(function() {          return jqLite('<a>hello</a>');        })); @@ -73,7 +79,7 @@ describe("directive", function() {        expect(element.text()).toEqual('Hello Misko!');      })); -    it('should have $element set to current bind element', inject(function($rootScope, $compile, $filterProvider) { +    it('should have $element set to current bind element', inject(function($rootScope, $compile) {        var innerText;        $filterProvider.register('myFilter', valueFn(function(text) {          innerText = innerText || this.$element.text(); @@ -415,7 +421,7 @@ describe("directive", function() {          scope.$apply();          expect(element.css(preCompStyle)).not.toBe('88px');          expect(element.css(postCompStyle)).not.toBe('99px'); -      });  +      });      });    }); diff --git a/test/loaderSpec.js b/test/loaderSpec.js index afea159b..e419a198 100644 --- a/test/loaderSpec.js +++ b/test/loaderSpec.js @@ -40,12 +40,12 @@ describe('module loader', function() {      expect(myModule.requires).toEqual(['other']);      expect(myModule.invokeQueue).toEqual([ -      ['$injector', 'invoke', [null, 'init'] ], +      ['$injector', 'invoke', ['init'] ],        ['$provide', 'service', ['sk', 'sv'] ],        ['$provide', 'factory', ['fk', 'fv'] ],        ['$provide', 'value', ['k', 'v'] ],        ['$filterProvider', 'register', ['f', 'ff'] ], -      ['$injector', 'invoke', [null, 'init2'] ] +      ['$injector', 'invoke', ['init2'] ]      ]);    }); diff --git a/test/markupSpec.js b/test/markupSpec.js index 7c7f64f8..e2e11f7f 100644 --- a/test/markupSpec.js +++ b/test/markupSpec.js @@ -150,7 +150,7 @@ describe("markups", function() {    it('should bind Text with no Bindings', inject(function($compile) {      var $rootScope;      function newScope (){ -      return $rootScope = angular.injector('ng').get('$rootScope'); +      return $rootScope = angular.injector(['ng']).get('$rootScope');      }      forEach(['checked', 'disabled', 'multiple', 'readonly', 'selected'], function(name) {        var element = $compile('<div ng:' + name + '="some"></div>')(newScope()) diff --git a/test/service/autoScrollSpec.js b/test/service/autoScrollSpec.js index 8d04268b..86a47f50 100644 --- a/test/service/autoScrollSpec.js +++ b/test/service/autoScrollSpec.js @@ -53,7 +53,7 @@ describe('$autoScroll', function() {    } -  beforeEach(inject(function($provide) { +  beforeEach(module(function($provide) {      elmSpy = {};      $provide.value('$window', {        scrollTo: jasmine.createSpy('$window.scrollTo'), @@ -108,11 +108,14 @@ describe('$autoScroll', function() {      expectScrollingTo('id=top'))); -  it('should not scroll when disabled', inject( -    addElements('id=fake', 'a name=fake', 'input name=fake'), -    disableScroller(), -    changeHashAndScroll('fake'), -    expectNoScrolling())); +  it('should not scroll when disabled', function() { +    module(disableScroller()); +    inject( +      addElements('id=fake', 'a name=fake', 'input name=fake'), +      changeHashAndScroll('fake'), +      expectNoScrolling() +    ); +  });    describe('watcher', function() { @@ -136,40 +139,57 @@ describe('$autoScroll', function() {      })); -    it('should scroll to element when hash change in hashbang mode', inject( -      initLocation({html5Mode: false, historyApi: true}), -      addElements('id=some'), -      changeHashAndDigest('some'), -      expectScrollingTo('id=some'))); +    it('should scroll to element when hash change in hashbang mode', function() { +      module(initLocation({html5Mode: false, historyApi: true})); +      inject( +        addElements('id=some'), +        changeHashAndDigest('some'), +        expectScrollingTo('id=some') +      ); +    }); -    it('should scroll to element when hash change in html5 mode with no history api', inject( -      initLocation({html5Mode: true, historyApi: false}), -      addElements('id=some'), -      changeHashAndDigest('some'), -      expectScrollingTo('id=some'))); +    it('should scroll to element when hash change in html5 mode with no history api', function() { +      module(initLocation({html5Mode: true, historyApi: false})); +      inject( +        addElements('id=some'), +        changeHashAndDigest('some'), +        expectScrollingTo('id=some') +      ); +    }); -    it('should not scroll when element does not exist', inject( -      initLocation({html5Mode: false, historyApi: false}), -      addElements('id=some'), -      changeHashAndDigest('other'), -      expectNoScrolling())); +    it('should not scroll when element does not exist', function() { +      module(initLocation({html5Mode: false, historyApi: false})); +      inject( +        addElements('id=some'), +        changeHashAndDigest('other'), +        expectNoScrolling() +      ); +    }); -    it('should not scroll when html5 mode with history api', inject( -      initLocation({html5Mode: true, historyApi: true}), -      addElements('id=some'), -      changeHashAndDigest('some'), -      expectNoScrolling())); +    it('should not scroll when html5 mode with history api', function() { +      module(initLocation({html5Mode: true, historyApi: true})); +      inject( +        addElements('id=some'), +        changeHashAndDigest('some'), +        expectNoScrolling() +      ); +    }); -    it('should not scroll when disabled', inject( -      disableScroller(), -      initLocation({html5Mode: false, historyApi: false}), -      addElements('id=fake'), -      changeHashAndDigest('fake'), -      expectNoScrolling())); +    it('should not scroll when disabled', function() { +      module( +          disableScroller(), +          initLocation({html5Mode: false, historyApi: false}) +      ); +      inject( +        addElements('id=fake'), +        changeHashAndDigest('fake'), +        expectNoScrolling() +      ); +    });    });  }); diff --git a/test/service/compilerSpec.js b/test/service/compilerSpec.js index ccf70aaf..6e6c211b 100644 --- a/test/service/compilerSpec.js +++ b/test/service/compilerSpec.js @@ -1,10 +1,10 @@  'use strict';  describe('compiler', function() { -  var compiler, textMmarkup, attrMarkup, directives, widgets, compile, log, $rootScope; +  var textMarkup, attrMarkup, directives, widgets, compile, log; -  beforeEach(inject(function($provide){ -    textMmarkup = []; +  beforeEach(module(function($provide){ +    textMarkup = [];      attrMarkup = [];      widgets = extensionMap({}, 'widget');      directives = { @@ -26,7 +26,7 @@ describe('compiler', function() {      };      log = ""; -    $provide.value('$textMarkup', textMmarkup); +    $provide.value('$textMarkup', textMarkup);      $provide.value('$attrMarkup', attrMarkup);      $provide.value('$directive', directives);      $provide.value('$widget', widgets); @@ -138,7 +138,7 @@ describe('compiler', function() {    it('should process markup before directives', inject(function($rootScope, $compile) { -    textMmarkup.push(function(text, textNode, parentNode) { +    textMarkup.push(function(text, textNode, parentNode) {        if (text == 'middle') {          expect(textNode.text()).toEqual(text);          parentNode.attr('hello', text); @@ -176,7 +176,7 @@ describe('compiler', function() {        this.directives(true);        return noop;      }; -    textMmarkup.push(function(text, textNode, parent){ +    textMarkup.push(function(text, textNode, parent){        if (text == '{{1+2}}')          parent.text('3');      }); @@ -186,7 +186,7 @@ describe('compiler', function() {    it('should allow multiple markups per text element', inject(function($rootScope, $compile) { -    textMmarkup.push(function(text, textNode, parent){ +    textMarkup.push(function(text, textNode, parent){        var index = text.indexOf('---');        if (index > -1) {          textNode.after(text.substring(index + 3)); @@ -195,7 +195,7 @@ describe('compiler', function() {          textNode.remove();        }      }); -    textMmarkup.push(function(text, textNode, parent){ +    textMarkup.push(function(text, textNode, parent){        var index = text.indexOf('===');        if (index > -1) {          textNode.after(text.substring(index + 3)); diff --git a/test/service/cookiesSpec.js b/test/service/cookiesSpec.js index d73923a6..5427ac36 100644 --- a/test/service/cookiesSpec.js +++ b/test/service/cookiesSpec.js @@ -1,13 +1,13 @@  'use strict';  describe('$cookies', function() { -  beforeEach(inject(function($provide) { +  beforeEach(module(function($provide) {      $provide.factory('$browser', function(){        return angular.extend(new angular.mock.$Browser(), {cookieHash: {preexisting:'oldCookie'}});      });    })); -   +    it('should provide access to existing cookies via object properties and keep them in sync',        inject(function($cookies, $browser, $rootScope) {      expect($cookies).toEqual({'preexisting': 'oldCookie'}); diff --git a/test/service/deferSpec.js b/test/service/deferSpec.js index e4554601..48c9e912 100644 --- a/test/service/deferSpec.js +++ b/test/service/deferSpec.js @@ -1,7 +1,7 @@  'use strict';  describe('$defer', function() { -  beforeEach(inject(function($provide) { +  beforeEach(module(function($provide) {      $provide.factory('$exceptionHandler', function(){        return jasmine.createSpy('$exceptionHandler');      }); diff --git a/test/service/exceptionHandlerSpec.js b/test/service/exceptionHandlerSpec.js index 00abff30..2f3d0e66 100644 --- a/test/service/exceptionHandlerSpec.js +++ b/test/service/exceptionHandlerSpec.js @@ -3,13 +3,13 @@  describe('$exceptionHandler', function() { -  it('should log errors', inject( -    function($provide){ +  it('should log errors', function() { +    module(function($provide){        $provide.service('$exceptionHandler', $ExceptionHandlerProvider); -    }, -    function($log, $exceptionHandler) { +    }); +    inject(function($log, $exceptionHandler) {        $exceptionHandler('myError');        expect($log.error.logs.shift()).toEqual(['myError']); -    } -  )); +    }); +  });  }); diff --git a/test/service/filter/filtersSpec.js b/test/service/filter/filtersSpec.js index 40a78558..cc006447 100644 --- a/test/service/filter/filtersSpec.js +++ b/test/service/filter/filtersSpec.js @@ -8,13 +8,15 @@ describe('filters', function() {      filter = $filter;    })); -  it('should called the filter when evaluating expression', inject(function($rootScope, $filterProvider) { +  it('should call the filter when evaluating expression', function(){      var filter = jasmine.createSpy('myFilter'); -    $filterProvider.register('myFilter', valueFn(filter)); - -    $rootScope.$eval('10|myFilter'); +    createInjector(['ng', function($filterProvider) { +      $filterProvider.register('myFilter', valueFn(filter)); +    }]).invoke(function($rootScope) { +      $rootScope.$eval('10|myFilter'); +    });      expect(filter).toHaveBeenCalledWith(10); -  })); +  });    describe('formatNumber', function() {      var pattern; diff --git a/test/service/httpSpec.js b/test/service/httpSpec.js index 5efe2954..c6adee9e 100644 --- a/test/service/httpSpec.js +++ b/test/service/httpSpec.js @@ -1,20 +1,15 @@  'use strict';  describe('$http', function() { -  var $rootScope, callback; -  beforeEach(inject( -    function($exceptionHandlerProvider) { -      $exceptionHandlerProvider.mode('log'); -    }, -    ['$rootScope', function($rs) { -      $rootScope = $rs; - -      spyOn($rootScope, '$apply').andCallThrough(); -      callback = jasmine.createSpy('done'); -    }] -  )); +  var callback; +  beforeEach(function() { +    callback = jasmine.createSpy('done'); +  }); +  beforeEach(module(function($exceptionHandlerProvider) { +      $exceptionHandlerProvider.mode('log'); +  }));    afterEach(inject(function($exceptionHandler, $httpBackend) {      forEach($exceptionHandler.errors, function(e) { @@ -33,73 +28,87 @@ describe('$http', function() {      describe('interceptors', function() { -      it('should default to an empty array', inject(function($httpProvider) { +      it('should default to an empty array', module(function($httpProvider) {          expect($httpProvider.responseInterceptors).toEqual([]);        })); -      it('should pass the responses through interceptors', inject(function($httpProvider, $q) { -        // just change the response data and pass the response object along -        $httpProvider.responseInterceptors.push(function(httpPromise) { -          return httpPromise.then(function(response) { -            response.data += '!'; -            return response; +      it('should pass the responses through interceptors', function() { +        var shared = {}; +        module(function($httpProvider, $provide) { +          $provide.factory('testInterceptor', function ($q) { +            return function(httpPromise) { +              return httpPromise.then(function(response) { +                var deferred = $q.defer(); +                deferred.resolve({ +                  data: response.data + '?', +                  status: 209, +                  headers: response.headers, +                  config: response.config +                }); +                return deferred.promise; +              }); +            };            }); -        }); - -        // return a new resolved promise representing modified response object -        $httpProvider.responseInterceptors.push(function(httpPromise) { -          return httpPromise.then(function(response) { -            var deferred = $q.defer(); -            deferred.resolve({ -              data: response.data + '?', -              status: 209, -              headers: response.headers, -              config: response.config +          // just change the response data and pass the response object along +          $httpProvider.responseInterceptors.push(function(httpPromise) { +            return httpPromise.then(function(response) { +              response.data += '!'; +              return response;              }); -            return deferred.promise;            }); + +          // return a new resolved promise representing modified response object +          $httpProvider.responseInterceptors.push('testInterceptor');          }); -      }, function($http, $httpBackend) { -        $httpBackend.expect('GET', '/foo').respond(201, 'Hello'); -        $http.get('/foo').success(function(data, status) { -          expect(data).toBe('Hello!?'); -          expect(status).toBe(209); -          callback(); +        inject(function($http, $httpBackend) { +          $httpBackend.expect('GET', '/foo').respond(201, 'Hello'); +          $http.get('/foo').success(function(data, status) { +            expect(data).toBe('Hello!?'); +            expect(status).toBe(209); +            callback(); +          }); +          $httpBackend.flush(); +          expect(callback).toHaveBeenCalledOnce();          }); -        $httpBackend.flush(); -        expect(callback).toHaveBeenCalledOnce(); -      })); +      }); -      it('should support interceptors defined as services', inject( -          function($provide, $httpProvider) { -            $provide.factory('myInterceptor', function() { -              return function(promise) { -                return promise.then(function(response) { -                  response.data = uppercase(response.data); -                  return response; -                }); -              } -            }); -            $httpProvider.responseInterceptors.push('myInterceptor'); -          }, function($http, $httpBackend) { -            var response; +      it('should support interceptors defined as services', function() { +        module(function($provide, $httpProvider) { +          $provide.factory('myInterceptor', function() { +            return function(promise) { +              return promise.then(function(response) { +                response.data = uppercase(response.data); +                return response; +              }); +            } +          }); +          $httpProvider.responseInterceptors.push('myInterceptor'); +        }); +        inject(function($http, $httpBackend) { +          var response; -            $httpBackend.expect('GET', '/test').respond('hello!'); -            $http.get('/test').success(function(data) {response = data;}); -            expect(response).toBeUndefined(); +          $httpBackend.expect('GET', '/test').respond('hello!'); +          $http.get('/test').success(function(data) {response = data;}); +          expect(response).toBeUndefined(); -            $httpBackend.flush(); -            expect(response).toBe('HELLO!'); -          } -      )); +          $httpBackend.flush(); +          expect(response).toBe('HELLO!'); +        }); +      });      });    });    describe('the instance', function() { -    var $httpBackend, $http; +    var $httpBackend, $http, $rootScope; + +    beforeEach(inject(['$rootScope', function($rs) { +      $rootScope = $rs; + +      spyOn($rootScope, '$apply').andCallThrough(); +    }]));      beforeEach(inject(['$httpBackend', '$http', function($hb, $h) {        $httpBackend = $hb; diff --git a/test/service/locationSpec.js b/test/service/locationSpec.js index 7c075fc0..c7cc9c23 100644 --- a/test/service/locationSpec.js +++ b/test/service/locationSpec.js @@ -335,11 +335,11 @@ describe('$location', function() {    function initService(html5Mode, hashPrefix, supportHistory) { -    return function($provide, $locationProvider){ +    return module(function($provide, $locationProvider){        $locationProvider.html5Mode(html5Mode);        $locationProvider.hashPrefix(hashPrefix);        $provide.value('$sniffer', {history: supportHistory}); -    }; +    });    }    function initBrowser(url, basePath) {      return function($browser){ @@ -350,7 +350,8 @@ describe('$location', function() {    describe('wiring', function() { -    beforeEach(inject(initService(false, '!', true), initBrowser('http://new.com/a/b#!', '/a/b'))); +    beforeEach(initService(false, '!', true)); +    beforeEach(inject(initBrowser('http://new.com/a/b#!', '/a/b')));      it('should update $location when browser url changes', inject(function($browser, $location) { @@ -413,30 +414,34 @@ describe('$location', function() {    // html5 history is disabled    describe('disabled history', function() { -    it('should use hashbang url with hash prefix', inject( -      initService(false, '!'), -      initBrowser('http://domain.com/base/index.html#!/a/b', '/base/index.html'), -      function($rootScope, $location, $browser) { -        expect($browser.url()).toBe('http://domain.com/base/index.html#!/a/b'); -        $location.path('/new'); -        $location.search({a: true}); -        $rootScope.$apply(); -        expect($browser.url()).toBe('http://domain.com/base/index.html#!/new?a'); -      }) -    ); - - -    it('should use hashbang url without hash prefix', inject( -      initService(false, ''), -      initBrowser('http://domain.com/base/index.html#/a/b', '/base/index.html'), -      function($rootScope, $location, $browser) { -        expect($browser.url()).toBe('http://domain.com/base/index.html#/a/b'); -        $location.path('/new'); -        $location.search({a: true}); -        $rootScope.$apply(); -        expect($browser.url()).toBe('http://domain.com/base/index.html#/new?a'); -      }) -    ); +    it('should use hashbang url with hash prefix', function() { +      initService(false, '!'); +      inject( +        initBrowser('http://domain.com/base/index.html#!/a/b', '/base/index.html'), +        function($rootScope, $location, $browser) { +          expect($browser.url()).toBe('http://domain.com/base/index.html#!/a/b'); +          $location.path('/new'); +          $location.search({a: true}); +          $rootScope.$apply(); +          expect($browser.url()).toBe('http://domain.com/base/index.html#!/new?a'); +        } +      ); +    }); + + +    it('should use hashbang url without hash prefix', function() { +      initService(false, ''); +      inject( +        initBrowser('http://domain.com/base/index.html#/a/b', '/base/index.html'), +        function($rootScope, $location, $browser) { +          expect($browser.url()).toBe('http://domain.com/base/index.html#/a/b'); +          $location.path('/new'); +          $location.search({a: true}); +          $rootScope.$apply(); +          expect($browser.url()).toBe('http://domain.com/base/index.html#/new?a'); +        } +      ); +    });    }); @@ -447,26 +452,30 @@ describe('$location', function() {        dealoc($document);      })); -    it('should use hashbang url with hash prefix', inject( -      initService(true, '!!', false), -      initBrowser('http://domain.com/base/index.html#!!/a/b', '/base/index.html'), -      function($rootScope, $location,  $browser) { -        expect($browser.url()).toBe('http://domain.com/base/index.html#!!/a/b'); -        $location.path('/new'); -        $location.search({a: true}); -        $rootScope.$apply(); -        expect($browser.url()).toBe('http://domain.com/base/index.html#!!/new?a'); -      }) -    ); - - -    it('should redirect to hashbang url when new url given', inject( -      initService(true, '!'), -      initBrowser('http://domain.com/base/new-path/index.html', '/base/index.html'), -      function($browser, $location) { -        expect($browser.url()).toBe('http://domain.com/base/index.html#!/new-path/index.html'); -      }) -    ); +    it('should use hashbang url with hash prefix', function() { +      initService(true, '!!', false); +      inject( +        initBrowser('http://domain.com/base/index.html#!!/a/b', '/base/index.html'), +        function($rootScope, $location,  $browser) { +          expect($browser.url()).toBe('http://domain.com/base/index.html#!!/a/b'); +          $location.path('/new'); +          $location.search({a: true}); +          $rootScope.$apply(); +          expect($browser.url()).toBe('http://domain.com/base/index.html#!!/new?a'); +        } +      ); +    }); + + +    it('should redirect to hashbang url when new url given', function() { +      initService(true, '!'); +      inject( +        initBrowser('http://domain.com/base/new-path/index.html', '/base/index.html'), +        function($browser, $location) { +          expect($browser.url()).toBe('http://domain.com/base/index.html#!/new-path/index.html'); +        } +      ); +    });    }); @@ -477,41 +486,47 @@ describe('$location', function() {        dealoc($document);      })); -    it('should use new url', inject( -      initService(true, '', true), -      initBrowser('http://domain.com/base/old/index.html#a', '/base/index.html'), -      function($rootScope, $location, $browser) { -        expect($browser.url()).toBe('http://domain.com/base/old/index.html#a'); -        $location.path('/new'); -        $location.search({a: true}); -        $rootScope.$apply(); -        expect($browser.url()).toBe('http://domain.com/base/new?a#a'); -      }) -    ); - - -    it('should rewrite when hashbang url given', inject( -      initService(true, '!', true), -      initBrowser('http://domain.com/base/index.html#!/a/b', '/base/index.html'), -      function($rootScope, $location, $browser) { -        expect($browser.url()).toBe('http://domain.com/base/a/b'); -        $location.path('/new'); -        $location.hash('abc'); -        $rootScope.$apply(); -        expect($browser.url()).toBe('http://domain.com/base/new#abc'); -        expect($location.path()).toBe('/new'); -      }) -    ); - - -    it('should rewrite when hashbang url given (without hash prefix)', inject( -      initService(true, '', true), -      initBrowser('http://domain.com/base/index.html#/a/b', '/base/index.html'), -      function($rootScope, $location, $browser) { -        expect($browser.url()).toBe('http://domain.com/base/a/b'); -        expect($location.path()).toBe('/a/b'); -      }) -    ); +    it('should use new url', function() { +      initService(true, '', true); +      inject( +        initBrowser('http://domain.com/base/old/index.html#a', '/base/index.html'), +        function($rootScope, $location, $browser) { +          expect($browser.url()).toBe('http://domain.com/base/old/index.html#a'); +          $location.path('/new'); +          $location.search({a: true}); +          $rootScope.$apply(); +          expect($browser.url()).toBe('http://domain.com/base/new?a#a'); +        } +      ); +    }); + + +    it('should rewrite when hashbang url given', function() { +      initService(true, '!', true); +      inject( +        initBrowser('http://domain.com/base/index.html#!/a/b', '/base/index.html'), +        function($rootScope, $location, $browser) { +          expect($browser.url()).toBe('http://domain.com/base/a/b'); +          $location.path('/new'); +          $location.hash('abc'); +          $rootScope.$apply(); +          expect($browser.url()).toBe('http://domain.com/base/new#abc'); +          expect($location.path()).toBe('/new'); +        } +      ); +    }); + + +    it('should rewrite when hashbang url given (without hash prefix)', function() { +      initService(true, '', true); +      inject( +        initBrowser('http://domain.com/base/index.html#/a/b', '/base/index.html'), +        function($rootScope, $location, $browser) { +          expect($browser.url()).toBe('http://domain.com/base/a/b'); +          expect($location.path()).toBe('/a/b'); +        } +      ); +    });    }); @@ -604,7 +619,7 @@ describe('$location', function() {      var root, link, originalBrowser, lastEventPreventDefault;      function configureService(linkHref, html5Mode, supportHist, attrs, content) { -      return function($provide, $locationProvider){ +      module(function($provide, $locationProvider) {          var jqRoot = jqLite('<div></div>');          attrs = attrs ? ' ' + attrs + ' ' : '';          link = jqLite('<a href="' + linkHref + '"' + attrs + '>' + content + '</a>')[0]; @@ -616,7 +631,7 @@ describe('$location', function() {          $provide.value('$sniffer', {history: supportHist});          $locationProvider.html5Mode(html5Mode);          $locationProvider.hashPrefix('!'); -      }; +      });      }      function initBrowser() { @@ -654,152 +669,178 @@ describe('$location', function() {      }); -    it('should rewrite rel link to new url when history enabled on new browser', inject( -      configureService('link?a#b', true, true), -      initBrowser(), -      initLocation(), -      function($browser) { -        browserTrigger(link, 'click'); -        expectRewriteTo($browser, 'http://host.com/base/link?a#b'); -      }) -    ); - - -    it('should rewrite abs link to new url when history enabled on new browser', inject( -      configureService('/base/link?a#b', true, true), -      initBrowser(), -      initLocation(), -      function($browser) { -        browserTrigger(link, 'click'); -        expectRewriteTo($browser, 'http://host.com/base/link?a#b'); -      }) -    ); - - -    it('should rewrite rel link to hashbang url when history enabled on old browser', inject( -      configureService('link?a#b', true, false), -      initBrowser(), -      initLocation(), -      function($browser) { -        browserTrigger(link, 'click'); -        expectRewriteTo($browser, 'http://host.com/base/index.html#!/link?a#b'); -      }) -    ); - - -    it('should rewrite abs link to hashbang url when history enabled on old browser', inject( -      configureService('/base/link?a#b', true, false), -      initBrowser(), -      initLocation(), -      function($browser) { -        browserTrigger(link, 'click'); -        expectRewriteTo($browser, 'http://host.com/base/index.html#!/link?a#b'); -      }) -    ); - - -    it('should not rewrite when history disabled', inject( -      configureService('#new', false), -      initBrowser(), -      initLocation(), -      function($browser) { -        browserTrigger(link, 'click'); -        expectNoRewrite($browser); -      }) -    ); - - -    it('should not rewrite ng:ext-link', inject( -      configureService('#new', true, true, 'ng:ext-link'), -      initBrowser(), -      initLocation(), -      function($browser) { -        browserTrigger(link, 'click'); -        expectNoRewrite($browser); -      }) -    ); - - -    it('should not rewrite full url links do different domain', inject( -      configureService('http://www.dot.abc/a?b=c', true), -      initBrowser(), -      initLocation(), -      function($browser) { -        browserTrigger(link, 'click'); -        expectNoRewrite($browser); -      }) -    ); - - -    it('should not rewrite links with target="_blank"', inject( -      configureService('/a?b=c', true, true, 'target="_blank"'), -      initBrowser(), -      initLocation(), -      function($browser) { -        browserTrigger(link, 'click'); -        expectNoRewrite($browser); -      }) -    ); - - -    it('should not rewrite links with target specified', inject( -      configureService('/a?b=c', true, true, 'target="some-frame"'), -      initBrowser(), -      initLocation(), -      function($browser) { -        browserTrigger(link, 'click'); -        expectNoRewrite($browser); -      }) -    ); - - -    it('should rewrite full url links to same domain and base path', inject( -      configureService('http://host.com/base/new', true), -      initBrowser(), -      initLocation(), -      function($browser) { -        browserTrigger(link, 'click'); -        expectRewriteTo($browser, 'http://host.com/base/index.html#!/new'); -      }) -    ); - - -    it('should rewrite when clicked span inside link', inject( -      configureService('some/link', true, true, '', '<span>link</span>'), -      initBrowser(), -      initLocation(), -      function($browser) { -        var span = jqLite(link).find('span'); - -        browserTrigger(span, 'click'); -        expectRewriteTo($browser, 'http://host.com/base/some/link'); -      }) -    ); +    it('should rewrite rel link to new url when history enabled on new browser', function() { +      configureService('link?a#b', true, true); +      inject( +        initBrowser(), +        initLocation(), +        function($browser) { +          browserTrigger(link, 'click'); +          expectRewriteTo($browser, 'http://host.com/base/link?a#b'); +        } +      ); +    }); -    // don't run next tests on IE<9, as browserTrigger does not simulate pressed keys -    if (!(msie < 9)) { +    it('should rewrite abs link to new url when history enabled on new browser', function() { +      configureService('/base/link?a#b', true, true); +      inject( +        initBrowser(), +        initLocation(), +        function($browser) { +          browserTrigger(link, 'click'); +          expectRewriteTo($browser, 'http://host.com/base/link?a#b'); +        } +      ); +    }); + -      it('should not rewrite when clicked with ctrl pressed', inject( -        configureService('/a?b=c', true, true), +    it('should rewrite rel link to hashbang url when history enabled on old browser', function() { +      configureService('link?a#b', true, false); +      inject(          initBrowser(),          initLocation(),          function($browser) { -          browserTrigger(link, 'click', ['ctrl']); +          browserTrigger(link, 'click'); +          expectRewriteTo($browser, 'http://host.com/base/index.html#!/link?a#b'); +        } +      ); +    }); + + +    it('should rewrite abs link to hashbang url when history enabled on old browser', function() { +      configureService('/base/link?a#b', true, false); +      inject( +        initBrowser(), +        initLocation(), +        function($browser) { +          browserTrigger(link, 'click'); +          expectRewriteTo($browser, 'http://host.com/base/index.html#!/link?a#b'); +        } +      ); +    }); + + +    it('should not rewrite when history disabled', function() { +      configureService('#new', false); +      inject( +        initBrowser(), +        initLocation(), +        function($browser) { +          browserTrigger(link, 'click'); +          expectNoRewrite($browser); +        } +      ); +    }); + + +    it('should not rewrite ng:ext-link', function() { +      configureService('#new', true, true, 'ng:ext-link'); +      inject( +        initBrowser(), +        initLocation(), +        function($browser) { +          browserTrigger(link, 'click'); +          expectNoRewrite($browser); +        } +      ); +    }); + + +    it('should not rewrite full url links do different domain', function() { +      configureService('http://www.dot.abc/a?b=c', true); +      inject( +        initBrowser(), +        initLocation(), +        function($browser) { +          browserTrigger(link, 'click');            expectNoRewrite($browser); -        }) +        }        ); +    }); + + +    it('should not rewrite links with target="_blank"', function() { +      configureService('/a?b=c', true, true, 'target="_blank"'); +      inject( +        initBrowser(), +        initLocation(), +        function($browser) { +          browserTrigger(link, 'click'); +          expectNoRewrite($browser); +        } +      ); +    }); -      it('should not rewrite when clicked with meta pressed', inject( -        configureService('/a?b=c', true, true), +    it('should not rewrite links with target specified', function() { +      configureService('/a?b=c', true, true, 'target="some-frame"'); +      inject(          initBrowser(),          initLocation(),          function($browser) { -          browserTrigger(link, 'click', ['meta']); +          browserTrigger(link, 'click');            expectNoRewrite($browser); -        }) +        }        ); +    }); + + +    it('should rewrite full url links to same domain and base path', function() { +      configureService('http://host.com/base/new', true); +      inject( +        initBrowser(), +        initLocation(), +        function($browser) { +          browserTrigger(link, 'click'); +          expectRewriteTo($browser, 'http://host.com/base/index.html#!/new'); +        } +      ); +    }); + + +    it('should rewrite when clicked span inside link', function() { +      configureService('some/link', true, true, '', '<span>link</span>'); +      inject( +        initBrowser(), +        initLocation(), +        function($browser) { +          var span = jqLite(link).find('span'); + +          browserTrigger(span, 'click'); +          expectRewriteTo($browser, 'http://host.com/base/some/link'); +        } +      ); +    }); + + +    // don't run next tests on IE<9, as browserTrigger does not simulate pressed keys +    if (!(msie < 9)) { + +      it('should not rewrite when clicked with ctrl pressed', function() { +        configureService('/a?b=c', true, true); +        inject( +          initBrowser(), +          initLocation(), +          function($browser) { +            browserTrigger(link, 'click', ['ctrl']); +            expectNoRewrite($browser); +          } +        ); +      }); + + +      it('should not rewrite when clicked with meta pressed', function() { +        configureService('/a?b=c', true, true); +        inject( +          initBrowser(), +          initLocation(), +          function($browser) { +            browserTrigger(link, 'click', ['meta']); +            expectNoRewrite($browser); +          } +        ); +      });      }    });  }); diff --git a/test/service/logSpec.js b/test/service/logSpec.js index ee250b66..98158ae0 100644 --- a/test/service/logSpec.js +++ b/test/service/logSpec.js @@ -9,7 +9,7 @@ describe('$log', function() {    function info() { logger+= 'info;'; }    function error() { logger+= 'error;'; } -  beforeEach(inject(function($provide){ +  beforeEach(module(function($provide){      $window = {};      logger = '';      $provide.service('$log', $LogProvider); diff --git a/test/service/parseSpec.js b/test/service/parseSpec.js index f57a52c7..08167843 100644 --- a/test/service/parseSpec.js +++ b/test/service/parseSpec.js @@ -154,7 +154,10 @@ describe('parser', function() {      });    }); -  var scope; +  var scope, $filterProvider; +  beforeEach(module(['$filterProvider', function (filterProvider) { +    $filterProvider = filterProvider; +  }]));    beforeEach(inject(function ($rootScope) {      scope = $rootScope;    })); @@ -191,19 +194,19 @@ describe('parser', function() {      expect(scope.$eval("'a' + 'b c'")).toEqual("ab c");    }); -  it('should parse filters', inject(function($filterProvider) { +  it('should parse filters', function() {      $filterProvider.register('substring', valueFn(function(input, start, end) {        return input.substring(start, end);      }));      expect(function() {        scope.$eval("1|nonexistent"); -    }).toThrow(new Error("Unknown provider for 'nonexistentFilter'.")); +    }).toThrow(new Error("Unknown provider: nonexistentFilterProvider <- nonexistentFilter"));      scope.offset =  3;      expect(scope.$eval("'abcd'|substring:1:offset")).toEqual("bc");      expect(scope.$eval("'abcd'|substring:1:3|uppercase")).toEqual("BC"); -  })); +  });    it('should access scope', function() {      scope.a =  123; diff --git a/test/service/scopeSpec.js b/test/service/scopeSpec.js index e1e8ab8b..96271bc9 100644 --- a/test/service/scopeSpec.js +++ b/test/service/scopeSpec.js @@ -117,15 +117,18 @@ describe('Scope', function() {      })); -    it('should delegate exceptions', inject(function($exceptionHandlerProvider) { -      $exceptionHandlerProvider.mode('log'); -    }, function($rootScope, $exceptionHandler, $log) { -      $rootScope.$watch('a', function() {throw new Error('abc');}); -      $rootScope.a = 1; -      $rootScope.$digest(); -      expect($exceptionHandler.errors[0].message).toEqual('abc'); -      $log.assertEmpty(); -    })); +    it('should delegate exceptions', function() { +      module(function($exceptionHandlerProvider) { +        $exceptionHandlerProvider.mode('log'); +      }); +      inject(function($rootScope, $exceptionHandler, $log) { +        $rootScope.$watch('a', function() {throw new Error('abc');}); +        $rootScope.a = 1; +        $rootScope.$digest(); +        expect($exceptionHandler.errors[0].message).toEqual('abc'); +        $log.assertEmpty(); +      }); +    });      it('should fire watches in order of addition', inject(function($rootScope) { @@ -459,25 +462,29 @@ describe('Scope', function() {      })); -    it('should catch exceptions', inject(function($exceptionHandlerProvider) { +    it('should catch exceptions', function() { +      module(function($exceptionHandlerProvider) {          $exceptionHandlerProvider.mode('log'); -      }, function($rootScope, $exceptionHandler, $log) { -      var log = ''; -      var child = $rootScope.$new(); -      $rootScope.$watch('a', function(scope, a) { log += '1'; }); -      $rootScope.a = 0; -      child.$apply(function() { throw new Error('MyError'); }); -      expect(log).toEqual('1'); -      expect($exceptionHandler.errors[0].message).toEqual('MyError'); -      $log.error.logs.shift(); -    })); +      }); +      inject(function($rootScope, $exceptionHandler, $log) { +        var log = ''; +        var child = $rootScope.$new(); +        $rootScope.$watch('a', function(scope, a) { log += '1'; }); +        $rootScope.a = 0; +        child.$apply(function() { throw new Error('MyError'); }); +        expect(log).toEqual('1'); +        expect($exceptionHandler.errors[0].message).toEqual('MyError'); +        $log.error.logs.shift(); +      }); +    });      describe('exceptions', function() {        var log; -      beforeEach(inject(function($exceptionHandlerProvider) { -          $exceptionHandlerProvider.mode('log'); -        }, function($rootScope) { +      beforeEach(module(function($exceptionHandlerProvider) { +        $exceptionHandlerProvider.mode('log'); +      })); +      beforeEach(inject(function($rootScope) {          log = '';          $rootScope.$watch(function() { log += '$digest;'; });          $rootScope.$digest(); @@ -613,10 +620,10 @@ describe('Scope', function() {          log += event.currentScope.id + '>';        } -      beforeEach(inject( -          function($exceptionHandlerProvider) { +      beforeEach(module(function($exceptionHandlerProvider) {          $exceptionHandlerProvider.mode('log'); -      }, function($rootScope) { +      })); +      beforeEach(inject(function($rootScope) {          log = '';          child = $rootScope.$new();          grandChild = child.$new(); diff --git a/test/widgetsSpec.js b/test/widgetsSpec.js index 632724ce..753a36b4 100644 --- a/test/widgetsSpec.js +++ b/test/widgetsSpec.js @@ -247,8 +247,8 @@ describe('widget', function() {          };        } +      beforeEach(module(spyOnAutoScroll()));        beforeEach(inject( -          spyOnAutoScroll(),            putIntoCache('template.html', 'CONTENT'),            putIntoCache('another.html', 'CONTENT'))); @@ -681,7 +681,7 @@ describe('widget', function() {      it('should be possible to nest ng:view in ng:include', inject(function() {        // TODO(vojta): refactor this test -      var injector = angular.injector('ng', 'ngMock'); +      var injector = angular.injector(['ng', 'ngMock']);        var myApp = injector.get('$rootScope');        var $httpBackend = injector.get('$httpBackend');        $httpBackend.expect('GET', 'includePartial.html').respond('view: <ng:view></ng:view>'); | 
