'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('
' +
'
Message is set
' +
'
')($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('' +
' Message is set' +
'')($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('' +
'
Message is set
' +
'
')($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('' +
'
This message is blue
' +
'
This message is red
' +
'
')($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('' +
'
Message#one
' +
'
Message#two
' +
'
Message#three
' +
'
')($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('' +
'
This message is ready
' +
'
')($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('' +
'
This message is ready
' +
'
')($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',
{'':
'
',
'
':
''},
function(html) {
inject(function($compile, $rootScope, $templateCache) {
$templateCache.put('abc.html', 'A
' +
'B
' +
'C
');
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('')($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,'You did not enter a value
');
element = $compile('' +
'
Your value is that of failure
' +
'
')($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', 'A
' +
'B
' +
'C
');
element = $compile('')($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', 'C
' +
'A
' +
'B
');
element = $compile('')($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('' +
'
1
' +
'
2
' +
'
3
' +
'
')($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', 'X
' +
'Y
' +
'Z
');
element = $compile('')($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', 'X
' +
'Y
' +
'Z
');
element = $compile('')($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");
}));
});
});