diff --git a/.deepsource.toml b/.deepsource.toml index e8c615c..f429023 100644 --- a/.deepsource.toml +++ b/.deepsource.toml @@ -2,4 +2,8 @@ version = 1 [[analyzers]] name = "javascript" +enabled = true + +[[analyzers]] +name = "test-coverage" enabled = true \ No newline at end of file diff --git a/.dependency-cruiser.js b/.dependency-cruiser.js index 8efdafe..98fd858 100644 --- a/.dependency-cruiser.js +++ b/.dependency-cruiser.js @@ -45,19 +45,19 @@ module.exports = { 'core' ], path: [ - '^(v8\/tools\/codemap)$', - '^(v8\/tools\/consarray)$', - '^(v8\/tools\/csvparser)$', - '^(v8\/tools\/logreader)$', - '^(v8\/tools\/profile_view)$', - '^(v8\/tools\/profile)$', - '^(v8\/tools\/SourceMap)$', - '^(v8\/tools\/splaytree)$', - '^(v8\/tools\/tickprocessor-driver)$', - '^(v8\/tools\/tickprocessor)$', - '^(node-inspect\/lib\/_inspect)$', - '^(node-inspect\/lib\/internal\/inspect_client)$', - '^(node-inspect\/lib\/internal\/inspect_repl)$', + '^(v8/tools/codemap)$', + '^(v8/tools/consarray)$', + '^(v8/tools/csvparser)$', + '^(v8/tools/logreader)$', + '^(v8/tools/profile_view)$', + '^(v8/tools/profile)$', + '^(v8/tools/SourceMap)$', + '^(v8/tools/splaytree)$', + '^(v8/tools/tickprocessor-driver)$', + '^(v8/tools/tickprocessor)$', + '^(node-inspect/lib/_inspect)$', + '^(node-inspect/lib/internal/inspect_client)$', + '^(node-inspect/lib/internal/inspect_repl)$', '^(async_hooks)$', '^(punycode)$', '^(domain)$', diff --git a/.github/workflows/action.yml b/.github/workflows/action.yml index 06f9425..d8b3d63 100644 --- a/.github/workflows/action.yml +++ b/.github/workflows/action.yml @@ -10,25 +10,40 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - name: Use Node.js + - name: Checkout code + uses: actions/checkout@v3 + + - name: Setup Node.js uses: actions/setup-node@v3 with: node-version: 16 + - name: install run: | npm install npm install -g yarn npm install -g vsce + - name: lint run: npm run lint + - name: static code analysis run: npm run code-analysis + - name: test uses: GabrielBB/xvfb-action@v1 with: run: npm run coverage - - name: coverage + + - name: Report test coverage to Coveralls uses: coverallsapp/github-action@master with: github-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Report test coverage to DeepSource + uses: deepsourcelabs/test-coverage-action@master + with: + key: javascript + coverage-file: coverage/lcov.info + dsn: ${{ secrets.DEEPSOURCE_DSN }} + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ec8e9ea..c715a06 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -13,7 +13,9 @@ The following commands support you at developing good code: * `npm run test`: Run the tests * `npm run lint`: Run the linter -### SonarQube +### Static code analysis +#### SonarQube +##### Local * `docker-compose up -d`: Start the sonarqube container. This will take some time. * `docker-compose stop`: Stop the container * `docker-compose down`: Remove the container @@ -22,6 +24,12 @@ SonarQube will be reachable on `http://localhost:9000`. * `npm run sonar`: Start sonarscanner and upload result to local container +##### SonarCloud +Find analysis on [sonarcloud.io](https://sonarcloud.io/project/overview?id=pascalre_vscode-yaml-sort) + +#### DeepSource +Find analysis on [deepsource.io](https://deepsource.io/gh/pascalre/vscode-yaml-sort) + ### Commit changes Refer to [this blogpost](https://cbea.ms/git-commit/#end) by cbeams when committing changes. Issue numbers can be added in braces to the end of the commit message. diff --git a/src/adapter/js-yaml-adapter.ts b/src/adapter/js-yaml-adapter.ts index d28c51d..1b66df8 100644 --- a/src/adapter/js-yaml-adapter.ts +++ b/src/adapter/js-yaml-adapter.ts @@ -1,5 +1,5 @@ import { Settings } from "../settings" -import * as jsyaml from "js-yaml" +import { load, dump } from "js-yaml" import { SortUtil } from "../util/sort-util" import { removeTrailingCharacters, splitYaml } from "../util/yaml-util" @@ -15,7 +15,7 @@ export class JsYamlAdapter { } load(text: string) { - return jsyaml.load(text, this.getLoadOptions()) + return load(text, this.getLoadOptions()) } /** @@ -25,7 +25,7 @@ export class JsYamlAdapter { */ validateYaml(text: string): boolean { splitYaml(text).forEach((yaml) => { - jsyaml.load(yaml, { schema: this.settings.getSchema() }) + load(yaml, { schema: this.settings.getSchema() }) }) return true } @@ -37,23 +37,23 @@ export class JsYamlAdapter { * @param {boolean} sortKeys If set to true, the function will sort the keys in the document. Defaults to true. * @returns {string} Clean yaml document. */ - dumpYaml(text: string, sortKeys: boolean, custom: number, settings: Settings): string { + dumpYaml(text: string, sortKeys: boolean, custom: number): string { if (Object.keys(text).length === 0) { return "" } - const sort = new SortUtil(settings, custom) + const sort = new SortUtil(this.settings, custom) - let yaml = jsyaml.dump(text, { - indent: settings.getIndent(), - forceQuotes: settings.getForceQuotes(), - lineWidth: settings.getLineWidth(), - noArrayIndent: settings.getNoArrayIndent(), - noCompatMode: settings.getNoCompatMode(), - quotingType: settings.getQuotingType(), - schema: settings.getSchema(), - sortKeys: (!(custom > 0 && settings.getUseCustomSortRecursively()) ? sortKeys : (a: string, b: string) => { + let yaml = dump(text, { + indent: this.settings.getIndent(), + forceQuotes: this.settings.getForceQuotes(), + lineWidth: this.settings.getLineWidth(), + noArrayIndent: this.settings.getNoArrayIndent(), + noCompatMode: this.settings.getNoCompatMode(), + quotingType: this.settings.getQuotingType(), + schema: this.settings.getSchema(), + sortKeys: (!(custom > 0 && this.settings.getUseCustomSortRecursively()) ? sortKeys : (a: string, b: string) => { return sort.customSort(a, b) }) }) diff --git a/src/adapter/vs-code-adapter.ts b/src/adapter/vs-code-adapter.ts index 641cd4a..047908b 100644 --- a/src/adapter/vs-code-adapter.ts +++ b/src/adapter/vs-code-adapter.ts @@ -1,4 +1,4 @@ -import * as vscode from "vscode" +import { workspace, TextEditor, Range, Position, Selection, TextEdit, WorkspaceEdit, window, DocumentFormattingEditProvider, languages, Disposable } from "vscode" import { Settings } from "../settings" export enum Severity { @@ -14,20 +14,42 @@ export class VsCodeAdapter { } getProperty(property: string) { - return vscode.workspace.getConfiguration().get(`${this.section}.${property}`) + return workspace.getConfiguration().get(`${this.section}.${property}`) } - getActiveDocument(textEditor: vscode.TextEditor) { - return textEditor.document.getText() + // have a function that adds/removes the formatter based + // on a configuration setting + registerFormatter(formatter: DocumentFormattingEditProvider) { + let registration: Disposable | undefined + const useAsFormatter = this.settings.getUseAsFormatter() + if (useAsFormatter && !registration) { + languages.registerDocumentFormattingEditProvider('yaml', formatter) + } else if (!useAsFormatter && registration) { + registration.dispose() + } + } + + showMessage(severity: Severity, message: string) { + if (severity === Severity.ERROR) { + window.showErrorMessage(message) + } else { + if (this.settings.getNotifySuccess()) { + window.showInformationMessage(message) + } + } + } + + static getText(textEditor: TextEditor, range: Range) { + return textEditor.document.getText(range) } - getFullDocumentRange(textEditor: vscode.TextEditor) { - return new vscode.Range( - new vscode.Position(0, 0), - new vscode.Position(textEditor.document.lineCount + 1, 0)) + static getFullDocumentRange(textEditor: TextEditor) { + return new Range( + new Position(0, 0), + new Position(textEditor.document.lineCount + 1, 0)) } - getSelectedRange(textEditor: vscode.TextEditor) { + static getSelectedRange(textEditor: TextEditor) { let endLine = textEditor.selection.end.line // if selection ends on the first character on a new line ignore this line if (textEditor.selection.end.character === 0) { @@ -35,64 +57,40 @@ export class VsCodeAdapter { } // ensure selection covers whole start and end line - return new vscode.Selection( + return new Selection( textEditor.selection.start.line, 0, endLine, textEditor.document.lineAt(endLine).range.end.character) } - getRange(textEditor: vscode.TextEditor) { - if (textEditor.selection.isEmpty) { - return this.getFullDocumentRange(textEditor) - } else { - return this.getSelectedRange(textEditor) - } - } - - getText(textEditor: vscode.TextEditor, range: vscode.Range) { - return textEditor.document.getText(range) - } - - getEdits(textEditor: vscode.TextEditor, text: string) { - const range = this.getRange(textEditor) - return vscode.TextEdit.replace(range, text) - } - /** * Applys edits to a text editor * @param activeEditor Editor to apply the changes * @param edits Changes to apply */ - applyEdits(edit: [vscode.TextEdit]) { - if (vscode.window.activeTextEditor) { - const workspaceEdit = new vscode.WorkspaceEdit() - workspaceEdit.set(vscode.window.activeTextEditor.document.uri, edit) - vscode.workspace.applyEdit(workspaceEdit) + static applyEdits(edit: [TextEdit]) { + if (window.activeTextEditor) { + const workspaceEdit = new WorkspaceEdit() + workspaceEdit.set(window.activeTextEditor.document.uri, edit) + workspace.applyEdit(workspaceEdit) } } - // have a function that adds/removes the formatter based - // on a configuration setting - registerFormatter(formatter: vscode.DocumentFormattingEditProvider) { - let registration: vscode.Disposable | undefined - const useAsFormatter = this.settings.getUseAsFormatter() - if (useAsFormatter && !registration) { - vscode.languages.registerDocumentFormattingEditProvider('yaml', formatter) - } else if (!useAsFormatter && registration) { - registration.dispose() - } + static getActiveDocument(textEditor: TextEditor) { + return textEditor.document.getText() } - showMessage(severity: Severity, message: string) { - switch(severity) { - case Severity.ERROR : - vscode.window.showErrorMessage(message) - break - case Severity.INFO : - if (this.settings.getNotifySuccess()) { - vscode.window.showInformationMessage(message) - } - break + static getRange(textEditor: TextEditor) { + if (textEditor.selection.isEmpty) { + return VsCodeAdapter.getFullDocumentRange(textEditor) + } else { + return VsCodeAdapter.getSelectedRange(textEditor) } } + + static getEdits(textEditor: TextEditor, text: string) { + const range = VsCodeAdapter.getRange(textEditor) + return TextEdit.replace(range, text) + } + } diff --git a/src/controller.ts b/src/controller.ts index f2f76ed..d503232 100644 --- a/src/controller.ts +++ b/src/controller.ts @@ -1,5 +1,5 @@ -import * as vscode from "vscode" -import * as fs from "fs" +import { TextEdit, Uri, window } from "vscode" +import { readFileSync, writeFileSync } from "fs" import { JsYamlAdapter } from "./adapter/js-yaml-adapter" import { Severity, VsCodeAdapter } from "./adapter/vs-code-adapter" import { prependWhitespacesOnEachLine, removeLeadingLineBreakOfFirstElement } from "./lib" @@ -12,12 +12,12 @@ const jsyamladapter = new JsYamlAdapter() const vscodeadapter = new VsCodeAdapter() const yamlutil = new YamlUtil() -export function sortYamlWrapper(customSort = 0): vscode.TextEdit[] { - const activeEditor = vscode.window.activeTextEditor +export function sortYamlWrapper(customSort = 0): TextEdit[] { + const activeEditor = window.activeTextEditor if (activeEditor) { - const textRange = vscodeadapter.getRange(activeEditor) - let text = vscodeadapter.getText(activeEditor, textRange) + const textRange = VsCodeAdapter.getRange(activeEditor) + let text = VsCodeAdapter.getText(activeEditor, textRange) try { validateTextRange(text) @@ -26,7 +26,7 @@ export function sortYamlWrapper(customSort = 0): vscode.TextEdit[] { if (e instanceof Error) { vscodeadapter.showMessage(Severity.ERROR, e.message) } - return [] + return [] as TextEdit[] } let numberOfLeadingSpaces = 0 @@ -35,8 +35,7 @@ export function sortYamlWrapper(customSort = 0): vscode.TextEdit[] { // remove yaml metadata tags const matchMetadata = /^%.*\n/gm // set metadata tags, if there is no metadata tag it should be an emtpy array - let newText = "" - if (text.match(matchMetadata)) { + if (matchMetadata.test(text)) { delimiters.shift() delimiters = removeLeadingLineBreakOfFirstElement(delimiters) } @@ -44,40 +43,37 @@ export function sortYamlWrapper(customSort = 0): vscode.TextEdit[] { text = text.replace(/^\n/, "") // sort yaml + let newText = "" splitYaml(text).forEach((unsortedYaml) => { let sortedYaml = yamlutil.sortYaml(unsortedYaml, customSort) if (sortedYaml) { if (!activeEditor.selection.isEmpty) { // get number of leading whitespaces, these whitespaces will be used for indentation - if (!unsortedYaml.startsWith(" ")) { - numberOfLeadingSpaces = 0 - } else { - numberOfLeadingSpaces = unsortedYaml.search(/\S/) - } + numberOfLeadingSpaces = YamlUtil.getNumberOfLeadingSpaces(unsortedYaml) sortedYaml = prependWhitespacesOnEachLine(sortedYaml, numberOfLeadingSpaces) } newText += delimiters.shift() + sortedYaml } else { - return [] + return [] as TextEdit[] } }) if (activeEditor.selection.isEmpty && settings.getUseLeadingDashes()) { - newText = "---\n" + newText + newText = `---\n${newText}` } - const edits = vscodeadapter.getEdits(activeEditor, newText) + const edits = VsCodeAdapter.getEdits(activeEditor, newText) vscodeadapter.showMessage(Severity.INFO, "Keys resorted successfully") - vscodeadapter.applyEdits([edits]) + VsCodeAdapter.applyEdits([edits]) return [edits] } - return [] + return [] as TextEdit[] } export function validateYamlWrapper(): boolean { - const activeEditor = vscode.window.activeTextEditor + const activeEditor = window.activeTextEditor if (activeEditor) { - const text = vscodeadapter.getActiveDocument(activeEditor) + const text = VsCodeAdapter.getActiveDocument(activeEditor) try { jsyamladapter.validateYaml(text) vscodeadapter.showMessage(Severity.INFO, "YAML is valid.") @@ -91,8 +87,8 @@ export function validateYamlWrapper(): boolean { return false } -export function formatYamlWrapper(): vscode.TextEdit[] { - const activeEditor = vscode.window.activeTextEditor +export function formatYamlWrapper(): TextEdit[] { + const activeEditor = window.activeTextEditor if (activeEditor) { let doc = activeEditor.document.getText() @@ -100,7 +96,7 @@ export function formatYamlWrapper(): vscode.TextEdit[] { // remove yaml metadata tags const matchMetadata = /^%.*\n/gm // set metadata tags, if there is no metadata tag it should be an emtpy array - if (doc.match(matchMetadata)) { + if (matchMetadata.test(doc)) { delimiters.shift() delimiters = removeLeadingLineBreakOfFirstElement(delimiters) } @@ -119,10 +115,10 @@ export function formatYamlWrapper(): vscode.TextEdit[] { } } if (settings.getUseLeadingDashes()) { - newText = "---\n" + newText + newText = `---\n${newText}` } - const edits = vscodeadapter.getEdits(activeEditor, newText) - vscodeadapter.applyEdits([edits]) + const edits = VsCodeAdapter.getEdits(activeEditor, newText) + VsCodeAdapter.applyEdits([edits]) return [edits] } return [] @@ -130,17 +126,17 @@ export function formatYamlWrapper(): vscode.TextEdit[] { /** * Sorts all yaml files in a directory - * @param {vscode.Uri} uri Base URI + * @param {Uri} uri Base URI */ -export function sortYamlFiles(uri: vscode.Uri): boolean { +export function sortYamlFiles(uri: Uri): boolean { const files = new FileUtil().getFilesWithExtensions(uri.fsPath) files.forEach((file: string) => { - const yaml = fs.readFileSync(file, 'utf-8').toString() + const yaml = readFileSync(file, 'utf-8').toString() const sortedYaml = yamlutil.sortYaml(yaml, 0) if (sortedYaml) { try { - fs.writeFileSync(file, sortedYaml) + writeFileSync(file, sortedYaml) } catch (e) { /* istanbul ignore next */ vscodeadapter.showMessage(Severity.ERROR, `File ${file} could not be sorted`) diff --git a/src/lib.ts b/src/lib.ts index ba13dd4..02ecfb2 100644 --- a/src/lib.ts +++ b/src/lib.ts @@ -64,12 +64,12 @@ export function addNewLineBeforeKeywordsUpToLevelN(n: number, indent: number, te let result = text; while (level < n) { - if (level == 0) { + if (level === 0) { result = result.replace(/\n[^\s].*:/g, "\n$&") } else { let spaces = " ".repeat(indent) spaces = spaces.repeat(level) - const regex = new RegExp("\n" + spaces + "[\\w-]*:", "g") + const regex = new RegExp(`\n${spaces}[\\w-]*:`, "g") result = result.replace(regex, "\n$&") } level++; diff --git a/src/settings.ts b/src/settings.ts index 6c63517..367445d 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -1,4 +1,4 @@ -import * as jsyaml from "js-yaml" +import { Schema, CORE_SCHEMA, FAILSAFE_SCHEMA, JSON_SCHEMA, DEFAULT_SCHEMA } from "js-yaml" import { workspace } from "vscode" import { CLOUDFORMATION_SCHEMA } from "cloudformation-js-yaml-schema" import { HOMEASSISTANT_SCHEMA } from "homeassistant-js-yaml-schema" @@ -23,22 +23,6 @@ export class Settings { getIndent(): number { return this.workspace.getConfiguration().get("vscode-yaml-sort.indent") as number } - getJsYamlSchemaFromString(schema: string): jsyaml.Schema { - switch (schema) { - case "HOMEASSISTANT_SCHEMA": - return HOMEASSISTANT_SCHEMA as jsyaml.Schema - case "CLOUDFORMATION_SCHEMA": - return CLOUDFORMATION_SCHEMA as jsyaml.Schema - case "CORE_SCHEMA": - return jsyaml.CORE_SCHEMA - case "FAILSAFE_SCHEMA": - return jsyaml.FAILSAFE_SCHEMA - case "JSON_SCHEMA": - return jsyaml.JSON_SCHEMA - default: - return jsyaml.DEFAULT_SCHEMA - } - } getLineWidth(): number { return this.workspace.getConfiguration().get("vscode-yaml-sort.lineWidth") as number } @@ -57,9 +41,9 @@ export class Settings { getQuotingType(): "'" | "\"" { return this.workspace.getConfiguration().get("vscode-yaml-sort.quotingType") as "'" | "\"" } - getSchema(): jsyaml.Schema { + getSchema(): Schema { const schema = this.workspace.getConfiguration().get("vscode-yaml-sort.schema") as string - return this.getJsYamlSchemaFromString(schema) + return Settings.getJsYamlSchemaFromString(schema) } getSortOnSave(): number { return this.workspace.getConfiguration().get('vscode-yaml-sort.sortOnSave') as number @@ -91,4 +75,21 @@ export class Settings { useAsFormatter = this.getUseAsFormatter() useCustomSortRecursively = this.getUseCustomSortRecursively() useLeadingDashes = this.getUseLeadingDashes() + + static getJsYamlSchemaFromString(schema: string): Schema { + switch (schema) { + case "HOMEASSISTANT_SCHEMA": + return HOMEASSISTANT_SCHEMA as Schema + case "CLOUDFORMATION_SCHEMA": + return CLOUDFORMATION_SCHEMA as Schema + case "CORE_SCHEMA": + return CORE_SCHEMA + case "FAILSAFE_SCHEMA": + return FAILSAFE_SCHEMA + case "JSON_SCHEMA": + return JSON_SCHEMA + default: + return DEFAULT_SCHEMA + } + } } diff --git a/src/test/runTest.ts b/src/test/runTest.ts index 494ecbe..70fa4d4 100644 --- a/src/test/runTest.ts +++ b/src/test/runTest.ts @@ -1,16 +1,15 @@ -import * as path from 'path' - -import { runTests } from '@vscode/test-electron' +import { resolve } from "path" +import { runTests } from "@vscode/test-electron" async function main() { try { // The folder containing the Extension Manifest package.json // Passed to `--extensionDevelopmentPath` - const extensionDevelopmentPath = path.resolve(__dirname, '../../'); + const extensionDevelopmentPath = resolve(__dirname, '../../'); // The path to test runner // Passed to --extensionTestsPath - const extensionTestsPath = path.resolve(__dirname, './suite/index'); + const extensionTestsPath = resolve(__dirname, './suite/index'); // Download VS Code, unzip it and run the integration test await runTests({ extensionDevelopmentPath, extensionTestsPath }); diff --git a/src/test/suite/adapter/js-yaml-adapter.test.ts b/src/test/suite/adapter/js-yaml-adapter.test.ts index ca538ea..8973315 100644 --- a/src/test/suite/adapter/js-yaml-adapter.test.ts +++ b/src/test/suite/adapter/js-yaml-adapter.test.ts @@ -1,4 +1,4 @@ -import * as assert from "assert" +import { strictEqual, throws } from "assert" import { CLOUDFORMATION_SCHEMA } from "cloudformation-js-yaml-schema" import { HOMEASSISTANT_SCHEMA } from "homeassistant-js-yaml-schema" import jsyaml = require("js-yaml") @@ -18,7 +18,7 @@ suite("Test JsYamlAdapter - validateYaml()", () => { ' kitty:\n' + ' age: 3' - assert.strictEqual(jsyamladapter.validateYaml(actual), true) + strictEqual(jsyamladapter.validateYaml(actual), true) }) test("when text are two seperated valid yaml documents should return true", () => { @@ -32,13 +32,13 @@ suite("Test JsYamlAdapter - validateYaml()", () => { ' kitty:\n' + ' age: 3' - assert.strictEqual(jsyamladapter.validateYaml(actual), true) + strictEqual(jsyamladapter.validateYaml(actual), true) }) test("when text is an invalid yaml document should throw YAMLException", () => { const actual = "network: ethernets:" - assert.throws(() => jsyamladapter.validateYaml(actual), jsyaml.YAMLException) + throws(() => jsyamladapter.validateYaml(actual), jsyaml.YAMLException) }) test("when indentation is not correct should throw YAMLException", () => { const actual = @@ -46,7 +46,7 @@ suite("Test JsYamlAdapter - validateYaml()", () => { "bob\n" + " age:23" - assert.throws(() => jsyamladapter.validateYaml(actual), jsyaml.YAMLException) + throws(() => jsyamladapter.validateYaml(actual), jsyaml.YAMLException) }) test("when text contains duplicate key should throw YAMLException", () => { const actual = @@ -56,7 +56,7 @@ suite("Test JsYamlAdapter - validateYaml()", () => { " bob:\n" + " age: 25" - assert.throws(() => jsyamladapter.validateYaml(actual), jsyaml.YAMLException) + throws(() => jsyamladapter.validateYaml(actual), jsyaml.YAMLException) }) test("when text is a yaml document using CLOUDFORMATION_SCHEMA and schema is CORE_SCHEMA should throw YAMLException", () => { const actual = "RoleName: !Sub \"AdministratorAccess\"" @@ -64,7 +64,7 @@ suite("Test JsYamlAdapter - validateYaml()", () => { return jsyaml.CORE_SCHEMA } - assert.throws(() => jsyamladapter.validateYaml(actual), jsyaml.YAMLException) + throws(() => jsyamladapter.validateYaml(actual), jsyaml.YAMLException) }) test("when text is a yaml document using CLOUDFORMATION_SCHEMA and schema is CLOUDFORMATION_SCHEMA should return true", () => { const actual = "RoleName: !Sub \"AdministratorAccess\"" @@ -72,7 +72,7 @@ suite("Test JsYamlAdapter - validateYaml()", () => { return CLOUDFORMATION_SCHEMA } - assert.strictEqual(jsyamladapter.validateYaml(actual), true) + strictEqual(jsyamladapter.validateYaml(actual), true) }) test("when text is a yaml document using HOMEASSISTANT_SCHEMA and schema is CORE_SCHEMA should throw YAMLException", () => { const actual = "password: !env_var PASSWORD default_password" @@ -80,7 +80,7 @@ suite("Test JsYamlAdapter - validateYaml()", () => { return jsyaml.CORE_SCHEMA } - assert.throws(() => jsyamladapter.validateYaml(actual), jsyaml.YAMLException) + throws(() => jsyamladapter.validateYaml(actual), jsyaml.YAMLException) }) test("when text is a yaml document using HOMEASSISTANT_SCHEMA and schema is HOMEASSISTANT_SCHEMA should return true", () => { const actual = "password: !env_var PASSWORD default_password" @@ -88,7 +88,7 @@ suite("Test JsYamlAdapter - validateYaml()", () => { return HOMEASSISTANT_SCHEMA } - assert.strictEqual(jsyamladapter.validateYaml(actual), true) + strictEqual(jsyamladapter.validateYaml(actual), true) }) }) diff --git a/src/test/suite/adapter/vs-code-adapter.test.ts b/src/test/suite/adapter/vs-code-adapter.test.ts index 44ef08f..60b2455 100644 --- a/src/test/suite/adapter/vs-code-adapter.test.ts +++ b/src/test/suite/adapter/vs-code-adapter.test.ts @@ -1,44 +1,44 @@ -import * as assert from "assert" +import { strictEqual, fail } from "assert" import path = require("path") -import * as vscode from "vscode" +import { Uri, workspace, window } from "vscode" import { VsCodeAdapter } from "../../../adapter/vs-code-adapter" suite("Test VsCodeAdapter - getProperty()", () => { const vscodeadapter = new VsCodeAdapter() test("when property is locale should return en", () => { - assert.strictEqual(vscodeadapter.getProperty("locale"), "en") + strictEqual(vscodeadapter.getProperty("locale"), "en") }) }) /* suite("Test VsCodeAdapter - applyEdits()", () => { const vscodeadapter = new VsCodeAdapter() - const textEditor = vscode.window.activeTextEditor + const textEditor = window.activeTextEditor if (textEditor) { const edits = vscodeadapter.getEdits(textEditor, 'foobar') - vscode.window.activeTextEditor = undefined - assert.throws(() => vscodeadapter.applyEdits([edits])) + window.activeTextEditor = undefined + throws(() => vscodeadapter.applyEdits([edits])) test("when property is locale should return en", () => { - assert.strictEqual(vscodeadapter.getProperty("locale"), "en") + strictEqual(vscodeadapter.getProperty("locale"), "en") }) } })*/ suite("Test VsCodeAdapter - getActiveDocument()", () => { test("when text editor is active should open document", async () => { - const uri = vscode.Uri.parse(path.resolve("./src/test/files/getYamlFilesInDirectory/file.yaml")) - const doc = await vscode.workspace.openTextDocument(uri) - await vscode.window.showTextDocument(doc, { preview: false }) + const uri = Uri.parse(path.resolve("./src/test/files/getYamlFilesInDirectory/file.yaml")) + const doc = await workspace.openTextDocument(uri) + await window.showTextDocument(doc, { preview: false }) - if (vscode.window.activeTextEditor) { + if (window.activeTextEditor) { const expected = 'key:\n' + ' key2: value' - assert.strictEqual(new VsCodeAdapter().getActiveDocument(vscode.window.activeTextEditor), expected) + strictEqual(VsCodeAdapter.getActiveDocument(window.activeTextEditor), expected) } else { - assert.fail("vscode.window.activeTextEditor is not set") + fail("window.activeTextEditor is not set") } }) }) \ No newline at end of file diff --git a/src/test/suite/controller.test.ts b/src/test/suite/controller.test.ts index 9009a0b..cfafd4c 100644 --- a/src/test/suite/controller.test.ts +++ b/src/test/suite/controller.test.ts @@ -1,62 +1,62 @@ -import * as vscode from "vscode" -import * as assert from "assert" -import * as path from "path" -import * as fs from "fs" +import { Uri, commands, window, workspace } from "vscode" +import { strictEqual } from "assert" +import { resolve } from "path" +import { readFileSync, writeFileSync } from "fs" import { formatYamlWrapper, sortYamlFiles, validateYamlWrapper } from "../../controller" suite("Test sortYamlFiles", () => { test("should sort all yaml files in directory", async () => { - const uri = vscode.Uri.parse(path.resolve("./src/test/files/getYamlFilesInDirectory/folder1")) + const uri = Uri.parse(resolve("./src/test/files/getYamlFilesInDirectory/folder1")) - await vscode.commands.executeCommand("vscode-yaml-sort.sortYamlFilesInDirectory", uri) + await commands.executeCommand("vscode-yaml-sort.sortYamlFilesInDirectory", uri) - let sortedFile = fs.readFileSync("./src/test/files/getYamlFilesInDirectory/folder1/file.yaml", 'utf-8').toString() - assert.strictEqual(sortedFile, "akey: value\nkey: value") - sortedFile = fs.readFileSync("./src/test/files/getYamlFilesInDirectory/folder1/file2.yaml", 'utf-8').toString() - assert.strictEqual(sortedFile, "akey: value\nkey: value") + let sortedFile = readFileSync("./src/test/files/getYamlFilesInDirectory/folder1/file.yaml", 'utf-8').toString() + strictEqual(sortedFile, "akey: value\nkey: value") + sortedFile = readFileSync("./src/test/files/getYamlFilesInDirectory/folder1/file2.yaml", 'utf-8').toString() + strictEqual(sortedFile, "akey: value\nkey: value") - fs.writeFileSync("./src/test/files/getYamlFilesInDirectory/folder1/file.yaml", "key: value\nakey: value") - fs.writeFileSync("./src/test/files/getYamlFilesInDirectory/folder1/file2.yaml", "key: value\nakey: value") + writeFileSync("./src/test/files/getYamlFilesInDirectory/folder1/file.yaml", "key: value\nakey: value") + writeFileSync("./src/test/files/getYamlFilesInDirectory/folder1/file2.yaml", "key: value\nakey: value") }) - test("should return `true` on invalid yaml", async () => { - const uri = vscode.Uri.parse(path.resolve("./src/test/files/getYamlFilesInDirectory/folder2")) - assert.strictEqual(sortYamlFiles(uri), true) + test("should return `true` on invalid yaml", () => { + const uri = Uri.parse(resolve("./src/test/files/getYamlFilesInDirectory/folder2")) + strictEqual(sortYamlFiles(uri), true) }) }) -suite("Test validateYamlWrapper", async () => { +suite("Test validateYamlWrapper", () => { test("should return true on open document", async () => { - const uri = vscode.Uri.parse(path.resolve("./src/test/files/getYamlFilesInDirectory/file.yaml")) - const doc = await vscode.workspace.openTextDocument(uri) - await vscode.window.showTextDocument(doc, { preview: false }) - assert.strictEqual(validateYamlWrapper(), true) + const uri = Uri.parse(resolve("./src/test/files/getYamlFilesInDirectory/file.yaml")) + const doc = await workspace.openTextDocument(uri) + await window.showTextDocument(doc, { preview: false }) + strictEqual(validateYamlWrapper(), true) }) }) suite("Test formatYamlWrapper", () => { test("should return true on a valid yaml", async () => { - const uri = vscode.Uri.parse(path.resolve("./src/test/files/getYamlFilesInDirectory/file.yaml")) - const doc = await vscode.workspace.openTextDocument(uri) - await vscode.window.showTextDocument(doc, { preview: false }) + const uri = Uri.parse(resolve("./src/test/files/getYamlFilesInDirectory/file.yaml")) + const doc = await workspace.openTextDocument(uri) + await window.showTextDocument(doc, { preview: false }) - const activeEditor = vscode.window.activeTextEditor + const activeEditor = window.activeTextEditor if (activeEditor) { const expected = '---\n' + 'key:\n' + ' key2: value' - assert.strictEqual(formatYamlWrapper()[0].newText, expected) + strictEqual(formatYamlWrapper()[0].newText, expected) } else { - assert.strictEqual(true, false) + strictEqual(true, false) } }) test("should format multiple yaml in one file", async () => { - const uri = vscode.Uri.parse(path.resolve("./src/test/files/testFormatYamlWrapper.yaml")) - const doc = await vscode.workspace.openTextDocument(uri) - await vscode.window.showTextDocument(doc, { preview: false }) + const uri = Uri.parse(resolve("./src/test/files/testFormatYamlWrapper.yaml")) + const doc = await workspace.openTextDocument(uri) + await window.showTextDocument(doc, { preview: false }) - const activeEditor = vscode.window.activeTextEditor + const activeEditor = window.activeTextEditor if (activeEditor) { const expected = '---\n' + @@ -64,21 +64,21 @@ suite("Test formatYamlWrapper", () => { '---\n' + 'key2: value' - assert.strictEqual(formatYamlWrapper()[0].newText, expected) + strictEqual(formatYamlWrapper()[0].newText, expected) } else { - assert.strictEqual(true, false) + strictEqual(true, false) } }) test("should fail on invalid yaml", async () => { - const uri = vscode.Uri.parse(path.resolve("./src/test/files/testFormatYamlWrapper-fail.yaml")) - const doc = await vscode.workspace.openTextDocument(uri) - await vscode.window.showTextDocument(doc, { preview: false }) + const uri = Uri.parse(resolve("./src/test/files/testFormatYamlWrapper-fail.yaml")) + const doc = await workspace.openTextDocument(uri) + await window.showTextDocument(doc, { preview: false }) - const activeEditor = vscode.window.activeTextEditor + const activeEditor = window.activeTextEditor if (activeEditor) { - assert.strictEqual(undefined, undefined) + strictEqual(undefined, undefined) } else { - assert.strictEqual(true, false) + strictEqual(true, false) } }) }) \ No newline at end of file diff --git a/src/test/suite/extension.test.ts b/src/test/suite/extension.test.ts index ee36a93..4aa7e5d 100644 --- a/src/test/suite/extension.test.ts +++ b/src/test/suite/extension.test.ts @@ -3,9 +3,9 @@ // Please refer to their documentation on https://mochajs.org/ for help. // -import * as assert from "assert" -import * as vscode from "vscode" -import * as path from "path" +import { deepStrictEqual, strictEqual, notDeepStrictEqual, equal, deepEqual } from "assert" +import { Uri, workspace, window, commands, Position, Range, Selection } from "vscode" +import { resolve } from "path" import { Settings } from "../../settings" import { applyComments, findComments, hasTextYamlKeys, isSelectionInvalid, splitYaml } from "../../util/yaml-util" @@ -17,124 +17,124 @@ suite("Test getCustomSortKeywords", () => { settings.getCustomSortKeywords = function () { return ["apiVersion", "kind", "metadata", "spec", "data"] } - assert.deepStrictEqual(settings.getCustomSortKeywords(1), ["apiVersion", "kind", "metadata", "spec", "data"]) + deepStrictEqual(settings.getCustomSortKeywords(1), ["apiVersion", "kind", "metadata", "spec", "data"]) }) test("should return `[]` for custom keywords 2 and 3", () => { - assert.deepStrictEqual(new Settings().getCustomSortKeywords(2), []) - assert.deepStrictEqual(new Settings().getCustomSortKeywords(3), []) + deepStrictEqual(new Settings().getCustomSortKeywords(2), []) + deepStrictEqual(new Settings().getCustomSortKeywords(3), []) }) test("should return [] when parameter is not in [1, 2, 3]", () => { - assert.deepStrictEqual(new Settings().getCustomSortKeywords(0), []) - assert.deepStrictEqual(new Settings().getCustomSortKeywords(4), []) - assert.deepStrictEqual(new Settings().getCustomSortKeywords(-1), []) - assert.deepStrictEqual(new Settings().getCustomSortKeywords(1.5), []) + deepStrictEqual(new Settings().getCustomSortKeywords(0), []) + deepStrictEqual(new Settings().getCustomSortKeywords(4), []) + deepStrictEqual(new Settings().getCustomSortKeywords(-1), []) + deepStrictEqual(new Settings().getCustomSortKeywords(1.5), []) }) }) suite("Test isSelectionInvalid", () => { test("should return `true` when `text` is passed", () => { - assert.strictEqual(isSelectionInvalid("text"), false) + strictEqual(isSelectionInvalid("text"), false) }) test("should return `false` when a string with trailing colon is passed", () => { - assert.strictEqual(isSelectionInvalid("text:"), true) + strictEqual(isSelectionInvalid("text:"), true) }) test("should return `false` when a string with trailing colon and whitespaces is passed", () => { - assert.strictEqual(isSelectionInvalid("text: "), true) + strictEqual(isSelectionInvalid("text: "), true) }) }) suite("Test validateYaml", () => { test("do not fail when executing command", async () => { - const uri = vscode.Uri.parse(path.resolve("./src/test/files/getYamlFilesInDirectory/file.yaml")) - const doc = await vscode.workspace.openTextDocument(uri) - await vscode.window.showTextDocument(doc, { preview: false }) - await vscode.commands.executeCommand("vscode-yaml-sort.validateYaml") + const uri = Uri.parse(resolve("./src/test/files/getYamlFilesInDirectory/file.yaml")) + const doc = await workspace.openTextDocument(uri) + await window.showTextDocument(doc, { preview: false }) + await commands.executeCommand("vscode-yaml-sort.validateYaml") }) }) suite("Test sortYamlWrapper", () => { /* test("should return `[]` on invalid quotingType", async () => { - const settings = vscode.workspace.getConfiguration("vscode-yaml-sort") - await settings.update("quotingType", "`", vscode.ConfigurationTarget.Global) + const settings = workspace.getConfiguration("vscode-yaml-sort") + await settings.update("quotingType", "`", ConfigurationTarget.Global) - const uri = vscode.Uri.parse(path.resolve("./src/test/files/getYamlFilesInDirectory/file.yaml")) - const doc = await vscode.workspace.openTextDocument(uri) - await vscode.window.showTextDocument(doc, { preview: false }) + const uri = Uri.parse(resolve("./src/test/files/getYamlFilesInDirectory/file.yaml")) + const doc = await workspace.openTextDocument(uri) + await window.showTextDocument(doc, { preview: false }) - const activeEditor = vscode.window.activeTextEditor + const activeEditor = window.activeTextEditor if (activeEditor) { const actual = 'key:\n' + ' key2: value' activeEditor.edit((builder) => builder.replace( - new vscode.Range( - new vscode.Position(0, 0), - new vscode.Position(activeEditor.document.lineCount + 1, 0)), + new Range( + new Position(0, 0), + new Position(activeEditor.document.lineCount + 1, 0)), actual)) - assert.deepStrictEqual(sortYamlWrapper(), []) + deepStrictEqual(sortYamlWrapper(), []) } else { - assert.strictEqual(true, false) + strictEqual(true, false) } - await settings.update("quotingType", "'", vscode.ConfigurationTarget.Global) + await settings.update("quotingType", "'", ConfigurationTarget.Global) }) */ test("should return edits on a valid yaml", async () => { - const uri = vscode.Uri.parse(path.resolve("./src/test/files/getYamlFilesInDirectory/file.yaml")) - const doc = await vscode.workspace.openTextDocument(uri) - await vscode.window.showTextDocument(doc, { preview: false }) + const uri = Uri.parse(resolve("./src/test/files/getYamlFilesInDirectory/file.yaml")) + const doc = await workspace.openTextDocument(uri) + await window.showTextDocument(doc, { preview: false }) - const activeEditor = vscode.window.activeTextEditor + const activeEditor = window.activeTextEditor if (activeEditor) { const actual = 'key:\n' + ' key2: value' activeEditor.edit((builder) => builder.replace( - new vscode.Range( - new vscode.Position(0, 0), - new vscode.Position(activeEditor.document.lineCount + 1, 0)), + new Range( + new Position(0, 0), + new Position(activeEditor.document.lineCount + 1, 0)), actual)) - assert.notDeepStrictEqual(sortYamlWrapper(), []) + notDeepStrictEqual(sortYamlWrapper(), []) } else { - assert.strictEqual(true, false) + strictEqual(true, false) } }) test("should return `[]` on invalid selection", async () => { - const uri = vscode.Uri.parse(path.resolve("./src/test/files/getYamlFilesInDirectory/file.yaml")) - const doc = await vscode.workspace.openTextDocument(uri) - await vscode.window.showTextDocument(doc, { preview: false }) + const uri = Uri.parse(resolve("./src/test/files/getYamlFilesInDirectory/file.yaml")) + const doc = await workspace.openTextDocument(uri) + await window.showTextDocument(doc, { preview: false }) - const activeEditor = vscode.window.activeTextEditor + const activeEditor = window.activeTextEditor if (activeEditor) { const actual = 'key:\n' + ' key2: value' activeEditor.edit((builder) => builder.replace( - new vscode.Range( - new vscode.Position(0, 0), - new vscode.Position(activeEditor.document.lineCount + 1, 0)), + new Range( + new Position(0, 0), + new Position(activeEditor.document.lineCount + 1, 0)), actual)) - activeEditor.selection = new vscode.Selection(0, 0, 0, 4) - assert.deepStrictEqual(sortYamlWrapper(), []) + activeEditor.selection = new Selection(0, 0, 0, 4) + deepStrictEqual(sortYamlWrapper(), []) } else { - assert.strictEqual(true, false) + strictEqual(true, false) } }) test("should ignore line if selection ends on a lines first character", async () => { - const uri = vscode.Uri.parse(path.resolve("./src/test/files/testSortYamlWrapper.yaml")) - const doc = await vscode.workspace.openTextDocument(uri) - await vscode.window.showTextDocument(doc, { preview: false }) + const uri = Uri.parse(resolve("./src/test/files/testSortYamlWrapper.yaml")) + const doc = await workspace.openTextDocument(uri) + await window.showTextDocument(doc, { preview: false }) - const activeEditor = vscode.window.activeTextEditor + const activeEditor = window.activeTextEditor if (activeEditor) { const expected = 'key:\n' + @@ -142,23 +142,23 @@ suite("Test sortYamlWrapper", () => { ' key3: value\n' + 'key4: value' - activeEditor.selection = new vscode.Selection(0, 0, 3, 0) - await vscode.commands.executeCommand("vscode-yaml-sort.sortYaml") + activeEditor.selection = new Selection(0, 0, 3, 0) + await commands.executeCommand("vscode-yaml-sort.sortYaml") // do not assert too fast await new Promise(r => setTimeout(r, 2000)); - assert.strictEqual(activeEditor.document.getText(), expected) + strictEqual(activeEditor.document.getText(), expected) } else { - assert.strictEqual(true, false) + strictEqual(true, false) } }) test("should remove yaml metadata tags (directives)", async () => { // Todo: This test needs a refactoring - const uri = vscode.Uri.parse(path.resolve("./src/test/files/getYamlFilesInDirectory/file.yaml")) - // const uri = vscode.Uri.parse(path.resolve("./src/test/files/testSortYaml.yaml")) - const doc = await vscode.workspace.openTextDocument(uri) - await vscode.window.showTextDocument(doc, { preview: false }) + const uri = Uri.parse(resolve("./src/test/files/getYamlFilesInDirectory/file.yaml")) + // const uri = Uri.parse(resolve("./src/test/files/testSortYaml.yaml")) + const doc = await workspace.openTextDocument(uri) + await window.showTextDocument(doc, { preview: false }) - const activeEditor = vscode.window.activeTextEditor + const activeEditor = window.activeTextEditor if (activeEditor) { const actual = '%YAML 1.1' + @@ -170,17 +170,17 @@ suite("Test sortYamlWrapper", () => { ' key2: value' activeEditor.edit((builder) => builder.replace( - new vscode.Range( - new vscode.Position(0, 0), - new vscode.Position(activeEditor.document.lineCount + 1, 0)), + new Range( + new Position(0, 0), + new Position(activeEditor.document.lineCount + 1, 0)), actual)) - await vscode.commands.executeCommand("vscode-yaml-sort.sortYaml") + await commands.executeCommand("vscode-yaml-sort.sortYaml") // do not assert too fast // await new Promise(r => setTimeout(r, 2000)); - assert.strictEqual(activeEditor.document.getText(), expected) + strictEqual(activeEditor.document.getText(), expected) } else { - assert.strictEqual(true, false) + strictEqual(true, false) } }) }) @@ -188,11 +188,11 @@ suite("Test sortYamlWrapper", () => { suite("Test hasTextYamlKeys", () => { test("when a text with no yaml keys is passed, `false` is returned", () => { - assert.equal(hasTextYamlKeys(""), false) + equal(hasTextYamlKeys(""), false) }) test("when a text with yaml keys is passed, `true` is returned", () => { - assert.equal(hasTextYamlKeys("api: v1"), true) + equal(hasTextYamlKeys("api: v1"), true) }) }) @@ -202,14 +202,14 @@ suite("Test splitYaml", () => { const actual = `\ - Orange - Apple` - assert.deepStrictEqual(splitYaml(actual), ["- Orange\n- Apple"]) + deepStrictEqual(splitYaml(actual), ["- Orange\n- Apple"]) }) test("should return the input document without the delimiters", () => { const actual = `\ --- - Orange - Apple` - assert.deepStrictEqual(splitYaml(actual), ["\n- Orange\n- Apple"]) + deepStrictEqual(splitYaml(actual), ["\n- Orange\n- Apple"]) }) test("should return an array with the yaml documents", () => { const actual = `\ @@ -218,7 +218,7 @@ suite("Test splitYaml", () => { --- - Orange - Apple` - assert.deepStrictEqual(splitYaml(actual), ["- Orange\n- Apple\n", "\n- Orange\n- Apple"]) + deepStrictEqual(splitYaml(actual), ["- Orange\n- Apple\n", "\n- Orange\n- Apple"]) }) test("Split multiple yaml documents with leading dashes", () => { const actual = `\ @@ -229,7 +229,7 @@ suite("Test splitYaml", () => { - Orange - Apple` - assert.deepStrictEqual(splitYaml(actual), + deepStrictEqual(splitYaml(actual), ["\n- Orange\n- Apple\n", "\n- Orange\n- Apple"]) }) test("Split multiple yaml documents with text behind delimiter", () => { @@ -240,7 +240,7 @@ suite("Test splitYaml", () => { --- text - Orange - Apple` - assert.deepStrictEqual(splitYaml(actual), + deepStrictEqual(splitYaml(actual), ["\n- Orange\n- Apple\n", "\n- Orange\n- Apple"]) }) }) @@ -254,7 +254,7 @@ suite("Test findComments", () => { ' place: Germany\n' + ' age: 23\n' const expected = new Map() - assert.deepEqual(findComments(yaml), expected) + deepEqual(findComments(yaml), expected) }) test("should return a map with the line below the comment as key and the comment as value", () => { @@ -267,7 +267,7 @@ suite("Test findComments", () => { const expected = new Map() expected.set('# bob is 1st', ' bob:') - assert.deepEqual(findComments(yaml), expected) + deepEqual(findComments(yaml), expected) }) test("should return a map with the line below the comment as key and the comment as value (comment on top)", () => { @@ -280,7 +280,7 @@ suite("Test findComments", () => { const expected = new Map() expected.set('# comment on top', 'persons:') - assert.deepEqual(findComments(yaml), expected) + deepEqual(findComments(yaml), expected) }) test("should return a map with the line below the comment as key and the comment as value (comment at the bottom)", () => { @@ -293,7 +293,7 @@ suite("Test findComments", () => { const expected = new Map() expected.set('# comment at the bottom', '') - assert.deepEqual(findComments(yaml), expected) + deepEqual(findComments(yaml), expected) }) test("should merge multiline comments", () => { @@ -307,7 +307,7 @@ suite("Test findComments", () => { const expected = new Map() expected.set('# bob is 1st\n# alice is 2nd', ' bob:') - assert.deepEqual(findComments(yaml), expected) + deepEqual(findComments(yaml), expected) }) }) @@ -329,7 +329,7 @@ suite("Test applyComments", () => { ' place: Germany\n' + ' age: 23\n' - assert.deepEqual(applyComments(yaml, comments), expected) + deepEqual(applyComments(yaml, comments), expected) }) test("should apply comment to last line in yaml", () => { @@ -342,7 +342,7 @@ suite("Test applyComments", () => { 'persons: bob\n' + '# last line comment' - assert.deepEqual(applyComments(yaml, comments), expected) + deepEqual(applyComments(yaml, comments), expected) }) test("should apply multiple comments to yaml", () => { @@ -366,7 +366,7 @@ suite("Test applyComments", () => { '\n' + '# last line comment' - assert.deepEqual(applyComments(yaml, comments), expected) + deepEqual(applyComments(yaml, comments), expected) }) test("should recognize indentation", () => { @@ -385,6 +385,6 @@ suite("Test applyComments", () => { ' place: Germany\n' + ' age: 23\n' - assert.deepEqual(applyComments(yaml, comments), expected) + deepEqual(applyComments(yaml, comments), expected) }) }) diff --git a/src/test/suite/index.ts b/src/test/suite/index.ts index dbfb4c8..c638406 100644 --- a/src/test/suite/index.ts +++ b/src/test/suite/index.ts @@ -1,19 +1,19 @@ -import * as path from 'path' -import * as Mocha from 'mocha' +import { resolve, join} from 'path' +import Mocha = require('mocha') // eslint-disable-next-line @typescript-eslint/no-var-requires -const NYC = require('nyc'); -import * as glob from 'glob' +const NYC = require('nyc') +import { sync } from 'glob' // Recommended modules, loading them here to speed up NYC init // and minimize risk of race condition import 'ts-node/register' export async function run(): Promise { - const testsRoot = path.resolve(__dirname, '..') + const testsRoot = resolve(__dirname, '..') // Setup coverage pre-test, including post-test hook to report const nyc = new NYC({ - cwd: path.join(__dirname, '..', '..', '..'), + cwd: join(__dirname, '..', '..', '..'), reporter: ['text-summary', 'html', 'lcov'], all: true, silent: false, @@ -24,17 +24,8 @@ export async function run(): Promise { }); await nyc.wrap(); -// Check the modules already loaded and warn in case of race condition - // (ideally, at this point the require cache should only contain one file - this module) - const myFilesRegex = /vscode-yaml-sort\/out/; - const filterFn = myFilesRegex.test.bind(myFilesRegex); - if (Object.keys(require.cache).filter(filterFn).length > 1) { - console.warn('NYC initialized after modules were loaded', Object.keys(require.cache).filter(filterFn)); - } - // Debug which files will be included/excluded // console.log('Glob verification', await nyc.exclude.glob(nyc.cwd)); - await nyc.createTempDirectory(); // Create the mocha test const mocha = new Mocha({ @@ -44,25 +35,13 @@ export async function run(): Promise { }) // Add all files to the test suite - const files = glob.sync('**/*.test.js', { cwd: testsRoot }); - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); + const files = sync('**/*.test.js', { cwd: testsRoot }); + files.forEach(f => mocha.addFile(resolve(testsRoot, f))); - const failures: number = await new Promise(resolve => mocha.run(resolve)); + const failures: number = await new Promise(executor => mocha.run(executor)); await nyc.writeCoverageFile(); - // Capture text-summary reporter's output and log it in console - console.log(await captureStdout(nyc.report.bind(nyc))); - if (failures > 0) { throw new Error(`${failures} tests failed.`); } } - -async function captureStdout(fn: () => unknown) { - const w = process.stdout.write; - let buffer = ''; - process.stdout.write = (s) => { buffer = buffer + s; return true; }; - fn(); - process.stdout.write = w; - return buffer; -} \ No newline at end of file diff --git a/src/test/suite/lib.test.ts b/src/test/suite/lib.test.ts index 6e7f40d..fc09340 100644 --- a/src/test/suite/lib.test.ts +++ b/src/test/suite/lib.test.ts @@ -1,10 +1,4 @@ -// -// 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" +import { strictEqual, throws, equal, deepStrictEqual, deepEqual } from "assert" import { addNewLineBeforeKeywordsUpToLevelN, addNewLineBeforeRootKeywords, @@ -16,53 +10,46 @@ import { getDelimiters, removeTrailingCharacters } from "../../util/yaml-util" suite("Test removeTrailingCharacters", () => { const actual = "text" test("should return `t` when `t` and 0 are passed", () => { - assert.strictEqual(removeTrailingCharacters("t", 0), "t") + strictEqual(removeTrailingCharacters("t", 0), "t") }) test("should return `t` when `text` and 3 are passed", () => { - assert.strictEqual(removeTrailingCharacters(actual, actual.length - 1 ), "t") + strictEqual(removeTrailingCharacters(actual, actual.length - 1 ), "t") }) test("should return `tex` when `text` and 1 are passed", () => { - assert.strictEqual(removeTrailingCharacters(actual, 1), "tex") + strictEqual(removeTrailingCharacters(actual, 1), "tex") }) test("should return `` when `text` and 4 are passed", () => { - assert.strictEqual(removeTrailingCharacters(actual, actual.length), "") + strictEqual(removeTrailingCharacters(actual, actual.length), "") }) test("should throw an error when a negative input is passed", () => { - assert.throws(() => removeTrailingCharacters(actual, -1)) + throws(() => removeTrailingCharacters(actual, -1)) }) test("should throw an error when the count parameter is bigger than the text lenght", () => { - assert.throws(() => removeTrailingCharacters(actual, actual.length + 1)) + throws(() => removeTrailingCharacters(actual, actual.length + 1)) }) const actual2 = "text\n" test("should return `text` when `text\\n` and 1 are passed", () => { - assert.strictEqual(removeTrailingCharacters(actual2, 1), "text") + strictEqual(removeTrailingCharacters(actual2, 1), "text") }) test("should return `text\\n` when `text\\n` and 0 are passed", () => { - assert.strictEqual(removeTrailingCharacters(actual2, 0), actual2) + strictEqual(removeTrailingCharacters(actual2, 0), actual2) }) }) suite("Test prependWhitespacesOnEachLine", () => { const actual = "text" test("should return ` text` when `text` and 2 are passed", () => { - assert.strictEqual(prependWhitespacesOnEachLine(actual, 2), " text") + strictEqual(prependWhitespacesOnEachLine(actual, 2), " text") }) test("should return `text` when `text` and 0 are passed", () => { - assert.strictEqual(prependWhitespacesOnEachLine(actual, 0), "text") + strictEqual(prependWhitespacesOnEachLine(actual, 0), "text") }) test("should throw an error when a negative input is passed", () => { - assert.throws(() => prependWhitespacesOnEachLine(actual, -1)) + throws(() => prependWhitespacesOnEachLine(actual, -1)) }) const actual2 = "text\n" test("should return ` text\\n ` when `text\\n` and 2 are passed", () => { - assert.strictEqual(prependWhitespacesOnEachLine(actual2, 2), " text\n ") - }) -}) - -suite("Test removeLeadingLineBreakOfFirstElement", () => { - test("should remove only the first line break of an string array", () => { - //const actual = ["\ntext", "\ntext"] as RegExpExecArray - // assert.deepStrictEqual(removeLeadingLineBreakOfFirstElement(actual), ["text", "\ntext"]) + strictEqual(prependWhitespacesOnEachLine(actual2, 2), " text\n ") }) }) @@ -72,7 +59,7 @@ yaml: data spec: spec ` test("should return `` when the input string does not contain a delimiter and isSelectionEmpty=true and useLeadingDashes=false", () => { - assert.equal(getDelimiters(doc, true, false), "") + equal(getDelimiters(doc, true, false), "") }) test("should return all delimiters except the first (return an empty string instead) when the input document starts with a delimiter and isSelectionEmpty=true and useLeadingDashes=false", () => { doc = ` @@ -82,7 +69,7 @@ yaml: data spec: spec ` const actual = getDelimiters(doc, true, false) - assert.deepStrictEqual(actual, ["", "\n--- #comment\n"]) + deepStrictEqual(actual, ["", "\n--- #comment\n"]) }) test("should add leading dashes when useLeadingDashes=true and given document does not have leading dashes", () => { doc = ` @@ -91,7 +78,7 @@ foo: bar foo2: baz ` const actual = getDelimiters(doc, true, true) - assert.deepStrictEqual(actual, ["---\n", "\n---\n"]) + deepStrictEqual(actual, ["---\n", "\n---\n"]) }) test("Get each delimiter (empty selection, leading linebreak)", () => { doc = ` @@ -103,7 +90,7 @@ spec: spec--- ` const actual = getDelimiters(doc, true, false) - assert.deepStrictEqual(actual, ["", "\n--- #comment\n"]) + deepStrictEqual(actual, ["", "\n--- #comment\n"]) }) test("Get each delimiter (empty selection, leading text)", () => { doc = ` @@ -112,7 +99,7 @@ bla test: bla ` const actual = getDelimiters(doc, true, false) - assert.deepStrictEqual(actual, ["", "\n--- text\n"]) + deepStrictEqual(actual, ["", "\n--- text\n"]) }) test("Get each delimiter (with selection, leading delimiter)", () => { doc = ` @@ -120,7 +107,7 @@ test: bla test: bla ` const actual = getDelimiters(doc, false, false) - assert.deepEqual(actual, ["--- text\n"]) + deepEqual(actual, ["--- text\n"]) }) test("Get each delimiter (with selection, leading text)", () => { doc = ` @@ -129,7 +116,7 @@ bla test: bla ` const actual = getDelimiters(doc, false, false) - assert.deepEqual(actual, ["", "\n--- text\n"]) + deepEqual(actual, ["", "\n--- text\n"]) }) }) @@ -147,10 +134,10 @@ a-1: c: d: g` test("should replace all tabs with spaces", () => { - assert.strictEqual(replaceTabsWithSpaces(actual, 2), expected) + strictEqual(replaceTabsWithSpaces(actual, 2), expected) }) test("should throw error when count is smaller than `1`", () => { - assert.throws(() => replaceTabsWithSpaces(actual, 0)) + throws(() => replaceTabsWithSpaces(actual, 0)) }) }) @@ -165,7 +152,7 @@ spec: value spec: value ` - assert.strictEqual(addNewLineBeforeRootKeywords(actual), expected) + strictEqual(addNewLineBeforeRootKeywords(actual), expected) }) }) @@ -182,7 +169,7 @@ spec: value spec: value ` - assert.strictEqual(addNewLineBeforeKeywordsUpToLevelN(1, 2, actual), expected) + strictEqual(addNewLineBeforeKeywordsUpToLevelN(1, 2, actual), expected) expected = `data: @@ -191,7 +178,7 @@ spec: value spec: value ` - assert.strictEqual(addNewLineBeforeKeywordsUpToLevelN(2, 2, actual), expected) + strictEqual(addNewLineBeforeKeywordsUpToLevelN(2, 2, actual), expected) }) test("should recognize keywords containing the char -", () => { @@ -208,7 +195,7 @@ spec: value sp-ec: value ` - assert.strictEqual(addNewLineBeforeKeywordsUpToLevelN(2, 2, actual), expected) + strictEqual(addNewLineBeforeKeywordsUpToLevelN(2, 2, actual), expected) }) test("should recognize keywords containing spaces", () => { @@ -226,6 +213,6 @@ spec: value '\n' + 'foo bar: value' - assert.strictEqual(addNewLineBeforeKeywordsUpToLevelN(2, 2, actual), expected) + strictEqual(addNewLineBeforeKeywordsUpToLevelN(2, 2, actual), expected) }) }) diff --git a/src/test/suite/settings.test.ts b/src/test/suite/settings.test.ts index 7cd70c7..872b4dc 100644 --- a/src/test/suite/settings.test.ts +++ b/src/test/suite/settings.test.ts @@ -1,5 +1,5 @@ -import * as assert from "assert" -import * as jsyaml from "js-yaml" +import { deepEqual } from "assert" +import { Schema, DEFAULT_SCHEMA, CORE_SCHEMA, JSON_SCHEMA, FAILSAFE_SCHEMA} from "js-yaml" import { Settings } from "../../settings" import { CLOUDFORMATION_SCHEMA } from "cloudformation-js-yaml-schema" import { HOMEASSISTANT_SCHEMA } from "homeassistant-js-yaml-schema" @@ -8,71 +8,71 @@ suite("Test Settings - getter", () => { const settings: Settings = new Settings(); test("default value of customSortKeywords_1 is set to `['apiVersion', 'kind', 'metadata', 'spec', 'data']`", () => { - assert.deepEqual(settings.getCustomSortKeywords(1), ["apiVersion", "kind", "metadata", "spec", "data"]) + deepEqual(settings.getCustomSortKeywords(1), ["apiVersion", "kind", "metadata", "spec", "data"]) }) test("default value of customSortKeywords_2 is set to `[]`", () => { - assert.deepEqual(settings.getCustomSortKeywords(2), []) + deepEqual(settings.getCustomSortKeywords(2), []) }) test("default value of customSortKeywords_3 is set to `[]`", () => { - assert.deepEqual(settings.getCustomSortKeywords(3), []) + deepEqual(settings.getCustomSortKeywords(3), []) }) test("default value of emptyLinesUntilLevel is set to `0`", () => { - assert.deepEqual(settings.getEmptyLinesUntilLevel(), 0) + deepEqual(settings.getEmptyLinesUntilLevel(), 0) }) test("default value of forceQuotes is set to `false`", () => { - assert.deepEqual(settings.getForceQuotes(), false) + deepEqual(settings.getForceQuotes(), false) }) test("default value of indent is set to `2`", () => { - assert.deepEqual(settings.getIndent(), 2) + deepEqual(settings.getIndent(), 2) }) test("default value of lineWidth is set to `500`", () => { - assert.deepEqual(settings.getLineWidth(), 500) + deepEqual(settings.getLineWidth(), 500) }) test("default value of locale is set to `en`", () => { - assert.deepEqual(settings.getLocale(), "en") + deepEqual(settings.getLocale(), "en") }) test("default value of noArrayIndent is set to `false`", () => { - assert.deepEqual(settings.getNoArrayIndent(), false) + deepEqual(settings.getNoArrayIndent(), false) }) test("default value of noCompatMode is set to `false`", () => { - assert.deepEqual(settings.getNoCompatMode(), false) + deepEqual(settings.getNoCompatMode(), false) }) test("default value of notifySuccess is set to `true`", () => { - assert.deepEqual(settings.getNotifySuccess(), true) + deepEqual(settings.getNotifySuccess(), true) }) test("default value of quotingType is set to `'`", () => { - assert.deepEqual(settings.getQuotingType(), "'") + deepEqual(settings.getQuotingType(), "'") }) test("default value of schema is set to `DEFAULT_SCHEMA`", () => { - assert.deepEqual(settings.getSchema(), jsyaml.DEFAULT_SCHEMA) + deepEqual(settings.getSchema(), DEFAULT_SCHEMA) }) test("default value of sortOnSave is set to `0`", () => { - assert.deepEqual(settings.getSortOnSave(), 0) + deepEqual(settings.getSortOnSave(), 0) }) test("default value of useAsFormatter is set to `false`", () => { - assert.deepEqual(settings.getUseAsFormatter(), false) + deepEqual(settings.getUseAsFormatter(), false) }) test("default value of useCustomSortRecursively is set to `false`", () => { - assert.deepEqual(settings.getUseCustomSortRecursively(), false) + deepEqual(settings.getUseCustomSortRecursively(), false) }) test("default value of useLeadingDashes is set to `true`", () => { - assert.deepEqual(settings.getUseLeadingDashes(), true) + deepEqual(settings.getUseLeadingDashes(), true) }) }) @@ -80,34 +80,32 @@ suite("Test Settings - getCustomSortKeywords()", () => { const settings: Settings = new Settings() test("when index is not in [1, 2, 3] return `[]`", () => { - assert.deepEqual(settings.getCustomSortKeywords(0), []) + deepEqual(settings.getCustomSortKeywords(0), []) }) }) suite("Test Settings - getJsYamlSchemaFromString()", () => { - const settings: Settings = new Settings() - test("when `HOMEASSISTANT_SCHEMA` is input return HOMEASSISTANT_SCHEMA", () => { - assert.deepEqual(settings.getJsYamlSchemaFromString("HOMEASSISTANT_SCHEMA"), HOMEASSISTANT_SCHEMA as jsyaml.Schema) + deepEqual(Settings.getJsYamlSchemaFromString("HOMEASSISTANT_SCHEMA"), HOMEASSISTANT_SCHEMA as Schema) }) test("when `CLOUDFORMATION_SCHEMA` is input return CLOUDFORMATION_SCHEMA", () => { - assert.deepEqual(settings.getJsYamlSchemaFromString("CLOUDFORMATION_SCHEMA"), CLOUDFORMATION_SCHEMA as jsyaml.Schema) + deepEqual(Settings.getJsYamlSchemaFromString("CLOUDFORMATION_SCHEMA"), CLOUDFORMATION_SCHEMA as Schema) }) - test("when `CORE_SCHEMA` is input return jsyaml.CORE_SCHEMA", () => { - assert.deepEqual(settings.getJsYamlSchemaFromString("CORE_SCHEMA"), jsyaml.CORE_SCHEMA) + test("when `CORE_SCHEMA` is input return CORE_SCHEMA", () => { + deepEqual(Settings.getJsYamlSchemaFromString("CORE_SCHEMA"), CORE_SCHEMA) }) - test("when `FAILSAFE_SCHEMA` is input return jsyaml.FAILSAFE_SCHEMA", () => { - assert.deepEqual(settings.getJsYamlSchemaFromString("FAILSAFE_SCHEMA"), jsyaml.FAILSAFE_SCHEMA) + test("when `FAILSAFE_SCHEMA` is input return FAILSAFE_SCHEMA", () => { + deepEqual(Settings.getJsYamlSchemaFromString("FAILSAFE_SCHEMA"), FAILSAFE_SCHEMA) }) - test("when `JSON_SCHEMA` is input return jsyaml.JSON_SCHEMA", () => { - assert.deepEqual(settings.getJsYamlSchemaFromString("JSON_SCHEMA"), jsyaml.JSON_SCHEMA) + test("when `JSON_SCHEMA` is input return JSON_SCHEMA", () => { + deepEqual(Settings.getJsYamlSchemaFromString("JSON_SCHEMA"), JSON_SCHEMA) }) - test("when a non-valid schema is input return jsyaml.DEFAULT_SCHEMA", () => { - assert.deepEqual(settings.getJsYamlSchemaFromString("DEFAULT_SCHEMA"), jsyaml.DEFAULT_SCHEMA) + test("when a non-valid schema is input return DEFAULT_SCHEMA", () => { + deepEqual(Settings.getJsYamlSchemaFromString("DEFAULT_SCHEMA"), DEFAULT_SCHEMA) }) }) \ No newline at end of file diff --git a/src/test/suite/util/file-util.test.ts b/src/test/suite/util/file-util.test.ts index b355f1d..aaa1c3b 100644 --- a/src/test/suite/util/file-util.test.ts +++ b/src/test/suite/util/file-util.test.ts @@ -1,4 +1,4 @@ -import * as assert from "assert" +import { strictEqual, throws, deepStrictEqual } from "assert" import { Settings } from "../../../settings" import { FileUtil } from "../../../util/file-util" @@ -6,11 +6,11 @@ suite("Test FileUtil - readFile()", () => { const fileutil = new FileUtil() test("when `file` is a path to an existing file should return the files content", () => { - assert.strictEqual(fileutil.readFile("./src/test/suite/util/resources/readFile.txt"), "lorem impsum") + strictEqual(fileutil.readFile("./src/test/suite/util/resources/readFile.txt"), "lorem impsum") }) test("when `file` is a path to a non existing file should throw", () => { - assert.throws(() => fileutil.readFile("nonexistent-path"), Error) + throws(() => fileutil.readFile("nonexistent-path"), Error) }) }) @@ -28,7 +28,7 @@ suite("Test FileUtil - getFilesWithExtensions()", () => { "./src/test/suite/util/resources/bar.yml", "./src/test/suite/util/resources/subfolder/.customyaml", ] - assert.deepStrictEqual(fileutil.getFilesWithExtensions("./src/test/suite/util/resources"), expected) + deepStrictEqual(fileutil.getFilesWithExtensions("./src/test/suite/util/resources"), expected) }) test("should list all files with extension *.yaml or *.yml in a directory and all its subdirectories", () => { @@ -40,6 +40,6 @@ suite("Test FileUtil - getFilesWithExtensions()", () => { './src/test/files/getYamlFilesInDirectory/folder2/file.yaml', './src/test/files/getYamlFilesInDirectory/file.yml' ] - assert.deepStrictEqual(fileutil.getFilesWithExtensions("./src/test/files/getYamlFilesInDirectory"), expected) + deepStrictEqual(fileutil.getFilesWithExtensions("./src/test/files/getYamlFilesInDirectory"), expected) }) }) \ No newline at end of file diff --git a/src/test/suite/util/sort-util.test.ts b/src/test/suite/util/sort-util.test.ts index 941e20b..03847e5 100644 --- a/src/test/suite/util/sort-util.test.ts +++ b/src/test/suite/util/sort-util.test.ts @@ -1,4 +1,4 @@ -import * as assert from "assert" +import { strictEqual } from "assert" import { Settings } from "../../../settings" import { SortUtil } from "../../../util/sort-util" @@ -9,7 +9,7 @@ suite("Test Sort - localeSort()", () => { return "sv" } const sort = new SortUtil(settings) - assert.strictEqual(sort.localeSort("ä", "z"), 1) + strictEqual(sort.localeSort("ä", "z"), 1) }) test("when `locale` is `en` and a is `ä` and b is `z` should return -1", () => { @@ -18,7 +18,7 @@ suite("Test Sort - localeSort()", () => { return "en" } const sort = new SortUtil(settings) - assert.strictEqual(sort.localeSort("ä", "z"), -1) + strictEqual(sort.localeSort("ä", "z"), -1) }) }) @@ -31,29 +31,12 @@ suite("Test Sort - customSort()", () => { sort.custom = 1 test("when `custom` is `1` and keywords are `['kind', 'data']` and a is `data` and b is `kind` should return 1", () => { - assert.strictEqual(sort.customSort("data", "kind"), 1) + strictEqual(sort.customSort("data", "kind"), 1) }) test("when `custom` is `1` and keywords are `['kind', 'data']` and a is `kind` and b is `data` should return -1", () => { - assert.strictEqual(sort.customSort("kind", "data"), -1) + strictEqual(sort.customSort("kind", "data"), -1) }) test("when `custom` is `1` and keywords are `['kind', 'data']` and a is `kind` and b is `kind` should return 0", () => { - assert.strictEqual(sort.customSort("kind", "kind"), 0) - }) -}) - -suite("Test Sort - getSortingAlgorithm()", () => { - test("when `custom` is bigger than `0` and useCustomSortRecursively is `true` return customSort", () => { - const settings = new Settings() - settings.getUseCustomSortRecursively = function () { - return true - } - const sort = new SortUtil(settings) - sort.custom = 1 - assert.strictEqual(sort.getSortingAlgorithm(), sort.customSort) - }) - test("when `custom` is `0` return localeSort", () => { - const settings = new Settings() - const sort = new SortUtil(settings) - assert.strictEqual(sort.getSortingAlgorithm(), sort.localeSort) + strictEqual(sort.customSort("kind", "kind"), 0) }) }) \ No newline at end of file diff --git a/src/test/suite/util/yaml-util.test.ts b/src/test/suite/util/yaml-util.test.ts index d831e4c..8645923 100644 --- a/src/test/suite/util/yaml-util.test.ts +++ b/src/test/suite/util/yaml-util.test.ts @@ -1,4 +1,4 @@ -import * as assert from "assert" +import { equal, strictEqual } from "assert" import { CLOUDFORMATION_SCHEMA } from "cloudformation-js-yaml-schema" import jsyaml = require("js-yaml") import { Settings } from "../../../settings" @@ -6,7 +6,7 @@ import { YamlUtil } from "../../../util/yaml-util" suite("Test dumpYaml", () => { - test("when useCustomSortRecursively is set to `true` should recursively use customSort", async () => { + test("when useCustomSortRecursively is set to `true` should recursively use customSort", () => { const actual = 'keyword1: value\n' + 'keyword: value\n' + @@ -34,7 +34,7 @@ suite("Test dumpYaml", () => { return true } const yamlutil = new YamlUtil(settings) - assert.strictEqual(yamlutil.sortYaml(actual, 1), expected) + strictEqual(yamlutil.sortYaml(actual, 1), expected) }) test("when locale is `en` should sort character `ä` over `z`", () => { @@ -54,7 +54,7 @@ suite("Test dumpYaml", () => { return true } const yamlutil = new YamlUtil(settings) - assert.strictEqual(yamlutil.sortYaml(actual, 1), expected) + strictEqual(yamlutil.sortYaml(actual, 1), expected) }) test("when locale is `sv` should sort character `z` over `ä`", () => { @@ -71,7 +71,7 @@ suite("Test dumpYaml", () => { return "sv" } const yamlutil = new YamlUtil(settings) - assert.strictEqual(yamlutil.sortYaml(actual, 1), expected) + strictEqual(yamlutil.sortYaml(actual, 1), expected) }) test("should ignore case when sorting", () => { @@ -88,7 +88,7 @@ suite("Test dumpYaml", () => { return true } const yamlutil = new YamlUtil(settings) - assert.strictEqual(yamlutil.sortYaml(actual, 1), expected) + strictEqual(yamlutil.sortYaml(actual, 1), expected) }) }) @@ -122,7 +122,7 @@ suite("Test dumpYaml", () => { return true } const yamlutil = new YamlUtil(settings) - assert.strictEqual(yamlutil.sortYaml(actual, 1), expected) + strictEqual(yamlutil.sortYaml(actual, 1), expected) }) test("should sort with by locale behaviour", () => { const actual = @@ -138,7 +138,7 @@ suite("Test dumpYaml", () => { return true } const yamlutil = new YamlUtil(settings) - assert.strictEqual(yamlutil.sortYaml(actual, 1), expected) + strictEqual(yamlutil.sortYaml(actual, 1), expected) expected = 'z: value\n' + @@ -147,7 +147,7 @@ suite("Test dumpYaml", () => { yamlutil.settings.getLocale = function () { return "sv" } - assert.strictEqual(yamlutil.sortYaml(actual, 1), expected) + strictEqual(yamlutil.sortYaml(actual, 1), expected) }) test("should ignore case when sorting", () => { const actual = @@ -163,13 +163,13 @@ suite("Test dumpYaml", () => { return true } const yamlutil = new YamlUtil(settings) - assert.strictEqual(yamlutil.sortYaml(actual, 1), expected) + strictEqual(yamlutil.sortYaml(actual, 1), expected) }) - }) - - - suite("Test sortYaml", () => { - test("should sort a given yaml document", async () => { +}) + + +suite("Test sortYaml", () => { + test("should sort a given yaml document", () => { const actual = 'persons:\n' + ' bob:\n' + @@ -194,10 +194,10 @@ suite("Test dumpYaml", () => { ' This is a very long sentence that spans several lines in the YAML' const yamlutil = new YamlUtil() - assert.strictEqual(yamlutil.sortYaml(actual, 1), expected) + strictEqual(yamlutil.sortYaml(actual, 1), expected) }) - test("should put top level keyword `spec` before `data` when passing customsort=1", async () => { + test("should put top level keyword `spec` before `data` when passing customsort=1", () => { let actual = 'data: data\n' + 'spec: spec' @@ -207,7 +207,7 @@ suite("Test dumpYaml", () => { 'data: data\n' const yamlutil = new YamlUtil() - assert.strictEqual(yamlutil.sortYaml(actual, 1), expected) + strictEqual(yamlutil.sortYaml(actual, 1), expected) actual = 'data: data\n' + @@ -219,7 +219,7 @@ suite("Test dumpYaml", () => { ' - aa: b\n' + 'data: data\n' - assert.strictEqual(yamlutil.sortYaml(actual, 1), expected) + strictEqual(yamlutil.sortYaml(actual, 1), expected) actual = 'data:\n' + @@ -239,7 +239,7 @@ suite("Test dumpYaml", () => { ' skills:\n' + ' - pascal\n' - assert.strictEqual(yamlutil.sortYaml(actual, 1), expected) + strictEqual(yamlutil.sortYaml(actual, 1), expected) actual = 'data: data\n' + @@ -253,7 +253,7 @@ suite("Test dumpYaml", () => { ' - b\n' + 'data: data\n' - assert.strictEqual(yamlutil.sortYaml(actual, 1), expected) + strictEqual(yamlutil.sortYaml(actual, 1), expected) }) test("should wrap words after 500 characters (`vscode-yaml-sort.lineWidth`)", () => { @@ -276,7 +276,7 @@ suite("Test dumpYaml", () => { ' dolores et e' const yamlutil = new YamlUtil() - assert.strictEqual(yamlutil.sortYaml(actual, 1), expected) + strictEqual(yamlutil.sortYaml(actual, 1), expected) }) test("should add an empty line before `spec`", () => { @@ -298,13 +298,13 @@ suite("Test dumpYaml", () => { return 2 } const yamlutil = new YamlUtil(settings) - assert.strictEqual(yamlutil.sortYaml(actual, 0), expected) + strictEqual(yamlutil.sortYaml(actual, 0), expected) }) test("should not format a date in CORE_SCHEMA", () => { const actual = 'AWSTemplateFormatVersion: 2010-09-09' let expected = 'AWSTemplateFormatVersion: 2010-09-09T00:00:00.000Z' let yamlutil = new YamlUtil() - assert.strictEqual(yamlutil.sortYaml(actual, 0), expected) + strictEqual(yamlutil.sortYaml(actual, 0), expected) expected = actual @@ -314,7 +314,7 @@ suite("Test dumpYaml", () => { } yamlutil = new YamlUtil(settings) - assert.strictEqual(yamlutil.sortYaml(actual, 0), expected) + strictEqual(yamlutil.sortYaml(actual, 0), expected) }) test("should sort a yaml with CLOUDFORMATION_SCHEMA", () => { const actual = @@ -344,7 +344,7 @@ suite("Test dumpYaml", () => { return 2 } const yamlutil = new YamlUtil(settings) - assert.strictEqual(yamlutil.sortYaml(actual, 0), expected) + strictEqual(yamlutil.sortYaml(actual, 0), expected) }) test("compatibility with older yaml versions should be configurable", () => { const actual = @@ -365,7 +365,7 @@ suite("Test dumpYaml", () => { return "\"" } const yamlutil = new YamlUtil(settings) - assert.strictEqual(yamlutil.sortYaml(actual, 0), expected) + strictEqual(yamlutil.sortYaml(actual, 0), expected) expected = 'key:\n' + @@ -374,10 +374,9 @@ suite("Test dumpYaml", () => { yamlutil.settings.getNoCompatMode = function () { return true } - assert.strictEqual(yamlutil.sortYaml(actual, 0), expected) + strictEqual(yamlutil.sortYaml(actual, 0), expected) }) - }) - +}) suite("Test formatYaml", () => { test("should sort all yaml files in directory", () => { @@ -404,7 +403,7 @@ suite("Test formatYaml", () => { return false } let yamlutil = new YamlUtil(settings) - assert.strictEqual(yamlutil.formatYaml(actual, false), expected) + strictEqual(yamlutil.formatYaml(actual, false), expected) expected = '---\n' + @@ -417,11 +416,53 @@ suite("Test formatYaml", () => { ' age: 3' yamlutil = new YamlUtil() - assert.strictEqual(yamlutil.formatYaml(actual, true), expected) + strictEqual(yamlutil.formatYaml(actual, true), expected) }) test("should return `null` on invalid yaml", () => { const yamlutil = new YamlUtil() - assert.strictEqual(yamlutil.formatYaml('key: 1\nkey: 1', true), null) + strictEqual(yamlutil.formatYaml('key: 1\nkey: 1', true), null) + }) +}) + +suite("Test YamlUtil - getNumberOfLeadingSpaces()", () => { + test("should return the number of leading spaces of 'text'", () => { + strictEqual(YamlUtil.getNumberOfLeadingSpaces(" foo"), 2) + strictEqual(YamlUtil.getNumberOfLeadingSpaces("foo"), 0) + strictEqual(YamlUtil.getNumberOfLeadingSpaces("foo "), 0) + }) +}) + +suite("Test YamlUtil - isValueMultiline", () => { + test("when text starts with '-' should return true", () => { + const text = + '- foo: bar\n' + + ' bar: baz' + equal(YamlUtil.isValueMultiline(text), true) }) -}) \ No newline at end of file +}) + +suite("Test YamlUtil - transformMultilineValue()", () => { + const yamlutil = new YamlUtil() + yamlutil.settings.getIndent = function () { + return 2 + } + test("Should prepend spaces on each line", () => { + const text = + '- foo: bar\n' + + ' bar: baz' + const expected = + ' - foo: bar\n' + + ' bar: baz' + strictEqual(yamlutil.transformMultilineValue(text), expected) + }) + test("When text ends with newline should remove trailing indent", () => { + const text = + '- foo: bar\n' + + ' bar: baz\n' + const expected = + ' - foo: bar\n' + + ' bar: baz\n' + strictEqual(yamlutil.transformMultilineValue(text), expected) + }) +}) diff --git a/src/util/file-util.ts b/src/util/file-util.ts index c28b5a6..26be84f 100644 --- a/src/util/file-util.ts +++ b/src/util/file-util.ts @@ -1,4 +1,4 @@ -import * as fs from "fs" +import { readFileSync } from "fs" import { sync } from "glob" import { Settings } from "../settings" @@ -20,6 +20,6 @@ export class FileUtil { } readFile(file: string) { - return fs.readFileSync(file, this.encoding).toString() + return readFileSync(file, this.encoding).toString() } } diff --git a/src/util/sort-util.ts b/src/util/sort-util.ts index 72e170d..a00af60 100644 --- a/src/util/sort-util.ts +++ b/src/util/sort-util.ts @@ -35,12 +35,4 @@ export class SortUtil { } return this.localeSort(a, b) } - - getSortingAlgorithm() { - if (this.custom > 0 && this.settings.getUseCustomSortRecursively()) { - return this.customSort - } else { - return this.localeSort - } - } } \ No newline at end of file diff --git a/src/util/yaml-util.ts b/src/util/yaml-util.ts index 93f4172..9949dd1 100644 --- a/src/util/yaml-util.ts +++ b/src/util/yaml-util.ts @@ -1,6 +1,6 @@ import { addNewLineBeforeKeywordsUpToLevelN, prependWhitespacesOnEachLine, replaceTabsWithSpaces } from "../lib" import { Settings } from "../settings" -import * as vscode from "vscode" +import { window } from "vscode" import { JsYamlAdapter } from "../adapter/js-yaml-adapter" import { Severity, VsCodeAdapter } from "../adapter/vs-code-adapter" @@ -13,6 +13,26 @@ export class YamlUtil { this.jsyamladapter = new JsYamlAdapter(settings) } + static getNumberOfLeadingSpaces(text: string): number { + if (!text.startsWith(" ")) { + return 0 + } else { + return text.search(/\S/) + } + } + + static isValueMultiline(text: string) { + return (!text.startsWith("|") && text.includes(":")) || text.startsWith("-") + } + + transformMultilineValue(text: string) { + let result = prependWhitespacesOnEachLine(text, this.settings.getIndent()) + if (text.endsWith("\n")) { + result = removeTrailingCharacters(result, this.settings.getIndent()) + } + return result + } + sortYaml(unsortedYaml: string, customSort = 0): string | null { try { const unsortedYamlWithoutTabs = replaceTabsWithSpaces(unsortedYaml, this.settings.getIndent()) @@ -26,17 +46,12 @@ export class YamlUtil { keywords.forEach(key => { if (doc[key]) { - let sortedSubYaml = this.jsyamladapter.dumpYaml(doc[key], true, customSort, this.settings) - if ((sortedSubYaml.includes(":") && !sortedSubYaml.startsWith("|")) || sortedSubYaml.startsWith("-")) { - // when key cotains more than one line, we need some transformation: - // add a new line and indent each line some spaces - sortedSubYaml = prependWhitespacesOnEachLine(sortedSubYaml, this.settings.getIndent()) - if (sortedSubYaml.endsWith("\n")) { - sortedSubYaml = removeTrailingCharacters(sortedSubYaml, this.settings.getIndent()) - } - sortedYaml += key + ":\n" + sortedSubYaml + "\n" + let sortedSubYaml = this.jsyamladapter.dumpYaml(doc[key], true, customSort) + if (YamlUtil.isValueMultiline(sortedSubYaml)) { + sortedSubYaml = this.transformMultilineValue(sortedSubYaml) + sortedYaml += `${key}:\n${sortedSubYaml}\n` } else { - sortedYaml += key + ": " + sortedSubYaml + "\n" + sortedYaml += `${key}: ${sortedSubYaml}\n` } // delete key from yaml delete doc[key] @@ -45,7 +60,7 @@ export class YamlUtil { } // either sort whole yaml or sort the rest of the yaml (which can be empty) and add it to the sortedYaml - sortedYaml += this.jsyamladapter.dumpYaml(doc, true, customSort, this.settings) + sortedYaml += this.jsyamladapter.dumpYaml(doc, true, customSort) if (this.settings.getEmptyLinesUntilLevel() > 0) { sortedYaml = addNewLineBeforeKeywordsUpToLevelN(this.settings.getEmptyLinesUntilLevel(), this.settings.getIndent(), sortedYaml) @@ -56,7 +71,7 @@ export class YamlUtil { return sortedYaml } catch (e) { if (e instanceof Error) { - vscode.window.showErrorMessage("Keys could not be resorted: " + e.message) + window.showErrorMessage(`Keys could not be resorted: ${e.message}`) } return null } @@ -71,18 +86,18 @@ export class YamlUtil { formatYaml(yaml: string, useLeadingDashes: boolean): string | null { try { const comments = findComments(yaml) - let doc = new JsYamlAdapter().dumpYaml(this.jsyamladapter.load(yaml) as string, false, 0, this.settings) + let doc = new JsYamlAdapter().dumpYaml(this.jsyamladapter.load(yaml) as string, false, 0) doc = applyComments(doc, comments) if (useLeadingDashes) { - doc = "---\n" + doc + doc = `---\n${doc}` } if (this.settings.getNotifySuccess()) { - vscode.window.showInformationMessage("Yaml formatted successfully") + window.showInformationMessage("Yaml formatted successfully") } return doc } catch (e) { if (e instanceof Error) { - vscode.window.showErrorMessage("Yaml could not be formatted: " + e.message) + window.showErrorMessage(`Yaml could not be formatted: ${e.message}`) } return null } @@ -115,9 +130,9 @@ export function removeTrailingCharacters(text: string, count = 1): string { * @param {string} text Text which should represent a valid yaml selection to sort. * @returns {boolean} true, if selection is missing something */ -export function isSelectionInvalid(text: string): boolean { +export function isSelectionInvalid(selection: string): boolean { // remove trailing whitespaces, to check for things like 'text: ' - text = text.trim() + const text = selection.trim() const notValidEndingCharacters = [":", "|", ">"] if (notValidEndingCharacters.includes(text.charAt(text.length - 1))) { return true @@ -133,9 +148,9 @@ export function isSelectionInvalid(text: string): boolean { } } -export function validateTextRange(text: string) { +export function validateTextRange(textRange: string) { // remove trailing whitespaces, to check for things like 'text: ' - text = text.trim() + const text = textRange.trim() const notValidEndingCharacters = [":", "|", ">"] if (notValidEndingCharacters.includes(text.charAt(text.length - 1))) { throw new Error("YAML selection is invalid. Check the ending of your selection.") @@ -153,11 +168,11 @@ export function findComments(text: string): Map { for (let i = 0; i < lines.length; i++) { let comment = "" while (/^ *#/.test(lines[i])) { - comment += lines[i] + "\n" + comment += `${lines[i]}\n` i++ } comment = comment.replace(/\n$/, "") - if (comment != "") { + if (comment !== "") { if (i < lines.length) { comments.set(comment, lines[i]) } else { @@ -170,29 +185,30 @@ export function findComments(text: string): Map { } export function applyComments(text: string, comments: Map): string { + let result = text for (const [comment, line] of comments) { - if (line == '') { - text += "\n" + comment + if (line === '') { + result += `\n${comment}` } else { - let index = text.search(line) - if (index == -1) { + let index = result.search(line) + if (index === -1) { const trimmedLine = line.trim() - index = text.search(trimmedLine) - if (index != -1) { - const textHelper = text.slice(0, index) + index = result.search(trimmedLine) + if (index !== -1) { + const textHelper = result.slice(0, index) const lastLineBreak = textHelper.lastIndexOf('\n') // remove trailing whitespaces const textBeforeComment = textHelper.slice(0, lastLineBreak) let textAfterComment = textHelper.slice(lastLineBreak) - textAfterComment += text.slice(text.search(trimmedLine)) - text = textBeforeComment + "\n" + comment.split("\n")[0] + textAfterComment + textAfterComment += result.slice(result.search(trimmedLine)) + result = `${textBeforeComment}\n${comment.split("\n")[0]}${textAfterComment}` } } else { - text = text.slice(0, index) + comment + "\n" + text.slice(text.search(line)) + result = `${result.slice(0, index)}${comment}\n${result.slice(result.search(line))}` } } } - return text + return result } /** @@ -212,9 +228,9 @@ export function splitYaml(multipleYamls: string): [string] { * If set to false, it will add an empty array element at the beginning of the output. * @returns {[string]} Array of yaml delimiters. */ -export function getDelimiters(multipleYamls: string, isSelectionEmpty: boolean, useLeadingDashes: boolean): RegExpMatchArray { +export function getDelimiters(yamls: string, isSelectionEmpty: boolean, useLeadingDashes: boolean): RegExpMatchArray { // remove empty lines - multipleYamls = multipleYamls.trim() + let multipleYamls = yamls.trim() multipleYamls = multipleYamls.replace(/^\n/, "") let delimiters = multipleYamls.match(/^---.*/gm) if (!delimiters) { @@ -222,7 +238,7 @@ export function getDelimiters(multipleYamls: string, isSelectionEmpty: boolean, } // append line break to every delimiter - delimiters = delimiters.map((delimiter) => "\n" + delimiter + "\n") as RegExpMatchArray + delimiters = delimiters.map((delimiter) => `\n${delimiter}\n`) as RegExpMatchArray if (delimiters) { if (isSelectionEmpty) {