[doclint] move doclint testing to golden
This patch: - move doclint testing to golden - refactor doclint/lint.js to drop specs and everything
This commit is contained in:
parent
9b2e9ce6ca
commit
c468c451c5
1
utils/doclint/.gitignore
vendored
Normal file
1
utils/doclint/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
output/
|
@ -1,4 +1,3 @@
|
|||||||
const {describe, it, fail, runSpecs} = require('./specRunner');
|
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const jsBuilder = require('./JSBuilder');
|
const jsBuilder = require('./JSBuilder');
|
||||||
const mdBuilder = require('./MDBuilder');
|
const mdBuilder = require('./MDBuilder');
|
||||||
@ -29,101 +28,88 @@ let EXCLUDE_METHODS = new Set([
|
|||||||
'Response.constructor',
|
'Response.constructor',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const browser = new Browser({args: ['--no-sandbox']});
|
/**
|
||||||
browser.newPage()
|
* @param {!Page} page
|
||||||
.then(initializeSpecs)
|
* @param {string} docsFolderPath
|
||||||
.then(runSpecs)
|
* @param {string} jsFolderPath
|
||||||
.catch(console.error)
|
* @return {!Promise<!Array<string>>}
|
||||||
.then(() => browser.close());
|
*/
|
||||||
|
async function lint(page, docsFolderPath, jsFolderPath) {
|
||||||
async function initializeSpecs(page) {
|
let mdResult = await mdBuilder(page, docsFolderPath);
|
||||||
let jsResult = await jsBuilder(path.join(PROJECT_DIR, 'lib'));
|
let jsResult = await jsBuilder(jsFolderPath);
|
||||||
let mdResult = await mdBuilder(page, path.join(PROJECT_DIR, 'docs'));
|
|
||||||
let jsDocumentation = filterJSDocumentation(jsResult);
|
let jsDocumentation = filterJSDocumentation(jsResult);
|
||||||
let mdDocumentation = mdResult.documentation;
|
let mdDocumentation = mdResult.documentation;
|
||||||
let diff = Documentation.diff(mdDocumentation, jsDocumentation);
|
let diff = Documentation.diff(mdDocumentation, jsDocumentation);
|
||||||
|
|
||||||
describe('JavaScript documentation parser', function() {
|
let jsErrors = [];
|
||||||
it('should not contain any duplicate classes (probably error in parsing!)', () => {
|
let mdErrors = [];
|
||||||
let jsClasses = new Map();
|
|
||||||
for (let jsClass of jsDocumentation.classesArray) {
|
|
||||||
if (jsClasses.has(jsClass.name))
|
|
||||||
fail(`JavaScript has duplicate declaration of ${jsClass.name}. (This probably means that this linter has an error)`);
|
|
||||||
jsClasses.set(jsClass.name, jsClass);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Markdown Documentation', function() {
|
// Report all markdown parse errors.
|
||||||
it('should not have any parse errors', () => {
|
mdErrors.push(...mdResult.errors);
|
||||||
for (let error of mdResult.errors)
|
{
|
||||||
fail(error);
|
// Report duplicate JavaScript classes.
|
||||||
});
|
let jsClasses = new Map();
|
||||||
it('should not contain any duplicate classes', () => {
|
for (let jsClass of jsDocumentation.classesArray) {
|
||||||
let mdClasses = new Map();
|
if (jsClasses.has(jsClass.name))
|
||||||
for (let mdClass of mdDocumentation.classesArray) {
|
jsErrors.push(`Duplicate declaration of class ${jsClass.name}`);
|
||||||
if (mdClasses.has(mdClass.name))
|
jsClasses.set(jsClass.name, jsClass);
|
||||||
fail(`Documentation has duplicate declaration of class ${mdClass.name}`);
|
}
|
||||||
mdClasses.set(mdClass.name, mdClass);
|
}
|
||||||
}
|
{
|
||||||
});
|
// Report duplicate MarkDown classes.
|
||||||
it('class constructors should be defined before other methods', () => {
|
let mdClasses = new Map();
|
||||||
for (let mdClass of mdDocumentation.classesArray) {
|
for (let mdClass of mdDocumentation.classesArray) {
|
||||||
let constructorMethod = mdClass.methods.get('constructor');
|
if (mdClasses.has(mdClass.name))
|
||||||
if (!constructorMethod)
|
mdErrors.push(`Duplicate declaration of class ${mdClass.name}`);
|
||||||
|
mdClasses.set(mdClass.name, mdClass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// Make sure class constructors are defined before other methods.
|
||||||
|
for (let mdClass of mdDocumentation.classesArray) {
|
||||||
|
let constructorMethod = mdClass.methods.get('constructor');
|
||||||
|
if (!constructorMethod)
|
||||||
|
continue;
|
||||||
|
if (mdClass.methodsArray[0] !== constructorMethod)
|
||||||
|
mdErrors.push(`Constructor of ${mdClass.name} should go before other methods`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// Methods should be sorted alphabetically.
|
||||||
|
for (let mdClass of mdDocumentation.classesArray) {
|
||||||
|
for (let i = 0; i < mdClass.methodsArray.length - 1; ++i) {
|
||||||
|
// Constructor should always go first.
|
||||||
|
if (mdClass.methodsArray[i].name === 'constructor')
|
||||||
continue;
|
continue;
|
||||||
if (mdClass.methodsArray[0] !== constructorMethod)
|
let method1 = mdClass.methodsArray[i];
|
||||||
fail(`Method 'new ${mdClass.name}' should go before other methods of class ${mdClass.name}`);
|
let method2 = mdClass.methodsArray[i + 1];
|
||||||
|
if (method1.name > method2.name)
|
||||||
|
mdErrors.push(`${mdClass.name}.${method1.name} breaks alphabetic sorting inside class ${mdClass.name}`);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
it('methods should be sorted alphabetically', () => {
|
}
|
||||||
for (let mdClass of mdDocumentation.classesArray) {
|
// Report non-existing and missing classes.
|
||||||
for (let i = 0; i < mdClass.methodsArray.length - 1; ++i) {
|
mdErrors.push(...diff.extraClasses.map(className => `Non-existing class found: ${className}`));
|
||||||
// Constructor should always go first.
|
mdErrors.push(...diff.missingClasses.map(className => `Class not found: ${className}`));
|
||||||
if (mdClass.methodsArray[i].name === 'constructor')
|
mdErrors.push(...diff.extraMethods.map(methodName => `Non-existing method found: ${methodName}`));
|
||||||
continue;
|
mdErrors.push(...diff.missingMethods.map(methodName => `Method not found: ${methodName}`));
|
||||||
let method1 = mdClass.methodsArray[i];
|
mdErrors.push(...diff.extraProperties.map(propertyName => `Non-existing property found: ${propertyName}`));
|
||||||
let method2 = mdClass.methodsArray[i + 1];
|
mdErrors.push(...diff.missingProperties.map(propertyName => `Property not found: ${propertyName}`));
|
||||||
if (method1.name > method2.name)
|
{
|
||||||
fail(`${mdClass.name}.${method1.name} breaks alphabetic sorting inside class ${mdClass.name}`);
|
// Report badly described arguments.
|
||||||
}
|
for (let badArgument of diff.badArguments) {
|
||||||
}
|
let text = [`Method ${badArgument.method} fails to describe its parameters:`];
|
||||||
});
|
for (let missing of badArgument.missingArgs)
|
||||||
it('should not contain any non-existing class', () => {
|
text.push(`- Missing description for "${missing}"`);
|
||||||
for (let className of diff.extraClasses)
|
for (let extra of badArgument.extraArgs)
|
||||||
fail(`Documentation describes non-existing class ${className}`);
|
text.push(`- Described non-existing parameter "${extra}"`);
|
||||||
});
|
mdErrors.push(text.join('\n'));
|
||||||
it('should describe all existing classes', () => {
|
}
|
||||||
for (let className of diff.missingClasses)
|
}
|
||||||
fail(`Documentation lacks description of class ${className}`);
|
// Push all errors with proper prefixes
|
||||||
});
|
let errors = jsErrors.map(error => '[JavaScript] ' + error);
|
||||||
it('should not contain any non-existing methods', () => {
|
errors.push(...mdErrors.map(error => '[MarkDown] ' + error));
|
||||||
for (let methodName of diff.extraMethods)
|
return errors;
|
||||||
fail(`Documentation describes non-existing method: ${methodName}`);
|
|
||||||
});
|
|
||||||
it('should describe all existing methods', () => {
|
|
||||||
for (let methodName of diff.missingMethods)
|
|
||||||
fail(`Documentation lacks method ${methodName}`);
|
|
||||||
});
|
|
||||||
it('should describe all arguments propertly', () => {
|
|
||||||
for (let badArgument of diff.badArguments) {
|
|
||||||
let text = [`Method ${badArgument.method} fails to describe its parameters:`];
|
|
||||||
for (let missing of badArgument.missingArgs)
|
|
||||||
text.push(`- Missing description for "${missing}"`);
|
|
||||||
for (let extra of badArgument.extraArgs)
|
|
||||||
text.push(`- Described non-existing parameter "${extra}"`);
|
|
||||||
fail(text.join('\n'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
it('should not contain any non-existing properties', () => {
|
|
||||||
for (let propertyName of diff.extraProperties)
|
|
||||||
fail(`Documentation describes non-existing property: ${propertyName}`);
|
|
||||||
});
|
|
||||||
it('should describe all existing properties', () => {
|
|
||||||
for (let propertyName of diff.missingProperties)
|
|
||||||
fail(`Documentation lacks property ${propertyName}`);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -146,3 +132,30 @@ function filterJSDocumentation(jsDocumentation) {
|
|||||||
}
|
}
|
||||||
return new Documentation(classes);
|
return new Documentation(classes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module.exports = lint;
|
||||||
|
|
||||||
|
const RED_COLOR = '\x1b[31m';
|
||||||
|
const RESET_COLOR = '\x1b[0m';
|
||||||
|
|
||||||
|
// Handle CLI invocation.
|
||||||
|
if (!module.parent) {
|
||||||
|
const startTime = Date.now();
|
||||||
|
const browser = new Browser({args: ['--no-sandbox']});
|
||||||
|
browser.newPage().then(async page => {
|
||||||
|
const errors = await lint(page, path.join(PROJECT_DIR, 'docs'), path.join(PROJECT_DIR, 'lib'));
|
||||||
|
await browser.close();
|
||||||
|
if (errors.length) {
|
||||||
|
console.log('Documentation Failures:');
|
||||||
|
for (let i = 0; i < errors.length; ++i) {
|
||||||
|
let error = errors[i];
|
||||||
|
error = error.split('\n').join('\n ');
|
||||||
|
console.log(`${i + 1}) ${RED_COLOR}${error}${RESET_COLOR}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(`${errors.length} failures`);
|
||||||
|
const runningTime = Date.now() - startTime;
|
||||||
|
console.log(`Finished in ${runningTime / 1000} seconds`);
|
||||||
|
process.exit(errors.length > 0 ? 1 : 0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@ -1,85 +0,0 @@
|
|||||||
const startTime = Date.now();
|
|
||||||
let allTests = [];
|
|
||||||
let titles = [];
|
|
||||||
let currentTest = null;
|
|
||||||
|
|
||||||
const colors = {
|
|
||||||
reset: '\x1b[0m',
|
|
||||||
red: '\x1b[31m',
|
|
||||||
green: '\x1b[32m',
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} title
|
|
||||||
* @param {function()} fun
|
|
||||||
*/
|
|
||||||
function describe(title, fun) {
|
|
||||||
titles.push(title);
|
|
||||||
fun();
|
|
||||||
titles.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} title
|
|
||||||
* @param {function()} fun
|
|
||||||
*/
|
|
||||||
function it(title, fun) {
|
|
||||||
titles.push(title);
|
|
||||||
allTests.push({
|
|
||||||
errors: [],
|
|
||||||
title: titles.join(' '),
|
|
||||||
fun,
|
|
||||||
});
|
|
||||||
titles.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} msg
|
|
||||||
*/
|
|
||||||
function fail(msg) {
|
|
||||||
currentTest.errors.push(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
function runSpecs() {
|
|
||||||
console.log('Started\n');
|
|
||||||
for (currentTest of allTests) {
|
|
||||||
currentTest.fun();
|
|
||||||
if (currentTest.errors.length)
|
|
||||||
process.stdout.write(`${colors.red}F${colors.reset}`);
|
|
||||||
else
|
|
||||||
process.stdout.write(`${colors.green}.${colors.reset}`);
|
|
||||||
}
|
|
||||||
console.log('\n');
|
|
||||||
reportErrors();
|
|
||||||
}
|
|
||||||
|
|
||||||
function reportErrors() {
|
|
||||||
let failedTests = allTests.filter(test => !!test.errors.length);
|
|
||||||
if (failedTests.length) {
|
|
||||||
console.log('Failures:');
|
|
||||||
for (let i = 0; i < failedTests.length; ++i) {
|
|
||||||
let test = failedTests[i];
|
|
||||||
console.log(`${i + 1}) ${test.title}`);
|
|
||||||
console.log(` Messages:`);
|
|
||||||
for (let error of test.errors) {
|
|
||||||
error = error.split('\n').join('\n ');
|
|
||||||
console.log(' * ' + colors.red + error + colors.reset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log('');
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`Ran ${allTests.length} specs`);
|
|
||||||
console.log(`${allTests.length} specs, ${failedTests.length} failures`);
|
|
||||||
const runningTime = Date.now() - startTime;
|
|
||||||
console.log(`Finished in ${runningTime / 1000} seconds`);
|
|
||||||
process.exit(failedTests.length > 0 ? 1 : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
describe,
|
|
||||||
it,
|
|
||||||
fail,
|
|
||||||
runSpecs,
|
|
||||||
};
|
|
||||||
|
|
3
utils/doclint/test/01-class-errors/01-class-errors.txt
Normal file
3
utils/doclint/test/01-class-errors/01-class-errors.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[MarkDown] Non-existing class found: Bar
|
||||||
|
[MarkDown] Non-existing class found: Baz
|
||||||
|
[MarkDown] Class not found: Other
|
@ -1,3 +1,5 @@
|
|||||||
### class: Foo
|
### class: Foo
|
||||||
|
|
||||||
### class: Bar
|
### class: Bar
|
||||||
|
|
||||||
|
### class: Baz
|
2
utils/doclint/test/01-class-errors/other.js
Normal file
2
utils/doclint/test/01-class-errors/other.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
class Other {
|
||||||
|
}
|
6
utils/doclint/test/02-method-errors/doc.md
Normal file
6
utils/doclint/test/02-method-errors/doc.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
### class: Foo
|
||||||
|
|
||||||
|
#### foo.proceed()
|
||||||
|
|
||||||
|
#### foo.start()
|
||||||
|
|
7
utils/doclint/test/02-method-errors/foo.js
Normal file
7
utils/doclint/test/02-method-errors/foo.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
class Foo {
|
||||||
|
start() {
|
||||||
|
}
|
||||||
|
|
||||||
|
stop() {
|
||||||
|
}
|
||||||
|
}
|
@ -1,2 +0,0 @@
|
|||||||
### class: Foo
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
|||||||
class Foo {
|
|
||||||
bar() {
|
|
||||||
}
|
|
||||||
}
|
|
5
utils/doclint/test/03-property-errors/doc.md
Normal file
5
utils/doclint/test/03-property-errors/doc.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
### class: Foo
|
||||||
|
|
||||||
|
#### foo.a
|
||||||
|
|
||||||
|
#### foo.c
|
7
utils/doclint/test/03-property-errors/foo.js
Normal file
7
utils/doclint/test/03-property-errors/foo.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
class Foo {
|
||||||
|
constructor() {
|
||||||
|
this.a = 42;
|
||||||
|
this.b = 'hello';
|
||||||
|
this.emit('done');
|
||||||
|
}
|
||||||
|
}
|
7
utils/doclint/test/04-bad-arguments/doc.md
Normal file
7
utils/doclint/test/04-bad-arguments/doc.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
### class: Foo
|
||||||
|
#### new Foo(arg1, arg2)
|
||||||
|
- `arg1` <[string]>
|
||||||
|
- `arg2` <[string]>
|
||||||
|
|
||||||
|
#### foo.test(fileNames)
|
||||||
|
- `filePaths` <[Array]>
|
7
utils/doclint/test/04-bad-arguments/foo.js
Normal file
7
utils/doclint/test/04-bad-arguments/foo.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
class Foo {
|
||||||
|
constructor(arg1, arg3) {
|
||||||
|
}
|
||||||
|
|
||||||
|
test(filePaths) {
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +0,0 @@
|
|||||||
### class: Foo
|
|
||||||
|
|
||||||
#### foo.bar()
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
|||||||
class Foo {
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
### class: Foo
|
|
||||||
|
|
||||||
#### new Foo()
|
|
@ -1,5 +0,0 @@
|
|||||||
class Foo {
|
|
||||||
constructor() {
|
|
||||||
this.barProperty = 42;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
### class: Foo
|
|
||||||
|
|
||||||
#### foo.bazProperty
|
|
@ -1,4 +0,0 @@
|
|||||||
class Foo {
|
|
||||||
constructor() {
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
### class: Foo
|
|
||||||
|
|
||||||
#### new Foo(arg2)
|
|
||||||
- `arg2` <[string]> Some arg.
|
|
@ -1,4 +0,0 @@
|
|||||||
class Foo {
|
|
||||||
constructor(arg1) {
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,2 +0,0 @@
|
|||||||
class Foo {
|
|
||||||
}
|
|
3
utils/doclint/test/golden/01-class-errors.txt
Normal file
3
utils/doclint/test/golden/01-class-errors.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[MarkDown] Non-existing class found: Bar
|
||||||
|
[MarkDown] Non-existing class found: Baz
|
||||||
|
[MarkDown] Class not found: Other
|
2
utils/doclint/test/golden/02-method-errors.txt
Normal file
2
utils/doclint/test/golden/02-method-errors.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
[MarkDown] Non-existing method found: Foo.proceed
|
||||||
|
[MarkDown] Method not found: Foo.stop
|
3
utils/doclint/test/golden/03-property-errors.txt
Normal file
3
utils/doclint/test/golden/03-property-errors.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[MarkDown] Method not found: Foo.constructor
|
||||||
|
[MarkDown] Non-existing property found: Foo.c
|
||||||
|
[MarkDown] Property not found: Foo.b
|
4
utils/doclint/test/golden/04-bad-arguments.txt
Normal file
4
utils/doclint/test/golden/04-bad-arguments.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
[MarkDown] Heading arguments for "foo.test(fileNames)" do not match described ones, i.e. "fileNames" != "filePaths"
|
||||||
|
[MarkDown] Method Foo.constructor fails to describe its parameters:
|
||||||
|
- Missing description for "arg3"
|
||||||
|
- Described non-existing parameter "arg2"
|
1
utils/doclint/test/golden/05-outdated-toc.txt
Normal file
1
utils/doclint/test/golden/05-outdated-toc.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
[MarkDown] Markdown TOC is outdated, run `yarn generate-toc`
|
@ -1,69 +1,47 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
const rm = require('rimraf').sync;
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const jsBuilder = require('../JSBuilder');
|
|
||||||
const mdBuilder = require('../MDBuilder');
|
|
||||||
const Documentation = require('../Documentation');
|
|
||||||
const Browser = require('../../../lib/Browser');
|
const Browser = require('../../../lib/Browser');
|
||||||
|
const doclint = require('../lint');
|
||||||
|
const GoldenUtils = require('../../../test/golden-utils');
|
||||||
|
|
||||||
|
const OUTPUT_DIR = path.join(__dirname, 'output');
|
||||||
|
const GOLDEN_DIR = path.join(__dirname, 'golden');
|
||||||
|
|
||||||
const browser = new Browser({args: ['--no-sandbox']});
|
const browser = new Browser({args: ['--no-sandbox']});
|
||||||
let page;
|
let page;
|
||||||
|
let specName;
|
||||||
|
|
||||||
|
jasmine.getEnv().addReporter({
|
||||||
|
specStarted: result => specName = result.description
|
||||||
|
});
|
||||||
|
|
||||||
beforeAll(SX(async function() {
|
beforeAll(SX(async function() {
|
||||||
page = await browser.newPage();
|
page = await browser.newPage();
|
||||||
|
if (fs.existsSync(OUTPUT_DIR))
|
||||||
|
rm(OUTPUT_DIR);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
afterAll(SX(async function() {
|
afterAll(SX(async function() {
|
||||||
await browser.close();
|
await browser.close();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe('doclint', function() {
|
beforeEach(function() {
|
||||||
test('01-missing-class', diff => {
|
GoldenUtils.addMatchers(jasmine, GOLDEN_DIR, OUTPUT_DIR);
|
||||||
expect(diff.missingClasses.length).toBe(1);
|
|
||||||
expect(diff.missingClasses[0]).toBe('Foo');
|
|
||||||
});
|
|
||||||
test('02-extra-class', diff => {
|
|
||||||
expect(diff.extraClasses.length).toBe(1);
|
|
||||||
expect(diff.extraClasses[0]).toBe('Bar');
|
|
||||||
});
|
|
||||||
test('03-missing-method', diff => {
|
|
||||||
expect(diff.missingMethods.length).toBe(1);
|
|
||||||
expect(diff.missingMethods[0]).toBe('Foo.bar');
|
|
||||||
});
|
|
||||||
test('04-extra-method', diff => {
|
|
||||||
expect(diff.extraMethods.length).toBe(1);
|
|
||||||
expect(diff.extraMethods[0]).toBe('Foo.bar');
|
|
||||||
});
|
|
||||||
test('05-missing-property', diff => {
|
|
||||||
expect(diff.missingProperties.length).toBe(1);
|
|
||||||
expect(diff.missingProperties[0]).toBe('Foo.barProperty');
|
|
||||||
});
|
|
||||||
test('06-extra-property', diff => {
|
|
||||||
expect(diff.extraProperties.length).toBe(1);
|
|
||||||
expect(diff.extraProperties[0]).toBe('Foo.bazProperty');
|
|
||||||
});
|
|
||||||
test('07-bad-arguments', diff => {
|
|
||||||
expect(diff.badArguments.length).toBe(1);
|
|
||||||
expect(diff.badArguments[0]).toEqual({
|
|
||||||
method: 'Foo.constructor',
|
|
||||||
missingArgs: ['arg1'],
|
|
||||||
extraArgs: ['arg2']
|
|
||||||
});
|
|
||||||
});
|
|
||||||
test('08-outdated-table-of-contents', (diff, mdErrors) => {
|
|
||||||
expect(mdErrors.length).toBe(1);
|
|
||||||
expect(mdErrors[0]).toBe('Markdown TOC is outdated, run `yarn generate-toc`');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
async function test(folderName, func) {
|
describe('doclint', function() {
|
||||||
it(folderName, SX(async () => {
|
it('01-class-errors', SX(test));
|
||||||
const [jsResult, mdResult] = await Promise.all([
|
it('02-method-errors', SX(test));
|
||||||
jsBuilder(path.join(__dirname, folderName)),
|
it('03-property-errors', SX(test));
|
||||||
mdBuilder(page, path.join(__dirname, folderName))
|
it('04-bad-arguments', SX(test));
|
||||||
]);
|
it('05-outdated-toc', SX(test));
|
||||||
const jsDocumentation = jsResult;
|
});
|
||||||
const mdDocumentation = mdResult.documentation;
|
|
||||||
func(Documentation.diff(mdDocumentation, jsDocumentation), mdResult.errors);
|
async function test() {
|
||||||
}));
|
const filePath = path.join(__dirname, specName);
|
||||||
|
const errors = await doclint(page, filePath, filePath);
|
||||||
|
expect(errors.join('\n')).toBeGolden(specName + '.txt');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Since Jasmine doesn't like async functions, they should be wrapped
|
// Since Jasmine doesn't like async functions, they should be wrapped
|
||||||
|
Loading…
Reference in New Issue
Block a user