angular.js/test/testabilityPatch.js

248 lines
6.7 KiB
JavaScript
Raw Normal View History

'use strict';
/**
* Here is the problem: http://bugs.jquery.com/ticket/7292
* basically jQuery treats change event on some browsers (IE) as a
* special event and changes it form 'change' to 'click/keydown' and
* few others. This horrible hack removes the special treatment
*/
_jQuery.event.special.change = undefined;
bindJQuery();
beforeEach(function() {
publishExternalAPI(angular);
// workaround for IE bug https://plus.google.com/104744871076396904202/posts/Kqjuj6RSbbT
// IE overwrite window.jQuery with undefined because of empty jQuery var statement, so we have to
// correct this, but only if we are not running in jqLite mode
if (!_jqLiteMode && _jQuery !== jQuery) {
jQuery = _jQuery;
}
2011-09-08 20:56:29 +00:00
// This resets global id counter;
uid = ['0', '0', '0'];
// reset to jQuery or default to us.
bindJQuery();
jqLite(document.body).html('');
});
afterEach(function() {
if (this.$injector) {
var $rootScope = this.$injector.get('$rootScope');
var $log = this.$injector.get('$log');
// release the injector
dealoc($rootScope);
// check $log mock
$log.assertEmpty && $log.assertEmpty();
}
// complain about uncleared jqCache references
var count = 0;
// This line should be enabled as soon as this bug is fixed: http://bugs.jquery.com/ticket/11775
//var cache = jqLite.cache;
var cache = JQLite.cache;
forEachSorted(cache, function(expando, key){
forEach(expando.data, function(value, key){
count ++;
if (value.$element) {
dump('LEAK', key, value.$id, sortedHtml(value.$element));
} else {
dump('LEAK', key, toJson(value));
}
});
});
if (count) {
throw new Error('Found jqCache references that were not deallocated! count: ' + count);
}
});
2010-01-06 00:36:58 +00:00
2010-03-30 21:55:04 +00:00
function dealoc(obj) {
var jqCache = jqLite.cache;
if (obj) {
if (isElement(obj)) {
cleanup(jqLite(obj));
} else {
for(var key in jqCache) {
var value = jqCache[key];
if (value.data && value.data.$scope == obj) {
delete jqCache[key];
}
}
}
}
function cleanup(element) {
element.unbind().removeData();
for ( var i = 0, children = element.contents() || []; i < children.length; i++) {
cleanup(jqLite(children[i]));
}
}
}
/**
* @param {DOMElement} element
* @param {boolean=} showNgClass
*/
function sortedHtml(element, showNgClass) {
2010-01-06 00:36:58 +00:00
var html = "";
forEach(jqLite(element), function toString(node) {
2010-01-06 00:36:58 +00:00
if (node.nodeName == "#text") {
html += node.nodeValue.
replace(/&(\w+[&;\W])?/g, function(match, entity){return entity?match:'&amp;';}).
replace(/</g, '&lt;').
replace(/>/g, '&gt;');
2010-01-06 00:36:58 +00:00
} else {
html += '<' + (node.nodeName || '?NOT_A_NODE?').toLowerCase();
2010-01-06 00:36:58 +00:00
var attributes = node.attributes || [];
var attrs = [];
var className = node.className || '';
if (!showNgClass) {
className = className.replace(/ng-[\w-]+\s*/g, '');
}
className = trim(className);
if (className) {
attrs.push(' class="' + className + '"');
}
2010-01-06 00:36:58 +00:00
for(var i=0; i<attributes.length; i++) {
if (i>0 && attributes[i] == attributes[i-1])
continue; //IE9 creates dupes. Ignore them!
2010-01-06 00:36:58 +00:00
var attr = attributes[i];
2012-03-09 08:00:05 +00:00
if(attr.name.match(/^ng[\:\-]/) ||
2010-01-06 00:36:58 +00:00
attr.value &&
attr.value !='null' &&
attr.value !='auto' &&
attr.value !='false' &&
attr.value !='inherit' &&
2011-04-19 23:34:49 +00:00
(attr.value !='0' || attr.name =='value') &&
2010-01-06 00:36:58 +00:00
attr.name !='loop' &&
2010-04-21 19:50:05 +00:00
attr.name !='complete' &&
2010-01-06 00:36:58 +00:00
attr.name !='maxLength' &&
attr.name !='size' &&
2010-07-23 20:54:12 +00:00
attr.name !='class' &&
2010-01-06 00:36:58 +00:00
attr.name !='start' &&
attr.name !='tabIndex' &&
attr.name !='style' &&
2010-01-06 00:36:58 +00:00
attr.name.substr(0, 6) != 'jQuery') {
// in IE we need to check for all of these.
if (!/ng-\d+/.exec(attr.name) &&
attr.name != 'getElementById' &&
// IE7 has `selected` in attributes
attr.name !='selected' &&
// IE7 adds `value` attribute to all LI tags
(node.nodeName != 'LI' || attr.name != 'value'))
2010-04-21 19:50:05 +00:00
attrs.push(' ' + attr.name + '="' + attr.value + '"');
2010-01-06 00:36:58 +00:00
}
}
attrs.sort();
html += attrs.join('');
2010-04-15 21:17:33 +00:00
if (node.style) {
var style = [];
if (node.style.cssText) {
forEach(node.style.cssText.split(';'), function(value){
2010-04-15 21:17:33 +00:00
value = trim(value);
if (value) {
2010-04-21 19:50:05 +00:00
style.push(lowercase(value));
2010-04-15 21:17:33 +00:00
}
});
}
for(var css in node.style){
var value = node.style[css];
if (isString(value) && isString(css) && css != 'cssText' && value && (1*css != css)) {
2010-04-21 19:50:05 +00:00
var text = lowercase(css + ': ' + value);
2010-04-19 21:36:41 +00:00
if (value != 'false' && indexOf(style, text) == -1) {
2010-04-15 21:17:33 +00:00
style.push(text);
}
}
2010-04-19 21:41:36 +00:00
}
2010-04-13 02:16:30 +00:00
style.sort();
2010-04-22 22:50:20 +00:00
var tmp = style;
style = [];
forEach(tmp, function(value){
2010-04-22 22:50:20 +00:00
if (!value.match(/^max[^\-]/))
style.push(value);
});
2010-04-15 21:17:33 +00:00
if (style.length) {
html += ' style="' + style.join('; ') + ';"';
}
}
2010-01-06 00:36:58 +00:00
html += '>';
var children = node.childNodes;
for(var j=0; j<children.length; j++) {
toString(children[j]);
2010-01-06 00:36:58 +00:00
}
html += '</' + node.nodeName.toLowerCase() + '>';
}
});
2010-01-06 00:36:58 +00:00
return html;
2010-04-04 00:04:36 +00:00
}
2010-01-06 00:36:58 +00:00
// TODO(vojta): migrate these helpers into jasmine matchers
/**a
* This method is a cheap way of testing if css for a given node is not set to 'none'. It doesn't
* actually test if an element is displayed by the browser. Be aware!!!
*/
2010-04-08 20:43:40 +00:00
function isCssVisible(node) {
2010-03-31 20:57:25 +00:00
var display = node.css('display');
return display != 'none';
}
2010-01-06 00:36:58 +00:00
function assertHidden(node) {
if (isCssVisible(node)) {
throw new Error('Node should be hidden but was visible: ' + angular.module.ngMock.dump(node));
}
2010-01-06 00:36:58 +00:00
}
function assertVisible(node) {
if (!isCssVisible(node)) {
throw new Error('Node should be visible but was hidden: ' + angular.module.ngMock.dump(node));
}
2010-01-06 00:36:58 +00:00
}
function provideLog($provide) {
$provide.factory('log', function() {
var messages = [];
function log(msg) {
messages.push(msg);
return msg;
}
log.toString = function() {
return messages.join('; ');
}
log.toArray = function() {
return messages;
}
log.reset = function() {
messages = [];
}
log.fn = function(msg) {
return function() {
log(msg);
}
}
log.$$log = true;
return log;
});
}
function pending() {
dump('PENDING');
};
function trace(name) {
dump(new Error(name).stack);
}