diff options
| author | Misko Hevery | 2012-02-15 15:45:07 -0800 | 
|---|---|---|
| committer | Vojta Jina | 2012-02-28 17:46:58 -0800 | 
| commit | f16bd2f747ed94547eabdc4c337775a22a365255 (patch) | |
| tree | bffa267eec9e90a8f1bc12c0063402c4c021d685 | |
| parent | ef7346ff70c745178d5c615e6ae5e559a4549f32 (diff) | |
| download | angular.js-f16bd2f747ed94547eabdc4c337775a22a365255.tar.bz2 | |
refactor($route): move when/otherwise to provider
| -rw-r--r-- | src/service/route.js | 145 | ||||
| -rw-r--r-- | test/service/routeParamsSpec.js | 24 | ||||
| -rw-r--r-- | test/service/routeSpec.js | 677 | ||||
| -rw-r--r-- | test/widgetsSpec.js | 244 | 
4 files changed, 592 insertions, 498 deletions
| diff --git a/src/service/route.js b/src/service/route.js index 932e26d5..7cdcfd05 100644 --- a/src/service/route.js +++ b/src/service/route.js @@ -63,6 +63,78 @@      </doc:example>   */  function $RouteProvider(){ +  var routes = {}; + +  /** +   * @ngdoc method +   * @name angular.module.ng.$route#when +   * @methodOf angular.module.ng.$route +   * +   * @param {string} path Route path (matched against `$location.hash`) +   * @param {Object} route Mapping information to be assigned to `$route.current` on route +   *    match. +   * +   *    Object properties: +   * +   *    - `controller` – `{function()=}` – Controller fn that should be associated with newly +   *      created scope. +   *    - `template` – `{string=}` – path to an html template that should be used by +   *      {@link angular.module.ng.$compileProvider.directive.ng:view ng:view} or +   *      {@link angular.module.ng.$compileProvider.directive.ng:include ng:include} widgets. +   *    - `redirectTo` – {(string|function())=} – value to update +   *      {@link angular.module.ng.$location $location} path with and trigger route redirection. +   * +   *      If `redirectTo` is a function, it will be called with the following parameters: +   * +   *      - `{Object.<string>}` - route parameters extracted from the current +   *        `$location.path()` by applying the current route template. +   *      - `{string}` - current `$location.path()` +   *      - `{Object}` - current `$location.search()` +   * +   *      The custom `redirectTo` function is expected to return a string which will be used +   *      to update `$location.path()` and `$location.search()`. +   * +   *    - `[reloadOnSearch=true]` - {boolean=} - reload route when only $location.search() +   *    changes. +   * +   *      If the option is set to false and url in the browser changes, then +   *      $routeUpdate event is emited on the current route scope. You can use this event to +   *      react to {@link angular.module.ng.$routeParams} changes: +   * +   *            function MyCtrl($route, $routeParams) { +   *              this.$on('$routeUpdate', function() { +   *                // do stuff with $routeParams +   *              }); +   *            } +   * +   * @returns {Object} route object +   * +   * @description +   * Adds a new route definition to the `$route` service. +   */ +  this.when = function(path, route) { +    var routeDef = routes[path]; +    if (!routeDef) routeDef = routes[path] = {reloadOnSearch: true}; +    if (route) extend(routeDef, route); // TODO(im): what the heck? merge two route definitions? +    return routeDef; +  }; + +  /** +   * @ngdoc method +   * @name angular.module.ng.$route#otherwise +   * @methodOf angular.module.ng.$route +   * +   * @description +   * Sets route definition that will be used on route change when no other route definition +   * is matched. +   * +   * @param {Object} params Mapping information to be assigned to `$route.current`. +   */ +  this.otherwise = function(params) { +    this.when(null, params); +  }; + +    this.$get = ['$rootScope', '$location', '$routeParams', '$controller',        function( $rootScope,  $location,  $routeParams, $controller) {      /** @@ -112,8 +184,7 @@ function $RouteProvider(){       * instance of the Controller.       */ -    var routes = {}, -        matcher = switchRouteMatcher, +    var matcher = switchRouteMatcher,          parentScope = $rootScope,          dirty = 0,          forceReload = false, @@ -138,76 +209,6 @@ function $RouteProvider(){            /**             * @ngdoc method -           * @name angular.module.ng.$route#when -           * @methodOf angular.module.ng.$route -           * -           * @param {string} path Route path (matched against `$location.hash`) -           * @param {Object} route Mapping information to be assigned to `$route.current` on route -           *    match. -           * -           *    Object properties: -           * -           *    - `controller` – `{function()=}` – Controller fn that should be associated with newly -           *      created scope. -           *    - `template` – `{string=}` – path to an html template that should be used by -           *      {@link angular.module.ng.$compileProvider.directive.ng:view ng:view} or -           *      {@link angular.module.ng.$compileProvider.directive.ng:include ng:include} widgets. -           *    - `redirectTo` – {(string|function())=} – value to update -           *      {@link angular.module.ng.$location $location} path with and trigger route redirection. -           * -           *      If `redirectTo` is a function, it will be called with the following parameters: -           * -           *      - `{Object.<string>}` - route parameters extracted from the current -           *        `$location.path()` by applying the current route template. -           *      - `{string}` - current `$location.path()` -           *      - `{Object}` - current `$location.search()` -           * -           *      The custom `redirectTo` function is expected to return a string which will be used -           *      to update `$location.path()` and `$location.search()`. -           * -           *    - `[reloadOnSearch=true]` - {boolean=} - reload route when only $location.search() -           *    changes. -           * -           *      If the option is set to false and url in the browser changes, then -           *      $routeUpdate event is emited on the current route scope. You can use this event to -           *      react to {@link angular.module.ng.$routeParams} changes: -           * -           *            function MyCtrl($route, $routeParams) { -           *              this.$on('$routeUpdate', function() { -           *                // do stuff with $routeParams -           *              }); -           *            } -           * -           * @returns {Object} route object -           * -           * @description -           * Adds a new route definition to the `$route` service. -           */ -          when: function(path, route) { -            var routeDef = routes[path]; -            if (!routeDef) routeDef = routes[path] = {reloadOnSearch: true}; -            if (route) extend(routeDef, route); // TODO(im): what the heck? merge two route definitions? -            dirty++; -            return routeDef; -          }, - -          /** -           * @ngdoc method -           * @name angular.module.ng.$route#otherwise -           * @methodOf angular.module.ng.$route -           * -           * @description -           * Sets route definition that will be used on route change when no other route definition -           * is matched. -           * -           * @param {Object} params Mapping information to be assigned to `$route.current`. -           */ -          otherwise: function(params) { -            $route.when(null, params); -          }, - -          /** -           * @ngdoc method             * @name angular.module.ng.$route#reload             * @methodOf angular.module.ng.$route             * diff --git a/test/service/routeParamsSpec.js b/test/service/routeParamsSpec.js index d4088767..d1b2ecb1 100644 --- a/test/service/routeParamsSpec.js +++ b/test/service/routeParamsSpec.js @@ -1,16 +1,20 @@  'use strict';  describe('$routeParams', function() { -  it('should publish the params into a service', inject(function($rootScope, $route, $location, $routeParams) { -    $route.when('/foo'); -    $route.when('/bar/:barId'); +  it('should publish the params into a service',  function() { +    module(function($routeProvider) { +      $routeProvider.when('/foo'); +      $routeProvider.when('/bar/:barId'); +    }); -    $location.path('/foo').search('a=b'); -    $rootScope.$digest(); -    expect($routeParams).toEqual({a:'b'}); +    inject(function($rootScope, $route, $location, $routeParams) { +      $location.path('/foo').search('a=b'); +      $rootScope.$digest(); +      expect($routeParams).toEqual({a:'b'}); -    $location.path('/bar/123').search('x=abc'); -    $rootScope.$digest(); -    expect($routeParams).toEqual({barId:'123', x:'abc'}); -  })); +      $location.path('/bar/123').search('x=abc'); +      $rootScope.$digest(); +      expect($routeParams).toEqual({barId:'123', x:'abc'}); +    }); +  });  }); diff --git a/test/service/routeSpec.js b/test/service/routeSpec.js index d6f7d753..6c6828bc 100644 --- a/test/service/routeSpec.js +++ b/test/service/routeSpec.js @@ -1,7 +1,7 @@  'use strict';  describe('$route', function() { -  it('should route and fire change event', inject(function($route, $location, $rootScope) { +  it('should route and fire change event', function() {      var log = '',          lastRoute,          nextRoute; @@ -9,367 +9,415 @@ describe('$route', function() {      function BookChapter() {        log += '<init>;';      } - -    $route.when('/Book/:book/Chapter/:chapter', -      {controller: BookChapter, template: 'Chapter.html'}); -    $route.when('/Blank'); -    $rootScope.$on('$beforeRouteChange', function(event, next, current) { -      log += 'before();'; -      expect(current).toBe($route.current); -      lastRoute = current; -      nextRoute = next; -    }); -    $rootScope.$on('$afterRouteChange', function(event, current, last) { -      log += 'after();'; -      expect(current).toBe($route.current); -      expect(lastRoute).toBe(last); -      expect(nextRoute).toBe(current); +    module(function($routeProvider) { +      $routeProvider.when('/Book/:book/Chapter/:chapter', +          {controller: BookChapter, template: 'Chapter.html'}); +      $routeProvider.when('/Blank');      }); +    inject(function($route, $location, $rootScope) { +      $rootScope.$on('$beforeRouteChange', function(event, next, current) { +        log += 'before();'; +        expect(current).toBe($route.current); +        lastRoute = current; +        nextRoute = next; +      }); +      $rootScope.$on('$afterRouteChange', function(event, current, last) { +        log += 'after();'; +        expect(current).toBe($route.current); +        expect(lastRoute).toBe(last); +        expect(nextRoute).toBe(current); +      }); -    $location.path('/Book/Moby/Chapter/Intro').search('p=123'); -    $rootScope.$digest(); -    expect(log).toEqual('before();<init>;after();'); -    expect($route.current.params).toEqual({book:'Moby', chapter:'Intro', p:'123'}); -    var lastId = $route.current.scope.$id; - -    log = ''; -    $location.path('/Blank').search('ignore'); -    $rootScope.$digest(); -    expect(log).toEqual('before();after();'); -    expect($route.current.params).toEqual({ignore:true}); -    expect($route.current.scope.$id).not.toEqual(lastId); +      $location.path('/Book/Moby/Chapter/Intro').search('p=123'); +      $rootScope.$digest(); +      expect(log).toEqual('before();<init>;after();'); +      expect($route.current.params).toEqual({book:'Moby', chapter:'Intro', p:'123'}); +      var lastId = $route.current.scope.$id; -    log = ''; -    $location.path('/NONE'); -    $rootScope.$digest(); -    expect(log).toEqual('before();after();'); -    expect($route.current).toEqual(null); +      log = ''; +      $location.path('/Blank').search('ignore'); +      $rootScope.$digest(); +      expect(log).toEqual('before();after();'); +      expect($route.current.params).toEqual({ignore:true}); +      expect($route.current.scope.$id).not.toEqual(lastId); -    $route.when('/NONE', {template:'instant update'}); -    $rootScope.$digest(); -    expect($route.current.template).toEqual('instant update'); -  })); +      log = ''; +      $location.path('/NONE'); +      $rootScope.$digest(); +      expect(log).toEqual('before();after();'); +      expect($route.current).toEqual(null); +    }); +  }); -  it('should match a route that contains special chars in the path', -      inject(function($route, $location, $rootScope) { -    $route.when('/$test.23/foo(bar)/:baz', {template: 'test.html'}); +  it('should match a route that contains special chars in the path', function() { +    module(function($routeProvider) { +      $routeProvider.when('/$test.23/foo(bar)/:baz', {template: 'test.html'}); +    }); +    inject(function($route, $location, $rootScope) { -    $location.path('/test'); -    $rootScope.$digest(); -    expect($route.current).toBeUndefined(); +      $location.path('/test'); +      $rootScope.$digest(); +      expect($route.current).toBeUndefined(); -    $location.path('/$testX23/foo(bar)/222'); -    $rootScope.$digest(); -    expect($route.current).toBeUndefined(); +      $location.path('/$testX23/foo(bar)/222'); +      $rootScope.$digest(); +      expect($route.current).toBeUndefined(); -    $location.path('/$test.23/foo(bar)/222'); -    $rootScope.$digest(); -    expect($route.current).toBeDefined(); +      $location.path('/$test.23/foo(bar)/222'); +      $rootScope.$digest(); +      expect($route.current).toBeDefined(); -    $location.path('/$test.23/foo\\(bar)/222'); -    $rootScope.$digest(); -    expect($route.current).toBeUndefined(); -  })); +      $location.path('/$test.23/foo\\(bar)/222'); +      $rootScope.$digest(); +      expect($route.current).toBeUndefined(); +    }); +  }); -  it('should change route even when only search param changes', -      inject(function($route, $location, $rootScope) { -    var callback = jasmine.createSpy('onRouteChange'); +  it('should change route even when only search param changes', function() { +    module(function($routeProvider) { +      $routeProvider.when('/test', {template: 'test.html'}); +    }); -    $route.when('/test', {template: 'test.html'}); -    $rootScope.$on('$beforeRouteChange', callback); -    $location.path('/test'); -    $rootScope.$digest(); -    callback.reset(); +    inject(function($route, $location, $rootScope) { +      var callback = jasmine.createSpy('onRouteChange'); -    $location.search({any: true}); -    $rootScope.$digest(); +      $rootScope.$on('$beforeRouteChange', callback); +      $location.path('/test'); +      $rootScope.$digest(); +      callback.reset(); -    expect(callback).toHaveBeenCalled(); -  })); +      $location.search({any: true}); +      $rootScope.$digest(); +      expect(callback).toHaveBeenCalled(); +    }); +  }); -  it('should allow routes to be defined with just templates without controllers', -      inject(function($route, $location, $rootScope) { -    var onChangeSpy = jasmine.createSpy('onChange'); -    $route.when('/foo', {template: 'foo.html'}); -    $rootScope.$on('$beforeRouteChange', onChangeSpy); -    expect($route.current).toBeUndefined(); -    expect(onChangeSpy).not.toHaveBeenCalled(); +  it('should allow routes to be defined with just templates without controllers', function() { +    module(function($routeProvider) { +      $routeProvider.when('/foo', {template: 'foo.html'}); +    }); -    $location.path('/foo'); -    $rootScope.$digest(); +    inject(function($route, $location, $rootScope) { +      var onChangeSpy = jasmine.createSpy('onChange'); -    expect($route.current.template).toEqual('foo.html'); -    expect($route.current.controller).toBeUndefined(); -    expect(onChangeSpy).toHaveBeenCalled(); -  })); +      $rootScope.$on('$beforeRouteChange', onChangeSpy); +      expect($route.current).toBeUndefined(); +      expect(onChangeSpy).not.toHaveBeenCalled(); +      $location.path('/foo'); +      $rootScope.$digest(); -  it('should handle unknown routes with "otherwise" route definition', -      inject(function($route, $location, $rootScope) { -    var onChangeSpy = jasmine.createSpy('onChange'); +      expect($route.current.template).toEqual('foo.html'); +      expect($route.current.controller).toBeUndefined(); +      expect(onChangeSpy).toHaveBeenCalled(); +    }); +  }); -    function NotFoundCtrl($scope) {$scope.notFoundProp = 'not found!';} -    $route.when('/foo', {template: 'foo.html'}); -    $route.otherwise({template: '404.html', controller: NotFoundCtrl}); -    $rootScope.$on('$beforeRouteChange', onChangeSpy); -    expect($route.current).toBeUndefined(); -    expect(onChangeSpy).not.toHaveBeenCalled(); +  it('should handle unknown routes with "otherwise" route definition', function() { +    function NotFoundCtrl($scope) { +      $scope.notFoundProp = 'not found!'; +    } -    $location.path('/unknownRoute'); -    $rootScope.$digest(); +    module(function($routeProvider){ +      $routeProvider.when('/foo', {template: 'foo.html'}); +      $routeProvider.otherwise({template: '404.html', controller: NotFoundCtrl}); +    }); -    expect($route.current.template).toBe('404.html'); -    expect($route.current.controller).toBe(NotFoundCtrl); -    expect($route.current.scope.notFoundProp).toBe('not found!'); -    expect(onChangeSpy).toHaveBeenCalled(); +    inject(function($route, $location, $rootScope) { +      var onChangeSpy = jasmine.createSpy('onChange'); -    onChangeSpy.reset(); -    $location.path('/foo'); -    $rootScope.$digest(); +      $rootScope.$on('$beforeRouteChange', onChangeSpy); +      expect($route.current).toBeUndefined(); +      expect(onChangeSpy).not.toHaveBeenCalled(); -    expect($route.current.template).toEqual('foo.html'); -    expect($route.current.controller).toBeUndefined(); -    expect($route.current.scope.notFoundProp).toBeUndefined(); -    expect(onChangeSpy).toHaveBeenCalled(); -  })); +      $location.path('/unknownRoute'); +      $rootScope.$digest(); +      expect($route.current.template).toBe('404.html'); +      expect($route.current.controller).toBe(NotFoundCtrl); +      expect($route.current.scope.notFoundProp).toBe('not found!'); +      expect(onChangeSpy).toHaveBeenCalled(); -  it('should $destroy old routes', inject(function($route, $location, $rootScope) { -    $route.when('/foo', {template: 'foo.html', controller: function() {this.name = 'FOO';}}); -    $route.when('/bar', {template: 'bar.html', controller: function() {this.name = 'BAR';}}); -    $route.when('/baz', {template: 'baz.html'}); +      onChangeSpy.reset(); +      $location.path('/foo'); +      $rootScope.$digest(); -    expect($rootScope.$childHead).toEqual(null); +      expect($route.current.template).toEqual('foo.html'); +      expect($route.current.controller).toBeUndefined(); +      expect($route.current.scope.notFoundProp).toBeUndefined(); +      expect(onChangeSpy).toHaveBeenCalled(); +    }); +  }); -    $location.path('/foo'); -    $rootScope.$digest(); -    expect($rootScope.$$childHead.$id).toBeTruthy(); -    expect($rootScope.$$childHead.$id).toEqual($rootScope.$$childTail.$id); -    $location.path('/bar'); -    $rootScope.$digest(); -    expect($rootScope.$$childHead.$id).toBeTruthy(); -    expect($rootScope.$$childHead.$id).toEqual($rootScope.$$childTail.$id); +  it('should $destroy old routes', function() { +    module(function($routeProvider) { +      $routeProvider.when('/foo', {template: 'foo.html', controller: function() {this.name = 'FOO';}}); +      $routeProvider.when('/bar', {template: 'bar.html', controller: function() {this.name = 'BAR';}}); +      $routeProvider.when('/baz', {template: 'baz.html'}); +    }); -    $location.path('/baz'); -    $rootScope.$digest(); -    expect($rootScope.$$childHead.$id).toBeTruthy(); -    expect($rootScope.$$childHead.$id).toEqual($rootScope.$$childTail.$id); +    inject(function($route, $location, $rootScope) { +      expect($rootScope.$childHead).toEqual(null); -    $location.path('/'); -    $rootScope.$digest(); -    expect($rootScope.$$childHead).toEqual(null); -    expect($rootScope.$$childTail).toEqual(null); -  })); +      $location.path('/foo'); +      $rootScope.$digest(); +      expect($rootScope.$$childHead.$id).toBeTruthy(); +      expect($rootScope.$$childHead.$id).toEqual($rootScope.$$childTail.$id); +      $location.path('/bar'); +      $rootScope.$digest(); +      expect($rootScope.$$childHead.$id).toBeTruthy(); +      expect($rootScope.$$childHead.$id).toEqual($rootScope.$$childTail.$id); -  it('should infer arguments in injection', inject(function($route, $location, $rootScope) { -    var injectedRoute; -    $route.when('/test', {controller: function($route) {injectedRoute = $route;}}); -    $location.path('/test'); -    $rootScope.$digest(); -    expect(injectedRoute).toBe($route); -  })); +      $location.path('/baz'); +      $rootScope.$digest(); +      expect($rootScope.$$childHead.$id).toBeTruthy(); +      expect($rootScope.$$childHead.$id).toEqual($rootScope.$$childTail.$id); +      $location.path('/'); +      $rootScope.$digest(); +      expect($rootScope.$$childHead).toEqual(null); +      expect($rootScope.$$childTail).toEqual(null); +    }); +  }); -  describe('redirection', function() { -    it('should support redirection via redirectTo property by updating $location', -        inject(function($route, $location, $rootScope) { -      var onChangeSpy = jasmine.createSpy('onChange'); -      $route.when('/', {redirectTo: '/foo'}); -      $route.when('/foo', {template: 'foo.html'}); -      $route.when('/bar', {template: 'bar.html'}); -      $route.when('/baz', {redirectTo: '/bar'}); -      $route.otherwise({template: '404.html'}); -      $rootScope.$on('$beforeRouteChange', onChangeSpy); -      expect($route.current).toBeUndefined(); -      expect(onChangeSpy).not.toHaveBeenCalled(); +  it('should infer arguments in injection', function() { +    var injectedRoute; +    module(function($routeProvider) { +      $routeProvider.when('/test', {controller: function($route) {injectedRoute = $route;}}); +    }); -      $location.path('/'); +    inject(function($route, $location, $rootScope) { +      $location.path('/test');        $rootScope.$digest(); -      expect($location.path()).toBe('/foo'); -      expect($route.current.template).toBe('foo.html'); -      expect(onChangeSpy.callCount).toBe(2); +      expect(injectedRoute).toBe($route); +    }); +  }); -      onChangeSpy.reset(); -      $location.path('/baz'); -      $rootScope.$digest(); -      expect($location.path()).toBe('/bar'); -      expect($route.current.template).toBe('bar.html'); -      expect(onChangeSpy.callCount).toBe(2); -    })); +  describe('redirection', function() { +    it('should support redirection via redirectTo property by updating $location', function() { +      module(function($routeProvider) { +        $routeProvider.when('/', {redirectTo: '/foo'}); +        $routeProvider.when('/foo', {template: 'foo.html'}); +        $routeProvider.when('/bar', {template: 'bar.html'}); +        $routeProvider.when('/baz', {redirectTo: '/bar'}); +        $routeProvider.otherwise({template: '404.html'}); +      }); -    it('should interpolate route vars in the redirected path from original path', -        inject(function($route, $location, $rootScope) { -      $route.when('/foo/:id/foo/:subid/:extraId', {redirectTo: '/bar/:id/:subid/23'}); -      $route.when('/bar/:id/:subid/:subsubid', {template: 'bar.html'}); +      inject(function($route, $location, $rootScope) { +        var onChangeSpy = jasmine.createSpy('onChange'); -      $location.path('/foo/id1/foo/subid3/gah'); -      $rootScope.$digest(); +        $rootScope.$on('$beforeRouteChange', onChangeSpy); +        expect($route.current).toBeUndefined(); +        expect(onChangeSpy).not.toHaveBeenCalled(); -      expect($location.path()).toEqual('/bar/id1/subid3/23'); -      expect($location.search()).toEqual({extraId: 'gah'}); -      expect($route.current.template).toEqual('bar.html'); -    })); +        $location.path('/'); +        $rootScope.$digest(); +        expect($location.path()).toBe('/foo'); +        expect($route.current.template).toBe('foo.html'); +        expect(onChangeSpy.callCount).toBe(2); +        onChangeSpy.reset(); +        $location.path('/baz'); +        $rootScope.$digest(); +        expect($location.path()).toBe('/bar'); +        expect($route.current.template).toBe('bar.html'); +        expect(onChangeSpy.callCount).toBe(2); +      }); +    }); -    it('should interpolate route vars in the redirected path from original search', -        inject(function($route, $location, $rootScope) { -      $route.when('/bar/:id/:subid/:subsubid', {template: 'bar.html'}); -      $route.when('/foo/:id/:extra', {redirectTo: '/bar/:id/:subid/99'}); -      $location.path('/foo/id3/eId').search('subid=sid1&appended=true'); -      $rootScope.$digest(); +    it('should interpolate route vars in the redirected path from original path', function() { +      module(function($routeProvider) { +        $routeProvider.when('/foo/:id/foo/:subid/:extraId', {redirectTo: '/bar/:id/:subid/23'}); +        $routeProvider.when('/bar/:id/:subid/:subsubid', {template: 'bar.html'}); +      }); -      expect($location.path()).toEqual('/bar/id3/sid1/99'); -      expect($location.search()).toEqual({appended: 'true', extra: 'eId'}); -      expect($route.current.template).toEqual('bar.html'); -    })); +      inject(function($route, $location, $rootScope) { +        $location.path('/foo/id1/foo/subid3/gah'); +        $rootScope.$digest(); +        expect($location.path()).toEqual('/bar/id1/subid3/23'); +        expect($location.search()).toEqual({extraId: 'gah'}); +        expect($route.current.template).toEqual('bar.html'); +      }); +    }); -    it('should allow custom redirectTo function to be used', -        inject(function($route, $location, $rootScope) { -      $route.when('/bar/:id/:subid/:subsubid', {template: 'bar.html'}); -      $route.when('/foo/:id', {redirectTo: customRedirectFn}); -      $location.path('/foo/id3').search('subid=sid1&appended=true'); -      $rootScope.$digest(); +    it('should interpolate route vars in the redirected path from original search', function() { +      module(function($routeProvider) { +        $routeProvider.when('/bar/:id/:subid/:subsubid', {template: 'bar.html'}); +        $routeProvider.when('/foo/:id/:extra', {redirectTo: '/bar/:id/:subid/99'}); +      }); + +      inject(function($route, $location, $rootScope) { +        $location.path('/foo/id3/eId').search('subid=sid1&appended=true'); +        $rootScope.$digest(); + +        expect($location.path()).toEqual('/bar/id3/sid1/99'); +        expect($location.search()).toEqual({appended: 'true', extra: 'eId'}); +        expect($route.current.template).toEqual('bar.html'); +      }); +    }); -      expect($location.path()).toEqual('/custom'); +    it('should allow custom redirectTo function to be used', function() {        function customRedirectFn(routePathParams, path, search) {          expect(routePathParams).toEqual({id: 'id3'}); -        expect(path).toEqual($location.path()); -        expect(search).toEqual($location.search()); +        expect(path).toEqual('/foo/id3'); +        expect(search).toEqual({ subid: 'sid1', appended: 'true' });          return '/custom';        } -    })); +      module(function($routeProvider){ +        $routeProvider.when('/bar/:id/:subid/:subsubid', {template: 'bar.html'}); +        $routeProvider.when('/foo/:id', {redirectTo: customRedirectFn}); +      }); -    it('should replace the url when redirecting', inject(function($route, $location, $rootScope) { -      $route.when('/bar/:id', {template: 'bar.html'}); -      $route.when('/foo/:id/:extra', {redirectTo: '/bar/:id'}); +      inject(function($route, $location, $rootScope) { +        $location.path('/foo/id3').search('subid=sid1&appended=true'); +        $rootScope.$digest(); -      var replace; -      $rootScope.$watch(function() { -        if (isUndefined(replace)) replace = $location.$$replace; +        expect($location.path()).toEqual('/custom');        }); +    }); -      $location.path('/foo/id3/eId'); -      $rootScope.$digest(); -      expect($location.path()).toEqual('/bar/id3'); -      expect(replace).toBe(true); -    })); +    it('should replace the url when redirecting',  function() { +      module(function($routeProvider) { +        $routeProvider.when('/bar/:id', {template: 'bar.html'}); +        $routeProvider.when('/foo/:id/:extra', {redirectTo: '/bar/:id'}); +      }); +      inject(function($route, $location, $rootScope) { +        var replace; +        $rootScope.$watch(function() { +          if (isUndefined(replace)) replace = $location.$$replace; +        }); + +        $location.path('/foo/id3/eId'); +        $rootScope.$digest(); + +        expect($location.path()).toEqual('/bar/id3'); +        expect(replace).toBe(true); +      }); +    });    });    describe('reloadOnSearch', function() { -    it('should reload a route when reloadOnSearch is enabled and .search() changes', -        inject(function($route, $location, $rootScope, $routeParams) { +    it('should reload a route when reloadOnSearch is enabled and .search() changes', function() {        var reloaded = jasmine.createSpy('route reload'); -      $route.when('/foo', {controller: FooCtrl}); -      $rootScope.$on('$beforeRouteChange', reloaded); -        function FooCtrl() {          reloaded();        } -      $location.path('/foo'); -      $rootScope.$digest(); -      expect(reloaded).toHaveBeenCalled(); -      expect($routeParams).toEqual({}); -      reloaded.reset(); +      module(function($routeProvider) { +        $routeProvider.when('/foo', {controller: FooCtrl}); +      }); -      // trigger reload -      $location.search({foo: 'bar'}); -      $rootScope.$digest(); -      expect(reloaded).toHaveBeenCalled(); -      expect($routeParams).toEqual({foo:'bar'}); -    })); +      inject(function($route, $location, $rootScope, $routeParams) { +        $rootScope.$on('$beforeRouteChange', reloaded); +        $location.path('/foo'); +        $rootScope.$digest(); +        expect(reloaded).toHaveBeenCalled(); +        expect($routeParams).toEqual({}); +        reloaded.reset(); +        // trigger reload +        $location.search({foo: 'bar'}); +        $rootScope.$digest(); +        expect(reloaded).toHaveBeenCalled(); +        expect($routeParams).toEqual({foo:'bar'}); +      }); +    }); -    it('should not reload a route when reloadOnSearch is disabled and only .search() changes', -        inject(function($route, $location, $rootScope) { + +    it('should not reload a route when reloadOnSearch is disabled and only .search() changes', function() {        var reloaded = jasmine.createSpy('route reload'),            routeUpdateEvent = jasmine.createSpy('route reload'); -      $route.when('/foo', {controller: FooCtrl, reloadOnSearch: false}); -      $rootScope.$on('$beforeRouteChange', reloaded); -        function FooCtrl($scope) {          reloaded();          $scope.$on('$routeUpdate', routeUpdateEvent);        } -      expect(reloaded).not.toHaveBeenCalled(); +      module(function($routeProvider) { +        $routeProvider.when('/foo', {controller: FooCtrl, reloadOnSearch: false}); +      }); -      $location.path('/foo'); -      $rootScope.$digest(); -      expect(reloaded).toHaveBeenCalled(); -      expect(routeUpdateEvent).not.toHaveBeenCalled(); -      reloaded.reset(); +      inject(function($route, $location, $rootScope) { +        $rootScope.$on('$beforeRouteChange', reloaded); -      // don't trigger reload -      $location.search({foo: 'bar'}); -      $rootScope.$digest(); -      expect(reloaded).not.toHaveBeenCalled(); -      expect(routeUpdateEvent).toHaveBeenCalled(); -    })); +        expect(reloaded).not.toHaveBeenCalled(); +        $location.path('/foo'); +        $rootScope.$digest(); +        expect(reloaded).toHaveBeenCalled(); +        expect(routeUpdateEvent).not.toHaveBeenCalled(); +        reloaded.reset(); -    it('should reload reloadOnSearch route when url differs only in route path param', -        inject(function($route, $location, $rootScope) { +        // don't trigger reload +        $location.search({foo: 'bar'}); +        $rootScope.$digest(); +        expect(reloaded).not.toHaveBeenCalled(); +        expect(routeUpdateEvent).toHaveBeenCalled(); +      }); +    }); + + +    it('should reload reloadOnSearch route when url differs only in route path param', function() {        var reloaded = jasmine.createSpy('routeReload'),            onRouteChange = jasmine.createSpy('onRouteChange'); -      $route.when('/foo/:fooId', {controller: FooCtrl, reloadOnSearch: false}); -      $rootScope.$on('$beforeRouteChange', onRouteChange); -        function FooCtrl() {          reloaded();        } -      expect(reloaded).not.toHaveBeenCalled(); -      expect(onRouteChange).not.toHaveBeenCalled(); +      module(function($routeProvider) { +        $routeProvider.when('/foo/:fooId', {controller: FooCtrl, reloadOnSearch: false}); +      }); -      $location.path('/foo/aaa'); -      $rootScope.$digest(); -      expect(reloaded).toHaveBeenCalled(); -      expect(onRouteChange).toHaveBeenCalled(); -      reloaded.reset(); -      onRouteChange.reset(); +      inject(function($route, $location, $rootScope) { +        $rootScope.$on('$beforeRouteChange', onRouteChange); -      $location.path('/foo/bbb'); -      $rootScope.$digest(); -      expect(reloaded).toHaveBeenCalled(); -      expect(onRouteChange).toHaveBeenCalled(); -      reloaded.reset(); -      onRouteChange.reset(); +        expect(reloaded).not.toHaveBeenCalled(); +        expect(onRouteChange).not.toHaveBeenCalled(); -      $location.search({foo: 'bar'}); -      $rootScope.$digest(); -      expect(reloaded).not.toHaveBeenCalled(); -      expect(onRouteChange).not.toHaveBeenCalled(); -    })); +        $location.path('/foo/aaa'); +        $rootScope.$digest(); +        expect(reloaded).toHaveBeenCalled(); +        expect(onRouteChange).toHaveBeenCalled(); +        reloaded.reset(); +        onRouteChange.reset(); +        $location.path('/foo/bbb'); +        $rootScope.$digest(); +        expect(reloaded).toHaveBeenCalled(); +        expect(onRouteChange).toHaveBeenCalled(); +        reloaded.reset(); +        onRouteChange.reset(); -    it('should update params when reloadOnSearch is disabled and .search() changes', -        inject(function($route, $location, $rootScope) { -      var routeParams = jasmine.createSpy('routeParams'); +        $location.search({foo: 'bar'}); +        $rootScope.$digest(); +        expect(reloaded).not.toHaveBeenCalled(); +        expect(onRouteChange).not.toHaveBeenCalled(); +      }); +    }); -      $route.when('/foo', {controller: FooCtrl}); -      $route.when('/bar/:barId', {controller: FooCtrl, reloadOnSearch: false}); -      function FooCtrl($scope) { +    it('should update params when reloadOnSearch is disabled and .search() changes', function() { +      var routeParams = jasmine.createSpy('routeParams'); + +      function FooCtrl($scope, $route) {          $scope.$watch(function() {            return $route.current.params;          }, function(value) { @@ -377,33 +425,39 @@ describe('$route', function() {          });        } -      expect(routeParams).not.toHaveBeenCalled(); +      module(function($routeProvider) { +        $routeProvider.when('/foo', {controller: FooCtrl}); +        $routeProvider.when('/bar/:barId', {controller: FooCtrl, reloadOnSearch: false}); +      }); -      $location.path('/foo'); -      $rootScope.$digest(); -      expect(routeParams).toHaveBeenCalledWith({}); -      routeParams.reset(); +      inject(function($route, $location, $rootScope) { +        expect(routeParams).not.toHaveBeenCalled(); -      // trigger reload -      $location.search({foo: 'bar'}); -      $rootScope.$digest(); -      expect(routeParams).toHaveBeenCalledWith({foo: 'bar'}); -      routeParams.reset(); +        $location.path('/foo'); +        $rootScope.$digest(); +        expect(routeParams).toHaveBeenCalledWith({}); +        routeParams.reset(); -      $location.path('/bar/123').search({}); -      $rootScope.$digest(); -      expect(routeParams).toHaveBeenCalledWith({barId: '123'}); -      routeParams.reset(); +        // trigger reload +        $location.search({foo: 'bar'}); +        $rootScope.$digest(); +        expect(routeParams).toHaveBeenCalledWith({foo: 'bar'}); +        routeParams.reset(); -      // don't trigger reload -      $location.search({foo: 'bar'}); -      $rootScope.$digest(); -      expect(routeParams).toHaveBeenCalledWith({barId: '123', foo: 'bar'}); -    })); +        $location.path('/bar/123').search({}); +        $rootScope.$digest(); +        expect(routeParams).toHaveBeenCalledWith({barId: '123'}); +        routeParams.reset(); + +        // don't trigger reload +        $location.search({foo: 'bar'}); +        $rootScope.$digest(); +        expect(routeParams).toHaveBeenCalledWith({barId: '123', foo: 'bar'}); +      }); +    }); -    it('should $destroy scope after update and reload', -        inject(function($route, $location, $rootScope) { +    it('should $destroy scope after update and reload',  function() {        // this is a regression of bug, where $route doesn't copy scope when only updating        var log = []; @@ -422,48 +476,55 @@ describe('$route', function() {          };        } -      $route.when('/foo', {controller: createController('foo'), reloadOnSearch: false}); -      $route.when('/bar', {controller: createController('bar')}); +      module(function($routeProvider) { +        $routeProvider.when('/foo', {controller: createController('foo'), reloadOnSearch: false}); +        $routeProvider.when('/bar', {controller: createController('bar')}); +      }); -      $location.url('/foo'); -      $rootScope.$digest(); -      expect(log).toEqual(['init-foo']); +      inject(function($route, $location, $rootScope) { +        $location.url('/foo'); +        $rootScope.$digest(); +        expect(log).toEqual(['init-foo']); -      $location.search({q: 'some'}); -      $rootScope.$digest(); -      expect(log).toEqual(['init-foo', 'route-update']); +        $location.search({q: 'some'}); +        $rootScope.$digest(); +        expect(log).toEqual(['init-foo', 'route-update']); -      $location.url('/bar'); -      $rootScope.$digest(); -      expect(log).toEqual(['init-foo', 'route-update', 'destroy-foo', 'init-bar']); -    })); +        $location.url('/bar'); +        $rootScope.$digest(); +        expect(log).toEqual(['init-foo', 'route-update', 'destroy-foo', 'init-bar']); +      }); +    });      describe('reload', function() { -      it('should reload even if reloadOnSearch is false', -          inject(function($route, $location, $rootScope, $routeParams) { +      it('should reload even if reloadOnSearch is false', function() {          var count = 0; -        $route.when('/bar/:barId', {controller: FooCtrl, reloadOnSearch: false}); -          function FooCtrl() { count ++; } -        $location.path('/bar/123'); -        $rootScope.$digest(); -        expect($routeParams).toEqual({barId:'123'}); -        expect(count).toEqual(1); - -        $location.path('/bar/123').search('a=b'); -        $rootScope.$digest(); -        expect($routeParams).toEqual({barId:'123', a:'b'}); -        expect(count).toEqual(1); +        module(function($routeProvider) { +          $routeProvider.when('/bar/:barId', {controller: FooCtrl, reloadOnSearch: false}); +        }); -        $route.reload(); -        $rootScope.$digest(); -        expect($routeParams).toEqual({barId:'123', a:'b'}); -        expect(count).toEqual(2); -      })); +        inject(function($route, $location, $rootScope, $routeParams) { +          $location.path('/bar/123'); +          $rootScope.$digest(); +          expect($routeParams).toEqual({barId:'123'}); +          expect(count).toEqual(1); + +          $location.path('/bar/123').search('a=b'); +          $rootScope.$digest(); +          expect($routeParams).toEqual({barId:'123', a:'b'}); +          expect(count).toEqual(1); + +          $route.reload(); +          $rootScope.$digest(); +          expect($routeParams).toEqual({barId:'123', a:'b'}); +          expect(count).toEqual(2); +        }); +      });      });    });  }); diff --git a/test/widgetsSpec.js b/test/widgetsSpec.js index 6f0e3731..e762e7c0 100644 --- a/test/widgetsSpec.js +++ b/test/widgetsSpec.js @@ -618,8 +618,10 @@ describe('widget', function() {    describe('ng:view', function() { -    beforeEach(inject(function($rootScope, $compile) { -      element = $compile('<ng:view></ng:view>')($rootScope); +    beforeEach(module(function() { +      return function($rootScope, $compile) { +        element = $compile('<ng:view></ng:view>')($rootScope); +      };      })); @@ -631,71 +633,82 @@ describe('widget', function() {      })); -    it('should load content via xhr when route changes', -        inject(function($rootScope, $compile, $httpBackend, $location, $route) { -      $route.when('/foo', {template: 'myUrl1'}); -      $route.when('/bar', {template: 'myUrl2'}); +    it('should load content via xhr when route changes', function() { +      module(function($routeProvider) { +        $routeProvider.when('/foo', {template: 'myUrl1'}); +        $routeProvider.when('/bar', {template: 'myUrl2'}); +      }); -      expect(element.text()).toEqual(''); +      inject(function($rootScope, $compile, $httpBackend, $location, $route) { +        expect(element.text()).toEqual(''); -      $location.path('/foo'); -      $httpBackend.expect('GET', 'myUrl1').respond('<div>{{1+3}}</div>'); -      $rootScope.$digest(); -      $httpBackend.flush(); -      expect(element.text()).toEqual('4'); +        $location.path('/foo'); +        $httpBackend.expect('GET', 'myUrl1').respond('<div>{{1+3}}</div>'); +        $rootScope.$digest(); +        $httpBackend.flush(); +        expect(element.text()).toEqual('4'); -      $location.path('/bar'); -      $httpBackend.expect('GET', 'myUrl2').respond('angular is da best'); -      $rootScope.$digest(); -      $httpBackend.flush(); -      expect(element.text()).toEqual('angular is da best'); -    })); +        $location.path('/bar'); +        $httpBackend.expect('GET', 'myUrl2').respond('angular is da best'); +        $rootScope.$digest(); +        $httpBackend.flush(); +        expect(element.text()).toEqual('angular is da best'); +      }); +    }); -    it('should remove all content when location changes to an unknown route', -        inject(function($rootScope, $compile, $location, $httpBackend, $route) { -      $route.when('/foo', {template: 'myUrl1'}); +    it('should remove all content when location changes to an unknown route', function() { +      module(function($routeProvider) { +        $routeProvider.when('/foo', {template: 'myUrl1'}); +      }); -      $location.path('/foo'); -      $httpBackend.expect('GET', 'myUrl1').respond('<div>{{1+3}}</div>'); -      $rootScope.$digest(); -      $httpBackend.flush(); -      expect(element.text()).toEqual('4'); +      inject(function($rootScope, $compile, $location, $httpBackend, $route) { +        $location.path('/foo'); +        $httpBackend.expect('GET', 'myUrl1').respond('<div>{{1+3}}</div>'); +        $rootScope.$digest(); +        $httpBackend.flush(); +        expect(element.text()).toEqual('4'); -      $location.path('/unknown'); -      $rootScope.$digest(); -      expect(element.text()).toEqual(''); -    })); +        $location.path('/unknown'); +        $rootScope.$digest(); +        expect(element.text()).toEqual(''); +      }); +    }); -    it('should chain scopes and propagate evals to the child scope', -        inject(function($rootScope, $compile, $location, $httpBackend, $route) { -      $route.when('/foo', {template: 'myUrl1'}); -      $rootScope.parentVar = 'parent'; +    it('should chain scopes and propagate evals to the child scope', function() { +      module(function($routeProvider) { +        $routeProvider.when('/foo', {template: 'myUrl1'}); +      }); -      $location.path('/foo'); -      $httpBackend.expect('GET', 'myUrl1').respond('<div>{{parentVar}}</div>'); -      $rootScope.$digest(); -      $httpBackend.flush(); -      expect(element.text()).toEqual('parent'); +      inject(function($rootScope, $compile, $location, $httpBackend, $route) { +        $rootScope.parentVar = 'parent'; -      $rootScope.parentVar = 'new parent'; -      $rootScope.$digest(); -      expect(element.text()).toEqual('new parent'); -    })); +        $location.path('/foo'); +        $httpBackend.expect('GET', 'myUrl1').respond('<div>{{parentVar}}</div>'); +        $rootScope.$digest(); +        $httpBackend.flush(); +        expect(element.text()).toEqual('parent'); + +        $rootScope.parentVar = 'new parent'; +        $rootScope.$digest(); +        expect(element.text()).toEqual('new parent'); +      }); +    });      it('should be possible to nest ng:view in ng:include', inject(function() {        // TODO(vojta): refactor this test        dealoc(element); -      var injector = angular.injector(['ng', 'ngMock']); +      var injector = angular.injector(['ng', 'ngMock', function($routeProvider) { +        $routeProvider.when('/foo', {controller: angular.noop, template: 'viewPartial.html'}); +      }]);        var myApp = injector.get('$rootScope');        var $httpBackend = injector.get('$httpBackend');        $httpBackend.expect('GET', 'includePartial.html').respond('view: <ng:view></ng:view>');        injector.get('$location').path('/foo');        var $route = injector.get('$route'); -      $route.when('/foo', {controller: angular.noop, template: 'viewPartial.html'});        element = injector.get('$compile')(            '<div>' + @@ -714,94 +727,109 @@ describe('widget', function() {      it('should initialize view template after the view controller was initialized even when ' + -       'templates were cached', -       inject(function($rootScope, $compile, $location, $httpBackend, $route) { -      //this is a test for a regression that was introduced by making the ng:view cache sync - -      $route.when('/foo', {controller: ParentCtrl, template: 'viewPartial.html'}); -      $rootScope.log = []; - +       'templates were cached', function() { +       //this is a test for a regression that was introduced by making the ng:view cache sync        function ParentCtrl($scope) { -        $scope.log.push('parent'); +         $scope.log.push('parent');        } -      $rootScope.ChildCtrl = function($scope) { -        $scope.log.push('child'); -      }; +      module(function($routeProvider) { +        $routeProvider.when('/foo', {controller: ParentCtrl, template: 'viewPartial.html'}); +      }); -      $location.path('/foo'); -      $httpBackend.expect('GET', 'viewPartial.html'). -          respond('<div ng:init="log.push(\'init\')">' + -                    '<div ng:controller="ChildCtrl"></div>' + -                  '</div>'); -      $rootScope.$apply(); -      $httpBackend.flush(); -      expect($rootScope.log).toEqual(['parent', 'init', 'child']); +      inject(function($rootScope, $compile, $location, $httpBackend, $route) { +        $rootScope.log = []; -      $location.path('/'); -      $rootScope.$apply(); -      expect($rootScope.log).toEqual(['parent', 'init', 'child']); +        $rootScope.ChildCtrl = function($scope) { +          $scope.log.push('child'); +        }; -      $rootScope.log = []; -      $location.path('/foo'); -      $rootScope.$apply(); +        $location.path('/foo'); +        $httpBackend.expect('GET', 'viewPartial.html'). +            respond('<div ng:init="log.push(\'init\')">' + +                      '<div ng:controller="ChildCtrl"></div>' + +                    '</div>'); +        $rootScope.$apply(); +        $httpBackend.flush(); -      expect($rootScope.log).toEqual(['parent', 'init', 'child']); -    })); +        expect($rootScope.log).toEqual(['parent', 'init', 'child']); + +        $location.path('/'); +        $rootScope.$apply(); +        expect($rootScope.log).toEqual(['parent', 'init', 'child']); + +        $rootScope.log = []; +        $location.path('/foo'); +        $rootScope.$apply(); + +        expect($rootScope.log).toEqual(['parent', 'init', 'child']); +      }); +    });      it('should discard pending xhr callbacks if a new route is requested before the current ' + -        'finished loading', inject(function($route, $rootScope, $location, $httpBackend) { +        'finished loading',  function() {        // this is a test for a bad race condition that affected feedback -      $route.when('/foo', {template: 'myUrl1'}); -      $route.when('/bar', {template: 'myUrl2'}); +      module(function($routeProvider) { +        $routeProvider.when('/foo', {template: 'myUrl1'}); +        $routeProvider.when('/bar', {template: 'myUrl2'}); +      }); -      expect(element.text()).toEqual(''); +      inject(function($route, $rootScope, $location, $httpBackend) { +        expect(element.text()).toEqual(''); -      $location.path('/foo'); -      $httpBackend.expect('GET', 'myUrl1').respond('<div>{{1+3}}</div>'); -      $rootScope.$digest(); -      $location.path('/bar'); -      $httpBackend.expect('GET', 'myUrl2').respond('<div>{{1+1}}</div>'); -      $rootScope.$digest(); -      $httpBackend.flush(); // now that we have two requests pending, flush! +        $location.path('/foo'); +        $httpBackend.expect('GET', 'myUrl1').respond('<div>{{1+3}}</div>'); +        $rootScope.$digest(); +        $location.path('/bar'); +        $httpBackend.expect('GET', 'myUrl2').respond('<div>{{1+1}}</div>'); +        $rootScope.$digest(); +        $httpBackend.flush(); // now that we have two requests pending, flush! -      expect(element.text()).toEqual('2'); -    })); +        expect(element.text()).toEqual('2'); +      }); +    }); -    it('should clear the content when error during xhr request', -        inject(function($route, $location, $rootScope, $httpBackend) { -      $route.when('/foo', {controller: noop, template: 'myUrl1'}); +    it('should clear the content when error during xhr request', function() { +      module(function($routeProvider) { +        $routeProvider.when('/foo', {controller: noop, template: 'myUrl1'}); +      }); -      $location.path('/foo'); -      $httpBackend.expect('GET', 'myUrl1').respond(404, ''); -      element.text('content'); +      inject(function($route, $location, $rootScope, $httpBackend) { +        $location.path('/foo'); +        $httpBackend.expect('GET', 'myUrl1').respond(404, ''); +        element.text('content'); -      $rootScope.$digest(); -      $httpBackend.flush(); - -      expect(element.text()).toBe(''); -    })); +        $rootScope.$digest(); +        $httpBackend.flush(); +        expect(element.text()).toBe(''); +      }); +    }); -    it('should be async even if served from cache', -        inject(function($route, $rootScope, $location, $templateCache, $browser) { -      $templateCache.put('myUrl1', [200, 'my partial', {}]); -      $route.when('/foo', {controller: noop, template: 'myUrl1'}); -      $location.path('/foo'); -      var called = 0; -      // we want to assert only during first watch -      $rootScope.$watch(function() { -        if (!called++) expect(element.text()).toBe(''); +    it('should be async even if served from cache', function() { +      module(function($routeProvider) { +        $routeProvider.when('/foo', {controller: noop, template: 'myUrl1'});        }); -      $rootScope.$digest(); -      expect(element.text()).toBe('my partial'); -    })); +      inject(function($route, $rootScope, $location, $templateCache, $browser) { +        $templateCache.put('myUrl1', [200, 'my partial', {}]); +        $location.path('/foo'); + +        var called = 0; +        // we want to assert only during first watch +        $rootScope.$watch(function() { +          if (!called++) expect(element.text()).toBe(''); +        }); + +        $rootScope.$digest(); +        expect(element.text()).toBe('my partial'); +      }); +    });    }); | 
