diff --git a/src/languageservice/services/dollarUtils.ts b/src/languageservice/services/dollarUtils.ts index 8620da8c5..122f11b12 100644 --- a/src/languageservice/services/dollarUtils.ts +++ b/src/languageservice/services/dollarUtils.ts @@ -12,7 +12,7 @@ import { JSONDocument } from '../parser/jsonParser07'; * @param doc */ export function getDollarSchema(doc: SingleYAMLDocument | JSONDocument): string | undefined { - if (doc instanceof SingleYAMLDocument && doc.root && doc.root.type === 'object') { + if (doc.root && doc.root.type === 'object') { let dollarSchema = doc.root.properties['$schema']; dollarSchema = typeof dollarSchema === 'string' ? dollarSchema.trim() : undefined; if (typeof dollarSchema === 'string') { diff --git a/test/fixtures/sample-dollar-schema.json b/test/fixtures/sample-dollar-schema.json new file mode 100644 index 000000000..22f9ecb73 --- /dev/null +++ b/test/fixtures/sample-dollar-schema.json @@ -0,0 +1,8 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "properties": { + "dollar-schema": { + "type":"string" + } + } +} diff --git a/test/schema.test.ts b/test/schema.test.ts index 1747b1c40..4ab901ebe 100644 --- a/test/schema.test.ts +++ b/test/schema.test.ts @@ -590,6 +590,8 @@ describe('JSON Schema', () => { // eslint-disable-next-line @typescript-eslint/no-var-requires const schemaModelineSample = path.join(__dirname, './fixtures/sample-modeline.json'); // eslint-disable-next-line @typescript-eslint/no-var-requires + const schemaDollarSample = path.join(__dirname, './fixtures/sample-dollar-schema.json'); + // eslint-disable-next-line @typescript-eslint/no-var-requires const schemaDefaultSnippetSample = require(path.join(__dirname, './fixtures/defaultSnippets-const-if-else.json')); const languageSettingsSetup = new ServiceSetup().withCompletion(); @@ -615,12 +617,42 @@ describe('JSON Schema', () => { }); languageService.configure(languageSettingsSetup.languageSettings); languageService.registerCustomSchemaProvider((uri: string) => Promise.resolve(uri)); - const testTextDocument = setupTextDocument(`# yaml-language-server: $schema=${schemaModelineSample}\n\n`); + const testTextDocument = setupTextDocument( + `# yaml-language-server: $schema=${schemaModelineSample}\n$schema: ${schemaDollarSample}\n\n` + ); const result = await languageService.doComplete(testTextDocument, Position.create(1, 0), false); assert.strictEqual(result.items.length, 1); assert.strictEqual(result.items[0].label, 'modeline'); }); + it('Explicit $schema takes precedence over all other lower priority schemas', async () => { + languageSettingsSetup + .withSchemaFileMatch({ + fileMatch: ['test.yaml'], + uri: TEST_URI, + priority: SchemaPriority.SchemaStore, + schema: schemaStoreSample, + }) + .withSchemaFileMatch({ + fileMatch: ['test.yaml'], + uri: TEST_URI, + priority: SchemaPriority.SchemaAssociation, + schema: schemaAssociationSample, + }) + .withSchemaFileMatch({ + fileMatch: ['test.yaml'], + uri: TEST_URI, + priority: SchemaPriority.Settings, + schema: schemaSettingsSample, + }); + languageService.configure(languageSettingsSetup.languageSettings); + languageService.registerCustomSchemaProvider((uri: string) => Promise.resolve(uri)); + const testTextDocument = setupTextDocument(`$schema: ${schemaDollarSample}\n\n`); + const result = await languageService.doComplete(testTextDocument, Position.create(1, 0), false); + assert.strictEqual(result.items.length, 1); + assert.strictEqual(result.items[0].label, 'dollar-schema'); + }); + it('Manually setting schema takes precendence over all other lower priority schemas', async () => { languageSettingsSetup .withSchemaFileMatch({