@@ -214,6 +214,135 @@ suite('Extension Test Suite', () => {
214214 'Sourcemeta Studio should still report metaschema errors' ) ;
215215 } ) ;
216216
217+ test ( 'Should clamp root-level lint diagnostics to first token' , async function ( ) {
218+ this . timeout ( 15000 ) ;
219+
220+ const extension = vscode . extensions . getExtension ( 'sourcemeta.sourcemeta-studio' ) ;
221+ if ( extension && ! extension . isActive ) {
222+ await extension . activate ( ) ;
223+ }
224+
225+ const fixtureDir = path . join ( __dirname , '..' , '..' , '..' , 'test' , 'vscode' , 'fixtures' ) ;
226+ const schemaPath = path . join ( fixtureDir , 'root-only-lint-schema.json' ) ;
227+
228+ const document = await vscode . workspace . openTextDocument ( vscode . Uri . file ( schemaPath ) ) ;
229+ await vscode . window . showTextDocument ( document ) ;
230+
231+ await vscode . commands . executeCommand ( 'sourcemeta-studio.openPanel' ) ;
232+
233+ await new Promise ( resolve => setTimeout ( resolve , 5000 ) ) ;
234+
235+ const diagnostics = vscode . languages . getDiagnostics ( document . uri ) ;
236+
237+ const lintDiagnostics = diagnostics . filter ( diagnostic =>
238+ diagnostic . source === 'Sourcemeta Studio (Lint)' ) ;
239+
240+ assert . ok ( lintDiagnostics . length > 0 ,
241+ 'Root-level lint issues should still produce diagnostics' ) ;
242+
243+ for ( const diagnostic of lintDiagnostics ) {
244+ assert . strictEqual ( diagnostic . range . start . line , 0 ,
245+ 'Root-level diagnostic should start at line 0' ) ;
246+ assert . strictEqual ( diagnostic . range . start . character , 0 ,
247+ 'Root-level diagnostic should start at character 0' ) ;
248+ assert . strictEqual ( diagnostic . range . end . line , 0 ,
249+ 'Root-level diagnostic should not extend beyond line 0' ) ;
250+ assert . strictEqual ( diagnostic . range . end . character , 0 ,
251+ 'Root-level diagnostic should have zero-width range' ) ;
252+ }
253+ } ) ;
254+
255+ test ( 'Should clamp root-level lint diagnostics on minified single-line files' , async function ( ) {
256+ this . timeout ( 15000 ) ;
257+
258+ const extension = vscode . extensions . getExtension ( 'sourcemeta.sourcemeta-studio' ) ;
259+ if ( extension && ! extension . isActive ) {
260+ await extension . activate ( ) ;
261+ }
262+
263+ const fixtureDir = path . join ( __dirname , '..' , '..' , '..' , 'test' , 'vscode' , 'fixtures' ) ;
264+ const schemaPath = path . join ( fixtureDir , 'minified-root-lint-schema.json' ) ;
265+
266+ const document = await vscode . workspace . openTextDocument ( vscode . Uri . file ( schemaPath ) ) ;
267+ await vscode . window . showTextDocument ( document ) ;
268+
269+ await vscode . commands . executeCommand ( 'sourcemeta-studio.openPanel' ) ;
270+
271+ await new Promise ( resolve => setTimeout ( resolve , 5000 ) ) ;
272+
273+ const diagnostics = vscode . languages . getDiagnostics ( document . uri ) ;
274+
275+ const lintDiagnostics = diagnostics . filter ( diagnostic =>
276+ diagnostic . source === 'Sourcemeta Studio (Lint)' ) ;
277+
278+ assert . ok ( lintDiagnostics . length > 0 ,
279+ 'Minified schema should still produce root-level lint diagnostics' ) ;
280+
281+ for ( const diagnostic of lintDiagnostics ) {
282+ assert . strictEqual ( diagnostic . range . start . line , 0 ,
283+ 'Root-level diagnostic should start at line 0' ) ;
284+ assert . strictEqual ( diagnostic . range . start . character , 0 ,
285+ 'Root-level diagnostic should start at character 0' ) ;
286+ assert . strictEqual ( diagnostic . range . end . line , 0 ,
287+ 'Root-level diagnostic should not extend beyond line 0' ) ;
288+ assert . strictEqual ( diagnostic . range . end . character , 0 ,
289+ 'Root-level diagnostic should have zero-width range' ) ;
290+ }
291+ } ) ;
292+
293+ test ( 'Should clamp root-level metaschema diagnostics to first token' , async function ( ) {
294+ this . timeout ( 15000 ) ;
295+
296+ const extension = vscode . extensions . getExtension ( 'sourcemeta.sourcemeta-studio' ) ;
297+ if ( extension && ! extension . isActive ) {
298+ await extension . activate ( ) ;
299+ }
300+
301+ const fixtureDir = path . join ( __dirname , '..' , '..' , '..' , 'test' , 'vscode' , 'fixtures' ) ;
302+ const schemaPath = path . join ( fixtureDir , 'invalid-metaschema.json' ) ;
303+
304+ const document = await vscode . workspace . openTextDocument ( vscode . Uri . file ( schemaPath ) ) ;
305+ await vscode . window . showTextDocument ( document ) ;
306+
307+ await vscode . commands . executeCommand ( 'sourcemeta-studio.openPanel' ) ;
308+
309+ await new Promise ( resolve => setTimeout ( resolve , 5000 ) ) ;
310+
311+ const diagnostics = vscode . languages . getDiagnostics ( document . uri ) ;
312+
313+ const metaschemaDiagnostics = diagnostics . filter ( diagnostic =>
314+ diagnostic . source === 'Sourcemeta Studio (Metaschema)' ) ;
315+
316+ assert . ok ( metaschemaDiagnostics . length > 0 ,
317+ 'Metaschema errors should produce diagnostics' ) ;
318+
319+ const rootDiagnostics = metaschemaDiagnostics . filter ( diagnostic =>
320+ diagnostic . range . start . line === 0 ) ;
321+
322+ assert . ok ( rootDiagnostics . length > 0 ,
323+ 'Should have root-level metaschema diagnostics' ) ;
324+
325+ for ( const diagnostic of rootDiagnostics ) {
326+ assert . strictEqual ( diagnostic . range . start . character , 0 ,
327+ 'Root-level metaschema diagnostic should start at character 0' ) ;
328+ assert . strictEqual ( diagnostic . range . end . line , 0 ,
329+ 'Root-level metaschema diagnostic should not extend beyond line 0' ) ;
330+ assert . strictEqual ( diagnostic . range . end . character , 0 ,
331+ 'Root-level metaschema diagnostic should have zero-width range' ) ;
332+ }
333+
334+ const nonRootDiagnostics = metaschemaDiagnostics . filter ( diagnostic =>
335+ diagnostic . range . start . line > 0 ) ;
336+
337+ assert . ok ( nonRootDiagnostics . length > 0 ,
338+ 'Should also have non-root metaschema diagnostics' ) ;
339+
340+ for ( const diagnostic of nonRootDiagnostics ) {
341+ assert . ok ( diagnostic . range . end . character > diagnostic . range . start . character ,
342+ 'Non-root metaschema diagnostic should retain a non-zero-width range' ) ;
343+ }
344+ } ) ;
345+
217346 test ( 'Should run linter even when metaschema validation fails' , async function ( ) {
218347 this . timeout ( 15000 ) ;
219348
0 commit comments