@ -30,12 +30,8 @@
|
|||||||
"@types/app-root-path": "^1.2.4",
|
"@types/app-root-path": "^1.2.4",
|
||||||
"@types/archiver": "^0.15.37",
|
"@types/archiver": "^0.15.37",
|
||||||
"@types/express": "^4.0.35",
|
"@types/express": "^4.0.35",
|
||||||
"@types/lodash": "^4.14.54",
|
|
||||||
"app-root-path": "^2.0.1",
|
"app-root-path": "^2.0.1",
|
||||||
"archiver": "^1.3.0",
|
"archiver": "^1.3.0",
|
||||||
"install": "^0.8.7",
|
|
||||||
"lodash": "^4.6.1",
|
|
||||||
"npm": "^4.3.0",
|
|
||||||
"xml": "^1.0.1"
|
"xml": "^1.0.1"
|
||||||
},
|
},
|
||||||
"author": "Dolan Miu",
|
"author": "Dolan Miu",
|
||||||
|
@ -26,10 +26,8 @@ interface IDocumentAttributesProperties {
|
|||||||
type?: string;
|
type?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class DocumentAttributes extends XmlAttributeComponent {
|
export class DocumentAttributes extends XmlAttributeComponent<IDocumentAttributesProperties> {
|
||||||
|
protected xmlKeys = {
|
||||||
constructor(properties?: IDocumentAttributesProperties) {
|
|
||||||
super({
|
|
||||||
wpc: "xmlns:wpc",
|
wpc: "xmlns:wpc",
|
||||||
mc: "xmlns:mc",
|
mc: "xmlns:mc",
|
||||||
o: "xmlns:o",
|
o: "xmlns:o",
|
||||||
@ -53,12 +51,5 @@ export class DocumentAttributes extends XmlAttributeComponent {
|
|||||||
dcmitype: "xmlns:dcmitype",
|
dcmitype: "xmlns:dcmitype",
|
||||||
xsi: "xmlns:xsi",
|
xsi: "xmlns:xsi",
|
||||||
type: "xsi:type",
|
type: "xsi:type",
|
||||||
}, properties);
|
};
|
||||||
|
|
||||||
this.root = properties;
|
|
||||||
|
|
||||||
if (!properties) {
|
|
||||||
this.root = {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -33,4 +33,10 @@ export class Document extends XmlComponent {
|
|||||||
public addParagraph(paragraph: Paragraph): void {
|
public addParagraph(paragraph: Paragraph): void {
|
||||||
this.body.push(paragraph);
|
this.body.push(paragraph);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public createParagraph(text?: string): Paragraph {
|
||||||
|
const para = new Paragraph(text);
|
||||||
|
this.addParagraph(para);
|
||||||
|
return para;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,15 @@
|
|||||||
import { XmlAttributeComponent, XmlComponent } from "../xml-components";
|
import { XmlAttributeComponent, XmlComponent } from "../xml-components";
|
||||||
|
|
||||||
interface IndentAttributesProperties {
|
interface IIndentAttributesProperties {
|
||||||
left: number;
|
left?: number;
|
||||||
hanging: number;
|
hanging?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
class IndentAttributes extends XmlAttributeComponent {
|
class IndentAttributes extends XmlAttributeComponent<IIndentAttributesProperties> {
|
||||||
|
protected xmlKeys = {
|
||||||
constructor(properties: IndentAttributesProperties) {
|
|
||||||
super({
|
|
||||||
left: "w:left",
|
left: "w:left",
|
||||||
hanging: "w:hanging",
|
hanging: "w:hanging",
|
||||||
}, properties);
|
};
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Indent extends XmlComponent {
|
export class Indent extends XmlComponent {
|
||||||
|
@ -38,6 +38,12 @@ export class Paragraph extends XmlComponent {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public createTextRun(text: string): TextRun {
|
||||||
|
const run = new TextRun(text);
|
||||||
|
this.addText(run);
|
||||||
|
return run;
|
||||||
|
}
|
||||||
|
|
||||||
public heading1(): Paragraph {
|
public heading1(): Paragraph {
|
||||||
this.properties.push(new Style("Heading1"));
|
this.properties.push(new Style("Heading1"));
|
||||||
return this;
|
return this;
|
||||||
|
@ -6,14 +6,12 @@ export interface ISpacingProperties {
|
|||||||
line?: number;
|
line?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
class SpacingAttributes extends XmlAttributeComponent {
|
class SpacingAttributes extends XmlAttributeComponent<ISpacingProperties> {
|
||||||
constructor(properties: ISpacingProperties) {
|
protected xmlKeys = {
|
||||||
super({
|
|
||||||
after: "w:after",
|
after: "w:after",
|
||||||
before: "w:before",
|
before: "w:before",
|
||||||
line: "w:line",
|
line: "w:line",
|
||||||
}, properties);
|
};
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Spacing extends XmlComponent {
|
export class Spacing extends XmlComponent {
|
||||||
|
@ -6,15 +6,12 @@ interface IRunFontAttributesProperties {
|
|||||||
hint?: string;
|
hint?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
class RunFontAttributes extends XmlAttributeComponent {
|
class RunFontAttributes extends XmlAttributeComponent<IRunFontAttributesProperties> {
|
||||||
|
protected xmlKeys = {
|
||||||
constructor(properties: IRunFontAttributesProperties) {
|
|
||||||
super({
|
|
||||||
ascii: "w:ascii",
|
ascii: "w:ascii",
|
||||||
hAnsi: "w:hAnsi",
|
hAnsi: "w:hAnsi",
|
||||||
hint: "w:hint",
|
hint: "w:hint",
|
||||||
}, properties);
|
};
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class RunFonts extends XmlComponent {
|
export class RunFonts extends XmlComponent {
|
||||||
|
@ -22,10 +22,8 @@ interface IAttributesProperties {
|
|||||||
pos?: string | number; // Little strange. Perhaps it is normal. Need to clarify in the spec.
|
pos?: string | number; // Little strange. Perhaps it is normal. Need to clarify in the spec.
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Attributes extends XmlAttributeComponent {
|
export class Attributes extends XmlAttributeComponent<IAttributesProperties> {
|
||||||
|
protected xmlKeys = {
|
||||||
constructor(properties?: IAttributesProperties) {
|
|
||||||
super({
|
|
||||||
val: "w:val",
|
val: "w:val",
|
||||||
color: "w:color",
|
color: "w:color",
|
||||||
space: "w:space",
|
space: "w:space",
|
||||||
@ -45,6 +43,5 @@ export class Attributes extends XmlAttributeComponent {
|
|||||||
gutter: "w:gutter",
|
gutter: "w:gutter",
|
||||||
linePitch: "w:linePitch",
|
linePitch: "w:linePitch",
|
||||||
pos: "w:pos",
|
pos: "w:pos",
|
||||||
}, properties);
|
};
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,31 +1,25 @@
|
|||||||
import * as _ from "lodash";
|
|
||||||
import { BaseXmlComponent } from "./base";
|
import { BaseXmlComponent } from "./base";
|
||||||
|
|
||||||
export abstract class XmlAttributeComponent extends BaseXmlComponent {
|
type AttributeMap<T> = {[P in keyof T]: string};
|
||||||
protected root: object;
|
|
||||||
private xmlKeys: object;
|
|
||||||
|
|
||||||
constructor(xmlKeys: object, properties: object) {
|
export abstract class XmlAttributeComponent<T> extends BaseXmlComponent {
|
||||||
|
protected root: T;
|
||||||
|
protected xmlKeys: AttributeMap<T>;
|
||||||
|
|
||||||
|
constructor(properties: T) {
|
||||||
super("_attr");
|
super("_attr");
|
||||||
this.xmlKeys = xmlKeys;
|
|
||||||
|
|
||||||
this.root = properties;
|
this.root = properties;
|
||||||
|
|
||||||
if (!properties) {
|
|
||||||
this.root = {};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public prepForXml(): {_attr: {[key: string]: (string | number | boolean)}} {
|
public prepForXml(): {_attr: {[key: string]: (string | number | boolean)}} {
|
||||||
const attrs = {};
|
const attrs = {};
|
||||||
if (this.root !== undefined) {
|
Object.keys(this.root).forEach((key) => {
|
||||||
_.forOwn(this.root, (value, key) => {
|
const value = this.root[key];
|
||||||
if (value !== undefined) {
|
if (value !== undefined) {
|
||||||
const newKey = this.xmlKeys[key];
|
const newKey = this.xmlKeys[key];
|
||||||
attrs[newKey] = value;
|
attrs[newKey] = value;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
return {_attr: attrs};
|
return {_attr: attrs};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
export { LocalPacker } from "./packer/local";
|
export { LocalPacker } from "./packer/local";
|
||||||
export { ExpressPacker } from "./packer/express";
|
export { ExpressPacker } from "./packer/express";
|
||||||
|
export { Packer } from "./packer/packer";
|
||||||
|
@ -20,17 +20,18 @@ export abstract class Packer {
|
|||||||
constructor(document: Document, style?: Styles, properties?: Properties, numbering?: Numbering) {
|
constructor(document: Document, style?: Styles, properties?: Properties, numbering?: Numbering) {
|
||||||
this.formatter = new Formatter();
|
this.formatter = new Formatter();
|
||||||
this.document = document;
|
this.document = document;
|
||||||
this.style = style;
|
|
||||||
this.properties = properties;
|
|
||||||
this.numbering = numbering;
|
|
||||||
this.archive = archiver.create("zip", {});
|
this.archive = archiver.create("zip", {});
|
||||||
|
|
||||||
if (!style) {
|
if (style) {
|
||||||
|
this.style = style;
|
||||||
|
} else {
|
||||||
const stylesFactory = new DefaultStylesFactory();
|
const stylesFactory = new DefaultStylesFactory();
|
||||||
this.style = stylesFactory.newInstance();
|
this.style = stylesFactory.newInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!properties) {
|
if (properties) {
|
||||||
|
this.properties = properties;
|
||||||
|
} else {
|
||||||
this.properties = new Properties({
|
this.properties = new Properties({
|
||||||
creator: "Un-named",
|
creator: "Un-named",
|
||||||
revision: "1",
|
revision: "1",
|
||||||
@ -38,7 +39,9 @@ export abstract class Packer {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!numbering) {
|
if (numbering) {
|
||||||
|
this.numbering = numbering;
|
||||||
|
} else {
|
||||||
this.numbering = new Numbering();
|
this.numbering = new Numbering();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,3 +2,4 @@ export * from "./docx";
|
|||||||
export * from "./export";
|
export * from "./export";
|
||||||
export { Numbering } from "./numbering";
|
export { Numbering } from "./numbering";
|
||||||
export { Styles } from "./styles";
|
export { Styles } from "./styles";
|
||||||
|
export * from './export';
|
||||||
|
@ -7,14 +7,11 @@ interface IAbstractNumberingAttributesProperties {
|
|||||||
restartNumberingAfterBreak?: number;
|
restartNumberingAfterBreak?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
class AbstractNumberingAttributes extends XmlAttributeComponent {
|
class AbstractNumberingAttributes extends XmlAttributeComponent<IAbstractNumberingAttributesProperties> {
|
||||||
|
protected xmlKeys = {
|
||||||
constructor(properties: IAbstractNumberingAttributesProperties) {
|
|
||||||
super({
|
|
||||||
abstractNumId: "w:abstractNumId",
|
abstractNumId: "w:abstractNumId",
|
||||||
restartNumberingAfterBreak: "w15:restartNumberingAfterBreak",
|
restartNumberingAfterBreak: "w15:restartNumberingAfterBreak",
|
||||||
}, properties);
|
};
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AbstractNumbering extends XmlComponent {
|
export class AbstractNumbering extends XmlComponent {
|
||||||
|
@ -7,14 +7,11 @@ interface ILevelAttributesProperties {
|
|||||||
tentative?: number;
|
tentative?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
class LevelAttributes extends XmlAttributeComponent {
|
class LevelAttributes extends XmlAttributeComponent<ILevelAttributesProperties> {
|
||||||
|
protected xmlKeys = {
|
||||||
constructor(properties: ILevelAttributesProperties) {
|
|
||||||
super({
|
|
||||||
ilvl: "w:ilvl",
|
ilvl: "w:ilvl",
|
||||||
tentative: "w15:tentative",
|
tentative: "w15:tentative",
|
||||||
}, properties);
|
};
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Start extends XmlComponent {
|
class Start extends XmlComponent {
|
||||||
|
@ -14,13 +14,8 @@ interface INumAttributesProperties {
|
|||||||
numId: number;
|
numId: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
class NumAttributes extends XmlAttributeComponent {
|
class NumAttributes extends XmlAttributeComponent<INumAttributesProperties> {
|
||||||
|
protected xmlKeys = {numId: "w:numId"};
|
||||||
constructor(properties: INumAttributesProperties) {
|
|
||||||
super({
|
|
||||||
numId: "w:numId",
|
|
||||||
}, properties);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Num extends XmlComponent {
|
export class Num extends XmlComponent {
|
||||||
|
@ -3,7 +3,6 @@ import { XmlComponent } from "../docx/xml-components";
|
|||||||
import { DocumentDefaults } from "./defaults";
|
import { DocumentDefaults } from "./defaults";
|
||||||
import { LatentStyles } from "./latent-styles";
|
import { LatentStyles } from "./latent-styles";
|
||||||
import { LatentStyleException } from "./latent-styles/exceptions";
|
import { LatentStyleException } from "./latent-styles/exceptions";
|
||||||
import { LatentStyleExceptionAttributes } from "./latent-styles/exceptions/attributes";
|
|
||||||
import { ParagraphStyle } from "./style";
|
import { ParagraphStyle } from "./style";
|
||||||
|
|
||||||
export class Styles extends XmlComponent {
|
export class Styles extends XmlComponent {
|
||||||
|
27
ts/styles/latent-styles/exceptions.ts
Normal file
27
ts/styles/latent-styles/exceptions.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { XmlAttributeComponent, XmlComponent } from "../../docx/xml-components";
|
||||||
|
|
||||||
|
interface ILatentStyleExceptionAttributesProperties {
|
||||||
|
name?: string;
|
||||||
|
uiPriority?: string;
|
||||||
|
qFormat?: string;
|
||||||
|
semiHidden?: string;
|
||||||
|
unhideWhenUsed?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
class LatentStyleExceptionAttributes extends XmlAttributeComponent<ILatentStyleExceptionAttributesProperties> {
|
||||||
|
protected xmlKeys = {
|
||||||
|
name: "w:name",
|
||||||
|
uiPriority: "w:uiPriority",
|
||||||
|
qFormat: "w:qFormat",
|
||||||
|
semiHidden: "w:semiHidden",
|
||||||
|
unhideWhenUsed: "w:unhideWhenUsed",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export class LatentStyleException extends XmlComponent {
|
||||||
|
|
||||||
|
constructor(attributes: ILatentStyleExceptionAttributesProperties) {
|
||||||
|
super("w:lsdException");
|
||||||
|
this.root.push(new LatentStyleExceptionAttributes(attributes));
|
||||||
|
}
|
||||||
|
}
|
@ -1,33 +0,0 @@
|
|||||||
import {XmlComponent} from "../../../docx/xml-components";
|
|
||||||
|
|
||||||
interface ILatentStyleExceptionAttributesProperties {
|
|
||||||
name?: string;
|
|
||||||
uiPriority?: string;
|
|
||||||
qFormat?: string;
|
|
||||||
semiHidden?: string;
|
|
||||||
unhideWhenUsed?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class LatentStyleExceptionAttributes extends XmlComponent {
|
|
||||||
/* tslint:disable */
|
|
||||||
private _attr: ILatentStyleExceptionAttributesProperties;
|
|
||||||
/* tslint:enable */
|
|
||||||
|
|
||||||
private xmlKeys = {
|
|
||||||
name: "w:name",
|
|
||||||
uiPriority: "w:uiPriority",
|
|
||||||
qFormat: "w:qFormat",
|
|
||||||
semiHidden: "w:semiHidden",
|
|
||||||
unhideWhenUsed: "w:unhideWhenUsed",
|
|
||||||
};
|
|
||||||
|
|
||||||
constructor(properties?: ILatentStyleExceptionAttributesProperties) {
|
|
||||||
super("_attr");
|
|
||||||
this._attr = properties;
|
|
||||||
|
|
||||||
if (!properties) {
|
|
||||||
this._attr = {};
|
|
||||||
}
|
|
||||||
// this._attr.xmlKeys = this.xmlKeys;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
import { XmlComponent } from "../../../docx/xml-components";
|
|
||||||
import { LatentStyleExceptionAttributes } from "./attributes";
|
|
||||||
|
|
||||||
export class LatentStyleException extends XmlComponent {
|
|
||||||
|
|
||||||
constructor(attributes: LatentStyleExceptionAttributes) {
|
|
||||||
super("w:lsdException");
|
|
||||||
this.root.push(attributes);
|
|
||||||
}
|
|
||||||
}
|
|
@ -4,10 +4,8 @@ interface IComponentAttributes {
|
|||||||
val: string;
|
val: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ComponentAttributes extends XmlAttributeComponent {
|
class ComponentAttributes extends XmlAttributeComponent<IComponentAttributes> {
|
||||||
constructor(properties: IComponentAttributes) {
|
protected xmlKeys = {val: "w:val"};
|
||||||
super({val: "w:val"}, properties);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Name extends XmlComponent {
|
export class Name extends XmlComponent {
|
||||||
|
@ -14,15 +14,13 @@ export interface IStyleAttributes {
|
|||||||
customStyle?: string;
|
customStyle?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
class StyleAttributes extends XmlAttributeComponent {
|
class StyleAttributes extends XmlAttributeComponent<IStyleAttributes> {
|
||||||
constructor(properties: IStyleAttributes) {
|
protected xmlKeys = {
|
||||||
super({
|
|
||||||
type: "w:type",
|
type: "w:type",
|
||||||
styleId: "w:styleId",
|
styleId: "w:styleId",
|
||||||
default: "w:default",
|
default: "w:default",
|
||||||
customStyle: "w:customStyle",
|
customStyle: "w:customStyle",
|
||||||
}, properties);
|
};
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Style extends XmlComponent {
|
export class Style extends XmlComponent {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { assert } from "chai";
|
import { assert, expect } from "chai";
|
||||||
import * as docx from "../../../docx";
|
import * as docx from "../../../docx";
|
||||||
|
import { Formatter } from "../../../export/formatter";
|
||||||
|
|
||||||
describe("Document", () => {
|
describe("Document", () => {
|
||||||
let document: docx.Document;
|
let document: docx.Document;
|
||||||
@ -22,4 +23,27 @@ describe("Document", () => {
|
|||||||
assert.isTrue(true);
|
assert.isTrue(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("#createParagraph", () => {
|
||||||
|
it("should create a new paragraph and append it to body", () => {
|
||||||
|
const para = document.createParagraph();
|
||||||
|
expect(para).to.be.an.instanceof(docx.Paragraph);
|
||||||
|
const body = new Formatter().format(document)["w:document"][1]["w:body"];
|
||||||
|
expect(body).to.be.an("array").which.has.length.at.least(1);
|
||||||
|
expect(body[0]).to.have.property("w:p");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should use the text given to create a run in the paragraph", () => {
|
||||||
|
const para = document.createParagraph("sample paragraph text");
|
||||||
|
expect(para).to.be.an.instanceof(docx.Paragraph);
|
||||||
|
const body = new Formatter().format(document)["w:document"][1]["w:body"];
|
||||||
|
expect(body).to.be.an("array").which.has.length.at.least(1);
|
||||||
|
expect(body[0]).to.have.property("w:p").which.includes({
|
||||||
|
"w:r": [
|
||||||
|
{"w:rPr": []},
|
||||||
|
{"w:t": ["sample paragraph text"]},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -32,6 +32,20 @@ describe("Paragraph", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("#createTextRun", () => {
|
||||||
|
it("should add a new run to the paragraph and return it", () => {
|
||||||
|
const run = paragraph.createTextRun("this is a test run");
|
||||||
|
expect(run).to.be.instanceof(docx.TextRun);
|
||||||
|
const tree = new Formatter().format(paragraph)["w:p"];
|
||||||
|
expect(tree).to.be.an("array").which.includes({
|
||||||
|
"w:r": [
|
||||||
|
{"w:rPr": []},
|
||||||
|
{"w:t": ["this is a test run"]},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("#heading1()", () => {
|
describe("#heading1()", () => {
|
||||||
it("should add heading style to JSON", () => {
|
it("should add heading style to JSON", () => {
|
||||||
paragraph.heading1();
|
paragraph.heading1();
|
||||||
|
@ -2,21 +2,8 @@ import { assert } from "chai";
|
|||||||
import { Attributes } from "../../../docx/xml-components";
|
import { Attributes } from "../../../docx/xml-components";
|
||||||
|
|
||||||
describe("Attribute", () => {
|
describe("Attribute", () => {
|
||||||
let attributes: Attributes;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
attributes = new Attributes();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("#constructor()", () => {
|
describe("#constructor()", () => {
|
||||||
|
|
||||||
it("should not add val with empty constructor", () => {
|
|
||||||
const newAttrs = new Attributes();
|
|
||||||
const stringifiedJson = JSON.stringify(newAttrs);
|
|
||||||
const newJson = JSON.parse(stringifiedJson);
|
|
||||||
assert.isUndefined(newJson.root.val);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should have val as defined with populated constructor", () => {
|
it("should have val as defined with populated constructor", () => {
|
||||||
const newAttrs = new Attributes({
|
const newAttrs = new Attributes({
|
||||||
val: "test",
|
val: "test",
|
||||||
|
Reference in New Issue
Block a user