From b446b9e596fc0487b88597d8e818dae61512f309 Mon Sep 17 00:00:00 2001 From: Rowan Goemans Date: Fri, 29 Dec 2017 00:15:59 +0100 Subject: -- Added more unit tests. -- Added support for alignas. --- src/CodeParser/CParser/CParser.ts | 44 +++++++++------- src/CodeParser/CParser/Token.ts | 2 +- src/test/Attributes.test.ts | 49 ++++++++++++++++++ src/test/FunctionPointer.test.ts | 42 +++++++++++++++ src/test/MockDocument.ts | 52 ------------------- src/test/MockEditor.ts | 43 ---------------- src/test/MockLine.ts | 13 ----- src/test/MockPosition.ts | 39 -------------- src/test/MockSelection.ts | 35 ------------- src/test/MockTextEditorEdit.ts | 18 ------- src/test/Operators.test.ts | 38 ++++++++++++++ src/test/ReturnTypes.test.ts | 99 ++++++++++++++++++++++++++++++++++++ src/test/Templates.test.ts | 44 ++++++++++++++++ src/test/TestSetup.ts | 46 ----------------- src/test/TrailingReturns.test.ts | 39 ++++++++++++++ src/test/Variadic.test.ts | 38 ++++++++++++++ src/test/functionPointer.test.ts | 42 --------------- src/test/simpleReturn.test.ts | 79 ---------------------------- src/test/tools/MockDocument.ts | 52 +++++++++++++++++++ src/test/tools/MockEditor.ts | 43 ++++++++++++++++ src/test/tools/MockLine.ts | 13 +++++ src/test/tools/MockPosition.ts | 39 ++++++++++++++ src/test/tools/MockSelection.ts | 35 +++++++++++++ src/test/tools/MockTextEditorEdit.ts | 18 +++++++ src/test/tools/TestSetup.ts | 46 +++++++++++++++++ 25 files changed, 621 insertions(+), 387 deletions(-) create mode 100644 src/test/Attributes.test.ts create mode 100644 src/test/FunctionPointer.test.ts delete mode 100644 src/test/MockDocument.ts delete mode 100644 src/test/MockEditor.ts delete mode 100644 src/test/MockLine.ts delete mode 100644 src/test/MockPosition.ts delete mode 100644 src/test/MockSelection.ts delete mode 100644 src/test/MockTextEditorEdit.ts create mode 100644 src/test/Operators.test.ts create mode 100644 src/test/ReturnTypes.test.ts create mode 100644 src/test/Templates.test.ts delete mode 100644 src/test/TestSetup.ts create mode 100644 src/test/TrailingReturns.test.ts create mode 100644 src/test/Variadic.test.ts delete mode 100644 src/test/functionPointer.test.ts delete mode 100644 src/test/simpleReturn.test.ts create mode 100644 src/test/tools/MockDocument.ts create mode 100644 src/test/tools/MockEditor.ts create mode 100644 src/test/tools/MockLine.ts create mode 100644 src/test/tools/MockPosition.ts create mode 100644 src/test/tools/MockSelection.ts create mode 100644 src/test/tools/MockTextEditorEdit.ts create mode 100644 src/test/tools/TestSetup.ts (limited to 'src') diff --git a/src/CodeParser/CParser/CParser.ts b/src/CodeParser/CParser/CParser.ts index 3203b40..34ffba4 100644 --- a/src/CodeParser/CParser/CParser.ts +++ b/src/CodeParser/CParser/CParser.ts @@ -22,7 +22,7 @@ export default class CParser implements ICodeParser { private typeKeywords: string[]; private stripKeywords: string[]; private keywords: string[]; - private noexcepts: string[]; + private specifiers: string[]; private lexerVocabulary; constructor() { @@ -33,6 +33,7 @@ export default class CParser implements ICodeParser { ]; this.stripKeywords = [ + "final", "static", "inline", "friend", @@ -44,9 +45,10 @@ export default class CParser implements ICodeParser { "typename", ]; - this.noexcepts = [ + this.specifiers = [ "noexcept", "throw", + "alignas", ]; // Non type keywords will be stripped from the final return type. @@ -85,36 +87,36 @@ export default class CParser implements ICodeParser { return startEndOffset[1] === 0 ? undefined : x.slice(0, startEndOffset[1]); }, Ellipsis: (x: string): string => (x.match("^\\.\\.\\.") || [])[0], - Noexcept: (x: string): string => { - const foundIndex: number = this.noexcepts + OpenParenthesis: (x: string): string => (x.match("^\\(") || [])[0], + Pointer: (x: string): string => (x.match("^\\*") || [])[0], + Reference: (x: string): string => (x.match("^&") || [])[0], + Specifier: (x: string): string => { + const foundIndex: number = this.specifiers .findIndex((n: string) => x.startsWith(n) === true); if (foundIndex === -1) { return undefined; } - if (x.slice(this.noexcepts[foundIndex].length).trim().startsWith("(") === false) { - return x.slice(0, this.noexcepts[foundIndex].length); + if (x.slice(this.specifiers[foundIndex].length).trim().startsWith("(") === false) { + return x.slice(0, this.specifiers[foundIndex].length); } const startEndOffset: number[] = this.GetSubExprStartEnd(x, 0, "(", ")"); return startEndOffset[1] === 0 ? undefined : x.slice(0, startEndOffset[1]); }, - OpenParenthesis: (x: string): string => (x.match("^\\(") || [])[0], - Pointer: (x: string): string => (x.match("^\\*") || [])[0], - Reference: (x: string): string => (x.match("^&") || [])[0], Symbol: (x: string): string => { // Handle access specifiers since they aren't really symbols. if (x.startsWith("public:") || x.startsWith("protected:") || x.startsWith("private:")) { return undefined; } - // Handle noexcept and throw since they aren't normal symbols. - const noExceptFound: number = this.noexcepts + // Handle specifiers + const specifierFound: number = this.specifiers .findIndex((n: string) => x.startsWith(n) === true); - if (noExceptFound !== -1) { + if (specifierFound !== -1) { return undefined; } @@ -156,10 +158,10 @@ export default class CParser implements ICodeParser { break; } - symbol += reMatch.trim(); + symbol += reMatch; } - return symbol.trim(); + return symbol.replace(/\s+$/, ""); }, }; } @@ -348,11 +350,15 @@ export default class CParser implements ICodeParser { tree.nodes = tree.nodes.slice(0, assignmentIndex); } - // Noexcept isn't needed so slice everything after it. - const noexcept = tree.nodes - .findIndex((n) => n instanceof Token && n.Type === TokenType.Noexcept); - if (noexcept !== -1) { - tree.nodes = tree.nodes.slice(0, noexcept); + // Specifiers aren't needed so remove them. + while (true) { + const specifierIndex = tree.nodes + .findIndex((n) => n instanceof Token && n.Type === TokenType.Specifier); + if (specifierIndex !== -1) { + tree.nodes.splice(specifierIndex, 1); + } else { + break; + } } return tree; diff --git a/src/CodeParser/CParser/Token.ts b/src/CodeParser/CParser/Token.ts index c9d3065..0cbd412 100644 --- a/src/CodeParser/CParser/Token.ts +++ b/src/CodeParser/CParser/Token.ts @@ -13,7 +13,7 @@ export enum TokenType { CommentLine, Ellipsis, Attribute, - Noexcept, + Specifier, } export class Token { diff --git a/src/test/Attributes.test.ts b/src/test/Attributes.test.ts new file mode 100644 index 0000000..680694a --- /dev/null +++ b/src/test/Attributes.test.ts @@ -0,0 +1,49 @@ +// +// Note: This example test is leveraging the Mocha test framework. +// Please refer to their documentation on https://mochajs.org/ for help. +// + +// The module 'assert' provides assertion methods from node +import * as assert from "assert"; + +// You can import and use all API from the 'vscode' module +// as well as import your extension to test it +import * as vscode from "vscode"; +import TestSetup from "./tools/TestSetup"; + +// Defines a Mocha test suite to group tests of similar kind together +suite("Attributes Tests", () => { + const testSetup: TestSetup = new TestSetup("void foo();"); + + // Tests + test("Attributes on parameter", () => { + const result = testSetup.SetLine("int foo([[maybe_unused]] int a, [[maybe_unused]]double& b);").GetResult(); + assert.equal("/**\n * @brief \n * \n * @param a \n * @param b \n * @return int \n */", result); + }); + + test("Attributes on function", () => { + const result = testSetup.SetLine("[[nodiscard]] int foo(int a, double& b);").GetResult(); + assert.equal("/**\n * @brief \n * \n * @param a \n * @param b \n * @return int \n */", result); + }); + + test("Multiple attributes on parameter", () => { + const result = testSetup.SetLine("int foo([[maybe_unused]] [[carries_dependency]]" + + " int a, double& b);").GetResult(); + assert.equal("/**\n * @brief \n * \n * @param a \n * @param b \n * @return int \n */", result); + }); + + test("Multiple attributes on function", () => { + const result = testSetup.SetLine("[[nodiscard]][[deprecated(\"old\")]] int foo(int a, double& b);").GetResult(); + assert.equal("/**\n * @brief \n * \n * @param a \n * @param b \n * @return int \n */", result); + }); + + test("Specifier and attribute on class", () => { + const result = testSetup.SetLine("class [[nodiscard]] alignas(8) Matrix {").GetResult(); + assert.equal("/**\n * @brief \n * \n */", result); + }); + + test("Specifier and attribute on struct", () => { + const result = testSetup.SetLine("struct [[nodiscard]] alignas(8) Matrix {").GetResult(); + assert.equal("/**\n * @brief \n * \n */", result); + }); +}); diff --git a/src/test/FunctionPointer.test.ts b/src/test/FunctionPointer.test.ts new file mode 100644 index 0000000..dd1ead0 --- /dev/null +++ b/src/test/FunctionPointer.test.ts @@ -0,0 +1,42 @@ +// +// Note: This example test is leveraging the Mocha test framework. +// Please refer to their documentation on https://mochajs.org/ for help. +// + +// The module 'assert' provides assertion methods from node +import * as assert from "assert"; + +// You can import and use all API from the 'vscode' module +// as well as import your extension to test it +import * as vscode from "vscode"; +import TestSetup from "./tools/TestSetup"; + +// Defines a Mocha test suite to group tests of similar kind together +suite("Function pointer Tests", () => { + const testSetup: TestSetup = new TestSetup("void foo();"); + + // Tests + test("function pointer return", () => { + const result = testSetup.SetLine("int (*idputs(int a, int b))(char *);").GetResult(); + assert.equal("/**\n * @brief \n * \n * @param a \n * @param b \n * @return int(*)(char*) \n */", result); + }); + + test("nested function pointer return", () => { + const result = testSetup.SetLine("int (*(*(*foo(int a, int b))(int))(double))(float);").GetResult(); + assert.equal("/**\n * @brief \n * \n * @param a \n * @param b \n" + + " * @return int(*(*(*)(int))(double))(float) \n */", result); + }); + + test("function pointer parameter", () => { + const result = testSetup.SetLine("int foo(int (*puts)(const char *));").GetResult(); + assert.equal("/**\n * @brief \n * \n * @param puts \n * @return int \n */", result); + }); + + test("struct function pointer return with struct FP parameters and keywords", () => { + const result = testSetup.SetLine("const struct foo (*idputs(int (*puts)(const char *), const" + + " struct test(*str)(int *, const struct test(*str2))))(const char *);").GetResult(); + + assert.equal("/**\n * @brief \n * \n * @param puts \n * @param str " + + "\n * @return const struct foo(*)(const char*) \n */", result); + }); +}); diff --git a/src/test/MockDocument.ts b/src/test/MockDocument.ts deleted file mode 100644 index cb6bbfe..0000000 --- a/src/test/MockDocument.ts +++ /dev/null @@ -1,52 +0,0 @@ -import * as vscode from "vscode"; -import MockLine from "./MockLine"; - -export default class MockDocument implements vscode.TextDocument { - public uri: vscode.Uri; - public fileName: string; - public isUntitled: boolean; - public languageId: string; - public version: number; - public isDirty: boolean; - public isClosed: boolean; - public eol: vscode.EndOfLine; - public lineCount: number; - private line: vscode.TextLine; - private callCount: number; - public constructor(line: vscode.TextLine) { - this.line = line; - this.callCount = 0; - } - public save(): Thenable { - throw new Error("Method not implemented."); - } - public lineAt(line: number | vscode.Position): vscode.TextLine; - public lineAt(position: any): any { - if (++this.callCount === 1) { - return new MockLine(""); - } else if (this.callCount === 2) { - return this.line; - } else { - return new MockLine(";"); - } - } - public offsetAt(position: vscode.Position): number { - throw new Error("Method not implemented."); - } - public positionAt(offset: number): vscode.Position { - throw new Error("Method not implemented."); - } - public getText(range?: vscode.Range): string { - throw new Error("Method not implemented."); - } - public getWordRangeAtPosition(position: vscode.Position, regex?: RegExp): vscode.Range { - throw new Error("Method not implemented."); - } - public validateRange(range: vscode.Range): vscode.Range { - throw new Error("Method not implemented."); - } - public validatePosition(position: vscode.Position): vscode.Position { - throw new Error("Method not implemented."); - } - -} diff --git a/src/test/MockEditor.ts b/src/test/MockEditor.ts deleted file mode 100644 index 5368fb8..0000000 --- a/src/test/MockEditor.ts +++ /dev/null @@ -1,43 +0,0 @@ -import * as vscode from "vscode"; -import { TextEditor } from "vscode"; -import MockDocument from "./MockDocument"; -import MockSelection from "./MockSelection"; -import MockTextEditorEdit from "./MockTextEditorEdit"; - -export default class MockEditor implements TextEditor { - public document: vscode.TextDocument; - public selection: vscode.Selection; - public selections: vscode.Selection[]; - public options: vscode.TextEditorOptions; - public viewColumn?: vscode.ViewColumn; - public editBuilder: MockTextEditorEdit; - public constructor(s: MockSelection, d: MockDocument) { - this.selection = s; - this.document = d; - this.editBuilder = new MockTextEditorEdit(); - } - - public edit(callback: (editBuilder: vscode.TextEditorEdit) => void, - options?: { undoStopBefore: boolean; undoStopAfter: boolean; }): Thenable { - callback(this.editBuilder); - return Promise.resolve(true); - } - public insertSnippet(snippet: vscode.SnippetString, - location?: vscode.Position | vscode.Range | vscode.Position[] | vscode.Range[], - options?: { undoStopBefore: boolean; undoStopAfter: boolean; }): Thenable { - throw new Error("Method not implemented."); - } - public setDecorations(decorationType: vscode.TextEditorDecorationType, - rangesOrOptions: vscode.Range[] | vscode.DecorationOptions[]): void { - throw new Error("Method not implemented."); - } - public revealRange(range: vscode.Range, revealType?: vscode.TextEditorRevealType): void { - throw new Error("Method not implemented."); - } - public show(column?: vscode.ViewColumn): void { - throw new Error("Method not implemented."); - } - public hide(): void { - throw new Error("Method not implemented."); - } -} diff --git a/src/test/MockLine.ts b/src/test/MockLine.ts deleted file mode 100644 index 7196a38..0000000 --- a/src/test/MockLine.ts +++ /dev/null @@ -1,13 +0,0 @@ -import * as vscode from "vscode"; - -export default class MockLine implements vscode.TextLine { - public lineNumber: number; - public text: string; - public range: vscode.Range; - public rangeIncludingLineBreak: vscode.Range; - public firstNonWhitespaceCharacterIndex: number; - public isEmptyOrWhitespace: boolean; - public constructor(text: string) { - this.text = text; - } -} diff --git a/src/test/MockPosition.ts b/src/test/MockPosition.ts deleted file mode 100644 index 0753670..0000000 --- a/src/test/MockPosition.ts +++ /dev/null @@ -1,39 +0,0 @@ -import * as vscode from "vscode"; - -export default class MockPosition implements vscode.Position { - public line: number; - public character: number; - public constructor(l: number, c: number) { - this.line = l; - this.character = c; - } - public isBefore(other: vscode.Position): boolean { - throw new Error("Method not implemented."); - } - public isBeforeOrEqual(other: vscode.Position): boolean { - throw new Error("Method not implemented."); - } - public isAfter(other: vscode.Position): boolean { - throw new Error("Method not implemented."); - } - public isAfterOrEqual(other: vscode.Position): boolean { - throw new Error("Method not implemented."); - } - public isEqual(other: vscode.Position): boolean { - throw new Error("Method not implemented."); - } - public compareTo(other: vscode.Position): number { - throw new Error("Method not implemented."); - } - public translate(lineDelta?: number, characterDelta?: number): vscode.Position; - public translate(change: { lineDelta?: number; characterDelta?: number; }): vscode.Position; - public translate(lineDelta?: any, characterDelta?: any): any { - throw new Error("Method not implemented."); - } - public with(line?: number, character?: number): vscode.Position; - public with(change: { line?: number; character?: number; }): vscode.Position; - public with(line?: any, character?: any): any { - throw new Error("Method not implemented."); - } - -} diff --git a/src/test/MockSelection.ts b/src/test/MockSelection.ts deleted file mode 100644 index e72ff8b..0000000 --- a/src/test/MockSelection.ts +++ /dev/null @@ -1,35 +0,0 @@ -import * as vscode from "vscode"; -import MockPosition from "./MockPosition"; - -export default class MockSelection implements vscode.Selection { - public anchor: vscode.Position; - public active: vscode.Position; - public isReversed: boolean; - public start: vscode.Position; - public end: vscode.Position; - public isEmpty: boolean; - public isSingleLine: boolean; - - public constructor(a: MockPosition) { - this.active = a; - this.start = a; - } - - public contains(positionOrRange: vscode.Range | vscode.Position): boolean { - throw new Error("Method not implemented."); - } - public isEqual(other: vscode.Range): boolean { - throw new Error("Method not implemented."); - } - public intersection(range: vscode.Range): vscode.Range { - throw new Error("Method not implemented."); - } - public union(other: vscode.Range): vscode.Range { - throw new Error("Method not implemented."); - } - public with(start?: vscode.Position, end?: vscode.Position): vscode.Range; - public with(change: { start?: vscode.Position; end?: vscode.Position; }): vscode.Range; - public with(start?: any, end?: any): any { - throw new Error("Method not implemented."); - } -} diff --git a/src/test/MockTextEditorEdit.ts b/src/test/MockTextEditorEdit.ts deleted file mode 100644 index e751182..0000000 --- a/src/test/MockTextEditorEdit.ts +++ /dev/null @@ -1,18 +0,0 @@ -import * as vscode from "vscode"; - -export default class MockTextEditorEdit implements vscode.TextEditorEdit { - public text: string; - public replace(location: vscode.Position | vscode.Range | vscode.Selection, value: string): void { - this.text = value; - } - public insert(location: vscode.Position, value: string): void { - throw new Error("Method not implemented."); - } - public delete(location: vscode.Range | vscode.Selection): void { - throw new Error("Method not implemented."); - } - public setEndOfLine(endOfLine: vscode.EndOfLine): void { - throw new Error("Method not implemented."); - } - -} diff --git a/src/test/Operators.test.ts b/src/test/Operators.test.ts new file mode 100644 index 0000000..86c04b2 --- /dev/null +++ b/src/test/Operators.test.ts @@ -0,0 +1,38 @@ +// +// Note: This example test is leveraging the Mocha test framework. +// Please refer to their documentation on https://mochajs.org/ for help. +// + +// The module 'assert' provides assertion methods from node +import * as assert from "assert"; + +// You can import and use all API from the 'vscode' module +// as well as import your extension to test it +import * as vscode from "vscode"; +import TestSetup from "./tools/TestSetup"; + +// Defines a Mocha test suite to group tests of similar kind together +suite("Operators Tests", () => { + const testSetup: TestSetup = new TestSetup("void foo();"); + + // Tests + test("", () => { + const result = testSetup.SetLine("").GetResult(); + assert.equal("", result); + }); + + test("", () => { + const result = testSetup.SetLine("").GetResult(); + assert.equal("", result); + }); + + test("", () => { + const result = testSetup.SetLine("").GetResult(); + assert.equal("", result); + }); + + test("", () => { + const result = testSetup.SetLine("").GetResult(); + assert.equal("", result); + }); +}); diff --git a/src/test/ReturnTypes.test.ts b/src/test/ReturnTypes.test.ts new file mode 100644 index 0000000..f38fb1f --- /dev/null +++ b/src/test/ReturnTypes.test.ts @@ -0,0 +1,99 @@ +// +// Note: This example test is leveraging the Mocha test framework. +// Please refer to their documentation on https://mochajs.org/ for help. +// + +// The module 'assert' provides assertion methods from node +import * as assert from "assert"; + +// You can import and use all API from the 'vscode' module +// as well as import your extension to test it +import * as vscode from "vscode"; +import TestSetup from "./tools/TestSetup"; + +// Defines a Mocha test suite to group tests of similar kind together +suite("Return type Tests", () => { + + const testSetup: TestSetup = new TestSetup("void foo();"); + + // Tests + test("void return", () => { + const result = testSetup.SetLine("void foo();").GetResult(); + assert.equal("/**\n * @brief \n * \n */", result); + }); + + test("void pointer return", () => { + const result = testSetup.SetLine("void* foo();").GetResult(); + assert.equal("/**\n * @brief \n * \n * @return void* \n */", result); + }); + + test("Reference return", () => { + const result = testSetup.SetLine("int& foo();").GetResult(); + assert.equal("/**\n * @brief \n * \n * @return int& \n */", result); + }); + + test("simple type return", () => { + const result = testSetup.SetLine("int foo();").GetResult(); + assert.equal("/**\n * @brief \n * \n * @return int \n */", result); + }); + + test("bool return type", () => { + const result = testSetup.SetLine("bool foo();").GetResult(); + assert.equal("/**\n * @brief \n * \n * @return true \n * @return false \n */", result); + }); + + test("pointer return type", () => { + const result = testSetup.SetLine("int* foo();").GetResult(); + assert.equal("/**\n * @brief \n * \n * @return int* \n */", result); + }); + + test("bool pointer return type", () => { + const result = testSetup.SetLine("bool* foo();").GetResult(); + assert.equal("/**\n * @brief \n * \n * @return true \n * @return false \n * @return null \n */", result); + }); + + test("Struct pointer return type", () => { + const result = testSetup.SetLine("struct foo* foo();").GetResult(); + assert.equal("/**\n * @brief \n * \n * @return struct foo* \n */", result); + }); + + test("Struct return type", () => { + const result = testSetup.SetLine("struct Bar* foo();").GetResult(); + assert.equal("/**\n * @brief \n * \n * @return struct Bar* \n */", result); + }); + + test("Return type with keywords and noexcept", () => { + const result = testSetup.SetLine("static constexpr inline struct Bar* foo() " + + "const noexcept(false);").GetResult(); + assert.equal("/**\n * @brief \n * \n * @return constexpr struct Bar* \n */", result); + }); + + test("Fundamental return type with modifiers", () => { + let result = testSetup.SetLine("unsigned int foo();").GetResult(); + assert.equal("/**\n * @brief \n * \n * @return unsigned int \n */", result); + + result = testSetup.SetLine("unsigned short int foo();").GetResult(); + assert.equal("/**\n * @brief \n * \n * @return unsigned short int \n */", result); + + result = testSetup.SetLine("signed short foo();").GetResult(); + assert.equal("/**\n * @brief \n * \n * @return signed short \n */", result); + + result = testSetup.SetLine("long foo();").GetResult(); + assert.equal("/**\n * @brief \n * \n * @return long \n */", result); + + result = testSetup.SetLine("unsigned long long int foo();").GetResult(); + assert.equal("/**\n * @brief \n * \n * @return unsigned long long int \n */", result); + + result = testSetup.SetLine("signed foo();").GetResult(); + assert.equal("/**\n * @brief \n * \n * @return signed \n */", result); + + result = testSetup.SetLine("unsigned foo();").GetResult(); + assert.equal("/**\n * @brief \n * \n * @return unsigned \n */", result); + + result = testSetup.SetLine("unsigned char foo();").GetResult(); + assert.equal("/**\n * @brief \n * \n * @return unsigned char \n */", result); + + result = testSetup.SetLine("long double foo();").GetResult(); + assert.equal("/**\n * @brief \n * \n * @return long double \n */", result); + }); +}); diff --git a/src/test/Templates.test.ts b/src/test/Templates.test.ts new file mode 100644 index 0000000..d4c0fe6 --- /dev/null +++ b/src/test/Templates.test.ts @@ -0,0 +1,44 @@ +// +// Note: This example test is leveraging the Mocha test framework. +// Please refer to their documentation on https://mochajs.org/ for help. +// + +// The module 'assert' provides assertion methods from node +import * as assert from "assert"; + +// You can import and use all API from the 'vscode' module +// as well as import your extension to test it +import * as vscode from "vscode"; +import TestSetup from "./tools/TestSetup"; + +// Defines a Mocha test suite to group tests of similar kind together +suite("Template tests", () => { + const testSetup: TestSetup = new TestSetup("void foo();"); + + // Tests + test("template class", () => { + const result = testSetup.SetLine("template::value, T>::type>" + + "class matrix {").GetResult(); + assert.equal("/**\n * @brief \n * \n * @tparam T \n * @tparam M \n * @tparam N \n * " + + "@tparam std::enable_if::value, T>::type \n */", result); + }); + + test("template function", () => { + const result = testSetup.SetLine("template\nT f(T a, S b);").GetResult(); + assert.equal("/**\n * @brief \n * \n * @tparam T \n * @tparam S \n * @param a \n * " + + "@param b \n * @return T \n */", result); + }); + + test("double template", () => { + const result = testSetup.SetLine("template\ntemplate\nT f(T a, S b);").GetResult(); + assert.equal("/**\n * @brief \n * \n * @tparam T \n * @tparam S \n * @param a \n * " + + "@param b \n * @return T \n */", result); + }); + + test("template struct", () => { + const result = testSetup.SetLine("template\n" + + "struct myStruct {").GetResult(); + assert.equal("/**\n * @brief \n * \n * @tparam T \n * @tparam m \n * @tparam n \n */", result); + }); +}); diff --git a/src/test/TestSetup.ts b/src/test/TestSetup.ts deleted file mode 100644 index 2f4f64a..0000000 --- a/src/test/TestSetup.ts +++ /dev/null @@ -1,46 +0,0 @@ -import * as vscode from "vscode"; -import CodeParser from "../CodeParser/CodeParser"; -import CParser from "../CodeParser/CParser/CParser"; -import { IDocGen } from "../DocGen/DocGen"; -import * as myExtension from "../extension"; -import MockDocument from "./MockDocument"; -import MockEditor from "./MockEditor"; -import MockLine from "./MockLine"; -import MockPosition from "./MockPosition"; -import MockSelection from "./MockSelection"; - -export default class TestSetup { - private editor: MockEditor; - - constructor(method: string) { - this.SetMethod(method); - } - - public SetMethod(method: string): TestSetup { - let position: MockPosition; - position = new MockPosition(0, 0); - - let selection: MockSelection; - selection = new MockSelection(position); - - let line: MockLine; - line = new MockLine(method); - - let doc: MockDocument; - doc = new MockDocument(line); - - this.editor = new MockEditor(selection, doc); - - return this; - } - - public GetResult(): string { - let parser: CodeParser; - parser = new CParser(); - - const gen: IDocGen = parser.Parse(this.editor); - gen.GenerateDoc(new vscode.Range(new vscode.Position(0, 0), new vscode.Position(0, 0))); - - return this.editor.editBuilder.text; - } -} diff --git a/src/test/TrailingReturns.test.ts b/src/test/TrailingReturns.test.ts new file mode 100644 index 0000000..6c182f9 --- /dev/null +++ b/src/test/TrailingReturns.test.ts @@ -0,0 +1,39 @@ +// +// Note: This example test is leveraging the Mocha test framework. +// Please refer to their documentation on https://mochajs.org/ for help. +// + +// The module 'assert' provides assertion methods from node +import * as assert from "assert"; + +// You can import and use all API from the 'vscode' module +// as well as import your extension to test it +import * as vscode from "vscode"; +import TestSetup from "./tools/TestSetup"; + +// Defines a Mocha test suite to group tests of similar kind together +suite("Trailing returns tests", () => { + const testSetup: TestSetup = new TestSetup("void foo();"); + + // tests + test("Trailing return", () => { + const result = testSetup.SetLine("auto foo() -> int;").GetResult(); + assert.equal("/**\n * @brief \n * \n * @return int \n */", result); + }); + + test("Trailing return with decltype", () => { + const result = testSetup.SetLine("auto foo(int a, double b) -> decltype(a + b);").GetResult(); + assert.equal("/**\n * @brief \n * \n * @param a \n * @param b \n * @return decltype(a + b) \n */", result); + }); + + test("Multiple trailing returns", () => { + const result = testSetup.SetLine("auto foo() -> auto(*)() -> tmp(*)();").GetResult(); + assert.equal("/**\n * @brief \n * \n * @return auto(*)() -> tmp(*)() \n */", result); + }); + + test("Trailing return with keywords", () => { + const result = testSetup.SetLine("auto foo(const int& a, const double* b) const noexcept -> const double&;") + .GetResult(); + assert.equal("/**\n * @brief \n * \n * @param a \n * @param b \n * @return const double& \n */", result); + }); +}); diff --git a/src/test/Variadic.test.ts b/src/test/Variadic.test.ts new file mode 100644 index 0000000..2ded458 --- /dev/null +++ b/src/test/Variadic.test.ts @@ -0,0 +1,38 @@ +// +// Note: This example test is leveraging the Mocha test framework. +// Please refer to their documentation on https://mochajs.org/ for help. +// + +// The module 'assert' provides assertion methods from node +import * as assert from "assert"; + +// You can import and use all API from the 'vscode' module +// as well as import your extension to test it +import * as vscode from "vscode"; +import TestSetup from "./tools/TestSetup"; + +// Defines a Mocha test suite to group tests of similar kind together +suite("Variadic tests", () => { + const testSetup: TestSetup = new TestSetup("void foo();"); + + // Tests + test("", () => { + const result = testSetup.SetLine("").GetResult(); + assert.equal("", result); + }); + + test("", () => { + const result = testSetup.SetLine("").GetResult(); + assert.equal("", result); + }); + + test("", () => { + const result = testSetup.SetLine("").GetResult(); + assert.equal("", result); + }); + + test("", () => { + const result = testSetup.SetLine("").GetResult(); + assert.equal("", result); + }); +}); diff --git a/src/test/functionPointer.test.ts b/src/test/functionPointer.test.ts deleted file mode 100644 index 3b6b857..0000000 --- a/src/test/functionPointer.test.ts +++ /dev/null @@ -1,42 +0,0 @@ -// -// Note: This example test is leveraging the Mocha test framework. -// Please refer to their documentation on https://mochajs.org/ for help. -// - -// The module 'assert' provides assertion methods from node -import * as assert from "assert"; - -// You can import and use all API from the 'vscode' module -// as well as import your extension to test it -import * as vscode from "vscode"; -import TestSetup from "./TestSetup"; - -// Defines a Mocha test suite to group tests of similar kind together -suite("Function pointer tests", () => { - const testSetup: TestSetup = new TestSetup("void foo();"); - - // Tests - test("function pointer return", () => { - const result = testSetup.SetMethod("int (*idputs(int a, int b))(char *);").GetResult(); - assert.equal("/**\n * @brief \n * \n * @param a \n * @param b \n * @return int(*)(char*) \n */", result); - }); - - test("nested function pointer return", () => { - const result = testSetup.SetMethod("int (*(*(*foo(int a, int b))(int))(double))(float);").GetResult(); - assert.equal("/**\n * @brief \n * \n * @param a \n * @param b \n" - + " * @return int(*(*(*)(int))(double))(float) \n */", result); - }); - - test("function pointer parameter", () => { - const result = testSetup.SetMethod("int foo(int (*puts)(const char *));").GetResult(); - assert.equal("/**\n * @brief \n * \n * @param puts \n * @return int \n */", result); - }); - - test("struct function pointer return with struct FP parameter", () => { - const result = testSetup.SetMethod("struct foo (*idputs(int (*puts)(const char *), const" - + " struct test(*str)(int *, const struct test(*str2))))(const char *);").GetResult(); - - assert.equal("/**\n * @brief \n * \n * @param puts \n * @param str " - + "\n * @return struct foo(*)(const char*) \n */", result); - }); -}); diff --git a/src/test/simpleReturn.test.ts b/src/test/simpleReturn.test.ts deleted file mode 100644 index 8f3e5d1..0000000 --- a/src/test/simpleReturn.test.ts +++ /dev/null @@ -1,79 +0,0 @@ -// -// Note: This example test is leveraging the Mocha test framework. -// Please refer to their documentation on https://mochajs.org/ for help. -// - -// The module 'assert' provides assertion methods from node -import * as assert from "assert"; - -// You can import and use all API from the 'vscode' module -// as well as import your extension to test it -import * as vscode from "vscode"; -import TestSetup from "./TestSetup"; - -// Defines a Mocha test suite to group tests of similar kind together -suite("Arguments tests", () => { - - const testSetup: TestSetup = new TestSetup("void foo();"); - - // Tests - test("void return", () => { - const result = testSetup.SetMethod("void foo();").GetResult(); - assert.equal("/**\n * @brief \n * \n */", result); - }); - - test("simple type return", () => { - const result = testSetup.SetMethod("int foo();").GetResult(); - assert.equal("/**\n * @brief \n * \n * @return int \n */", result); - }); - - test("bool return type", () => { - const result = testSetup.SetMethod("bool foo();").GetResult(); - assert.equal("/**\n * @brief \n * \n * @return true \n * @return false \n */", result); - }); - - test("pointer return type", () => { - const result = testSetup.SetMethod("int* foo();").GetResult(); - assert.equal("/**\n * @brief \n * \n * @return int* \n */", result); - }); - - test("bool pointer return type", () => { - const result = testSetup.SetMethod("bool* foo();").GetResult(); - assert.equal("/**\n * @brief \n * \n * @return true \n * @return false \n * @return null \n */", result); - }); - - test("Fundamental return type with modifiers", () => { - let result = testSetup.SetMethod("unsigned int foo();").GetResult(); - assert.equal("/**\n * @brief \n * \n * @return unsigned int \n */", result); - - result = testSetup.SetMethod("unsigned short int foo();").GetResult(); - assert.equal("/**\n * @brief \n * \n * @return unsigned short int \n */", result); - - result = testSetup.SetMethod("signed short foo();").GetResult(); - assert.equal("/**\n * @brief \n * \n * @return signed short \n */", result); - - result = testSetup.SetMethod("long foo();").GetResult(); - assert.equal("/**\n * @brief \n * \n * @return long \n */", result); - - result = testSetup.SetMethod("unsigned long long int foo();").GetResult(); - assert.equal("/**\n * @brief \n * \n * @return unsigned long long int \n */", result); - - result = testSetup.SetMethod("signed foo();").GetResult(); - assert.equal("/**\n * @brief \n * \n * @return signed \n */", result); - - result = testSetup.SetMethod("unsigned foo();").GetResult(); - assert.equal("/**\n * @brief \n * \n * @return unsigned \n */", result); - - result = testSetup.SetMethod("unsigned char foo();").GetResult(); - assert.equal("/**\n * @brief \n * \n * @return unsigned char \n */", result); - - result = testSetup.SetMethod("long double foo();").GetResult(); - assert.equal("/**\n * @brief \n * \n * @return long double \n */", result); - }); - - test("struct return type", () => { - const result = testSetup.SetMethod("struct my_struct foo();").GetResult(); - assert.equal("/**\n * @brief \n * \n * @return struct my_struct \n */", result); - }); - -}); diff --git a/src/test/tools/MockDocument.ts b/src/test/tools/MockDocument.ts new file mode 100644 index 0000000..cb6bbfe --- /dev/null +++ b/src/test/tools/MockDocument.ts @@ -0,0 +1,52 @@ +import * as vscode from "vscode"; +import MockLine from "./MockLine"; + +export default class MockDocument implements vscode.TextDocument { + public uri: vscode.Uri; + public fileName: string; + public isUntitled: boolean; + public languageId: string; + public version: number; + public isDirty: boolean; + public isClosed: boolean; + public eol: vscode.EndOfLine; + public lineCount: number; + private line: vscode.TextLine; + private callCount: number; + public constructor(line: vscode.TextLine) { + this.line = line; + this.callCount = 0; + } + public save(): Thenable { + throw new Error("Method not implemented."); + } + public lineAt(line: number | vscode.Position): vscode.TextLine; + public lineAt(position: any): any { + if (++this.callCount === 1) { + return new MockLine(""); + } else if (this.callCount === 2) { + return this.line; + } else { + return new MockLine(";"); + } + } + public offsetAt(position: vscode.Position): number { + throw new Error("Method not implemented."); + } + public positionAt(offset: number): vscode.Position { + throw new Error("Method not implemented."); + } + public getText(range?: vscode.Range): string { + throw new Error("Method not implemented."); + } + public getWordRangeAtPosition(position: vscode.Position, regex?: RegExp): vscode.Range { + throw new Error("Method not implemented."); + } + public validateRange(range: vscode.Range): vscode.Range { + throw new Error("Method not implemented."); + } + public validatePosition(position: vscode.Position): vscode.Position { + throw new Error("Method not implemented."); + } + +} diff --git a/src/test/tools/MockEditor.ts b/src/test/tools/MockEditor.ts new file mode 100644 index 0000000..5368fb8 --- /dev/null +++ b/src/test/tools/MockEditor.ts @@ -0,0 +1,43 @@ +import * as vscode from "vscode"; +import { TextEditor } from "vscode"; +import MockDocument from "./MockDocument"; +import MockSelection from "./MockSelection"; +import MockTextEditorEdit from "./MockTextEditorEdit"; + +export default class MockEditor implements TextEditor { + public document: vscode.TextDocument; + public selection: vscode.Selection; + public selections: vscode.Selection[]; + public options: vscode.TextEditorOptions; + public viewColumn?: vscode.ViewColumn; + public editBuilder: MockTextEditorEdit; + public constructor(s: MockSelection, d: MockDocument) { + this.selection = s; + this.document = d; + this.editBuilder = new MockTextEditorEdit(); + } + + public edit(callback: (editBuilder: vscode.TextEditorEdit) => void, + options?: { undoStopBefore: boolean; undoStopAfter: boolean; }): Thenable { + callback(this.editBuilder); + return Promise.resolve(true); + } + public insertSnippet(snippet: vscode.SnippetString, + location?: vscode.Position | vscode.Range | vscode.Position[] | vscode.Range[], + options?: { undoStopBefore: boolean; undoStopAfter: boolean; }): Thenable { + throw new Error("Method not implemented."); + } + public setDecorations(decorationType: vscode.TextEditorDecorationType, + rangesOrOptions: vscode.Range[] | vscode.DecorationOptions[]): void { + throw new Error("Method not implemented."); + } + public revealRange(range: vscode.Range, revealType?: vscode.TextEditorRevealType): void { + throw new Error("Method not implemented."); + } + public show(column?: vscode.ViewColumn): void { + throw new Error("Method not implemented."); + } + public hide(): void { + throw new Error("Method not implemented."); + } +} diff --git a/src/test/tools/MockLine.ts b/src/test/tools/MockLine.ts new file mode 100644 index 0000000..7196a38 --- /dev/null +++ b/src/test/tools/MockLine.ts @@ -0,0 +1,13 @@ +import * as vscode from "vscode"; + +export default class MockLine implements vscode.TextLine { + public lineNumber: number; + public text: string; + public range: vscode.Range; + public rangeIncludingLineBreak: vscode.Range; + public firstNonWhitespaceCharacterIndex: number; + public isEmptyOrWhitespace: boolean; + public constructor(text: string) { + this.text = text; + } +} diff --git a/src/test/tools/MockPosition.ts b/src/test/tools/MockPosition.ts new file mode 100644 index 0000000..0753670 --- /dev/null +++ b/src/test/tools/MockPosition.ts @@ -0,0 +1,39 @@ +import * as vscode from "vscode"; + +export default class MockPosition implements vscode.Position { + public line: number; + public character: number; + public constructor(l: number, c: number) { + this.line = l; + this.character = c; + } + public isBefore(other: vscode.Position): boolean { + throw new Error("Method not implemented."); + } + public isBeforeOrEqual(other: vscode.Position): boolean { + throw new Error("Method not implemented."); + } + public isAfter(other: vscode.Position): boolean { + throw new Error("Method not implemented."); + } + public isAfterOrEqual(other: vscode.Position): boolean { + throw new Error("Method not implemented."); + } + public isEqual(other: vscode.Position): boolean { + throw new Error("Method not implemented."); + } + public compareTo(other: vscode.Position): number { + throw new Error("Method not implemented."); + } + public translate(lineDelta?: number, characterDelta?: number): vscode.Position; + public translate(change: { lineDelta?: number; characterDelta?: number; }): vscode.Position; + public translate(lineDelta?: any, characterDelta?: any): any { + throw new Error("Method not implemented."); + } + public with(line?: number, character?: number): vscode.Position; + public with(change: { line?: number; character?: number; }): vscode.Position; + public with(line?: any, character?: any): any { + throw new Error("Method not implemented."); + } + +} diff --git a/src/test/tools/MockSelection.ts b/src/test/tools/MockSelection.ts new file mode 100644 index 0000000..e72ff8b --- /dev/null +++ b/src/test/tools/MockSelection.ts @@ -0,0 +1,35 @@ +import * as vscode from "vscode"; +import MockPosition from "./MockPosition"; + +export default class MockSelection implements vscode.Selection { + public anchor: vscode.Position; + public active: vscode.Position; + public isReversed: boolean; + public start: vscode.Position; + public end: vscode.Position; + public isEmpty: boolean; + public isSingleLine: boolean; + + public constructor(a: MockPosition) { + this.active = a; + this.start = a; + } + + public contains(positionOrRange: vscode.Range | vscode.Position): boolean { + throw new Error("Method not implemented."); + } + public isEqual(other: vscode.Range): boolean { + throw new Error("Method not implemented."); + } + public intersection(range: vscode.Range): vscode.Range { + throw new Error("Method not implemented."); + } + public union(other: vscode.Range): vscode.Range { + throw new Error("Method not implemented."); + } + public with(start?: vscode.Position, end?: vscode.Position): vscode.Range; + public with(change: { start?: vscode.Position; end?: vscode.Position; }): vscode.Range; + public with(start?: any, end?: any): any { + throw new Error("Method not implemented."); + } +} diff --git a/src/test/tools/MockTextEditorEdit.ts b/src/test/tools/MockTextEditorEdit.ts new file mode 100644 index 0000000..e751182 --- /dev/null +++ b/src/test/tools/MockTextEditorEdit.ts @@ -0,0 +1,18 @@ +import * as vscode from "vscode"; + +export default class MockTextEditorEdit implements vscode.TextEditorEdit { + public text: string; + public replace(location: vscode.Position | vscode.Range | vscode.Selection, value: string): void { + this.text = value; + } + public insert(location: vscode.Position, value: string): void { + throw new Error("Method not implemented."); + } + public delete(location: vscode.Range | vscode.Selection): void { + throw new Error("Method not implemented."); + } + public setEndOfLine(endOfLine: vscode.EndOfLine): void { + throw new Error("Method not implemented."); + } + +} diff --git a/src/test/tools/TestSetup.ts b/src/test/tools/TestSetup.ts new file mode 100644 index 0000000..1270616 --- /dev/null +++ b/src/test/tools/TestSetup.ts @@ -0,0 +1,46 @@ +import * as vscode from "vscode"; +import CodeParser from "../../CodeParser/CodeParser"; +import CParser from "../../CodeParser/CParser/CParser"; +import { IDocGen } from "../../DocGen/DocGen"; +import * as myExtension from "../../extension"; +import MockDocument from "./MockDocument"; +import MockEditor from "./MockEditor"; +import MockLine from "./MockLine"; +import MockPosition from "./MockPosition"; +import MockSelection from "./MockSelection"; + +export default class TestSetup { + private editor: MockEditor; + + constructor(method: string) { + this.SetLine(method); + } + + public SetLine(method: string): TestSetup { + let position: MockPosition; + position = new MockPosition(0, 0); + + let selection: MockSelection; + selection = new MockSelection(position); + + let line: MockLine; + line = new MockLine(method); + + let doc: MockDocument; + doc = new MockDocument(line); + + this.editor = new MockEditor(selection, doc); + + return this; + } + + public GetResult(): string { + let parser: CodeParser; + parser = new CParser(); + + const gen: IDocGen = parser.Parse(this.editor); + gen.GenerateDoc(new vscode.Range(new vscode.Position(0, 0), new vscode.Position(0, 0))); + + return this.editor.editBuilder.text; + } +} -- cgit v1.2.3