Skip to content

Commit 6b8878f

Browse files
committed
test(jqLite): test not firing $destroy on jqLite.cleanData with jQuery UI
So far it wasn't tested that Angular's logic for skipping it triggering the $destroy event on jQuery.cleanData in the replaceWith internal function works correctly when Angular is not the last one to patch the cleanData method (e.g. if jQuery UI does the patching later). This commits adds the relevant test. Ref angular#8486
1 parent 38f8c97 commit 6b8878f

File tree

1 file changed

+82
-54
lines changed

1 file changed

+82
-54
lines changed

test/ng/compileSpec.js

+82-54
Original file line numberDiff line numberDiff line change
@@ -2080,17 +2080,47 @@ describe('$compile', function() {
20802080
));
20812081

20822082

2083-
it('should work when directive is in a repeater', inject(
2084-
function($compile, $httpBackend, $rootScope) {
2085-
$httpBackend.expect('GET', 'hello.html').
2083+
describe('when directive is in a repeater', function() {
2084+
var is;
2085+
beforeEach(function() {
2086+
is = [1, 2];
2087+
});
2088+
2089+
function runTest() {
2090+
inject(function($compile, $httpBackend, $rootScope) {
2091+
$httpBackend.expect('GET', 'hello.html').
20862092
respond('<span>i=<span ng-transclude></span>;</span>');
2087-
element = jqLite('<div><b class=hello ng-repeat="i in [1,2]">{{i}}</b></div>');
2088-
$compile(element)($rootScope);
2093+
element = jqLite('<div><b class=hello ng-repeat="i in [' + is + ']">{{i}}</b></div>');
2094+
$compile(element)($rootScope);
20892095

2090-
$httpBackend.flush();
2091-
expect(element.text()).toEqual('i=1;i=2;');
2096+
$httpBackend.flush();
2097+
expect(element.text()).toEqual('i=' + is.join(';i=') + ';');
2098+
});
20922099
}
2093-
));
2100+
2101+
it('should work in jqLite and jQuery with jQuery.cleanData last patched by Angular', runTest);
2102+
2103+
it('should work with another library patching jqLite/jQuery.cleanData after Angular', function() {
2104+
var cleanedCount = 0;
2105+
var currentCleanData = jqLite.cleanData;
2106+
jqLite.cleanData = function(elems) {
2107+
cleanedCount += elems.length;
2108+
// Don't return the output and explicitly pass only the first parameter
2109+
// so that we're sure we're not relying on either of them. jQuery UI patch
2110+
// behaves in this way.
2111+
currentCleanData(elems);
2112+
};
2113+
2114+
runTest();
2115+
2116+
// The initial ng-repeat div is dumped after parsing hence we expect cleanData
2117+
// count to be one larger than size of the iterated array.
2118+
expect(cleanedCount).toBe(is.length + 1);
2119+
2120+
// Restore the previous cleanData.
2121+
jqLite.cleanData = currentCleanData;
2122+
});
2123+
});
20942124

20952125
describe('replace and not exactly one root element', function() {
20962126

@@ -8573,64 +8603,62 @@ describe('$compile', function() {
85738603
});
85748604
});
85758605

8576-
if (jQuery) {
8577-
describe('cleaning up after a replaced element', function() {
8578-
var $compile, xs;
8579-
beforeEach(inject(function(_$compile_) {
8580-
$compile = _$compile_;
8581-
xs = [0, 1];
8582-
}));
8583-
8584-
function testCleanup() {
8585-
var privateData, firstRepeatedElem;
8606+
describe('cleaning up after a replaced element', function() {
8607+
var $compile, xs;
8608+
beforeEach(inject(function(_$compile_) {
8609+
$compile = _$compile_;
8610+
xs = [0, 1];
8611+
}));
85868612

8587-
element = $compile('<div><div ng-repeat="x in xs" ng-click="noop()">{{x}}</div></div>')($rootScope);
8613+
function testCleanup() {
8614+
var privateData, firstRepeatedElem;
85888615

8589-
$rootScope.$apply('xs = [' + xs + ']');
8590-
firstRepeatedElem = element.children('.ng-scope').eq(0);
8616+
element = $compile('<div><div ng-repeat="x in xs" ng-click="noop()">{{x}}</div></div>')($rootScope);
85918617

8592-
expect(firstRepeatedElem.data('$scope')).toBeDefined();
8593-
privateData = jQuery._data(firstRepeatedElem[0]);
8594-
expect(privateData.events).toBeDefined();
8595-
expect(privateData.events.click).toBeDefined();
8596-
expect(privateData.events.click[0]).toBeDefined();
8618+
$rootScope.$apply('xs = [' + xs + ']');
8619+
firstRepeatedElem = element.children('.ng-scope').eq(0);
85978620

8598-
//Ensure the AngularJS $destroy event is still sent
8599-
var destroyCount = 0;
8600-
element.find('div').on('$destroy', function() { destroyCount++; });
8621+
expect(firstRepeatedElem.data('$scope')).toBeDefined();
8622+
privateData = jQuery._data(firstRepeatedElem[0]);
8623+
expect(privateData.events).toBeDefined();
8624+
expect(privateData.events.click).toBeDefined();
8625+
expect(privateData.events.click[0]).toBeDefined();
86018626

8602-
$rootScope.$apply('xs = null');
8627+
//Ensure the AngularJS $destroy event is still sent
8628+
var destroyCount = 0;
8629+
element.find('div').on('$destroy', function() { destroyCount++; });
86038630

8604-
expect(destroyCount).toBe(2);
8605-
expect(firstRepeatedElem.data('$scope')).not.toBeDefined();
8606-
privateData = jQuery._data(firstRepeatedElem[0]);
8607-
expect(privateData && privateData.events).not.toBeDefined();
8608-
}
8631+
$rootScope.$apply('xs = null');
86098632

8610-
it('should work without external libraries (except jQuery)', testCleanup);
8633+
expect(destroyCount).toBe(2);
8634+
expect(firstRepeatedElem.data('$scope')).not.toBeDefined();
8635+
privateData = jQuery._data(firstRepeatedElem[0]);
8636+
expect(privateData && privateData.events).not.toBeDefined();
8637+
}
86118638

8612-
it('should work with another library patching jQuery.cleanData after AngularJS', function() {
8613-
var cleanedCount = 0;
8614-
var currentCleanData = jQuery.cleanData;
8615-
jQuery.cleanData = function(elems) {
8616-
cleanedCount += elems.length;
8617-
// Don't return the output and explicitly pass only the first parameter
8618-
// so that we're sure we're not relying on either of them. jQuery UI patch
8619-
// behaves in this way.
8620-
currentCleanData(elems);
8621-
};
8639+
it('should work without external libraries (except jQuery)', testCleanup);
8640+
8641+
it('should work with another library patching jqLite/jQuery.cleanData after AngularJS', function() {
8642+
var cleanedCount = 0;
8643+
var currentCleanData = jqLite.cleanData;
8644+
jqLite.cleanData = function(elems) {
8645+
cleanedCount += elems.length;
8646+
// Don't return the output and explicitly pass only the first parameter
8647+
// so that we're sure we're not relying on either of them. jQuery UI patch
8648+
// behaves in this way.
8649+
currentCleanData(elems);
8650+
};
86228651

8623-
testCleanup();
8652+
testCleanup();
86248653

8625-
// The ng-repeat template is removed/cleaned (the +1)
8626-
// and each clone of the ng-repeat template is also removed (xs.length)
8627-
expect(cleanedCount).toBe(xs.length + 1);
8654+
// The ng-repeat template is removed/cleaned (the +1)
8655+
// and each clone of the ng-repeat template is also removed (xs.length)
8656+
expect(cleanedCount).toBe(xs.length + 1);
86288657

8629-
// Restore the previous jQuery.cleanData.
8630-
jQuery.cleanData = currentCleanData;
8631-
});
8658+
// Restore the previous cleanData.
8659+
jqLite.cleanData = currentCleanData;
86328660
});
8633-
}
8661+
});
86348662

86358663

86368664
it('should add a $$transcluded property onto the transcluded scope', function() {

0 commit comments

Comments
 (0)