diff --git a/CHANGELOG.md b/CHANGELOG.md index 0af27a0..60b5c7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,14 +9,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.15.1] - Unreleased +### Added: + +- Diagnostics: Ensure at least one plugin is enabled + ### Changed: - Snippets: `devproxy-plugin-open-api-spec-generator` - OpenApiSpecGeneratorPlugin config section - Snippets: All snippets that reference schemas updated to use `v0.24.0` schema +- Diagnostics: Refactored code to be more readable and maintainable +- Diagnostics: Improved config section check ### Fixed: - Snippets: Fix invalid Json in `devproxy-config-file` +- Diagnostics: Fixed update schema check in proxy files ## [0.14.0] - 2024-11-27 diff --git a/README.md b/README.md index 25032d4..93d695c 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ The following sections describe the features that the extension contributes to V - Check for missing `configSection` when defined in plugin instance - Check that schema matches installed version of Dev Proxy - Check that reporters are placed after plugins +- Check that at least one plugin is enabled ### Editor Actions diff --git a/src/diagnostics.ts b/src/diagnostics.ts index c352aef..ec99099 100644 --- a/src/diagnostics.ts +++ b/src/diagnostics.ts @@ -2,9 +2,9 @@ import * as vscode from 'vscode'; import parse from "json-to-ast"; import { pluginSnippets } from "./constants"; import { getASTNode, getRangeFromASTNode } from "./helpers"; -import { DevProxyInstall } from './types'; +import { DevProxyInstall, PluginConfig } from "./types"; -export const updateConfigDiagnostics = ( +export const updateConfigFileDiagnostics = ( context: vscode.ExtensionContext, document: vscode.TextDocument, collection: vscode.DiagnosticCollection, @@ -14,145 +14,16 @@ export const updateConfigDiagnostics = ( return; } const diagnostics: vscode.Diagnostic[] = []; - const documentNode = parse(document.getText()) as parse.ObjectNode; + const documentNode = getObjectNodeFromDocument(document); + const pluginsNode = getPluginsNode(documentNode); - // check if schema version is compatible checkSchemaCompatibility(documentNode, devProxyInstall, diagnostics); - - // check validity of plugins - const pluginsNode = getASTNode( - documentNode.children, - 'Identifier', - 'plugins' - ); - if ( - pluginsNode && - (pluginsNode.value as parse.ArrayNode).children.length !== 0 - ) { - const pluginNodes = (pluginsNode.value as parse.ArrayNode) - .children as parse.ObjectNode[]; - - // check for plugins - if (pluginNodes.length === 0) { - diagnostics.push( - new vscode.Diagnostic( - getRangeFromASTNode(pluginsNode), - 'Add at least one plugin', - vscode.DiagnosticSeverity.Error - ) - ); - } - - // check if we have any plugins that contain the name reporter in the plugins node - const reporterIndex = pluginNodes.findIndex((pluginNode: parse.ObjectNode) => { - const pluginNameNode = getASTNode( - pluginNode.children, - 'Identifier', - 'name' - ); - const pluginName = (pluginNameNode?.value as parse.LiteralNode) - .value as string; - return pluginName.toLowerCase().includes('reporter'); - }); - - if (reporterIndex !== -1) { - // check if we have any more plugins after the reporter plugin - const pluginsAfterReporter = pluginNodes.slice(reporterIndex + 1); - // if we do, add a warning to the reporter plugin stating that it should be the last plugin - if (pluginsAfterReporter.length > 0) { - // check if there are any plugins after the reporter plugin that are not reporters - const pluginAfterReporter = pluginsAfterReporter.find((pluginNode: parse.ObjectNode) => { - const pluginNameNode = getASTNode( - pluginNode.children, - 'Identifier', - 'name' - ); - const pluginName = (pluginNameNode?.value as parse.LiteralNode) - .value as string; - return !pluginName.toLowerCase().includes('reporter'); - }); - // if there are, add a warning to the reporter plugin - if (pluginAfterReporter) { - const diagnostic = new vscode.Diagnostic( - getRangeFromASTNode(pluginNodes[reporterIndex]), - 'Reporters should be placed after other plugins.', - vscode.DiagnosticSeverity.Warning - ); - diagnostics.push(diagnostic); - } - } - } - - // does the plugin have a config section? - pluginNodes.forEach((pluginNode: parse.ObjectNode) => { - const pluginNameNode = getASTNode( - pluginNode.children, - 'Identifier', - 'name' - ); - const pluginName = (pluginNameNode?.value as parse.LiteralNode) - .value as string; - const enabledNode = getASTNode( - pluginNode.children, - 'Identifier', - 'enabled' - ); - const isEnabled = (enabledNode?.value as parse.LiteralNode) - .value as boolean; - const pluginSnippet = pluginSnippets[pluginName]; - const requiresConfig = pluginSnippet.config - ? pluginSnippet.config.required - : false; - - if (requiresConfig) { - // check to see if the plugin has a config section - const configSectionNode = getASTNode( - pluginNode.children, - 'Identifier', - 'configSection' - ); - if (!configSectionNode) { - // there is no config section defined on the plugin instance - diagnostics.push( - new vscode.Diagnostic( - getRangeFromASTNode(pluginNode), - `${pluginName} requires a config section.`, - isEnabled - ? vscode.DiagnosticSeverity.Error - : vscode.DiagnosticSeverity.Warning - ) - ); - } else { - // check to see if the config section is in the document - const configSectionName = ( - configSectionNode.value as parse.LiteralNode - ).value as string; - const configSection = getASTNode( - documentNode.children, - 'Identifier', - configSectionName - ); - - if (!configSection) { - diagnostics.push( - new vscode.Diagnostic( - getRangeFromASTNode(configSectionNode.value), - `${configSectionName} config section is missing. Use '${pluginSnippet.config?.name}' snippet to create one.`, - isEnabled - ? vscode.DiagnosticSeverity.Error - : vscode.DiagnosticSeverity.Warning - ) - ); - } - } - } - }); - } + checkPlugins(pluginsNode, diagnostics, documentNode); collection.set(document.uri, diagnostics); }; -export const updateDiagnostics = ( +export const updateFileDiagnostics = ( context: vscode.ExtensionContext, document: vscode.TextDocument, collection: vscode.DiagnosticCollection, @@ -163,15 +34,14 @@ export const updateDiagnostics = ( } const diagnostics: vscode.Diagnostic[] = []; - const documentNode = parse(document.getText()) as parse.ObjectNode; + const documentNode = getObjectNodeFromDocument(document); - // check if schema version is compatible checkSchemaCompatibility(documentNode, devProxyInstall, diagnostics); collection.set(document.uri, diagnostics); }; -export const checkSchemaCompatibility = (documentNode: parse.ObjectNode, devProxyInstall: DevProxyInstall, diagnostics: vscode.Diagnostic[]) => { +const checkSchemaCompatibility = (documentNode: parse.ObjectNode, devProxyInstall: DevProxyInstall, diagnostics: vscode.Diagnostic[]) => { const schemaNode = getASTNode(documentNode.children, 'Identifier', '$schema'); if (schemaNode) { const schemaValue = (schemaNode.value as parse.LiteralNode).value as string; @@ -187,3 +57,182 @@ export const checkSchemaCompatibility = (documentNode: parse.ObjectNode, devProx } } }; + +const checkPlugins = (pluginsNode: parse.PropertyNode | undefined, diagnostics: vscode.Diagnostic[], documentNode: parse.ObjectNode) => { + if (pluginsNode && + (pluginsNode.value as parse.ArrayNode)) { + const pluginNodes = (pluginsNode.value as parse.ArrayNode) + .children as parse.ObjectNode[]; + + checkAtLeastOneEnabledPlugin(pluginNodes, diagnostics, pluginsNode); + warnOnReporterPosition(pluginNodes, diagnostics); + validatePluginConfigurations(pluginNodes, diagnostics, documentNode); + } +}; + +const validatePluginConfigurations = (pluginNodes: parse.ObjectNode[], diagnostics: vscode.Diagnostic[], documentNode: parse.ObjectNode) => { + pluginNodes.forEach((pluginNode: parse.ObjectNode) => { + const pluginNameNode = getASTNode( + pluginNode.children, + 'Identifier', + 'name' + ); + const pluginName = (pluginNameNode?.value as parse.LiteralNode) + .value as string; + const enabledNode = getASTNode( + pluginNode.children, + 'Identifier', + 'enabled' + ); + const isEnabled = (enabledNode?.value as parse.LiteralNode) + .value as boolean; + const pluginSnippet = pluginSnippets[pluginName]; + + checkPluginConfiguration(pluginNode, diagnostics, pluginName, isEnabled, documentNode, pluginSnippet); + }); +}; + +const warnOnReporterPosition = (pluginNodes: parse.ObjectNode[], diagnostics: vscode.Diagnostic[]) => { + const reporterIndex = pluginNodes.findIndex((pluginNode: parse.ObjectNode) => { + const pluginNameNode = getASTNode( + pluginNode.children, + 'Identifier', + 'name' + ); + const pluginName = (pluginNameNode?.value as parse.LiteralNode) + .value as string; + return pluginName.toLowerCase().includes('reporter'); + }); + + if (reporterIndex !== -1) { + // check if we have any more plugins after the reporter plugin + const pluginsAfterReporter = pluginNodes.slice(reporterIndex + 1); + // if we do, add a warning to the reporter plugin stating that it should be the last plugin + if (pluginsAfterReporter.length > 0) { + // check if there are any plugins after the reporter plugin that are not reporters + const pluginAfterReporter = pluginsAfterReporter.find((pluginNode: parse.ObjectNode) => { + const pluginNameNode = getASTNode( + pluginNode.children, + 'Identifier', + 'name' + ); + const pluginName = (pluginNameNode?.value as parse.LiteralNode) + .value as string; + return !pluginName.toLowerCase().includes('reporter'); + }); + // if there are, add a warning to the reporter plugin + if (pluginAfterReporter) { + const diagnostic = new vscode.Diagnostic( + getRangeFromASTNode(pluginNodes[reporterIndex]), + 'Reporters should be placed after other plugins.', + vscode.DiagnosticSeverity.Warning + ); + diagnostics.push(diagnostic); + } + } + } +}; + +const checkAtLeastOneEnabledPlugin = (pluginNodes: parse.ObjectNode[], diagnostics: vscode.Diagnostic[], pluginsNode: parse.PropertyNode) => { + // check if there are any plugins + if (pluginNodes.length === 0) { + diagnostics.push( + new vscode.Diagnostic( + getRangeFromASTNode(pluginsNode), + 'Add at least one plugin', + vscode.DiagnosticSeverity.Error + ) + ); + } else { + // check if there are any enabled plugins + const enabledPlugins = pluginNodes.filter((pluginNode: parse.ObjectNode) => { + const enabledNode = getASTNode( + pluginNode.children, + 'Identifier', + 'enabled' + ); + return (enabledNode?.value as parse.LiteralNode).value as boolean; + }); + if (enabledPlugins.length === 0) { + diagnostics.push( + new vscode.Diagnostic( + getRangeFromASTNode(pluginsNode), + 'At least one plugin must be enabled', + vscode.DiagnosticSeverity.Error + ) + ); + } + } +}; + +const checkPluginConfiguration = (pluginNode: parse.ObjectNode, diagnostics: vscode.Diagnostic[], pluginName: string, isEnabled: boolean, documentNode: parse.ObjectNode, pluginSnippet: { instance: string; config?: PluginConfig; }) => { + const configSectionNode = getASTNode( + pluginNode.children, + 'Identifier', + 'configSection' + ); + + // if the plugin does not require a config section, we should not have one + if (!pluginSnippet.config && configSectionNode) { + diagnostics.push( + new vscode.Diagnostic( + getRangeFromASTNode(configSectionNode), + `${pluginName} does not require a config section.`, + isEnabled + ? vscode.DiagnosticSeverity.Error + : vscode.DiagnosticSeverity.Warning + ) + ); + return; + } + + // if there is no config section defined on the plugin, we should have one if the plugin requires it + if (!configSectionNode) { + if (pluginSnippet.config?.required) { + diagnostics.push( + new vscode.Diagnostic( + getRangeFromASTNode(pluginNode), + `${pluginName} requires a config section.`, + isEnabled + ? vscode.DiagnosticSeverity.Error + : vscode.DiagnosticSeverity.Warning + ) + ); + } + } else { + // if there is a config section defined on the plugin, we should have the config section defined in the document + const configSectionName = ( + configSectionNode.value as parse.LiteralNode + ).value as string; + const configSection = getASTNode( + documentNode.children, + 'Identifier', + configSectionName + ); + + if (!configSection) { + diagnostics.push( + new vscode.Diagnostic( + getRangeFromASTNode(configSectionNode.value), + `${configSectionName} config section is missing. Use '${pluginSnippet.config?.name}' snippet to create one.`, + isEnabled + ? vscode.DiagnosticSeverity.Error + : vscode.DiagnosticSeverity.Warning + ) + ); + } + } +}; + +const getPluginsNode = (documentNode: parse.ObjectNode) => { + return getASTNode( + documentNode.children, + 'Identifier', + 'plugins' + ); +}; + +const getObjectNodeFromDocument = (document: vscode.TextDocument): parse.ObjectNode => { + return parse(document.getText()) as parse.ObjectNode; +}; + diff --git a/src/documents.ts b/src/documents.ts index 043b2d8..5419106 100644 --- a/src/documents.ts +++ b/src/documents.ts @@ -1,12 +1,12 @@ import * as vscode from 'vscode'; import { isConfigFile, isProxyFile } from './helpers'; -import { updateConfigDiagnostics, updateDiagnostics } from './diagnostics'; +import { updateFileDiagnostics, updateConfigFileDiagnostics } from './diagnostics'; export const registerDocumentListeners = (context: vscode.ExtensionContext, collection: vscode.DiagnosticCollection) => { context.subscriptions.push( vscode.workspace.onDidOpenTextDocument(document => { if (isProxyFile(document)) { - updateDiagnostics(context, document, collection); + updateFileDiagnostics(context, document, collection); vscode.commands.executeCommand('setContext', 'isDevProxyConfigFile', false); } if (!isConfigFile(document)) { @@ -14,25 +14,25 @@ export const registerDocumentListeners = (context: vscode.ExtensionContext, coll return; } else { vscode.commands.executeCommand('setContext', 'isDevProxyConfigFile', true); - updateConfigDiagnostics(context, document, collection); + updateConfigFileDiagnostics(context, document, collection); } }) ); context.subscriptions.push( vscode.workspace.onDidChangeTextDocument(event => { - if (!isConfigFile(event.document) || !isProxyFile(event.document)) { + if (!isConfigFile(event.document) && !isProxyFile(event.document)) { collection.delete(event.document.uri); vscode.commands.executeCommand('setContext', 'isDevProxyConfigFile', false); return; } if (isConfigFile(event.document)) { - updateConfigDiagnostics(context, event.document, collection); + updateConfigFileDiagnostics(context, event.document, collection); vscode.commands.executeCommand('setContext', 'isDevProxyConfigFile', true); return; } if (isProxyFile(event.document)) { - updateDiagnostics(context, event.document, collection); + updateFileDiagnostics(context, event.document, collection); vscode.commands.executeCommand('setContext', 'isDevProxyConfigFile', false); } }) diff --git a/src/test/examples/config-incorrect-schema-with-plugins.json b/src/test/examples/config-incorrect-schema-with-plugins.json index 5e4be70..d41feb5 100644 --- a/src/test/examples/config-incorrect-schema-with-plugins.json +++ b/src/test/examples/config-incorrect-schema-with-plugins.json @@ -1,4 +1,4 @@ { - "$schema": "https://raw.githubusercontent.com/microsoft/dev-proxy/main/schemas/v0.14.1/mockresponseplugin.schema.json", + "$schema": "https://raw.githubusercontent.com/microsoft/dev-proxy/main/schemas/v0.24.0/mockresponseplugin.schema.json", "plugins": {} } \ No newline at end of file diff --git a/src/test/examples/config-incorrect-schema.json b/src/test/examples/config-incorrect-schema.json index 1257e7c..d6d1d12 100644 --- a/src/test/examples/config-incorrect-schema.json +++ b/src/test/examples/config-incorrect-schema.json @@ -1,3 +1,3 @@ { - "$schema": "https://raw.githubusercontent.com/microsoft/dev-proxy/main/schemas/v0.14.1/mockresponseplugin.schema.json" + "$schema": "https://raw.githubusercontent.com/microsoft/dev-proxy/main/schemas/v0.24.0/mockresponseplugin.schema.json" } \ No newline at end of file diff --git a/src/test/examples/config-plugin-config-missing-disabled.json b/src/test/examples/config-plugin-config-missing-disabled.json index 1869363..21c2c05 100644 --- a/src/test/examples/config-plugin-config-missing-disabled.json +++ b/src/test/examples/config-plugin-config-missing-disabled.json @@ -1,6 +1,11 @@ { - "$schema": "https://raw.githubusercontent.com/microsoft/dev-proxy/main/schemas/v0.14.1/rc.schema.json", + "$schema": "https://raw.githubusercontent.com/microsoft/dev-proxy/main/schemas/v0.24.0/rc.schema.json", "plugins": [ + { + "name": "LatencyPlugin", + "enabled": true, + "pluginPath": "~appFolder/plugins/dev-proxy-plugins.dll" + }, { "name": "GenericRandomErrorPlugin", "enabled": false, diff --git a/src/test/examples/config-plugin-config-missing.json b/src/test/examples/config-plugin-config-missing.json index 7b8b46d..c51f922 100644 --- a/src/test/examples/config-plugin-config-missing.json +++ b/src/test/examples/config-plugin-config-missing.json @@ -1,5 +1,5 @@ { - "$schema": "https://raw.githubusercontent.com/microsoft/dev-proxy/main/schemas/v0.14.1/rc.schema.json", + "$schema": "https://raw.githubusercontent.com/microsoft/dev-proxy/main/schemas/v0.24.0/rc.schema.json", "plugins": [ { "name": "GenericRandomErrorPlugin", diff --git a/src/test/examples/config-plugin-config-required-disabled.json b/src/test/examples/config-plugin-config-required-disabled.json index f9daa28..a5f120c 100644 --- a/src/test/examples/config-plugin-config-required-disabled.json +++ b/src/test/examples/config-plugin-config-required-disabled.json @@ -1,6 +1,11 @@ { - "$schema": "https://raw.githubusercontent.com/microsoft/dev-proxy/main/schemas/v0.14.1/rc.schema.json", + "$schema": "https://raw.githubusercontent.com/microsoft/dev-proxy/main/schemas/v0.24.0/rc.schema.json", "plugins": [ + { + "name": "LatencyPlugin", + "enabled": true, + "pluginPath": "~appFolder/plugins/dev-proxy-plugins.dll" + }, { "name": "GenericRandomErrorPlugin", "enabled": false, diff --git a/src/test/examples/config-plugin-config-required.json b/src/test/examples/config-plugin-config-required.json index fed9a1e..996b0f4 100644 --- a/src/test/examples/config-plugin-config-required.json +++ b/src/test/examples/config-plugin-config-required.json @@ -1,5 +1,5 @@ { - "$schema": "https://raw.githubusercontent.com/microsoft/dev-proxy/main/schemas/v0.14.1/rc.schema.json", + "$schema": "https://raw.githubusercontent.com/microsoft/dev-proxy/main/schemas/v0.24.0/rc.schema.json", "plugins": [ { "name": "GenericRandomErrorPlugin", diff --git a/src/test/examples/config-plugins-codelens.json b/src/test/examples/config-plugins-codelens.json index 0c5857b..794d1c0 100644 --- a/src/test/examples/config-plugins-codelens.json +++ b/src/test/examples/config-plugins-codelens.json @@ -1,5 +1,5 @@ { - "$schema": "https://raw.githubusercontent.com/microsoft/dev-proxy/main/schemas/v0.14.1/rc.schema.json", + "$schema": "https://raw.githubusercontent.com/microsoft/dev-proxy/main/schemas/v0.24.0/rc.schema.json", "plugins": [ { "name": "CachingGuidancePlugin", diff --git a/src/test/examples/config-schema-mismatch.json b/src/test/examples/config-schema-mismatch.json index 1a35d4e..d7ec73e 100644 --- a/src/test/examples/config-schema-mismatch.json +++ b/src/test/examples/config-schema-mismatch.json @@ -1,4 +1,4 @@ { - "$schema": "https://raw.githubusercontent.com/microsoft/dev-proxy/main/schemas/v0.14.1/rc.schema.json", + "$schema": "https://raw.githubusercontent.com/microsoft/dev-proxy/main/schemas/v0.24.0/rc.schema.json", "plugins": [] } \ No newline at end of file diff --git a/src/test/examples/config-schema-version.json b/src/test/examples/config-schema-version.json index 1a35d4e..036e8e1 100644 --- a/src/test/examples/config-schema-version.json +++ b/src/test/examples/config-schema-version.json @@ -1,4 +1,10 @@ { - "$schema": "https://raw.githubusercontent.com/microsoft/dev-proxy/main/schemas/v0.14.1/rc.schema.json", - "plugins": [] + "$schema": "https://raw.githubusercontent.com/microsoft/dev-proxy/main/schemas/v0.24.0/rc.schema.json", + "plugins": [ + { + "name": "LatencyPlugin", + "enabled": true, + "pluginPath": "~appFolder/plugins/dev-proxy-plugins.dll" + } + ] } \ No newline at end of file diff --git a/src/test/examples/config-schema.json b/src/test/examples/config-schema.json index 1a35d4e..d7ec73e 100644 --- a/src/test/examples/config-schema.json +++ b/src/test/examples/config-schema.json @@ -1,4 +1,4 @@ { - "$schema": "https://raw.githubusercontent.com/microsoft/dev-proxy/main/schemas/v0.14.1/rc.schema.json", + "$schema": "https://raw.githubusercontent.com/microsoft/dev-proxy/main/schemas/v0.24.0/rc.schema.json", "plugins": [] } \ No newline at end of file diff --git a/src/test/examples/config-urls-to-watch-required.json b/src/test/examples/config-urls-to-watch-required.json index 7db2a39..d5b7cf9 100644 --- a/src/test/examples/config-urls-to-watch-required.json +++ b/src/test/examples/config-urls-to-watch-required.json @@ -1,5 +1,5 @@ { - "$schema": "https://raw.githubusercontent.com/microsoft/dev-proxy/main/schemas/v0.14.1/rc.schema.json", + "$schema": "https://raw.githubusercontent.com/microsoft/dev-proxy/main/schemas/v0.24.0/rc.schema.json", "plugins": [], "urlsToWatch": [] } diff --git a/src/test/examples/devproxyrc.json b/src/test/examples/devproxyrc.json index 1a35d4e..d7ec73e 100644 --- a/src/test/examples/devproxyrc.json +++ b/src/test/examples/devproxyrc.json @@ -1,4 +1,4 @@ { - "$schema": "https://raw.githubusercontent.com/microsoft/dev-proxy/main/schemas/v0.14.1/rc.schema.json", + "$schema": "https://raw.githubusercontent.com/microsoft/dev-proxy/main/schemas/v0.24.0/rc.schema.json", "plugins": [] } \ No newline at end of file diff --git a/src/test/examples/mock-schema.json b/src/test/examples/mock-schema.json index 9b1bd40..7cda0aa 100644 --- a/src/test/examples/mock-schema.json +++ b/src/test/examples/mock-schema.json @@ -1,4 +1,4 @@ { - "$schema": "https://raw.githubusercontent.com/microsoft/dev-proxy/main/schemas/v0.14.1/mockresponseplugin.schema.json", + "$schema": "https://raw.githubusercontent.com/microsoft/dev-proxy/main/schemas/v0.24.0/mockresponseplugin.schema.json", "mocks": [] } \ No newline at end of file diff --git a/src/test/extension.test.ts b/src/test/extension.test.ts index 8c56294..ab35dfa 100644 --- a/src/test/extension.test.ts +++ b/src/test/extension.test.ts @@ -1,14 +1,10 @@ import * as assert from 'assert'; import * as vscode from 'vscode'; -import * as fs from 'fs'; import { - getASTNode, - getStartPositionFromASTNode, isConfigFile, sleep, } from '../helpers'; import * as path from 'path'; -import parse from 'json-to-ast'; import { createCodeLensForPluginNodes } from '../codelens'; import { handleStartNotification } from '../notifications'; import { handleStatusBarUpdate, statusBarLoop } from '../statusbar'; @@ -25,7 +21,7 @@ export const testDevProxyInstall: DevProxyInstall = { outdatedVersion: '0.14.1', platform: 'win32', version: '0.14.1', -}; +}; suite('extension', () => { @@ -142,9 +138,12 @@ suite('plugins', () => { message: 'GenericRandomErrorPlugin requires a config section.', severity: vscode.DiagnosticSeverity.Error, }; + const diagnostic = diagnostics.find((diagnostic) => { + return diagnostic.message === expected.message; + }); const actual = { - message: diagnostics[0]?.message, - severity: diagnostics[0]?.severity, + message: diagnostic?.message, + severity: diagnostic?.severity, }; assert.deepStrictEqual(actual, expected); }); @@ -160,9 +159,12 @@ suite('plugins', () => { message: 'GenericRandomErrorPlugin requires a config section.', severity: vscode.DiagnosticSeverity.Warning, }; + const diagnostic = diagnostics.find((diagnostic) => { + return diagnostic.message === expected.message; + }); const actual = { - message: diagnostics[0]?.message, - severity: diagnostics[0]?.severity, + message: diagnostic?.message, + severity: diagnostic?.severity, }; assert.deepStrictEqual(actual, expected); }); @@ -179,9 +181,12 @@ suite('plugins', () => { "genericRandomErrorPlugin config section is missing. Use 'devproxy-plugin-generic-random-error-config' snippet to create one.", severity: vscode.DiagnosticSeverity.Error, }; + const diagnostic = diagnostics.find((diagnostic) => { + return diagnostic.message === expected.message; + }); const actual = { - message: diagnostics[0]?.message, - severity: diagnostics[0]?.severity, + message: diagnostic?.message, + severity: diagnostic?.severity, }; assert.deepStrictEqual(actual, expected); }); @@ -198,9 +203,12 @@ suite('plugins', () => { "genericRandomErrorPlugin config section is missing. Use 'devproxy-plugin-generic-random-error-config' snippet to create one.", severity: vscode.DiagnosticSeverity.Warning, }; + const diagnostic = diagnostics.find((diagnostic) => { + return diagnostic.message === expected.message; + }); const actual = { - message: diagnostics[0]?.message, - severity: diagnostics[0]?.severity, + message: diagnostic?.message, + severity: diagnostic?.severity, }; assert.deepStrictEqual(actual, expected); }); @@ -489,7 +497,7 @@ suite('schema', () => { isRunning: false, platform: 'win32', outdatedVersion: '', - version: '0.14.1', + version: '0.24.0', } as DevProxyInstall); const fileName = 'config-schema-version.json';