mirror of
https://github.com/documentationjs/documentation.git
synced 2025-12-08 18:23:43 +00:00
423 lines
11 KiB
JavaScript
423 lines
11 KiB
JavaScript
/* global jasmine */
|
|
|
|
const path = require('path');
|
|
const os = require('os');
|
|
const exec = require('child_process').exec;
|
|
const tmp = require('tmp');
|
|
const fs = require('fs-extra');
|
|
|
|
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
|
|
|
|
function documentation(args, options, parseJSON) {
|
|
if (!options) {
|
|
options = {};
|
|
}
|
|
if (!options.cwd) {
|
|
options.cwd = __dirname;
|
|
}
|
|
|
|
options.maxBuffer = 1024 * 1024;
|
|
|
|
args.unshift('node ' + path.join(__dirname, '..', 'bin', 'documentation.js'));
|
|
|
|
return new Promise((resolve, reject) => {
|
|
exec(args.join(' '), options, function(err, stdout, stderr) {
|
|
if (err) {
|
|
err.stderr = stderr;
|
|
return reject(err);
|
|
}
|
|
if (parseJSON === false) {
|
|
resolve(stdout);
|
|
} else {
|
|
try {
|
|
resolve(JSON.parse(stdout));
|
|
} catch (e) {
|
|
reject(e);
|
|
}
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
function normalize(result) {
|
|
result.forEach(function(item) {
|
|
item.context.file = '[path]';
|
|
});
|
|
return result;
|
|
}
|
|
|
|
test.skip('documentation binary', async function() {
|
|
const data = await documentation(['build fixture/simple.input.js'], {});
|
|
expect(data.length).toBe(1);
|
|
});
|
|
|
|
test.skip('defaults to parsing package.json main', async function() {
|
|
const data = await documentation(['build'], {
|
|
cwd: path.join(__dirname, '..')
|
|
});
|
|
expect(data.length).toBeTruthy();
|
|
});
|
|
|
|
test.skip('accepts config file', async function() {
|
|
const data = await documentation([
|
|
'build fixture/sorting/input.js -c fixture/config.json'
|
|
]);
|
|
expect(normalize(data)).toMatchSnapshot();
|
|
});
|
|
|
|
test.skip('accepts config file - reports failures', async function() {
|
|
try {
|
|
await documentation(
|
|
['build fixture/sorting/input.js -c fixture/config-bad.yml'],
|
|
{},
|
|
false
|
|
);
|
|
} catch (stderr) {
|
|
expect(stderr).toMatchSnapshot();
|
|
}
|
|
});
|
|
|
|
test.skip('accepts config file - reports parse failures', async function() {
|
|
try {
|
|
await documentation(
|
|
['build fixture/sorting/input.js -c fixture/config-malformed.json'],
|
|
{},
|
|
false
|
|
);
|
|
} catch (stderr) {
|
|
expect(stderr.stderr.match(/SyntaxError/g)).toBeTruthy();
|
|
}
|
|
});
|
|
|
|
test.skip('--shallow option', async function() {
|
|
const data = await documentation([
|
|
'build --shallow fixture/internal.input.js'
|
|
]);
|
|
expect(data.length).toBe(0);
|
|
});
|
|
|
|
test.skip('external modules option', async function() {
|
|
const data = await documentation([
|
|
'build fixture/external.input.js ' +
|
|
'--external=external --external=external/node_modules'
|
|
]);
|
|
expect(data.length).toBe(2);
|
|
});
|
|
|
|
test.skip('when a file is specified both in a glob and explicitly, it is only documented once', async function() {
|
|
const data = await documentation([
|
|
'build fixture/simple.input.js fixture/simple.input.*'
|
|
]);
|
|
expect(data.length).toBe(1);
|
|
});
|
|
|
|
test.skip('extension option', async function() {
|
|
const data = await documentation([
|
|
'build fixture/extension/index.otherextension ' +
|
|
'--requireExtension=otherextension --parseExtension=otherextension'
|
|
]);
|
|
expect(data.length).toBe(1);
|
|
});
|
|
|
|
test.skip('extension option', function() {
|
|
return documentation(['build fixture/extension.jsx']);
|
|
});
|
|
|
|
describe('invalid arguments', function() {
|
|
test.skip('bad -f option', async function() {
|
|
try {
|
|
await documentation(
|
|
['build -f DOES-NOT-EXIST fixture/internal.input.js'],
|
|
{},
|
|
false
|
|
);
|
|
} catch (err) {
|
|
expect(err).toBeTruthy();
|
|
}
|
|
});
|
|
|
|
test.skip('html with no destination', async function() {
|
|
try {
|
|
await documentation(['build -f html fixture/internal.input.js']);
|
|
} catch (err) {
|
|
expect(
|
|
err
|
|
.toString()
|
|
.match(
|
|
/The HTML output mode requires a destination directory set with -o/
|
|
)
|
|
).toBeTruthy();
|
|
}
|
|
});
|
|
|
|
test.skip('bad command', async function() {
|
|
try {
|
|
await documentation(['-f html fixture/internal.input.js'], {}, false);
|
|
} catch (err) {
|
|
expect(err.code).toBeTruthy();
|
|
}
|
|
});
|
|
});
|
|
|
|
const semver = /\bv?(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:-[\da-z-]+(?:\.[\da-z-]+)*)?(?:\+[\da-z-]+(?:\.[\da-z-]+)*)?\b/gi;
|
|
test.skip('--config', async function() {
|
|
const dst = path.join(os.tmpdir(), (Date.now() + Math.random()).toString());
|
|
fs.mkdirSync(dst);
|
|
const outputIndex = path.join(dst, 'index.html');
|
|
const data = await documentation(
|
|
[
|
|
'build -c fixture/html/documentation.yml -f html fixture/html/nested.input.js -o ' +
|
|
dst
|
|
],
|
|
{},
|
|
false
|
|
);
|
|
let output = fs.readFileSync(outputIndex, 'utf8');
|
|
const version = require('../package.json').version;
|
|
output = output.replace(new RegExp(version.replace(/\./g, '\\.'), 'g'), '');
|
|
expect(output).toMatchSnapshot();
|
|
});
|
|
|
|
test.skip('--version', async function() {
|
|
const output = await documentation(['--version'], {}, false);
|
|
expect(output).toBeTruthy();
|
|
});
|
|
|
|
describe('lint command', function() {
|
|
test.skip('generates lint output', async function() {
|
|
try {
|
|
await documentation(['lint fixture/lint/lint.input.js'], {}, false);
|
|
} catch (err) {
|
|
const data = err.stderr
|
|
.toString()
|
|
.split('\n')
|
|
.slice(2)
|
|
.join('\n');
|
|
expect(data).toMatchSnapshot();
|
|
}
|
|
});
|
|
|
|
test.skip('generates no output on a good file', async function() {
|
|
const data = await documentation(
|
|
['lint fixture/simple.input.js'],
|
|
{},
|
|
false
|
|
);
|
|
expect(data).toBe('');
|
|
});
|
|
|
|
test.skip('exposes syntax error on a bad file', async function() {
|
|
try {
|
|
await documentation(
|
|
['lint fixture/bad/syntax.input', '--parseExtension input'],
|
|
{},
|
|
false
|
|
);
|
|
} catch (err) {
|
|
expect(err.code > 0).toBeTruthy();
|
|
}
|
|
});
|
|
|
|
test.skip('lint with no inputs', async function() {
|
|
try {
|
|
await documentation(
|
|
['lint'],
|
|
{
|
|
cwd: path.join(__dirname, 'fixture/bad')
|
|
},
|
|
false
|
|
);
|
|
} catch (err) {
|
|
expect(err.code > 0).toBeTruthy();
|
|
}
|
|
});
|
|
|
|
test.skip('generates lint output with shallow', async function() {
|
|
const data = await documentation(
|
|
['lint fixture/lint/lint.input.shallow.js --shallow'],
|
|
{},
|
|
false
|
|
);
|
|
expect(data).toBe('');
|
|
});
|
|
});
|
|
|
|
test.skip('given no files', async function() {
|
|
try {
|
|
await documentation(['build']);
|
|
} catch (err) {
|
|
expect(
|
|
err
|
|
.toString()
|
|
.match(
|
|
/documentation was given no files and was not run in a module directory/
|
|
)
|
|
).toBeTruthy();
|
|
}
|
|
});
|
|
|
|
test.skip('with an invalid command', async function() {
|
|
try {
|
|
await documentation(['invalid'], {}, false);
|
|
} catch (err) {
|
|
expect(err).toBeTruthy();
|
|
}
|
|
});
|
|
|
|
test.skip('--access flag', async function() {
|
|
const data = await documentation(
|
|
['build --shallow fixture/internal.input.js -a public'],
|
|
{},
|
|
false
|
|
);
|
|
expect(data).toBe('[]');
|
|
});
|
|
|
|
test.skip('--private flag', async function() {
|
|
const data = await documentation(
|
|
['build fixture/internal.input.js --private'],
|
|
{},
|
|
false
|
|
);
|
|
expect(data.length > 2).toBeTruthy();
|
|
});
|
|
|
|
test.skip('--infer-private flag', async function() {
|
|
const data = await documentation(
|
|
['build fixture/infer-private.input.js --infer-private ^_'],
|
|
{},
|
|
false
|
|
);
|
|
// This uses JSON.parse with a reviver used as a visitor.
|
|
JSON.parse(data, function(n, v) {
|
|
// Make sure we do not see any names that match `^_`.
|
|
if (n === 'name') {
|
|
expect(typeof v).toBe('string');
|
|
expect(!/_$/.test.skip(v)).toBeTruthy();
|
|
}
|
|
return v;
|
|
});
|
|
});
|
|
|
|
test.skip('write to file', async function() {
|
|
const dst = path.join(os.tmpdir(), (Date.now() + Math.random()).toString());
|
|
|
|
const data = await documentation(
|
|
['build --shallow fixture/internal.input.js -o ' + dst],
|
|
{},
|
|
false
|
|
);
|
|
expect(data).toBe('');
|
|
expect(fs.existsSync(dst)).toBeTruthy();
|
|
});
|
|
|
|
test.skip('write to html', async function() {
|
|
const dstDir = path.join(
|
|
os.tmpdir(),
|
|
(Date.now() + Math.random()).toString()
|
|
);
|
|
fs.mkdirSync(dstDir);
|
|
|
|
const data = await documentation(
|
|
['build --shallow fixture/internal.input.js -f html -o ' + dstDir],
|
|
{},
|
|
false
|
|
);
|
|
expect(data).toBe('');
|
|
expect(fs.existsSync(path.join(dstDir, 'index.html'))).toBeTruthy();
|
|
});
|
|
|
|
test.skip('write to html with custom theme', async function() {
|
|
const dstDir = path.join(
|
|
os.tmpdir(),
|
|
(Date.now() + Math.random()).toString()
|
|
);
|
|
fs.mkdirSync(dstDir);
|
|
|
|
const data = await documentation(
|
|
[
|
|
'build -t fixture/custom_theme --shallow fixture/internal.input.js -f html -o ' +
|
|
dstDir
|
|
],
|
|
{},
|
|
false
|
|
);
|
|
expect(data).toBe('');
|
|
expect(fs.readFileSync(path.join(dstDir, 'index.html'), 'utf8')).toBeTruthy();
|
|
});
|
|
|
|
test.skip('write to html, highlightAuto', function() {
|
|
const fixture = 'fixture/auto_lang_hljs/multilanguage.input.js';
|
|
const config = 'fixture/auto_lang_hljs/config.yml';
|
|
const dstDir = path.join(
|
|
os.tmpdir(),
|
|
(Date.now() + Math.random()).toString()
|
|
);
|
|
|
|
fs.mkdirSync(dstDir);
|
|
|
|
return documentation(
|
|
['build --shallow ' + fixture + ' -c ' + config + ' -f html -o ' + dstDir],
|
|
{},
|
|
false
|
|
).then(() => {
|
|
const result = fs.readFileSync(path.join(dstDir, 'index.html'), 'utf8');
|
|
expect(
|
|
result.indexOf('<span class="hljs-number">42</span>') > 0
|
|
).toBeTruthy();
|
|
expect(
|
|
result.indexOf('<span class="hljs-selector-attr">[data-foo]</span>') > 0
|
|
).toBeTruthy();
|
|
expect(
|
|
result.indexOf('<span class="hljs-attr">data-foo</span>') > 0
|
|
).toBeTruthy();
|
|
});
|
|
});
|
|
|
|
test.skip('fatal error', async function() {
|
|
try {
|
|
await documentation(
|
|
['build --shallow fixture/bad/syntax.input --parseExtension input'],
|
|
{},
|
|
false
|
|
);
|
|
} catch (err) {
|
|
expect(err.toString().match(/Unexpected token/)).toBeTruthy();
|
|
}
|
|
});
|
|
|
|
test.skip('build --document-exported', async function() {
|
|
const data = await documentation(
|
|
['build fixture/document-exported.input.js --document-exported -f md'],
|
|
{},
|
|
false
|
|
);
|
|
expect(data).toMatchSnapshot();
|
|
});
|
|
|
|
test.skip('build large file without error (no deoptimized styling error)', function() {
|
|
const dstFile =
|
|
path.join(os.tmpdir(), (Date.now() + Math.random()).toString()) + '.js';
|
|
let contents = '';
|
|
for (let i = 0; i < 4e4; i++) {
|
|
contents += '/* - */\n';
|
|
}
|
|
fs.writeFileSync(dstFile, contents, 'utf8');
|
|
|
|
return documentation(['build ' + dstFile], {}, false).then(() => {
|
|
fs.unlinkSync(dstFile);
|
|
});
|
|
});
|
|
|
|
test.skip('should use browser resolve', async function() {
|
|
const data = await documentation(['build fixture/resolve/index.js']);
|
|
expect(normalize(data)).toMatchSnapshot();
|
|
});
|
|
|
|
test.skip('should use node resolve', async function() {
|
|
const data = await documentation([
|
|
'build fixture/resolve/index.js --resolve node'
|
|
]);
|
|
expect(normalize(data)).toMatchSnapshot();
|
|
});
|