Files
angular.js/test/ngMessages/messagesSpec.js
2014-10-20 10:39:32 +01:00

472 lines
14 KiB
JavaScript

'use strict';
describe('ngMessages', function() {
beforeEach(inject.strictDi());
beforeEach(module('ngMessages'));
function they(msg, vals, spec, focus) {
forEach(vals, function(val, key) {
var m = msg.replace('$prop', key);
(focus ? iit : it)(m, function() {
spec(val);
});
});
}
function tthey(msg, vals, spec) {
they(msg, vals, spec, true);
}
function s(str) {
return str.replace(/\s+/g,'');
}
var element;
afterEach(function() {
dealoc(element);
});
it('should render based off of a hashmap collection', inject(function($rootScope, $compile) {
element = $compile('<div ng-messages="col">' +
' <div ng-message="val">Message is set</div>' +
'</div>')($rootScope);
$rootScope.$digest();
expect(element.text()).not.toContain('Message is set');
$rootScope.$apply(function() {
$rootScope.col = { val: true };
});
expect(element.text()).toContain('Message is set');
}));
it('should use the data attribute when an element directive is used',
inject(function($rootScope, $compile) {
element = $compile('<ng-messages for="col">' +
' <ng-message when="val">Message is set</div>' +
'</ng-messages>')($rootScope);
$rootScope.$digest();
expect(element.text()).not.toContain('Message is set');
$rootScope.$apply(function() {
$rootScope.col = { val: true };
});
expect(element.text()).toContain('Message is set');
}));
they('should render empty when $prop is used as a collection value',
{ 'null': null,
'false': false,
'0': 0,
'[]': [],
'[{}]': [{}],
'': '',
'{ val2 : true }': { val2: true } },
function(prop) {
inject(function($rootScope, $compile) {
element = $compile('<div ng-messages="col">' +
' <div ng-message="val">Message is set</div>' +
'</div>')($rootScope);
$rootScope.$digest();
$rootScope.$apply(function() {
$rootScope.col = prop;
});
expect(element.text()).not.toContain('Message is set');
});
});
they('should insert and remove matching inner elements when $prop is used as a value',
{ 'true': true,
'1': 1,
'{}': {},
'[]': [],
'[null]': [null] },
function(prop) {
inject(function($rootScope, $compile) {
element = $compile('<div ng-messages="col">' +
' <div ng-message="blue">This message is blue</div>' +
' <div ng-message="red">This message is red</div>' +
'</div>')($rootScope);
$rootScope.$apply(function() {
$rootScope.col = {};
});
expect(element.children().length).toBe(0);
expect(trim(element.text())).toEqual('');
$rootScope.$apply(function() {
$rootScope.col = {
blue: true,
red: false
};
});
expect(element.children().length).toBe(1);
expect(trim(element.text())).toEqual('This message is blue');
$rootScope.$apply(function() {
$rootScope.col = {
red: prop
};
});
expect(element.children().length).toBe(1);
expect(trim(element.text())).toEqual('This message is red');
$rootScope.$apply(function() {
$rootScope.col = null;
});
expect(element.children().length).toBe(0);
expect(trim(element.text())).toEqual('');
$rootScope.$apply(function() {
$rootScope.col = {
blue: 0,
red: null
};
});
expect(element.children().length).toBe(0);
expect(trim(element.text())).toEqual('');
});
});
it('should display the elements in the order defined in the DOM',
inject(function($rootScope, $compile) {
element = $compile('<div ng-messages="col">' +
' <div ng-message="one">Message#one</div>' +
' <div ng-message="two">Message#two</div>' +
' <div ng-message="three">Message#three</div>' +
'</div>')($rootScope);
$rootScope.$apply(function() {
$rootScope.col = {
three: true,
one: true,
two: true
};
});
angular.forEach(['one','two','three'], function(key) {
expect(s(element.text())).toEqual('Message#' + key);
$rootScope.$apply(function() {
$rootScope.col[key] = false;
});
});
expect(s(element.text())).toEqual('');
}));
it('should add ng-active/ng-inactive CSS classes to the element when errors are/aren\'t displayed',
inject(function($rootScope, $compile) {
element = $compile('<div ng-messages="col">' +
' <div ng-message="ready">This message is ready</div>' +
'</div>')($rootScope);
$rootScope.$apply(function() {
$rootScope.col = {};
});
expect(element.hasClass('ng-active')).toBe(false);
expect(element.hasClass('ng-inactive')).toBe(true);
$rootScope.$apply(function() {
$rootScope.col = { ready: true };
});
expect(element.hasClass('ng-active')).toBe(true);
expect(element.hasClass('ng-inactive')).toBe(false);
}));
it('should render animations when the active/inactive classes are added/removed', function() {
module('ngAnimate');
module('ngAnimateMock');
inject(function($rootScope, $compile, $animate) {
element = $compile('<div ng-messages="col">' +
' <div ng-message="ready">This message is ready</div>' +
'</div>')($rootScope);
$rootScope.$apply(function() {
$rootScope.col = {};
});
var event = $animate.queue.pop();
expect(event.event).toBe('setClass');
expect(event.args[1]).toBe('ng-inactive');
expect(event.args[2]).toBe('ng-active');
$rootScope.$apply(function() {
$rootScope.col = { ready: true };
});
event = $animate.queue.pop();
expect(event.event).toBe('setClass');
expect(event.args[1]).toBe('ng-active');
expect(event.args[2]).toBe('ng-inactive');
});
});
describe('when including templates', function() {
they('should load a remote template using $prop',
{'<div ng-messages ng-messages-include="...">':
'<div ng-messages="data" ng-messages-include="abc.html"></div>',
'<ng-messages include="...">':
'<ng-messages for="data" include="abc.html"></ng-messages>'},
function(html) {
inject(function($compile, $rootScope, $templateCache) {
$templateCache.put('abc.html', '<div ng-message="a">A</div>' +
'<div ng-message="b">B</div>' +
'<div ng-message="c">C</div>');
element = $compile(html)($rootScope);
$rootScope.$apply(function() {
$rootScope.data = {
'a': 1,
'b': 2,
'c': 3
};
});
expect(element.children().length).toBe(1);
expect(trim(element.text())).toEqual("A");
$rootScope.$apply(function() {
$rootScope.data = {
'c': 3
};
});
expect(element.children().length).toBe(1);
expect(trim(element.text())).toEqual("C");
});
});
it('should cache the template after download',
inject(function($rootScope, $compile, $templateCache, $httpBackend) {
$httpBackend.expect('GET', 'tpl').respond(201, 'abc');
expect($templateCache.get('tpl')).toBeUndefined();
element = $compile('<div ng-messages="data" ng-messages-include="tpl"></div>')($rootScope);
$rootScope.$digest();
$httpBackend.flush();
expect($templateCache.get('tpl')).toBeDefined();
}));
it('should re-render the messages after download without an extra digest',
inject(function($rootScope, $compile, $httpBackend) {
$httpBackend.expect('GET', 'my-messages').respond(201,'<div ng-message="required">You did not enter a value</div>');
element = $compile('<div ng-messages="data" ng-messages-include="my-messages">' +
' <div ng-message="failed">Your value is that of failure</div>' +
'</div>')($rootScope);
$rootScope.data = {
required: true,
failed: true
};
$rootScope.$digest();
expect(element.children().length).toBe(1);
expect(trim(element.text())).toEqual("Your value is that of failure");
$httpBackend.flush();
expect(element.children().length).toBe(1);
expect(trim(element.text())).toEqual("You did not enter a value");
}));
it('should allow for overriding the remote template messages within the element',
inject(function($compile, $rootScope, $templateCache) {
$templateCache.put('abc.html', '<div ng-message="a">A</div>' +
'<div ng-message="b">B</div>' +
'<div ng-message="c">C</div>');
element = $compile('<div ng-messages="data" ng-messages-include="abc.html">' +
' <div ng-message="a">AAA</div>' +
' <div ng-message="c">CCC</div>' +
'</div>')($rootScope);
$rootScope.$apply(function() {
$rootScope.data = {
'a': 1,
'b': 2,
'c': 3
};
});
expect(element.children().length).toBe(1);
expect(trim(element.text())).toEqual("AAA");
$rootScope.$apply(function() {
$rootScope.data = {
'b': 2,
'c': 3
};
});
expect(element.children().length).toBe(1);
expect(trim(element.text())).toEqual("B");
$rootScope.$apply(function() {
$rootScope.data = {
'c': 3
};
});
expect(element.children().length).toBe(1);
expect(trim(element.text())).toEqual("CCC");
}));
it('should retain the order of the remote template\'s messages when overriding within the element',
inject(function($compile, $rootScope, $templateCache) {
$templateCache.put('abc.html', '<div ng-message="c">C</div>' +
'<div ng-message="a">A</div>' +
'<div ng-message="b">B</div>');
element = $compile('<div ng-messages="data" ng-messages-include="abc.html">' +
' <div ng-message="a">AAA</div>' +
' <div ng-message="c">CCC</div>' +
'</div>')($rootScope);
$rootScope.$apply(function() {
$rootScope.data = {
'a': 1,
'b': 2,
'c': 3
};
});
expect(element.children().length).toBe(1);
expect(trim(element.text())).toEqual("CCC");
$rootScope.$apply(function() {
$rootScope.data = {
'a': 1,
'b': 2
};
});
expect(element.children().length).toBe(1);
expect(trim(element.text())).toEqual("AAA");
$rootScope.$apply(function() {
$rootScope.data = {
'b': 3
};
});
expect(element.children().length).toBe(1);
expect(trim(element.text())).toEqual("B");
}));
});
describe('when multiple', function() {
they('should show all truthy messages when the $prop attr is present',
{ 'multiple': 'multiple',
'ng-messages-multiple': 'ng-messages-multiple' },
function(prop) {
inject(function($rootScope, $compile) {
element = $compile('<div ng-messages="data" ' + prop + '>' +
' <div ng-message="one">1</div>' +
' <div ng-message="two">2</div>' +
' <div ng-message="three">3</div>' +
'</div>')($rootScope);
$rootScope.$apply(function() {
$rootScope.data = {
'one': true,
'two': false,
'three': true
};
});
expect(element.children().length).toBe(2);
expect(s(element.text())).toContain("13");
});
});
it('should render all truthy messages from a remote template',
inject(function($rootScope, $compile, $templateCache) {
$templateCache.put('xyz.html', '<div ng-message="x">X</div>' +
'<div ng-message="y">Y</div>' +
'<div ng-message="z">Z</div>');
element = $compile('<div ng-messages="data" ' +
'ng-messages-multiple="true" ' +
'ng-messages-include="xyz.html"></div>')($rootScope);
$rootScope.$apply(function() {
$rootScope.data = {
'x': 'a',
'y': null,
'z': true
};
});
expect(element.children().length).toBe(2);
expect(s(element.text())).toEqual("XZ");
$rootScope.$apply(function() {
$rootScope.data.y = {};
});
expect(element.children().length).toBe(3);
expect(s(element.text())).toEqual("XYZ");
}));
it('should render and override all truthy messages from a remote template',
inject(function($rootScope, $compile, $templateCache) {
$templateCache.put('xyz.html', '<div ng-message="x">X</div>' +
'<div ng-message="y">Y</div>' +
'<div ng-message="z">Z</div>');
element = $compile('<div ng-messages="data" ' +
'ng-messages-multiple="true" ' +
'ng-messages-include="xyz.html">' +
'<div ng-message="y">YYY</div>' +
'<div ng-message="z">ZZZ</div>' +
'</div>')($rootScope);
$rootScope.$apply(function() {
$rootScope.data = {
'x': 'a',
'y': null,
'z': true
};
});
expect(element.children().length).toBe(2);
expect(s(element.text())).toEqual("XZZZ");
$rootScope.$apply(function() {
$rootScope.data.y = {};
});
expect(element.children().length).toBe(3);
expect(s(element.text())).toEqual("XYYYZZZ");
}));
});
});