diff --git a/packages/ansible-language-server/src/interfaces/extensionSettings.ts b/packages/ansible-language-server/src/interfaces/extensionSettings.ts index 2bc3d799d..996142dd2 100644 --- a/packages/ansible-language-server/src/interfaces/extensionSettings.ts +++ b/packages/ansible-language-server/src/interfaces/extensionSettings.ts @@ -10,7 +10,12 @@ export type IContainerEngine = "auto" | "podman" | "docker"; export type IPullPolicy = "always" | "missing" | "never" | "tag"; -export interface ExtensionSettingsWithDescription { +interface ExtensionSettingsWithDescriptionBase { + [key: string]: SettingsEntry | string | boolean; +} + +export interface ExtensionSettingsWithDescription + extends ExtensionSettingsWithDescriptionBase { ansible: AnsibleSettingsWithDescription; completion: CompletionSettingsWithDescription; validation: ValidationSettingsWithDescription; @@ -18,7 +23,18 @@ export interface ExtensionSettingsWithDescription { python: PythonSettingsWithDescription; } -export interface ExtensionSettings { +export interface ExtensionSettingsType { + [name: string]: + | ExtensionSettingsType + | string + | boolean + | string[] + | IContainerEngine + | IPullPolicy + | IVolumeMounts[]; +} + +export interface ExtensionSettings extends ExtensionSettingsType { ansible: { path: string; useFullyQualifiedCollectionNames: boolean; @@ -45,7 +61,7 @@ export interface ExtensionSettings { /** * Interface for execution environment settings */ -interface ExecutionEnvironmentSettingsWithDescription { +interface ExecutionEnvironmentSettingsWithDescription extends SettingsEntry { containerEngine: { default: IContainerEngine; description: string; @@ -73,7 +89,23 @@ export interface IVolumeMounts { /** * Interface for ansible settings */ -interface AnsibleSettingsWithDescription { +export interface SettingsEntry { + [name: string]: + | { + default: string | boolean; + description: string; + } + | SettingsEntry + | string + | boolean + | Array<{ + src: { default: string; description: string }; + dest: { default: string; description: string }; + options: { default: string; description: string }; + }>; +} + +interface AnsibleSettingsWithDescription extends SettingsEntry { path: { default: string; description: string; @@ -87,7 +119,7 @@ interface AnsibleSettingsWithDescription { /** * Interface for python settings */ -interface PythonSettingsWithDescription { +interface PythonSettingsWithDescription extends SettingsEntry { interpreterPath: { default: string; description: string; @@ -101,7 +133,7 @@ interface PythonSettingsWithDescription { /** * Interface for completion settings */ -interface CompletionSettingsWithDescription { +interface CompletionSettingsWithDescription extends SettingsEntry { provideRedirectModules: { default: boolean; description: string; @@ -115,7 +147,7 @@ interface CompletionSettingsWithDescription { /** * Interface for validation settings */ -interface ValidationSettingsWithDescription { +interface ValidationSettingsWithDescription extends SettingsEntry { enabled: { default: boolean; description: string; diff --git a/packages/ansible-language-server/src/services/ansibleConfig.ts b/packages/ansible-language-server/src/services/ansibleConfig.ts index aafc782bf..8fec75d27 100644 --- a/packages/ansible-language-server/src/services/ansibleConfig.ts +++ b/packages/ansible-language-server/src/services/ansibleConfig.ts @@ -5,6 +5,7 @@ import { URI } from "vscode-uri"; import { Connection } from "vscode-languageserver"; import { WorkspaceFolderContext } from "./workspaceManager"; import { CommandRunner } from "../utils/commandRunner"; +import { ansibleMetaDataType } from "../utils/getAnsibleMetaData"; export class AnsibleConfig { private connection: Connection; @@ -13,7 +14,7 @@ export class AnsibleConfig { private _module_locations: string[] = []; private _ansible_location = ""; private _default_host_list: string[] = []; - private _ansible_meta_data = {}; + private _ansible_meta_data = {}; // ini data constructor(connection: Connection, context: WorkspaceFolderContext) { this.connection = connection; @@ -127,7 +128,7 @@ export class AnsibleConfig { return this._ansible_location; } - public get ansible_meta_data(): object { + public get ansible_meta_data(): ansibleMetaDataType { return this._ansible_meta_data; } } diff --git a/packages/ansible-language-server/src/services/ansibleLint.ts b/packages/ansible-language-server/src/services/ansibleLint.ts index b46125494..517bc797d 100644 --- a/packages/ansible-language-server/src/services/ansibleLint.ts +++ b/packages/ansible-language-server/src/services/ansibleLint.ts @@ -126,7 +126,7 @@ export class AnsibleLint { progressTracker.done(); this.connection.window.showErrorMessage(execError.message); - return; + return new Map(); } } else { const exceptionString = `Exception in AnsibleLint service: ${JSON.stringify( @@ -136,7 +136,7 @@ export class AnsibleLint { progressTracker.done(); this.connection.console.error(exceptionString); this.connection.window.showErrorMessage(exceptionString); - return; + return new Map(); } } @@ -266,7 +266,7 @@ export class AnsibleLint { return configPath; } - get ansibleLintConfigFilePath(): string { + get ansibleLintConfigFilePath(): string | undefined { return this._ansibleLintConfigFilePath; } } diff --git a/packages/ansible-language-server/src/services/docsLibrary.ts b/packages/ansible-language-server/src/services/docsLibrary.ts index fcef0882a..d4c4188fb 100644 --- a/packages/ansible-language-server/src/services/docsLibrary.ts +++ b/packages/ansible-language-server/src/services/docsLibrary.ts @@ -86,7 +86,9 @@ export class DocsLibrary { documentUri?: string, ): Promise<[IModuleMetadata | undefined, string | undefined]> { // support playbook adjacent collections - const playbookDirectory = URI.parse(documentUri).path.split(path.sep); + const playbookDirectory = URI.parse(String(documentUri)).path.split( + path.sep, + ); playbookDirectory.pop(); playbookDirectory.push("collections"); diff --git a/packages/ansible-language-server/src/services/executionEnvironment.ts b/packages/ansible-language-server/src/services/executionEnvironment.ts index f74bbdd97..d7d228fee 100644 --- a/packages/ansible-language-server/src/services/executionEnvironment.ts +++ b/packages/ansible-language-server/src/services/executionEnvironment.ts @@ -15,7 +15,7 @@ import { import { IVolumeMounts } from "../interfaces/extensionSettings"; export class ExecutionEnvironment { - public isServiceInitialized: boolean; + public isServiceInitialized: boolean = false; private settings: ExtensionSettings; private connection: Connection; private context: WorkspaceFolderContext; diff --git a/packages/ansible-language-server/src/services/settingsManager.ts b/packages/ansible-language-server/src/services/settingsManager.ts index 7db092920..fab7e7c28 100644 --- a/packages/ansible-language-server/src/services/settingsManager.ts +++ b/packages/ansible-language-server/src/services/settingsManager.ts @@ -4,6 +4,7 @@ import { DidChangeConfigurationParams } from "vscode-languageserver-protocol"; import { ExtensionSettingsWithDescription, ExtensionSettings, + SettingsEntry, } from "../interfaces/extensionSettings"; export class SettingsManager { @@ -130,7 +131,7 @@ export class SettingsManager { // Structure the settings similar to the ExtensionSettings interface for usage in the code private defaultSettings: ExtensionSettings = this._settingsAdjustment( _.cloneDeep(this.defaultSettingsWithDescription), - ); + ) as unknown as ExtensionSettings; public globalSettings: ExtensionSettings = this.defaultSettings; @@ -223,18 +224,24 @@ export class SettingsManager { * @param settingsObject - settings object with `default` and `description` as keys * @returns settings - object with a structure similar to ExtensionSettings interface */ - private _settingsAdjustment(settingsObject) { + private _settingsAdjustment( + settingsObject: ExtensionSettingsWithDescription | SettingsEntry, + ): ExtensionSettingsWithDescription { for (const key in settingsObject) { const value = settingsObject[key]; - if (value && typeof value === "object") { - if (value.default !== undefined) { + if (value && typeof value === "object" && !Array.isArray(value)) { + if ( + Object.hasOwn(value, "default") && + value.default !== undefined && + typeof value.default != "object" + ) { settingsObject[key] = value.default; } else { this._settingsAdjustment(value); } } } - return settingsObject; + return settingsObject as ExtensionSettingsWithDescription; } } diff --git a/packages/ansible-language-server/src/utils/getAnsibleMetaData.ts b/packages/ansible-language-server/src/utils/getAnsibleMetaData.ts index fef235172..bc3d9ba7b 100644 --- a/packages/ansible-language-server/src/utils/getAnsibleMetaData.ts +++ b/packages/ansible-language-server/src/utils/getAnsibleMetaData.ts @@ -5,20 +5,38 @@ import { CommandRunner } from "./commandRunner"; import * as child_process from "child_process"; let context: WorkspaceFolderContext; -let connection: Connection; +let connection: Connection | undefined; + +export interface ansibleMetaDataEntryType { + [name: string]: + | { + [name: string]: string | string[] | undefined | object[]; + } + | string + | string[] + | object[] + | undefined; +} + +export interface ansibleMetaDataType { + "ansible information"?: ansibleMetaDataEntryType; + "python information"?: ansibleMetaDataEntryType; + "ansible-lint information"?: ansibleMetaDataEntryType; + "execution environment information"?: ansibleMetaDataEntryType | undefined; +} export async function getAnsibleMetaData( contextLocal: WorkspaceFolderContext, - connectionLocal: Connection, -) { + connectionLocal: Connection | undefined, +): Promise { context = contextLocal; connection = connectionLocal; - const ansibleMetaData = {}; - - ansibleMetaData["ansible information"] = await getAnsibleInfo(); - ansibleMetaData["python information"] = await getPythonInfo(); - ansibleMetaData["ansible-lint information"] = await getAnsibleLintInfo(); + const ansibleMetaData: ansibleMetaDataType = { + "ansible information": await getAnsibleInfo(), + "python information": await getPythonInfo(), + "ansible-lint information": await getAnsibleLintInfo(), + }; const settings = await context.documentSettings.get( context.workspaceFolder.uri, @@ -32,7 +50,7 @@ export async function getAnsibleMetaData( return ansibleMetaData; } -export async function getResultsThroughCommandRunner(cmd, arg) { +export async function getResultsThroughCommandRunner(cmd: string, arg: string) { const settings = await context.documentSettings.get( context.workspaceFolder.uri, ); @@ -56,8 +74,14 @@ export async function getResultsThroughCommandRunner(cmd, arg) { return result; } } catch (error) { + let errorMessage: string; + if (error instanceof Error) { + errorMessage = error.message; + } else { + errorMessage = String(error); + } console.log( - `cmd '${cmd} ${arg}' was not executed with the following error: ' ${error.toString()}`, + `cmd '${cmd} ${arg}' was not executed with the following error: ' ${errorMessage}`, ); return undefined; } @@ -66,7 +90,7 @@ export async function getResultsThroughCommandRunner(cmd, arg) { } async function getAnsibleInfo() { - const ansibleInfo = {}; + const ansibleInfo: ansibleMetaDataEntryType = {}; const ansibleVersionObj = (await context.ansibleConfig).ansible_meta_data; const ansibleVersionObjKeys = Object.keys(ansibleVersionObj); @@ -76,21 +100,25 @@ async function getAnsibleInfo() { return ansibleInfo; } - let ansibleCoreVersion; + let ansibleCoreVersion: string[] = []; if (ansibleVersionObjKeys[0].includes(" [")) { ansibleCoreVersion = ansibleVersionObjKeys[0].split(" ["); } else { ansibleCoreVersion = ansibleVersionObjKeys[0].split(" "); } ansibleInfo["core version"] = ansibleCoreVersion[1] - .slice(0, -1) - .split(" ") - .pop() - .trim(); + ?.slice(0, -1) + ?.split(" ") + ?.pop() + ?.trim(); ansibleInfo["location"] = (await context.ansibleConfig).ansible_location; - ansibleInfo["config file path"] = ansibleVersionObj["config file"]; + if ("config file" in ansibleVersionObj) { + ansibleInfo["config file path"] = ansibleVersionObj[ + "config file" + ] as string; + } ansibleInfo["collections location"] = ( await context.ansibleConfig @@ -108,7 +136,7 @@ async function getAnsibleInfo() { } async function getPythonInfo() { - const pythonInfo = {}; + const pythonInfo: ansibleMetaDataEntryType = {}; const pythonVersionResult = await getResultsThroughCommandRunner( "python3", @@ -118,25 +146,25 @@ async function getPythonInfo() { return pythonInfo; } - pythonInfo["version"] = pythonVersionResult.stdout - .trim() - .split(" ") - .pop() - .trim(); + pythonInfo["version"] = pythonVersionResult?.stdout + ?.trim() + ?.split(" ") + ?.pop() + ?.trim(); const pythonPathResult = await getResultsThroughCommandRunner( "python3", '-c "import sys; print(sys.executable)"', ); - pythonInfo["location"] = pythonPathResult.stdout.trim(); + pythonInfo["location"] = pythonPathResult?.stdout?.trim(); return pythonInfo; } async function getAnsibleLintInfo() { - const ansibleLintInfo = {}; + const ansibleLintInfo: ansibleMetaDataEntryType = {}; - let ansibleLintVersionResult = await getResultsThroughCommandRunner( + const ansibleLintVersionResult = await getResultsThroughCommandRunner( "ansible-lint", "--version", ); @@ -153,21 +181,20 @@ async function getAnsibleLintInfo() { // ansible-lint version reports if a newer version of the ansible-lint is available or not // along with the current version itself // so the following lines of code are to segregate the two information into to keys - ansibleLintVersionResult = ansibleLintVersionResult.stdout.trim().split("\n"); - const ansibleLintVersion = ansibleLintVersionResult[0]; - const ansibleLintUpgradeStatus = ansibleLintVersionResult[1] - ? ansibleLintVersionResult[1] - : undefined; - - ansibleLintInfo["version"] = ansibleLintVersion - .split("using")[0] + const ansibleLintVersionStdout = ansibleLintVersionResult.stdout .trim() - .split(" ") - .pop() - .trim(); - ansibleLintInfo["upgrade status"] = ansibleLintUpgradeStatus; + .split("\n"); + const ansibleLintVersion = ansibleLintVersionStdout[0]; + if (ansibleLintVersionStdout.length >= 2) { + ansibleLintInfo["upgrade status"] = ansibleLintVersionStdout[1]; + } + + ansibleLintInfo["version"] = + ansibleLintVersion?.split("using")[0]?.trim()?.split(" ")?.pop()?.trim() || + undefined; - ansibleLintInfo["location"] = ansibleLintPathResult.stdout.trim(); + ansibleLintInfo["location"] = + ansibleLintPathResult?.stdout?.trim() || undefined; ansibleLintInfo["config file path"] = context.ansibleLint.ansibleLintConfigFilePath; @@ -176,12 +203,12 @@ async function getAnsibleLintInfo() { } async function getExecutionEnvironmentInfo() { - const eeInfo = {}; + const eeInfo: ansibleMetaDataEntryType = {}; const basicDetails = (await context.executionEnvironment) .getBasicContainerAndImageDetails; - eeInfo["container engine"] = basicDetails.containerEngine; + eeInfo["container engine"] = String(basicDetails.containerEngine); eeInfo["container image"] = basicDetails.containerImage; eeInfo["container image ID"] = basicDetails.containerImageId; diff --git a/packages/ansible-language-server/test/providers/settingsManager.test.ts b/packages/ansible-language-server/test/providers/settingsManager.test.ts index 0ba5385cf..e1ec4aea3 100644 --- a/packages/ansible-language-server/test/providers/settingsManager.test.ts +++ b/packages/ansible-language-server/test/providers/settingsManager.test.ts @@ -5,36 +5,45 @@ import { } from "../../src/services/workspaceManager"; import { createTestWorkspaceManager } from "../helper"; import { ExtensionSettings } from "../../src/interfaces/extensionSettings"; +import { ConfigurationItem } from "vscode-languageclient"; -function simulateClientSettings(workspaceManager: WorkspaceManager, settings) { +function simulateClientSettings( + workspaceManager: WorkspaceManager, + settings: ConfigurationItem[] | ConfigurationItem | object, +) { workspaceManager.clientCapabilities.workspace = { configuration: true, }; workspaceManager.connection.workspace.getConfiguration = function () { - return Promise.resolve(settings); + return Promise.resolve(settings as unknown[]); }; } describe("get()", () => { describe("Merge settings from client", () => { describe("When client provides empty settings", () => { - let context: WorkspaceFolderContext; + let context: WorkspaceFolderContext | undefined; let mergedSettings: ExtensionSettings; before(async () => { const workspaceManager = createTestWorkspaceManager(); - simulateClientSettings(workspaceManager, {}); + simulateClientSettings(workspaceManager, []); context = workspaceManager.getContext(""); - mergedSettings = await context.documentSettings.get(""); + if (typeof context !== "undefined") { + mergedSettings = await context.documentSettings.get(""); + } }); it("should return default value for all settings", () => { - expect(mergedSettings).to.deep.equal( - context.documentSettings.globalSettings, - ); + expect(typeof context !== "undefined"); + if (typeof context !== "undefined") { + expect(mergedSettings).to.deep.equal( + context.documentSettings.globalSettings, + ); + } }); }); describe("When client provides partial settings", () => { - let context: WorkspaceFolderContext; + let context: WorkspaceFolderContext | undefined; let mergedSettings: ExtensionSettings; before(async () => { const workspaceManager = createTestWorkspaceManager(); @@ -42,15 +51,19 @@ describe("get()", () => { validation: { lint: { enabled: false } }, }); context = workspaceManager.getContext(""); - mergedSettings = await context.documentSettings.get(""); + if (typeof context !== "undefined") { + mergedSettings = await context.documentSettings.get(""); + } }); it("should return setting from client when defined", () => { expect(mergedSettings.validation.lint.enabled).to.equal(false); }); it("should return default value otherwise", () => { - expect(mergedSettings.validation.lint.path).to.equal( - context.documentSettings.globalSettings.validation.lint.path, - ); + if (typeof context !== "undefined") { + expect(mergedSettings.validation.lint.path).to.equal( + context.documentSettings.globalSettings.validation.lint.path, + ); + } }); }); }); diff --git a/packages/ansible-language-server/test/utils/getAnsibleMetaData.test.ts b/packages/ansible-language-server/test/utils/getAnsibleMetaData.test.ts index 5fd81a614..43f860d2d 100644 --- a/packages/ansible-language-server/test/utils/getAnsibleMetaData.test.ts +++ b/packages/ansible-language-server/test/utils/getAnsibleMetaData.test.ts @@ -1,6 +1,8 @@ import { expect } from "chai"; import path = require("path"); import { + ansibleMetaDataEntryType, + ansibleMetaDataType, getAnsibleMetaData, getResultsThroughCommandRunner, } from "../../src/utils/getAnsibleMetaData"; @@ -13,7 +15,7 @@ import { } from "../helper"; function getAnsibleTestInfo() { - const ansibleInfo = {}; + const ansibleInfo: ansibleMetaDataEntryType = {}; ansibleInfo["core version"] = "."; ansibleInfo["location"] = "/ansible"; (ansibleInfo["config file path"] = path.resolve( @@ -42,14 +44,14 @@ function getAnsibleTestInfo() { } function getPythonTestInfo() { - const pythonInfo = {}; + const pythonInfo: ansibleMetaDataEntryType = {}; pythonInfo["version"] = "."; pythonInfo["location"] = "/python"; return pythonInfo; } function getAnsibleLintTestInfo() { - const ansibleLintInfo = {}; + const ansibleLintInfo: ansibleMetaDataEntryType = {}; ansibleLintInfo["version"] = "."; ansibleLintInfo["upgrade status"] = "A new version"; // this key will be undefined (but the key will be present) because the value only gets updated based on the ansible-lint version used ansibleLintInfo["location"] = "/ansible-lint"; @@ -58,7 +60,7 @@ function getAnsibleLintTestInfo() { } function getExecutionEnvironmentTestInfo() { - const eeInfo = {}; + const eeInfo: ansibleMetaDataEntryType = {}; eeInfo["container engine"] = ["docker", "podman"]; eeInfo["container image"] = "ghcr.io/"; eeInfo["container volume mounts"] = [ @@ -97,7 +99,7 @@ function testCommands() { if (result === undefined) { expect(output).to.be.undefined; } else { - expect(output.stdout).contains(result); + expect(output?.stdout).contains(result); } }); }); @@ -111,17 +113,19 @@ describe("getAnsibleMetaData()", () => { const context = workspaceManager.getContext(fixtureFileUri); const textDoc = getDoc(fixtureFilePath); - const docSettings = context.documentSettings.get(textDoc.uri); + const docSettings = context?.documentSettings.get(textDoc.uri); - let actualAnsibleMetaData = {}; - let ansibleInfoForTest = {}; - let pythonInfoForTest = {}; - let ansibleLintInfoForTest = {}; - let executionEnvironmentInfoForTest = {}; + let actualAnsibleMetaData: ansibleMetaDataType = {}; + let ansibleInfoForTest: ansibleMetaDataEntryType = {}; + let pythonInfoForTest: ansibleMetaDataEntryType = {}; + let ansibleLintInfoForTest: ansibleMetaDataEntryType = {}; + let executionEnvironmentInfoForTest: ansibleMetaDataEntryType = {}; describe("With EE disabled", () => { before(async () => { - actualAnsibleMetaData = await getAnsibleMetaData(context, null); + if (context !== undefined) { + actualAnsibleMetaData = await getAnsibleMetaData(context, undefined); + } ansibleInfoForTest = getAnsibleTestInfo(); pythonInfoForTest = getPythonTestInfo(); ansibleLintInfoForTest = getAnsibleLintTestInfo(); @@ -129,79 +133,134 @@ describe("getAnsibleMetaData()", () => { describe("Verify ansible details", () => { it("should contain all the keys for ansible information", function () { - expect(Object.keys(ansibleInfoForTest).length).equals( - Object.keys(actualAnsibleMetaData["ansible information"]).length, - ); + if (actualAnsibleMetaData["ansible information"]) { + expect(Object.keys(ansibleInfoForTest).length).equals( + Object.keys(actualAnsibleMetaData["ansible information"]).length, + ); + } else { + expect(false); + } }); it("should have information about ansible version used", function () { - expect( - actualAnsibleMetaData["ansible information"]["core version"], - ).includes(ansibleInfoForTest["core version"]); + if (actualAnsibleMetaData["ansible information"]) { + expect( + actualAnsibleMetaData["ansible information"]["core version"], + ).includes(ansibleInfoForTest["core version"]); + } else { + expect(false); + } }); it("should have a valid ansible location", function () { - expect( - actualAnsibleMetaData["ansible information"]["location"], - ).include(ansibleInfoForTest["location"]); + if (actualAnsibleMetaData["ansible information"]) { + expect( + actualAnsibleMetaData["ansible information"]["location"], + ).include(ansibleInfoForTest["location"]); + } else { + expect(false); + } }); it("should have a valid config file location", function () { - expect( - actualAnsibleMetaData["ansible information"]["config file path"], - ).to.include(ansibleInfoForTest["config file path"]); + if (actualAnsibleMetaData["ansible information"]) { + expect( + actualAnsibleMetaData["ansible information"]["config file path"], + ).to.include(ansibleInfoForTest["config file path"]); + } else { + expect(false); + } }); it("should have a valid collections location", function () { - expect( - actualAnsibleMetaData["ansible information"]["collections location"], - ).to.include.members(ansibleInfoForTest["collections location"]); + const x = ansibleInfoForTest["collections location"]; + if (Array.isArray(x)) { + if (actualAnsibleMetaData["ansible information"]) { + expect( + actualAnsibleMetaData["ansible information"][ + "collections location" + ], + ).to.include.members(x); + } else { + expect(false); + } + } }); it("should have a valid inventory file path", function () { - expect( - actualAnsibleMetaData["ansible information"][ - "default host list path" - ], - ).to.include.members(ansibleInfoForTest["default host list path"]); + const x = ansibleInfoForTest["default host list path"]; + if (Array.isArray(x) && actualAnsibleMetaData["ansible information"]) { + expect( + actualAnsibleMetaData["ansible information"][ + "default host list path" + ], + ).to.include.members(x); + } else { + expect(false); + } }); }); describe("Verify python details", () => { it("should contain all the keys for python information", function () { - expect(Object.keys(pythonInfoForTest).length).equals( - Object.keys(actualAnsibleMetaData["python information"]).length, - ); + if (actualAnsibleMetaData["python information"]) { + expect(Object.keys(pythonInfoForTest).length).equals( + Object.keys(actualAnsibleMetaData["python information"]).length, + ); + } else { + expect(false); + } }); it("should have information about python version used", function () { - expect(actualAnsibleMetaData["python information"]["version"]).includes( - pythonInfoForTest["version"], - ); + if (actualAnsibleMetaData["python information"]) { + expect( + actualAnsibleMetaData["python information"]["version"], + ).includes(pythonInfoForTest["version"]); + } else { + expect(false); + } }); it("should have a valid python location", function () { - expect(actualAnsibleMetaData["python information"]["location"]).include( - pythonInfoForTest["location"], - ); + if (actualAnsibleMetaData["python information"]) { + expect( + actualAnsibleMetaData["python information"]["location"], + ).include(pythonInfoForTest["location"]); + } else { + expect(false); + } }); }); describe("Verify ansible-lint details", () => { it("should contain all the keys for ansible-lint information", function () { - expect(Object.keys(ansibleLintInfoForTest).length).equals( - Object.keys(actualAnsibleMetaData["ansible-lint information"]).length, - ); + if (actualAnsibleMetaData["ansible-lint information"]) { + expect(Object.keys(ansibleLintInfoForTest).length).equals( + Object.keys(actualAnsibleMetaData["ansible-lint information"]) + .length, + ); + } else { + expect(false); + } }); it("should have information about ansible-lint version used", function () { - expect( - actualAnsibleMetaData["ansible-lint information"]["version"], - ).includes(ansibleLintInfoForTest["version"]); + if (actualAnsibleMetaData["ansible-lint information"]) { + expect( + actualAnsibleMetaData["ansible-lint information"]["version"], + ).includes(ansibleLintInfoForTest["version"]); + } else { + expect(false); + } }); it("should have a valid ansible-lint location", function () { - expect( - actualAnsibleMetaData["ansible-lint information"]["location"], - ).include(ansibleLintInfoForTest["location"]); + if (actualAnsibleMetaData["ansible-lint information"]) { + expect( + actualAnsibleMetaData["ansible-lint information"]["location"], + ).include(ansibleLintInfoForTest["location"]); + } else { + expect(false); + } }); }); @@ -217,9 +276,13 @@ describe("getAnsibleMetaData()", () => { describe("With EE enabled @ee", () => { before(async () => { - await enableExecutionEnvironmentSettings(docSettings); + if (docSettings) { + await enableExecutionEnvironmentSettings(docSettings); + } - actualAnsibleMetaData = await getAnsibleMetaData(context, null); + if (context) { + actualAnsibleMetaData = await getAnsibleMetaData(context, undefined); + } ansibleInfoForTest = getAnsibleTestInfo(); pythonInfoForTest = getPythonTestInfo(); ansibleLintInfoForTest = getAnsibleLintTestInfo(); @@ -228,23 +291,35 @@ describe("getAnsibleMetaData()", () => { describe("Verify the presence of execution environment details", () => { it("should have a valid container engine", function () { - expect(executionEnvironmentInfoForTest["container engine"]).to.include( - actualAnsibleMetaData["execution environment information"][ - "container engine" - ], - ); + if (actualAnsibleMetaData["execution environment information"]) { + expect( + executionEnvironmentInfoForTest["container engine"], + ).to.include( + actualAnsibleMetaData["execution environment information"][ + "container engine" + ], + ); + } else { + expect(false); + } }); it("should have a valid container image", function () { - expect( - actualAnsibleMetaData["execution environment information"][ - "container image" - ], - ).to.include(executionEnvironmentInfoForTest["container image"]); + if (actualAnsibleMetaData["execution environment information"]) { + expect( + actualAnsibleMetaData["execution environment information"][ + "container image" + ], + ).to.include(executionEnvironmentInfoForTest["container image"]); + } else { + expect(false); + } }); after(async () => { - await disableExecutionEnvironmentSettings(docSettings); + if (docSettings) { + await disableExecutionEnvironmentSettings(docSettings); + } }); }); diff --git a/packages/ansible-language-server/test/utils/withInterpreter.test.ts b/packages/ansible-language-server/test/utils/withInterpreter.test.ts index 2dbbfa5b5..50dfef19c 100644 --- a/packages/ansible-language-server/test/utils/withInterpreter.test.ts +++ b/packages/ansible-language-server/test/utils/withInterpreter.test.ts @@ -67,6 +67,7 @@ describe("withInterpreter", () => { expectedKeys.forEach((key) => { expect(actualCommand[1]).to.haveOwnProperty(key); + expect(typeof actualCommand[1] === "object"); expect(actualCommand[1][key]).to.include(expectedEnv[key]); }); }