Skip to content

Commit b4b8bdc

Browse files
committed
add tests to make sure the global and plugin APIs are available and that configs can be functions
1 parent f72bf4c commit b4b8bdc

File tree

3 files changed

+120
-10
lines changed

3 files changed

+120
-10
lines changed

src/core/index.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import initGlobalAPI from './global-api';
1111
* @returns {Number|void} If the page is already laoded returns the result of the setTimeout callback,
1212
* otherwise it only attaches the callback to the DOMContentLoaded event
1313
*/
14-
function ready(callback) {
14+
export function documentReady(callback) {
1515
const state = document.readyState;
1616

1717
if (state === 'complete' || state === 'interactive') {
@@ -21,7 +21,7 @@ function ready(callback) {
2121
document.addEventListener('DOMContentLoaded', callback);
2222
}
2323

24-
function Docsify() {
24+
export function Docsify() {
2525
this._init();
2626
}
2727

@@ -42,4 +42,4 @@ initGlobalAPI();
4242
* Run Docsify
4343
*/
4444
// eslint-disable-next-line no-unused-vars
45-
ready(_ => new Docsify());
45+
documentReady(_ => new Docsify());

test/_helper.js

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,21 @@ function ready(callback) {
1919
document.addEventListener('DOMContentLoaded', callback);
2020
}
2121

22+
module.exports.initJSDOM = initJSDOM;
23+
24+
/** @param {string} markup - The HTML document to initialize JSDOM with. */
25+
function initJSDOM(markup, options = {}) {
26+
const dom = new JSDOM(markup, options);
27+
28+
global.window = dom.window;
29+
global.document = dom.window.document;
30+
global.navigator = dom.window.navigator;
31+
global.location = dom.window.location;
32+
global.XMLHttpRequest = dom.window.XMLHttpRequest;
33+
34+
return dom;
35+
}
36+
2237
module.exports.init = function(
2338
fixture = 'default',
2439
config = {},
@@ -39,15 +54,9 @@ module.exports.init = function(
3954

4055
const rootPath = path.join(__dirname, 'fixtures', fixture);
4156

42-
const dom = new JSDOM(markup);
57+
const dom = initJSDOM(markup);
4358
dom.reconfigure({ url: 'file:///' + rootPath });
4459

45-
global.window = dom.window;
46-
global.document = dom.window.document;
47-
global.navigator = dom.window.navigator;
48-
global.location = dom.window.location;
49-
global.XMLHttpRequest = dom.window.XMLHttpRequest;
50-
5160
// Mimic src/core/index.js but for Node.js
5261
function Docsify() {
5362
this._init();

test/unit/docsify.test.js

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/* eslint-disable no-global-assign */
2+
require = require('esm')(module /* , options */);
3+
4+
const path = require('path');
5+
const { expect } = require('chai');
6+
const { initJSDOM } = require('../_helper');
7+
8+
const docsifySite = path.join(__dirname, '..', '..', 'docs');
9+
10+
const markup = /* html */ `<!DOCTYPE html>
11+
<html>
12+
<head></head>
13+
<body>
14+
<div id="app"></div>
15+
</body>
16+
</html>
17+
`;
18+
19+
describe('Docsify public API', () => {
20+
it('is available', async () => {
21+
const DOM = initJSDOM(markup);
22+
DOM.reconfigure({ url: 'file:///' + docsifySite });
23+
24+
const { documentReady } = require('../../src/core/index');
25+
await new Promise(resolve => documentReady(resolve));
26+
27+
expect(typeof window.Docsify).to.equal('object');
28+
expect(typeof window.Docsify.util).to.equal('object');
29+
expect(typeof window.Docsify.dom).to.equal('object');
30+
expect(typeof window.Docsify.get).to.equal('function');
31+
expect(typeof window.Docsify.slugify).to.equal('function');
32+
expect(typeof window.Docsify.version).to.equal('string');
33+
34+
expect(window.DocsifyCompiler).to.be.an.instanceof(Function);
35+
expect(window.marked).to.be.an.instanceof(Function);
36+
expect(typeof window.Prism).to.equal('object');
37+
});
38+
});
39+
40+
describe('Docsify config function', function() {
41+
it('allows $docsify to be a function', async function() {
42+
const DOM = initJSDOM(markup);
43+
DOM.reconfigure({ url: 'file:///' + docsifySite });
44+
45+
window.configFunctionCalled = false;
46+
47+
window.$docsify = function(vm) {
48+
// Check public API (that which is available at this point)
49+
expect(vm).to.be.an.instanceof(Object);
50+
expect(vm.constructor.name).to.equal('Docsify');
51+
expect(vm.$fetch).to.be.an.instanceof(Function);
52+
expect(vm.$resetEvents).to.be.an.instanceof(Function);
53+
expect(vm.route).to.be.an.instanceof(Object);
54+
55+
window.configFunctionCalled = true;
56+
57+
return {};
58+
};
59+
60+
const { documentReady, Docsify } = require('../../src/core/index');
61+
await new Promise(resolve => documentReady(resolve));
62+
63+
new Docsify(); // eslint-disable-line
64+
65+
expect(window.configFunctionCalled).to.equal(true);
66+
});
67+
68+
it('provides the hooks and vm API to plugins', async function() {
69+
const DOM = initJSDOM(markup);
70+
DOM.reconfigure({ url: 'file:///' + docsifySite });
71+
72+
window.pluginFunctionCalled = false;
73+
74+
window.$docsify = function(vm) {
75+
const vm1 = vm;
76+
return {
77+
plugins: [
78+
function(hook, vm2) {
79+
expect(vm1).to.equal(vm2);
80+
81+
expect(hook.init).to.be.an.instanceof(Function);
82+
expect(hook.beforeEach).to.be.an.instanceof(Function);
83+
expect(hook.afterEach).to.be.an.instanceof(Function);
84+
expect(hook.doneEach).to.be.an.instanceof(Function);
85+
expect(hook.mounted).to.be.an.instanceof(Function);
86+
expect(hook.ready).to.be.an.instanceof(Function);
87+
88+
window.pluginFunctionCalled = true;
89+
},
90+
],
91+
};
92+
};
93+
94+
const { documentReady, Docsify } = require('../../src/core/index');
95+
await new Promise(resolve => documentReady(resolve));
96+
97+
new Docsify(); // eslint-disable-line
98+
99+
expect(window.pluginFunctionCalled).to.equal(true);
100+
});
101+
});

0 commit comments

Comments
 (0)