Files
docx-js/src/file/numbering/numbering.spec.ts

405 lines
19 KiB
TypeScript
Raw Normal View History

2017-03-08 17:07:54 +01:00
import { expect } from "chai";
2017-12-20 00:01:23 +00:00
import { Formatter } from "../../export/formatter";
import { Numbering } from "./";
import { AbstractNumbering } from "./abstract-numbering";
import { LevelForOverride } from "./level";
import { Num } from "./num";
2016-07-01 22:09:55 +01:00
2017-03-08 17:07:54 +01:00
describe("Numbering", () => {
2017-03-08 17:37:14 +01:00
let numbering: Numbering;
2017-03-09 22:56:08 +00:00
2016-07-01 22:09:55 +01:00
beforeEach(() => {
numbering = new Numbering();
});
2017-03-08 17:07:54 +01:00
describe("#constructor", () => {
it("creates a default numbering with one abstract and one concrete instance", () => {
const tree = new Formatter().format(numbering);
2017-03-08 17:37:14 +01:00
expect(Object.keys(tree)).to.deep.equal(["w:numbering"]);
const abstractNums = tree["w:numbering"].filter((el) => el["w:abstractNum"]);
2017-03-08 17:07:54 +01:00
expect(abstractNums).to.have.lengthOf(1);
2017-03-08 17:37:14 +01:00
expect(abstractNums[0]["w:abstractNum"]).to.deep.include.members([
2017-03-09 22:56:08 +00:00
{ _attr: { "w:abstractNumId": 0, "w15:restartNumberingAfterBreak": 0 } },
{ "w:multiLevelType": [{ _attr: { "w:val": "hybridMultilevel" } }] },
2017-03-08 17:07:54 +01:00
]);
2016-07-01 22:09:55 +01:00
2017-03-08 17:37:14 +01:00
abstractNums.filter((el) => el["w:lvl"]).forEach((el, ix) => {
2017-03-08 17:07:54 +01:00
expect(Object.keys(el)).to.have.lengthOf(1);
2018-01-23 01:33:12 +00:00
expect(Object.keys(el["w:lvl"]).sort()).to.deep.equal(["_attr", "w:start", "w:lvlJc", "w:numFmt", "w:pPr", "w:rPr"]);
2017-03-08 17:37:14 +01:00
expect(el["w:lvl"]).to.have.deep.members([
2017-03-09 22:56:08 +00:00
{ _attr: { "w:ilvl": ix, "w15:tentative": 1 } },
{ "w:start": [{ _attr: { "w:val": 1 } }] },
{ "w:lvlJc": [{ _attr: { "w:val": "left" } }] },
{ "w:numFmt": [{ _attr: { "w:val": "bullet" } }] },
2017-03-08 17:07:54 +01:00
]);
// Once chai 4.0.0 lands and #644 is resolved, we can add the following to the test:
// {"w:lvlText": [{"_attr": {"w:val": "•"}}]},
2018-07-24 12:24:26 +08:00
// {"w:rPr": [{"w:rFonts": [{"_attr": {"w:ascii": "Symbol", "w:cs": "Symbol", "w:eastAsia": "Symbol", "w:hAnsi": "Symbol", "w:hint": "default"}}]}]},
2017-03-08 17:07:54 +01:00
// {"w:pPr": [{"_attr": {}},
// {"w:ind": [{"_attr": {"w:left": 720, "w:hanging": 360}}]}]},
2017-03-08 17:37:14 +01:00
});
2016-07-01 22:09:55 +01:00
});
});
describe("#createAbstractNumbering", () => {
it("returns a new AbstractNumbering instance", () => {
const a2 = numbering.createAbstractNumbering();
expect(a2).to.be.instanceof(AbstractNumbering);
});
it("assigns a unique ID to each abstract numbering it creates", () => {
const a2 = numbering.createAbstractNumbering();
const a3 = numbering.createAbstractNumbering();
expect(a2.id).not.to.equal(a3.id);
});
});
describe("#createConcreteNumbering", () => {
it("returns a new Num instance with its abstract ID set to the AbstractNumbering's ID", () => {
const a2 = numbering.createAbstractNumbering();
const n = numbering.createConcreteNumbering(a2);
expect(n).to.be.instanceof(Num);
const tree = new Formatter().format(numbering);
2018-01-23 01:33:12 +00:00
const serializedN = tree["w:numbering"].find((obj) => obj["w:num"] && obj["w:num"][0]._attr["w:numId"] === n.id);
2017-03-09 20:49:34 +01:00
expect(serializedN["w:num"][1]["w:abstractNumId"][0]._attr["w:val"]).to.equal(a2.id);
});
it("assigns a unique ID to each concrete numbering it creates", () => {
const a2 = numbering.createAbstractNumbering();
const n = numbering.createConcreteNumbering(a2);
const n2 = numbering.createConcreteNumbering(a2);
expect(n.id).not.to.equal(n2.id);
});
});
2017-03-08 17:18:12 +01:00
});
describe("AbstractNumbering", () => {
it("stores its ID at its .id property", () => {
const abstractNumbering = new AbstractNumbering(5);
expect(abstractNumbering.id).to.equal(5);
});
describe("#createLevel", () => {
it("creates a level with the given characteristics", () => {
const abstractNumbering = new AbstractNumbering(1);
const level = abstractNumbering.createLevel(3, "lowerLetter", "%1)", "end");
const tree = new Formatter().format(level);
2017-03-09 22:56:08 +00:00
expect(tree["w:lvl"]).to.include({ _attr: { "w:ilvl": 3, "w15:tentative": 1 } });
expect(tree["w:lvl"]).to.include({ "w:start": [{ _attr: { "w:val": 1 } }] });
expect(tree["w:lvl"]).to.include({ "w:lvlJc": [{ _attr: { "w:val": "end" } }] });
expect(tree["w:lvl"]).to.include({ "w:numFmt": [{ _attr: { "w:val": "lowerLetter" } }] });
expect(tree["w:lvl"]).to.include({ "w:lvlText": [{ _attr: { "w:val": "%1)" } }] });
});
it("uses 'start' as the default alignment", () => {
const abstractNumbering = new AbstractNumbering(1);
const level = abstractNumbering.createLevel(3, "lowerLetter", "%1)");
const tree = new Formatter().format(level);
2017-03-09 22:56:08 +00:00
expect(tree["w:lvl"]).to.include({ _attr: { "w:ilvl": 3, "w15:tentative": 1 } });
expect(tree["w:lvl"]).to.include({ "w:start": [{ _attr: { "w:val": 1 } }] });
expect(tree["w:lvl"]).to.include({ "w:lvlJc": [{ _attr: { "w:val": "start" } }] });
expect(tree["w:lvl"]).to.include({ "w:numFmt": [{ _attr: { "w:val": "lowerLetter" } }] });
expect(tree["w:lvl"]).to.include({ "w:lvlText": [{ _attr: { "w:val": "%1)" } }] });
});
describe("formatting methods: paragraph properties", () => {
it("#indent", () => {
const abstractNumbering = new AbstractNumbering(1);
2018-01-23 01:33:12 +00:00
const level = abstractNumbering.createLevel(0, "lowerLetter", "%0.").indent({ left: 720 });
const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({
2018-01-23 01:33:12 +00:00
"w:pPr": [{ "w:ind": [{ _attr: { "w:left": 720 } }] }],
});
});
it("#spacing", () => {
const abstractNumbering = new AbstractNumbering(1);
2018-01-23 01:33:12 +00:00
const level = abstractNumbering.createLevel(0, "lowerLetter", "%0.").spacing({ before: 50, after: 150 });
const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({
2018-01-23 01:33:12 +00:00
"w:pPr": [{ "w:spacing": [{ _attr: { "w:before": 50, "w:after": 150 } }] }],
});
});
it("#center", () => {
const abstractNumbering = new AbstractNumbering(1);
2018-01-23 01:33:12 +00:00
const level = abstractNumbering.createLevel(0, "lowerLetter", "%0.").center();
const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({
2018-01-23 01:33:12 +00:00
"w:pPr": [{ "w:jc": [{ _attr: { "w:val": "center" } }] }],
});
});
it("#left", () => {
const abstractNumbering = new AbstractNumbering(1);
2018-01-23 01:33:12 +00:00
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.", "left").left();
const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({
2018-01-23 01:33:12 +00:00
"w:pPr": [{ "w:jc": [{ _attr: { "w:val": "left" } }] }],
});
});
it("#right", () => {
const abstractNumbering = new AbstractNumbering(1);
2018-01-23 01:33:12 +00:00
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").right();
const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({
2018-01-23 01:33:12 +00:00
"w:pPr": [{ "w:jc": [{ _attr: { "w:val": "right" } }] }],
});
});
it("#justified", () => {
const abstractNumbering = new AbstractNumbering(1);
2018-01-23 01:33:12 +00:00
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").justified();
const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({
2018-01-23 01:33:12 +00:00
"w:pPr": [{ "w:jc": [{ _attr: { "w:val": "both" } }] }],
});
});
it("#thematicBreak", () => {
const abstractNumbering = new AbstractNumbering(1);
2018-01-23 01:33:12 +00:00
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").thematicBreak();
const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({
"w:pPr": [
2018-01-23 01:33:12 +00:00
{
"w:pBdr": [
{
"w:bottom": [
{
_attr: {
"w:color": "auto",
"w:space": "1",
"w:val": "single",
"w:sz": "6",
},
},
],
},
],
},
],
});
});
it("#leftTabStop", () => {
const abstractNumbering = new AbstractNumbering(1);
2018-01-23 01:33:12 +00:00
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").leftTabStop(1200);
const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({
"w:pPr": [
2018-01-23 01:33:12 +00:00
{
"w:tabs": [{ "w:tab": [{ _attr: { "w:val": "left", "w:pos": 1200 } }] }],
},
],
});
});
it("#maxRightTabStop", () => {
const abstractNumbering = new AbstractNumbering(1);
2018-01-23 01:33:12 +00:00
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").maxRightTabStop();
const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({
"w:pPr": [
2018-01-23 01:33:12 +00:00
{
"w:tabs": [{ "w:tab": [{ _attr: { "w:val": "right", "w:pos": 9026 } }] }],
},
],
});
});
it("#keepLines", () => {
const abstractNumbering = new AbstractNumbering(1);
2018-01-23 01:33:12 +00:00
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").keepLines();
const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({
2018-01-23 01:33:12 +00:00
"w:pPr": [{ "w:keepLines": [] }],
});
});
it("#keepNext", () => {
const abstractNumbering = new AbstractNumbering(1);
2018-01-23 01:33:12 +00:00
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").keepNext();
const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({
2018-01-23 01:33:12 +00:00
"w:pPr": [{ "w:keepNext": [] }],
});
});
});
2017-03-13 12:30:36 +01:00
describe("formatting methods: run properties", () => {
it("#size", () => {
const abstractNumbering = new AbstractNumbering(1);
2018-01-23 01:33:12 +00:00
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").size(24);
2017-03-13 12:30:36 +01:00
const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({
2018-01-23 01:33:12 +00:00
"w:rPr": [{ "w:sz": [{ _attr: { "w:val": 24 } }] }],
2017-03-13 12:30:36 +01:00
});
});
it("#smallCaps", () => {
const abstractNumbering = new AbstractNumbering(1);
2018-01-23 01:33:12 +00:00
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").smallCaps();
2017-03-13 12:30:36 +01:00
const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({
2018-01-23 01:33:12 +00:00
"w:rPr": [{ "w:smallCaps": [{ _attr: { "w:val": true } }] }],
2017-03-13 12:30:36 +01:00
});
});
it("#allCaps", () => {
const abstractNumbering = new AbstractNumbering(1);
2018-01-23 01:33:12 +00:00
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").allCaps();
2017-03-13 12:30:36 +01:00
const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({
2018-01-23 01:33:12 +00:00
"w:rPr": [{ "w:caps": [{ _attr: { "w:val": true } }] }],
2017-03-13 12:30:36 +01:00
});
});
it("#strike", () => {
const abstractNumbering = new AbstractNumbering(1);
2018-01-23 01:33:12 +00:00
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").strike();
2017-03-13 12:30:36 +01:00
const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({
2018-01-23 01:33:12 +00:00
"w:rPr": [{ "w:strike": [{ _attr: { "w:val": true } }] }],
2017-03-13 12:30:36 +01:00
});
});
it("#doubleStrike", () => {
const abstractNumbering = new AbstractNumbering(1);
2018-01-23 01:33:12 +00:00
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").doubleStrike();
2017-03-13 12:30:36 +01:00
const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({
2018-01-23 01:33:12 +00:00
"w:rPr": [{ "w:dstrike": [{ _attr: { "w:val": true } }] }],
2017-03-13 12:30:36 +01:00
});
});
it("#subScript", () => {
const abstractNumbering = new AbstractNumbering(1);
2018-01-23 01:33:12 +00:00
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").subScript();
2017-03-13 12:30:36 +01:00
const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({
2018-01-23 01:33:12 +00:00
"w:rPr": [{ "w:vertAlign": [{ _attr: { "w:val": "subscript" } }] }],
2017-03-13 12:30:36 +01:00
});
});
it("#superScript", () => {
const abstractNumbering = new AbstractNumbering(1);
2018-01-23 01:33:12 +00:00
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").superScript();
2017-03-13 12:30:36 +01:00
const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({
2018-01-23 01:33:12 +00:00
"w:rPr": [{ "w:vertAlign": [{ _attr: { "w:val": "superscript" } }] }],
2017-03-13 12:30:36 +01:00
});
});
it("#font", () => {
const abstractNumbering = new AbstractNumbering(1);
2018-01-23 01:33:12 +00:00
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").font("Times");
2017-03-13 12:30:36 +01:00
const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({
2018-07-24 12:37:15 +08:00
"w:rPr": [
{ "w:rFonts": [{ _attr: { "w:ascii": "Times", "w:cs": "Times", "w:eastAsia": "Times", "w:hAnsi": "Times" } }] },
],
2017-03-13 12:30:36 +01:00
});
});
it("#bold", () => {
const abstractNumbering = new AbstractNumbering(1);
2018-01-23 01:33:12 +00:00
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").bold();
2017-03-13 12:30:36 +01:00
const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({
2018-01-23 01:33:12 +00:00
"w:rPr": [{ "w:b": [{ _attr: { "w:val": true } }] }],
2017-03-13 12:30:36 +01:00
});
});
it("#italics", () => {
const abstractNumbering = new AbstractNumbering(1);
2018-01-23 01:33:12 +00:00
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").italics();
2017-03-13 12:30:36 +01:00
const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({
2018-01-23 01:33:12 +00:00
"w:rPr": [{ "w:i": [{ _attr: { "w:val": true } }] }],
2017-03-13 12:30:36 +01:00
});
});
describe("#underline", () => {
it("should set underline to 'single' if no arguments are given", () => {
const abstractNumbering = new AbstractNumbering(1);
2018-01-23 01:33:12 +00:00
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").underline();
2017-03-13 12:30:36 +01:00
const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({
2018-01-23 01:33:12 +00:00
"w:rPr": [{ "w:u": [{ _attr: { "w:val": "single" } }] }],
2017-03-13 12:30:36 +01:00
});
});
it("should set the style if given", () => {
const abstractNumbering = new AbstractNumbering(1);
2018-01-23 01:33:12 +00:00
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").underline("double");
2017-03-13 12:30:36 +01:00
const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({
2018-01-23 01:33:12 +00:00
"w:rPr": [{ "w:u": [{ _attr: { "w:val": "double" } }] }],
2017-03-13 12:30:36 +01:00
});
});
it("should set the style and color if given", () => {
const abstractNumbering = new AbstractNumbering(1);
2018-01-23 01:33:12 +00:00
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").underline("double", "005599");
2017-03-13 12:30:36 +01:00
const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({
2018-01-23 01:33:12 +00:00
"w:rPr": [{ "w:u": [{ _attr: { "w:val": "double", "w:color": "005599" } }] }],
2017-03-13 12:30:36 +01:00
});
});
});
it("#color", () => {
const abstractNumbering = new AbstractNumbering(1);
2018-01-23 01:33:12 +00:00
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").color("123456");
2017-03-13 12:30:36 +01:00
const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({
2018-01-23 01:33:12 +00:00
"w:rPr": [{ "w:color": [{ _attr: { "w:val": "123456" } }] }],
2017-03-13 12:30:36 +01:00
});
});
});
});
2017-03-08 17:37:14 +01:00
});
describe("concrete numbering", () => {
describe("#overrideLevel", () => {
let numbering;
let abstractNumbering;
let concreteNumbering;
beforeEach(() => {
numbering = new Numbering();
abstractNumbering = numbering.createAbstractNumbering();
concreteNumbering = numbering.createConcreteNumbering(abstractNumbering);
});
it("sets a new override level for the given level number", () => {
concreteNumbering.overrideLevel(3);
const tree = new Formatter().format(concreteNumbering);
2018-01-23 01:33:12 +00:00
expect(tree["w:num"]).to.include({ "w:lvlOverride": [{ _attr: { "w:ilvl": 3 } }] });
});
it("sets the startOverride element if start is given", () => {
concreteNumbering.overrideLevel(1, 9);
const tree = new Formatter().format(concreteNumbering);
expect(tree["w:num"]).to.include({
2018-01-23 01:33:12 +00:00
"w:lvlOverride": [{ _attr: { "w:ilvl": 1 } }, { "w:startOverride": [{ _attr: { "w:val": 9 } }] }],
});
});
2018-08-07 01:25:28 +01:00
it("sets the lvl element if overrideLevel.Level is accessed", () => {
const ol = concreteNumbering.overrideLevel(1);
2018-08-07 01:25:28 +01:00
expect(ol.Level).to.be.instanceof(LevelForOverride);
const tree = new Formatter().format(concreteNumbering);
expect(tree["w:num"]).to.include({
"w:lvlOverride": [
2018-01-23 01:33:12 +00:00
{ _attr: { "w:ilvl": 1 } },
{
"w:lvl": [{ _attr: { "w15:tentative": 1, "w:ilvl": 1 } }, { "w:pPr": [] }, { "w:rPr": [] }],
},
],
});
});
});
});