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

Commit 5a013dd

Browse files
committed
test($anchorScroll): add tests regarding waiting for readyState === 'complete'
1 parent c10d313 commit 5a013dd

File tree

1 file changed

+107
-2
lines changed

1 file changed

+107
-2
lines changed

test/ng/anchorScrollSpec.js

Lines changed: 107 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
describe('$anchorScroll', function() {
44

55
var elmSpy;
6+
var docSpies;
67
var windowSpies;
78

89
function addElements() {
@@ -69,7 +70,7 @@ describe('$anchorScroll', function() {
6970
return function($window) {
7071
forEach(elmSpy, function(spy, id) {
7172
var count = map[id] || 0;
72-
expect(spy.calls.length).toBe(count);
73+
expect(spy.callCount).toBe(count);
7374
});
7475
expect($window.scrollTo).not.toHaveBeenCalled();
7576
};
@@ -79,17 +80,66 @@ describe('$anchorScroll', function() {
7980
return expectScrollingTo(NaN);
8081
}
8182

83+
function mockDocumentReadyState() {
84+
var docMock = {
85+
readyState: 'mocked',
86+
updateReadyState: function(newState) {
87+
this.readyState = newState;
88+
this.dispatchFakeReadyStateChangeEvent();
89+
}
90+
};
91+
92+
docSpies = {};
93+
var i = 0;
94+
95+
return function($rootScope, $window) {
96+
var propsToMock = ['body', 'documentElement'];
97+
var methodsToMock = [
98+
'getElementById',
99+
'getElementsByName',
100+
'addEventListener',
101+
'removeEventListener'
102+
];
103+
104+
var document_ = $window.document;
105+
106+
propsToMock.forEach(function(prop) {
107+
docMock[prop] = document_[prop];
108+
});
109+
methodsToMock.forEach(function(method) {
110+
docMock[method] = document_[method].bind(document_);
111+
docSpies[method] = spyOn(docMock, method).andCallThrough();
112+
});
113+
114+
docMock.dispatchFakeReadyStateChangeEvent = function() {
115+
var evt = document.createEvent('Event');
116+
evt.initEvent('readystatechange', false, false);
117+
document_.dispatchEvent(evt);
118+
$rootScope.$digest();
119+
};
120+
121+
$window.document = docMock;
122+
};
123+
}
124+
82125
function resetAllSpies() {
83126
function resetSpy(spy) {
84127
spy.reset();
85128
}
86129

87130
return function($window) {
88131
forEach(elmSpy, resetSpy);
132+
forEach(docSpies, resetSpy);
89133
forEach(windowSpies, resetSpy);
90134
};
91135
}
92136

137+
function updateMockReadyState(newState) {
138+
return function($window) {
139+
$window.document.updateReadyState(newState);
140+
};
141+
}
142+
93143

94144
beforeEach(module(function($provide) {
95145
elmSpy = {};
@@ -155,6 +205,61 @@ describe('$anchorScroll', function() {
155205
expectScrollingTo('id=top')));
156206

157207

208+
it('should wait for `document.readyState === "complete"', inject(
209+
mockDocumentReadyState(),
210+
addElements('id=some1'),
211+
212+
changeHashTo('some1'),
213+
expectNoScrolling(),
214+
215+
updateMockReadyState('some-arbitrary-state'),
216+
expectNoScrolling(),
217+
218+
updateMockReadyState('complete'),
219+
expectScrollingTo('id=some1')));
220+
221+
222+
it('should only register one execution for when `document.readyState === "complete"', inject(
223+
mockDocumentReadyState(),
224+
addElements('id=some1', 'id=some2'),
225+
226+
changeHashTo('some1'),
227+
changeHashTo('some2'),
228+
updateMockReadyState('some-other-arbitrary-state'),
229+
changeHashTo('some1'),
230+
changeHashTo('some2'),
231+
expectNoScrolling(),
232+
233+
updateMockReadyState('complete'),
234+
expectScrollingTo('id=some2')));
235+
236+
237+
it('should properly register and unregister listeners for `readystatechange` event', inject(
238+
mockDocumentReadyState(),
239+
addElements('id=some1', 'id=some2'),
240+
241+
changeHashTo('some1'),
242+
changeHashTo('some2'),
243+
updateMockReadyState('some-other-arbitrary-state'),
244+
changeHashTo('some1'),
245+
changeHashTo('some2'),
246+
updateMockReadyState('complete'),
247+
248+
function() {
249+
expect(docSpies.addEventListener.callCount).toBe(1);
250+
expect(docSpies.addEventListener).
251+
toHaveBeenCalledWith('readystatechange', jasmine.any(Function));
252+
253+
expect(docSpies.removeEventListener.callCount).toBe(1);
254+
expect(docSpies.removeEventListener).
255+
toHaveBeenCalledWith('readystatechange', jasmine.any(Function));
256+
257+
var registeredListener = docSpies.addEventListener.calls[0].args[1];
258+
var unregisteredListener = docSpies.removeEventListener.calls[0].args[1];
259+
expect(unregisteredListener).toBe(registeredListener);
260+
}));
261+
262+
158263
describe('watcher', function() {
159264

160265
function initAnchorScroll() {
@@ -270,7 +375,7 @@ describe('$anchorScroll', function() {
270375

271376
return function($window) {
272377
expectScrollingTo(identifierCountMap)($window);
273-
expect($window.scrollBy.calls.length).toBe(list.length);
378+
expect($window.scrollBy.callCount).toBe(list.length);
274379
forEach(list, function(offset, idx) {
275380
// Due to sub-pixel rendering, there is a +/-1 error margin in the actual offset
276381
var args = $window.scrollBy.calls[idx].args;

0 commit comments

Comments
 (0)