diff --git a/package.json b/package.json index 52777cde3c..67af57da5c 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "smoketest-ui": "playwright test --config=test/smoke/playwright.config.ts --ui", "smoketest-headed": "playwright test --config=test/smoke/playwright.config.ts --headed", "test": "ts-node ./build/check-samples && npm run test:grammars", - "test:grammars": "node --import tsx --import ./test/test-setup.mjs --test \"src/languages/definitions/*/*.test.ts\"", + "test:grammars": "node --import tsx --import ./test/test-setup.mjs --test \"src/languages/**/*.test.ts\"", "deps-all-remove": "ts-node ./build/npm/removeAll", "deps-all-install": "ts-node ./build/npm/installAll", "update-actions": "pin-github-action ./.github/workflows/website.yml", diff --git a/src/languages/features/css/cssWorker.test.ts b/src/languages/features/css/cssWorker.test.ts new file mode 100644 index 0000000000..ebab90799b --- /dev/null +++ b/src/languages/features/css/cssWorker.test.ts @@ -0,0 +1,31 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { describe, it } from 'node:test'; +import assert from 'node:assert'; +import { CSSWorker } from './cssWorker'; + +function createWorker(content: string, uri = 'file:///test.css'): CSSWorker { + const model = { + uri: { toString: () => uri }, + version: 1, + getValue: () => content + }; + const ctx = { getMirrorModels: () => [model] } as any; + return new CSSWorker(ctx, { languageId: 'css', options: {} }); +} + +describe('CSSWorker', () => { + it('doHover does not throw on invalid nth-child selectors', async () => { + const worker = createWorker(':nth-child() { }'); + assert.strictEqual(await worker.doHover('file:///test.css', { line: 0, character: 3 }), null); + }); + + it('doHover returns a hover for valid selectors', async () => { + const worker = createWorker('li:nth-child(2n of .important) { }'); + const hover = await worker.doHover('file:///test.css', { line: 0, character: 1 }); + assert.ok(hover); + }); +}); diff --git a/src/languages/features/css/cssWorker.ts b/src/languages/features/css/cssWorker.ts index ced922370a..d912a341de 100644 --- a/src/languages/features/css/cssWorker.ts +++ b/src/languages/features/css/cssWorker.ts @@ -79,8 +79,14 @@ export class CSSWorker { return null; } const stylesheet = this._languageService.parseStylesheet(document); - const hover = this._languageService.doHover(document, position, stylesheet); - return Promise.resolve(hover); + try { + const hover = this._languageService.doHover(document, position, stylesheet); + return Promise.resolve(hover); + } catch (e) { + // The CSS language service can throw on invalid selectors, e.g. `:nth-child()`. + // https://github.com/microsoft/monaco-editor/issues/5430 + return null; + } } async findDefinition( uri: string,