From f01d6fbd3e1e31eb30681b2d45f3f160831a09aa Mon Sep 17 00:00:00 2001 From: Marios Ntoulas Date: Mon, 16 Mar 2026 11:27:47 +0200 Subject: [PATCH 1/2] test: add failing unit test for local references --- server/src/test/definition.test.ts | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/server/src/test/definition.test.ts b/server/src/test/definition.test.ts index 4229aca..0a11227 100644 --- a/server/src/test/definition.test.ts +++ b/server/src/test/definition.test.ts @@ -98,4 +98,32 @@ suite('Definition Test Suite', () => { // ^--- value {} is at character 27 assert.strictEqual(link.targetRange.start.character, 27); }); + + test('Should return a definition for local $ref', () => { + const text = '{"foo": { "$ref": "#/a" }, "a": 42}'; + const uri = URI.file(path.resolve('/abs/path/local.jref')).toString(); + const doc = TextDocument.create(uri, 'jref', 1, text); + + const { symbols } = analyze(text); + + const context = { + documents: new MockTextDocuments([doc]) as any, + documentSymbols: new WeakMap([[doc, symbols]]), + }; + + const params: DefinitionParams = { + textDocument: { uri: uri }, + position: { line: 0, character: 19 }, // Inside "#/a" + }; + + const result = onDefinition(params, context); + + assert.ok(result && result.length > 0); + const link = result![0]; + assert.ok(link.targetUri.endsWith('local.jref')); + // Target range should point to the "a" property value in schema.jref + // {"foo": { "$ref": "#/a" }, "a": 42} + // ^--- value 42 is at character 33 + assert.strictEqual(link.targetRange.start.character, 33); + }); }); From 42cb1a95860113861c2876b7c40097b730ae8f92 Mon Sep 17 00:00:00 2001 From: Marios Ntoulas Date: Mon, 16 Mar 2026 12:01:13 +0200 Subject: [PATCH 2/2] fix(definition): handle local references (#19) - Added 'isLocalReference' to ensure local references are resolved to the current document - Added a testfile with local references - Fixed the unit test assertion to match the go to definition offset --- server/src/providers/definition.ts | 7 +++++++ server/src/test/definition.test.ts | 4 ++-- testfiles/local-references.jref | 8 ++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 testfiles/local-references.jref diff --git a/server/src/providers/definition.ts b/server/src/providers/definition.ts index 9b965db..0aa37ca 100644 --- a/server/src/providers/definition.ts +++ b/server/src/providers/definition.ts @@ -53,7 +53,14 @@ function createDefinitionLink( ]; } +function isLocalReference(targetPath: string): boolean { + return targetPath.startsWith('#'); +} + function resolveTargetUriAndFragment(documentUri: string, targetPath: string) { + if (isLocalReference(targetPath)) { + return { targetUri: documentUri, fragment: targetPath.slice(1) }; + } const uri = URI.parse(targetPath); const currentDir = path.dirname(URI.parse(documentUri).fsPath); const absolutePath = path.resolve(currentDir, uri.path.slice(1)); diff --git a/server/src/test/definition.test.ts b/server/src/test/definition.test.ts index 0a11227..5a86db6 100644 --- a/server/src/test/definition.test.ts +++ b/server/src/test/definition.test.ts @@ -123,7 +123,7 @@ suite('Definition Test Suite', () => { assert.ok(link.targetUri.endsWith('local.jref')); // Target range should point to the "a" property value in schema.jref // {"foo": { "$ref": "#/a" }, "a": 42} - // ^--- value 42 is at character 33 - assert.strictEqual(link.targetRange.start.character, 33); + // ^--- value 42 is at character 32 + assert.strictEqual(link.targetRange.start.character, 32); }); }); diff --git a/testfiles/local-references.jref b/testfiles/local-references.jref new file mode 100644 index 0000000..b145c2c --- /dev/null +++ b/testfiles/local-references.jref @@ -0,0 +1,8 @@ +{ + "foo": { "$ref": "#/a" }, + "a": 42, + "bar": { "$ref": "#/bob/age" }, + "bob": { + "age": 20 + } +} \ No newline at end of file