summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChristoph Schlosser <2466365+cschlosser@users.noreply.github.com>2021-04-17 22:12:38 +0200
committerGitHub <noreply@github.com>2021-04-17 22:12:38 +0200
commitdbcf5dc87d83ee59fc23e4eaa225a15655d17d2d (patch)
treed22cb94be324153581658e80a8596765755971a0 /src
parent703019a593c1e4118b580015b1af8bcfbb86b135 (diff)
downloaddoxdocgen-dbcf5dc87d83ee59fc23e4eaa225a15655d17d2d.tar.gz
Prepare release 1.2.0 (#213)1.2.0
* Prepare release 1.2.0 * Update versions * Lint * update appveyor * Update travis * Use yarn * Add nyc * Run cov instead of test * remove package-lock.json * Remove istanbul
Diffstat (limited to 'src')
-rw-r--r--src/DoxygenCompletionItemProvider.ts48
-rw-r--r--src/extension.ts26
-rw-r--r--src/test/index.ts277
-rw-r--r--src/test/runTests.ts28
4 files changed, 128 insertions, 251 deletions
diff --git a/src/DoxygenCompletionItemProvider.ts b/src/DoxygenCompletionItemProvider.ts
index 54baaaa..b71b827 100644
--- a/src/DoxygenCompletionItemProvider.ts
+++ b/src/DoxygenCompletionItemProvider.ts
@@ -1,17 +1,19 @@
import * as vscode from "vscode";
+
+// tslint:disable:max-line-length
+
/*https://github.com/cschlosser/doxdocgen/issues/30 */
-export default class DoxygenCompletionItemProvider implements vscode.CompletionItemProvider
-{
+export default class DoxygenCompletionItemProvider implements vscode.CompletionItemProvider {
/**
* commands are a tuple of <command, snippet, documentation>
*/
- static readonly commands: [string, string, string][] = [
+ public static readonly commands: Array<[string, string, string]> = [
/*Special commands */
["a", "${1:word}", "Display `<word>` in italics"],
["arg", "${1:item-description}", "Generate a simple, non-nested list of arguments"],
["b", "${1:word}", "Display `<word>` in bold"],
["c", "${1:word}", "Dispaly `<word>` using a typewriter font"],
- ["code", ".${1:language-id}\n${2:code}\n@endcode", "Starts a block of code"], //TODO: match end block symbol with trigger character
+ ["code", ".${1:language-id}\n${2:code}\n@endcode", "Starts a block of code"], // TODO: match end block symbol with trigger character
["copydoc", "${1:link-object}", "Copy a documentation block from the object specified by `<link-object>` and paste it at the location of the command. The link object can point to a member (of a class, file or group), a class, a namespace, a group, a page, or a file. If the memeber if overloaded, you should specify the argument types explicitly"],
["copybrief", "${1:link-object}", "Work in a similar way as `@copydoc` but will only copy the brief description, not the detailed documentation"],
["copydetails", "${1:link-object}", "Work in a similar way as `@copydoc` but will only copy the detailed documentation, not the brief description"],
@@ -100,7 +102,7 @@ export default class DoxygenCompletionItemProvider implements vscode.CompletionI
["include", "{${1|lineno,doc|}} ${2:file-name}", "This command can be used to include a source file as a block of code. Using the `@include` command is equivalent to inserting the file into the documentation block and surrounding it with `@code` and `@endcode` commands."],
["line", "${1:pattern}", "This command searches line by line through the example that was last included using `@include` or `@dontinclude` until it finds a non-blank line. If that line contains the specified pattern, it is written to the output."],
["skip", "${1:pattern}", "This command searches line by line through the example that was last included using `@include` or `@dontinclude` until it finds a line that contains the specified pattern."],
- ["skipline", "${1:pattern}", "This command searches line by line through the example that was last included using `@include` or `@dontinclude` until it finds a line that contains the specified pattern. It then writes the line to the output.",],
+ ["skipline", "${1:pattern}", "This command searches line by line through the example that was last included using `@include` or `@dontinclude` until it finds a line that contains the specified pattern. It then writes the line to the output."],
["snippet", "{${1|lineno,doc|}} ${2:file-name} ${3:block_id}", "Where the `@include` command can be used to include a complete file as source code, this command can be used to quote only a fragment of a source file. In case this is used as `<file-name>` the current file is taken as file to take the snippet from."],
["until", "${1:pattern}", "This command writes all lines of the example that was last included using `@include` or `@dontinclude` to the output, until it finds a line containing the specified pattern. The line containing the pattern will be written as well."],
["verbinclude", "${1:file-name}", "This command includes the contents of the file `<file-name>` verbatim in the documentation. The command is equivalent to pasting the contents of the file in the documentation and placing `@verbatim` and `@endverbatim` commands around it."],
@@ -109,14 +111,12 @@ export default class DoxygenCompletionItemProvider implements vscode.CompletionI
["rtfinclude", "${1:file-name}", "This command includes the contents of the file `<file-name>` as is in the RTF documentation and tagged with `<rtfonly>` in the generated XML output. The command is equivalent to pasting the contents of the file in the documentation and placing `@rtfonly` and `@endrtfonly` commands around it."],
["maninclude", "${1:file-name}", "This command includes the contents of the file `<file-name>` as is in the MAN documentation and tagged with `<manonly>` in the generated XML output. The command is equivalent to pasting the contents of the file in the documentation and placing `@manonly` and `@endmanonly` commands around it."],
["docbookinclude", "${1:file-name}", "This command includes the contents of the file `<file-name>` as is in the DocBook documentation and tagged with `<docbookonly>` in the generated XML output. The command is equivalent to pasting the contents of the file in the documentation and placing `@docbookonly` and `@enddocbookonly` commands around it."],
- ["xmlinclude", "${1:file-name}", "This command includes contents of the the file `<file-name>` as is in the XML documentation. The command is equivalent to pasting the contents of the file in the documentation and placing `@xmlonly` and `@endxmlonly` commands around it."]
+ ["xmlinclude", "${1:file-name}", "This command includes contents of the the file `<file-name>` as is in the XML documentation. The command is equivalent to pasting the contents of the file in the documentation and placing `@xmlonly` and `@endxmlonly` commands around it."],
];
- static completionItems = (() =>
- {
- let items: vscode.CompletionItem[] = [];
- for (const item of DoxygenCompletionItemProvider.commands)
- {
- let newItem = new vscode.CompletionItem(item[0]);
+ public static completionItems = (() => {
+ const items: vscode.CompletionItem[] = [];
+ for (const item of DoxygenCompletionItemProvider.commands) {
+ const newItem = new vscode.CompletionItem(item[0]);
newItem.documentation = new vscode.MarkdownString(item[2]);
newItem.insertText = new vscode.SnippetString(`${item[0]} ${item[1]}`);
newItem.kind = vscode.CompletionItemKind.Snippet;
@@ -125,31 +125,31 @@ export default class DoxygenCompletionItemProvider implements vscode.CompletionI
return items;
})();
- trigger: string = "";
- indentSpace: number;
- provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, context: vscode.CompletionContext)
- {
+ public trigger: string = "";
+ public indentSpace: number;
+ public provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, context: vscode.CompletionContext) {
this.trigger = context.triggerCharacter;
this.indentSpace = position.character;
- //TODO: check if current position is comment
+ // TODO: check if current position is comment
return DoxygenCompletionItemProvider.completionItems;
}
- resolveCompletionItem(item: vscode.CompletionItem, token: vscode.CancellationToken)
- {
+ public resolveCompletionItem(item: vscode.CompletionItem, token: vscode.CancellationToken) {
let insertion = (item.insertText as vscode.SnippetString).value;
- if (this.trigger === "\\")
+ if (this.trigger === "\\") {
insertion = insertion.replace("@", "\\");
+ }
const indentPrefix = "\n".concat("* ");
insertion = insertion.replace(/\n/g, indentPrefix);
-
+
/*insert an empty line if the snippet is multi-line, so * can be auto-completed */
- if (insertion.includes("\n"))
+ if (insertion.includes("\n")) {
insertion = insertion.concat(indentPrefix);
+ }
- let newItem = new vscode.CompletionItem(item.label, item.kind);
+ const newItem = new vscode.CompletionItem(item.label, item.kind);
newItem.documentation = item.documentation;
newItem.insertText = new vscode.SnippetString(insertion);
return newItem;
}
-} \ No newline at end of file
+}
diff --git a/src/extension.ts b/src/extension.ts
index b7c148c..dfd38c5 100644
--- a/src/extension.ts
+++ b/src/extension.ts
@@ -6,16 +6,14 @@ import CodeParserController from "./CodeParserController";
import DoxygenCompletionItemProvider from "./DoxygenCompletionItemProvider";
enum Version {
- CURRENT = "1.1.0",
- PREVIOUS = "1.0.1",
+ CURRENT = "1.2.0",
+ PREVIOUS = "1.1.0",
KEY = "doxdocgen_version",
}
// this method is called when your extension is activated
// your extension is activated the very first time the command is executed
-export function activate(context: vscode.ExtensionContext)
-{
-
+export function activate(context: vscode.ExtensionContext) {
const parser = new CodeParserController();
context.subscriptions.push(parser);
@@ -28,15 +26,17 @@ export function activate(context: vscode.ExtensionContext)
}
/*register doxygen commands intellisense */
- if (vscode.workspace.getConfiguration("doxdocgen.generic").get<boolean>("commandSuggestion"))
+ if (vscode.workspace.getConfiguration("doxdocgen.generic").get<boolean>("commandSuggestion")) {
+ // tslint:disable-next-line: max-line-length
vscode.languages.registerCompletionItemProvider({ language: "cpp", scheme: "file" }, new DoxygenCompletionItemProvider(), "@", "\\");
-
- //After the CompletionItemProvider is registered, it cannot be unregistered
- //Check the settings everytime when it is triggered would be inefficient
- //So just prompt the user to restart to take effect
- vscode.workspace.onDidChangeConfiguration(event =>
- {
- if (event.affectsConfiguration("doxdocgen.generic.commandSuggestion"))
+ }
+
+ // After the CompletionItemProvider is registered, it cannot be unregistered
+ // Check the settings everytime when it is triggered would be inefficient
+ // So just prompt the user to restart to take effect
+ vscode.workspace.onDidChangeConfiguration((event) => {
+ if (event.affectsConfiguration("doxdocgen.generic.commandSuggestion")) {
vscode.window.showWarningMessage("Please restart vscode to apply the changes!");
+ }
});
}
diff --git a/src/test/index.ts b/src/test/index.ts
index 5dfa541..89f953b 100644
--- a/src/test/index.ts
+++ b/src/test/index.ts
@@ -1,220 +1,69 @@
-"use strict";
-
-import * as fs from "fs";
import * as glob from "glob";
-import * as paths from "path";
-
-import istanbul = require("istanbul");
-import remapIstanbul = require("remap-istanbul");
-// tslint:disable-next-line:no-var-requires
-const tty = require("tty");
-// tslint:disable-next-line:no-var-requires
-const Mocha = require("mocha");
-
-// Linux: prevent a weird NPE when mocha on Linux requires the window size from the TTY
-// Since we are not running in a tty environment, we just implementt he method statically
-if (!tty.getWindowSize) {
- tty.getWindowSize = (): number[] => {
- return [80, 75];
- };
-}
-
-let mocha = new Mocha({
- ui: "tdd",
- useColors: true,
-});
-
-function configure(mochaOpts): void {
- mocha = new Mocha(mochaOpts);
-}
-exports.configure = configure;
-
-function _mkDirIfExists(dir: string): void {
- if (!fs.existsSync(dir)) {
- fs.mkdirSync(dir);
- }
-}
-
-function _readCoverOptions(testsRoot: string): ITestRunnerOptions {
- const coverConfigPath = paths.join(testsRoot, "..", "..", "coverconfig.json");
- let coverConfig: ITestRunnerOptions;
- if (fs.existsSync(coverConfigPath)) {
- const configContent = fs.readFileSync(coverConfigPath, "utf-8");
- coverConfig = JSON.parse(configContent);
- }
- return coverConfig;
-}
-
-function run(testsRoot, clb): any {
- // Enable source map support
- require("source-map-support").install();
-
- // Read configuration for the coverage file
- const coverOptions: ITestRunnerOptions = _readCoverOptions(testsRoot);
- if (coverOptions && coverOptions.enabled) {
- // Setup coverage pre-test, including post-test hook to report
- const coverageRunner = new CoverageRunner(coverOptions, testsRoot, clb);
- coverageRunner.setupCoverage();
- }
-
- // Glob test files
- glob("**/**.test.js", { cwd: testsRoot }, (error, files): any => {
- if (error) {
- return clb(error);
- }
- try {
- // Fill into Mocha
- files.forEach((f): Mocha => {
- return mocha.addFile(paths.join(testsRoot, f));
- });
- // Run the tests
- let failureCount = 0;
-
- mocha.run()
- .on("fail", (test, err): void => {
- failureCount++;
- })
- .on("end", (): void => {
- clb(undefined, failureCount);
- });
- } catch (error) {
- return clb(error);
- }
+import * as Mocha from "mocha";
+import * as path from "path";
+
+function setupNyc() {
+ const NYC = require("nyc");
+ // create an nyc instance, config here is the same as your package.json
+ const nyc = new NYC({
+ cache: false,
+ cwd: path.join(__dirname, "..", ".."),
+ exclude: [
+ "**/**.test.js",
+ ],
+ extension: [
+ ".ts",
+ ".tsx",
+ ],
+ hookRequire: true,
+ hookRunInContext: true,
+ hookRunInThisContext: true,
+ instrument: true,
+ reporter: ["text", "lcov", "cobertura"],
+ require: [
+ "ts-node/register",
+ "source-map-support/register",
+ ],
+ sourceMap: true,
});
+ nyc.reset();
+ nyc.wrap();
+ return nyc;
}
-exports.run = run;
-
-interface ITestRunnerOptions {
- enabled?: boolean;
- relativeCoverageDir: string;
- relativeSourcePath: string;
- ignorePatterns: string[];
- includePid?: boolean;
- reports?: string[];
- verbose?: boolean;
-}
-
-class CoverageRunner {
-
- private coverageVar: string = "$$cov_" + new Date().getTime() + "$$";
- private transformer: any = undefined;
- private matchFn: any = undefined;
- private instrumenter: any = undefined;
-
- constructor(private options: ITestRunnerOptions, private testsRoot: string, private endRunCallback: any) {
- if (!options.relativeSourcePath) {
- return endRunCallback("Error - relativeSourcePath must be defined for code coverage to work");
- }
-
- }
- public setupCoverage(): void {
- // Set up Code Coverage, hooking require so that instrumented code is returned
- this.instrumenter = new istanbul.Instrumenter({ coverageVariable: this.coverageVar });
- const sourceRoot = paths.join(this.testsRoot, this.options.relativeSourcePath);
-
- // Glob source files
- const srcFiles = glob.sync("**/**.js", {
- cwd: sourceRoot,
- ignore: this.options.ignorePatterns,
- });
-
- // Create a match function - taken from the run-with-cover.js in istanbul.
- const decache = require("decache");
- const fileMap = {};
- srcFiles.forEach( (file) => {
- const fullPath = paths.join(sourceRoot, file);
- fileMap[fullPath] = true;
-
- // On Windows, extension is loaded pre-test hooks and this mean we lose
- // our chance to hook the Require call. In order to instrument the code
- // we have to decache the JS file so on next load it gets instrumented.
- // This doesn"t impact tests, but is a concern if we had some integration
- // tests that relied on VSCode accessing our module since there could be
- // some shared global state that we lose.
- decache(fullPath);
- });
-
- this.matchFn = (file): boolean => fileMap[file];
- this.matchFn.files = Object.keys(fileMap);
-
- // Hook up to the Require function so that when this is called, if any of our source files
- // are required, the instrumented version is pulled in instead. These instrumented versions
- // write to a global coverage variable with hit counts whenever they are accessed
- this.transformer = this.instrumenter.instrumentSync.bind(this.instrumenter);
- const hookOpts = { verbose: false, extensions: [".js"]};
- istanbul.hook.hookRequire(this.matchFn, this.transformer, hookOpts);
-
- // initialize the global variable to stop mocha from complaining about leaks
- global[this.coverageVar] = {};
-
- // Hook the process exit event to handle reporting
- // Only report coverage if the process is exiting successfully
- process.on("exit", (code) => {
- this.reportCoverage();
- });
- }
-
- /**
- * Writes a coverage report.
- * Note that as this is called in the process exit callback, all calls must be synchronous.
- *
- * @returns {void}
- *
- * @memberOf CoverageRunner
- */
- public reportCoverage(): void {
- istanbul.hook.unhookRequire();
- let cov: any;
- if (typeof global[this.coverageVar] === "undefined" || Object.keys(global[this.coverageVar]).length === 0) {
- // tslint:disable:no-console
- console.error("No coverage information was collected, exit without writing coverage information");
- return;
- } else {
- cov = global[this.coverageVar];
- }
-
- // TODO consider putting this under a conditional flag
- // Files that are not touched by code ran by the test runner is manually instrumented, to
- // illustrate the missing coverage.
- this.matchFn.files.forEach( (file) => {
- if (!cov[file]) {
- this.transformer(fs.readFileSync(file, "utf-8"), file);
-
- // When instrumenting the code, istanbul will give each FunctionDeclaration a value of 1 in
- // coverState.s, presumably to compensate for function hoisting. We need to reset this, as the function
- // was not hoisted, as it was never loaded.
- Object.keys(this.instrumenter.coverState.s).forEach( (key) => {
- this.instrumenter.coverState.s[key] = 0;
- });
-
- cov[file] = this.instrumenter.coverState;
- }
- });
-
- // TODO Allow config of reporting directory with
- const reportingDir = paths.join(this.testsRoot, this.options.relativeCoverageDir);
- const includePid = this.options.includePid;
- const pidExt = includePid ? ("-" + process.pid) : "";
- const coverageFile = paths.resolve(reportingDir, "coverage" + pidExt + ".json");
-
- // yes, do this again since some test runners could clean the dir initially created
- _mkDirIfExists(reportingDir);
- fs.writeFileSync(coverageFile, JSON.stringify(cov), "utf8");
-
- const remappedCollector = remapIstanbul.remap(cov, {warn: (warning) => {
- // We expect some warnings as any JS file without a typescript mapping will cause this.
- // By default, we"ll skip printing these to the console as it clutters it up
- if (this.options.verbose) {
- console.warn(warning);
- }
- }});
-
- const reporter = new istanbul.Reporter(undefined, reportingDir);
- const reportTypes = (this.options.reports instanceof Array) ? this.options.reports : ["lcov"];
- reporter.addAll(reportTypes);
- reporter.write(remappedCollector, true, () => {
- console.log(`reports written to ${reportingDir}`);
+export function run(): Promise<void> {
+ // Create the mocha test
+ const mocha = new Mocha({
+ ui: "tdd",
+ });
+
+ const nyc = setupNyc();
+ const testsRoot = path.resolve(__dirname, ".");
+
+ return new Promise((c, e) => {
+ glob("**/**.test.js", { cwd: testsRoot }, (err, files) => {
+ if (err) {
+ return e(err);
+ }
+
+ // Add files to the test suite
+ files.forEach((f) => mocha.addFile(path.resolve(testsRoot, f)));
+
+ try {
+ // Run the mocha test
+ mocha.run((failures) => {
+ if (failures > 0) {
+ e(new Error(`${failures} tests failed.`));
+ } else {
+ c();
+ }
});
- }
+ } catch (err) {
+ e(err);
+ } finally {
+ nyc.writeCoverageFile();
+ nyc.report();
+ }
+ });
+ });
}
diff --git a/src/test/runTests.ts b/src/test/runTests.ts
new file mode 100644
index 0000000..70c2381
--- /dev/null
+++ b/src/test/runTests.ts
@@ -0,0 +1,28 @@
+import * as path from "path";
+
+import { runTests } from "vscode-test";
+
+async function main() {
+ try {
+ // The folder containing the Extension Manifest package.json
+ // Passed to `--extensionDevelopmentPath`
+ const extensionDevelopmentPath = path.resolve(__dirname, "../../");
+
+ // The path to the extension test runner script
+ // Passed to --extensionTestsPath
+ const extensionTestsPath = path.resolve(__dirname, "./index");
+
+ // Download VS Code, unzip it and run the integration test
+ await runTests({ extensionDevelopmentPath, extensionTestsPath });
+ } catch (err) {
+ // tslint:disable-next-line: no-console
+ console.error("Got error:");
+ // tslint:disable-next-line: no-console
+ console.error(err);
+ // tslint:disable-next-line: no-console
+ console.error("Failed to run tests");
+ process.exit(1);
+ }
+}
+
+main();