From b57036765f5aba6ce7c33ab34de61ceb76bc3e12 Mon Sep 17 00:00:00 2001 From: Roberto Mosca Date: Sat, 9 Dec 2023 18:10:52 +0100 Subject: [PATCH] Refactor code, eliminate tests --- .github/workflows/main.yml | 6 +- .npmrc | 1 + .nvmrc | 2 +- .vscode-test.mjs | 5 + .vscode/extensions.json | 11 +- .vscode/launch.json | 5 +- .vscode/tasks.json | 32 +-- package.json | 32 +-- pnpm-lock.yaml | 240 +++++++----------- src/Ri5devBrowser.ts | 3 +- src/api.ts | 74 ++++-- src/device.ts | 42 ++- src/extension.ts | 2 +- src/test/extension.test.ts | 15 ++ src/test/runTest.ts | 23 -- src/test/suite/api.test.ts | 134 ---------- src/test/suite/extension.test.ts | 14 - .../suite/helpers/SerialProcessor.test.ts | 58 ----- src/test/suite/helpers/askDevice.test.ts | 57 ----- src/test/suite/index.ts | 38 --- src/test/suite/utils.test.ts | 85 ------- 21 files changed, 249 insertions(+), 630 deletions(-) create mode 100644 .npmrc create mode 100644 .vscode-test.mjs create mode 100644 src/test/extension.test.ts delete mode 100644 src/test/runTest.ts delete mode 100644 src/test/suite/api.test.ts delete mode 100644 src/test/suite/extension.test.ts delete mode 100644 src/test/suite/helpers/SerialProcessor.test.ts delete mode 100644 src/test/suite/helpers/askDevice.test.ts delete mode 100644 src/test/suite/index.ts delete mode 100644 src/test/suite/utils.test.ts diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6f3283d..75cb19e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -3,10 +3,10 @@ name: CI on: push: branches: - - "*" + - '*' pull_request: branches: - - "main" + - 'main' # Allows you to run this workflow manually from the Actions tab workflow_dispatch: @@ -24,7 +24,7 @@ jobs: - name: Install Node.js uses: actions/setup-node@v1 with: - node-version: 18.18.2 + node-version: 18.19.0 - name: Install Pnpm uses: pnpm/action-setup@v2.0.1 diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..37d1b60 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +enable-pre-post-scripts = true \ No newline at end of file diff --git a/.nvmrc b/.nvmrc index 3a57185..3bd3dce 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1,2 +1,2 @@ -v18.18.2 +v18.19.0 diff --git a/.vscode-test.mjs b/.vscode-test.mjs new file mode 100644 index 0000000..b62ba25 --- /dev/null +++ b/.vscode-test.mjs @@ -0,0 +1,5 @@ +import { defineConfig } from '@vscode/test-cli'; + +export default defineConfig({ + files: 'out/test/**/*.test.js', +}); diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 3ac9aeb..5906abf 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,7 +1,8 @@ { - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format - "recommendations": [ - "dbaeumer.vscode-eslint" - ] + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "dbaeumer.vscode-eslint", + "ms-vscode.extension-test-runner" + ] } diff --git a/.vscode/launch.json b/.vscode/launch.json index 36aadd0..0855344 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -9,7 +9,10 @@ "name": "Run Extension", "type": "extensionHost", "request": "launch", - "args": ["--extensionDevelopmentPath=${workspaceFolder}"], + "args": [ + "--trace-deprecation", + "--extensionDevelopmentPath=${workspaceFolder}" + ], "outFiles": ["${workspaceFolder}/out/**/*.js"], "preLaunchTask": "${defaultBuildTask}" }, diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 3b17e53..078ff7e 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -1,20 +1,20 @@ // See https://go.microsoft.com/fwlink/?LinkId=733558 // for the documentation about the tasks.json format { - "version": "2.0.0", - "tasks": [ - { - "type": "npm", - "script": "watch", - "problemMatcher": "$tsc-watch", - "isBackground": true, - "presentation": { - "reveal": "never" - }, - "group": { - "kind": "build", - "isDefault": true - } - } - ] + "version": "2.0.0", + "tasks": [ + { + "type": "npm", + "script": "watch", + "problemMatcher": "$tsc-watch", + "isBackground": true, + "presentation": { + "reveal": "never" + }, + "group": { + "kind": "build", + "isDefault": true + } + } + ] } diff --git a/package.json b/package.json index d29565c..ac37504 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "robotinventor", "displayName": "robotinventor", "description": "A Microsoft Visual Studio Code extension to program LEGO® Mindstorms® Robot Inventor in MicroPython", - "version": "0.0.1", + "version": "1.0.0", "publisher": "robmosca", "repository": "https://github.com/robmosca/robotinventor-vscode", "engines": { @@ -22,37 +22,37 @@ { "command": "ri5devBrowser.action.connectDevice", "title": "Connect to a device", - "category": "ri5dev" + "category": "Robot Inventor" }, { "command": "ri5devBrowser.action.disconnectDevice", "title": "Disconnect", - "category": "ri5dev" + "category": "Robot Inventor" }, { "command": "ri5devBrowser.runProgram", "title": "Run program", - "category": "ri5dev" + "category": "Robot Inventor" }, { "command": "ri5devBrowser.stopProgram", "title": "Stop program", - "category": "ri5dev" + "category": "Robot Inventor" }, { "command": "ri5devBrowser.moveProgram", "title": "Move program", - "category": "ri5dev" + "category": "Robot Inventor" }, { "command": "ri5devBrowser.removeProgram", "title": "Remove program", - "category": "ri5dev" + "category": "Robot Inventor" }, { "command": "ri5devBrowser.uploadProgram", "title": "Upload program", - "category": "ri5dev" + "category": "Robot Inventor" } ], "menus": { @@ -87,7 +87,7 @@ "explorer": [ { "id": "ri5devBrowser", - "name": "ri5dev device browser" + "name": "Robot Inventor Device Browser" } ] }, @@ -99,16 +99,18 @@ ] }, "scripts": { + "clean": "rimraf ./out", "compile": "tsc -p ./", "coverage": "nyc npm test", "lint": "eslint src --ext ts", - "pretest": "npm run compile && npm run lint", - "test": "node ./out/test/runTest.js", + "pretest": "pnpm run compile && pnpm run lint", + "test": "vscode-test", "typecheck": "tsc --noEmit -p ./", - "vscode:prepublish": "npm run compile", + "vscode:prepublish": "pnpm run compile", "watch": "tsc -watch -p ./" }, "devDependencies": { + "@electron/rebuild": "^3.4.1", "@istanbuljs/nyc-config-typescript": "^1.0.1", "@types/chai": "^4.2.14", "@types/glob": "^8.1.0", @@ -120,9 +122,10 @@ "@types/vscode": "^1.53.0", "@typescript-eslint/eslint-plugin": "^6.13.2", "@typescript-eslint/parser": "^6.13.2", + "@vscode/test-cli": "^0.0.4", + "@vscode/test-electron": "^2.3.8", "chai": "^4.2.0", "chai-match": "^1.1.1", - "electron-rebuild": "^3.2.9", "eslint": "^8.55.0", "glob": "^10.3.10", "mocha": "^10.2.0", @@ -132,8 +135,7 @@ "sinon-chai": "^3.5.0", "ts-mock-imports": "^1.3.1", "ts-node": "^10.9.1", - "typescript": "^5.3.3", - "vscode-test": "^1.4.0" + "typescript": "^5.3.3" }, "dependencies": { "serialport": "^12.0.0" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b2a3ad8..2f21a54 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,6 +10,9 @@ dependencies: version: 12.0.0 devDependencies: + '@electron/rebuild': + specifier: ^3.4.1 + version: 3.4.1 '@istanbuljs/nyc-config-typescript': specifier: ^1.0.1 version: 1.0.2(nyc@15.1.0) @@ -43,15 +46,18 @@ devDependencies: '@typescript-eslint/parser': specifier: ^6.13.2 version: 6.13.2(eslint@8.55.0)(typescript@5.3.3) + '@vscode/test-cli': + specifier: ^0.0.4 + version: 0.0.4 + '@vscode/test-electron': + specifier: ^2.3.8 + version: 2.3.8 chai: specifier: ^4.2.0 version: 4.3.10 chai-match: specifier: ^1.1.1 version: 1.1.1 - electron-rebuild: - specifier: ^3.2.9 - version: 3.2.9 eslint: specifier: ^8.55.0 version: 8.55.0 @@ -82,9 +88,6 @@ devDependencies: typescript: specifier: ^5.3.3 version: 5.3.3 - vscode-test: - specifier: ^1.4.0 - version: 1.6.1 packages: @@ -299,6 +302,30 @@ packages: '@jridgewell/trace-mapping': 0.3.9 dev: true + /@electron/rebuild@3.4.1: + resolution: {integrity: sha512-iMKb6KJgKcdURbejs0j2GLEmrY8uY4rg1ESThXx9sFTgdWb8UOfJuTqW6LIEtcoY8FrbFqDmJrkWc4tBpdStXw==} + engines: {node: '>=12.13.0'} + hasBin: true + dependencies: + '@malept/cross-spawn-promise': 2.0.0 + chalk: 4.1.2 + debug: 4.3.4(supports-color@8.1.1) + detect-libc: 2.0.2 + fs-extra: 10.1.0 + got: 11.8.6 + node-abi: 3.52.0 + node-api-version: 0.1.4 + node-gyp: 9.4.1 + ora: 5.4.1 + read-binary-file-arch: 1.0.6 + semver: 7.5.4 + tar: 6.2.0 + yargs: 17.7.2 + transitivePeerDependencies: + - bluebird + - supports-color + dev: true + /@eslint-community/eslint-utils@4.4.0(eslint@8.55.0): resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -884,6 +911,31 @@ packages: resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} dev: true + /@vscode/test-cli@0.0.4: + resolution: {integrity: sha512-Tx0tfbxeSb2Xlo+jpd+GJrNLgKQHobhRHrYvOipZRZQYWZ82sKiK02VY09UjU1Czc/YnZnqyAnjUfaVGl3h09w==} + hasBin: true + dependencies: + '@types/mocha': 10.0.6 + chokidar: 3.5.3 + glob: 10.3.10 + minimatch: 9.0.3 + mocha: 10.2.0 + supports-color: 9.4.0 + yargs: 17.7.2 + dev: true + + /@vscode/test-electron@2.3.8: + resolution: {integrity: sha512-b4aZZsBKtMGdDljAsOPObnAi7+VWIaYl3ylCz1jTs+oV6BZ4TNHcVNC3xUn0azPeszBmwSBDQYfFESIaUQnrOg==} + engines: {node: '>=16'} + dependencies: + http-proxy-agent: 4.0.1 + https-proxy-agent: 5.0.1 + jszip: 3.10.1 + semver: 7.5.4 + transitivePeerDependencies: + - supports-color + dev: true + /abbrev@1.1.1: resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} dev: true @@ -1036,23 +1088,11 @@ packages: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} dev: true - /big-integer@1.6.52: - resolution: {integrity: sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==} - engines: {node: '>=0.6'} - dev: true - /binary-extensions@2.2.0: resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} engines: {node: '>=8'} dev: true - /binary@0.3.0: - resolution: {integrity: sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg==} - dependencies: - buffers: 0.1.1 - chainsaw: 0.1.0 - dev: true - /bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} dependencies: @@ -1061,10 +1101,6 @@ packages: readable-stream: 3.6.2 dev: true - /bluebird@3.4.7: - resolution: {integrity: sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==} - dev: true - /brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} dependencies: @@ -1100,11 +1136,6 @@ packages: update-browserslist-db: 1.0.13(browserslist@4.22.2) dev: true - /buffer-indexof-polyfill@1.0.2: - resolution: {integrity: sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==} - engines: {node: '>=0.10'} - dev: true - /buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} dependencies: @@ -1112,11 +1143,6 @@ packages: ieee754: 1.2.1 dev: true - /buffers@0.1.1: - resolution: {integrity: sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==} - engines: {node: '>=0.2.0'} - dev: true - /cacache@16.1.3: resolution: {integrity: sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} @@ -1207,12 +1233,6 @@ packages: type-detect: 4.0.8 dev: true - /chainsaw@0.1.0: - resolution: {integrity: sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ==} - dependencies: - traverse: 0.3.9 - dev: true - /chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} @@ -1468,41 +1488,10 @@ packages: esutils: 2.0.3 dev: true - /duplexer2@0.1.4: - resolution: {integrity: sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==} - dependencies: - readable-stream: 2.3.8 - dev: true - /eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} dev: true - /electron-rebuild@3.2.9: - resolution: {integrity: sha512-FkEZNFViUem3P0RLYbZkUjC8LUFIK+wKq09GHoOITSJjfDAVQv964hwaNseTTWt58sITQX3/5fHNYcTefqaCWw==} - engines: {node: '>=12.13.0'} - deprecated: Please use @electron/rebuild moving forward. There is no API change, just a package name change - hasBin: true - dependencies: - '@malept/cross-spawn-promise': 2.0.0 - chalk: 4.1.2 - debug: 4.3.4(supports-color@8.1.1) - detect-libc: 2.0.2 - fs-extra: 10.1.0 - got: 11.8.6 - lzma-native: 8.0.6 - node-abi: 3.52.0 - node-api-version: 0.1.4 - node-gyp: 9.4.1 - ora: 5.4.1 - semver: 7.5.4 - tar: 6.2.0 - yargs: 17.7.2 - transitivePeerDependencies: - - bluebird - - supports-color - dev: true - /electron-to-chromium@1.4.607: resolution: {integrity: sha512-YUlnPwE6eYxzwBnFmawA8LiLRfm70R2aJRIUv0n03uHt/cUzzYACOogmvk8M2+hVzt/kB80KJXx7d5f5JofPvQ==} dev: true @@ -1794,16 +1783,6 @@ packages: dev: true optional: true - /fstream@1.0.12: - resolution: {integrity: sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==} - engines: {node: '>=0.6'} - dependencies: - graceful-fs: 4.2.11 - inherits: 2.0.4 - mkdirp: 0.5.6 - rimraf: 2.7.1 - dev: true - /gauge@4.0.4: resolution: {integrity: sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} @@ -2050,6 +2029,10 @@ packages: engines: {node: '>= 4'} dev: true + /immediate@3.0.6: + resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} + dev: true + /import-fresh@3.3.0: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} engines: {node: '>=6'} @@ -2290,6 +2273,15 @@ packages: graceful-fs: 4.2.11 dev: true + /jszip@3.10.1: + resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} + dependencies: + lie: 3.3.0 + pako: 1.0.11 + readable-stream: 2.3.8 + setimmediate: 1.0.5 + dev: true + /just-extend@4.2.1: resolution: {integrity: sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==} dev: true @@ -2308,8 +2300,10 @@ packages: type-check: 0.4.0 dev: true - /listenercount@1.0.1: - resolution: {integrity: sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ==} + /lie@3.3.0: + resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} + dependencies: + immediate: 3.0.6 dev: true /locate-path@5.0.0: @@ -2380,17 +2374,6 @@ packages: engines: {node: '>=12'} dev: true - /lzma-native@8.0.6: - resolution: {integrity: sha512-09xfg67mkL2Lz20PrrDeNYZxzeW7ADtpYFbwSQh9U8+76RIzx5QsJBMy8qikv3hbUPfpy6hqwxt6FcGK81g9AA==} - engines: {node: '>=10.0.0'} - hasBin: true - requiresBuild: true - dependencies: - node-addon-api: 3.2.1 - node-gyp-build: 4.6.0 - readable-stream: 3.6.2 - dev: true - /make-dir@3.1.0: resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} engines: {node: '>=8'} @@ -2482,10 +2465,6 @@ packages: brace-expansion: 2.0.1 dev: true - /minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - dev: true - /minipass-collect@1.0.2: resolution: {integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==} engines: {node: '>= 8'} @@ -2550,13 +2529,6 @@ packages: yallist: 4.0.0 dev: true - /mkdirp@0.5.6: - resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} - hasBin: true - dependencies: - minimist: 1.2.8 - dev: true - /mkdirp@1.0.4: resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} engines: {node: '>=10'} @@ -2630,10 +2602,6 @@ packages: semver: 7.5.4 dev: true - /node-addon-api@3.2.1: - resolution: {integrity: sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==} - dev: true - /node-addon-api@7.0.0: resolution: {integrity: sha512-vgbBJTS4m5/KkE16t5Ly0WW9hz46swAstv0hYYwMtbG7AznRhNyfLRe8HZAiWIpcHzoO7HxhLuBQj9rJ/Ho0ZA==} dev: false @@ -2647,6 +2615,7 @@ packages: /node-gyp-build@4.6.0: resolution: {integrity: sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==} hasBin: true + dev: false /node-gyp@9.4.1: resolution: {integrity: sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ==} @@ -2846,6 +2815,10 @@ packages: release-zalgo: 1.0.0 dev: true + /pako@1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + dev: true + /parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -2973,6 +2946,15 @@ packages: safe-buffer: 5.2.1 dev: true + /read-binary-file-arch@1.0.6: + resolution: {integrity: sha512-BNg9EN3DD3GsDXX7Aa8O4p92sryjkmzYYgmgTAc6CA4uGLEDzFfxOxugu21akOxpcXHiEgsYkC6nPsQvLLLmEg==} + hasBin: true + dependencies: + debug: 4.3.4(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + dev: true + /readable-stream@2.3.8: resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} dependencies: @@ -3055,13 +3037,6 @@ packages: engines: {iojs: '>=1.0.0', node: '>=0.10.0'} dev: true - /rimraf@2.7.1: - resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} - hasBin: true - dependencies: - glob: 7.2.3 - dev: true - /rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} hasBin: true @@ -3311,6 +3286,11 @@ packages: dependencies: has-flag: 4.0.0 + /supports-color@9.4.0: + resolution: {integrity: sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw==} + engines: {node: '>=12'} + dev: true + /tar@6.2.0: resolution: {integrity: sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==} engines: {node: '>=10'} @@ -3348,10 +3328,6 @@ packages: is-number: 7.0.0 dev: true - /traverse@0.3.9: - resolution: {integrity: sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==} - dev: true - /ts-api-utils@1.0.3(typescript@5.3.3): resolution: {integrity: sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==} engines: {node: '>=16.13.0'} @@ -3459,21 +3435,6 @@ packages: engines: {node: '>= 10.0.0'} dev: true - /unzipper@0.10.14: - resolution: {integrity: sha512-ti4wZj+0bQTiX2KmKWuwj7lhV+2n//uXEotUmGuQqrbVZSEGFMbI68+c6JCQ8aAmUWYvtHEz2A8K6wXvueR/6g==} - dependencies: - big-integer: 1.6.52 - binary: 0.3.0 - bluebird: 3.4.7 - buffer-indexof-polyfill: 1.0.2 - duplexer2: 0.1.4 - fstream: 1.0.12 - graceful-fs: 4.2.11 - listenercount: 1.0.1 - readable-stream: 2.3.8 - setimmediate: 1.0.5 - dev: true - /update-browserslist-db@1.0.13(browserslist@4.22.2): resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} hasBin: true @@ -3504,19 +3465,6 @@ packages: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} dev: true - /vscode-test@1.6.1: - resolution: {integrity: sha512-086q88T2ca1k95mUzffvbzb7esqQNvJgiwY4h29ukPhFo8u+vXOOmelUoU5EQUHs3Of8+JuQ3oGdbVCqaxuTXA==} - engines: {node: '>=8.9.3'} - deprecated: This package has been renamed to @vscode/test-electron, please update to the new name - dependencies: - http-proxy-agent: 4.0.1 - https-proxy-agent: 5.0.1 - rimraf: 3.0.2 - unzipper: 0.10.14 - transitivePeerDependencies: - - supports-color - dev: true - /wcwidth@1.0.1: resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} dependencies: diff --git a/src/Ri5devBrowser.ts b/src/Ri5devBrowser.ts index 71f1b1d..1b29486 100644 --- a/src/Ri5devBrowser.ts +++ b/src/Ri5devBrowser.ts @@ -16,6 +16,7 @@ export class DeviceTreeItem extends vscode.TreeItem { this.tooltip = name; this.description = 'No version available'; this.contextValue = 'device'; + this.collapsibleState = vscode.TreeItemCollapsibleState.Expanded; } iconPath = { @@ -96,12 +97,12 @@ export class Ri5devBrowserProvider this.device?.refresh(); this._onDidChangeTreeData.fire(); }); - this._onDidChangeTreeData.fire(); } public clearDevice() { removeDeviceAllListeners(); + this.device = undefined; this._onDidChangeTreeData.fire(); } } diff --git a/src/api.ts b/src/api.ts index bb94d02..9e28872 100644 --- a/src/api.ts +++ b/src/api.ts @@ -2,6 +2,17 @@ import { SerialPort } from 'serialport'; import SerialProcessor from './SerialProcessor'; import { decodeBase64, randomId } from './utils'; +type ParsedLine = { + e?: string; + i?: string; + r?: unknown; +}; + +type ProcessingFunctionReturnValue = { + resolve: boolean; + returnValue?: any; +}; + class API { constructor(private serialPort: SerialPort) {} @@ -20,6 +31,7 @@ class API { request: string, params: object, timeout_in_ms: number = 5000, + cmdResolver?: (line: string) => ProcessingFunctionReturnValue, reqId?: string, ): Promise { const id = reqId ?? randomId(); @@ -27,34 +39,44 @@ class API { const serializedMsg = JSON.stringify(msg); let response = ''; const serialProcessor = new SerialProcessor(this.serialPort, (data) => { - const crPos = data.indexOf('\r'); - if (crPos !== -1) { - const accData = response + data; - const lines = accData.split('\r'); - for (let i = 0; i < lines.length - 1; ++i) { - let parsedLine: { - e?: string; - i?: string; - r?: unknown; - } = {}; + function defaultCmdResolver(line: string) { + let parsedLine: ParsedLine = {}; - try { - parsedLine = JSON.parse(lines[i]); - } catch (err) {} + try { + parsedLine = JSON.parse(line); + } catch (err) {} - if (parsedLine.e) { - const err = JSON.parse(decodeBase64(parsedLine.e)); - throw new Error(err.message); - } + if (parsedLine.e) { + const err = JSON.parse(decodeBase64(parsedLine.e)); + throw new Error(err.message); + } - if (parsedLine.i === id) { - return { resolve: true, returnValue: parsedLine.r }; - } + if (parsedLine.i === id) { + return { resolve: true, returnValue: parsedLine.r }; } - response = lines[lines.length - 1]; - } else { + return { resolve: false }; + } + + const crPos = data.indexOf('\r'); + const crNlPos = data.indexOf('\r\n'); + if (crPos === -1) { response += data; + return { resolve: false }; + } + + const accData = response + data; + const lines = + crNlPos !== -1 ? accData.split('\r\n') : accData.split('\r'); + for (let i = 0; i < lines.length - 1; ++i) { + const resolution = cmdResolver + ? cmdResolver(lines[i]) + : defaultCmdResolver(lines[i]); + if (resolution.resolve) { + return resolution; + } } + + response = lines[lines.length - 1]; return { resolve: false }; }); @@ -67,8 +89,14 @@ export function APIRequest( request: string, params: object = {}, timeout_in_ms: number = 5000, + cmdResolver?: (line: string) => ProcessingFunctionReturnValue, ) { - return new API(serialPort).sendRequest(request, params, timeout_in_ms); + return new API(serialPort).sendRequest( + request, + params, + timeout_in_ms, + cmdResolver, + ); } export const _testing = { diff --git a/src/device.ts b/src/device.ts index 6c36b19..da20e20 100644 --- a/src/device.ts +++ b/src/device.ts @@ -63,7 +63,7 @@ class Device extends EventEmitter { this.ttyDevice = ttyDevice; } - private assertDeviceInitialized() { + private assertConnected() { if (!this.serialPort) { throw new Error('Device not initialized'); } @@ -71,7 +71,7 @@ class Device extends EventEmitter { private async obtainPrompt() { return new Promise((resolve) => { - this.assertDeviceInitialized(); + this.assertConnected(); const dataHandler = (data: Buffer) => { if (data.toString().endsWith(PROMPT)) { this.serialPort?.removeListener('data', dataHandler); @@ -95,7 +95,7 @@ class Device extends EventEmitter { } return new Promise((resolve, reject) => { - this.assertDeviceInitialized(); + this.assertConnected(); let output = ''; @@ -137,7 +137,7 @@ class Device extends EventEmitter { // } private executeSlotSpecificCommand(cmd: string, slotId: number) { - this.assertDeviceInitialized(); + this.assertConnected(); checkSlotId(slotId); return APIRequest(this.serialPort!, cmd, { slotid: slotId, @@ -153,12 +153,23 @@ class Device extends EventEmitter { } public async stopProgram() { - this.assertDeviceInitialized(); - return APIRequest(this.serialPort!, 'program_terminate'); + this.assertConnected(); + return APIRequest( + this.serialPort!, + 'program_terminate', + {}, + 5000, + (line) => { + if (line.includes('SystemExit:')) { + return { resolve: true }; + } + return { resolve: false }; + }, + ); } public async moveProgram(fromSlotId: number, toSlotId: number) { - this.assertDeviceInitialized(); + this.assertConnected(); checkSlotId(fromSlotId); checkSlotId(toSlotId); await APIRequest(this.serialPort!, 'move_project', { @@ -208,7 +219,7 @@ class Device extends EventEmitter { } public async refreshStorageStatus() { - this.assertDeviceInitialized(); + this.assertConnected(); const storageStatus = (await APIRequest( this.serialPort!, 'get_storage_status', @@ -227,6 +238,7 @@ class Device extends EventEmitter { }, async (err) => { if (err) { + this.serialPort = undefined; reject(err); } else { resolve(); @@ -236,7 +248,7 @@ class Device extends EventEmitter { }); } - public disconnect() { + disconnect() { return new Promise((resolve, reject) => { if (!this.serialPort) { resolve(); @@ -246,11 +258,16 @@ class Device extends EventEmitter { if (err) { reject(err); } else { + this.serialPort = undefined; resolve(); } }); }); } + + isConnected() { + return !!this.serialPort; + } } let device: Device | undefined = undefined; @@ -266,8 +283,15 @@ export async function connectDevice(deviceName: string) { try { device = new Device(deviceName); await device.connect(); + } catch (err) { + device = undefined; + throw err; + } + + try { return device.refreshStorageStatus(); } catch (err) { + await device?.disconnect(); device = undefined; throw err; } diff --git a/src/extension.ts b/src/extension.ts index a4cca0e..d788db7 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -133,9 +133,9 @@ async function connectDeviceCmd(): Promise { title: 'Connecting...', }, async () => { - ri5devBrowserProvider.refreshDevice(); try { await connectDevice(deviceName); + ri5devBrowserProvider.refreshDevice(); showTemporaryStatusBarMessage(`Connected`); } catch (err) { const msg = err instanceof Error ? err.message : err; diff --git a/src/test/extension.test.ts b/src/test/extension.test.ts new file mode 100644 index 0000000..4ca0ab4 --- /dev/null +++ b/src/test/extension.test.ts @@ -0,0 +1,15 @@ +import * as assert from 'assert'; + +// You can import and use all API from the 'vscode' module +// as well as import your extension to test it +import * as vscode from 'vscode'; +// import * as myExtension from '../../extension'; + +suite('Extension Test Suite', () => { + vscode.window.showInformationMessage('Start all tests.'); + + test('Sample test', () => { + assert.strictEqual(-1, [1, 2, 3].indexOf(5)); + assert.strictEqual(-1, [1, 2, 3].indexOf(0)); + }); +}); diff --git a/src/test/runTest.ts b/src/test/runTest.ts deleted file mode 100644 index a629e3e..0000000 --- a/src/test/runTest.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as path from 'path'; - -import { runTests } from 'vscode-test'; - -async function main() { - try { - // The folder containing the Extension Manifest package.json - // Passed to `--extensionDevelopmentPath` - const extensionDevelopmentPath = path.resolve(__dirname, '../../'); - - // The path to test runner - // Passed to --extensionTestsPath - const extensionTestsPath = path.resolve(__dirname, './suite/index'); - - // Download VS Code, unzip it and run the integration test - await runTests({ extensionDevelopmentPath, extensionTestsPath }); - } catch (err) { - console.error('Failed to run tests'); - process.exit(1); - } -} - -main(); diff --git a/src/test/suite/api.test.ts b/src/test/suite/api.test.ts deleted file mode 100644 index a03ea0d..0000000 --- a/src/test/suite/api.test.ts +++ /dev/null @@ -1,134 +0,0 @@ -import * as sinon from 'sinon'; -import * as sinonChai from 'sinon-chai'; -import * as chai from 'chai'; -import { _testing } from '../../api'; - -const SerialPort = require('@serialport/stream'); -const MockBinding = require('@serialport/binding-mock'); - -chai.use(sinonChai); -const expect = chai.expect; - -suite('_testing.API Test Suite', function () { - suite('Waits for the _testing.API to be ready', function () { - test('Waits for _testing.API to be ready', async function () { - MockBinding.createPort('/dev/echoserialport', { - echo: true, - record: true, - readyData: Buffer.from('{"m":0, e: "", i: ""}\r'), - }); - SerialPort.Binding = MockBinding; - const port = new SerialPort('/dev/echoserialport'); - const api = new _testing.API(port); - - await api.waitAPIready(); - - expect(port.binding.recording.toString()).to.equal('\x04\r'); - }); - - test('Times out if the device does not emit the correct sequence', async function () { - MockBinding.createPort('/dev/echoserialport', { - echo: true, - record: true, - readyData: Buffer.from(''), - }); - SerialPort.Binding = MockBinding; - const port = new SerialPort('/dev/echoserialport'); - const api = new _testing.API(port); - - try { - await api.waitAPIready(500); - } catch (err) { - expect(err).instanceOf(Error); - expect((err as Error).message).to.equal( - "Timeout while processing message '\x04'", - ); - } - }); - }); - - suite('Sends request', function () { - test('and retrieve the corresponding response', async function () { - const reqId = '1234'; - - MockBinding.createPort('/dev/echoserialport', { - echo: true, - record: true, - readyData: Buffer.from(`{"m":0, "r": "response", "i": "${reqId}"}\r`), - }); - SerialPort.Binding = MockBinding; - const port = new SerialPort('/dev/echoserialport'); - const api = new _testing.API(port); - - const response = await api.sendRequest( - 'request', - { param1: '1', param2: 2 }, - 500, - reqId, - ); - - expect(port.binding.recording.toString()).to.equal( - '{"m":"request","p":{"param1":"1","param2":2},"i":"1234"}\r', - ); - expect(response).to.equal('response'); - }); - - test('and raises an exception in case of error', async function () { - const reqId = '1234'; - - MockBinding.createPort('/dev/echoserialport', { - echo: true, - record: true, - readyData: Buffer.from( - `{"m":0, "e": "eyJtZXNzYWdlIjogImVycm9yIn0=", "i": "${reqId}"}\r`, - ), - }); - SerialPort.Binding = MockBinding; - const port = new SerialPort('/dev/echoserialport'); - const api = new _testing.API(port); - - try { - await api.sendRequest( - 'request', - { param1: '1', param2: 2 }, - 500, - reqId, - ); - } catch (error) { - expect(port.binding.recording.toString()).to.equal( - '{"m":"request","p":{"param1":"1","param2":2},"i":"1234"}\r', - ); - expect(error).instanceOf(Error); - expect((error as Error).message).to.equal('error'); - } - }); - - test('and times out if the response does not come back in time', async function () { - const reqId = '1234'; - MockBinding.createPort('/dev/echoserialport', { - echo: false, - record: true, - readyData: Buffer.from(''), - }); - SerialPort.Binding = MockBinding; - const port = new SerialPort('/dev/echoserialport'); - const api = new _testing.API(port); - - try { - const response = await api.sendRequest( - 'request', - { param1: '1', param2: 2 }, - 500, - reqId, - ); - } catch (error) { - expect(port.binding.recording.toString()).to.equal( - '{"m":"request","p":{"param1":"1","param2":2},"i":"1234"}\r', - ); - expect(error.message).to.equal( - 'Timeout while processing message \'{"m":"request","p":{"param1":"1","param2":2},"i":"1234"}\'', - ); - } - }); - }); -}); diff --git a/src/test/suite/extension.test.ts b/src/test/suite/extension.test.ts deleted file mode 100644 index 55655fb..0000000 --- a/src/test/suite/extension.test.ts +++ /dev/null @@ -1,14 +0,0 @@ -import * as assert from 'assert'; -import * as vscode from 'vscode'; - -suite('Extension Test Suite', function () { - vscode.window.showInformationMessage('Start all tests.'); - - test('Activate the extension', async function () { - const ext = vscode.extensions.getExtension('robmosca.robotinventor'); - assert.notStrictEqual(ext, undefined); - assert.strictEqual(ext?.isActive, false); - await ext?.activate(); - assert.strictEqual(ext?.isActive, true); - }); -}); diff --git a/src/test/suite/helpers/SerialProcessor.test.ts b/src/test/suite/helpers/SerialProcessor.test.ts deleted file mode 100644 index 5fefccd..0000000 --- a/src/test/suite/helpers/SerialProcessor.test.ts +++ /dev/null @@ -1,58 +0,0 @@ -import * as sinon from 'sinon'; -import * as sinonChai from 'sinon-chai'; -import * as chai from 'chai'; -import SerialProcessor from '../../../SerialProcessor'; - -const SerialPort = require('@serialport/stream'); -const MockBinding = require('@serialport/binding-mock'); - -chai.use(sinonChai); -const expect = chai.expect; - -suite('SerialProcessor Test Suite', () => { - setup(function () { - MockBinding.reset(); - }); - - test('Sends the message and processes the reply', async function () { - const callback = sinon.stub(); - callback.returns({ resolve: true, returnValue: 'This is the answer' }); - MockBinding.createPort('/dev/echoserialport', { - echo: true, - record: true, - readyData: Buffer.from([]), - }); - SerialPort.Binding = MockBinding; - const port = new SerialPort('/dev/echoserialport'); - const sp = new SerialProcessor(port, callback); - - const response = await sp.sendAndProcess('test message', 30); - - expect(port.binding.recording.toString()).to.equal('test message\r'); - expect(callback).to.have.been.calledWith('test message\r'); - expect(response).to.equal('This is the answer'); - }); - - test('Times out after n milliseconds', async function () { - const callback = sinon.stub(); - callback.returns({ resolve: true, returnValue: 'This is the answer' }); - MockBinding.createPort('/dev/muteserialport', { - echo: false, - record: true, - readyData: Buffer.from([]), - }); - SerialPort.Binding = MockBinding; - const port = new SerialPort('/dev/muteserialport'); - const sp = new SerialProcessor(port, callback); - - try { - await sp.sendAndProcess('test message', 30); - } catch (err) { - expect(port.binding.recording.toString()).to.equal('test message\r'); - expect(callback).to.not.have.been.called; - expect(err.message).to.equal( - "Timeout while processing message 'test message'", - ); - } - }); -}); diff --git a/src/test/suite/helpers/askDevice.test.ts b/src/test/suite/helpers/askDevice.test.ts deleted file mode 100644 index aa3cee2..0000000 --- a/src/test/suite/helpers/askDevice.test.ts +++ /dev/null @@ -1,57 +0,0 @@ -import * as vscode from 'vscode'; -import * as chai from 'chai'; -import { askDeviceFromList } from '../../../extension'; - -const SerialPort = require('@serialport/stream'); -const MockBinding = require('@serialport/binding-mock'); - -const expect = chai.expect; - -suite('askDeviceFromList Test Suite', function () { - setup(function () { - MockBinding.reset(); - }); - - test('Select port corresponding to a LEGO Hub', async function () { - MockBinding.createPort('/dev/hubserialport', { - echo: true, - record: true, - readyData: Buffer.from([]), - manufacturer: 'LEGO System A/S', - }); - SerialPort.Binding = MockBinding; - - const response = askDeviceFromList("I don't see my device..."); - - await vscode.commands.executeCommand( - 'workbench.action.quickOpenSelectNext', - ); - await vscode.commands.executeCommand( - 'workbench.action.acceptSelectedQuickOpenItem', - ); - - const data = await response; - expect(data).to.equal('/dev/hubserialport'); - }); - - test('Shows only ports corresponding to a LEGO Hub', async function () { - MockBinding.createPort('/dev/anotherserialport', { - echo: true, - record: true, - readyData: Buffer.from([]), - }); - SerialPort.Binding = MockBinding; - - const response = askDeviceFromList("I don't see my device..."); - - await vscode.commands.executeCommand( - 'workbench.action.quickOpenSelectNext', - ); - await vscode.commands.executeCommand( - 'workbench.action.acceptSelectedQuickOpenItem', - ); - - const data = await response; - expect(data).to.equal("I don't see my device..."); - }); -}); diff --git a/src/test/suite/index.ts b/src/test/suite/index.ts deleted file mode 100644 index 8ced9b1..0000000 --- a/src/test/suite/index.ts +++ /dev/null @@ -1,38 +0,0 @@ -import * as path from 'path'; -import * as Mocha from 'mocha'; -import * as glob from 'glob'; - -export function run(): Promise { - // Create the mocha test - const mocha = new Mocha({ - ui: 'tdd', - color: true, - }); - - const testsRoot = path.resolve(__dirname, '..'); - - return new Promise((c, e) => { - glob('**/**.test.js', { cwd: testsRoot }, (err, files) => { - if (err) { - return e(err); - } - - // Add files to the test suite - files.forEach((f) => mocha.addFile(path.resolve(testsRoot, f))); - - try { - // Run the mocha test - mocha.run((failures) => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } - }); - } catch (err) { - console.error(err); - e(err); - } - }); - }); -} diff --git a/src/test/suite/utils.test.ts b/src/test/suite/utils.test.ts deleted file mode 100644 index edf74c8..0000000 --- a/src/test/suite/utils.test.ts +++ /dev/null @@ -1,85 +0,0 @@ -import * as vscode from 'vscode'; -import * as sinon from 'sinon'; -import * as sinonChai from 'sinon-chai'; -import * as chai from 'chai'; -import { - decodeBase64, - encodeBase64, - formatFilesize, - randomId, - showTemporaryStatusBarMessage, -} from '../../utils'; - -const chaiMatch = require('chai-match'); - -const mockSetStatusBarMessage = sinon.spy(vscode.window, 'setStatusBarMessage'); - -chai.use(sinonChai); -chai.use(chaiMatch); -const expect = chai.expect; - -suite('Utils Test Suite', function () { - suite('showTemporaryStatusBarMessage', function () { - test('Shows temporary message in status bar', function () { - showTemporaryStatusBarMessage('This is a test message'); - expect(mockSetStatusBarMessage).to.have.been.calledWith( - 'This is a test message', - ); - }); - }); - - suite('randomId', function () { - test('Generates an empty id', function () { - for (let length = -4; length < 1; ++length) { - expect(randomId(length)).to.equal(''); - } - }); - - test('Generates a random id', function () { - for (let length = 1; length < 10; ++length) { - const randId = randomId(length); - expect(randId.length).to.equal(length); - expect(randId).to.match(/^[0-9a-zA-Z]+$/); - } - }); - }); - - suite('decodeBase64', function () { - test('Decodes from base64', function () { - expect(decodeBase64('')).to.equal(''); - expect(decodeBase64('VGhpcyBpcyBhIHRlc3Q=')).to.equal('This is a test'); - expect( - decodeBase64('VDNzdCB3MXRoIG51bThlcjUgJiBjaDZyYWN0M3JzISE='), - ).to.equal('T3st w1th num8er5 & ch6ract3rs!!'); - }); - }); - - suite('encodeBase64', function () { - test('Encodes in base64', function () { - expect(encodeBase64('')).to.equal(''); - expect(encodeBase64('A simple test :)')).to.equal( - 'QSBzaW1wbGUgdGVzdCA6KQ==', - ); - expect( - encodeBase64('Hey, what a t3st th1s 1 with num8er5 & ch6ract3rs!!'), - ).to.equal( - 'SGV5LCB3aGF0IGEgdDNzdCB0aDFzIDEgd2l0aCBudW04ZXI1ICYgY2g2cmFjdDNycyEh', - ); - }); - }); - - suite('formatFilesize', function () { - test('Formats file sizes', function () { - expect(formatFilesize(0)).to.equal('0 B'); - expect(formatFilesize(54)).to.equal('54 B'); - expect(formatFilesize(1024)).to.equal('1 KB'); - expect(formatFilesize(Math.pow(1024, 2))).to.equal('1 MB'); - expect(formatFilesize(Math.pow(1024, 3))).to.equal('1 GB'); - expect(formatFilesize(Math.pow(1024, 4))).to.equal('1 TB'); - expect(formatFilesize(Math.pow(1024, 5))).to.equal('1 PB'); - expect(formatFilesize(Math.pow(1024, 6))).to.equal('1 EB'); - expect(formatFilesize(Math.pow(1024, 7))).to.equal('1 ZB'); - expect(formatFilesize(Math.pow(1024, 8))).to.equal('1 YB'); - }); - }); -});