Fix tests and use proper types for disregarding XMLComponent

This commit is contained in:
Dolan
2018-09-20 00:41:57 +01:00
parent fc71ebdfef
commit f2b50478bf
14 changed files with 68 additions and 44 deletions

View File

@ -2,6 +2,12 @@ import { BaseXmlComponent, IXmlableObject } from "file/xml-components";
export class Formatter {
public format(input: BaseXmlComponent): IXmlableObject {
return input.prepForXml();
const output = input.prepForXml();
if (output) {
return output;
} else {
throw Error("XMLComponent did not format correctly");
}
}
}

View File

@ -35,7 +35,7 @@ export class Body extends XmlComponent {
this.sections.push(new SectionProperties(params));
}
}
public prepForXml(): IXmlableObject {
public prepForXml(): IXmlableObject | undefined {
if (this.sections.length === 1) {
this.root.push(this.sections[0]);
} else if (this.sections.length > 1) {

View File

@ -8,9 +8,7 @@ describe("PageBorders", () => {
describe("#constructor()", () => {
it("should create empty element when no options are passed", () => {
const properties = new PageBorders();
const tree = new Formatter().format(properties);
expect(tree).to.equal("");
expect(() => new Formatter().format(properties)).to.throw();
});
it("should create page borders with some configuration", () => {

View File

@ -98,7 +98,9 @@ export class PageBorders extends XmlComponent {
}
}
public prepForXml(): IXmlableObject {
return this.root.length > 0 ? super.prepForXml() : "";
public prepForXml(): IXmlableObject | undefined {
if (this.root.length > 0) {
return super.prepForXml();
}
}
}

View File

@ -41,7 +41,7 @@ export class FooterWrapper {
return this.footer.createTable(rows, cols);
}
public addChildElement(childElement: XmlComponent | string): void {
public addChildElement(childElement: XmlComponent): void {
this.footer.addChildElement(childElement);
}

View File

@ -71,7 +71,7 @@ export class Numbering extends XmlComponent {
return num;
}
public prepForXml(): IXmlableObject {
public prepForXml(): IXmlableObject | undefined {
this.abstractNumbering.forEach((x) => this.root.push(x));
this.concreteNumbering.forEach((x) => this.root.push(x));
return super.prepForXml();

View File

@ -21,8 +21,10 @@ export class TableCellMargin extends XmlComponent {
super("w:tblCellMar");
}
public prepForXml(): IXmlableObject {
return this.root.length > 0 ? super.prepForXml() : "";
public prepForXml(): IXmlableObject | undefined {
if (this.root.length > 0) {
return super.prepForXml();
}
}
public addTopMargin(value: number, type: WidthType = WidthType.DXA): void {

View File

@ -8,8 +8,7 @@ describe("TableCellBorders", () => {
describe("#prepForXml", () => {
it("should not add empty borders element if there are no borders defined", () => {
const tb = new TableCellBorders();
const tree = new Formatter().format(tb);
expect(tree).to.deep.equal("");
expect(() => new Formatter().format(tb)).to.throw();
});
});

View File

@ -29,8 +29,10 @@ export class TableCellBorders extends XmlComponent {
super("w:tcBorders");
}
public prepForXml(): IXmlableObject {
return this.root.length > 0 ? super.prepForXml() : "";
public prepForXml(): IXmlableObject | undefined {
if (this.root.length > 0) {
return super.prepForXml();
}
}
public addTopBorder(style: BorderStyle, size: number, color: string): TableCellBorders {

View File

@ -126,9 +126,13 @@ export class TableCell extends XmlComponent {
return this;
}
public prepForXml(): IXmlableObject {
public prepForXml(): IXmlableObject | undefined {
// Cells must end with a paragraph
const retval = super.prepForXml();
if (!retval) {
return undefined;
}
const content = retval["w:tc"];
if (!content[content.length - 1]["w:p"]) {
content.push(new Paragraph().prepForXml());

View File

@ -8,7 +8,7 @@ export abstract class BaseXmlComponent {
this.rootKey = rootKey;
}
public abstract prepForXml(): IXmlableObject;
public abstract prepForXml(): IXmlableObject | undefined;
public get IsDeleted(): boolean {
return this.deleted;

View File

@ -1,7 +1,7 @@
/* tslint:disable */
import { XmlComponent, IXmlableObject } from ".";
// tslint:disable:no-any
import * as fastXmlParser from "fast-xml-parser";
import { flatMap } from "lodash";
import { IXmlableObject, XmlComponent } from ".";
export const parseOptions = {
ignoreAttributes: false,
@ -54,8 +54,27 @@ export function convertToXmlComponent(elementName: string, element: any): Import
* Represents imported xml component from xml file.
*/
export class ImportedXmlComponent extends XmlComponent {
private _attr: any;
/**
* Converts the xml string to a XmlComponent tree.
*
* @param importedContent xml content of the imported component
*/
public static fromXmlString(importedContent: string): ImportedXmlComponent {
const imported = fastXmlParser.parse(importedContent, parseOptions);
const elementName = Object.keys(imported)[0];
const converted = convertToXmlComponent(elementName, imported[elementName]);
if (Array.isArray(converted) && converted.length > 1) {
throw new Error("Invalid conversion, input must be one element.");
}
return Array.isArray(converted) ? converted[0] : converted;
}
// tslint:disable-next-line:variable-name
private readonly _attr: any;
// tslint:disable-next-line:variable-name
constructor(rootKey: string, _attr?: any) {
super(rootKey);
if (_attr) {
@ -89,8 +108,12 @@ export class ImportedXmlComponent extends XmlComponent {
* ]
* }
*/
prepForXml(): IXmlableObject {
public prepForXml(): IXmlableObject | undefined {
const result = super.prepForXml();
if (!result) {
return undefined;
}
if (!!this._attr) {
if (!Array.isArray(result[this.rootKey])) {
result[this.rootKey] = [result[this.rootKey]];
@ -100,33 +123,17 @@ export class ImportedXmlComponent extends XmlComponent {
return result;
}
push(xmlComponent: XmlComponent) {
public push(xmlComponent: XmlComponent): void {
this.root.push(xmlComponent);
}
/**
* Converts the xml string to a XmlComponent tree.
*
* @param importedContent xml content of the imported component
*/
static fromXmlString(importedContent: string): ImportedXmlComponent {
const imported = fastXmlParser.parse(importedContent, parseOptions);
const elementName = Object.keys(imported)[0];
const converted = convertToXmlComponent(elementName, imported[elementName]);
if (Array.isArray(converted) && converted.length > 1) {
throw new Error("Invalid conversion, input must be one element.");
}
return Array.isArray(converted) ? converted[0] : converted;
}
}
/**
* Used for the attributes of root element that is being imported.
*/
export class ImportedRootElementAttributes extends XmlComponent {
constructor(private _attr: any) {
// tslint:disable-next-line:variable-name
constructor(private readonly _attr: any) {
super("");
}

View File

@ -26,6 +26,11 @@ describe("XmlComponent", () => {
xmlComponent.addChildElement(child);
const xml = xmlComponent.prepForXml();
if (!xml) {
return;
}
assert.equal(xml["w:test"].length, 0);
});
});

View File

@ -7,10 +7,10 @@ export abstract class XmlComponent extends BaseXmlComponent {
constructor(rootKey: string) {
super(rootKey);
this.root = new Array<BaseXmlComponent>();
this.root = new Array<BaseXmlComponent | string>();
}
public prepForXml(): IXmlableObject {
public prepForXml(): IXmlableObject | undefined {
const children = this.root
.filter((c) => {
if (c instanceof BaseXmlComponent) {
@ -24,13 +24,12 @@ export abstract class XmlComponent extends BaseXmlComponent {
}
return comp;
})
.filter((comp) => comp); // Exclude null, undefined, and empty strings
.filter((comp) => comp !== undefined); // Exclude undefined
return {
[this.rootKey]: children,
};
}
// TODO: Unused method
public addChildElement(child: XmlComponent | string): XmlComponent {
this.root.push(child);