protocol/packages/sol-doc/test/gen_md_test.ts
Lawrence Forman b7b457b076
Generate (complete) solidity docs (#2391)
* `@0x/sol-doc`: New doc generator.

* `@0x/sol-compiler`: Be more tolerant of AST-only compilation targets.

* `@0x/contracts-exchange`: Add more devdoc comments.
`@0x/contracts-exchange-libs`: Add more devdoc comments.

* `@0x/sol-doc`: Update package script.

* `@0x/sol-doc`: Remove unused files and update package scripts to be easier to configure.

* Add more devdocs to contracts.

* `@0x/sol-doc`: Remove doc artifacts.

* `@0x/sol-doc`: Add `.gitignore` and `.npmignore`.

* `@0x/contracts-exchange`: Fix compilation errors.

* Fix more broken contracts.

* `@0x/contracts-erc20-bridge-sampler`: Fix failing tests.

* `@0x/contracts-asset-proxy`: Remove accidentally introduced hackathion file (lol).

* `@0x/sol-doc`: Prevent some inherited contracts from being included in docs unintentionally.

* `@0x/sol-doc`: Rename test file.

* `@0x/contracts-exchange`: Update `orderEpoch` devdoc.

* `@0x/sol-doc`: Tweak event and function docs.

* Update CODEOWNERS.

* `@0x/sol-doc` Tweak function md generation.

* `@0x/sol-doc`: add `transformDocs()` tests.

* `@0x/sol-doc`: add `extract_docs` tests.

* `@0x/sol-doc` Fix linter errors.

* `@0x/contracts-erc20-bridge-sampler`: Fix broken `ERC20BridgeSampler.sol` compile.

* `@0x/sol-doc` Fix mismatched `dev-utils` dep version.

* `@0x/sol-doc`: Add `gen_md` tests.

* `@0x/sol-doc`: Remove `fs.promises` calls.

* `@0x/sol-doc`: Fix linter errors.

* `@0x/sol-doc`: Export all relevant types and functions.

Co-authored-by: Lawrence Forman <me@merklejerk.com>
2020-01-03 22:59:18 -05:00

115 lines
3.8 KiB
TypeScript

import { chaiSetup } from '@0x/dev-utils';
import { expect } from 'chai';
import * as _ from 'lodash';
import { FunctionKind, SolidityDocs } from '../src/extract_docs';
import { generateMarkdownFromDocs } from '../src/gen_md';
import { randomContract, randomWord } from './utils/random_docs';
chaiSetup.configure();
// tslint:disable: custom-no-magic-numbers
describe('generateMarkdownFromDocs()', () => {
const URL_PREFIX = randomWord();
const DOCS: SolidityDocs = {
contracts: {
..._.mapValues(
_.groupBy(
_.times(_.random(2, 8), () =>
((name: string) => ({ name, ...randomContract(name) }))(`${randomWord()}Contract`),
),
'name',
),
g => g[0],
),
},
};
let md: string;
let mdLines: string[];
function getMarkdownHeaders(level: number): string[] {
const lines = mdLines.filter(line => new RegExp(`^\\s*#{${level}}[^#]`).test(line));
// tslint:disable-next-line: no-non-null-assertion
return lines.map(line => /^\s*#+\s*(.+?)\s*$/.exec(line)![1]);
}
function getMarkdownLinks(): string[] {
const links: string[] = [];
for (const line of mdLines) {
const re = /\[[^\]]+\]\(([^)]+)\)/g;
let m: string[] | undefined | null;
do {
m = re.exec(line);
if (m) {
links.push(m[1]);
}
} while (m);
}
return links;
}
before(() => {
md = generateMarkdownFromDocs(DOCS, { urlPrefix: URL_PREFIX });
mdLines = md.split('\n');
});
it('generates entries for all contracts', () => {
const headers = getMarkdownHeaders(1);
for (const [contractName, contract] of Object.entries(DOCS.contracts)) {
expect(headers).to.include(`${contract.kind} \`${contractName}\``);
}
});
it('generates entries for all enums', () => {
const headers = getMarkdownHeaders(3);
for (const contract of Object.values(DOCS.contracts)) {
for (const enumName of Object.keys(contract.enums)) {
expect(headers).to.include(`\`${enumName}\``);
}
}
});
it('generates entries for all structs', () => {
const headers = getMarkdownHeaders(3);
for (const contract of Object.values(DOCS.contracts)) {
for (const structName of Object.keys(contract.structs)) {
expect(headers).to.include(`\`${structName}\``);
}
}
});
it('generates entries for all events', () => {
const headers = getMarkdownHeaders(3);
for (const contract of Object.values(DOCS.contracts)) {
for (const event of contract.events) {
expect(headers).to.include(`\`${event.name}\``);
}
}
});
it('generates entries for all methods', () => {
const headers = getMarkdownHeaders(3);
for (const contract of Object.values(DOCS.contracts)) {
for (const method of contract.methods) {
if (method.kind === FunctionKind.Fallback) {
expect(headers).to.include(`\`<fallback>\``);
} else if (method.kind === FunctionKind.Constructor) {
expect(headers).to.include(`\`constructor\``);
} else {
expect(headers).to.include(`\`${method.name}\``);
}
}
}
});
it('prefixes all URLs with the prefix', () => {
const urls = getMarkdownLinks();
for (const url of urls) {
expect(url.startsWith(URL_PREFIX)).to.be.true();
}
});
});
// tslint:disable: max-file-line-count