From 417a68eb6b46d49e9b39fab4171e1eb85c087b99 Mon Sep 17 00:00:00 2001 From: Gorkem Ercan Date: Wed, 18 May 2022 10:02:35 -0400 Subject: [PATCH] Schemas through files.association settings are enabled (#714) --- .../handlers/settingsHandlers.ts | 15 ++- src/yamlSettings.ts | 4 + test/settingsHandlers.test.ts | 91 ++++++++++++++++++- 3 files changed, 108 insertions(+), 2 deletions(-) diff --git a/src/languageserver/handlers/settingsHandlers.ts b/src/languageserver/handlers/settingsHandlers.ts index 411bdcda..5be99371 100644 --- a/src/languageserver/handlers/settingsHandlers.ts +++ b/src/languageserver/handlers/settingsHandlers.ts @@ -43,6 +43,7 @@ export class SettingsHandler { { section: 'http' }, { section: '[yaml]' }, { section: 'editor' }, + { section: 'files' }, ]); const settings: Settings = { yaml: config[0], @@ -52,6 +53,7 @@ export class SettingsHandler { }, yamlEditor: config[2], vscodeEditor: config[3], + files: config[4], }; await this.setConfiguration(settings); } @@ -83,6 +85,13 @@ export class SettingsHandler { this.yamlSettings.schemaStoreUrl = settings.yaml.schemaStore.url; } } + if (settings.files?.associations) { + for (const [ext, languageId] of Object.entries(settings.files.associations)) { + if (languageId === 'yaml') { + this.yamlSettings.fileExtensions.push(ext); + } + } + } this.yamlSettings.yamlVersion = settings.yaml.yamlVersion ?? '1.2'; if (settings.yaml.format) { @@ -205,7 +214,11 @@ export class SettingsHandler { for (const fileMatch in schema.fileMatch) { const currFileMatch: string = schema.fileMatch[fileMatch]; // If the schema is for files with a YAML extension, save the schema association - if (currFileMatch.indexOf('.yml') !== -1 || currFileMatch.indexOf('.yaml') !== -1) { + if ( + this.yamlSettings.fileExtensions.findIndex((value) => { + return currFileMatch.indexOf(value) > -1; + }) > -1 + ) { languageSettings.schemas.push({ uri: schema.url, fileMatch: [currFileMatch], diff --git a/src/yamlSettings.ts b/src/yamlSettings.ts index 2d9a0d58..445194d0 100644 --- a/src/yamlSettings.ts +++ b/src/yamlSettings.ts @@ -40,6 +40,9 @@ export interface Settings { vscodeEditor: { detectIndentation: boolean; }; + files: { + associations: Map; + }; } export interface JSONSchemaSettings { @@ -97,6 +100,7 @@ export class SettingsState { yamlVersion: YamlVersion = '1.2'; useSchemaSelectionRequests = false; hasWsChangeWatchedFileDynamicRegistration = false; + fileExtensions: string[] = ['.yml', '.yaml']; } export class TextDocumentTestManager extends TextDocuments { diff --git a/test/settingsHandlers.test.ts b/test/settingsHandlers.test.ts index 8c4d4afa..e53f2365 100644 --- a/test/settingsHandlers.test.ts +++ b/test/settingsHandlers.test.ts @@ -77,6 +77,93 @@ describe('Settings Handlers Tests', () => { expect(connection.client.register).calledOnce; }); + describe('Settings for file associations should ', () => { + it('reflect to settings state', async () => { + const settingsHandler = new SettingsHandler( + connection, + (languageService as unknown) as LanguageService, + settingsState, + (validationHandler as unknown) as ValidationHandler, + {} as Telemetry + ); + workspaceStub.getConfiguration.resolves([{}, {}, {}, {}, { associations: { '*.bu': 'yaml' } }]); + + await settingsHandler.pullConfiguration(); + expect(settingsState.fileExtensions).to.include('*.bu'); + expect(settingsState.fileExtensions).to.include('.yml'); + expect(settingsState.fileExtensions).to.include('.yaml'); + }); + it('SettingsHandler should match patterns from file associations', async () => { + const languageServerSetup = setupLanguageService({}); + const languageService = languageServerSetup.languageService; + xhrStub.resolves({ + responseText: `{"schemas": [ + { + "name": "Butane config schema", + "description": "Schema to validate butane files for Fedora CoreOS", + "fileMatch": [ + "*.bu" + ], + "url": "https://raw.githubusercontent.com/Relativ-IT/Butane-Schemas/Release/Butane-Schema.json" + }]}`, + }); + settingsState.fileExtensions.push('*.bu'); + const settingsHandler = new SettingsHandler( + connection, + (languageService as unknown) as LanguageService, + settingsState, + (validationHandler as unknown) as ValidationHandler, + {} as Telemetry + ); + workspaceStub.getConfiguration.resolves([{}, {}, {}, {}]); + const configureSpy = sinon.stub(languageService, 'configure'); + await settingsHandler.pullConfiguration(); + configureSpy.restore(); + expect(settingsState.schemaStoreSettings).deep.include({ + uri: 'https://raw.githubusercontent.com/Relativ-IT/Butane-Schemas/Release/Butane-Schema.json', + fileMatch: ['*.bu'], + priority: SchemaPriority.SchemaStore, + name: 'Butane config schema', + description: 'Schema to validate butane files for Fedora CoreOS', + versions: undefined, + }); + }); + it('SettingsHandler should not match non-yaml files if there is no file assosication', async () => { + const languageServerSetup = setupLanguageService({}); + const languageService = languageServerSetup.languageService; + xhrStub.resolves({ + responseText: `{"schemas": [ + { + "name": "Butane config schema", + "description": "Schema to validate butane files for Fedora CoreOS", + "fileMatch": [ + "*.bu" + ], + "url": "https://raw.githubusercontent.com/Relativ-IT/Butane-Schemas/Release/Butane-Schema.json" + }]}`, + }); + const settingsHandler = new SettingsHandler( + connection, + (languageService as unknown) as LanguageService, + settingsState, + (validationHandler as unknown) as ValidationHandler, + {} as Telemetry + ); + workspaceStub.getConfiguration.resolves([{}, {}, {}, {}]); + const configureSpy = sinon.stub(languageService, 'configure'); + await settingsHandler.pullConfiguration(); + configureSpy.restore(); + expect(settingsState.schemaStoreSettings).not.deep.include({ + uri: 'https://raw.githubusercontent.com/Relativ-IT/Butane-Schemas/Release/Butane-Schema.json', + fileMatch: ['*.bu'], + priority: SchemaPriority.SchemaStore, + name: 'Butane config schema', + description: 'Schema to validate butane files for Fedora CoreOS', + versions: undefined, + }); + }); + }); + it('SettingsHandler should not modify file match patterns', async () => { const languageServerSetup = setupLanguageService({}); @@ -211,7 +298,7 @@ describe('Settings Handlers Tests', () => { (validationHandler as unknown) as ValidationHandler, {} as Telemetry ); - workspaceStub.getConfiguration.resolves([{}, {}, {}, {}]); + workspaceStub.getConfiguration.resolves([{}, {}, {}, {}, {}]); await settingsHandler.pullConfiguration(); @@ -220,6 +307,7 @@ describe('Settings Handlers Tests', () => { { section: 'http' }, { section: '[yaml]' }, { section: 'editor' }, + { section: 'files' }, ]); }); it('should set schemaStoreSettings to empty when schemaStore is disabled', async () => { @@ -259,6 +347,7 @@ describe('Settings Handlers Tests', () => { { section: 'http' }, { section: '[yaml]' }, { section: 'editor' }, + { section: 'files' }, ]); }); });