pull2refresh
Version:
Pull to refresh library
347 lines (288 loc) • 14.6 kB
text/typescript
import { expect } from "chai";
import { DOMWindow, JSDOM, Options, VirtualConsole } from "jsdom";
import "mocha";
import { setTimeout } from "timers";
import PullToRefresh from "../../dist/pull2refresh";
describe("pull2refresh", () => {
let dom: JSDOM;
let window: DOMWindow;
let document: Document;
let onPullRatio: number | null;
let onRefreshCalled: boolean;
let p2r: PullToRefresh | null;
beforeEach((done) => {
onPullRatio = null;
onRefreshCalled = false;
p2r = null;
const virtualConsole = new VirtualConsole().sendTo(console);
const options: Options = {
resources: "usable",
runScripts: "dangerously",
virtualConsole
};
dom = new JSDOM(`
<html>
<body>
<div class="content">
<div class="pulltorefresh" style="display: none; height: 35px;">
</div>
<h1>Pull down to refresh</h1>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
<script type="text/javascript" src="dist/pull2refresh.js"></script>
<script>
var p2r = new pull2refresh({
pullableElement: document.querySelector(".content"),
refreshElement: document.querySelector(".pulltorefresh"),
onRefresh: function() {
window.onRefresh();
},
onPull: function(ratio) {
window.onPull(ratio);
}
});
// Mock because jsdom cannot handle scrolling
p2r.isScrollToTop = function() { return true; };
window.registerP2r(p2r);
window.onLoaded();
</script>
</body>
</html>
`, options);
(global as any).window = window = dom.window;
(global as any).document = document = dom.window.document;
(dom.window as any).onLoaded = () => done();
(dom.window as any).onPull = (ratio: number) => onPullRatio = ratio;
(dom.window as any).onRefresh = () => onRefreshCalled = true;
(dom.window as any).registerP2r = (pullToRefresh: PullToRefresh) => p2r = pullToRefresh;
});
it("should change display property for pulltorefresh element when initialized", () => {
expect((document.querySelector(".pulltorefresh") as HTMLDivElement).style.display).to.be.equal("block");
});
it("should hide the pulltorefresh block when initialized", () => {
// content is on top of the pulltorefresh
expect((document.querySelector(".content") as HTMLDivElement).style.marginTop).to.be.equal("-35px");
});
it("should display the pulltorefresh block when pulling (mouse)", () => {
const startScroll = getRandomInt(1, 100);
const delta = 10;
(document.querySelector(".content") as HTMLDivElement).dispatchEvent(mouseEvent(window, "mousedown", startScroll));
document.dispatchEvent(mouseEvent(window, "mousemove", startScroll + delta));
expect((document.querySelector(".content") as HTMLDivElement).style.marginTop).to.be.equal("-25px");
});
it("should display the pulltorefresh block when pulling (touch)", () => {
const startScroll = getRandomInt(1, 100);
const delta = 10;
(document.querySelector(".content") as HTMLDivElement).dispatchEvent(touchEvent(window, "touchstart", startScroll));
document.dispatchEvent(touchEvent(window, "touchmove", startScroll + delta));
expect((document.querySelector(".content") as HTMLDivElement).style.marginTop).to.be.equal("-25px");
});
it("should call onPull callback when pulling (mouse)", () => {
const startScroll = getRandomInt(1, 100);
const delta = 7;
(document.querySelector(".content") as HTMLDivElement).dispatchEvent(mouseEvent(window, "mousedown", startScroll));
document.dispatchEvent(mouseEvent(window, "mousemove", startScroll + delta));
expect(onPullRatio).to.be.equal(0.2);
});
it("should call onPull callback when pulling (touch)", () => {
const startScroll = getRandomInt(1, 100);
const delta = 7;
(document.querySelector(".content") as HTMLDivElement).dispatchEvent(touchEvent(window, "touchstart", startScroll));
document.dispatchEvent(touchEvent(window, "touchmove", startScroll + delta));
expect(onPullRatio).to.be.equal(0.2);
});
it("should call onRefresh callback when pull is complete (mouse)", () => {
const startScroll = getRandomInt(1, 100);
const delta = 35;
(document.querySelector(".content") as HTMLDivElement).dispatchEvent(mouseEvent(window, "mousedown", startScroll));
document.dispatchEvent(mouseEvent(window, "mousemove", startScroll + delta));
document.dispatchEvent(mouseEvent(window, "mouseup", startScroll + delta));
expect(onRefreshCalled).to.be.equal(true);
});
it("should call onRefresh callback when pull is complete (touch)", () => {
const startScroll = getRandomInt(1, 100);
const delta = 35;
(document.querySelector(".content") as HTMLDivElement).dispatchEvent(touchEvent(window, "touchstart", startScroll));
document.dispatchEvent(touchEvent(window, "touchmove", startScroll + delta));
document.dispatchEvent(touchEvent(window, "touchend", startScroll + delta));
expect(onRefreshCalled).to.be.equal(true);
});
it("should not call onRefresh callback when pull is not complete (mouse)", () => {
const startScroll = getRandomInt(1, 100);
const delta = 30;
(document.querySelector(".content") as HTMLDivElement).dispatchEvent(mouseEvent(window, "mousedown", startScroll));
document.dispatchEvent(mouseEvent(window, "mousemove", startScroll + delta));
document.dispatchEvent(mouseEvent(window, "mouseup", startScroll + delta));
expect(onRefreshCalled).to.be.equal(false);
});
it("should not call onRefresh callback when pull is not complete (touch)", () => {
const startScroll = getRandomInt(1, 100);
const delta = 30;
(document.querySelector(".content") as HTMLDivElement).dispatchEvent(touchEvent(window, "touchstart", startScroll));
document.dispatchEvent(touchEvent(window, "touchmove", startScroll + delta));
document.dispatchEvent(touchEvent(window, "touchend", startScroll + delta));
expect(onRefreshCalled).to.be.equal(false);
});
it("should not be possible to pull again if done() wasn't called (mouse)", () => {
const startScroll = getRandomInt(1, 100);
const delta = 35;
(document.querySelector(".content") as HTMLDivElement).dispatchEvent(mouseEvent(window, "mousedown", startScroll));
document.dispatchEvent(mouseEvent(window, "mousemove", startScroll + delta));
document.dispatchEvent(mouseEvent(window, "mouseup", startScroll + delta));
expect(onRefreshCalled).to.be.equal(true);
// pull again
onPullRatio = null;
onRefreshCalled = false;
(document.querySelector(".content") as HTMLDivElement).dispatchEvent(mouseEvent(window, "mousedown", startScroll));
document.dispatchEvent(mouseEvent(window, "mousemove", startScroll + delta));
document.dispatchEvent(mouseEvent(window, "mouseup", startScroll + delta));
expect(onPullRatio).to.be.equal(null);
expect(onRefreshCalled).to.be.equal(false);
});
it("should not be possible to pull again if done() wasn't called (touch)", () => {
const startScroll = getRandomInt(1, 100);
const delta = 35;
(document.querySelector(".content") as HTMLDivElement).dispatchEvent(touchEvent(window, "touchstart", startScroll));
document.dispatchEvent(touchEvent(window, "touchmove", startScroll + delta));
document.dispatchEvent(touchEvent(window, "touchend", startScroll + delta));
expect(onRefreshCalled).to.be.equal(true);
// pull again
onPullRatio = null;
onRefreshCalled = false;
(document.querySelector(".content") as HTMLDivElement).dispatchEvent(touchEvent(window, "touchstart", startScroll));
document.dispatchEvent(touchEvent(window, "touchmove", startScroll + delta));
document.dispatchEvent(touchEvent(window, "touchend", startScroll + delta));
expect(onPullRatio).to.be.equal(null);
expect(onRefreshCalled).to.be.equal(false);
});
it("should be possible to pull again after done() called (mouse)", () => {
const startScroll = getRandomInt(1, 100);
const delta = 35;
(document.querySelector(".content") as HTMLDivElement).dispatchEvent(mouseEvent(window, "mousedown", startScroll));
document.dispatchEvent(mouseEvent(window, "mousemove", startScroll + delta));
document.dispatchEvent(mouseEvent(window, "mouseup", startScroll + delta));
expect(onRefreshCalled).to.be.equal(true);
// Call done()
if (p2r) {
p2r.done();
}
// pull again
onPullRatio = null;
onRefreshCalled = false;
(document.querySelector(".content") as HTMLDivElement).dispatchEvent(mouseEvent(window, "mousedown", startScroll));
document.dispatchEvent(mouseEvent(window, "mousemove", startScroll + delta));
document.dispatchEvent(mouseEvent(window, "mouseup", startScroll + delta));
expect(onPullRatio).to.be.equal(1);
expect(onRefreshCalled).to.be.equal(true);
});
it("should be possible to pull again after done() called (touch)", () => {
const startScroll = getRandomInt(1, 100);
const delta = 35;
(document.querySelector(".content") as HTMLDivElement).dispatchEvent(touchEvent(window, "touchstart", startScroll));
document.dispatchEvent(touchEvent(window, "touchmove", startScroll + delta));
document.dispatchEvent(touchEvent(window, "touchend", startScroll + delta));
expect(onRefreshCalled).to.be.equal(true);
// Call done()
if (p2r) {
p2r.done();
}
// pull again
onPullRatio = null;
onRefreshCalled = false;
(document.querySelector(".content") as HTMLDivElement).dispatchEvent(touchEvent(window, "touchstart", startScroll));
document.dispatchEvent(touchEvent(window, "touchmove", startScroll + delta));
document.dispatchEvent(touchEvent(window, "touchend", startScroll + delta));
expect(onPullRatio).to.be.equal(1);
expect(onRefreshCalled).to.be.equal(true);
});
it("should not hide the pulltorefresh block after pull ends (mouse)", () => {
const startScroll = getRandomInt(1, 100);
const delta = 35;
(document.querySelector(".content") as HTMLDivElement).dispatchEvent(mouseEvent(window, "mousedown", startScroll));
document.dispatchEvent(mouseEvent(window, "mousemove", startScroll + delta));
document.dispatchEvent(mouseEvent(window, "mouseup", startScroll + delta));
expect((document.querySelector(".content") as HTMLDivElement).style.marginTop).to.be.equal("0px");
});
it("should not hide the pulltorefresh block after pull ends (touch)", () => {
const startScroll = getRandomInt(1, 100);
const delta = 35;
(document.querySelector(".content") as HTMLDivElement).dispatchEvent(touchEvent(window, "touchstart", startScroll));
document.dispatchEvent(touchEvent(window, "touchmove", startScroll + delta));
document.dispatchEvent(touchEvent(window, "touchend", startScroll + delta));
expect((document.querySelector(".content") as HTMLDivElement).style.marginTop).to.be.equal("0px");
});
it("should hide the pulltorefresh block after pull ends and done() is called (mouse)", () => {
const startScroll = getRandomInt(1, 100);
const delta = 35;
(document.querySelector(".content") as HTMLDivElement).dispatchEvent(mouseEvent(window, "mousedown", startScroll));
document.dispatchEvent(mouseEvent(window, "mousemove", startScroll + delta));
document.dispatchEvent(mouseEvent(window, "mouseup", startScroll + delta));
if (p2r) {
p2r.done();
}
expect((document.querySelector(".content") as HTMLDivElement).style.marginTop).to.be.equal("-35px");
});
it("should hide the pulltorefresh block after pull ends and done() is called (touch)", () => {
const startScroll = getRandomInt(1, 100);
const delta = 35;
(document.querySelector(".content") as HTMLDivElement).dispatchEvent(touchEvent(window, "touchstart", startScroll));
document.dispatchEvent(touchEvent(window, "touchmove", startScroll + delta));
document.dispatchEvent(touchEvent(window, "touchend", startScroll + delta));
if (p2r) {
p2r.done();
}
expect((document.querySelector(".content") as HTMLDivElement).style.marginTop).to.be.equal("-35px");
});
it("should hide the pulltorefresh block when pull was not finished (mouse)", () => {
const startScroll = getRandomInt(1, 100);
const delta = 20;
(document.querySelector(".content") as HTMLDivElement).dispatchEvent(mouseEvent(window, "mousedown", startScroll));
document.dispatchEvent(mouseEvent(window, "mousemove", startScroll + delta));
document.dispatchEvent(mouseEvent(window, "mouseup", startScroll + delta));
expect((document.querySelector(".content") as HTMLDivElement).style.marginTop).to.be.equal("-35px");
});
it("should hide the pulltorefresh block when pull was not finished (touch)", () => {
const startScroll = getRandomInt(1, 100);
const delta = 20;
(document.querySelector(".content") as HTMLDivElement).dispatchEvent(touchEvent(window, "touchstart", startScroll));
document.dispatchEvent(touchEvent(window, "touchmove", startScroll + delta));
document.dispatchEvent(touchEvent(window, "touchend", startScroll + delta));
expect((document.querySelector(".content") as HTMLDivElement).style.marginTop).to.be.equal("-35px");
});
});
function getRandomInt(min: number, max: number): number {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function mouseEvent(window: DOMWindow, event: string, y: number): MouseEvent {
const mouse = new window.MouseEvent(event);
(mouse as any).pageY = y;
return mouse;
}
function touchEvent(window: DOMWindow, event: string, y: number): TouchEvent {
const touch = new window.TouchEvent(event);
touch.touches[0] = {
clientX: 0,
clientY: 0,
identifier: 0,
pageX: 0,
pageY: 0,
screenX: 0,
screenY: 0,
target: new window.EventTarget()
};
touch.touches[1] = {
clientX: 0,
clientY: 0,
identifier: 0,
pageX: 0,
pageY: y,
screenX: 0,
screenY: 0,
target: new window.EventTarget()
};
return touch;
}