first commit

This commit is contained in:
CrazyJasonwell
2026-07-23 20:36:13 +08:00
commit 513b68be8c
7915 changed files with 2642530 additions and 0 deletions
@@ -0,0 +1,88 @@
const MarkdownIt = require('markdown-it');
const { expect } = require('chai');
const { JSDOM } = require('jsdom');
const MarkdownItKroki = require('../../index');
describe('# [Security-test] anti-injecttion for syntax.', () => {
describe("## for alt", () => {
it('* escape double quote', () => {
const expected = 'this is a "test comment" test';
const md = new MarkdownIt();
md.use(MarkdownItKroki, {
entrypoint: "https://kroki.io",
marpAutoScaling: true,
containerClass: "the-container"
});
const result = md.render(
'```graphviz [this is a "test comment" test]\r\n' +
'digraph G {Hello->World}\r\n' +
'```\r\n'
);
const dom = new JSDOM(result);
const imgTag = dom.window.document.getElementsByTagName("embed")[0];
const actual = imgTag.getAttribute('title');
expect(actual).to.be.equal(expected);
})
})
});
describe('# [Security-test] anti-injecttion for option.', () => {
describe("## for entrypoint", () => {
it('* deny invalid URL', () => {
const testFunction = () => {
const md = new MarkdownIt();
md.use(MarkdownItKroki, {
entrypoint: "https://kroki.io\"> <script src=\"xxxx.js",
marpAutoScaling: true,
containerClass: "the-container"
});
}
expect(testFunction).to.throw();
})
})
describe("## for containerClass", () => {
it('* throw when containerClass are not alpha, digit, or \"-\"', () => {
const testFunction = () => {
const md = new MarkdownIt();
md.use(MarkdownItKroki, {
entrypoint: "https://kroki.io",
marpAutoScaling: true,
containerClass: "<container>"
});
const result = md.render(
'```graphviz [this is a test]\r\n' +
'digraph G {Hello->World}\r\n' +
'```\r\n'
);
};
expect(testFunction).to.throw();
})
})
describe("## for imageFormat", () => {
it('* ignore invalid imageFormat', () => {
const md = new MarkdownIt();
md.use(MarkdownItKroki, {
entrypoint: "https://kroki.io",
marpAutoScaling: true,
containerClass: "the-container",
imageFormat: "<injected>"
});
const html = md.render(
'```graphviz [this is a test]\r\n' +
'digraph G {Hello->World}\r\n' +
'```\r\n'
);
const dom = new JSDOM(html);
const imgTag = dom.window.document.getElementsByTagName("embed")[0];
const actual = imgTag.getAttribute('src');
expect(actual).to.includes('/svg/');
})
})
});
@@ -0,0 +1,154 @@
const { expect } = require('chai');
const sinon = require('sinon');
const MarkdownIt = require('markdown-it');
const MarkdownItKroki = require('../../index');
const { JSDOM } = require('jsdom');
const testData = [
// graphviz
{
langname: 'graphviz',
data: '```graphviz svg\r\n' +
'digraph G {Hello->World}\r\n' +
'```\r\n'
}
];
describe('# [total test] Test pulugin can Render DOM', () => {
for (const test of testData) {
describe(`## Test for ${test.langname}`, () => {
describe('### no option call test', () => {
it('* Not to Throw on no options', () => {
const testFunction = () => {
// render !
const md = new MarkdownIt();
md.use(MarkdownItKroki);
const _ = md.render(test.data);
};
expect(testFunction).to.not.throw();
});
it('* root DOM item is \'p\' on no option', () => {
// render !
const md = new MarkdownIt();
md.use(MarkdownItKroki);
const result = md.render(test.data);
// find p-tag
const dom = new JSDOM(result);
const document = dom.window.document;
const ptags = document.getElementsByTagName("p");
// test p-tag is only one
expect(ptags.length).to.be.equal(1);
// test root item is p
const thePtag = ptags[0];
expect(thePtag.isSameNode(document.body.firstChild)).to.true;
// test embeded default container class
expect(thePtag.getAttribute('class')).to.be.equal('kroki-image-container');
});
it('* has embed tag and source is created by this library.', () => {
// render !
const md = new MarkdownIt();
md.use(MarkdownItKroki);
const result = md.render(test.data);
// find embed tag
const dom = new JSDOM(result);
const document = dom.window.document;
const imgTags = document.getElementsByTagName("embed");
// test embed is only one
expect(imgTags.length).to.be.equal(1);
const imgTag = imgTags[0];
expect(imgTag.getAttribute('src')).not.to.empty;
});
});
describe('### option call test', () => {
it('* entrypoint is embeded in image tag.', () => {
const entrypoint = 'https://127.0.0.1';
// render !
const md = new MarkdownIt();
md.use(MarkdownItKroki, {entrypoint: entrypoint});
const result = md.render(test.data);
// find embed tag
const dom = new JSDOM(result);
const document = dom.window.document;
const imgTags = document.getElementsByTagName("embed");
const imgTag = imgTags[0];
expect(imgTag.getAttribute('src')).includes(entrypoint);
});
it('* containerClass is embeded.', () => {
const containerClass = 'my-container';
// render !
const md = new MarkdownIt();
md.use(MarkdownItKroki, {containerClass: containerClass});
const result = md.render(test.data);
// find p-tag
const dom = new JSDOM(result);
const document = dom.window.document;
const ptags = document.getElementsByTagName("p");
// test p-tag is only one
expect(ptags.length).to.be.equal(1);
const thePtag = ptags[0];
expect(thePtag.getAttribute('class')).to.be.equal(containerClass);
});
it('* imageFormat is embeded.', () => {
const imageFormat = 'png';
// render !
const md = new MarkdownIt();
md.use(MarkdownItKroki, {imageFormat: imageFormat});
const result = md.render(test.data);
// find embed tag
const dom = new JSDOM(result);
const document = dom.window.document;
const imgTags = document.getElementsByTagName("embed");
const imgTag = imgTags[0];
expect(imgTag.getAttribute('src')).includes(imageFormat);
});
it('* useImg is enable.', () => {
const useImg = true;
// render !
const md = new MarkdownIt();
md.use(MarkdownItKroki, {useImg: useImg});
const result = md.render(test.data);
// img embed tag
const dom = new JSDOM(result);
const document = dom.window.document;
const imgTags = document.getElementsByTagName("img");
expect(imgTags.length).to.be.equal(1);
});
it('* render is embeded.', () => {
const fakeTag = 'testXXXXXXXXXXXXXXX';
const render = sinon.fake.returns(fakeTag);
// render !
const md = new MarkdownIt();
md.use(MarkdownItKroki, {render: render});
const result = md.render(test.data);
// render must be called
expect(render.called).to.be.true;
// render must be called with correct argument
expect(render.getCall(0).args[0]).to.contains('https://kroki.io');
// endered embeded fakeTag
expect(result).to.contains(fakeTag);
})
});
});
}
})
@@ -0,0 +1,35 @@
const expect = require('chai').expect;
const contract = require('../../lib/contract');
describe('# [unit test]: contract.js', () => {
describe('## toNonEmptyString()', () => {
['abc', ' ', ' abc '].forEach((test) => {
it(`* normal cases. { testcase: ${test} }`, () => {
expect(() => {
contract.toNonEmptyString(test);
}).not.to.throw();
})
});
['', null, undefined, 123, 0.123, true, { test: 123 }].forEach((test) => {
it(`* abnormal cases. { testcase: ${test} }`, () => {
expect(() => {
contract.toNonEmptyString(test);
}).to.throw();
})
});
});
describe('## toTrue', () => {
it('* normal case. {test case: true}', () => {
expect(() => {
contract.toTrue(true);
}).not.to.throw();
});
['', null, undefined, 123, 0.123, false, { test: 123 }].forEach((test) => {
it(`* abnormal cases. { testcase: ${test} }`, () => {
expect(() => {
contract.toTrue(test);
}).to.throw();
})
});
});
})
@@ -0,0 +1,75 @@
const expect = require('chai').expect;
const { inflateSync } = require('zlib');
const { encode, generateUrl } = require('../../lib/diagram-encoder');
describe('# [unit-test]: diagram-encoder.js', () => {
describe('## [function]: encode()', () => {
it('* encoded data is able to decode.', () => {
const testFunc = () => {
const expected = '@startuml\nBob -> Alice : hello\n@enduml';
const encoded = encode(expected);
const deflated = Buffer.from(encoded, "base64url");
const actual = inflateSync(deflated).toString();
expect(actual).to.be.equal(expected);
}
expect(testFunc).not.to.Throw();
});
});
describe('## [function]: generateUrl()', () => {
it('* must start format like <entry-point>/<lang>/<format>/', () => {
const actual = generateUrl('https://kroki.io', 'graphviz', 'svg', 'digraph G {Hello->World}');
const expected = 'https://kroki.io/graphviz/svg/';
expect(actual).to.be.a('string');
expect(actual.startsWith(expected)).to.be.true;
});
it('* must endwith <encoded>', () => {
const actual = generateUrl('https://kroki.io', 'graphviz', 'svg', 'digraph G {Hello->World}');
const expected = encode('digraph G {Hello->World}');
expect(actual).to.be.a('string');
expect(actual.endsWith(expected)).to.be.true;
});
[1, '', null, undefined].forEach(test => {
it(`* [exception] throws when entry-point is, non-string object, empty string, null or undefined. Test: ${test}`, () => {
const testFunction = () => {
let _ = generateUrl(test, 'graphviz', 'svg', 'digraph G {Hello->World}');
}
expect(testFunction).throw();
});
it(`* [exception] throws when lang is, non-string object, empty string, null or undefined. Test: ${test}`, () => {
const testFunction = () => {
let _ = generateUrl('https://kroki.io', test, 'svg', 'digraph G {Hello->World}');
}
expect(testFunction).throw();
});
it(`* [exception] throws when imgType is, non-string object, empty string, null or undefined. Test: ${test}`, () => {
const testFunction = () => {
let _ = generateUrl('https://kroki.io', 'graphviz', test, 'digraph G {Hello->World}');
}
expect(testFunction).throw();
});
it(`* [exception] throws when diagram is, non-string object, empty string, null or undefined. Test: ${test}`, () => {
const testFunction = () => {
let _ = generateUrl('https://kroki.io', 'graphviz', 'svg', diagram);
}
expect(testFunction).throw();
});
});
it('* [exception] throws when lang is unsupported lang', () => {
const testFunction = () => {
let _ = generateUrl('https://kroki.io', 'graphviz123', 'svg', 'digraph G {Hello->World}');
}
expect(testFunction).throw();
});
it('* [exception] throws when imgType is unsupported imgType', () => {
const testFunction = () => {
let _ = generateUrl('https://kroki.io', 'graphviz', 'svg123', 'digraph G {Hello->World}');
}
expect(testFunction).throw();
});
});
});
@@ -0,0 +1,146 @@
const md = require('markdown-it');
const expect = require('chai').expect;
const { JSDOM } = require('jsdom');
const { MarkdownItKrokiCore } = require('../../lib/plugin-core');
const { encode } = require('../../lib/diagram-encoder');
describe('# [unit-test] plugin-core.js', () => {
describe('## method: buuildEmbedHTML', () => {
describe('### langAndAlt.language', () => {
[null, undefined, ''].forEach((test) => {
it(`* when langAndAlt.language is null or empty, throws error. testcase:${test}`, () => {
const diagramCode = '@startuml\nBob -> Alice : hello\n @enduml';
const plugin = new MarkdownItKrokiCore(new md()).setOptions();
const testFunc = () => {
plugin.use();
const _ = plugin.buildEmbedHTML(
{ language: test, alt: '' }, diagramCode);
};
expect(testFunc).to.throw();
});
});
it('* language embeded in to url', () => {
const test = 'plantuml';
const diagramCode = '@startuml\nBob -> Alice : hello\n @enduml';
// build embed HTML
const plugin = new MarkdownItKrokiCore(new md()).setOptions();
plugin.use();
const html = plugin.buildEmbedHTML({ language: test, alt: '' }, diagramCode);
// parse dom
const dom = new JSDOM(html);
const imgTag = dom.window.document.getElementsByTagName("embed")[0];
// get url attribute
const url = imgTag.getAttribute('src');
expect(/\/plantuml\//.test(url)).to.true;
});
});
describe('### langAndAlt.alt', () => {
[null, undefined, ''].forEach((test) => {
it(`* when langAndAlt.alt is null or empty, no alt attribute. testcase:${test}`, () => {
const diagramCode = '@startuml\nBob -> Alice : hello\n @enduml';
// prepair
const plugin = new MarkdownItKrokiCore(new md()).setOptions();
plugin.use();
// render
const html = plugin.buildEmbedHTML(
{ language: 'plantuml', alt: test }, diagramCode);
// parse dom
const dom = new JSDOM(html);
const imgTag = dom.window.document.getElementsByTagName("embed")[0];
expect(imgTag.hasAttribute('alt')).to.false;
});
});
it('* embeded altText', () => {
const expected = "this is test Text";
const diagramCode = '@startuml\nBob -> Alice : hello\n @enduml';
// prepair
const plugin = new MarkdownItKrokiCore(new md()).setOptions();
plugin.use();
// render
const html = plugin.buildEmbedHTML(
{ language: 'plantuml', alt: expected }, diagramCode);
// parse dom
const dom = new JSDOM(html);
const imgTag = dom.window.document.getElementsByTagName("embed")[0];
expect(imgTag.getAttribute('title')).to.equal(expected);
});
});
describe('### diagramCode', () => {
[null, undefined, ''].forEach((test) => {
it(`* when diagramCode is null or empty, throws error. testcase:${test}`, () => {
const plugin = new MarkdownItKrokiCore(new md()).setOptions();
const testFunc = () => {
plugin.use();
const _ = plugin.buildEmbedHTML(
{ language: 'plantuml', alt: '' }, test);
};
expect(testFunc).to.throw();
});
});
it('* encoded diagram must be embed to url on <img src=\'....\' ', () => {
const test = '@startuml\nBob -> Alice : hello\n @enduml';
const expected = encode(test);
// build embed HTML
const plugin = new MarkdownItKrokiCore(new md()).setOptions();
plugin.use();
const html = plugin.buildEmbedHTML({ language: 'plantuml', alt: '' }, test);
// parse dom
const dom = new JSDOM(html);
const imgTag = dom.window.document.getElementsByTagName("embed")[0];
// get url attribute
const url = imgTag.getAttribute('src');
expect(url.endsWith(expected)).to.true;
});
it('* <img> is surounded by <marp-auto-scaling> on to be used form marp-it', () => {
const test = '@startuml\nBob -> Alice : hello\n @enduml';
const markdownIt = new md()
markdownIt['marpit'] = { someObject: 'is implemented' };
// build embed HTML
const plugin = new MarkdownItKrokiCore(markdownIt).setOptions();
plugin.use();
const html = plugin.buildEmbedHTML({ language: 'plantuml', alt: '' }, test);
// parse dom
const dom = new JSDOM(html);
const imgTag = dom.window.document.getElementsByTagName("embed")[0];
const marpAutoScaling = dom.window.document.getElementsByTagName("marp-auto-scaling")[0];
expect(imgTag.isSameNode(marpAutoScaling.firstChild)).to.be.true;
});
it('* <img> is surounded by <marp-auto-scaling> on not to be used form marp-it', () => {
const test = '@startuml\nBob -> Alice : hello\n @enduml';
const markdownIt = new md()
// build embed HTML
const plugin = new MarkdownItKrokiCore(markdownIt).setOptions();
plugin.use();
const html = plugin.buildEmbedHTML({ language: 'plantuml', alt: '' }, test);
// parse dom
const dom = new JSDOM(html);
const marpAutoScaling = dom.window.document.getElementsByTagName("marp-auto-scaling");
expect(marpAutoScaling.length).to.equal(0);
})
});
});
});
@@ -0,0 +1,272 @@
const md = require('markdown-it');
const expect = require('chai').expect;
const sinon = require('sinon');
const { JSDOM } = require('jsdom');
const { MarkdownItKrokiCore } = require('../../lib/plugin-core');
describe('# [unit-test] plugin-core.js', () => {
describe('## method: setOptions() must be work', () => {
function buildHtmlForTest(options) {
const test = 'plantuml';
const alt = 'test alt text';
const diagramCode = '@startuml\nBob -> Alice : hello\n @enduml';
// build embed HTML
const plugin = new MarkdownItKrokiCore(new md()).setOptions(options);
plugin.use();
return plugin.buildEmbedHTML({ language: test, alt: alt }, diagramCode);
}
describe('### entrypoint', () => {
function expectEntryPointToEmbed(htmlString, expected) {
if (!expected) expected = 'https://kroki.io';
// parse dom
const dom = new JSDOM(htmlString);
const imgTag = dom.window.document.getElementsByTagName("embed")[0];
// get url attribute
const url = imgTag.getAttribute('src');
expect(url.startsWith(expected)).to.true;
}
it('* no options', () => {
const html = buildHtmlForTest();
expectEntryPointToEmbed(html);
});
it('* option is null', () => {
const html = buildHtmlForTest({ entrypoint: null });
expectEntryPointToEmbed(html);
});
it('* option is undefined', () => {
const html = buildHtmlForTest({ entrypoint: undefined });
expectEntryPointToEmbed(html);
});
it('* option is \'\'', () => {
const html = buildHtmlForTest({ entrypoint: '' });
expectEntryPointToEmbed(html);
});
it('* option is 1', () => {
const html = buildHtmlForTest({ entrypoint: 1 });
expectEntryPointToEmbed(html);
});
it('* option is true', () => {
const html = buildHtmlForTest({ entrypoint: true });
expectEntryPointToEmbed(html);
});
it('* option is \'https://localhost:8080\'', () => {
const html = buildHtmlForTest({
entrypoint: 'https://localhost:8080'
});
expectEntryPointToEmbed(html, 'https://localhost:8080');
});
});
describe.skip('### marpAutoScaling', () => {
function expectMarpAutoScalingToEmbed(htmlString, expected) {
// parse dom
const dom = new JSDOM(htmlString);
const tags = dom.window.document.getElementsByTagName("marp-auto-scaling");
if (expected) {
expect(tags).not.to.empty;
} else {
expect(tags).to.empty;
}
}
it('* no options', () => {
const html = buildHtmlForTest();
expectMarpAutoScalingToEmbed(html, true);
});
it('* option is null', () => {
const html = buildHtmlForTest({ marpAutoScaling: null });
expectMarpAutoScalingToEmbed(html, true);
});
it('* option is undefined', () => {
const html = buildHtmlForTest({ marpAutoScaling: undefined });
expectMarpAutoScalingToEmbed(html, true);
});
it('* option is \'\'', () => {
const html = buildHtmlForTest({ marpAutoScaling: '' });
expectMarpAutoScalingToEmbed(html, true);
});
it('* option is 1', () => {
const html = buildHtmlForTest({ marpAutoScaling: 1 });
expectMarpAutoScalingToEmbed(html, true);
});
it('* option is \'test\'', () => {
const html = buildHtmlForTest({ marpAutoScaling: 'test' });
expectMarpAutoScalingToEmbed(html, true);
});
it('* option is false', () => {
const html = buildHtmlForTest({ marpAutoScaling: false });
expectMarpAutoScalingToEmbed(html, false);
});
})
describe('### containerClass', () => {
function expectContainerClassToEmbed(htmlString, className) {
// parse dom
const dom = new JSDOM(htmlString);
const pTag = dom.window.document.getElementsByTagName("p")[0];
const actualClassName = pTag.getAttribute('class');
expect(actualClassName).to.equal(className);
}
it('* no options', () => {
const html = buildHtmlForTest();
expectContainerClassToEmbed(html, 'kroki-image-container');
});
it('* option is null', () => {
const html = buildHtmlForTest({ containerClass: null });
expectContainerClassToEmbed(html, 'kroki-image-container');
});
it('* option is undefined', () => {
const html = buildHtmlForTest({ containerClass: undefined });
expectContainerClassToEmbed(html, 'kroki-image-container');
});
it('* option is \'\'', () => {
const html = buildHtmlForTest({ containerClass: '' });
expectContainerClassToEmbed(html, 'kroki-image-container');
});
it('* option is 1', () => {
const html = buildHtmlForTest({ containerClass: 1 });
expectContainerClassToEmbed(html, 'kroki-image-container');
});
it('* option is \'containerClass\'', () => {
const html = buildHtmlForTest({ containerClass: 'containerClass' });
expectContainerClassToEmbed(html, 'containerClass');
});
});
describe('### imageFormat', () => {
function expectImageFormatToEmbed(htmlString, expected) {
// parse dom
const dom = new JSDOM(htmlString);
const imgTag = dom.window.document.getElementsByTagName("embed")[0];
// get url attribute
const url = imgTag.getAttribute('src');
expect(url).to.includes('/' + expected + '/');
}
it('* no options', () => {
const html = buildHtmlForTest();
expectImageFormatToEmbed(html, 'svg');
});
it('* option is null', () => {
const html = buildHtmlForTest({ imageFormat: null });
expectImageFormatToEmbed(html, 'svg');
});
it('* option is undefined', () => {
const html = buildHtmlForTest({ imageFormat: undefined });
expectImageFormatToEmbed(html, 'svg');
});
it('* option is \'\'', () => {
const html = buildHtmlForTest({ imageFormat: '' });
expectImageFormatToEmbed(html, 'svg');
});
it('* option is 1', () => {
const html = buildHtmlForTest({ imageFormat: 1 });
expectImageFormatToEmbed(html, 'svg');
});
it('* option is \'test\'', () => {
const html = buildHtmlForTest({ imageFormat: 'test' });
expectImageFormatToEmbed(html, 'svg');
});
it('* option is \'png\'', () => {
const html = buildHtmlForTest({ imageFormat: 'png' });
expectImageFormatToEmbed(html, 'png');
});
});
describe('### useImg', () => {
function expectUseImgTag(html, expectToUseImg) {
// parse dom
const dom = new JSDOM(html);
const imgTag = dom.window.document.getElementsByTagName("img")[0];
if(!expectToUseImg) {
expect(imgTag).to.be.undefined;
return;
} else {
expect(imgTag).not.to.be.undefined;
}
}
it('* no options', () => {
const html = buildHtmlForTest();
expectUseImgTag(html, false);
});
it('* option is true', () => {
const html = buildHtmlForTest({ useImg: true });
expectUseImgTag(html, true);
});
it('* option is null', () => {
const html = buildHtmlForTest({ useImg: null });
expectUseImgTag(html, false);
});
it('* option is undefined', () => {
const html = buildHtmlForTest({ useImg: undefined });
expectUseImgTag(html, false);
});
it('* option is \'\'', () => {
const html = buildHtmlForTest({ useImg: '' });
expectUseImgTag(html, false);
});
it('* option is 1', () => {
const html = buildHtmlForTest({ useImg: 1 });
expectUseImgTag(html, false);
});
});
describe('### render', () => {
it('* render was called', ()=>{
const renderCallback = sinon.fake();
buildHtmlForTest({ render: renderCallback });
expect(renderCallback.calledOnce).to.be.true;
});
it('* render was called with correct arg', ()=>{
const renderCallback = sinon.fake();
buildHtmlForTest({ render: renderCallback });
expect(renderCallback.firstCall.args[0]).to.be.an('string');
expect(renderCallback.firstCall.args[0]).to.includes('https://kroki.io');
expect(renderCallback.firstCall.args[1]).to.be.an('string');
expect(renderCallback.firstCall.args[1]).to.includes('test alt text');
});
it('* render the return value', ()=>{
const testReturnValue = '%%%%%test return value%%%%%';
const renderCallback = sinon.fake.returns(testReturnValue);
const html = buildHtmlForTest({ render: renderCallback });
expect(html).to.includes(testReturnValue);
})
it('* no options', () => {
expect(()=>{
buildHtmlForTest();
}).not.to.throw();
});
it('* option is true', () => {
expect(()=>{
buildHtmlForTest({ render: true });
}).not.to.throw();
});
it('* option is null', () => {
expect(()=>{
buildHtmlForTest({ render: false });
}).not.to.throw();
});
it('* option is undefined', () => {
expect(()=>{
buildHtmlForTest({ render: false });
}).not.to.throw();
});
it('* option is \'\'', () => {
expect(()=>{
buildHtmlForTest({ useImg: '' });
}).not.to.throw();
});
it('* option is 1', () => {
expect(()=>{
buildHtmlForTest({ useImg: 1 });
}).not.to.throw();
});
})
});
});
@@ -0,0 +1,49 @@
const expect = require('chai').expect;
const { MarkdownItKrokiCore } = require('../../lib/plugin-core');
describe('# [unit-test] plugin-core.js', () => {
describe('## static method: readLanguageAndAltText() - language', () => {
[
{ test: null, expected: '' },
{ test: undefined, expected: '' },
{ test: '', expected: '' },
{ test: ' ', expected: '' },
{ test: 'plantuml', expected: 'plantuml' },
{ test: ' plantuml', expected: 'plantuml' },
{ test: 'plantuml ', expected: 'plantuml' },
{ test: 'plantuml +++', expected: 'plantuml' },
{ test: 'html+md', expected: 'html+md' },
{ test: 'graphviz[]', expected: 'graphviz' },
{ test: 'graphviz[test]', expected: 'graphviz' },
{ test: 'graphviz [test test]', expected: 'graphviz' },
].forEach(testCase => {
it(`### Can read diagramLanguage. in case \'${testCase.test}\'`, () => {
const actual = MarkdownItKrokiCore.readLanguageAndAltText(testCase.test);
const expected = testCase.expected;
expect(actual.language).to.be.equal(expected);
})
});
});
describe('## static method: readLanguageAndAltText() - alt', () => {
[
{ test: null, expected: '' },
{ test: undefined, expected: '' },
{ test: '', expected: '' },
{ test: ' ', expected: '' },
{ test: 'plantuml', expected: '' },
{ test: ' plantuml', expected: '' },
{ test: 'plantuml ', expected: '' },
{ test: 'plantuml +++', expected: '' },
{ test: 'html+md', expected: '' },
{ test: 'graphviz[]', expected: '' },
{ test: 'graphviz[test]', expected: 'test' },
{ test: 'graphviz [test test]', expected: 'test test' },
].forEach(testCase => {
it(`### Can read diagramLanguage. in case \'${testCase.test}\'`, () => {
const actual = MarkdownItKrokiCore.readLanguageAndAltText(testCase.test);
const expected = testCase.expected;
expect(actual.alt).to.be.equal(expected);
})
});
});
});
@@ -0,0 +1,120 @@
const { expect } = require('chai');
const { safeProperty } = require('../../lib/safe-property');
describe('# [unit-test]: safe-property.js', () => {
[
{
testCaseDescription: "standard test - string",
testCase: {
test: {
property1: "hello"
},
name: "property1",
type: "string",
defaultValue: undefined
},
expected: "hello"
},
{
testCaseDescription: "standard test - boolean",
testCase: {
test: {
property1: true
},
name: "property1",
type: "boolean",
defaultValue: undefined
},
expected: true
},
{
testCaseDescription: "standard test - boolean on null",
testCase: {
test: {
property1: null
},
name: "property1",
type: "boolean",
defaultValue: false
},
expected: false
},
{
testCaseDescription: "on null",
testCase: {
test: {
property1: null
},
name: "property1",
type: "string",
defaultValue: "hello"
},
expected: "hello"
},
{
testCaseDescription: "on empty string",
testCase: {
test: {
property1: ''
},
name: "property1",
type: "string",
defaultValue: "hello"
},
expected: "hello"
},
{
testCaseDescription: "on undefined",
testCase: {
test: {
property1: undefined
},
name: "property1",
type: "string",
defaultValue: "hello"
},
expected: "hello"
},
{
testCaseDescription: "on not mutch type",
testCase: {
test: {
property1: 1
},
name: "property1",
type: "string",
defaultValue: "hello"
},
expected: "hello"
},
{
testCaseDescription: "on object is null",
testCase: {
test: null,
name: "property1",
type: "string",
defaultValue: "hello"
},
expected: "hello"
},
{
testCaseDescription: "on object is undefined",
testCase: {
test: undefined,
name: "property1",
type: "string",
defaultValue: "hello"
},
expected: "hello"
},
].forEach((testItem) => {
it(`* ${testItem.testCaseDescription}`, () => {
const actual = safeProperty(
testItem.testCase.test,
testItem.testCase.name,
testItem.testCase.type,
testItem.testCase.defaultValue);
expect(actual).to.equal(testItem.expected);
});
})
})