Skip to content

Commit

Permalink
fix autocomplete for schema with top level $ref
Browse files Browse the repository at this point in the history
  • Loading branch information
imolorhe committed May 29, 2024
1 parent 5e95143 commit 2c97572
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 9 deletions.
10 changes: 10 additions & 0 deletions src/__tests__/__fixtures__/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@ export const testSchema2 = {
foo: {
type: "string",
},
stringWithDefault: {
type: "string",
description: "a string with a default value",
default: "defaultString",
},
bracedStringDefault: {
type: "string",
description: "a string with a default value containing braces",
default: "✨ A message from %{whom}: ✨",
},
object: {
type: "object",
properties: {
Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/__helpers__/completion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export async function expectCompletion(
} = {}
) {
let cur = doc.indexOf("|"),
currentSchema = conf?.schema || testSchema2;
currentSchema = conf?.schema ?? testSchema2;
doc = doc.slice(0, cur) + doc.slice(cur + 1);

let state = EditorState.create({
Expand Down
70 changes: 68 additions & 2 deletions src/__tests__/json-completion.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { describe, it } from "vitest";

import { expectCompletion } from "./__helpers__/completion.js";
import { MODES } from "../constants.js";
import { testSchema3 } from "./__fixtures__/schemas.js";

describe.each([
{
Expand Down Expand Up @@ -46,6 +47,35 @@ describe.each([
},
],
},
{
name: "include defaults for string when available",
mode: MODES.JSON,
docs: ['{ "stringWithDefault| }'],
expectedResults: [
{
label: "stringWithDefault",
type: "property",
detail: "string",
info: "a string with a default value",
template: '"stringWithDefault": "${defaultString}"',
},
],
},
// TODO: fix the default template with braces: https://discuss.codemirror.net/t/inserting-literal-via-snippets/8136/4
// {
// name: "include defaults for string with braces",
// mode: MODES.JSON,
// docs: ['{ "bracedStringDefault| }'],
// expectedResults: [
// {
// label: "bracedStringDefault",
// type: "property",
// detail: "string",
// info: "a string with a default value containing braces",
// template: '"bracedStringDefault": "${✨ A message from %{whom}: ✨}"',
// },
// ],
// },
{
name: "include defaults for enum when available",
mode: MODES.JSON,
Expand Down Expand Up @@ -221,6 +251,20 @@ describe.each([
],
},
// TODO: completion for array of objects should enhance the template
{
name: "autocomplete for array of objects with filter",
mode: MODES.JSON,
docs: ['{ "arrayOfObjects": [ { "f|" } ] }'],
expectedResults: [
{
detail: "string",
info: "",
label: "foo",
template: '"foo": "#{}"',
type: "property",
},
],
},
{
name: "autocomplete for array of objects with items",
mode: MODES.JSON,
Expand Down Expand Up @@ -298,6 +342,28 @@ describe.each([
},
],
},
{
name: "autocomplete for a schema with top level $ref",
mode: MODES.JSON,
docs: ['{ "| }'],
expectedResults: [
{
type: "property",
detail: "string",
info: "",
label: "foo",
template: '"foo": "#{}"',
},
{
type: "property",
detail: "number",
info: "",
label: "bar",
template: '"bar": #{0}',
},
],
schema: testSchema3,
},
// JSON5
{
name: "return bare property key when no quotes are used",
Expand Down Expand Up @@ -653,8 +719,8 @@ describe.each([
},
],
},
])("jsonCompletion", ({ name, docs, mode, expectedResults }) => {
])("jsonCompletion", ({ name, docs, mode, expectedResults, schema }) => {
it.each(docs)(`${name} (mode: ${mode})`, async (doc) => {
await expectCompletion(doc, expectedResults, { mode });
await expectCompletion(doc, expectedResults, { mode, schema });
});
});
10 changes: 4 additions & 6 deletions src/json-completion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ export class JSONCompletion {
this.mode = opts.mode ?? MODES.JSON;
}
public doComplete(ctx: CompletionContext) {
this.schema = getJSONSchema(ctx.state)!;
const s = getJSONSchema(ctx.state)!;
this.schema = this.expandSchemaProperty(s, s) ?? s;
if (!this.schema) {
// todo: should we even do anything without schema
// without taking over the existing mode responsibilties?
Expand Down Expand Up @@ -484,13 +485,10 @@ export class JSONCompletion {
switch (this.mode) {
case MODES.JSON5:
return `'${prf}{${value}}'`;
break;
case MODES.YAML:
return `${prf}{${value}}`;
break;
default:
return `"${prf}{${value}}"`;
break;
}
}

Expand Down Expand Up @@ -847,8 +845,8 @@ export class JSONCompletion {
return [subSchema as JSONSchema7];
}

private expandSchemaProperty(
property: JSONSchema7Definition,
private expandSchemaProperty<T extends JSONSchema7Definition>(
property: T,
schema: JSONSchema7
) {
if (typeof property === "object" && property.$ref) {
Expand Down

0 comments on commit 2c97572

Please sign in to comment.