diff --git a/src/__tests__/__fixtures__/schemas.ts b/src/__tests__/__fixtures__/schemas.ts index 4b5f8ac..4cb2769 100644 --- a/src/__tests__/__fixtures__/schemas.ts +++ b/src/__tests__/__fixtures__/schemas.ts @@ -25,6 +25,7 @@ export const testSchema2 = { description: "an elegant string", }, }, + required: ["foo"], additionalProperties: false, }, oneOfEg: { @@ -71,7 +72,7 @@ export const testSchema2 = { type: "boolean", }, }, - required: ["foo", "object.foo"], + required: ["foo", "object"], additionalProperties: false, definitions: { fancyObject: { diff --git a/src/__tests__/json-validation.spec.ts b/src/__tests__/json-validation.spec.ts index 0695ce7..2e00a15 100644 --- a/src/__tests__/json-validation.spec.ts +++ b/src/__tests__/json-validation.spec.ts @@ -17,7 +17,7 @@ const getErrors = (jsonString: string, schema?: JSONSchema7) => { }; const expectErrors = ( jsonString: string, - errors: [from: number, to: number, message: string][], + errors: [from: number | undefined, to: number | undefined, message: string][], schema?: JSONSchema7 ) => { expect(getErrors(jsonString, schema)).toEqual( @@ -42,7 +42,9 @@ describe("json-validation", () => { ]); }); it("should not handle invalid json", () => { - expectErrors('{"foo": "example" "bar": 123}', []); + expectErrors('{"foo": "example" "bar": 123}', [ + [undefined, undefined, "Expected `object` but received `null`"], + ]); }); it("should provide range for invalid multline json", () => { expectErrors( @@ -57,9 +59,9 @@ describe("json-validation", () => { expectErrors( `{ "foo": "example", - "object": { "foo": "true" } + "object": {} }`, - [[43, 46, "Expected property `foo` in `#/object`"]], + [[46, 48, "The required property `foo` is missing at `object`"]], testSchema2 ); }); @@ -70,7 +72,7 @@ describe("json-validation", () => { "object": { "foo": "true" }, "oneOfEg": 123 }`, - [[43, 46, 'Expected one of `"string"`, `"array"`, or `"boolean"`']], + [[80, 83, 'Expected one of `"string"`, `"array"`, or `"boolean"`']], testSchema2 ); }); @@ -81,7 +83,7 @@ describe("json-validation", () => { "object": { "foo": "true" }, "oneOfEg2": 123 }`, - [[44, 47, 'Expected one of `"string"` or `"array"`']], + [[81, 84, 'Expected one of `"string"` or `"array"`']], testSchema2 ); }); diff --git a/src/json-validation.ts b/src/json-validation.ts index 9ae1105..30b0c08 100644 --- a/src/json-validation.ts +++ b/src/json-validation.ts @@ -106,7 +106,6 @@ export class JSONValidation { try { errors = this.schema.validate(json.data); } catch {} - console.log(Array.from(json.pointers.keys())); if (!errors.length) return []; // reduce() because we want to filter out errors that don't have a pointer return errors.reduce((acc, error) => { diff --git a/src/utils/__tests__/jsonPointers.spec.ts b/src/utils/__tests__/jsonPointers.spec.ts index aada790..a0ff1ff 100644 --- a/src/utils/__tests__/jsonPointers.spec.ts +++ b/src/utils/__tests__/jsonPointers.spec.ts @@ -63,7 +63,7 @@ describe("jsonPointerForPosition for json5", () => { describe("getJsonPointers", () => { it("should return a map of all pointers for a document", () => { const state = EditorState.create({ - doc: '{"object": { "foo": true }, "bar": 123, "baz": [1,2,3]}', + doc: '{"object": { "foo": true }, "bar": 123, "baz": [1,2,3], "boop": [{"foo": true}]}', extensions: [json()], }); const pointers = getJsonPointers(state); @@ -85,12 +85,19 @@ describe("getJsonPointers", () => { valueFrom: 47, valueTo: 54, }); - expect(pointers.get("/baz/0")).toEqual({ - keyFrom: 40, - keyTo: 45, - valueFrom: 47, - valueTo: 55, + expect(pointers.get("/boop/0")).toEqual({ + keyFrom: 65, + keyTo: 78, + valueFrom: 78, + valueTo: 79, }); + // TODO: return pointers for all array indexes, not just objects + // expect(pointers.get("/baz/0")).toEqual({ + // keyFrom: 40, + // keyTo: 45, + // valueFrom: 47, + // valueTo: 55, + // }); }); }); diff --git a/src/utils/__tests__/parseJSONDocument.spec.ts b/src/utils/__tests__/parseJSONDocument.spec.ts index cc44376..f4f76e4 100644 --- a/src/utils/__tests__/parseJSONDocument.spec.ts +++ b/src/utils/__tests__/parseJSONDocument.spec.ts @@ -8,6 +8,7 @@ describe("parseJSONDocument", () => { const doc = parseJSONDocument(`{"object": { "foo": true }, "bar": 123}`); expect(doc.data).toEqual({ object: { foo: true }, bar: 123 }); expect(Array.from(doc.pointers.keys())).toEqual([ + "", "/object", "/object/foo", "/bar", @@ -20,6 +21,7 @@ describe("parseJSON5Document", () => { const doc = parseJSON5Document(`{'obj"ect': { foo: true }, "bar": 123}`); expect(doc.data).toEqual({ ['obj"ect']: { foo: true }, bar: 123 }); expect(Array.from(doc.pointers.keys())).toEqual([ + "", '/obj"ect', '/obj"ect/foo', "/bar", diff --git a/src/utils/jsonPointers.ts b/src/utils/jsonPointers.ts index d7c1072..7ee6187 100644 --- a/src/utils/jsonPointers.ts +++ b/src/utils/jsonPointers.ts @@ -34,6 +34,7 @@ export function getJsonPointerAt(docText: Text, node: SyntaxNode): string { } } path.unshift(""); + return path.join("/"); } @@ -61,15 +62,7 @@ export const getJsonPointers = ( const pointers: JSONPointersMap = new Map(); json.iterate({ enter: (type: SyntaxNodeRef) => { - if ( - type.name === "PropertyName" || - type.name === "Object" - // type.name === "Number" || - // type.name === "String" || - // type.name === "Boolean" || - // type.name === "Null" || - // type.name === "Array" - ) { + if (type.name === "PropertyName" || type.name === "Object") { const pointer = getJsonPointerAt(state.doc, type.node); const { from: keyFrom, to: keyTo } = type.node;