Add tests
This commit is contained in:
41
src/patcher/from-docx.spec.ts
Normal file
41
src/patcher/from-docx.spec.ts
Normal file
@ -0,0 +1,41 @@
|
||||
import { expect } from "chai";
|
||||
import * as sinon from "sinon";
|
||||
import * as JSZip from "jszip";
|
||||
|
||||
import { TextRun } from "@file/paragraph";
|
||||
|
||||
import { patchDocument, PatchType } from "./from-docx";
|
||||
|
||||
describe("from-docx", () => {
|
||||
describe("patchDocument", () => {
|
||||
before(() => {
|
||||
sinon.createStubInstance(JSZip, {});
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
sinon.stub(JSZip, "loadAsync").callsFake(
|
||||
() =>
|
||||
new Promise<JSZip>((resolve) => {
|
||||
const zip = new JSZip();
|
||||
|
||||
zip.file("word/document.xml", `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>`);
|
||||
resolve(zip);
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
after(() => {
|
||||
(JSZip.loadAsync as unknown as sinon.SinonStub).restore();
|
||||
});
|
||||
|
||||
it("should find the index of a run element with a token", async () => {
|
||||
const output = await patchDocument(Buffer.from(""), {
|
||||
patches: {
|
||||
name: {
|
||||
type: PatchType.PARAGRAPH,
|
||||
children: [new TextRun("Sir. "), new TextRun("John Doe"), new TextRun("(The Conqueror)")],
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(output).to.not.be.undefined;
|
||||
});
|
||||
});
|
||||
});
|
@ -55,7 +55,6 @@ const imageReplacer = new ImageReplacer();
|
||||
|
||||
export const patchDocument = async (data: InputDataType, options: PatchDocumentOptions): Promise<Buffer> => {
|
||||
const zipContent = await JSZip.loadAsync(data);
|
||||
|
||||
const contexts = new Map<string, IContext>();
|
||||
const file = {
|
||||
Media: new Media(),
|
||||
|
101
src/patcher/paragraph-split-inject.spec.ts
Normal file
101
src/patcher/paragraph-split-inject.spec.ts
Normal file
@ -0,0 +1,101 @@
|
||||
import { expect } from "chai";
|
||||
|
||||
import { findRunElementIndexWithToken, splitRunElement } from "./paragraph-split-inject";
|
||||
|
||||
describe("paragraph-split-inject", () => {
|
||||
describe("findRunElementIndexWithToken", () => {
|
||||
it("should find the index of a run element with a token", () => {
|
||||
const output = findRunElementIndexWithToken(
|
||||
{
|
||||
name: "w:p",
|
||||
type: "element",
|
||||
elements: [
|
||||
{
|
||||
name: "w:r",
|
||||
type: "element",
|
||||
elements: [
|
||||
{
|
||||
name: "w:t",
|
||||
type: "element",
|
||||
elements: [
|
||||
{
|
||||
type: "text",
|
||||
text: "hello world",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
"hello",
|
||||
);
|
||||
expect(output).to.deep.equal(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("splitRunElement", () => {
|
||||
it("should split a run element", () => {
|
||||
const output = splitRunElement(
|
||||
{
|
||||
name: "w:r",
|
||||
type: "element",
|
||||
elements: [
|
||||
{
|
||||
name: "w:t",
|
||||
type: "element",
|
||||
elements: [
|
||||
{
|
||||
type: "text",
|
||||
text: "hello*world",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
"*",
|
||||
);
|
||||
|
||||
expect(output).to.deep.equal({
|
||||
left: {
|
||||
elements: [
|
||||
{
|
||||
attributes: {
|
||||
"xml:space": "preserve",
|
||||
},
|
||||
elements: [
|
||||
{
|
||||
text: "hello",
|
||||
type: "text",
|
||||
},
|
||||
],
|
||||
name: "w:t",
|
||||
type: "element",
|
||||
},
|
||||
],
|
||||
name: "w:r",
|
||||
type: "element",
|
||||
},
|
||||
right: {
|
||||
elements: [
|
||||
{
|
||||
attributes: {
|
||||
"xml:space": "preserve",
|
||||
},
|
||||
elements: [
|
||||
{
|
||||
text: "world",
|
||||
type: "text",
|
||||
},
|
||||
],
|
||||
name: "w:t",
|
||||
type: "element",
|
||||
},
|
||||
],
|
||||
name: "w:r",
|
||||
type: "element",
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@ -14,7 +14,7 @@ export const findRunElementIndexWithToken = (paragraphElement: Element, token: s
|
||||
}
|
||||
}
|
||||
}
|
||||
// return -1;
|
||||
|
||||
throw new Error("Token not found");
|
||||
};
|
||||
|
||||
|
74
src/patcher/paragraph-token-replacer.spec.ts
Normal file
74
src/patcher/paragraph-token-replacer.spec.ts
Normal file
@ -0,0 +1,74 @@
|
||||
import { expect } from "chai";
|
||||
|
||||
import { replaceTokenInParagraphElement } from "./paragraph-token-replacer";
|
||||
|
||||
describe("paragraph-token-replacer", () => {
|
||||
describe("replaceTokenInParagraphElement", () => {
|
||||
it("should replace token in paragraph", () => {
|
||||
const output = replaceTokenInParagraphElement({
|
||||
paragraphElement: {
|
||||
name: "w:p",
|
||||
elements: [
|
||||
{
|
||||
name: "w:r",
|
||||
elements: [
|
||||
{
|
||||
name: "w:t",
|
||||
elements: [
|
||||
{
|
||||
type: "text",
|
||||
text: "hello",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
renderedParagraph: {
|
||||
index: 0,
|
||||
path: [0],
|
||||
runs: [
|
||||
{
|
||||
end: 4,
|
||||
index: 0,
|
||||
parts: [
|
||||
{
|
||||
end: 4,
|
||||
index: 0,
|
||||
start: 0,
|
||||
text: "hello",
|
||||
},
|
||||
],
|
||||
start: 0,
|
||||
text: "hello",
|
||||
},
|
||||
],
|
||||
text: "hello",
|
||||
},
|
||||
originalText: "hello",
|
||||
replacementText: "world",
|
||||
});
|
||||
|
||||
expect(output).to.deep.equal({
|
||||
elements: [
|
||||
{
|
||||
elements: [
|
||||
{
|
||||
elements: [
|
||||
{
|
||||
text: "world",
|
||||
type: "text",
|
||||
},
|
||||
],
|
||||
name: "w:t",
|
||||
},
|
||||
],
|
||||
name: "w:r",
|
||||
},
|
||||
],
|
||||
name: "w:p",
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
61
src/patcher/relationship-manager.spec.ts
Normal file
61
src/patcher/relationship-manager.spec.ts
Normal file
@ -0,0 +1,61 @@
|
||||
import { TargetModeType } from "@file/relationships/relationship/relationship";
|
||||
import { expect } from "chai";
|
||||
|
||||
import { appendRelationship, getNextRelationshipIndex } from "./relationship-manager";
|
||||
|
||||
describe("relationship-manager", () => {
|
||||
describe("getNextRelationshipIndex", () => {
|
||||
it("should get next relationship index", () => {
|
||||
const output = getNextRelationshipIndex({
|
||||
elements: [
|
||||
{
|
||||
type: "element",
|
||||
name: "Relationships",
|
||||
elements: [
|
||||
{ type: "element", attributes: { Id: "rId1" }, name: "Relationship" },
|
||||
{ type: "element", attributes: { Id: "rId1" }, name: "Relationship" },
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
expect(output).to.deep.equal(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe("appendRelationship", () => {
|
||||
it("should append a relationship", () => {
|
||||
const output = appendRelationship(
|
||||
{
|
||||
elements: [
|
||||
{
|
||||
type: "element",
|
||||
name: "Relationships",
|
||||
elements: [
|
||||
{ type: "element", attributes: { Id: "rId1" }, name: "Relationship" },
|
||||
{ type: "element", attributes: { Id: "rId1" }, name: "Relationship" },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
1,
|
||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
|
||||
"test",
|
||||
TargetModeType.EXTERNAL,
|
||||
);
|
||||
expect(output).to.deep.equal([
|
||||
{ type: "element", attributes: { Id: "rId1" }, name: "Relationship" },
|
||||
{ type: "element", attributes: { Id: "rId1" }, name: "Relationship" },
|
||||
{
|
||||
attributes: {
|
||||
Id: "rId1",
|
||||
Type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
|
||||
TargetMode: TargetModeType.EXTERNAL,
|
||||
Target: "test",
|
||||
},
|
||||
name: "Relationship",
|
||||
type: "element",
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
@ -21,7 +21,7 @@ export const appendRelationship = (
|
||||
type: RelationshipType,
|
||||
target: string,
|
||||
targetMode?: TargetModeType,
|
||||
): void => {
|
||||
): readonly Element[] => {
|
||||
const relationshipElements = getFirstLevelElements(relationships, "Relationships");
|
||||
// eslint-disable-next-line functional/immutable-data
|
||||
relationshipElements.push({
|
||||
@ -34,4 +34,6 @@ export const appendRelationship = (
|
||||
name: "Relationship",
|
||||
type: "element",
|
||||
});
|
||||
|
||||
return relationshipElements;
|
||||
};
|
||||
|
153
src/patcher/replacer.spec.ts
Normal file
153
src/patcher/replacer.spec.ts
Normal file
@ -0,0 +1,153 @@
|
||||
import { IViewWrapper } from "@file/document-wrapper";
|
||||
import { File } from "@file/file";
|
||||
import { TextRun } from "@file/paragraph";
|
||||
import { IContext } from "@file/xml-components";
|
||||
import { expect } from "chai";
|
||||
import * as sinon from "sinon";
|
||||
|
||||
import { PatchType } from "./from-docx";
|
||||
|
||||
import { replacer } from "./replacer";
|
||||
|
||||
const MOCK_JSON = {
|
||||
elements: [
|
||||
{
|
||||
type: "element",
|
||||
name: "w:hdr",
|
||||
attributes: {
|
||||
"xmlns:wpc": "http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas",
|
||||
"xmlns:cx": "http://schemas.microsoft.com/office/drawing/2014/chartex",
|
||||
"xmlns:cx1": "http://schemas.microsoft.com/office/drawing/2015/9/8/chartex",
|
||||
"xmlns:cx2": "http://schemas.microsoft.com/office/drawing/2015/10/21/chartex",
|
||||
"xmlns:cx3": "http://schemas.microsoft.com/office/drawing/2016/5/9/chartex",
|
||||
"xmlns:cx4": "http://schemas.microsoft.com/office/drawing/2016/5/10/chartex",
|
||||
"xmlns:cx5": "http://schemas.microsoft.com/office/drawing/2016/5/11/chartex",
|
||||
"xmlns:cx6": "http://schemas.microsoft.com/office/drawing/2016/5/12/chartex",
|
||||
"xmlns:cx7": "http://schemas.microsoft.com/office/drawing/2016/5/13/chartex",
|
||||
"xmlns:cx8": "http://schemas.microsoft.com/office/drawing/2016/5/14/chartex",
|
||||
"xmlns:mc": "http://schemas.openxmlformats.org/markup-compatibility/2006",
|
||||
"xmlns:aink": "http://schemas.microsoft.com/office/drawing/2016/ink",
|
||||
"xmlns:am3d": "http://schemas.microsoft.com/office/drawing/2017/model3d",
|
||||
"xmlns:o": "urn:schemas-microsoft-com:office:office",
|
||||
"xmlns:oel": "http://schemas.microsoft.com/office/2019/extlst",
|
||||
"xmlns:r": "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
|
||||
"xmlns:m": "http://schemas.openxmlformats.org/officeDocument/2006/math",
|
||||
"xmlns:v": "urn:schemas-microsoft-com:vml",
|
||||
"xmlns:wp14": "http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing",
|
||||
"xmlns:wp": "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing",
|
||||
"xmlns:w10": "urn:schemas-microsoft-com:office:word",
|
||||
"xmlns:w": "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
|
||||
"xmlns:w14": "http://schemas.microsoft.com/office/word/2010/wordml",
|
||||
"xmlns:w15": "http://schemas.microsoft.com/office/word/2012/wordml",
|
||||
"xmlns:w16cex": "http://schemas.microsoft.com/office/word/2018/wordml/cex",
|
||||
"xmlns:w16cid": "http://schemas.microsoft.com/office/word/2016/wordml/cid",
|
||||
"xmlns:w16": "http://schemas.microsoft.com/office/word/2018/wordml",
|
||||
"xmlns:w16sdtdh": "http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash",
|
||||
"xmlns:w16se": "http://schemas.microsoft.com/office/word/2015/wordml/symex",
|
||||
"xmlns:wpg": "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup",
|
||||
"xmlns:wpi": "http://schemas.microsoft.com/office/word/2010/wordprocessingInk",
|
||||
"xmlns:wne": "http://schemas.microsoft.com/office/word/2006/wordml",
|
||||
"xmlns:wps": "http://schemas.microsoft.com/office/word/2010/wordprocessingShape",
|
||||
},
|
||||
elements: [
|
||||
{
|
||||
type: "element",
|
||||
name: "w:p",
|
||||
attributes: { "w14:paraId": "3BE1A671", "w14:textId": "74E856C4", "w:rsidR": "000D38A7", "w:rsidRDefault": "000D38A7" },
|
||||
elements: [
|
||||
{
|
||||
type: "element",
|
||||
name: "w:pPr",
|
||||
elements: [{ type: "element", name: "w:pStyle", attributes: { "w:val": "Header" } }],
|
||||
},
|
||||
{
|
||||
type: "element",
|
||||
name: "w:r",
|
||||
elements: [{ type: "element", name: "w:t", elements: [{ type: "text", text: "This is a {{head" }] }],
|
||||
},
|
||||
{
|
||||
type: "element",
|
||||
name: "w:r",
|
||||
attributes: { "w:rsidR": "004A3A99" },
|
||||
elements: [{ type: "element", name: "w:t", elements: [{ type: "text", text: "er" }] }],
|
||||
},
|
||||
{
|
||||
type: "element",
|
||||
name: "w:r",
|
||||
elements: [
|
||||
{ type: "element", name: "w:t", elements: [{ type: "text", text: "_adjective}} don’t you think?" }] },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
describe("replacer", () => {
|
||||
describe("replacer", () => {
|
||||
it("should return the same object if nothing is added", () => {
|
||||
const output = replacer(
|
||||
{
|
||||
elements: [],
|
||||
},
|
||||
{
|
||||
type: PatchType.PARAGRAPH,
|
||||
children: [],
|
||||
},
|
||||
"hello",
|
||||
[],
|
||||
sinon.mock() as unknown as IContext,
|
||||
);
|
||||
|
||||
expect(output).to.deep.equal({
|
||||
elements: [],
|
||||
});
|
||||
});
|
||||
|
||||
it("should return the same object if nothing is added", () => {
|
||||
const output = replacer(
|
||||
MOCK_JSON,
|
||||
{
|
||||
type: PatchType.PARAGRAPH,
|
||||
children: [new TextRun("Delightful Header")],
|
||||
},
|
||||
"{{header_adjective}}",
|
||||
[
|
||||
{
|
||||
text: "This is a {{header_adjective}} don’t you think?",
|
||||
runs: [
|
||||
{
|
||||
text: "This is a {{head",
|
||||
parts: [{ text: "This is a {{head", index: 0, start: 0, end: 15 }],
|
||||
index: 1,
|
||||
start: 0,
|
||||
end: 15,
|
||||
},
|
||||
{ text: "er", parts: [{ text: "er", index: 0, start: 16, end: 17 }], index: 2, start: 16, end: 17 },
|
||||
{
|
||||
text: "_adjective}} don’t you think?",
|
||||
parts: [{ text: "_adjective}} don’t you think?", index: 0, start: 18, end: 46 }],
|
||||
index: 3,
|
||||
start: 18,
|
||||
end: 46,
|
||||
},
|
||||
],
|
||||
index: 0,
|
||||
path: [0, 0, 0],
|
||||
},
|
||||
],
|
||||
{
|
||||
file: {} as unknown as File,
|
||||
viewWrapper: {
|
||||
Relationships: {},
|
||||
} as unknown as IViewWrapper,
|
||||
stack: [],
|
||||
},
|
||||
);
|
||||
|
||||
expect(JSON.stringify(output)).to.contain("Delightful Header");
|
||||
});
|
||||
});
|
||||
});
|
96
src/patcher/run-renderer.spec.ts
Normal file
96
src/patcher/run-renderer.spec.ts
Normal file
@ -0,0 +1,96 @@
|
||||
import { expect } from "chai";
|
||||
import { renderParagraphNode } from "./run-renderer";
|
||||
|
||||
describe("run-renderer", () => {
|
||||
describe("renderParagraphNode", () => {
|
||||
it("should return a rendered paragraph node if theres no elements", () => {
|
||||
const output = renderParagraphNode({ element: { name: "w:p" }, index: 0, parent: undefined });
|
||||
expect(output).to.deep.equal({
|
||||
index: -1,
|
||||
path: [],
|
||||
runs: [],
|
||||
text: "",
|
||||
});
|
||||
});
|
||||
|
||||
it("should return a rendered paragraph node if there are elements", () => {
|
||||
const output = renderParagraphNode({
|
||||
element: {
|
||||
name: "w:p",
|
||||
elements: [
|
||||
{
|
||||
name: "w:r",
|
||||
elements: [
|
||||
{
|
||||
name: "w:t",
|
||||
elements: [
|
||||
{
|
||||
type: "text",
|
||||
text: "hello",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
index: 0,
|
||||
parent: undefined,
|
||||
});
|
||||
expect(output).to.deep.equal({
|
||||
index: 0,
|
||||
path: [0],
|
||||
runs: [
|
||||
{
|
||||
end: 4,
|
||||
index: 0,
|
||||
parts: [
|
||||
{
|
||||
end: 4,
|
||||
index: 0,
|
||||
start: 0,
|
||||
text: "hello",
|
||||
},
|
||||
],
|
||||
start: 0,
|
||||
text: "hello",
|
||||
},
|
||||
],
|
||||
text: "hello",
|
||||
});
|
||||
});
|
||||
|
||||
it("should throw an error if the element is not a paragraph", () => {
|
||||
expect(() => renderParagraphNode({ element: { name: "w:r" }, index: 0, parent: undefined })).to.throw();
|
||||
});
|
||||
|
||||
it("should return blank defaults if run is empty", () => {
|
||||
const output = renderParagraphNode({
|
||||
element: {
|
||||
name: "w:p",
|
||||
elements: [
|
||||
{
|
||||
name: "w:r",
|
||||
},
|
||||
],
|
||||
},
|
||||
index: 0,
|
||||
parent: undefined,
|
||||
});
|
||||
expect(output).to.deep.equal({
|
||||
index: 0,
|
||||
path: [0],
|
||||
runs: [
|
||||
{
|
||||
end: 0,
|
||||
index: -1,
|
||||
parts: [],
|
||||
start: 0,
|
||||
text: "",
|
||||
},
|
||||
],
|
||||
text: "",
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@ -64,10 +64,6 @@ export const renderParagraphNode = (node: ElementWrapper): IRenderedParagraphNod
|
||||
};
|
||||
|
||||
const renderRunNode = (node: Element, index: number, currentRunStringIndex: number): IRenderedRunNode => {
|
||||
if (node.name !== "w:r") {
|
||||
throw new Error(`Invalid node type: ${node.name}`);
|
||||
}
|
||||
|
||||
if (!node.elements) {
|
||||
return {
|
||||
text: "",
|
||||
|
600
src/patcher/traverser.spec.ts
Normal file
600
src/patcher/traverser.spec.ts
Normal file
@ -0,0 +1,600 @@
|
||||
import { expect } from "chai";
|
||||
|
||||
import { findLocationOfText } from "./traverser";
|
||||
|
||||
const MOCK_JSON = {
|
||||
elements: [
|
||||
{
|
||||
type: "element",
|
||||
name: "w:document",
|
||||
attributes: {
|
||||
"xmlns:wpc": "http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas",
|
||||
"xmlns:cx": "http://schemas.microsoft.com/office/drawing/2014/chartex",
|
||||
"xmlns:cx1": "http://schemas.microsoft.com/office/drawing/2015/9/8/chartex",
|
||||
"xmlns:cx2": "http://schemas.microsoft.com/office/drawing/2015/10/21/chartex",
|
||||
"xmlns:cx3": "http://schemas.microsoft.com/office/drawing/2016/5/9/chartex",
|
||||
"xmlns:cx4": "http://schemas.microsoft.com/office/drawing/2016/5/10/chartex",
|
||||
"xmlns:cx5": "http://schemas.microsoft.com/office/drawing/2016/5/11/chartex",
|
||||
"xmlns:cx6": "http://schemas.microsoft.com/office/drawing/2016/5/12/chartex",
|
||||
"xmlns:cx7": "http://schemas.microsoft.com/office/drawing/2016/5/13/chartex",
|
||||
"xmlns:cx8": "http://schemas.microsoft.com/office/drawing/2016/5/14/chartex",
|
||||
"xmlns:mc": "http://schemas.openxmlformats.org/markup-compatibility/2006",
|
||||
"xmlns:aink": "http://schemas.microsoft.com/office/drawing/2016/ink",
|
||||
"xmlns:am3d": "http://schemas.microsoft.com/office/drawing/2017/model3d",
|
||||
"xmlns:o": "urn:schemas-microsoft-com:office:office",
|
||||
"xmlns:oel": "http://schemas.microsoft.com/office/2019/extlst",
|
||||
"xmlns:r": "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
|
||||
"xmlns:m": "http://schemas.openxmlformats.org/officeDocument/2006/math",
|
||||
"xmlns:v": "urn:schemas-microsoft-com:vml",
|
||||
"xmlns:wp14": "http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing",
|
||||
"xmlns:wp": "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing",
|
||||
"xmlns:w10": "urn:schemas-microsoft-com:office:word",
|
||||
"xmlns:w": "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
|
||||
"xmlns:w14": "http://schemas.microsoft.com/office/word/2010/wordml",
|
||||
"xmlns:w15": "http://schemas.microsoft.com/office/word/2012/wordml",
|
||||
"xmlns:w16cex": "http://schemas.microsoft.com/office/word/2018/wordml/cex",
|
||||
"xmlns:w16cid": "http://schemas.microsoft.com/office/word/2016/wordml/cid",
|
||||
"xmlns:w16": "http://schemas.microsoft.com/office/word/2018/wordml",
|
||||
"xmlns:w16sdtdh": "http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash",
|
||||
"xmlns:w16se": "http://schemas.microsoft.com/office/word/2015/wordml/symex",
|
||||
"xmlns:wpg": "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup",
|
||||
"xmlns:wpi": "http://schemas.microsoft.com/office/word/2010/wordprocessingInk",
|
||||
"xmlns:wne": "http://schemas.microsoft.com/office/word/2006/wordml",
|
||||
"xmlns:wps": "http://schemas.microsoft.com/office/word/2010/wordprocessingShape",
|
||||
"mc:Ignorable": "w14 w15 w16se w16cid w16 w16cex w16sdtdh wp14",
|
||||
},
|
||||
elements: [
|
||||
{
|
||||
type: "element",
|
||||
name: "w:body",
|
||||
elements: [
|
||||
{
|
||||
type: "element",
|
||||
name: "w:p",
|
||||
attributes: {
|
||||
"w14:paraId": "2499FE9F",
|
||||
"w14:textId": "0A3D130F",
|
||||
"w:rsidR": "00B51233",
|
||||
"w:rsidRDefault": "007B52ED",
|
||||
"w:rsidP": "007B52ED",
|
||||
},
|
||||
elements: [
|
||||
{
|
||||
type: "element",
|
||||
name: "w:pPr",
|
||||
elements: [{ type: "element", name: "w:pStyle", attributes: { "w:val": "Title" } }],
|
||||
},
|
||||
{
|
||||
type: "element",
|
||||
name: "w:r",
|
||||
elements: [{ type: "element", name: "w:t", elements: [{ type: "text", text: "Hello World" }] }],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "element",
|
||||
name: "w:p",
|
||||
attributes: {
|
||||
"w14:paraId": "6410D9A0",
|
||||
"w14:textId": "7579AB49",
|
||||
"w:rsidR": "007B52ED",
|
||||
"w:rsidRDefault": "007B52ED",
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "element",
|
||||
name: "w:p",
|
||||
attributes: {
|
||||
"w14:paraId": "57ACF964",
|
||||
"w14:textId": "315D7A05",
|
||||
"w:rsidR": "007B52ED",
|
||||
"w:rsidRDefault": "007B52ED",
|
||||
},
|
||||
elements: [
|
||||
{
|
||||
type: "element",
|
||||
name: "w:r",
|
||||
elements: [{ type: "element", name: "w:t", elements: [{ type: "text", text: "Hello {{name}}," }] }],
|
||||
},
|
||||
{
|
||||
type: "element",
|
||||
name: "w:r",
|
||||
attributes: { "w:rsidR": "008126CB" },
|
||||
elements: [
|
||||
{
|
||||
type: "element",
|
||||
name: "w:t",
|
||||
attributes: { "xml:space": "preserve" },
|
||||
elements: [{ type: "text", text: " how are you?" }],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "element",
|
||||
name: "w:p",
|
||||
attributes: {
|
||||
"w14:paraId": "38C7DF4A",
|
||||
"w14:textId": "66CDEC9A",
|
||||
"w:rsidR": "007B52ED",
|
||||
"w:rsidRDefault": "007B52ED",
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "element",
|
||||
name: "w:p",
|
||||
attributes: {
|
||||
"w14:paraId": "04FABE2B",
|
||||
"w14:textId": "3DACA001",
|
||||
"w:rsidR": "007B52ED",
|
||||
"w:rsidRDefault": "007B52ED",
|
||||
},
|
||||
elements: [
|
||||
{
|
||||
type: "element",
|
||||
name: "w:r",
|
||||
elements: [
|
||||
{ type: "element", name: "w:t", elements: [{ type: "text", text: "{{paragraph_replace}}" }] },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "element",
|
||||
name: "w:p",
|
||||
attributes: {
|
||||
"w14:paraId": "7AD7975D",
|
||||
"w14:textId": "77777777",
|
||||
"w:rsidR": "00EF161F",
|
||||
"w:rsidRDefault": "00EF161F",
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "element",
|
||||
name: "w:p",
|
||||
attributes: {
|
||||
"w14:paraId": "3BD6D75A",
|
||||
"w14:textId": "19AE3121",
|
||||
"w:rsidR": "00EF161F",
|
||||
"w:rsidRDefault": "00EF161F",
|
||||
},
|
||||
elements: [
|
||||
{
|
||||
type: "element",
|
||||
name: "w:r",
|
||||
elements: [{ type: "element", name: "w:t", elements: [{ type: "text", text: "{{table}}" }] }],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "element",
|
||||
name: "w:p",
|
||||
attributes: {
|
||||
"w14:paraId": "76023962",
|
||||
"w14:textId": "4E606AB9",
|
||||
"w:rsidR": "007B52ED",
|
||||
"w:rsidRDefault": "007B52ED",
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "element",
|
||||
name: "w:tbl",
|
||||
elements: [
|
||||
{
|
||||
type: "element",
|
||||
name: "w:tblPr",
|
||||
elements: [
|
||||
{ type: "element", name: "w:tblStyle", attributes: { "w:val": "TableGrid" } },
|
||||
{ type: "element", name: "w:tblW", attributes: { "w:w": "0", "w:type": "auto" } },
|
||||
{
|
||||
type: "element",
|
||||
name: "w:tblLook",
|
||||
attributes: {
|
||||
"w:val": "04A0",
|
||||
"w:firstRow": "1",
|
||||
"w:lastRow": "0",
|
||||
"w:firstColumn": "1",
|
||||
"w:lastColumn": "0",
|
||||
"w:noHBand": "0",
|
||||
"w:noVBand": "1",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "element",
|
||||
name: "w:tblGrid",
|
||||
elements: [
|
||||
{ type: "element", name: "w:gridCol", attributes: { "w:w": "3003" } },
|
||||
{ type: "element", name: "w:gridCol", attributes: { "w:w": "3003" } },
|
||||
{ type: "element", name: "w:gridCol", attributes: { "w:w": "3004" } },
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "element",
|
||||
name: "w:tr",
|
||||
attributes: {
|
||||
"w:rsidR": "00EF161F",
|
||||
"w14:paraId": "1DEC5955",
|
||||
"w14:textId": "77777777",
|
||||
"w:rsidTr": "00EF161F",
|
||||
},
|
||||
elements: [
|
||||
{
|
||||
type: "element",
|
||||
name: "w:tc",
|
||||
elements: [
|
||||
{
|
||||
type: "element",
|
||||
name: "w:tcPr",
|
||||
elements: [
|
||||
{ type: "element", name: "w:tcW", attributes: { "w:w": "3003", "w:type": "dxa" } },
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "element",
|
||||
name: "w:p",
|
||||
attributes: {
|
||||
"w14:paraId": "54DA5587",
|
||||
"w14:textId": "625BAC60",
|
||||
"w:rsidR": "00EF161F",
|
||||
"w:rsidRDefault": "00EF161F",
|
||||
},
|
||||
elements: [
|
||||
{
|
||||
type: "element",
|
||||
name: "w:r",
|
||||
elements: [
|
||||
{
|
||||
type: "element",
|
||||
name: "w:t",
|
||||
elements: [{ type: "text", text: "{{table_heading_1}}" }],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "element",
|
||||
name: "w:tc",
|
||||
elements: [
|
||||
{
|
||||
type: "element",
|
||||
name: "w:tcPr",
|
||||
elements: [
|
||||
{ type: "element", name: "w:tcW", attributes: { "w:w": "3003", "w:type": "dxa" } },
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "element",
|
||||
name: "w:p",
|
||||
attributes: {
|
||||
"w14:paraId": "57100910",
|
||||
"w14:textId": "71FD5616",
|
||||
"w:rsidR": "00EF161F",
|
||||
"w:rsidRDefault": "00EF161F",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "element",
|
||||
name: "w:tc",
|
||||
elements: [
|
||||
{
|
||||
type: "element",
|
||||
name: "w:tcPr",
|
||||
elements: [
|
||||
{ type: "element", name: "w:tcW", attributes: { "w:w": "3004", "w:type": "dxa" } },
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "element",
|
||||
name: "w:p",
|
||||
attributes: {
|
||||
"w14:paraId": "1D388FAB",
|
||||
"w14:textId": "77777777",
|
||||
"w:rsidR": "00EF161F",
|
||||
"w:rsidRDefault": "00EF161F",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "element",
|
||||
name: "w:tr",
|
||||
attributes: {
|
||||
"w:rsidR": "00EF161F",
|
||||
"w14:paraId": "0F53D2DC",
|
||||
"w14:textId": "77777777",
|
||||
"w:rsidTr": "00EF161F",
|
||||
},
|
||||
elements: [
|
||||
{
|
||||
type: "element",
|
||||
name: "w:tc",
|
||||
elements: [
|
||||
{
|
||||
type: "element",
|
||||
name: "w:tcPr",
|
||||
elements: [
|
||||
{ type: "element", name: "w:tcW", attributes: { "w:w": "3003", "w:type": "dxa" } },
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "element",
|
||||
name: "w:p",
|
||||
attributes: {
|
||||
"w14:paraId": "0F2BCCED",
|
||||
"w14:textId": "3C3B6706",
|
||||
"w:rsidR": "00EF161F",
|
||||
"w:rsidRDefault": "00EF161F",
|
||||
},
|
||||
elements: [
|
||||
{
|
||||
type: "element",
|
||||
name: "w:r",
|
||||
elements: [
|
||||
{
|
||||
type: "element",
|
||||
name: "w:t",
|
||||
elements: [{ type: "text", text: "Item: {{item_1}}" }],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "element",
|
||||
name: "w:tc",
|
||||
elements: [
|
||||
{
|
||||
type: "element",
|
||||
name: "w:tcPr",
|
||||
elements: [
|
||||
{ type: "element", name: "w:tcW", attributes: { "w:w": "3003", "w:type": "dxa" } },
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "element",
|
||||
name: "w:p",
|
||||
attributes: {
|
||||
"w14:paraId": "1E6158AC",
|
||||
"w14:textId": "77777777",
|
||||
"w:rsidR": "00EF161F",
|
||||
"w:rsidRDefault": "00EF161F",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "element",
|
||||
name: "w:tc",
|
||||
elements: [
|
||||
{
|
||||
type: "element",
|
||||
name: "w:tcPr",
|
||||
elements: [
|
||||
{ type: "element", name: "w:tcW", attributes: { "w:w": "3004", "w:type": "dxa" } },
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "element",
|
||||
name: "w:p",
|
||||
attributes: {
|
||||
"w14:paraId": "17937748",
|
||||
"w14:textId": "77777777",
|
||||
"w:rsidR": "00EF161F",
|
||||
"w:rsidRDefault": "00EF161F",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "element",
|
||||
name: "w:tr",
|
||||
attributes: {
|
||||
"w:rsidR": "00EF161F",
|
||||
"w14:paraId": "781DAC1A",
|
||||
"w14:textId": "77777777",
|
||||
"w:rsidTr": "00EF161F",
|
||||
},
|
||||
elements: [
|
||||
{
|
||||
type: "element",
|
||||
name: "w:tc",
|
||||
elements: [
|
||||
{
|
||||
type: "element",
|
||||
name: "w:tcPr",
|
||||
elements: [
|
||||
{ type: "element", name: "w:tcW", attributes: { "w:w": "3003", "w:type": "dxa" } },
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "element",
|
||||
name: "w:p",
|
||||
attributes: {
|
||||
"w14:paraId": "1DCD0343",
|
||||
"w14:textId": "77777777",
|
||||
"w:rsidR": "00EF161F",
|
||||
"w:rsidRDefault": "00EF161F",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "element",
|
||||
name: "w:tc",
|
||||
elements: [
|
||||
{
|
||||
type: "element",
|
||||
name: "w:tcPr",
|
||||
elements: [
|
||||
{ type: "element", name: "w:tcW", attributes: { "w:w": "3003", "w:type": "dxa" } },
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "element",
|
||||
name: "w:p",
|
||||
attributes: {
|
||||
"w14:paraId": "5D02E3CD",
|
||||
"w14:textId": "77777777",
|
||||
"w:rsidR": "00EF161F",
|
||||
"w:rsidRDefault": "00EF161F",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "element",
|
||||
name: "w:tc",
|
||||
elements: [
|
||||
{
|
||||
type: "element",
|
||||
name: "w:tcPr",
|
||||
elements: [
|
||||
{ type: "element", name: "w:tcW", attributes: { "w:w": "3004", "w:type": "dxa" } },
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "element",
|
||||
name: "w:p",
|
||||
attributes: {
|
||||
"w14:paraId": "52EA0DBB",
|
||||
"w14:textId": "77777777",
|
||||
"w:rsidR": "00EF161F",
|
||||
"w:rsidRDefault": "00EF161F",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "element",
|
||||
name: "w:p",
|
||||
attributes: {
|
||||
"w14:paraId": "47CD1FBC",
|
||||
"w14:textId": "23474CBC",
|
||||
"w:rsidR": "007B52ED",
|
||||
"w:rsidRDefault": "007B52ED",
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "element",
|
||||
name: "w:p",
|
||||
attributes: {
|
||||
"w14:paraId": "0ACCEE90",
|
||||
"w14:textId": "67907499",
|
||||
"w:rsidR": "00EF161F",
|
||||
"w:rsidRDefault": "0077578F",
|
||||
},
|
||||
elements: [
|
||||
{
|
||||
type: "element",
|
||||
name: "w:r",
|
||||
elements: [{ type: "element", name: "w:t", elements: [{ type: "text", text: "{{image_test}}" }] }],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "element",
|
||||
name: "w:p",
|
||||
attributes: {
|
||||
"w14:paraId": "23FA9862",
|
||||
"w14:textId": "77777777",
|
||||
"w:rsidR": "0077578F",
|
||||
"w:rsidRDefault": "0077578F",
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "element",
|
||||
name: "w:p",
|
||||
attributes: {
|
||||
"w14:paraId": "01578F2F",
|
||||
"w14:textId": "3BDC6C85",
|
||||
"w:rsidR": "007B52ED",
|
||||
"w:rsidRDefault": "007B52ED",
|
||||
},
|
||||
elements: [
|
||||
{
|
||||
type: "element",
|
||||
name: "w:r",
|
||||
elements: [{ type: "element", name: "w:t", elements: [{ type: "text", text: "Thank you" }] }],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "element",
|
||||
name: "w:sectPr",
|
||||
attributes: { "w:rsidR": "007B52ED", "w:rsidSect": "0072043F" },
|
||||
elements: [
|
||||
{ type: "element", name: "w:headerReference", attributes: { "w:type": "default", "r:id": "rId6" } },
|
||||
{ type: "element", name: "w:footerReference", attributes: { "w:type": "default", "r:id": "rId7" } },
|
||||
{ type: "element", name: "w:pgSz", attributes: { "w:w": "11900", "w:h": "16840" } },
|
||||
{
|
||||
type: "element",
|
||||
name: "w:pgMar",
|
||||
attributes: {
|
||||
"w:top": "1440",
|
||||
"w:right": "1440",
|
||||
"w:bottom": "1440",
|
||||
"w:left": "1440",
|
||||
"w:header": "708",
|
||||
"w:footer": "708",
|
||||
"w:gutter": "0",
|
||||
},
|
||||
},
|
||||
{ type: "element", name: "w:cols", attributes: { "w:space": "708" } },
|
||||
{ type: "element", name: "w:docGrid", attributes: { "w:linePitch": "360" } },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
describe("traverser", () => {
|
||||
describe("findLocationOfText", () => {
|
||||
it("should find the location of text", () => {
|
||||
const output = findLocationOfText(MOCK_JSON, "{{table_heading_1}}");
|
||||
expect(output).to.deep.equal([
|
||||
{
|
||||
index: 1,
|
||||
path: [0, 0, 0, 8, 2, 0, 1],
|
||||
runs: [
|
||||
{
|
||||
end: 18,
|
||||
index: 0,
|
||||
parts: [
|
||||
{
|
||||
end: 18,
|
||||
index: 0,
|
||||
start: 0,
|
||||
text: "{{table_heading_1}}",
|
||||
},
|
||||
],
|
||||
start: 0,
|
||||
text: "{{table_heading_1}}",
|
||||
},
|
||||
],
|
||||
text: "{{table_heading_1}}",
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
@ -32,14 +32,18 @@ describe("util", () => {
|
||||
|
||||
describe("getFirstLevelElements", () => {
|
||||
it("should return an empty array if no elements are found", () => {
|
||||
const output = toJson("<Relationships></Relationships>");
|
||||
const elements = getFirstLevelElements(output, "Relationships");
|
||||
const elements = getFirstLevelElements(
|
||||
{ elements: [{ type: "element", name: "Relationships", elements: [] }] },
|
||||
"Relationships",
|
||||
);
|
||||
expect(elements).to.deep.equal([]);
|
||||
});
|
||||
|
||||
it("should return an array if elements are found", () => {
|
||||
const output = toJson("<Relationships><Relationship></Relationship></Relationships>");
|
||||
const elements = getFirstLevelElements(output, "Relationships");
|
||||
const elements = getFirstLevelElements(
|
||||
{ elements: [{ type: "element", name: "Relationships", elements: [{ type: "element", name: "Relationship" }] }] },
|
||||
"Relationships",
|
||||
);
|
||||
expect(elements).to.deep.equal([{ type: "element", name: "Relationship" }]);
|
||||
});
|
||||
});
|
||||
|
Reference in New Issue
Block a user