Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow multiple matches for one yaml file with requestCustomSchema #272

Merged
merged 1 commit into from
Jan 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions src/schema-extension-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,20 +71,22 @@ class SchemaExtensionAPI implements ExtensionAPI {
}

/**
* Call requestSchema for each provider and find the first one who reports he can provide the schema.
* Call requestSchema for each provider and finds all matches.
*
* @param {string} resource
* @returns {string} the schema uri
*/
public requestCustomSchema(resource: string): string {
public requestCustomSchema(resource: string): string[] {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to server should we keep compatibility by returning string or string[]?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part is just internal API, it needs to be string[] now so that it can find all matching schema contributes for the given file

const matches = [];
for (let customKey of Object.keys(this._customSchemaContributors)) {
const contributor = this._customSchemaContributors[customKey];
const uri = contributor.requestSchema(resource);

if (uri) {
return uri;
matches.push(uri);
}
}
return matches;
}

/**
Expand Down
63 changes: 52 additions & 11 deletions test/schemaProvider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ describe('Tests for schema provider feature', () => {
it('completion, hover, and validation work with registered contributor schema', async () => {
const client = await activate(docUri);

client.registerContributor(SCHEMA, onRequestSchemaURI, onRequestSchemaContent);
client.registerContributor(SCHEMA, onRequestSchema1URI, onRequestSchema1Content);
await testCompletion(docUri, new vscode.Position(0, 0), {
items: [
{
Expand Down Expand Up @@ -44,7 +44,7 @@ describe('Tests for schema provider feature', () => {

it('Validation occurs automatically with registered contributor schema', async () => {
const client = await activate(hoverUri);
client.registerContributor(SCHEMA, onRequestSchemaURI, onRequestSchemaContent);
client.registerContributor(SCHEMA, onRequestSchema1URI, onRequestSchema1Content);

await sleep(2000); // Wait for the diagnostics to compute on this file
await testDiagnostics(hoverUri, [
Expand All @@ -54,10 +54,33 @@ describe('Tests for schema provider feature', () => {
severity: 0
}
]);
});

it('Multiple contributors can match one file', async () => {
const client = await activate(docUri);
client.registerContributor(SCHEMA2, onRequestSchema2URI, onRequestSchema2Content);
client.registerContributor(SCHEMA3, onRequestSchema3URI, onRequestSchema3Content);

await testCompletion(docUri, new vscode.Position(0, 0), {
items: [
{
label: "apple",
kind: 9,
documentation: "An apple"
},
{
label: "version",
kind: 9,
documentation: "A stringy string string"
}
]
});
});
});

const SCHEMA = "myschema";
const SCHEMA2 = "myschema2";
const SCHEMA3 = "myschema3";

const schemaJSON = JSON.stringify({
type: "object",
Expand All @@ -72,21 +95,39 @@ const schemaJSON = JSON.stringify({
}
});

function onRequestSchemaURI(resource: string): string | undefined {
if (resource.endsWith('.yaml')) {
function onRequestSchema1URI(resource: string): string | undefined {
if (resource.endsWith('completion.yaml') || resource.endsWith('basic.yaml')) {
return `${SCHEMA}://schema/porter`;
}
return undefined;
}

function onRequestSchemaContent(schemaUri: string): string | undefined {
const parsedUri = Uri.parse(schemaUri);
if (parsedUri.scheme !== SCHEMA) {
return undefined;
}
if (!parsedUri.path || !parsedUri.path.startsWith('/')) {
return undefined;
function onRequestSchema1Content(schemaUri: string): string | undefined {
return schemaJSON;
}

const schemaJSON2 = JSON.stringify({
"type": "object",
"properties": {
"apple": {
"type": "string",
"description": "An apple",
}
}
});

function onRequestSchema2URI(resource: string): string | undefined {
return `${SCHEMA2}://schema/porter`;
}

function onRequestSchema2Content(schemaUri: string): string | undefined {
return schemaJSON2;
}

function onRequestSchema3URI(resource: string): string | undefined {
return `${SCHEMA3}://schema/porter`;
}

function onRequestSchema3Content(schemaUri: string): string | undefined {
return schemaJSON;
}