Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 34f4026

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. (cherry-picked from bf7685a) Ref #8486
1 parent b8c06e3 commit 34f4026

File tree

1 file changed

+83
-51
lines changed

1 file changed

+83
-51
lines changed

test/ng/compileSpec.js

+83-51
Original file line numberDiff line numberDiff line change
@@ -2091,17 +2091,49 @@ describe('$compile', function() {
20912091
));
20922092

20932093

2094-
it('should work when directive is in a repeater', inject(
2095-
function($compile, $httpBackend, $rootScope) {
2096-
$httpBackend.expect('GET', 'hello.html').
2094+
describe('when directive is in a repeater', function() {
2095+
var is;
2096+
beforeEach(function() {
2097+
is = [1, 2];
2098+
});
2099+
2100+
function runTest() {
2101+
inject(function($compile, $httpBackend, $rootScope) {
2102+
$httpBackend.expect('GET', 'hello.html').
20972103
respond('<span>i=<span ng-transclude></span>;</span>');
2098-
element = jqLite('<div><b class=hello ng-repeat="i in [1,2]">{{i}}</b></div>');
2099-
$compile(element)($rootScope);
2104+
element = jqLite('<div><b class=hello ng-repeat="i in [' + is + ']">{{i}}</b></div>');
2105+
$compile(element)($rootScope);
21002106

2101-
$httpBackend.flush();
2102-
expect(element.text()).toEqual('i=1;i=2;');
2107+
$httpBackend.flush();
2108+
expect(element.text()).toEqual('i=' + is.join(';i=') + ';');
2109+
});
21032110
}
2104-
));
2111+
2112+
it('should work in jqLite and jQuery with jQuery.cleanData last patched by Angular', runTest);
2113+
2114+
if (jQuery) {
2115+
it('should work with another library patching jQuery.cleanData after Angular', function() {
2116+
var cleanedCount = 0;
2117+
var currentCleanData = jqLite.cleanData;
2118+
jqLite.cleanData = function(elems) {
2119+
cleanedCount += elems.length;
2120+
// Don't return the output and explicitly pass only the first parameter
2121+
// so that we're sure we're not relying on either of them. jQuery UI patch
2122+
// behaves in this way.
2123+
currentCleanData(elems);
2124+
};
2125+
2126+
runTest();
2127+
2128+
// The initial ng-repeat div is dumped after parsing hence we expect cleanData
2129+
// count to be one larger than size of the iterated array.
2130+
expect(cleanedCount).toBe(is.length + 1);
2131+
2132+
// Restore the previous cleanData.
2133+
jqLite.cleanData = currentCleanData;
2134+
});
2135+
}
2136+
});
21052137

21062138
describe('replace and not exactly one root element', function() {
21072139

@@ -8622,64 +8654,64 @@ describe('$compile', function() {
86228654
});
86238655
});
86248656

8625-
if (jQuery) {
8626-
describe('cleaning up after a replaced element', function() {
8627-
var $compile, xs;
8628-
beforeEach(inject(function(_$compile_) {
8629-
$compile = _$compile_;
8630-
xs = [0, 1];
8631-
}));
86328657

8633-
function testCleanup() {
8634-
var privateData, firstRepeatedElem;
8658+
describe('cleaning up after a replaced element', function() {
8659+
var $compile, xs;
8660+
beforeEach(inject(function(_$compile_) {
8661+
$compile = _$compile_;
8662+
xs = [0, 1];
8663+
}));
86358664

8636-
element = $compile('<div><div ng-repeat="x in xs" ng-click="noop()">{{x}}</div></div>')($rootScope);
8665+
function testCleanup() {
8666+
var privateData, firstRepeatedElem;
86378667

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

8641-
expect(firstRepeatedElem.data('$scope')).toBeDefined();
8642-
privateData = jQuery._data(firstRepeatedElem[0]);
8643-
expect(privateData.events).toBeDefined();
8644-
expect(privateData.events.click).toBeDefined();
8645-
expect(privateData.events.click[0]).toBeDefined();
8670+
$rootScope.$apply('xs = [' + xs + ']');
8671+
firstRepeatedElem = element.children('.ng-scope').eq(0);
86468672

8647-
//Ensure the angular $destroy event is still sent
8648-
var destroyCount = 0;
8649-
element.find('div').on('$destroy', function() { destroyCount++; });
8673+
expect(firstRepeatedElem.data('$scope')).toBeDefined();
8674+
privateData = jqLite._data(firstRepeatedElem[0]);
8675+
expect(privateData.events).toBeDefined();
8676+
expect(privateData.events.click).toBeDefined();
8677+
expect(privateData.events.click[0]).toBeDefined();
86508678

8651-
$rootScope.$apply('xs = null');
8679+
//Ensure the angular $destroy event is still sent
8680+
var destroyCount = 0;
8681+
element.find('div').on('$destroy', function() { destroyCount++; });
86528682

8653-
expect(destroyCount).toBe(2);
8654-
expect(firstRepeatedElem.data('$scope')).not.toBeDefined();
8655-
privateData = jQuery._data(firstRepeatedElem[0]);
8656-
expect(privateData && privateData.events).not.toBeDefined();
8657-
}
8683+
$rootScope.$apply('xs = null');
86588684

8659-
it('should work without external libraries (except jQuery)', testCleanup);
8660-
8661-
it('should work with another library patching jQuery.cleanData after Angular', function() {
8662-
var cleanedCount = 0;
8663-
var currentCleanData = jQuery.cleanData;
8664-
jQuery.cleanData = function(elems) {
8665-
cleanedCount += elems.length;
8666-
// Don't return the output and explicitly pass only the first parameter
8667-
// so that we're sure we're not relying on either of them. jQuery UI patch
8668-
// behaves in this way.
8669-
currentCleanData(elems);
8670-
};
8685+
expect(destroyCount).toBe(2);
8686+
expect(firstRepeatedElem.data('$scope')).not.toBeDefined();
8687+
privateData = jqLite._data(firstRepeatedElem[0]);
8688+
expect(privateData && privateData.events).not.toBeDefined();
8689+
}
8690+
8691+
it('should work without external libraries (except jQuery)', testCleanup);
8692+
8693+
if (jQuery) { it('should work with another library patching jQuery.cleanData after Angular', function() {
8694+
var cleanedCount = 0;
8695+
var currentCleanData = jqLite.cleanData;
8696+
jqLite.cleanData = function(elems) {
8697+
cleanedCount += elems.length;
8698+
// Don't return the output and explicitly pass only the first parameter
8699+
// so that we're sure we're not relying on either of them. jQuery UI patch
8700+
// behaves in this way.
8701+
currentCleanData(elems);
8702+
};
86718703

86728704
testCleanup();
86738705

86748706
// The ng-repeat template is removed/cleaned (the +1)
86758707
// and each clone of the ng-repeat template is also removed (xs.length)
86768708
expect(cleanedCount).toBe(xs.length + 1);
86778709

8678-
// Restore the previous jQuery.cleanData.
8679-
jQuery.cleanData = currentCleanData;
8680-
});
8681-
});
8682-
}
8710+
// Restore the previous cleanData.
8711+
jqLite.cleanData = currentCleanData;
8712+
});
8713+
}
8714+
});
86838715

86848716

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

0 commit comments

Comments
 (0)