diff --git a/.github/workflows/npm-test.yml b/.github/workflows/npm-test.yml index d2e6957..6c0af41 100644 --- a/.github/workflows/npm-test.yml +++ b/.github/workflows/npm-test.yml @@ -9,7 +9,13 @@ on: jobs: test: - runs-on: ubuntu-latest + strategy: + matrix: + include: + - os: windows-latest + - os: ubuntu-latest + - os: macos-latest + runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 @@ -17,4 +23,7 @@ jobs: node-version: 20.x cache: 'npm' - run: npm ci + - run: xvfb-run -a npm test + if: runner.os == 'Linux' - run: npm test + if: runner.os != 'Linux' diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 1e84625..e8ec9aa 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -3,23 +3,6 @@ { "version": "2.0.0", "tasks": [ - { - "type": "shell", - "label": "cp-wasm", - "command": "cp node_modules/float-pigment-css/float_pigment_css_bg.wasm dist/", - "problemMatcher": "$ts-webpack-watch", - "isBackground": true, - "presentation": { - "reveal": "never", - "group": "watchers" - }, - "group": { - "kind": "build" - }, - "options": { - "cwd": "${workspaceFolder}" - } - }, { "type": "npm", "script": "watch", @@ -55,7 +38,6 @@ "label": "tasks: watch-tests", "dependsOn": [ "npm: watch", - "cp-wasm", "npm: watch-tests" ], "problemMatcher": [] @@ -63,8 +45,7 @@ { "label": "tasks: watch", "dependsOn": [ - "npm: watch", - "cp-wasm" + "npm: watch" ], "problemMatcher": [] } diff --git a/package-lock.json b/package-lock.json index 4afb6ff..98abf53 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "float-pigment-css-analyzer", - "version": "0.1.0", + "version": "0.1.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "float-pigment-css-analyzer", - "version": "0.1.0", + "version": "0.1.1", "license": "MIT", "devDependencies": { "@types/assert": "^1.5.11", @@ -19,6 +19,7 @@ "@vscode/test-cli": "^0.0.10", "@vscode/test-electron": "^2.4.1", "assert": "^2.1.0", + "copy-webpack-plugin": "^12.0.2", "eslint": "^7.17.0", "eslint-config-airbnb-base": "^14.2.1", "eslint-config-prettier": "^8.6.0", @@ -462,6 +463,18 @@ "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", "dev": true }, + "node_modules/@sindresorhus/merge-streams": { + "version": "2.3.0", + "resolved": "https://mirrors.tencent.com/npm/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@tsconfig/node10": { "version": "1.0.11", "resolved": "https://mirrors.tencent.com/npm/@tsconfig/node10/-/node10-1.0.11.tgz", @@ -1880,6 +1893,148 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, + "node_modules/copy-webpack-plugin": { + "version": "12.0.2", + "resolved": "https://mirrors.tencent.com/npm/copy-webpack-plugin/-/copy-webpack-plugin-12.0.2.tgz", + "integrity": "sha512-SNwdBeHyII+rWvee/bTnAYyO8vfVdcSTud4EIb6jcZ8inLeWucJE0DnxXQBjlQ5zlteuuvooGQy3LIyGxhvlOA==", + "dev": true, + "dependencies": { + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.1", + "globby": "^14.0.0", + "normalize-path": "^3.0.0", + "schema-utils": "^4.2.0", + "serialize-javascript": "^6.0.2" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://mirrors.tencent.com/npm/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/copy-webpack-plugin/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://mirrors.tencent.com/npm/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/copy-webpack-plugin/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://mirrors.tencent.com/npm/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/globby": { + "version": "14.1.0", + "resolved": "https://mirrors.tencent.com/npm/globby/-/globby-14.1.0.tgz", + "integrity": "sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==", + "dev": true, + "dependencies": { + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.3", + "ignore": "^7.0.3", + "path-type": "^6.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/copy-webpack-plugin/node_modules/ignore": { + "version": "7.0.3", + "resolved": "https://mirrors.tencent.com/npm/ignore/-/ignore-7.0.3.tgz", + "integrity": "sha512-bAH5jbK/F3T3Jls4I0SO1hmPR0dKU0a7+SY6n1yzRtG54FLO8d6w/nxLFX2Nb7dBu6cCWXPaAME6cYqFUMmuCA==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/copy-webpack-plugin/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://mirrors.tencent.com/npm/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/copy-webpack-plugin/node_modules/path-type": { + "version": "6.0.0", + "resolved": "https://mirrors.tencent.com/npm/path-type/-/path-type-6.0.0.tgz", + "integrity": "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/copy-webpack-plugin/node_modules/schema-utils": { + "version": "4.3.0", + "resolved": "https://mirrors.tencent.com/npm/schema-utils/-/schema-utils-4.3.0.tgz", + "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/copy-webpack-plugin/node_modules/slash": { + "version": "5.1.0", + "resolved": "https://mirrors.tencent.com/npm/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://mirrors.tencent.com/npm/core-util-is/-/core-util-is-1.0.3.tgz", @@ -6831,6 +6986,18 @@ "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", "dev": true }, + "node_modules/unicorn-magic": { + "version": "0.3.0", + "resolved": "https://mirrors.tencent.com/npm/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/update-browserslist-db": { "version": "1.1.2", "resolved": "https://mirrors.tencent.com/npm/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz", diff --git a/package.json b/package.json index 4d458a1..9eebede 100644 --- a/package.json +++ b/package.json @@ -87,6 +87,7 @@ "@vscode/test-cli": "^0.0.10", "@vscode/test-electron": "^2.4.1", "assert": "^2.1.0", + "copy-webpack-plugin": "^12.0.2", "eslint": "^7.17.0", "eslint-config-airbnb-base": "^14.2.1", "eslint-config-prettier": "^8.6.0", diff --git a/src/test/index.test.ts b/src/test/index.test.ts index 65980bf..cc6a35a 100644 --- a/src/test/index.test.ts +++ b/src/test/index.test.ts @@ -4,6 +4,7 @@ import assert from 'assert' const EXTENSION_DIR = path.resolve(__dirname, '..', '..') const TEST_FIXTURE_DIR = path.resolve(EXTENSION_DIR, 'test-fixture') +const DIAGNOSTIC_SOURCE = 'float-pigment-css-analyzer' const getUri = (rel: string) => { const absPath = path.resolve(TEST_FIXTURE_DIR, rel) @@ -11,19 +12,49 @@ const getUri = (rel: string) => { return uri } -const sleep = (ms: number): Promise => +// const diagChangeCallbacks: ((uris: readonly vscode.Uri[]) => void)[] = [] +// vscode.languages.onDidChangeDiagnostics((e) => { +// // eslint-disable-next-line @typescript-eslint/no-floating-promises, promise/catch-or-return +// vscode.window.showInformationMessage('!!!') +// diagChangeCallbacks.forEach((f) => f(e.uris)) +// }) +const waitDiagnosticsUpdate = (uri: vscode.Uri, source: string): Promise => new Promise((resolve) => { - setTimeout(resolve, ms) + const diag = vscode.languages.getDiagnostics(uri).find((diag) => diag.source === source) + if (diag) { + resolve() + return + } + // const cb = (uris: readonly vscode.Uri[]) => { + // if (uris.includes(uri)) { + // const diag = vscode.languages.getDiagnostics(uri).find((diag) => diag.source === source) + // if (diag) { + // const index = diagChangeCallbacks.indexOf(cb) + // diagChangeCallbacks.splice(index, 1) + // resolve() + // } + // } + // } + // diagChangeCallbacks.push(cb) + const cb = () => { + const diag = vscode.languages.getDiagnostics(uri).find((diag) => diag.source === source) + if (diag) { + resolve() + return + } + setTimeout(cb, 100) + } + setTimeout(cb, 100) }) suite('common', () => { test('diagnostics for CSS', async () => { const uri = getUri('components/index.css') await vscode.window.showTextDocument(uri) - await sleep(1000) + await waitDiagnosticsUpdate(uri, DIAGNOSTIC_SOURCE) const diagList = vscode.languages .getDiagnostics(uri) - .filter((diag) => diag.source === 'float-pigment-css-analyzer') + .filter((diag) => diag.source === DIAGNOSTIC_SOURCE) assert.equal(diagList.length, 1) }) }) diff --git a/webpack.config.js b/webpack.config.js index 37d7024..c3e9df6 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,8 +1,9 @@ //@ts-check -'use strict'; +'use strict' -const path = require('path'); +const path = require('path') +const CopyPlugin = require('copy-webpack-plugin') //@ts-check /** @typedef {import('webpack').Configuration} WebpackConfig **/ @@ -10,22 +11,22 @@ const path = require('path'); /** @type WebpackConfig */ const extensionConfig = { target: 'node', // VS Code extensions run in a Node.js-context 📖 -> https://webpack.js.org/configuration/node/ - mode: 'none', // this leaves the source code as close as possible to the original (when packaging we set this to 'production') + mode: 'none', // this leaves the source code as close as possible to the original (when packaging we set this to 'production') entry: './src/extension.ts', // the entry point of this extension, 📖 -> https://webpack.js.org/configuration/entry-context/ output: { // the bundle is stored in the 'dist' folder (check package.json), 📖 -> https://webpack.js.org/configuration/output/ path: path.resolve(__dirname, 'dist'), filename: 'extension.js', - libraryTarget: 'commonjs2' + libraryTarget: 'commonjs2', }, externals: { - vscode: 'commonjs vscode' // the vscode-module is created on-the-fly and must be excluded. Add other modules that cannot be webpack'ed, 📖 -> https://webpack.js.org/configuration/externals/ + vscode: 'commonjs vscode', // the vscode-module is created on-the-fly and must be excluded. Add other modules that cannot be webpack'ed, 📖 -> https://webpack.js.org/configuration/externals/ // modules added here also need to be added in the .vscodeignore file }, resolve: { // support reading TypeScript and JavaScript files, 📖 -> https://github.com/TypeStrong/ts-loader - extensions: ['.ts', '.js'] + extensions: ['.ts', '.js'], }, module: { rules: [ @@ -34,15 +35,20 @@ const extensionConfig = { exclude: /node_modules/, use: [ { - loader: 'ts-loader' - } - ] - } - ] + loader: 'ts-loader', + }, + ], + }, + ], }, devtool: 'nosources-source-map', infrastructureLogging: { - level: "log", // enables logging required for problem matchers + level: 'log', // enables logging required for problem matchers }, -}; -module.exports = [ extensionConfig ]; \ No newline at end of file + plugins: [ + new CopyPlugin({ + patterns: [{ from: 'node_modules/float-pigment-css/float_pigment_css_bg.wasm', to: '.' }], + }), + ], +} +module.exports = [extensionConfig]