diff --git a/fixtures/config-errors/errors.st.css b/fixtures/config-errors/errors.st.css new file mode 100644 index 00000000..fef5a9eb --- /dev/null +++ b/fixtures/config-errors/errors.st.css @@ -0,0 +1 @@ +.root::unknownPseudoElement {} diff --git a/fixtures/config-errors/package.json b/fixtures/config-errors/package.json new file mode 100644 index 00000000..79d21ea0 --- /dev/null +++ b/fixtures/config-errors/package.json @@ -0,0 +1,4 @@ +{ + "name": "test-project-with-config-errors", + "version": "1.0.0" +} diff --git a/fixtures/config-errors/stylable.config.js b/fixtures/config-errors/stylable.config.js new file mode 100644 index 00000000..ec6f6d3c --- /dev/null +++ b/fixtures/config-errors/stylable.config.js @@ -0,0 +1,11 @@ +//@ts-check + +module.exports = { + defaultConfig() { + return { + resolveNamespace(namespace) { + throw new Error('resolveNamespace test error for namespace: ' + namespace); + }, + }; + }, +}; diff --git a/run-e2e-tests.js b/run-e2e-tests.js index f340fbe3..a405fa1f 100644 --- a/run-e2e-tests.js +++ b/run-e2e-tests.js @@ -31,6 +31,7 @@ async function runAllSuites() { await runSuite('latest'); await runSuite('v5-with-no-config'); await runSuite('v5-with-config'); + await runSuite('config-errors'); } runAllSuites(); diff --git a/src/lib/server.ts b/src/lib/server.ts index 44ab596f..9b02c48a 100644 --- a/src/lib/server.ts +++ b/src/lib/server.ts @@ -44,6 +44,18 @@ connection.onInitialize(async (params) => { fileSystem: wrappedFs, requireModule: require, cssParser: safeParse, + resolveNamespace(namespace, origin, source) { + try { + if (config.resolveNamespace) { + return config.resolveNamespace(namespace, origin, source); + } + } catch (e: unknown) { + // can be used to log project level errors + // console.warn('resolveNamespace failed', e); + } + // fallback to initial namespace + return namespace; + }, }) ); diff --git a/test/e2e/config-errors/config.test.ts b/test/e2e/config-errors/config.test.ts new file mode 100644 index 00000000..0b93013b --- /dev/null +++ b/test/e2e/config-errors/config.test.ts @@ -0,0 +1,54 @@ +import fs from '@file-services/node'; +import vscode from 'vscode'; +import { expect } from 'chai'; +import path from 'path'; + +suite('configuration with errors', function () { + this.timeout(60000); + + let rootDir: string | null; + + suiteSetup(() => { + rootDir = fs.dirname(fs.findClosestFileSync(__dirname, 'package.json')!); + }); + + async function getWorkingDocument(...testSubPath: string[]) { + const casesPath = path.join(rootDir!, 'fixtures', 'config-errors', ...testSubPath); + const ext = vscode.extensions.getExtension('wix.stylable-intelligence'); + + if (ext) { + const doc = await vscode.workspace.openTextDocument(casesPath); + await ext.activate(); + return doc; + } else { + throw new Error('Where is my extension?!!'); + } + } + function collectDiagnostics(source: 'stylable' | 'css', file: string) { + const diags = vscode.languages.getDiagnostics(); + const res = []; + + for (const [pathObj, fileDiags] of diags) { + for (const diag of fileDiags) { + if (diag.source === source && file === pathObj.fsPath) { + res.push({ + message: diag.message, + range: diag.range, + severity: diag.severity, + filePath: fs.realpathSync.native(pathObj.fsPath), + }); + } + } + } + + return res; + } + + test('should handle errors in resolve namespace config', async () => { + const testDoc = await getWorkingDocument('errors.st.css'); + await vscode.window.showTextDocument(testDoc); + const diags = collectDiagnostics('stylable', testDoc.uri.fsPath); + // make sure extension functions correctly + expect(diags.length).to.not.eql(0); + }); +}); diff --git a/test/e2e/config-errors/index.ts b/test/e2e/config-errors/index.ts new file mode 100644 index 00000000..2e1feaba --- /dev/null +++ b/test/e2e/config-errors/index.ts @@ -0,0 +1,5 @@ +import { collectAndRunTests } from '../../lsp-testkit/collect-and-run-tests'; + +export function run() { + return collectAndRunTests({ testsRoot: __dirname, suiteName: 'config errors' }); +}