implement phase 5 และ fix bugs

This commit is contained in:
Suphonchai Phoonsawat 2026-08-19 23:06:57 +07:00
parent f4b1c3e14b
commit 1bb850c6b8
40 changed files with 1507 additions and 429 deletions

View file

@ -9,10 +9,28 @@ interface FileMockState {
/** mock Office.context.document.getFileAsync + File.getSliceAsync/closeAsync */
function installOfficeFileMock(
slices: Uint8Array[],
options: { failSliceIndex?: number; failClose?: boolean; sliceDataForm?: "buffer" | "view" } = {}
options: {
failSliceIndex?: number;
failClose?: boolean;
/** รูปร่างของ slice.data ที่ host จริงส่งกลับ — ต่างกันตามแพลตฟอร์ม (Win=ArrayBuffer, Mac=string/array) */
sliceDataForm?: "buffer" | "view" | "array" | "base64";
} = {}
): FileMockState {
const state: FileMockState = { getFileCalls: 0, requestedSlices: [], closeCalls: 0 };
const toSliceData = (bytes: Uint8Array): unknown => {
switch (options.sliceDataForm) {
case "view":
return bytes;
case "array":
return Array.from(bytes);
case "base64":
return Buffer.from(bytes).toString("base64");
default:
return bytes.buffer;
}
};
const file = {
sliceCount: slices.length,
getSliceAsync: (index: number, callback: (result: unknown) => void) => {
@ -20,9 +38,10 @@ function installOfficeFileMock(
if (options.failSliceIndex === index) {
callback({ status: "failed", error: { message: `อ่าน slice ${index} พัง (mock)` } });
} else {
// host จริงอาจส่งมาเป็น ArrayBuffer หรือ view — ทดสอบทั้งคู่
const data = options.sliceDataForm === "view" ? slices[index] : slices[index].buffer;
callback({ status: "succeeded", value: { index, data, size: slices[index].byteLength } });
callback({
status: "succeeded",
value: { index, data: toSliceData(slices[index]), size: slices[index].byteLength },
});
}
},
closeAsync: (callback?: (result: unknown) => void) => {
@ -81,6 +100,26 @@ describe("getCurrentDocumentFile", () => {
expect(state.closeCalls).toBe(1);
});
it("slice มาเป็น byte array ธรรมดา number[] (Word บน Mac) ก็ประกอบได้", async () => {
const state = installOfficeFileMock([bytes(10, 20), bytes(30, 40)], { sliceDataForm: "array" });
const blob = await getCurrentDocumentFile();
expect(blob.size).toBe(4);
expect(state.closeCalls).toBe(1);
});
it("slice มาเป็น base64 string ก็ decode แล้วประกอบได้", async () => {
const state = installOfficeFileMock([bytes(200, 100, 50), bytes(255)], {
sliceDataForm: "base64",
});
const blob = await getCurrentDocumentFile();
expect(blob.size).toBe(4);
expect(state.closeCalls).toBe(1);
});
it("อ่าน slice กลางที่พัง → reject พร้อม error แต่ยังเรียก closeAsync เสมอ", async () => {
const state = installOfficeFileMock([bytes(1), bytes(2), bytes(3)], { failSliceIndex: 1 });