Skip to content

Commit

Permalink
Merge branch 'master' into fix/options
Browse files Browse the repository at this point in the history
  • Loading branch information
Gerrit0 committed Jan 10, 2020
2 parents c5cbc01 + 9a43f21 commit b2782d5
Show file tree
Hide file tree
Showing 23 changed files with 734 additions and 488 deletions.
250 changes: 189 additions & 61 deletions package-lock.json

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions package.json
@@ -1,7 +1,7 @@
{
"name": "typedoc",
"description": "Create api documentation for TypeScript projects.",
"version": "0.16.0-3",
"version": "0.16.0-6",
"homepage": "https://typedoc.org",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
Expand Down Expand Up @@ -32,7 +32,7 @@
"dependencies": {
"@types/minimatch": "3.0.3",
"fs-extra": "^8.1.0",
"handlebars": "^4.5.3",
"handlebars": "^4.7.0",
"highlight.js": "^9.17.1",
"lodash": "^4.17.15",
"marked": "^0.8.0",
Expand All @@ -48,9 +48,9 @@
"@types/marked": "^0.7.2",
"@types/mocha": "^5.2.7",
"@types/mockery": "^1.4.29",
"@types/node": "^13.1.1",
"@types/node": "^13.1.6",
"@types/shelljs": "^0.8.6",
"mocha": "^6.2.2",
"mocha": "^7.0.0",
"mockery": "^2.1.0",
"nyc": "15.0.0",
"tslint": "^5.20.1"
Expand Down
9 changes: 8 additions & 1 deletion scripts/rebuild_specs.js
Expand Up @@ -17,7 +17,8 @@ const app = new TypeDoc.Application({
"lib.es2015.iterable.d.ts",
"lib.es2015.collection.d.ts"
],
name: 'typedoc'
name: 'typedoc',
excludeExternals: true
});

// Note that this uses the test files in dist, not in src, this is important since
Expand All @@ -27,6 +28,10 @@ const base = path.join(__dirname, '../dist/test/converter');
/** @type {[string, () => void, () => void][]} */
const conversions = [
['specs', () => { }, () => { }],
['specs.d',
() => app.options.setValue('includeDeclarations', true),
() => app.options.setValue('includeDeclarations', false)
],
['specs-without-exported',
() => app.options.setValue('excludeNotExported', true),
() => app.options.setValue('excludeNotExported', false)
Expand Down Expand Up @@ -73,7 +78,9 @@ async function rebuildRendererTest() {
const out = path.join(__dirname, '../src/test/renderer/specs');

await fs.remove(out)
app.options.setValue('excludeExternals', false);
app.generateDocs(app.expandInputFiles([src]), out)
app.options.setValue('excludeExternals', true);
await fs.remove(path.join(out, 'assets'))

/**
Expand Down
12 changes: 11 additions & 1 deletion src/lib/converter/factories/declaration.ts
Expand Up @@ -73,6 +73,9 @@ export function createDeclaration(context: Context, node: ts.Declaration, kind:
let isExported: boolean;
if (kind === ReflectionKind.ExternalModule || kind === ReflectionKind.Global) {
isExported = true;
} else if (container.kind === ReflectionKind.Global) {
// In file mode, everything is exported.
isExported = true;
} else if (container.kindOf([ReflectionKind.Module, ReflectionKind.ExternalModule])) {
const symbol = context.getSymbolAtLocation(node);
if (!symbol) {
Expand All @@ -82,7 +85,14 @@ export function createDeclaration(context: Context, node: ts.Declaration, kind:
while (![ts.SyntaxKind.SourceFile, ts.SyntaxKind.ModuleDeclaration].includes(parentNode.kind)) {
parentNode = parentNode.parent;
}
isExported = !!context.getSymbolAtLocation(parentNode)?.exports?.get(symbol.escapedName);
const parentSymbol = context.getSymbolAtLocation(parentNode);
if (!parentSymbol) {
// This is a file with no imports/exports, so everything is
// global and therefore exported.
isExported = true;
} else {
isExported = !!parentSymbol.exports?.get(symbol.escapedName);
}
}
} else {
isExported = container.flags.isExported;
Expand Down
2 changes: 1 addition & 1 deletion src/lib/output/plugins/MarkedPlugin.ts
Expand Up @@ -138,7 +138,7 @@ export class MarkedPlugin extends ContextAwareRendererComponent {
const contents = FS.readFileSync(path, 'utf-8');
if (path.substr(-4).toLocaleLowerCase() === '.hbs') {
const template = Handlebars.compile(contents);
return template(context);
return template(context, { allowProtoMethodsByDefault: true, allowProtoPropertiesByDefault: true });
} else {
return contents;
}
Expand Down
2 changes: 1 addition & 1 deletion src/lib/output/renderer.ts
Expand Up @@ -163,7 +163,7 @@ export class Renderer extends ChildableComponent<Application, RendererComponent>

// Theme must be set as this is only called in render, and render ensures theme is set.
page.template = page.template || this.theme!.resources.templates.getResource(page.templateName)!.getTemplate();
page.contents = page.template(page);
page.contents = page.template(page, { allowProtoMethodsByDefault: true, allowProtoPropertiesByDefault: true });

this.trigger(PageEvent.END, page);
if (page.isDefaultPrevented) {
Expand Down
4 changes: 2 additions & 2 deletions src/lib/output/utils/resources/templates.ts
Expand Up @@ -17,9 +17,9 @@ export class Template<T = any> extends Resource {
return this.template;
}

render(context: any, options?: any): string {
render(context: any, options?: Handlebars.RuntimeOptions): string {
const template = this.getTemplate();
return template(context, options);
return template(context, { ...options, allowProtoMethodsByDefault: true, allowProtoPropertiesByDefault: true });
}
}

Expand Down
193 changes: 52 additions & 141 deletions src/test/converter.test.ts
Expand Up @@ -2,159 +2,70 @@ import { Application, resetReflectionID, normalizePath, ProjectReflection } from
import * as FS from 'fs';
import * as Path from 'path';
import { deepStrictEqual as equal, ok } from 'assert';
import { JsxEmit, ModuleKind, ScriptTarget } from 'typescript';
import { SourceFileMode } from '../lib/converter/nodes/block';
import { ScriptTarget, ModuleKind, JsxEmit } from 'typescript';

describe('Converter', function() {
const base = Path.join(__dirname, 'converter');
let app: Application;

before('constructs', function() {
app = new Application({
mode: 'Modules',
logger: 'none',
target: ScriptTarget.ES5,
module: ModuleKind.CommonJS,
experimentalDecorators: true,
jsx: JsxEmit.React,
name: 'typedoc',
ignoreCompilerErrors: true
});
const app = new Application({
mode: SourceFileMode.Modules,
logger: 'none',
target: ScriptTarget.ES5,
module: ModuleKind.CommonJS,
experimentalDecorators: true,
jsx: JsxEmit.React,
name: 'typedoc',
ignoreCompilerErrors: true,
excludeExternals: true
});

const checks: [string, () => void, () => void][] = [
['specs', () => { }, () => { }],
['specs.d',
() => app.options.setValue('includeDeclarations', true),
() => app.options.setValue('includeDeclarations', false)
],
['specs-without-exported',
() => app.options.setValue('excludeNotExported', true),
() => app.options.setValue('excludeNotExported', false)
],
['specs-with-lump-categories',
() => app.options.setValue('categorizeByGroup', false),
() => app.options.setValue('categorizeByGroup', true)
]
];

FS.readdirSync(base).forEach(function (directory) {
const path = Path.join(base, directory);
if (!FS.lstatSync(path).isDirectory()) {
return;
}

describe(directory, function() {
let result: ProjectReflection | undefined;

it('converts fixtures', function() {
resetReflectionID();
result = app.convert(app.expandInputFiles([path]));
ok(result instanceof ProjectReflection, 'No reflection returned');
});

it('matches specs', function() {
const specs = JSON.parse(FS.readFileSync(Path.join(path, 'specs.json')).toString());
let data = JSON.stringify(app.serializer.toObject(result), null, ' ');
data = data.split(normalizePath(base)).join('%BASE%');

equal(JSON.parse(data), specs);
});
});
});
});

describe('Converter with categorizeByGroup=false', function() {
const base = Path.join(__dirname, 'converter');
const categoryDir = Path.join(base, 'category');
const classDir = Path.join(base, 'class');
let app: Application;

before('constructs', function() {
app = new Application({
mode: 'Modules',
logger: 'none',
target: ScriptTarget.ES5,
module: ModuleKind.CommonJS,
experimentalDecorators: true,
categorizeByGroup: false,
jsx: JsxEmit.React,
name: 'typedoc',
ignoreCompilerErrors: true
for (const [file, before, after] of checks) {
const specsFile = Path.join(path, `${file}.json`);
if (!FS.existsSync(specsFile)) {
continue;
}

let result: ProjectReflection | undefined;

it(`[${file}] converts fixtures`, function() {
before();
resetReflectionID();
result = app.convert(app.expandInputFiles([path]));
after();
ok(result instanceof ProjectReflection, 'No reflection returned');
});

it(`[${file}] matches specs`, function() {
const specs = JSON.parse(FS.readFileSync(specsFile, 'utf-8'));
let data = JSON.stringify(app.serializer.toObject(result), null, ' ');
data = data.split(normalizePath(base)).join('%BASE%');

equal(JSON.parse(data), specs);
});
}
});
});

let result: ProjectReflection | undefined;

describe('category', () => {
it('converts fixtures', function() {
resetReflectionID();
result = app.convert(app.expandInputFiles([categoryDir]));
ok(result instanceof ProjectReflection, 'No reflection returned');
});

it('matches specs', function() {
const specs = JSON.parse(FS.readFileSync(Path.join(categoryDir, 'specs-with-lump-categories.json')).toString());
let data = JSON.stringify(result!.toObject(), null, ' ');
data = data.split(normalizePath(base)).join('%BASE%');

equal(JSON.parse(data), specs);
});
});

// verify that no categories are used when not specified during lump categorization
describe('class', () => {
it('converts fixtures', function() {
resetReflectionID();
result = app.convert(app.expandInputFiles([classDir]));
ok(result instanceof ProjectReflection, 'No reflection returned');
});

it('matches specs', function() {
const specs = JSON.parse(FS.readFileSync(Path.join(classDir, 'specs.json')).toString());
let data = JSON.stringify(result!.toObject(), null, ' ');
data = data.split(normalizePath(base)).join('%BASE%');

equal(JSON.parse(data), specs);
});
});
});

describe('Converter with excludeNotExported=true', function() {
const base = Path.join(__dirname, 'converter');
const exportWithLocalDir = Path.join(base, 'export-with-local');
const classDir = Path.join(base, 'class');
let app: Application;

before('constructs', function() {
app = new Application({
mode: 'Modules',
logger: 'none',
target: ScriptTarget.ES5,
module: ModuleKind.CommonJS,
experimentalDecorators: true,
excludeNotExported: true,
jsx: JsxEmit.React,
name: 'typedoc',
ignoreCompilerErrors: true
});
});

let result: ProjectReflection | undefined;

describe('export-with-local', () => {
it('converts fixtures', function() {
resetReflectionID();
result = app.convert(app.expandInputFiles([exportWithLocalDir]));
ok(result instanceof ProjectReflection, 'No reflection returned');
});

it('matches specs', function() {
const specs = JSON.parse(FS.readFileSync(Path.join(exportWithLocalDir, 'specs-without-exported.json')).toString());
let data = JSON.stringify(result!.toObject(), null, ' ');
data = data.split(normalizePath(base)).join('%BASE%');

equal(JSON.parse(data), specs);
});
});

describe('class', () => {
it('converts fixtures', function() {
resetReflectionID();
result = app.convert(app.expandInputFiles([classDir]));
ok(result instanceof ProjectReflection, 'No reflection returned');
});

it('matches specs', function() {
const specs = JSON.parse(FS.readFileSync(Path.join(classDir, 'specs-without-exported.json')).toString());
let data = JSON.stringify(result!.toObject(), null, ' ');
data = data.split(normalizePath(base)).join('%BASE%');

equal(JSON.parse(data), specs);
});
});

});
5 changes: 5 additions & 0 deletions src/test/converter/declaration/declaration.d.ts
@@ -0,0 +1,5 @@
declare class Decl {
prop: number;
}

declare const x: number
3 changes: 3 additions & 0 deletions src/test/converter/declaration/export-declaration.d.ts
@@ -0,0 +1,3 @@
export declare class Exported {}

declare class NotExported {}

0 comments on commit b2782d5

Please sign in to comment.