'use strict';
describe('compiler', function() {
var compiler, textMmarkup, attrMarkup, directives, widgets, compile, log, $rootScope;
beforeEach(inject(function($provide){
textMmarkup = [];
attrMarkup = [];
widgets = extensionMap({}, 'widget');
directives = {
hello: function(expression, element){
log += "hello ";
return function() {
log += expression;
};
},
observe: function(expression, element){
return function() {
this.$watch(expression, function(scope, val){
if (val)
log += ":" + val;
});
};
}
};
log = "";
$provide.value('$textMarkup', textMmarkup);
$provide.value('$attrMarkup', attrMarkup);
$provide.value('$directive', directives);
$provide.value('$widget', widgets);
}));
it('should not allow compilation of multiple roots', inject(function($rootScope, $compile) {
expect(function() {
$compile('
A
');
}).toThrow("Cannot compile multiple element roots: " + ie("A
"));
function ie(text) {
return msie < 9 ? uppercase(text) : text;
}
}));
it('should recognize a directive', inject(function($rootScope, $compile) {
var e = jqLite('');
directives.directive = function(expression, element){
log += "found";
expect(expression).toEqual("expr");
expect(element).toEqual(e);
return function initFn() {
log += ":init";
};
};
var linkFn = $compile(e);
expect(log).toEqual("found");
linkFn($rootScope);
expect(e.hasClass('ng-directive')).toEqual(true);
expect(log).toEqual("found:init");
}));
it('should recurse to children', inject(function($rootScope, $compile) {
$compile('
')($rootScope);
expect(log).toEqual("hello misko");
}));
it('should observe scope', inject(function($rootScope, $compile) {
$compile('')($rootScope);
expect(log).toEqual("");
$rootScope.$digest();
$rootScope.name = 'misko';
$rootScope.$digest();
$rootScope.$digest();
$rootScope.name = 'adam';
$rootScope.$digest();
$rootScope.$digest();
expect(log).toEqual(":misko:adam");
}));
it('should prevent descend', inject(function($rootScope, $compile) {
directives.stop = function() { this.descend(false); };
$compile('')($rootScope);
expect(log).toEqual("hello misko");
}));
it('should allow creation of templates', inject(function($rootScope, $compile) {
directives.duplicate = function(expr, element){
element.replaceWith(document.createComment("marker"));
element.removeAttr("duplicate");
var linker = this.compile(element);
return function(marker) {
this.$watch('value', function() {
var scope = $rootScope.$new;
linker(scope, noop);
marker.after(scope.$element);
});
};
};
$compile('beforexafter
')($rootScope);
expect(sortedHtml($rootScope.$element)).
toEqual('' +
'before<#comment>#comment>' +
'after' +
'
');
$rootScope.value = 1;
$rootScope.$digest();
expect(sortedHtml($rootScope.$element)).
toEqual('' +
'before<#comment>#comment>' +
'x' +
'after' +
'
');
$rootScope.value = 2;
$rootScope.$digest();
expect(sortedHtml($rootScope.$element)).
toEqual('' +
'before<#comment>#comment>' +
'x' +
'x' +
'after' +
'
');
$rootScope.value = 3;
$rootScope.$digest();
expect(sortedHtml($rootScope.$element)).
toEqual('' +
'before<#comment>#comment>' +
'x' +
'x' +
'x' +
'after' +
'
');
}));
it('should process markup before directives', inject(function($rootScope, $compile) {
textMmarkup.push(function(text, textNode, parentNode) {
if (text == 'middle') {
expect(textNode.text()).toEqual(text);
parentNode.attr('hello', text);
textNode[0].nodeValue = 'replaced';
}
});
$compile('beforemiddleafter
')($rootScope);
expect(sortedHtml($rootScope.$element[0], true)).
toEqual('beforereplacedafter
');
expect(log).toEqual("hello middle");
}));
it('should replace widgets', inject(function($rootScope, $compile) {
widgets['NG:BUTTON'] = function(element) {
expect(element.hasClass('ng-widget')).toEqual(true);
element.replaceWith('button
');
return function(element) {
log += 'init';
};
};
$compile('push me
')($rootScope);
expect(lowercase($rootScope.$element[0].innerHTML)).toEqual('button
');
expect(log).toEqual('init');
}));
it('should use the replaced element after calling widget', inject(function($rootScope, $compile) {
widgets['H1'] = function(element) {
// HTML elements which are augmented by acting as widgets, should not be marked as so
expect(element.hasClass('ng-widget')).toEqual(false);
var span = angular.element('{{1+2}}');
element.replaceWith(span);
this.descend(true);
this.directives(true);
return noop;
};
textMmarkup.push(function(text, textNode, parent){
if (text == '{{1+2}}')
parent.text('3');
});
$compile('ignore me
')($rootScope);
expect($rootScope.$element.text()).toEqual('3');
}));
it('should allow multiple markups per text element', inject(function($rootScope, $compile) {
textMmarkup.push(function(text, textNode, parent){
var index = text.indexOf('---');
if (index > -1) {
textNode.after(text.substring(index + 3));
textNode.after("
");
textNode.after(text.substring(0, index));
textNode.remove();
}
});
textMmarkup.push(function(text, textNode, parent){
var index = text.indexOf('===');
if (index > -1) {
textNode.after(text.substring(index + 3));
textNode.after("");
textNode.after(text.substring(0, index));
textNode.remove();
}
});
$compile('
A---B---C===D
')($rootScope);
expect(sortedHtml($rootScope.$element)).toEqual('');
}));
it('should add class for namespace elements', inject(function($rootScope, $compile) {
var element = $compile('abc')($rootScope);
expect(element.hasClass('ng-space')).toEqual(true);
}));
});