chore(typedoc-plugin-appium): fussing
made test helpers more sane
add a test or two
export a `setup` fn from main entry point to configure options and theme
MODIFY
packages/typedoc-plugin-appium/lib/converter/index.ts
packages/typedoc-plugin-appium/lib/converter/index.ts
@@ -27,7 +27,10 @@ import {ExternalConverter} from './external';
* @param parentLog - Logger
* @returns All commands found in the project
*/
-export function convertCommands(ctx: Context, parentLog: AppiumPluginLogger): ProjectCommands {
+export function convertCommands(
+ ctx: Context,
+ parentLog: AppiumPluginLogger
+): ProjectCommands | undefined {
const log = parentLog.createChildLogger('converter');
const bedConverter = new BuiltinExternalDriverConverter(ctx, log);
@@ -46,7 +49,13 @@ export function convertCommands(ctx: Context, parentLog: AppiumPluginLogger): Pr
const allCommands = [...builtinCommands.toProjectCommands(), ...externalCommands];
- return new ProjectCommands(allCommands);
+ const projectCmds = new ProjectCommands(allCommands);
+
+ if (projectCmds.empty) {
+ return;
+ }
+
+ return projectCmds;
}
export * from '../model/builtin-commands';

MODIFY
packages/typedoc-plugin-appium/lib/converter/overrides.ts
packages/typedoc-plugin-appium/lib/converter/overrides.ts
@@ -76,6 +76,7 @@ export function convertOverrides({
for (const commandData of commandSet) {
const method = classMethods.get(command)?.method;
if (!method) {
+ log.verbose('(%s) No method "%s" found; skipping', parentRefl.name, command);
continue;
}
const commentData = deriveComment(command, builtinMethods, method, commandData.comment);

MODIFY
packages/typedoc-plugin-appium/lib/index.ts
packages/typedoc-plugin-appium/lib/index.ts
+import _ from 'lodash';
import {Application, Context, Converter, DeclarationReflection} from 'typedoc';
import {convertCommands, createReflections, omitDefaultReflections} from './converter';
import {AppiumPluginLogger, AppiumPluginParentLogger} from './logger';
import {ExtensionReflection, NS, ProjectCommands} from './model';
import {configureOptions, declarations} from './options';
-import {AppiumTheme, THEME_NAME} from './theme';
+import {configureTheme, THEME_NAME} from './theme';
/**
* Loads the Appium TypeDoc plugin.
@@ -15,13 +16,17 @@ export function load(
app: Application
): Promise<[PromiseSettledResult<ConvertResult>, PromiseSettledResult<PostProcessResult>]> {
// register our custom theme. the user still has to choose it
- app.renderer.defineTheme(THEME_NAME, AppiumTheme);
-
- configureOptions(app);
+ setup(app);
+ // TypeDoc does not expect a return value here, but it's useful for testing
return Promise.allSettled([convert(app), postProcess(app)]);
}
+/**
+ * Registers theme and options, then monkeys with the options
+ */
+export const setup: (app: Application) => Application = _.flow(configureTheme, configureOptions);
+
/**
* Finds commands and creates new reflections for them, adding them to the project.
*
@@ -44,11 +49,16 @@ export async function convert(app: Application): Promise<ConvertResult> {
// this queries the declarations created by TypeDoc and extracts command information
projectCommands = convertCommands(ctx, log);
+ if (!projectCommands) {
+ log.verbose('Skipping creation of reflections');
+ resolve({ctx});
+ return;
+ }
// this creates new custom reflections from the data we gathered and registers them
// with TypeDoc
extensionReflections = createReflections(ctx, log, projectCommands);
} else {
- log.warn('Not using the Appium theme; skipping command reflection creation');
+ log.error(`Appium theme disabled! Use "theme: 'appium'" in your typedoc.json`);
}
resolve({ctx, extensionReflections, projectCommands});
});

MODIFY
packages/typedoc-plugin-appium/lib/model/project-commands.ts
packages/typedoc-plugin-appium/lib/model/project-commands.ts
@@ -14,4 +14,8 @@ export class ProjectCommands extends Map<string, ModuleCommands> {
}
return this;
}
+
+ get empty() {
+ return this.size === 0;
+ }
}

MODIFY
packages/typedoc-plugin-appium/lib/options/index.ts
packages/typedoc-plugin-appium/lib/options/index.ts
import {Application, ParameterType} from 'typedoc';
import {AppiumPluginOptionsReader} from './reader';
import {declarations} from './declarations';
+import {AppiumPluginLogger} from '../logger';
export * from './reader';
export {declarations};
@@ -9,20 +10,23 @@ export {declarations};
* Configures how this plugin handles TypeDoc options.
* @param app TypeDoc Application
*/
-export function configureOptions(app: Application) {
+export function configureOptions(app: Application): Application {
+ const log = new AppiumPluginLogger(app.logger, 'options');
+
// for evil
- app.options.addReader(new AppiumPluginOptionsReader());
+ app.options.addReader(new AppiumPluginOptionsReader(log));
// add our custom options
for (const declaration of Object.values(declarations)) {
app.options.addDeclaration(declaration);
}
+ return app;
}
export type AppiumPluginOptions = {
- [O in keyof typeof declarations]: typeof declarations[O]['type'] extends ParameterType.Boolean
+ [O in keyof typeof declarations]: (typeof declarations)[O]['type'] extends ParameterType.Boolean
? boolean
- : typeof declarations[O]['type'] extends ParameterType.String
+ : (typeof declarations)[O]['type'] extends ParameterType.String
? string
: unknown;
};

MODIFY
packages/typedoc-plugin-appium/lib/options/reader.ts
packages/typedoc-plugin-appium/lib/options/reader.ts
@@ -26,37 +26,40 @@ const REQUIRED_PACKAGES: Readonly<Set<string>> = new Set(['@appium/base-driver',
* It can do what has been undone and undo what has been done. It can make real your dreams... or nightmares.
*/
export class AppiumPluginOptionsReader implements OptionsReader {
+ readonly #log: AppiumPluginLogger;
+
/**
* I don't know the point of `name`, but the interface requires it, so here.
*/
- public name = 'naughty-appium-options-reader';
+ public readonly name = 'naughty-appium-options-reader';
/**
* This needs to be higher than the value in `MarkdownOptionsReader`.
*/
- public priority = 2000;
+ public readonly priority = 2000;
+
+ constructor(logger: AppiumPluginLogger) {
+ this.#log = logger.createChildLogger('options-reader');
+ }
/**
- * Forces the theme to be {@linkcode THEME_NAME}
- * @param container Options
- * @param log Logger
+ * Calls various private methods to override option values or provide defaults.
+ * @param container - Options container
*/
- #configureTheme(container: Options, log: AppiumPluginLogger) {
- if (OVERRIDE_THEME_NAMES.has(container.getValue('theme'))) {
- container.setValue('theme', THEME_NAME);
- log.verbose('Set option "theme" to "appium"');
- }
+ public read(container: Options) {
+ this.#configureTheme(container);
+ this.#configureEntryPointStrategy(container);
+ this.#configureEntryPoints(container);
}
/**
* Forces the `entryPointStrategy` option to be {@linkcode EntryPointStrategy.Packages}
* @param container Options
- * @param log Logger
*/
- #configureEntryPointStrategy(container: Options, log: AppiumPluginLogger) {
+ #configureEntryPointStrategy(container: Options) {
const entryPointStrategy = container.getValue('entryPointStrategy');
if (entryPointStrategy !== EntryPointStrategy.Packages) {
container.setValue('entryPointStrategy', EntryPointStrategy.Packages);
- log.verbose('Set option "entryPointStrategy" to "%s"', EntryPointStrategy.Packages);
+ this.#log.verbose('Set option "entryPointStrategy" to "%s"', EntryPointStrategy.Packages);
}
}
@@ -69,9 +72,8 @@ export class AppiumPluginOptionsReader implements OptionsReader {
*
* If a required package cannot be resolved, an error occurs
* @param container Options
- * @param log Logger
*/
- #configureEntryPoints(container: Options, log: AppiumPluginLogger) {
+ #configureEntryPoints(container: Options) {
const entryPoints = container.getValue('entryPoints');
const newEntryPoints: Set<string> = new Set(entryPoints);
@@ -79,9 +81,9 @@ export class AppiumPluginOptionsReader implements OptionsReader {
try {
const entryPointPath = path.dirname(require.resolve(`${entryPoint}/package.json`));
newEntryPoints.add(entryPointPath);
- log.verbose('Added %s to "entryPoint" option', entryPointPath);
+ this.#log.verbose('Added %s to "entryPoint" option', entryPointPath);
} catch (err) {
- log.error('Could not find required package "%s"', entryPoint);
+ this.#log.error('Could not find required package "%s"', entryPoint);
}
};
@@ -90,11 +92,11 @@ export class AppiumPluginOptionsReader implements OptionsReader {
if (foundReqdEP) {
try {
require.resolve(foundReqdEP);
- log.verbose('entryPoint %s already exists (%s)', reqdEntryPoint, foundReqdEP);
+ this.#log.verbose('entryPoint %s already exists (%s)', reqdEntryPoint, foundReqdEP);
} catch {
newEntryPoints.delete(foundReqdEP);
addEntryPoint(reqdEntryPoint);
- log.warn(
+ this.#log.warn(
'"entryPoint" option item matching required package "%s" is invalid or missing (%s); it was replaced',
reqdEntryPoint,
foundReqdEP
@@ -106,19 +108,17 @@ export class AppiumPluginOptionsReader implements OptionsReader {
}
container.setValue('entryPoints', [...newEntryPoints]);
- log.verbose('Final value of "entryPoints" option: %O', container.getValue('entryPoints'));
+ this.#log.verbose('Final value of "entryPoints" option: %O', container.getValue('entryPoints'));
}
/**
- * Calls various private methods to override option values or provide defaults.
- * @param container - Options container
- * @param logger - Logger
+ * Forces the theme to be {@linkcode THEME_NAME}
+ * @param container Options
*/
- public read(container: Options, logger: Logger) {
- const log = new AppiumPluginLogger(logger, `${NS}:options-reader`);
-
- this.#configureTheme(container, log);
- this.#configureEntryPointStrategy(container, log);
- this.#configureEntryPoints(container, log);
+ #configureTheme(container: Options) {
+ if (OVERRIDE_THEME_NAMES.has(container.getValue('theme'))) {
+ container.setValue('theme', THEME_NAME);
+ this.#log.verbose('Set option "theme" to "appium"');
+ }
}
}

MODIFY
packages/typedoc-plugin-appium/lib/theme/index.ts
packages/typedoc-plugin-appium/lib/theme/index.ts
-import {ContainerReflection, PageEvent, ReflectionKind, Renderer} from 'typedoc';
+import {Application, ContainerReflection, PageEvent, ReflectionKind, Renderer} from 'typedoc';
import {MarkdownTheme} from 'typedoc-plugin-markdown';
import {AppiumPluginLogger} from '../logger';
import {AppiumPluginReflectionKind, NS} from '../model';
@@ -115,3 +115,12 @@ export type TemplateMapping = {
};
export type {AppiumThemeTemplate};
+
+/**
+ * Registers {@linkcode AppiumTheme} with TypeDoc.
+ * @param app TypeDoc application
+ */
+export function configureTheme(app: Application): Application {
+ app.renderer.defineTheme(THEME_NAME, AppiumTheme);
+ return app;
+}

MODIFY
packages/typedoc-plugin-appium/test/unit/converter/index.spec.ts
packages/typedoc-plugin-appium/test/unit/converter/index.spec.ts
@@ -7,7 +7,7 @@ import {
} from '../../../lib/converter';
import {AppiumPluginLogger} from '../../../lib/logger';
import {ProjectCommands} from '../../../lib/model';
-import {initAppForPkgs, NAME_FAKE_DRIVER_MODULE, ROOT_TSCONFIG} from '../helpers';
+import {initAppForPkgs, NAME_FAKE_DRIVER_MODULE} from '../helpers';
const {expect} = chai;
@@ -24,12 +24,9 @@ describe('@appium/typedoc-plugin-appium', function () {
let ctx: Context;
let log: AppiumPluginLogger;
before(async function () {
- const app = await initAppForPkgs(
- ROOT_TSCONFIG,
- NAME_TYPES_MODULE,
- NAME_FAKE_DRIVER_MODULE,
- NAME_BUILTIN_COMMAND_MODULE
- );
+ const app = initAppForPkgs({
+ entryPoints: [NAME_TYPES_MODULE, NAME_FAKE_DRIVER_MODULE, NAME_BUILTIN_COMMAND_MODULE],
+ });
ctx = await new Promise((resolve) => {
app.converter.once(Converter.EVENT_RESOLVE_BEGIN, (ctx: Context) => {
resolve(ctx);

MODIFY
packages/typedoc-plugin-appium/test/unit/converter/plugin.spec.ts
packages/typedoc-plugin-appium/test/unit/converter/plugin.spec.ts
-import {createSandbox, SinonSandbox} from 'sinon';
import {
Application,
Context,
DeclarationReflection,
ProjectReflection,
ReflectionKind,
+ TypeDocOptions,
} from 'typedoc';
-import {
- AppiumTheme,
- configureOptions,
- convert,
- ConvertResult,
- postProcess,
- PostProcessResult,
- THEME_NAME,
-} from '../../../lib';
+import {convert, ConvertResult, postProcess, PostProcessResult, setup} from '../../../lib';
import {NAME_BUILTIN_COMMAND_MODULE, NAME_TYPES_MODULE} from '../../../lib/converter';
import {
AppiumPluginReflectionKind,
CommandReflection,
ExtensionReflection,
- ProjectCommands,
} from '../../../lib/model';
-import {initAppForPkgs, NAME_FAKE_DRIVER_MODULE, ROOT_TSCONFIG} from '../helpers';
+import {initAppForPkgs, NAME_FAKE_DRIVER_MODULE} from '../helpers';
const {expect} = chai;
describe('@appium/typedoc-plugin-appium', function () {
describe('plugin', function () {
- let sandbox: SinonSandbox;
- /**
- * Typedoc app
- */
- let app: Application;
-
- /**
- * All project commands as returned by the converters
- */
- let projectCommands: ProjectCommands;
-
/**
* Result of {@linkcode convert}
*/
@@ -51,6 +31,7 @@ describe('@appium/typedoc-plugin-appium', function () {
* Whatever {@linkcode Context} we're using to test
*/
let ctx: Context;
+
/**
* Array of {@linkcode ExtensionReflection} instances as in a {@linkcode ConvertResult}
*/
@@ -59,37 +40,34 @@ describe('@appium/typedoc-plugin-appium', function () {
/**
* Creates a new TypeDoc application and/or resets it
*/
- async function reset() {
- app = await initAppForPkgs(
- ROOT_TSCONFIG,
- NAME_TYPES_MODULE,
- NAME_FAKE_DRIVER_MODULE,
- NAME_BUILTIN_COMMAND_MODULE
- );
-
- // the load() function of the plugin does this stuff
- app.renderer.defineTheme(THEME_NAME, AppiumTheme);
- configureOptions(app);
+ function reset({
+ entryPoints = [NAME_TYPES_MODULE, NAME_FAKE_DRIVER_MODULE, NAME_BUILTIN_COMMAND_MODULE],
+ ...opts
+ }: Partial<TypeDocOptions> = {}): Application {
+ const app = initAppForPkgs({entryPoints, ...opts});
+ setup(app);
+ return app;
}
- before(async function () {
- await reset();
- });
-
- beforeEach(function () {
- sandbox = createSandbox();
+ describe('convert()', function () {
+ describe('when "theme" is not "markdown" or "appium"', function () {
+ it('should do nothing', async function () {
+ const app = reset({theme: 'foo'});
+ resolveBeginCtxPromise = convert(app);
+ app.convert();
+ await expect(resolveBeginCtxPromise).to.eventually.not.have.all.keys(
+ 'projectCommands',
+ 'extensionReflections'
+ );
});
-
- afterEach(function () {
- sandbox.restore();
});
- describe('convert()', function () {
+ describe('when commands are found in the project', function () {
before(async function () {
+ const app = reset();
resolveBeginCtxPromise = convert(app);
app.convert();
const result = await resolveBeginCtxPromise;
- projectCommands = result.projectCommands!;
extensionReflections = result.extensionReflections!;
});
@@ -109,7 +87,7 @@ describe('@appium/typedoc-plugin-appium', function () {
it('should sort exec methods in ascending order by script', function () {
for (const cmdsRefl of extensionReflections) {
- let lastScript = '';
+ let lastScript: string | undefined = undefined;
for (const cmdRefl of cmdsRefl.getChildrenByKind(
AppiumPluginReflectionKind.ExecuteMethod as any
) as CommandReflection[]) {
@@ -120,17 +98,28 @@ describe('@appium/typedoc-plugin-appium', function () {
}
}
});
- describe('when called with an empty ProjectCommands', function () {
- it('should log an error and return an empty array');
+ });
+
+ describe('when no commands found in the project', function () {
+ it('should return an object without projectCommands and extensionReflections', async function () {
+ const app = reset({entryPoints: [NAME_TYPES_MODULE]});
+ resolveBeginCtxPromise = convert(app);
+ app.convert();
+ await expect(resolveBeginCtxPromise).to.eventually.not.have.all.keys(
+ 'projectCommands',
+ 'extensionReflections'
+ );
+ });
});
});
describe('postProcess()', function () {
let project: ProjectReflection;
let removed: Set<DeclarationReflection> | undefined;
+
describe('when the `outputModules` option is false', function () {
before(async function () {
- await reset();
+ const app = reset();
app.options.setValue('outputModules', false);
resolveBeginCtxPromise = convert(app);
resolveEndCtxPromise = postProcess(app);
@@ -152,7 +141,7 @@ describe('@appium/typedoc-plugin-appium', function () {
describe('when the `outputModules` option is true', function () {
before(async function () {
- await reset();
+ const app = reset();
app.options.setValue('outputModules', true);
resolveBeginCtxPromise = convert(app);
resolveEndCtxPromise = postProcess(app);
@@ -173,7 +162,7 @@ describe('@appium/typedoc-plugin-appium', function () {
});
it('should not remove DeclarationReflections', function () {
- expect(removed).not.to.exist;
+ expect(removed).to.be.undefined;
});
});
});

MODIFY
packages/typedoc-plugin-appium/test/unit/helpers.ts
packages/typedoc-plugin-appium/test/unit/helpers.ts
import path from 'node:path';
import readPkg from 'read-pkg';
-import {Constructor} from 'type-fest';
-import {Application, Context, Converter, LogLevel, TSConfigReader} from 'typedoc';
-import ts from 'typescript';
+import {Constructor, SetRequired} from 'type-fest';
+import {
+ Application,
+ Context,
+ Converter,
+ EntryPointStrategy,
+ LogLevel,
+ TSConfigReader,
+ TypeDocOptions,
+} from 'typedoc';
import {THEME_NAME} from '../../lib';
import {BaseConverter} from '../../lib/converter';
import {AppiumPluginLogger} from '../../lib/logger';
const {expect} = chai;
+/**
+ * Name of the fake driver package which is good for testing
+ */
+export const NAME_FAKE_DRIVER_MODULE = '@appium/fake-driver';
+
+/**
+ * Path to monorepo root tsconfig
+ */
export const ROOT_TSCONFIG = path.join(__dirname, '..', '..', '..', '..', 'tsconfig.json');
-export async function getEntryPoint(pkgName: string): Promise<string> {
+/**
+ * Finds entry point for a single package. To be used when the `entryPointStrategy` is `resolve`
+ * @param pkgName Name of package
+ * @returns Path to its entry point
+ */
+async function getEntryPoint(pkgName: string): Promise<string> {
const pkgDir = path.dirname(require.resolve(`${pkgName}/package.json`));
if (!pkgDir) {
throw new TypeError(`Could not find package ${pkgName}!`);
@@ -21,62 +41,79 @@ export async function getEntryPoint(pkgName: string): Promise<string> {
return path.resolve(pkgDir, pkg.typedoc.entryPoint);
}
-export function getTypedocApp(
- tsconfig: string,
- entryPoints: string[] = [],
- opts: GetTypedocAppOpts = {}
-): Application {
+/**
+ * Initializes a new TypeDoc application with some defaults
+ *
+ * If `_FORCE_LOGS` is in the env, use verbose logging
+ * @param opts - Opts
+ * @returns New TypeDoc app
+ * @todo Figure out how to get plugin-specific options into TypeDoc other than via `Options.setValue`
+ */
+function getTypedocApp(opts: Partial<TypeDocOptions> = {}): Application {
const app = new Application();
app.options.addReader(new TSConfigReader());
- const {logger, plugin = ['none']} = opts;
- app.bootstrap({
- excludeExternals: true,
- tsconfig,
- plugin,
- logLevel: process.env._FORCE_LOGS ? LogLevel.Verbose : LogLevel.Info,
- logger,
- entryPoints,
- entryPointStrategy: entryPoints.length > 1 ? 'packages' : 'resolve',
- theme: THEME_NAME,
- });
- return app;
-}
-export interface GetTypedocAppOpts {
- logger?: TestLogger;
- plugin?: string[];
-}
+ const forceLogs = Boolean(process.env._FORCE_LOGS);
-export function getConverterProgram(app: Application): ts.Program {
- const program = ts.createProgram(app.options.getFileNames(), app.options.getCompilerOptions());
- const errors = ts.getPreEmitDiagnostics(program);
- expect(errors).to.be.empty;
+ const finalOpts = {
+ excludeExternals: true,
+ plugin: ['none'], // prevent any plugins from being auto-loaded
+ logLevel: forceLogs ? LogLevel.Verbose : LogLevel.Info,
+ logger: forceLogs ? undefined : 'none',
+ entryPointStrategy:
+ opts.entryPoints && opts.entryPoints.length > 1
+ ? EntryPointStrategy.Packages
+ : EntryPointStrategy.Resolve,
+ theme: THEME_NAME,
+ skipErrorChecking: true,
+ ...opts,
+ };
- return program;
+ app.bootstrap(finalOpts);
+ return app;
}
/**
- *
+ * Runs Typedoc against a single package
* @param pkgName Name of package to get Application for
- * @returns Object with stuff you need to do things
+ * @returns TypeDoc application
*/
-export async function initAppForPkg(pkgName: string, logger?: TestLogger): Promise<Application> {
+export async function initAppForPkg(
+ pkgName: string,
+ opts: Partial<TypeDocOptions> = {}
+): Promise<Application> {
const entryPoint = await getEntryPoint(pkgName);
const tsconfig = require.resolve(`${pkgName}/tsconfig.json`);
- return getTypedocApp(tsconfig, [entryPoint], {logger});
+ const entryPointStrategy = EntryPointStrategy.Resolve;
+ return getTypedocApp({...opts, tsconfig, entryPoints: [entryPoint], entryPointStrategy});
}
-export async function initAppForPkgs(
- tsconfig: string,
- ...pkgNames: string[]
-): Promise<Application> {
- const entryPoints = await Promise.all(
- pkgNames.map((pkgName) => path.dirname(require.resolve(`${pkgName}/package.json`)))
+/**
+ * Runs Typedoc against multiple packages (using `entryPointStrategy` of `packages`)
+ * @param opts
+ * @returns Typedoc Application
+ */
+export function initAppForPkgs({
+ tsconfig = ROOT_TSCONFIG,
+ ...opts
+}: SetRequired<Partial<TypeDocOptions>, 'entryPoints'>): Application {
+ let {entryPoints, ...typedocOpts} = opts;
+ entryPoints = entryPoints?.map((pkgName) =>
+ path.dirname(require.resolve(`${pkgName}/package.json`))
);
- return getTypedocApp(tsconfig, entryPoints);
+ // because entryPoints is a list of directories, this must be 'packages'
+ const entryPointStrategy = EntryPointStrategy.Packages;
+ return getTypedocApp({...typedocOpts, entryPoints, entryPointStrategy});
}
-export async function convert<T, C extends BaseConverter<T>, Args extends any = any>(
+/**
+ * Starts the conversion process and returns the instance of the converter class once it is ready.
+ * @param app TypeDoc application
+ * @param cls Converter class
+ * @param extraArgs Extra args to `cls`' constructor
+ * @returns Converter class instance
+ */
+async function convert<T, C extends BaseConverter<T>, Args extends any = any>(
app: Application,
cls: Constructor<C, [Context, AppiumPluginLogger, ...Args[]]>,
extraArgs: Args[] = []
@@ -88,7 +125,7 @@ export async function convert<T, C extends BaseConverter<T>, Args extends any =
};
app.converter.once(Converter.EVENT_RESOLVE_BEGIN, listener);
try {
- app.converter.convert(app.getEntryPoints()!);
+ app.convert();
} catch (err) {
reject(err);
} finally {
@@ -97,21 +134,25 @@ export async function convert<T, C extends BaseConverter<T>, Args extends any =
});
}
+/**
+ * Gets a new TypeDoc app for a single package, begins the conversion process but resolves
+ * with the converter class instance once it is ready (with whatever TypeDoc already converted).
+ * @param cls Converter class
+ * @param pkgName Package to convert
+ * @param opts Extra args to `cls`' constructor and typedoc options
+ * @returns Converter class instance
+ */
export async function initConverter<T, C extends BaseConverter<T>, Args extends any = any>(
cls: Constructor<C, [Context, AppiumPluginLogger, ...Args[]]>,
pkgName: string,
opts: InitConverterOptions<Args> = {}
): Promise<C> {
- const app = await initAppForPkg(pkgName, opts.logger);
+ const {extraArgs, ...typeDocOpts} = opts;
+ const app = await initAppForPkg(pkgName, typeDocOpts);
- return await convert(app, cls, opts.extraArgs);
+ return await convert(app, cls, extraArgs);
}
-export const NAME_FAKE_DRIVER_MODULE = '@appium/fake-driver';
-
-export interface InitConverterOptions<Args extends any = any> {
+export interface InitConverterOptions<Args extends any = any> extends Partial<TypeDocOptions> {
extraArgs?: Args[];
- logger?: TestLogger;
}
-
-export type TestLogger = (...args: any[]) => any | 'none';

chore(typedoc-plugin-appium): fussing

- made test helpers more sane
- add a test or two
- export a `setup` fn from main entry point to configure options and theme