mirror of
https://github.com/mozilla/pdf.js.git
synced 2026-06-22 16:05:56 +02:00
Improve the PDFDataRangeTransport unit-tests
- Add a new test using only streaming, since that was missing and the lack of which most likely contributed to previous bugs in the `PDFDataRangeTransport` implementation (see PR 10675 and 20634). - Improve the "ranges and streaming" test, to utilize both ranges *and* streaming properly, since the way it was written seemed somewhat unrealistic given how data will normally arrive when `PDFDataRangeTransport` is being used. - Provide more `initialData`, in relevant tests, since a length smaller than `rangeChunkSize` seem pretty pointless. - Test the `contentDispositionFilename`, and `contentLength`, handling in the `PDFDataRangeTransport` implementation.
This commit is contained in:
parent
218a687a3b
commit
fecb0aab1d
@ -5188,6 +5188,11 @@ have written that much by now. So, here’s to squashing bugs.`);
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("PDFDataRangeTransport", function () {
|
describe("PDFDataRangeTransport", function () {
|
||||||
|
async function streamDelay() {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
setTimeout(resolve, 250);
|
||||||
|
});
|
||||||
|
}
|
||||||
let dataPromise;
|
let dataPromise;
|
||||||
|
|
||||||
beforeAll(function () {
|
beforeAll(function () {
|
||||||
@ -5200,20 +5205,26 @@ have written that much by now. So, here’s to squashing bugs.`);
|
|||||||
dataPromise = null;
|
dataPromise = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should fetch document info and page using ranges", async function () {
|
it("should fetch document info and page using only ranges", async function () {
|
||||||
const initialDataLength = 4000;
|
const initialDataLength = 80000; // Larger than `rangeChunkSize`, since otherwise it's pretty pointless.
|
||||||
const subArrays = [];
|
const subArrays = [];
|
||||||
let initialProgress = null;
|
let initialProgress = null;
|
||||||
let fetches = 0;
|
let fetches = 0;
|
||||||
|
|
||||||
const data = await dataPromise;
|
const data = await dataPromise;
|
||||||
|
const dataLength = data.length;
|
||||||
const initialData = new Uint8Array(data.subarray(0, initialDataLength));
|
const initialData = new Uint8Array(data.subarray(0, initialDataLength));
|
||||||
subArrays.push(initialData);
|
subArrays.push(initialData);
|
||||||
|
|
||||||
const transport = new PDFDataRangeTransport(data.length, initialData);
|
const transport = new PDFDataRangeTransport(
|
||||||
transport.requestDataRange = function (begin, end) {
|
dataLength,
|
||||||
|
initialData,
|
||||||
|
/* progressiveDone = */ undefined,
|
||||||
|
/* contentDispositionFilename = */ "aaa.pdf"
|
||||||
|
);
|
||||||
|
transport.requestDataRange = (begin, end) => {
|
||||||
fetches++;
|
fetches++;
|
||||||
waitSome(function () {
|
waitSome(() => {
|
||||||
const chunk = new Uint8Array(data.subarray(begin, end));
|
const chunk = new Uint8Array(data.subarray(begin, end));
|
||||||
subArrays.push(chunk);
|
subArrays.push(chunk);
|
||||||
|
|
||||||
@ -5221,7 +5232,10 @@ have written that much by now. So, here’s to squashing bugs.`);
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadingTask = getDocument({ range: transport });
|
const loadingTask = getDocument({
|
||||||
|
range: transport,
|
||||||
|
rangeChunkSize: 65536,
|
||||||
|
});
|
||||||
loadingTask.onProgress = evt => {
|
loadingTask.onProgress = evt => {
|
||||||
initialProgress = evt;
|
initialProgress = evt;
|
||||||
loadingTask.onProgress = null;
|
loadingTask.onProgress = null;
|
||||||
@ -5232,13 +5246,176 @@ have written that much by now. So, here’s to squashing bugs.`);
|
|||||||
|
|
||||||
const pdfPage = await pdfDocument.getPage(10);
|
const pdfPage = await pdfDocument.getPage(10);
|
||||||
expect(pdfPage.rotate).toEqual(0);
|
expect(pdfPage.rotate).toEqual(0);
|
||||||
|
|
||||||
|
const { contentDispositionFilename, contentLength } =
|
||||||
|
await pdfDocument.getMetadata();
|
||||||
|
expect(contentDispositionFilename).toEqual("aaa.pdf");
|
||||||
|
expect(contentLength).toEqual(dataLength);
|
||||||
|
|
||||||
|
expect(fetches).toBeGreaterThan(4);
|
||||||
|
|
||||||
|
expect(initialProgress).toEqual({
|
||||||
|
loaded: initialDataLength,
|
||||||
|
total: dataLength,
|
||||||
|
percent: 8,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Check that the TypedArrays were transferred.
|
||||||
|
for (const array of subArrays) {
|
||||||
|
expect(array.length).toEqual(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
await loadingTask.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should fetch document info and page using only streaming", async function () {
|
||||||
|
const initialDataLength = 80000; // Larger than `rangeChunkSize`, since otherwise it's pretty pointless.
|
||||||
|
const subArrays = [];
|
||||||
|
let initialProgress = null;
|
||||||
|
let fetches = 0;
|
||||||
|
|
||||||
|
const data = await dataPromise;
|
||||||
|
const dataLength = data.length;
|
||||||
|
const initialData = new Uint8Array(data.subarray(0, initialDataLength));
|
||||||
|
subArrays.push(initialData);
|
||||||
|
|
||||||
|
const transport = new PDFDataRangeTransport(
|
||||||
|
dataLength,
|
||||||
|
initialData,
|
||||||
|
/* progressiveDone = */ undefined,
|
||||||
|
/* contentDispositionFilename = */ "BBB.PDF"
|
||||||
|
);
|
||||||
|
transport.requestDataRange = (begin, end) => {
|
||||||
|
fetches++; // There should be no range requests, since `disableRange` is used.
|
||||||
|
};
|
||||||
|
async function streamAllData() {
|
||||||
|
const streamChunkSize = 131072;
|
||||||
|
let pos = initialDataLength;
|
||||||
|
|
||||||
|
while (pos < dataLength) {
|
||||||
|
const begin = pos,
|
||||||
|
end = Math.min(pos + streamChunkSize, dataLength);
|
||||||
|
pos = end;
|
||||||
|
|
||||||
|
const chunk = new Uint8Array(data.subarray(begin, end));
|
||||||
|
subArrays.push(chunk);
|
||||||
|
|
||||||
|
transport.onDataProgressiveRead(chunk);
|
||||||
|
await streamDelay();
|
||||||
|
}
|
||||||
|
transport.onDataProgressiveDone();
|
||||||
|
}
|
||||||
|
streamAllData();
|
||||||
|
|
||||||
|
const loadingTask = getDocument({
|
||||||
|
range: transport,
|
||||||
|
rangeChunkSize: 65536,
|
||||||
|
disableRange: true,
|
||||||
|
});
|
||||||
|
loadingTask.onProgress = evt => {
|
||||||
|
initialProgress = evt;
|
||||||
|
loadingTask.onProgress = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const pdfDocument = await loadingTask.promise;
|
||||||
|
expect(pdfDocument.numPages).toEqual(14);
|
||||||
|
|
||||||
|
const pdfPage = await pdfDocument.getPage(10);
|
||||||
|
expect(pdfPage.rotate).toEqual(0);
|
||||||
|
|
||||||
|
const { contentDispositionFilename, contentLength } =
|
||||||
|
await pdfDocument.getMetadata();
|
||||||
|
expect(contentDispositionFilename).toEqual("BBB.PDF");
|
||||||
|
expect(contentLength).toEqual(dataLength);
|
||||||
|
|
||||||
|
expect(fetches).toEqual(0);
|
||||||
|
|
||||||
|
expect(initialProgress.loaded).toBeGreaterThan(initialDataLength);
|
||||||
|
expect(initialProgress.total).toEqual(dataLength);
|
||||||
|
expect(initialProgress.percent).toBeGreaterThan(8);
|
||||||
|
|
||||||
|
// Check that the TypedArrays were transferred.
|
||||||
|
for (const array of subArrays) {
|
||||||
|
expect(array.length).toEqual(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
await loadingTask.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should fetch document info and page using ranges and streaming", async function () {
|
||||||
|
const initialDataLength = 80000; // Larger than `rangeChunkSize`, since otherwise it's pretty pointless.
|
||||||
|
const subArrays = [];
|
||||||
|
let initialProgress = null;
|
||||||
|
let fetches = 0;
|
||||||
|
|
||||||
|
const data = await dataPromise;
|
||||||
|
const dataLength = data.length;
|
||||||
|
const initialData = new Uint8Array(data.subarray(0, initialDataLength));
|
||||||
|
subArrays.push(initialData);
|
||||||
|
|
||||||
|
const transport = new PDFDataRangeTransport(
|
||||||
|
dataLength,
|
||||||
|
initialData,
|
||||||
|
/* progressiveDone = */ undefined,
|
||||||
|
/* contentDispositionFilename = */ ""
|
||||||
|
);
|
||||||
|
transport.requestDataRange = (begin, end) => {
|
||||||
|
fetches++;
|
||||||
|
waitSome(() => {
|
||||||
|
const chunk = new Uint8Array(data.subarray(begin, end));
|
||||||
|
subArrays.push(chunk);
|
||||||
|
|
||||||
|
transport.onDataRange(begin, chunk);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
async function streamPartialData() {
|
||||||
|
const MAX_CHUNKS = 2;
|
||||||
|
let numChunks = 0;
|
||||||
|
const streamChunkSize = 131072;
|
||||||
|
let pos = initialDataLength;
|
||||||
|
|
||||||
|
while (pos < dataLength) {
|
||||||
|
const begin = pos,
|
||||||
|
end = Math.min(pos + streamChunkSize, dataLength);
|
||||||
|
pos = end;
|
||||||
|
|
||||||
|
const chunk = new Uint8Array(data.subarray(begin, end));
|
||||||
|
subArrays.push(chunk);
|
||||||
|
|
||||||
|
transport.onDataProgressiveRead(chunk);
|
||||||
|
if (++numChunks >= MAX_CHUNKS) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
await streamDelay();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
streamPartialData();
|
||||||
|
|
||||||
|
const loadingTask = getDocument({
|
||||||
|
range: transport,
|
||||||
|
rangeChunkSize: 65536,
|
||||||
|
});
|
||||||
|
loadingTask.onProgress = evt => {
|
||||||
|
initialProgress = evt;
|
||||||
|
loadingTask.onProgress = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const pdfDocument = await loadingTask.promise;
|
||||||
|
expect(pdfDocument.numPages).toEqual(14);
|
||||||
|
|
||||||
|
const pdfPage = await pdfDocument.getPage(10);
|
||||||
|
expect(pdfPage.rotate).toEqual(0);
|
||||||
|
|
||||||
|
const { contentDispositionFilename, contentLength } =
|
||||||
|
await pdfDocument.getMetadata();
|
||||||
|
expect(contentDispositionFilename).toEqual(null);
|
||||||
|
expect(contentLength).toEqual(dataLength);
|
||||||
|
|
||||||
expect(fetches).toBeGreaterThan(2);
|
expect(fetches).toBeGreaterThan(2);
|
||||||
|
|
||||||
expect(initialProgress).toEqual({
|
expect(initialProgress.loaded).toBeGreaterThan(initialDataLength);
|
||||||
loaded: initialDataLength,
|
expect(initialProgress.total).toEqual(dataLength);
|
||||||
total: data.length,
|
expect(initialProgress.percent).toBeGreaterThan(8);
|
||||||
percent: 0,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Check that the TypedArrays were transferred.
|
// Check that the TypedArrays were transferred.
|
||||||
for (const array of subArrays) {
|
for (const array of subArrays) {
|
||||||
@ -5248,89 +5425,29 @@ have written that much by now. So, here’s to squashing bugs.`);
|
|||||||
await loadingTask.destroy();
|
await loadingTask.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should fetch document info and page using range and streaming", async function () {
|
it("should fetch document info and page, without ranges, using complete initialData", async function () {
|
||||||
const initialDataLength = 4000;
|
|
||||||
const subArrays = [];
|
|
||||||
let initialProgress = null;
|
|
||||||
let fetches = 0;
|
|
||||||
|
|
||||||
const data = await dataPromise;
|
|
||||||
const initialData = new Uint8Array(data.subarray(0, initialDataLength));
|
|
||||||
subArrays.push(initialData);
|
|
||||||
|
|
||||||
const transport = new PDFDataRangeTransport(data.length, initialData);
|
|
||||||
transport.requestDataRange = function (begin, end) {
|
|
||||||
fetches++;
|
|
||||||
if (fetches === 1) {
|
|
||||||
const chunk = new Uint8Array(data.subarray(initialDataLength));
|
|
||||||
subArrays.push(chunk);
|
|
||||||
|
|
||||||
// Send rest of the data on first range request.
|
|
||||||
transport.onDataProgressiveRead(chunk);
|
|
||||||
}
|
|
||||||
waitSome(function () {
|
|
||||||
const chunk = new Uint8Array(data.subarray(begin, end));
|
|
||||||
subArrays.push(chunk);
|
|
||||||
|
|
||||||
transport.onDataRange(begin, chunk);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const loadingTask = getDocument({ range: transport });
|
|
||||||
loadingTask.onProgress = evt => {
|
|
||||||
initialProgress = evt;
|
|
||||||
loadingTask.onProgress = null;
|
|
||||||
};
|
|
||||||
|
|
||||||
const pdfDocument = await loadingTask.promise;
|
|
||||||
expect(pdfDocument.numPages).toEqual(14);
|
|
||||||
|
|
||||||
const pdfPage = await pdfDocument.getPage(10);
|
|
||||||
expect(pdfPage.rotate).toEqual(0);
|
|
||||||
expect(fetches).toEqual(1);
|
|
||||||
|
|
||||||
expect(initialProgress).toEqual({
|
|
||||||
loaded: initialDataLength,
|
|
||||||
total: data.length,
|
|
||||||
percent: 0,
|
|
||||||
});
|
|
||||||
|
|
||||||
await new Promise(resolve => {
|
|
||||||
waitSome(resolve);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Check that the TypedArrays were transferred.
|
|
||||||
for (const array of subArrays) {
|
|
||||||
expect(array.length).toEqual(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
await loadingTask.destroy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it(
|
|
||||||
"should fetch document info and page, without range, " +
|
|
||||||
"using complete initialData",
|
|
||||||
async function () {
|
|
||||||
const subArrays = [];
|
const subArrays = [];
|
||||||
let initialProgress = null;
|
let initialProgress = null;
|
||||||
let fetches = 0;
|
let fetches = 0;
|
||||||
|
|
||||||
const data = await dataPromise;
|
const data = await dataPromise;
|
||||||
|
const dataLength = data.length;
|
||||||
const initialData = new Uint8Array(data);
|
const initialData = new Uint8Array(data);
|
||||||
subArrays.push(initialData);
|
subArrays.push(initialData);
|
||||||
|
|
||||||
const transport = new PDFDataRangeTransport(
|
const transport = new PDFDataRangeTransport(
|
||||||
data.length,
|
dataLength,
|
||||||
initialData,
|
initialData,
|
||||||
/* progressiveDone = */ true
|
/* progressiveDone = */ true,
|
||||||
|
/* contentDispositionFilename = */ "pdf.txt"
|
||||||
);
|
);
|
||||||
transport.requestDataRange = function (begin, end) {
|
transport.requestDataRange = (begin, end) => {
|
||||||
fetches++;
|
fetches++; // There should be no range requests, since `initialData` is complete.
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadingTask = getDocument({
|
const loadingTask = getDocument({
|
||||||
disableRange: true,
|
|
||||||
range: transport,
|
range: transport,
|
||||||
|
rangeChunkSize: 65536,
|
||||||
});
|
});
|
||||||
loadingTask.onProgress = evt => {
|
loadingTask.onProgress = evt => {
|
||||||
initialProgress = evt;
|
initialProgress = evt;
|
||||||
@ -5342,11 +5459,17 @@ have written that much by now. So, here’s to squashing bugs.`);
|
|||||||
|
|
||||||
const pdfPage = await pdfDocument.getPage(10);
|
const pdfPage = await pdfDocument.getPage(10);
|
||||||
expect(pdfPage.rotate).toEqual(0);
|
expect(pdfPage.rotate).toEqual(0);
|
||||||
|
|
||||||
|
const { contentDispositionFilename, contentLength } =
|
||||||
|
await pdfDocument.getMetadata();
|
||||||
|
expect(contentDispositionFilename).toEqual(null);
|
||||||
|
expect(contentLength).toEqual(dataLength);
|
||||||
|
|
||||||
expect(fetches).toEqual(0);
|
expect(fetches).toEqual(0);
|
||||||
|
|
||||||
expect(initialProgress).toEqual({
|
expect(initialProgress).toEqual({
|
||||||
loaded: data.length,
|
loaded: dataLength,
|
||||||
total: data.length,
|
total: dataLength,
|
||||||
percent: 100,
|
percent: 100,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -5356,8 +5479,7 @@ have written that much by now. So, here’s to squashing bugs.`);
|
|||||||
}
|
}
|
||||||
|
|
||||||
await loadingTask.destroy();
|
await loadingTask.destroy();
|
||||||
}
|
});
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("Annotations", function () {
|
describe("Annotations", function () {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user