'use strict';
describe('ngView', function() {
var element;
beforeEach(module('ngRoute'));
beforeEach(module(function($provide) {
return function($rootScope, $compile, $animate) {
element = $compile('
')($rootScope);
$location.url('/view');
$rootScope.$apply();
expect(contentOnLink).toBe('someContent');
});
});
it('should add the content to the element before compiling it', function() {
var root;
module(function($compileProvider, $routeProvider) {
$routeProvider.when('/view', {template: '
'});
$compileProvider.directive('test', function() {
return {
link: function(scope, element) {
root = element.parent().parent();
}
};
});
});
inject(function($compile, $rootScope, $location) {
element = $compile('
')($rootScope);
$location.url('/view');
$rootScope.$apply();
expect(root[0]).toBe(element[0]);
});
});
});
describe('ngView animations', function() {
var body, element, $rootElement;
beforeEach(module('ngRoute'));
function html(html) {
$rootElement.html(html);
body.append($rootElement);
element = $rootElement.children().eq(0);
return element;
}
beforeEach(module(function() {
// we need to run animation on attached elements;
return function(_$rootElement_) {
$rootElement = _$rootElement_;
body = angular.element(document.body);
};
}));
afterEach(function(){
dealoc(body);
dealoc(element);
});
beforeEach(module(function($provide, $routeProvider) {
$routeProvider.when('/foo', {controller: angular.noop, templateUrl: '/foo.html'});
$routeProvider.when('/bar', {controller: angular.noop, templateUrl: '/bar.html'});
return function($templateCache) {
$templateCache.put('/foo.html', [200, '
data
', {}]);
$templateCache.put('/bar.html', [200, '
data2
', {}]);
}
}));
describe('hooks', function() {
beforeEach(module('ngAnimate'));
beforeEach(module('mock.animate'));
it('should fire off the enter animation',
inject(function($compile, $rootScope, $location, $timeout, $animate) {
element = $compile(html('
'))($rootScope);
$location.path('/foo');
$rootScope.$digest();
var animation = $animate.queue.pop();
expect(animation.event).toBe('enter');
}));
it('should fire off the leave animation',
inject(function($compile, $rootScope, $location, $templateCache, $timeout, $animate) {
var item;
$templateCache.put('/foo.html', [200, '
foo
', {}]);
element = $compile(html('
'))($rootScope);
$location.path('/foo');
$rootScope.$digest();
$timeout.flush();
$location.path('/');
$rootScope.$digest();
var animation = $animate.queue.pop();
expect(animation.event).toBe('leave');
}));
it('should animate two separate ngView elements',
inject(function($compile, $rootScope, $templateCache, $location, $animate) {
var item;
$rootScope.tpl = 'one';
element = $compile(html('
'))($rootScope);
$rootScope.$digest();
$location.path('/foo');
$rootScope.$digest();
//we don't care about the enter animation for the first element
$animate.queue.pop();
$location.path('/bar');
$rootScope.$digest();
var animationB = $animate.queue.pop();
expect(animationB.event).toBe('leave');
var itemB = animationB.args[0];
var animationA = $animate.queue.pop();
expect(animationA.event).toBe('enter');
var itemA = animationA.args[0];
expect(itemA).not.toEqual(itemB);
}));
it('should render ngClass on ngView',
inject(function($compile, $rootScope, $templateCache, $animate, $location, $timeout) {
var item;
$rootScope.tpl = 'one';
$rootScope.klass = 'classy';
element = $compile(html('
'))($rootScope);
$rootScope.$digest();
$location.path('/foo');
$rootScope.$digest();
//we don't care about the enter animation
$animate.queue.shift();
var animation = $animate.queue.shift();
expect(animation.event).toBe('addClass');
var item = animation.element;
expect(item.hasClass('classy')).toBe(true);
$rootScope.klass = 'boring';
$rootScope.$digest();
expect($animate.queue.shift().event).toBe('removeClass');
expect($animate.queue.shift().event).toBe('addClass');
expect(item.hasClass('classy')).toBe(false);
expect(item.hasClass('boring')).toBe(true);
$location.path('/bar');
$rootScope.$digest();
//we don't care about the enter animation
$animate.queue.shift();
animation = $animate.queue.shift();
item = animation.element;
expect(animation.event).toBe('leave');
expect($animate.queue.shift().event).toBe('addClass');
expect(item.hasClass('boring')).toBe(true);
}));
it('should not double compile when the route changes', function() {
var window;
module(function($routeProvider, $animateProvider, $provide) {
$routeProvider.when('/foo', {template: '
{{i}}
'});
$routeProvider.when('/bar', {template: '
{{i}}
'});
$animateProvider.register('.my-animation', function() {
return {
leave: function(element, done) {
done();
}
};
});
});
inject(function($rootScope, $compile, $location, $route, $timeout, $rootElement, $sniffer, $animate) {
element = $compile(html('
'))($rootScope);
$animate.enabled(true);
$location.path('/foo');
$rootScope.$digest();
expect($animate.queue.shift().event).toBe('enter'); //ngView
expect($animate.queue.shift().event).toBe('enter'); //repeat 1
expect($animate.queue.shift().event).toBe('enter'); //repeat 2
expect(element.text()).toEqual('12');
$location.path('/bar');
$rootScope.$digest();
expect($animate.queue.shift().event).toBe('enter'); //ngView new
expect($animate.queue.shift().event).toBe('leave'); //ngView old
$rootScope.$digest();
expect($animate.queue.shift().event).toBe('enter'); //ngRepeat 3
expect($animate.queue.shift().event).toBe('enter'); //ngRepeat 4
expect(element.text()).toEqual('34');
function n(text) {
return text.replace(/\r\n/m, '').replace(/\r\n/m, '');
}
});
});
});
describe('autoscroll', function () {
var autoScrollSpy;
function spyOnAnchorScroll() {
return function($provide, $routeProvider) {
autoScrollSpy = jasmine.createSpy('$anchorScroll');
$provide.value('$anchorScroll', autoScrollSpy);
$routeProvider.when('/foo', {
controller: angular.noop,
template: '
'
});
};
}
function spyOnAnimateEnter() {
return function($animate) {
spyOn($animate, 'enter').andCallThrough();
};
}
function compileAndLink(tpl) {
return function($compile, $rootScope, $location) {
element = $compile(tpl)($rootScope);
};
}
beforeEach(module(spyOnAnchorScroll(), 'mock.animate'));
beforeEach(inject(spyOnAnimateEnter()));
it('should call $anchorScroll if autoscroll attribute is present', inject(
compileAndLink('
'),
function($rootScope, $animate, $timeout, $location) {
$location.path('/foo');
$rootScope.$digest();
expect($animate.queue.shift().event).toBe('enter');
$timeout.flush();
expect(autoScrollSpy).toHaveBeenCalledOnce();
}));
it('should call $anchorScroll if autoscroll evaluates to true', inject(
compileAndLink('
'),
function($rootScope, $animate, $timeout, $location) {
$rootScope.value = true;
$location.path('/foo');
$rootScope.$digest();
expect($animate.queue.shift().event).toBe('enter');
$timeout.flush();
expect(autoScrollSpy).toHaveBeenCalledOnce();
}));
it('should not call $anchorScroll if autoscroll attribute is not present', inject(
compileAndLink('
'),
function($rootScope, $location, $animate, $timeout) {
$location.path('/foo');
$rootScope.$digest();
expect($animate.queue.shift().event).toBe('enter');
$timeout.flush();
expect(autoScrollSpy).not.toHaveBeenCalled();
}));
it('should not call $anchorScroll if autoscroll evaluates to false', inject(
compileAndLink('
'),
function($rootScope, $location, $animate, $timeout) {
$rootScope.value = false;
$location.path('/foo');
$rootScope.$digest();
expect($animate.queue.shift().event).toBe('enter');
$timeout.flush();
expect(autoScrollSpy).not.toHaveBeenCalled();
}));
it('should only call $anchorScroll after the "enter" animation completes', inject(
compileAndLink('
'),
function($rootScope, $location, $animate, $timeout) {
$location.path('/foo');
expect($animate.enter).not.toHaveBeenCalled();
$rootScope.$digest();
expect(autoScrollSpy).not.toHaveBeenCalled();
expect($animate.queue.shift().event).toBe('enter');
$timeout.flush();
expect($animate.enter).toHaveBeenCalledOnce();
expect(autoScrollSpy).toHaveBeenCalledOnce();
}));
});
});