From 8ed4611bf21e74a7eabb02a8a49a900f943ee033 Mon Sep 17 00:00:00 2001 From: Hao Chen <501018786@qq.com> Date: Fri, 18 Oct 2024 01:26:30 +0800 Subject: [PATCH] test: replace jest-mock with sinon, drop expect --- .github/dependabot.yml | 4 +- package-lock.json | 489 +++++++++--------- .../__tests__/integration.test.ts | 29 +- packages/integration-tests/package.json | 6 +- .../integration-tests/src/factory.test.ts | 98 ++-- packages/neovim/package.json | 4 +- packages/neovim/src/api/Buffer.test.ts | 184 +++---- packages/neovim/src/api/Neovim.test.ts | 143 +++-- packages/neovim/src/api/Tabpage.test.ts | 70 ++- packages/neovim/src/api/Window.test.ts | 87 ++-- packages/neovim/src/attach/attach.test.ts | 82 +-- packages/neovim/src/host/NvimPlugin.test.ts | 78 +-- packages/neovim/src/plugin/plugin.test.ts | 26 +- packages/neovim/src/testSetup.ts | 9 +- packages/neovim/src/testUtil.ts | 18 +- packages/neovim/src/utils/findNvim.test.ts | 143 ++--- packages/neovim/src/utils/transport.test.ts | 5 +- 17 files changed, 751 insertions(+), 724 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index ce02bc9e..6a57a41a 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -33,9 +33,9 @@ updates: patterns: - 'mocha*' - '@types/mocha' - - 'jest*' + - '@types/sinon' + - 'sinon' - 'c8' - - 'expect' # Check for updates to GitHub Actions every week - package-ecosystem: 'github-actions' directory: '/' diff --git a/package-lock.json b/package-lock.json index e32c4a00..7b5475f8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2306,18 +2306,6 @@ "node": ">=8" } }, - "node_modules/@jest/expect-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", - "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", - "dev": true, - "dependencies": { - "jest-get-type": "^29.6.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "node_modules/@jest/schemas": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", @@ -2504,6 +2492,50 @@ "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", "dev": true }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.2.tgz", + "integrity": "sha512-4Bb+oqXZTSTZ1q27Izly9lv8B9dlV61CROxPiVtywwzv5SnytJqhvYe6FclHYuXml4cd1VHPo1zd5PmTeJozvA==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^3.0.1" + } + }, + "node_modules/@sinonjs/samsam": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.2.tgz", + "integrity": "sha512-v46t/fwnhejRSFTGqbpn9u+LQ9xJDse10gNnPgAcxgdoCDMXj/G2asWAC/8Qs+BAZDicX+MNZouXT1A7c83kVw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^3.0.1", + "lodash.get": "^4.4.2", + "type-detect": "^4.1.0" + } + }, + "node_modules/@sinonjs/samsam/node_modules/type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@sinonjs/text-encoding": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.3.tgz", + "integrity": "sha512-DE427ROAphMQzU4ENbliGYrBSYPXF+TtLg9S8vzeA+OF4ZKzoDdzfL8sxuMUGS/lgRhM6j1URSk9ghf7Xo1tyA==", + "dev": true + }, "node_modules/@tsconfig/node10": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", @@ -2606,10 +2638,19 @@ "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", "dev": true }, - "node_modules/@types/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "node_modules/@types/sinon": { + "version": "17.0.3", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.3.tgz", + "integrity": "sha512-j3uovdn8ewky9kRBG19bOwaZbexJu/XjtkHyjvUgt4xfPFz18dcORIMqnYh66Fx3Powhcr85NT5+er3+oViapw==", + "dev": true, + "dependencies": { + "@types/sinonjs__fake-timers": "*" + } + }, + "node_modules/@types/sinonjs__fake-timers": { + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.5.tgz", + "integrity": "sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==", "dev": true }, "node_modules/@types/triple-beam": { @@ -3737,15 +3778,6 @@ "node": ">=0.3.1" } }, - "node_modules/diff-sequences": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", - "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", - "dev": true, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -4422,22 +4454,6 @@ "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", "dev": true }, - "node_modules/expect": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", - "dev": true, - "dependencies": { - "@jest/expect-utils": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -5398,21 +5414,6 @@ "@pkgjs/parseargs": "^0.11.0" } }, - "node_modules/jest-diff": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", - "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^29.6.3", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "node_modules/jest-get-type": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", @@ -5447,55 +5448,6 @@ "fsevents": "^2.3.2" } }, - "node_modules/jest-matcher-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", - "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-message-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", - "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.6.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-mock": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", - "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", - "dev": true, - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "node_modules/jest-pnp-resolver": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", @@ -5666,6 +5618,12 @@ "json5": "lib/cli.js" } }, + "node_modules/just-extend": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz", + "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==", + "dev": true + }, "node_modules/kuler": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", @@ -5995,6 +5953,12 @@ "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", "dev": true }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "dev": true + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -6547,6 +6511,19 @@ "resolved": "packages/neovim", "link": true }, + "node_modules/nise": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/nise/-/nise-6.1.1.tgz", + "integrity": "sha512-aMSAzLVY7LyeM60gvBS423nBmIPP+Wy7St7hsb+8/fc1HmeoHJfLO8CKse4u3BtOZvQLJghYPI2i/1WZrEj5/g==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^3.0.1", + "@sinonjs/fake-timers": "^13.0.1", + "@sinonjs/text-encoding": "^0.7.3", + "just-extend": "^6.2.0", + "path-to-regexp": "^8.1.0" + } + }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -6861,6 +6838,15 @@ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "dev": true }, + "node_modules/path-to-regexp": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", + "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -7520,6 +7506,33 @@ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" }, + "node_modules/sinon": { + "version": "19.0.2", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-19.0.2.tgz", + "integrity": "sha512-euuToqM+PjO4UgXeLETsfQiuoyPXlqFezr6YZDFwHR3t4qaX0fZUe1MfPMznTL5f8BWrVS89KduLdMUsxFCO6g==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^3.0.1", + "@sinonjs/fake-timers": "^13.0.2", + "@sinonjs/samsam": "^8.0.1", + "diff": "^7.0.0", + "nise": "^6.1.1", + "supports-color": "^7.2.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/sinon" + } + }, + "node_modules/sinon/node_modules/diff": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", + "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -7609,27 +7622,6 @@ "node": "*" } }, - "node_modules/stack-utils": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", - "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -8017,6 +8009,15 @@ "node": ">= 0.8.0" } }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", @@ -8601,10 +8602,10 @@ }, "devDependencies": { "@types/mocha": "^10.0.9", + "@types/sinon": "^17.0.3", "c8": "^10.1.2", - "expect": "^29.7.0", - "jest-mock": "^29.7.0", - "mocha": "^10.7.3" + "mocha": "^10.7.3", + "sinon": "^19.0.2" } }, "packages/neovim": { @@ -8624,10 +8625,10 @@ "@babel/preset-typescript": "^7.24.7", "@types/mocha": "^10.0.9", "@types/node": "^16.18.113", + "@types/sinon": "^17.0.3", "c8": "^10.1.2", - "expect": "^29.7.0", - "jest-mock": "^29.7.0", "mocha": "^10.7.3", + "sinon": "^19.0.2", "ts-node": "^10.9.2", "typedoc": "^0.26.7", "typescript": "^5.6.3" @@ -10233,15 +10234,6 @@ "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true }, - "@jest/expect-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", - "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", - "dev": true, - "requires": { - "jest-get-type": "^29.6.3" - } - }, "@jest/schemas": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", @@ -10369,11 +10361,11 @@ "requires": { "@neovim/example-plugin": "file:../example-plugin", "@types/mocha": "^10.0.9", + "@types/sinon": "^17.0.3", "c8": "^10.1.2", - "expect": "^29.7.0", - "jest-mock": "^29.7.0", "mocha": "^10.7.3", - "neovim": "file:../neovim" + "neovim": "file:../neovim", + "sinon": "^19.0.2" } }, "@nicolo-ribaudo/chokidar-2": { @@ -10444,6 +10436,49 @@ "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", "dev": true }, + "@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.2.tgz", + "integrity": "sha512-4Bb+oqXZTSTZ1q27Izly9lv8B9dlV61CROxPiVtywwzv5SnytJqhvYe6FclHYuXml4cd1VHPo1zd5PmTeJozvA==", + "dev": true, + "requires": { + "@sinonjs/commons": "^3.0.1" + } + }, + "@sinonjs/samsam": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.2.tgz", + "integrity": "sha512-v46t/fwnhejRSFTGqbpn9u+LQ9xJDse10gNnPgAcxgdoCDMXj/G2asWAC/8Qs+BAZDicX+MNZouXT1A7c83kVw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^3.0.1", + "lodash.get": "^4.4.2", + "type-detect": "^4.1.0" + }, + "dependencies": { + "type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "dev": true + } + } + }, + "@sinonjs/text-encoding": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.3.tgz", + "integrity": "sha512-DE427ROAphMQzU4ENbliGYrBSYPXF+TtLg9S8vzeA+OF4ZKzoDdzfL8sxuMUGS/lgRhM6j1URSk9ghf7Xo1tyA==", + "dev": true + }, "@tsconfig/node10": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", @@ -10546,10 +10581,19 @@ "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", "dev": true }, - "@types/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "@types/sinon": { + "version": "17.0.3", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.3.tgz", + "integrity": "sha512-j3uovdn8ewky9kRBG19bOwaZbexJu/XjtkHyjvUgt4xfPFz18dcORIMqnYh66Fx3Powhcr85NT5+er3+oViapw==", + "dev": true, + "requires": { + "@types/sinonjs__fake-timers": "*" + } + }, + "@types/sinonjs__fake-timers": { + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.5.tgz", + "integrity": "sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==", "dev": true }, "@types/triple-beam": { @@ -11327,12 +11371,6 @@ "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", "dev": true }, - "diff-sequences": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", - "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", - "dev": true - }, "dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -11833,19 +11871,6 @@ "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", "dev": true }, - "expect": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", - "dev": true, - "requires": { - "@jest/expect-utils": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0" - } - }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -12526,18 +12551,6 @@ "@pkgjs/parseargs": "^0.11.0" } }, - "jest-diff": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", - "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^29.6.3", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - } - }, "jest-get-type": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", @@ -12564,46 +12577,6 @@ "walker": "^1.0.8" } }, - "jest-matcher-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", - "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - } - }, - "jest-message-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", - "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.6.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - } - }, - "jest-mock": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", - "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", - "dev": true, - "requires": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-util": "^29.7.0" - } - }, "jest-pnp-resolver": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", @@ -12732,6 +12705,12 @@ "minimist": "^1.2.0" } }, + "just-extend": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz", + "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==", + "dev": true + }, "kuler": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", @@ -12951,6 +12930,12 @@ "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", "dev": true }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "dev": true + }, "lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -13368,16 +13353,29 @@ "@msgpack/msgpack": "^2.8.0", "@types/mocha": "^10.0.9", "@types/node": "^16.18.113", + "@types/sinon": "^17.0.3", "c8": "^10.1.2", - "expect": "^29.7.0", - "jest-mock": "^29.7.0", "mocha": "^10.7.3", + "sinon": "^19.0.2", "ts-node": "^10.9.2", "typedoc": "^0.26.7", "typescript": "^5.6.3", "winston": "3.15.0" } }, + "nise": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/nise/-/nise-6.1.1.tgz", + "integrity": "sha512-aMSAzLVY7LyeM60gvBS423nBmIPP+Wy7St7hsb+8/fc1HmeoHJfLO8CKse4u3BtOZvQLJghYPI2i/1WZrEj5/g==", + "dev": true, + "requires": { + "@sinonjs/commons": "^3.0.1", + "@sinonjs/fake-timers": "^13.0.1", + "@sinonjs/text-encoding": "^0.7.3", + "just-extend": "^6.2.0", + "path-to-regexp": "^8.1.0" + } + }, "node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -13620,6 +13618,12 @@ } } }, + "path-to-regexp": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", + "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==", + "dev": true + }, "path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -14077,6 +14081,28 @@ } } }, + "sinon": { + "version": "19.0.2", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-19.0.2.tgz", + "integrity": "sha512-euuToqM+PjO4UgXeLETsfQiuoyPXlqFezr6YZDFwHR3t4qaX0fZUe1MfPMznTL5f8BWrVS89KduLdMUsxFCO6g==", + "dev": true, + "requires": { + "@sinonjs/commons": "^3.0.1", + "@sinonjs/fake-timers": "^13.0.2", + "@sinonjs/samsam": "^8.0.1", + "diff": "^7.0.0", + "nise": "^6.1.1", + "supports-color": "^7.2.0" + }, + "dependencies": { + "diff": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", + "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==", + "dev": true + } + } + }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -14144,23 +14170,6 @@ "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" }, - "stack-utils": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", - "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", - "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - } - } - }, "string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -14439,6 +14448,12 @@ "prelude-ls": "^1.2.1" } }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, "type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", diff --git a/packages/integration-tests/__tests__/integration.test.ts b/packages/integration-tests/__tests__/integration.test.ts index 1b0454d7..8e192b2c 100644 --- a/packages/integration-tests/__tests__/integration.test.ts +++ b/packages/integration-tests/__tests__/integration.test.ts @@ -2,8 +2,9 @@ import * as cp from 'node:child_process'; import * as fs from 'node:fs'; import * as path from 'node:path'; import * as http from 'node:http'; -import expect from 'expect'; -import * as jestMock from 'jest-mock'; +import assert from 'node:assert'; +// eslint-disable-next-line import/no-extraneous-dependencies +import sinon from 'sinon'; import { NeovimClient, attach, findNvim } from 'neovim'; @@ -75,37 +76,40 @@ describe('Node host', () => { // }); it('console.log is monkey-patched to logger.info #329', async () => { - const spy = jestMock.spyOn(nvim.logger, 'info'); + const spy = sinon.spy(nvim.logger, 'info'); + // eslint-disable-next-line no-console console.log('log message'); - expect(spy).toHaveBeenCalledWith('log message'); + // @ts-expect-error Sinon types are broken with overloads + // see https://github.com/DefinitelyTyped/DefinitelyTyped/issues/36436 + assert(spy.calledWith('log message')); // Still alive? - expect(await nvim.eval('1+1')).toEqual(2); + assert.strictEqual(await nvim.eval('1+1'), 2); }); it('can run a command from plugin', async () => { await nvim.command('JSHostTestCmd'); const line = await nvim.line; - expect(line).toEqual('A line, for your troubles'); + assert.strictEqual(line, 'A line, for your troubles'); }); it('can catch thrown errors from plugin', async () => { try { await nvim.command('JSHostTestCmd canhazresponse?'); // Below should not be evaluated because above throws - expect(true).toEqual(false); + assert.strictEqual(true, false); } catch (err) { - expect(err).toBeInstanceOf(Error); + assert(err instanceof Error); } }); it('can call a function from plugin', async () => { const result = await nvim.callFunction('Func', []); - expect(result).toEqual('Funcy '); + assert.strictEqual(result, 'Funcy '); }); it('can call a function from plugin with args', async () => { const result = await nvim.callFunction('Func', ['args']); - expect(result).toEqual('Funcy args'); + assert.strictEqual(result, 'Funcy args'); }); it.skip('can call a function from plugin with args', async () => { @@ -129,8 +133,9 @@ describe('Node host', () => { try { const debugData = JSON.parse(rawData); childHost.kill(); - expect(Array.isArray(debugData) && debugData.length).toBeTruthy(); - expect(debugData[0].webSocketDebuggerUrl).toMatch( + assert(Array.isArray(debugData) && debugData.length); + sinon.assert.match( + debugData[0].webSocketDebuggerUrl, 'ws://127.0.0.1:9229' ); done(); diff --git a/packages/integration-tests/package.json b/packages/integration-tests/package.json index 426d85e8..6da8bcaf 100644 --- a/packages/integration-tests/package.json +++ b/packages/integration-tests/package.json @@ -51,9 +51,9 @@ ], "devDependencies": { "@types/mocha": "^10.0.9", + "@types/sinon": "^17.0.3", "c8": "^10.1.2", - "expect": "^29.7.0", - "jest-mock": "^29.7.0", - "mocha": "^10.7.3" + "mocha": "^10.7.3", + "sinon": "^19.0.2" } } diff --git a/packages/integration-tests/src/factory.test.ts b/packages/integration-tests/src/factory.test.ts index f57bcb90..5256361c 100644 --- a/packages/integration-tests/src/factory.test.ts +++ b/packages/integration-tests/src/factory.test.ts @@ -1,5 +1,5 @@ import { Neovim, NeovimClient, NvimPlugin, loadPlugin } from 'neovim'; -import expect from 'expect'; +import assert from 'node:assert'; function getFakeNvimClient(): NeovimClient { const logged: string[] = []; @@ -47,46 +47,52 @@ describe('Plugin Factory (used by host)', () => { { type: 'function', name: 'Func', sync: true, opts: {} }, { type: 'function', name: 'Global', sync: true, opts: {} }, ]; - expect(pluginObj.specs).toEqual(expected); + assert.deepStrictEqual(pluginObj.specs, expected); }); it('should collect the handlers from a plugin', async () => { - expect(await pluginObj.handleRequest('Func', 'function', ['town'])).toEqual( + assert.strictEqual( + await pluginObj.handleRequest('Func', 'function', ['town']), 'Funcy town' ); }); it('should load the plugin a sandbox', async () => { - expect( - await pluginObj.handleRequest('Global', 'function', ['loaded']) - ).toEqual(true); - expect( - await pluginObj.handleRequest('Global', 'function', ['Buffer']) - ).not.toEqual(undefined); - expect( - await pluginObj.handleRequest('Global', 'function', ['process']) - ).not.toContain(['chdir', 'exit']); + assert.strictEqual( + await pluginObj.handleRequest('Global', 'function', ['loaded']), + true + ); + assert.notStrictEqual( + await pluginObj.handleRequest('Global', 'function', ['Buffer']), + undefined + ); + const result = await pluginObj.handleRequest('Global', 'function', [ + 'process', + ]); + + // expect( + // await pluginObj.handleRequest('Global', 'function', ['process']) + // ).not.toContain(['chdir', 'exit']); + + assert('chdir' in result); + assert('exit' in result); }); it('should load files required by the plugin in a sandbox', async () => { - expect( - await pluginObj.handleRequest('Global', 'function', ['required']) - ).toEqual('you bet!'); - // expect( - // Object.keys(required.globals.process), - // ).not.toContain( - // ['chdir', 'exit'], - // ); + assert.strictEqual( + await pluginObj.handleRequest('Global', 'function', ['required']), + 'you bet!' + ); }); it('loads plugin with instance of nvim API', () => { const nvim = getFakeNvimClient(); const plugin = loadPlugin('@neovim/example-plugin', nvim); - expect(plugin?.nvim).toBe(nvim); + assert.strictEqual(plugin?.nvim, nvim); }); it('returns null on invalid module', () => { - expect(loadPlugin('/asdlfjka/fl', {} as Neovim, {})).toBeNull(); + assert.strictEqual(loadPlugin('/asdlfjka/fl', {} as Neovim, {}), null); }); }); @@ -121,52 +127,58 @@ describe('Plugin Factory (decorator api)', () => { { type: 'function', name: 'Func', sync: true, opts: {} }, { type: 'function', name: 'Global', sync: true, opts: {} }, { type: 'function', name: 'Illegal', sync: true, opts: {} }, + { type: 'function', name: 'Umask', sync: true, opts: {} }, ]; - expect(pluginObj.specs).toEqual(expect.arrayContaining(expected)); + assert.deepStrictEqual(pluginObj.specs, expected); }); it('should collect the handlers from a plugin', async () => { - expect(await pluginObj.handleRequest('Func', 'function', ['town'])).toEqual( + assert.strictEqual( + await pluginObj.handleRequest('Func', 'function', ['town']), 'Funcy town' ); }); - it('should load the plugin a sandbox', async () => { - expect( - await pluginObj.handleRequest('Global', 'function', ['loaded']) - ).toEqual(true); - expect( - await pluginObj.handleRequest('Global', 'function', ['process']) - ).not.toContain(['chdir', 'exit']); + it('should load the plugin in a sandbox', async () => { + assert.strictEqual( + await pluginObj.handleRequest('Global', 'function', ['loaded']), + true + ); + const result = await pluginObj.handleRequest('Global', 'function', [ + 'process', + ]); + + // expect( + // await pluginObj.handleRequest('Global', 'function', ['process']) + // ).not.toContain(['chdir', 'exit']); + // + assert('chdir' in result); + assert('exit' in result); }); it('should load files required by the plugin in a sandbox', async () => { - expect( - await pluginObj.handleRequest('Global', 'function', ['required']) - ).toEqual('you bet!'); - // expect( - // Object.keys(required.globals.process), - // ).not.toContain( - // ['chdir', 'exit'], - // ); + assert.strictEqual( + await pluginObj.handleRequest('Global', 'function', ['required']), + 'you bet!' + ); }); it('loads plugin with instance of nvim API', () => { const nvim = getFakeNvimClient(); const plugin = loadPlugin('@neovim/example-plugin-decorators', nvim, {}); - expect(plugin!.nvim).toBe(nvim); + assert.strictEqual(plugin!.nvim, nvim); }); it('cannot call illegal process functions', () => { const nvim = getFakeNvimClient(); const plugin = loadPlugin('@neovim/example-plugin-decorators', nvim, {}); - expect(plugin!.functions.Illegal.fn).toThrow(); + assert.throws(() => plugin!.functions.Illegal.fn()); }); it('can read process.umask()', () => { const nvim = getFakeNvimClient(); const plugin = loadPlugin('@neovim/example-plugin-decorators', nvim, {}); - expect(() => plugin!.functions.Umask.fn()).not.toThrow(); - expect(plugin!.functions.Umask.fn()).toBeDefined(); + assert.doesNotThrow(() => plugin!.functions.Umask.fn()); + assert.notStrictEqual(plugin!.functions.Umask.fn(), undefined); }); }); diff --git a/packages/neovim/package.json b/packages/neovim/package.json index 33606ac0..a4baeca3 100644 --- a/packages/neovim/package.json +++ b/packages/neovim/package.json @@ -60,10 +60,10 @@ "@babel/preset-typescript": "^7.24.7", "@types/mocha": "^10.0.9", "@types/node": "^16.18.113", + "@types/sinon": "^17.0.3", "c8": "^10.1.2", - "expect": "^29.7.0", - "jest-mock": "^29.7.0", "mocha": "^10.7.3", + "sinon": "^19.0.2", "ts-node": "^10.9.2", "typedoc": "^0.26.7", "typescript": "^5.6.3" diff --git a/packages/neovim/src/api/Buffer.test.ts b/packages/neovim/src/api/Buffer.test.ts index 44455869..8e5e048b 100644 --- a/packages/neovim/src/api/Buffer.test.ts +++ b/packages/neovim/src/api/Buffer.test.ts @@ -1,6 +1,5 @@ import assert from 'node:assert'; -import { expect } from 'expect'; -import * as jestMock from 'jest-mock'; +import sinon from 'sinon'; import * as testUtil from '../testUtil'; import type { Buffer } from './Buffer'; @@ -47,7 +46,7 @@ describe('Buffer API', () => { it( 'gets the current buffer', withBuffer([], async buffer => { - expect(buffer).toBeInstanceOf(nvim.Buffer); + assert(buffer instanceof nvim.Buffer); }) ); @@ -55,7 +54,7 @@ describe('Buffer API', () => { 'get bufnr by id', withBuffer([], async buffer => { const bufnr = await nvim.call('bufnr', ['%']); - expect(buffer.id).toBe(bufnr); + assert.strictEqual(buffer.id, bufnr); }) ); @@ -67,24 +66,24 @@ describe('Buffer API', () => { // insert a line buffer.append('hi'); - expect(await buffer.changedtick).toBe(initial + 1); + assert.strictEqual(await buffer.changedtick, initial + 1); // clear buffer buffer.remove(0, -1, false); - expect(await buffer.changedtick).toBe(initial + 2); + assert.strictEqual(await buffer.changedtick, initial + 2); }) ); it('sets/gets the current buffer name', async () => { (await nvim.buffers)[0].name = 'hello.txt'; const name = await (await nvim.buffers)[0].name; - expect(name).toMatch('hello.txt'); + assert(name.match('hello.txt')); }); it( 'is a valid buffer', withBuffer([], async buffer => { - expect(await buffer.valid).toBe(true); + assert.strictEqual(await buffer.valid, true); }) ); @@ -93,10 +92,11 @@ describe('Buffer API', () => { withBuffer([], async buffer => { // eslint-disable-next-line no-param-reassign buffer.name = 'foo.txt'; - expect(await buffer.name).toMatch('foo.txt'); + assert((await buffer.name).match('foo.txt')); + // eslint-disable-next-line no-param-reassign buffer.name = 'test2.txt'; - expect(await buffer.name).toMatch('test2.txt'); + assert((await buffer.name).match('test2.txt')); }) ); @@ -104,7 +104,7 @@ describe('Buffer API', () => { 'can replace first line of buffer with a string', withBuffer(['foo'], async buffer => { buffer.replace('test', 0); - expect(await buffer.lines).toEqual(['test']); + assert.deepStrictEqual(await buffer.lines, ['test']); }) ); @@ -112,7 +112,7 @@ describe('Buffer API', () => { 'can insert lines at beginning of buffer', withBuffer(['test'], async buffer => { await buffer.insert(['test', 'foo'], 0); - expect(await buffer.lines).toEqual(['test', 'foo', 'test']); + assert.deepStrictEqual(await buffer.lines, ['test', 'foo', 'test']); }) ); @@ -123,7 +123,7 @@ describe('Buffer API', () => { async buffer => { await buffer.replace(['a', 'b', 'c'], 2); - expect(await buffer.lines).toEqual([ + assert.deepStrictEqual(await buffer.lines, [ '0', '1', 'a', @@ -143,7 +143,7 @@ describe('Buffer API', () => { 'inserts line at index 2', withBuffer(['test', 'bar', 'bar', 'bar'], async buffer => { buffer.insert(['foo'], 2); - expect(await buffer.lines).toEqual([ + assert.deepStrictEqual(await buffer.lines, [ 'test', 'bar', 'foo', @@ -157,26 +157,26 @@ describe('Buffer API', () => { 'removes last 2 lines', withBuffer(['test', 'bar', 'foo', 'a', 'b'], async buffer => { buffer.remove(-3, -1, true); - expect(await buffer.lines).toEqual(['test', 'bar', 'foo']); + assert.deepStrictEqual(await buffer.lines, ['test', 'bar', 'foo']); }) ); it('checks if buffer is loaded', async () => { await nvim.command('new'); const buffer = await nvim.buffer; - expect(await buffer.loaded).toBe(true); + assert.strictEqual(await buffer.loaded, true); await nvim.command('bunload!'); - expect(await buffer.loaded).toBe(false); + assert.strictEqual(await buffer.loaded, false); }); it( 'gets byte offset for a line', withBuffer(['test', 'bar', ''], async buffer => { - expect(await buffer.getOffset(0)).toEqual(0); - expect(await buffer.getOffset(1)).toEqual(5); // test\n - expect(await buffer.getOffset(2)).toEqual(9); // test\n + bar\n - expect(await buffer.getOffset(3)).toEqual(10); // test\n + bar\n + \n - expect(buffer.getOffset(4)).rejects.toThrow(); + assert.strictEqual(await buffer.getOffset(0), 0); + assert.strictEqual(await buffer.getOffset(1), 5); // test\n + assert.strictEqual(await buffer.getOffset(2), 9); // test\n + bar\n + assert.strictEqual(await buffer.getOffset(3), 10); // test\n + bar\n + \n + await assert.rejects(buffer.getOffset(4)); }) ); @@ -184,7 +184,7 @@ describe('Buffer API', () => { await nvim.command('new'); await nvim.command('bunload!'); const buffer = await nvim.buffer; - expect(await buffer.getOffset(0)).toEqual(-1); + assert.strictEqual(await buffer.getOffset(0), -1); }); it( @@ -192,7 +192,7 @@ describe('Buffer API', () => { withBuffer(['test', 'bar', 'foo'], async buffer => { await buffer.append(['test', 'test']); - expect(await buffer.lines).toEqual([ + assert.deepStrictEqual(await buffer.lines, [ 'test', 'bar', 'foo', @@ -207,8 +207,8 @@ describe('Buffer API', () => { withBuffer(['foo'], async buffer => { buffer.remove(0, -1, true); // One empty line - expect(await buffer.length).toEqual(1); - expect(await buffer.lines).toEqual(['']); + assert.strictEqual(await buffer.length, 1); + assert.deepStrictEqual(await buffer.lines, ['']); }) ); @@ -217,13 +217,13 @@ describe('Buffer API', () => { withBuffer([], async buffer => { const initial = await buffer.getOption('copyindent'); buffer.setOption('copyindent', true); - expect(await buffer.getOption('copyindent')).toBe(true); + assert.strictEqual(await buffer.getOption('copyindent'), true); buffer.setOption('copyindent', false); - expect(await buffer.getOption('copyindent')).toBe(false); + assert.strictEqual(await buffer.getOption('copyindent'), false); assert(initial !== undefined); // Restore option buffer.setOption('copyindent', initial); - expect(await buffer.getOption('copyindent')).toBe(initial); + assert.strictEqual(await buffer.getOption('copyindent'), initial); }) ); @@ -231,7 +231,7 @@ describe('Buffer API', () => { 'returns null if variable is not found', withBuffer([], async buffer => { const test = await buffer.getVar('test'); - expect(test).toBe(null); + assert.strictEqual(test, null); }) ); @@ -240,19 +240,20 @@ describe('Buffer API', () => { withBuffer([], async buffer => { buffer.setVar('test', { foo: 'testValue' }); - expect(await buffer.getVar('test')).toEqual({ foo: 'testValue' }); + assert.deepStrictEqual(await buffer.getVar('test'), { + foo: 'testValue', + }); - expect(await nvim.eval('b:test')).toEqual({ foo: 'testValue' }); + assert.deepStrictEqual(await nvim.eval('b:test'), { foo: 'testValue' }); buffer.deleteVar('test'); - expect(await nvim.eval('exists("b:test")')).toBe(0); + assert.strictEqual(await nvim.eval('exists("b:test")'), 0); - expect(await buffer.getVar('test')).toBe(null); + assert.strictEqual(await buffer.getVar('test'), null); }) ); - it('can get list of commands', async () => { - expect(await nvim.buffer.commands).toEqual({}); + assert.deepStrictEqual(await nvim.buffer.commands, {}); }); it( @@ -271,29 +272,29 @@ describe('Buffer API', () => { it('sets/gets the current buffer name using api chaining', async () => { const buffer = await nvim.buffer; buffer.name = 'goodbye.txt'; - expect(await nvim.buffer.name).toMatch('goodbye.txt'); + assert((await nvim.buffer.name).match('goodbye.txt')); }); it('can chain calls from Base class i.e. getOption', async () => { const buffer = await nvim.buffer; const initial = await buffer.getOption('copyindent'); buffer.setOption('copyindent', true); - expect(await buffer.getOption('copyindent')).toBe(true); + assert.strictEqual(await buffer.getOption('copyindent'), true); buffer.setOption('copyindent', false); - expect(await buffer.getOption('copyindent')).toBe(false); + assert.strictEqual(await buffer.getOption('copyindent'), false); assert(initial !== undefined); // Restore option buffer.setOption('copyindent', initial); - expect(await buffer.getOption('copyindent')).toBe(initial); + assert.strictEqual(await buffer.getOption('copyindent'), initial); }); it('sets current buffer name to "bar.js" using api chaining', async () => { const buffer = await nvim.buffer; buffer.name = 'bar.js'; - expect(await buffer.name).toMatch('bar.js'); + assert((await buffer.name).match('bar.js')); buffer.name = 'test2.js'; - expect(await buffer.name).toMatch('test2.js'); + assert((await buffer.name).match('test2.js')); }); it( @@ -301,7 +302,7 @@ describe('Buffer API', () => { withBuffer([], async () => { const buffer = await nvim.buffer; await buffer.replace('test', 0); - expect(await buffer.lines).toEqual(['test']); + assert.deepStrictEqual(await buffer.lines, ['test']); }) ); @@ -313,7 +314,7 @@ describe('Buffer API', () => { const buffer = await nvim.buffer; await buffer.replace(['a', 'b', 'c'], 2); - expect(await buffer.lines).toEqual([ + assert.deepStrictEqual(await buffer.lines, [ '0', '1', 'a', @@ -334,7 +335,7 @@ describe('Buffer API', () => { withBuffer(['test'], async () => { const buffer = await nvim.buffer; await buffer.insert(['test', 'foo'], 0); - expect(await buffer.lines).toEqual(['test', 'foo', 'test']); + assert.deepStrictEqual(await buffer.lines, ['test', 'foo', 'test']); }) ); @@ -343,7 +344,12 @@ describe('Buffer API', () => { withBuffer(['test', 'foo'], async () => { const buffer = await nvim.buffer; await buffer.replace(['bar', 'bar', 'bar'], 1); - expect(await buffer.lines).toEqual(['test', 'bar', 'bar', 'bar']); + assert.deepStrictEqual(await buffer.lines, [ + 'test', + 'bar', + 'bar', + 'bar', + ]); }) ); @@ -352,7 +358,7 @@ describe('Buffer API', () => { withBuffer(['test', 'bar', 'bar', 'bar'], async () => { const buffer = await nvim.buffer; await buffer.insert(['foo'], 2); - expect(await buffer.lines).toEqual([ + assert.deepStrictEqual(await buffer.lines, [ 'test', 'bar', 'foo', @@ -367,7 +373,7 @@ describe('Buffer API', () => { withBuffer(['test', 'bar', 'foo', 'a', 'b'], async () => { const buffer = await nvim.buffer; await buffer.remove(-3, -1, true); - expect(await buffer.lines).toEqual(['test', 'bar', 'foo']); + assert.deepStrictEqual(await buffer.lines, ['test', 'bar', 'foo']); }) ); @@ -376,7 +382,7 @@ describe('Buffer API', () => { withBuffer(['test', 'bar', 'foo'], async () => { const buffer = await nvim.buffer; await buffer.append(['test', 'test']); - expect(await buffer.lines).toEqual([ + assert.deepStrictEqual(await buffer.lines, [ 'test', 'bar', 'foo', @@ -392,8 +398,8 @@ describe('Buffer API', () => { const buffer = await nvim.buffer; await buffer.remove(0, -1, true); // One empty line - expect(await buffer.length).toEqual(1); - expect(await buffer.lines).toEqual(['']); + assert.strictEqual(await buffer.length, 1); + assert.deepStrictEqual(await buffer.lines, ['']); }) ); }); @@ -416,57 +422,57 @@ describe('Buffer event updates', () => { it('can listen and unlisten', async () => { const buffer = await nvim.buffer; - const mock = jestMock.fn(); + const mock = sinon.spy(); const unlisten = buffer.listen('lines', mock); await buffer.insert(['bar'], 1); - expect(mock).toHaveBeenCalledTimes(1); + assert.strictEqual(mock.callCount, 1); unlisten(); await buffer.insert(['bar'], 1); - expect(mock).toHaveBeenCalledTimes(1); + assert.strictEqual(mock.callCount, 1); }); it('can reattach for buffer events', async () => { const buffer = await nvim.buffer; - let unlisten = buffer.listen('lines', jestMock.fn()); + let unlisten = buffer.listen('lines', sinon.spy()); unlisten(); await wait(10); - const mock = jestMock.fn(); + const mock = sinon.spy(); unlisten = buffer.listen('lines', mock); await buffer.insert(['bar'], 1); - expect(mock).toHaveBeenCalledTimes(1); + assert.strictEqual(mock.callCount, 1); unlisten(); }); it('should return attached state', async () => { const buffer = await nvim.buffer; - const unlisten = buffer.listen('lines', jestMock.fn()); + const unlisten = buffer.listen('lines', sinon.spy()); await wait(30); let attached = buffer.isAttached; - expect(attached).toBe(true); + assert.strictEqual(attached, true); unlisten(); await wait(30); attached = buffer.isAttached; - expect(attached).toBe(false); + assert.strictEqual(attached, false); }); - it('only bind once for the same event and handler ', async () => { + it('only bind once for the same event and handler', async () => { const buffer = await nvim.buffer; - const mock = jestMock.fn(); + const mock = sinon.spy(); buffer.listen('lines', mock); buffer.listen('lines', mock); await buffer.insert(['bar'], 1); - expect(mock).toHaveBeenCalledTimes(1); + assert.strictEqual(mock.callCount, 1); }); it('can use `buffer.unlisten` to unlisten', async () => { const buffer = await nvim.buffer; - const mock = jestMock.fn(); + const mock = sinon.spy(); buffer.listen('lines', mock); await buffer.insert(['bar'], 1); - expect(mock).toHaveBeenCalledTimes(1); + assert.strictEqual(mock.callCount, 1); buffer.unlisten('lines', mock); await buffer.insert(['bar'], 1); - expect(mock).toHaveBeenCalledTimes(1); + assert.strictEqual(mock.callCount, 1); }); it('listens to line updates', async () => { @@ -484,10 +490,10 @@ describe('Buffer event updates', () => { end: number, data: string[] ) => { - expect(await currentBuffer.name).toBe(bufferName); - expect(start).toBe(1); - expect(end).toBe(1); - expect(data).toEqual(['bar']); + assert.strictEqual(await currentBuffer.name, bufferName); + assert.strictEqual(start, 1); + assert.strictEqual(end, 1); + assert.deepStrictEqual(data, ['bar']); unlisten(); resolve(); } @@ -498,23 +504,23 @@ describe('Buffer event updates', () => { await promise; }); - it('has listener on multiple buffers ', async () => { + it('has listener on multiple buffers', async () => { await nvim.command('new!'); const buffers = await nvim.buffers; - const foo = jestMock.fn(); - const bar = jestMock.fn(); + const foo = sinon.spy(); + const bar = sinon.spy(); buffers[0].listen('lines', foo); buffers[1].listen('lines', bar); await (await nvim.buffer).insert(['bar'], 1); - expect(foo).toHaveBeenCalledTimes(0); - expect(bar).toHaveBeenCalledTimes(1); + assert.strictEqual(foo.callCount, 0); + assert.strictEqual(bar.callCount, 1); await nvim.command('q!'); await (await nvim.buffer).insert(['foo'], 0); - expect(foo).toHaveBeenCalledTimes(1); - expect(bar).toHaveBeenCalledTimes(1); + assert.strictEqual(foo.callCount, 1); + assert.strictEqual(bar.callCount, 1); buffers[0].unlisten('lines', foo); buffers[1].unlisten('lines', bar); @@ -524,21 +530,21 @@ describe('Buffer event updates', () => { await nvim.command('new!'); const buffer = await nvim.buffer; - const foo = jestMock.fn(); - const bar = jestMock.fn(); + const foo = sinon.spy(); + const bar = sinon.spy(); const unlisten1 = buffer.listen('lines', foo); const unlisten2 = buffer.listen('lines', bar); await buffer.insert(['bar'], 1); - expect(foo).toHaveBeenCalledTimes(1); - expect(bar).toHaveBeenCalledTimes(1); + assert.strictEqual(foo.callCount, 1); + assert.strictEqual(bar.callCount, 1); unlisten2(); await buffer.insert(['foo'], 0); - expect(foo).toHaveBeenCalledTimes(2); - expect(bar).toHaveBeenCalledTimes(1); + assert.strictEqual(foo.callCount, 2); + assert.strictEqual(bar.callCount, 1); unlisten1(); await nvim.command('q!'); @@ -548,21 +554,21 @@ describe('Buffer event updates', () => { await nvim.command('new!'); const buffer = await nvim.buffer; - const foo = jestMock.fn(); - const bar = jestMock.fn(); + const foo = sinon.spy(); + const bar = sinon.spy(); const unlisten1 = buffer.listen('lines', foo); const unlisten2 = buffer.listen('changedtick', bar); await buffer.insert(['bar'], 1); - expect(foo).toHaveBeenCalledTimes(1); - expect(bar).toHaveBeenCalledTimes(1); + assert.strictEqual(foo.callCount, 1); + assert.strictEqual(bar.callCount, 1); unlisten2(); await buffer.insert(['foo'], 0); - expect(foo).toHaveBeenCalledTimes(2); - expect(bar).toHaveBeenCalledTimes(1); + assert.strictEqual(foo.callCount, 2); + assert.strictEqual(bar.callCount, 1); unlisten1(); await nvim.command('q!'); diff --git a/packages/neovim/src/api/Neovim.test.ts b/packages/neovim/src/api/Neovim.test.ts index 542582e7..31aa1caf 100644 --- a/packages/neovim/src/api/Neovim.test.ts +++ b/packages/neovim/src/api/Neovim.test.ts @@ -1,6 +1,6 @@ import * as path from 'node:path'; import assert from 'node:assert'; -import expect from 'expect'; +import sinon from 'sinon'; import * as testUtil from '../testUtil'; describe('Neovim API', () => { @@ -17,20 +17,20 @@ describe('Neovim API', () => { describe('Normal API calls', () => { it('gets a list of buffers and switches buffers', async () => { const buffers = await nvim.buffers; - expect(buffers.length).toBe(1); + assert.strictEqual(buffers.length, 1); buffers[0].name = 'hello.txt'; - nvim.command('noswapfile e! goodbye.txt'); - expect((await nvim.buffers).length).toBe(2); - expect(await nvim.buffer.name).toMatch(/goodbye\.txt$/); + await nvim.command('noswapfile e! goodbye.txt'); + assert.strictEqual((await nvim.buffers).length, 2); + assert((await nvim.buffer.name).match(/goodbye\.txt$/)); // switch buffers [nvim.buffer] = buffers; - expect(await (await nvim.buffer).name).toMatch(/hello\.txt$/); + assert((await (await nvim.buffer).name).match(/hello\.txt$/)); }); it('can list runtimepaths', async () => { - expect((await nvim.runtimePaths).length).toBeGreaterThan(0); + assert((await nvim.runtimePaths).length > 0); }); it('can change current working directory', async () => { @@ -38,23 +38,23 @@ describe('Neovim API', () => { const newCwd = path.dirname(initial); nvim.dir = newCwd; - expect(await nvim.call('getcwd', [])).toBe(newCwd); + assert.strictEqual(await nvim.call('getcwd', []), newCwd); }); it.skip('can get current mode', async () => { const initial = await nvim.mode; - expect(initial).toEqual({ mode: 'n', blocking: false }); + assert.deepStrictEqual(initial, { mode: 'n', blocking: false }); await nvim.command('startinsert'); }); it('can get color map', async () => { const colorMap = await nvim.colorMap; - expect(Object.keys(colorMap).length).toBeGreaterThan(0); + assert(Object.keys(colorMap).length > 0); }); it('can get color by name', async () => { - expect(await nvim.getColorByName('white')).toBe(16777215); + assert.strictEqual(await nvim.getColorByName('white'), 16777215); }); it('can get highlight by name or id', async () => { @@ -68,67 +68,66 @@ describe('Neovim API', () => { colEnd: 3, srcId: 0, }); - expect(srcId).toBeGreaterThan(0); + assert(srcId > 0); const highlightById = await nvim.getHighlightById(srcId); - expect(highlightById).toEqual( - expect.objectContaining({ - foreground: expect.anything(), - }) - ); - expect(await nvim.getHighlight(srcId)).toEqual(highlightById); + sinon.assert.match(highlightById, { foreground: sinon.match.any }); + assert.deepStrictEqual(await nvim.getHighlight(srcId), highlightById); // Note this doesn't work as you would think because // addHighlight does not add a highlight group - expect(await nvim.getHighlightByName('test')).toEqual({}); + assert.deepStrictEqual(await nvim.getHighlightByName('test'), {}); buffer.remove(0, -1, false); }); it('can run lua', async () => { - expect( - await nvim.lua('function test(a) return a end return test(...)', [1]) - ).toBe(1); + assert.strictEqual( + await nvim.lua('function test(a) return a end return test(...)', [1]), + 1 + ); - expect( + assert.strictEqual( await nvim.lua('function test(a) return a end return test(...)', [ 'foo', - ]) - ).toBe('foo'); + ]), + 'foo' + ); - expect( + assert.strictEqual( await nvim.executeLua( 'function test(a) return a end return test(...)', ['foo'] - ) - ).toBe('foo'); + ), + 'foo' + ); }); it('get/set/delete current line', async () => { const line = await nvim.line; - expect(line).toBe(''); + assert.strictEqual(line, ''); nvim.line = 'current line'; - expect(await nvim.line).toBe('current line'); + assert.strictEqual(await nvim.line, 'current line'); nvim.deleteCurrentLine(); - expect(await nvim.line).toBe(''); + assert.strictEqual(await nvim.line, ''); }); it('gets v: vars', async () => { const initial = await nvim.eval('v:ctype'); - expect(await nvim.getVvar('ctype')).toBe(initial); + assert.strictEqual(await nvim.getVvar('ctype'), initial); }); it('sets v: vars', async () => { await nvim.setVvar('mouse_winid', 2); - expect(await nvim.eval('v:mouse_winid')).toBe(2); - expect(await nvim.getVvar('mouse_winid')).toBe(2); + assert.strictEqual(await nvim.eval('v:mouse_winid'), 2); + assert.strictEqual(await nvim.getVvar('mouse_winid'), 2); }); it('gets string width', async () => { - expect(await nvim.strWidth('string')).toBe(6); + assert.strictEqual(await nvim.strWidth('string'), 6); }); it('write to vim output buffer', async () => { @@ -143,62 +142,46 @@ describe('Neovim API', () => { }); it('parse expression', async () => { - expect(await nvim.parseExpression('@', 'm', true)).toEqual( - expect.objectContaining({}) - ); + const parsedExpression = await nvim.parseExpression('@', 'm', true); + sinon.assert.match(parsedExpression, sinon.match.object); }); it('gets api info', async () => { const [, apiInfo] = await nvim.apiInfo; - expect(apiInfo).toEqual( - expect.objectContaining({ - version: expect.anything(), - functions: expect.anything(), - ui_events: expect.anything(), - ui_options: expect.anything(), - error_types: expect.anything(), - types: expect.anything(), - }) - ); + sinon.assert.match(apiInfo, { + version: sinon.match.any, + functions: sinon.match.any, + ui_events: sinon.match.any, + ui_options: sinon.match.any, + error_types: sinon.match.any, + types: sinon.match.any, + }); }); it('gets all channels', async () => { const chans = await nvim.chans; - expect(chans).toEqual( - expect.arrayContaining([ - expect.objectContaining({ - id: expect.anything(), - stream: expect.anything(), - mode: expect.anything(), - }), - ]) - ); + assert(Array.isArray(chans)); + assert(chans.length > 0); }); it('gets channel info', async () => { - expect(await nvim.getChanInfo(1)).toEqual( - expect.objectContaining({ - id: expect.anything(), - stream: expect.anything(), - mode: expect.anything(), - }) - ); + assert(await nvim.getChanInfo(1)); }); it('gets commands', async () => { - expect(await nvim.commands).toEqual({}); + assert.deepStrictEqual(await nvim.commands, {}); }); it('gets proc', async () => { - expect(async () => nvim.getProc(1)).not.toThrow(); + assert.doesNotThrow(async () => nvim.getProc(1)); }); it('gets proc children', async () => { - expect(async () => nvim.getProcChildren(1)).not.toThrow(); + assert.doesNotThrow(async () => nvim.getProcChildren(1)); }); it('gets uis', async () => { - expect(await nvim.uis).toEqual([]); + assert.deepStrictEqual(await nvim.uis, []); }); it('can subscribe to vim events', async () => { @@ -207,7 +190,7 @@ describe('Neovim API', () => { }); it('sets clientInfo', async () => { - expect(() => nvim.setClientInfo('test', {}, '', {}, {})).not.toThrow(); + assert.doesNotThrow(() => nvim.setClientInfo('test', {}, '', {}, {})); }); it('selects popupmenu item', async () => { @@ -218,7 +201,7 @@ describe('Neovim API', () => { const numBuffers = (await nvim.buffers).length; const numWindows = (await nvim.windows).length; const buffer = await nvim.createBuffer(false, false); - expect(await nvim.buffers).toHaveLength(numBuffers + 1); + assert.strictEqual((await nvim.buffers).length, numBuffers + 1); assert(typeof buffer !== 'number'); const floatingWindow = await nvim.openWindow(buffer, true, { relative: 'editor', @@ -227,10 +210,10 @@ describe('Neovim API', () => { width: 50, height: 50, }); - expect(await nvim.windows).toHaveLength(numWindows + 1); + assert.strictEqual((await nvim.windows).length, numWindows + 1); assert(typeof floatingWindow !== 'number'); await nvim.windowClose(floatingWindow, true); - expect(await nvim.windows).toHaveLength(numWindows); + assert.strictEqual((await nvim.windows).length, numWindows); }); it('resizes a window', async () => { @@ -245,13 +228,13 @@ describe('Neovim API', () => { height: 10, }); assert(typeof floatingWindow !== 'number'); - expect(await nvim.windows).toHaveLength(numWindows + 1); - expect(await floatingWindow.height).toBe(10); - expect(await floatingWindow.width).toBe(10); + assert.strictEqual((await nvim.windows).length, numWindows + 1); + assert.strictEqual(await floatingWindow.height, 10); + assert.strictEqual(await floatingWindow.width, 10); await nvim.windowConfig(floatingWindow, { width: 20, height: 20 }); - expect(await floatingWindow.height).toBe(20); - expect(await floatingWindow.width).toBe(20); + assert.strictEqual(await floatingWindow.height, 20); + assert.strictEqual(await floatingWindow.width, 20); await nvim.windowClose(floatingWindow, true); }); @@ -260,16 +243,16 @@ describe('Neovim API', () => { describe('Namespaces', () => { it('creates and gets anonymous namespaces', async () => { const id = await nvim.createNamespace(); - expect(typeof id).toBe('number'); + assert.strictEqual(typeof id, 'number'); - expect(await nvim.getNamespaces()).toEqual({}); + assert.deepStrictEqual(await nvim.getNamespaces(), {}); }); it('creates and gets named namespaces', async () => { const foo = await nvim.createNamespace('foo'); const bar = await nvim.createNamespace('bar'); - expect(await nvim.getNamespaces()).toEqual({ foo, bar }); + assert.deepStrictEqual(await nvim.getNamespaces(), { foo, bar }); }); }); }); diff --git a/packages/neovim/src/api/Tabpage.test.ts b/packages/neovim/src/api/Tabpage.test.ts index 5ea694e9..25820c7a 100644 --- a/packages/neovim/src/api/Tabpage.test.ts +++ b/packages/neovim/src/api/Tabpage.test.ts @@ -1,5 +1,5 @@ -import * as jestMock from 'jest-mock'; -import expect from 'expect'; +import * as sinon from 'sinon'; +import assert from 'node:assert'; import * as testUtil from '../testUtil'; import type { Tabpage } from './Tabpage'; @@ -16,7 +16,7 @@ describe('Tabpage API', () => { it('gets the current Tabpage', async () => { const tabpage = await nvim.tabpage; - expect(tabpage).toBeInstanceOf(nvim.Tabpage); + assert(tabpage instanceof nvim.Tabpage); }); describe('Normal API calls', () => { @@ -29,115 +29,107 @@ describe('Tabpage API', () => { after(() => nvim.command('tabclose')); it('gets the current tabpage number', async () => { - expect(await tabpage.number).toBe(1); + assert.strictEqual(await tabpage.number, 1); }); it('is a valid tabpage', async () => { - expect(await tabpage.valid).toBe(true); + assert.strictEqual(await tabpage.valid, true); }); it('adds a tabpage and switches to it', async () => { - nvim.command('tabnew'); + await nvim.command('tabnew'); // Switch to new tabpage const tabpages = await nvim.tabpages; - expect(tabpages.length).toBe(2); + assert.strictEqual(tabpages.length, 2); nvim.tabpage = tabpages[tabpages.length - 1]; const newTabPage = await nvim.tabpage; - expect(await newTabPage.number).toBe(2); + assert.strictEqual(await newTabPage.number, 2); }); it('gets current window in tabpage', async () => { const window = await tabpage.window; - - expect(window).toBeInstanceOf(nvim.Window); + assert(window instanceof nvim.Window); }); it('gets list of windows in tabpage', async () => { const windows = await tabpage.windows; - - expect(windows.length).toBe(1); + assert.strictEqual(windows.length, 1); // Add a new window await nvim.command('vsplit'); const newWindows = await tabpage.windows; - expect(newWindows.length).toBe(2); + assert.strictEqual(newWindows.length, 2); }); it('logs an error when calling `getOption`', () => { - const spy = jestMock.spyOn(tabpage.logger, 'error'); + const spy = sinon.spy(tabpage.logger, 'error'); tabpage.getOption(); - expect(spy.mock.calls.length).toBe(1); + assert.strictEqual(spy.callCount, 1); tabpage.setOption(); - expect(spy.mock.calls.length).toBe(2); - spy.mockClear(); + assert.strictEqual(spy.callCount, 2); }); it('returns null if variable is not found', async () => { const test = await tabpage.getVar('test'); - expect(test).toBe(null); + assert.strictEqual(test, null); }); it('can set a t: variable', async () => { - tabpage.setVar('test', 'testValue'); + await tabpage.setVar('test', 'testValue'); - expect(await tabpage.getVar('test')).toBe('testValue'); - - expect(await nvim.eval('t:test')).toBe('testValue'); + assert.strictEqual(await tabpage.getVar('test'), 'testValue'); + assert.strictEqual(await nvim.eval('t:test'), 'testValue'); }); it('can delete a t: variable', async () => { - tabpage.deleteVar('test'); - - expect(await nvim.eval('exists("t:test")')).toBe(0); + await tabpage.deleteVar('test'); - expect(await tabpage.getVar('test')).toBe(null); + assert.strictEqual(await nvim.eval('exists("t:test")'), 0); + assert.strictEqual(await tabpage.getVar('test'), null); }); }); describe('Chainable API calls', () => { it('gets the current tabpage number', async () => { - expect(await nvim.tabpage.number).toBe(1); + assert.strictEqual(await nvim.tabpage.number, 1); }); it('is a valid tabpage', async () => { - expect(await nvim.tabpage.valid).toBe(true); + assert.strictEqual(await nvim.tabpage.valid, true); }); it('adds a tabpage and switches to it', async () => { - nvim.command('tabnew'); + await nvim.command('tabnew'); // Switch to new tabpage const tabpages = await nvim.tabpages; - // TODO - expect((await nvim.tabpages).length).toBe(2); + assert.strictEqual((await nvim.tabpages).length, 2); nvim.tabpage = tabpages[tabpages.length - 1]; - expect(await nvim.tabpage.number).toBe(2); + assert.strictEqual(await nvim.tabpage.number, 2); }); it('gets current window in tabpage', async () => { const window = await nvim.tabpage.window; - - expect(window).toBeInstanceOf(nvim.Window); + assert(window instanceof nvim.Window); }); it('gets list of windows in tabpage', async () => { const windows = await nvim.tabpage.windows; - - expect(windows.length).toBe(1); + assert.strictEqual(windows.length, 1); // Add a new window - nvim.command('vsplit'); + await nvim.command('vsplit'); - // TODO - expect((await nvim.tabpage.windows).length).toBe(2); + // Check the new window count + assert.strictEqual((await nvim.tabpage.windows).length, 2); }); }); }); diff --git a/packages/neovim/src/api/Window.test.ts b/packages/neovim/src/api/Window.test.ts index 7bf07557..ab1d0a3b 100644 --- a/packages/neovim/src/api/Window.test.ts +++ b/packages/neovim/src/api/Window.test.ts @@ -1,5 +1,4 @@ import assert from 'node:assert'; -import expect from 'expect'; import * as testUtil from '../testUtil'; import type { Window } from './Window'; @@ -16,13 +15,13 @@ describe('Window API', () => { it('gets the current Window', async () => { const win = await nvim.window; - expect(win).toBeInstanceOf(nvim.Window); + assert(win instanceof nvim.Window); }); it('get windowid by id', async () => { const win = await nvim.window; const winid = await nvim.call('win_getid'); - expect(win.id).toBe(winid); + assert.strictEqual(win.id, winid); }); describe('Normal API calls', () => { @@ -33,144 +32,140 @@ describe('Window API', () => { }); it('gets the current win number', async () => { - expect(await win.number).toBe(1); + assert.strictEqual(await win.number, 1); }); it('is a valid win', async () => { - expect(await win.valid).toBe(true); + assert.strictEqual(await win.valid, true); }); it('gets current tabpage from window', async () => { - expect(await win.tabpage).toBeInstanceOf(nvim.Tabpage); + assert((await win.tabpage) instanceof nvim.Tabpage); }); it('gets current buffer from window', async () => { - expect(await win.buffer).toBeInstanceOf(nvim.Buffer); + assert((await win.buffer) instanceof nvim.Buffer); }); it('gets current cursor position', async () => { - expect(await win.cursor).toEqual([1, 0]); + assert.deepStrictEqual(await win.cursor, [1, 0]); }); it('has same cursor position after appending a line to buffer', async () => { await (await win.buffer).append(['test']); - expect(await win.buffer.lines).toEqual(['', 'test']); - expect(await win.cursor).toEqual([1, 0]); + assert.deepStrictEqual(await win.buffer.lines, ['', 'test']); + assert.deepStrictEqual(await win.cursor, [1, 0]); }); it('changes cursor position', async () => { win.cursor = [2, 2]; - expect(await win.cursor).toEqual([2, 2]); + assert.deepStrictEqual(await win.cursor, [2, 2]); }); it('has correct height after ":split"', async () => { const currentHeight = await win.height; await nvim.command('split'); - expect(await win.height).toEqual(Math.floor(currentHeight / 2)); + assert.strictEqual(await win.height, Math.floor(currentHeight / 2)); win.height = 5; - expect(await win.height).toEqual(5); + assert.strictEqual(await win.height, 5); await nvim.command('q'); - expect(await win.height).toEqual(currentHeight); + assert.strictEqual(await win.height, currentHeight); }); it('has correct width after ":vsplit"', async () => { const width = await win.width; await nvim.command('vsplit'); - // XXX: Not sure if this is correct, but guessing after a vsplit we lose a col - // to gutter? - expect(await win.width).toEqual(Math.floor(width / 2) - 1); + assert.strictEqual(await win.width, Math.floor(width / 2) - 1); win.width = 10; - expect(await win.width).toEqual(10); + assert.strictEqual(await win.width, 10); await nvim.command('q'); - expect(await win.width).toEqual(width); + assert.strictEqual(await win.width, width); }); it('can get the window position', async () => { - expect(await win.position).toEqual([0, 0]); - expect(await win.row).toBe(0); - expect(await win.col).toBe(0); + assert.deepStrictEqual(await win.position, [0, 0]); + assert.strictEqual(await win.row, 0); + assert.strictEqual(await win.col, 0); }); it('has the right window positions in display cells', async () => { let windows: Awaited; - nvim.command('vsplit'); + await nvim.command('vsplit'); // XXX If we re-use `win` without a new call to `nvim.window`, // then `win` will reference the new split win = await nvim.window; - expect(await win.row).toBe(0); - expect(await win.col).toBe(0); + assert.strictEqual(await win.row, 0); + assert.strictEqual(await win.col, 0); windows = await nvim.windows; // Set to new split [, nvim.window] = windows; win = await nvim.window; - expect(await win.row).toBe(0); - expect((await win.col) > 0).toBe(true); + assert.strictEqual(await win.row, 0); + assert((await win.col) > 0); - nvim.command('split'); + await nvim.command('split'); windows = await nvim.windows; [, , nvim.window] = windows; win = await nvim.window; - expect((await win.row) > 0).toBe(true); - expect((await win.col) > 0).toBe(true); + assert((await win.row) > 0); + assert((await win.col) > 0); }); it('changes window options', async () => { const list = await win.getOption('list'); win.setOption('list', true); - expect(await win.getOption('list')).toBe(true); + assert.strictEqual(await win.getOption('list'), true); win.setOption('list', false); - expect(await win.getOption('list')).toBe(false); + assert.strictEqual(await win.getOption('list'), false); assert(list !== undefined); // Restore option win.setOption('list', list); - expect(await win.getOption('list')).toBe(list); + assert.strictEqual(await win.getOption('list'), list); }); it('returns null if variable is not found', async () => { const test = await win.getVar('test'); - expect(test).toBe(null); + assert.strictEqual(test, null); }); it('can set a w: variable', async () => { - win.setVar('test', 'testValue'); + await win.setVar('test', 'testValue'); - expect(await win.getVar('test')).toBe('testValue'); - - expect(await nvim.eval('w:test')).toBe('testValue'); + assert.strictEqual(await win.getVar('test'), 'testValue'); + assert.strictEqual(await nvim.eval('w:test'), 'testValue'); }); it('can delete a w: variable', async () => { - win.deleteVar('test'); - - expect(await nvim.eval('exists("w:test")')).toBe(0); + await win.deleteVar('test'); - expect(await win.getVar('test')).toBe(null); + assert.strictEqual(await nvim.eval('exists("w:test")'), 0); + assert.strictEqual(await win.getVar('test'), null); }); }); describe('Chainable API calls', () => { it('gets the current tabpage', async () => { - expect(await nvim.window.tabpage).toBeInstanceOf(nvim.Tabpage); + assert((await nvim.window.tabpage) instanceof nvim.Tabpage); }); it('is a valid window', async () => { - expect(await nvim.window.valid).toBe(true); + assert.strictEqual(await nvim.window.valid, true); }); it('gets the current buffer', async () => { - expect(await nvim.window.buffer).toBeInstanceOf(nvim.Buffer); + assert((await nvim.window.buffer) instanceof nvim.Buffer); }); it.skip('gets current lines in buffer', async () => { - expect(await (await nvim.window.buffer).lines).toEqual(['test']); + assert.deepStrictEqual(await (await nvim.window.buffer).lines, ['test']); }); }); }); diff --git a/packages/neovim/src/attach/attach.test.ts b/packages/neovim/src/attach/attach.test.ts index deb10786..0e90b6eb 100644 --- a/packages/neovim/src/attach/attach.test.ts +++ b/packages/neovim/src/attach/attach.test.ts @@ -1,5 +1,5 @@ -import * as jestMock from 'jest-mock'; -import expect from 'expect'; +import assert from 'node:assert'; +import sinon from 'sinon'; import { attach } from './attach'; import { Logger } from '../utils/logger'; import * as testUtil from '../testUtil'; @@ -42,29 +42,34 @@ describe('Nvim API', () => { it('failure modes', async () => { const c = new NeovimClient(); - await expect(c.channelId).rejects.toThrow( - 'channelId requested before _isReady' - ); + await assert.rejects(c.channelId, { + message: 'channelId requested before _isReady', + }); }); it('console.log is monkey-patched to logger.info #329', async () => { - const spy = jestMock.spyOn(nvim.logger, 'info'); + const spy = sinon.spy(nvim.logger, 'info'); // eslint-disable-next-line no-console console.log('log message'); - expect(spy).toHaveBeenCalledWith('log message'); + // @ts-expect-error Sinon types are broken with overloads + // see https://github.com/DefinitelyTyped/DefinitelyTyped/issues/36436 + assert(spy.calledWith('log message')); // Still alive? - expect(await nvim.eval('1+1')).toEqual(2); + assert.strictEqual(await nvim.eval('1+1'), 2); }); it('console.assert is monkey-patched', async () => { - const spy = jestMock.spyOn(nvim.logger, 'error'); + const spy = sinon.spy(nvim.logger, 'error'); // eslint-disable-next-line no-console console.assert(false, 'foo', 42, { x: [1, 2] }); - expect(spy).toHaveBeenCalledWith('assertion failed', 'foo', 42, { - x: [1, 2], - }); + assert( + // @ts-expect-error Sinon types are broken with overloads + spy.calledWithExactly('assertion failed', 'foo', 42, { + x: [1, 2], + }) + ); // Still alive? - expect(await nvim.eval('1+1')).toEqual(2); + assert.strictEqual(await nvim.eval('1+1'), 2); }); it('console.log NOT monkey-patched if custom logger passed to attach()', async () => { @@ -86,20 +91,20 @@ describe('Nvim API', () => { options: { logger: logger2 as Logger }, }); - const spy = jestMock.spyOn(nvim2.logger, 'info'); + const spy = sinon.spy(nvim2.logger, 'info'); // eslint-disable-next-line no-console console.log('message 1'); // console.log was NOT patched. - expect(spy).toHaveBeenCalledTimes(0); + assert(spy.notCalled); // Custom logger did NOT get the message. - expect(logged).toEqual([]); + assert.deepStrictEqual(logged, []); // Custom logger can be called explicitly. nvim2.logger.info('message 2'); - expect(logged).toEqual(['message 2']); + assert.deepStrictEqual(logged, ['message 2']); // Still alive? - expect(await nvim2.eval('1+1')).toEqual(2); + assert.strictEqual(await nvim2.eval('1+1'), 2); testUtil.stopNvim(nvim2); }); @@ -121,32 +126,35 @@ describe('Nvim API', () => { nvim.command('bwipeout!'); } - expect(requestCount).toEqual(99 * 2); + assert.strictEqual(requestCount, 99 * 2); + // Still alive? - expect(await nvim.eval('1+1')).toEqual(2); + assert.strictEqual(await nvim.eval('1+1'), 2); nvim.request = oldRequest; }); it('can send requests and receive response', async () => { const result = await nvim.eval('{"k1": "v1", "k2": 2}'); - expect(result).toEqual({ k1: 'v1', k2: 2 }); + assert.deepStrictEqual(result, { k1: 'v1', k2: 2 }); }); it('can receive requests and send responses', async () => { const res = await nvim.eval('rpcrequest(1, "request", 1, 2, 3)'); - expect(res).toEqual('received request(1,2,3)'); - expect(requests).toEqual([{ method: 'request', args: [1, 2, 3] }]); - expect(notifications).toEqual([]); + assert.strictEqual(res, 'received request(1,2,3)'); + assert.deepStrictEqual(requests, [{ method: 'request', args: [1, 2, 3] }]); + assert.deepStrictEqual(notifications, []); }); it('can receive notifications', async () => { const res = await nvim.eval('rpcnotify(1, "notify", 1, 2, 3)'); - expect(res).toEqual(1); - expect(requests).toEqual([]); + assert.strictEqual(res, 1); + assert.deepStrictEqual(requests, []); return new Promise(resolve => { setImmediate(() => { - expect(notifications).toEqual([{ method: 'notify', args: [1, 2, 3] }]); + assert.deepStrictEqual(notifications, [ + { method: 'notify', args: [1, 2, 3] }, + ]); resolve(undefined); }); }); @@ -158,25 +166,25 @@ describe('Nvim API', () => { await nvim.command('vsp'); const windows = await nvim.windows; - expect(windows.length).toEqual(4); - expect(windows[0] instanceof nvim.Window).toEqual(true); - expect(windows[1] instanceof nvim.Window).toEqual(true); + assert.strictEqual(windows.length, 4); + assert(windows[0] instanceof nvim.Window); + assert(windows[1] instanceof nvim.Window); await nvim.setWindow(windows[2]); const win = await nvim.window; - expect(win.equals(windows[0])).toBe(false); - expect(win.equals(windows[2])).toBe(true); + assert(!win.equals(windows[0])); + assert(win.equals(windows[2])); const buf = await nvim.buffer; - expect(buf instanceof nvim.Buffer).toEqual(true); + assert(buf instanceof nvim.Buffer); const lines = await buf.getLines({ start: 0, end: -1, strictIndexing: true, }); - expect(lines).toEqual(['']); + assert.deepStrictEqual(lines, ['']); buf.setLines(['line1', 'line2'], { start: 0, end: 1 }); const newLines = await buf.getLines({ @@ -184,19 +192,19 @@ describe('Nvim API', () => { end: -1, strictIndexing: true, }); - expect(newLines).toEqual(['line1', 'line2']); + assert.deepStrictEqual(newLines, ['line1', 'line2']); }); // skip for now. #419 it.skip('emits "disconnect" after quit', done => { - const disconnectMock = jestMock.fn(); + const disconnectMock = sinon.spy(); nvim.on('disconnect', disconnectMock); nvim.quit(); // TODO: 'close' event sometimes does not emit. #414 proc.on('exit', () => { - expect(disconnectMock).toHaveBeenCalledTimes(1); + assert.strictEqual(disconnectMock.callCount, 1); done(); }); diff --git a/packages/neovim/src/host/NvimPlugin.test.ts b/packages/neovim/src/host/NvimPlugin.test.ts index 3d1f6222..5a395f6f 100644 --- a/packages/neovim/src/host/NvimPlugin.test.ts +++ b/packages/neovim/src/host/NvimPlugin.test.ts @@ -1,5 +1,5 @@ -import expect from 'expect'; -import * as jestMock from 'jest-mock'; +import assert from 'node:assert'; +import * as sinon from 'sinon'; import { getFakeNvimClient } from '../testUtil'; import { callable, NvimPlugin } from './NvimPlugin'; @@ -8,12 +8,12 @@ describe('NvimPlugin', () => { const fakeNvimClient = getFakeNvimClient(); const plugin = new NvimPlugin('/tmp/filename', () => {}, fakeNvimClient); - expect(plugin.filename).toEqual('/tmp/filename'); - expect(plugin.nvim).toEqual(fakeNvimClient); - expect(plugin.dev).toBe(false); - expect(Object.keys(plugin.autocmds)).toHaveLength(0); - expect(Object.keys(plugin.commands)).toHaveLength(0); - expect(Object.keys(plugin.functions)).toHaveLength(0); + assert.strictEqual(plugin.filename, '/tmp/filename'); + assert.strictEqual(plugin.nvim, fakeNvimClient); + assert.strictEqual(plugin.dev, false); + assert.strictEqual(Object.keys(plugin.autocmds).length, 0); + assert.strictEqual(Object.keys(plugin.commands).length, 0); + assert.strictEqual(Object.keys(plugin.functions).length, 0); }); it('should set dev options when you call setOptions', () => { @@ -23,8 +23,8 @@ describe('NvimPlugin', () => { getFakeNvimClient() ); plugin.setOptions({ dev: true }); - expect(plugin.dev).toBe(true); - expect(plugin.shouldCacheModule).toBe(false); + assert.strictEqual(plugin.dev, true); + assert.strictEqual(plugin.shouldCacheModule, false); }); it('should store registered autocmds', () => { @@ -42,8 +42,8 @@ describe('NvimPlugin', () => { opts, }; plugin.registerAutocmd('BufWritePre', fn, opts); - expect(Object.keys(plugin.autocmds)).toHaveLength(1); - expect(plugin.autocmds['BufWritePre *']).toEqual({ fn, spec }); + assert.strictEqual(Object.keys(plugin.autocmds).length, 1); + assert.deepStrictEqual(plugin.autocmds['BufWritePre *'], { fn, spec }); }); it('should store registered commands', () => { @@ -61,8 +61,8 @@ describe('NvimPlugin', () => { opts: {}, }; plugin.registerCommand('MyCommand', fn, opts); - expect(Object.keys(plugin.commands)).toHaveLength(1); - expect(plugin.commands.MyCommand).toEqual({ fn, spec }); + assert.strictEqual(Object.keys(plugin.commands).length, 1); + assert.deepStrictEqual(plugin.commands.MyCommand, { fn, spec }); }); it('should store registered functions', () => { @@ -80,8 +80,8 @@ describe('NvimPlugin', () => { opts: {}, }; plugin.registerFunction('MyFunction', fn, opts); - expect(Object.keys(plugin.functions)).toHaveLength(1); - expect(plugin.functions.MyFunction).toEqual({ fn, spec }); + assert.strictEqual(Object.keys(plugin.functions).length, 1); + assert.deepStrictEqual(plugin.functions.MyFunction, { fn, spec }); }); it('should not add autocmds with no pattern option', () => { @@ -91,20 +91,20 @@ describe('NvimPlugin', () => { getFakeNvimClient() ); plugin.registerAutocmd('BufWritePre', () => {}, { pattern: '' }); - expect(Object.keys(plugin.autocmds)).toHaveLength(0); + assert.strictEqual(Object.keys(plugin.autocmds).length, 0); }); it('should create functions from callable arrays', () => { - const fn = jestMock.fn(function () { + const fn = sinon.spy(function () { // @ts-expect-error intentional return this; }); - expect(callable(fn)).toEqual(fn); + assert.strictEqual(callable(fn), fn); callable([{}, fn])(); - expect(fn).toHaveBeenCalledTimes(1); + assert.strictEqual(fn.callCount, 1); const thisObj = {}; - expect(callable([thisObj, fn])()).toBe(thisObj); + assert.strictEqual(callable([thisObj, fn])(), thisObj); const plugin = new NvimPlugin( '/tmp/filename', @@ -112,7 +112,7 @@ describe('NvimPlugin', () => { getFakeNvimClient() ); const obj = { - func: jestMock.fn(function () { + func: sinon.spy(function () { // @ts-expect-error intentional return this; }), @@ -121,8 +121,9 @@ describe('NvimPlugin', () => { plugin.registerCommand('MyCommand', [obj, obj.func], {}); const thisObject = plugin.commands.MyCommand.fn('arg1', 'arg2'); - expect(obj.func).toHaveBeenCalledWith('arg1', 'arg2'); - expect(thisObject).toBe(obj); + // @ts-expect-error intentional + assert.strictEqual(obj.func.calledWith('arg1', 'arg2'), true); + assert.strictEqual(thisObject, obj); }); it('should not register commands with incorrect callable arguments', () => { @@ -133,7 +134,7 @@ describe('NvimPlugin', () => { ); // @ts-expect-error Intentionally passing empty array for command arguments. plugin.registerCommand('MyCommand', [], {}); - expect(Object.keys(plugin.commands)).toHaveLength(0); + assert.strictEqual(Object.keys(plugin.commands).length, 0); }); it('should return specs for registered commands', () => { @@ -170,7 +171,7 @@ describe('NvimPlugin', () => { }; plugin.registerFunction('MyFunction', fn, fOpts); - expect(plugin.specs).toEqual([aSpec, cSpec, fSpec]); + assert.deepStrictEqual(plugin.specs, [aSpec, cSpec, fSpec]); }); it('should handle requests for registered commands', async () => { @@ -185,15 +186,18 @@ describe('NvimPlugin', () => { plugin.registerCommand('MyCommand', fn, { sync: true }); plugin.registerFunction('MyFunction', fn); - expect(await plugin.handleRequest('BufWritePre *', 'autocmd', [true])).toBe( + assert.strictEqual( + await plugin.handleRequest('BufWritePre *', 'autocmd', [true]), true ); - expect(await plugin.handleRequest('MyCommand', 'command', [false])).toBe( + assert.strictEqual( + await plugin.handleRequest('MyCommand', 'command', [false]), false ); - expect( - await plugin.handleRequest('MyFunction', 'function', ['blue']) - ).toEqual('blue'); + assert.strictEqual( + await plugin.handleRequest('MyFunction', 'function', ['blue']), + 'blue' + ); }); it('should throw on unknown request', () => { @@ -202,13 +206,9 @@ describe('NvimPlugin', () => { () => {}, getFakeNvimClient() ); - expect.assertions(1); - plugin.handleRequest('BufWritePre *', 'autocmd', [true]).catch(err => { - expect(err).toEqual( - new Error( - 'Missing handler for autocmd: "BufWritePre *" in /tmp/filename' - ) - ); - }); + assert.rejects( + plugin.handleRequest('BufWritePre *', 'autocmd', [true]), + new Error('Missing handler for autocmd: "BufWritePre *" in /tmp/filename') + ); }); }); diff --git a/packages/neovim/src/plugin/plugin.test.ts b/packages/neovim/src/plugin/plugin.test.ts index 8a734a6f..8308fcb9 100644 --- a/packages/neovim/src/plugin/plugin.test.ts +++ b/packages/neovim/src/plugin/plugin.test.ts @@ -1,5 +1,5 @@ -import expect from 'expect'; -import * as jestMock from 'jest-mock'; +import assert from 'node:assert'; +import sinon from 'sinon'; import { plugin as Plugin } from './plugin'; import { NvimPlugin } from '../host/NvimPlugin'; import { nvimFunction as FunctionDecorator } from './function'; @@ -22,21 +22,21 @@ describe('Plugin class decorator', () => { it('decorates class with no options', () => { class MyClass {} const plugin = Plugin(MyClass); - expect(typeof plugin).toEqual('function'); + assert(typeof plugin === 'function'); }); it('decorates class with dev mode option', () => { class MyClass {} const plugin = Plugin({ dev: true })(MyClass); - expect(typeof plugin).toEqual('function'); + assert(typeof plugin === 'function'); const pluginObject = { - setOptions: jestMock.fn(), + setOptions: sinon.fake(), nvim: getFakeNvimClient(), }; instantiateOrRun(plugin, pluginObject); - expect(pluginObject.setOptions).toHaveBeenCalledWith({ dev: true }); + pluginObject.setOptions.calledWith({ dev: true }); }); it('decorates class methods', () => { @@ -65,15 +65,15 @@ describe('Plugin class decorator', () => { const plugin = Plugin(MyClass); const pluginObject = { - registerAutocmd: jestMock.fn(), - registerCommand: jestMock.fn(), - registerFunction: jestMock.fn(), + registerAutocmd: sinon.fake(), + registerCommand: sinon.fake(), + registerFunction: sinon.fake(), nvim: getFakeNvimClient(), }; const instance = instantiateOrRun(plugin, pluginObject); - expect(pluginObject.registerAutocmd).toHaveBeenCalledWith( + pluginObject.registerAutocmd.calledWith( 'TestAutocmd', [instance, MyClass.prototype.testA], { @@ -83,13 +83,13 @@ describe('Plugin class decorator', () => { } ); - expect(pluginObject.registerCommand).toHaveBeenCalledWith( + pluginObject.registerCommand.calledWith( 'TestCommand', [instance, MyClass.prototype.testC], { sync: false, range: 'test', nargs: '3' } ); - expect(pluginObject.registerFunction).toHaveBeenCalledWith( + pluginObject.registerFunction.calledWith( 'TestF', [instance, MyClass.prototype.testF], { sync: false, eval: 'test', range: [1, 10] } @@ -120,7 +120,7 @@ describe('Plugin class decorator', () => { getFakeNvimClient() ); - expect(pluginObject.specs).toEqual([ + assert.deepStrictEqual(pluginObject.specs, [ { type: 'autocmd', name: 'TestAutocmd', diff --git a/packages/neovim/src/testSetup.ts b/packages/neovim/src/testSetup.ts index 5679d9e3..6cedd6d2 100644 --- a/packages/neovim/src/testSetup.ts +++ b/packages/neovim/src/testSetup.ts @@ -1,11 +1,16 @@ // Global test setup. Runs before each test. +// eslint-disable-next-line import/no-extraneous-dependencies +import sinon from 'sinon'; import { startNvim, stopNvim } from './testUtil'; export const mochaHooks = { - beforeAll: async () => { + beforeAll() { startNvim(); }, - afterAll: () => { + beforeEach() { + sinon.restore(); + }, + afterAll() { stopNvim(); }, }; diff --git a/packages/neovim/src/testUtil.ts b/packages/neovim/src/testUtil.ts index 9cbd8c05..310b7524 100644 --- a/packages/neovim/src/testUtil.ts +++ b/packages/neovim/src/testUtil.ts @@ -1,8 +1,6 @@ import * as cp from 'node:child_process'; -import * as fs from 'node:fs'; -import * as path from 'node:path'; -// eslint-disable-next-line import/no-extraneous-dependencies -import expect from 'expect'; +// import * as fs from 'node:fs'; +// import * as path from 'node:path'; import { NeovimClient } from './api/client'; import { attach } from './attach/attach'; import { findNvim } from './utils/findNvim'; @@ -34,12 +32,12 @@ export function startNvim( export function startNvim( doAttach: boolean = true ): [cp.ChildProcessWithoutNullStreams, NeovimClient | undefined] { - const testFile = expect.getState().testPath?.replace(/.*[\\/]/, ''); - const msg = `startNvim in test: ${testFile}`; - if (process.env.NVIM_NODE_LOG_FILE) { - const logfile = path.resolve(process.env.NVIM_NODE_LOG_FILE); - fs.writeFileSync(logfile, `${msg}\n`, { flag: 'a' }); - } + // const testFile = expect.getState().testPath?.replace(/.*[\\/]/, ''); + // const msg = `startNvim in test: ${testFile}`; + // if (process.env.NVIM_NODE_LOG_FILE) { + // const logfile = path.resolve(process.env.NVIM_NODE_LOG_FILE); + // fs.writeFileSync(logfile, `${msg}\n`, { flag: 'a' }); + // } proc = cp.spawn(nvimPath, ['-u', 'NONE', '--embed', '-n', '--noplugin'], { cwd: __dirname, diff --git a/packages/neovim/src/utils/findNvim.test.ts b/packages/neovim/src/utils/findNvim.test.ts index e647d7f7..ac1b69ec 100644 --- a/packages/neovim/src/utils/findNvim.test.ts +++ b/packages/neovim/src/utils/findNvim.test.ts @@ -1,6 +1,7 @@ import { join } from 'node:path'; import { mkdirSync, writeFileSync, rmSync } from 'node:fs'; -import expect from 'expect'; +import assert from 'node:assert'; +import * as sinon from 'sinon'; import { findNvim, exportsForTesting, FindNvimResult } from './findNvim'; const parseVersion = exportsForTesting.parseVersion; @@ -23,87 +24,95 @@ describe('findNvim', () => { }); it('parseVersion()', () => { - expect(parseVersion('0.5.0-dev+1357-g192f89ea1')).toEqual([ + assert.deepStrictEqual(parseVersion('0.5.0-dev+1357-g192f89ea1'), [ 0, 5, 0, 'dev+1357-g192f89ea1', ]); - expect(parseVersion('0.5.0-dev+1357-g192f89ea1-Homebrew')).toEqual([ + assert.deepStrictEqual(parseVersion('0.5.0-dev+1357-g192f89ea1-Homebrew'), [ 0, 5, 0, 'dev+1357-g192f89ea1-Homebrew', ]); - expect(parseVersion('0.9.1')).toEqual([0, 9, 1, 'zzz']); + assert.deepStrictEqual(parseVersion('0.9.1'), [0, 9, 1, 'zzz']); // Failure modes: - expect(() => parseVersion(42 as any)).toThrow(TypeError); - expect(parseVersion('x.y.z')).toEqual(undefined); - expect(parseVersion('1.y.z')).toEqual(undefined); - expect(parseVersion('1.2.z')).toEqual(undefined); - expect(parseVersion('x.2.3')).toEqual(undefined); - expect(parseVersion('1.y.3')).toEqual(undefined); + assert.throws(() => parseVersion(42 as any), TypeError); + assert.strictEqual(parseVersion('x.y.z'), undefined); + assert.strictEqual(parseVersion('1.y.z'), undefined); + assert.strictEqual(parseVersion('1.2.z'), undefined); + assert.strictEqual(parseVersion('x.2.3'), undefined); + assert.strictEqual(parseVersion('1.y.3'), undefined); }); it('compareVersions()', () => { - expect(compareVersions('0.3.0', '0.3.0')).toBe(0); - expect(compareVersions('0.3.0', '0.3.1')).toBe(-1); - expect(compareVersions('0.3.1', '0.3.0')).toBe(1); - expect(compareVersions('0.3.0-abc', '0.3.0-dev-420')).toBe(-1); - expect(compareVersions('0.3.0', '0.3.0-dev-658+g06694203e-Homebrew')).toBe( + assert.strictEqual(compareVersions('0.3.0', '0.3.0'), 0); + assert.strictEqual(compareVersions('0.3.0', '0.3.1'), -1); + assert.strictEqual(compareVersions('0.3.1', '0.3.0'), 1); + assert.strictEqual(compareVersions('0.3.0-abc', '0.3.0-dev-420'), -1); + assert.strictEqual( + compareVersions('0.3.0', '0.3.0-dev-658+g06694203e-Homebrew'), 1 ); - expect(compareVersions('0.3.0-dev-658+g06694203e-Homebrew', '0.3.0')).toBe( + assert.strictEqual( + compareVersions('0.3.0-dev-658+g06694203e-Homebrew', '0.3.0'), -1 ); - expect( + assert.strictEqual( compareVersions( '0.3.0-dev-658+g06694203e-Homebrew', '0.3.0-dev-658+g06694203e-Homebrew' - ) - ).toBe(0); - expect( + ), + 0 + ); + assert.strictEqual( compareVersions( '0.3.0-dev-658+g06694203e-Homebrew', '0.3.0-dev-659+g06694203e-Homebrew' - ) - ).toBe(-1); - expect( + ), + -1 + ); + assert.strictEqual( compareVersions( '0.3.0-dev-659+g06694203e-Homebrew', '0.3.0-dev-658+g06694203e-Homebrew' - ) - ).toBe(1); + ), + 1 + ); // Failure modes: - expect(compareVersions('0.3.0', 'nonsense')).toBe(1); - expect(() => compareVersions('nonsense', '0.3.0')).toThrow( - 'Invalid version: "nonsense"' + assert.strictEqual(compareVersions('0.3.0', 'nonsense'), 1); + assert.throws( + () => compareVersions('nonsense', '0.3.0'), + TypeError('Invalid version: "nonsense"') ); - expect(() => compareVersions('nonsense', 'nonsense')).toThrow( - 'Invalid version: "nonsense"' + assert.throws( + () => compareVersions('nonsense', 'nonsense'), + TypeError('Invalid version: "nonsense"') ); - expect(() => compareVersions(undefined, undefined)).toThrow( - 'Invalid version format: not a string' + assert.throws( + () => compareVersions(undefined, undefined), + TypeError('Invalid version format: not a string') ); }); /** Asserts that >=1 nvim binaries were found. */ function assertOneOrMore(nvimRes: Readonly) { - expect(nvimRes).toEqual({ - matches: expect.any(Array), - invalid: expect.any(Array), + sinon.assert.match(nvimRes, { + matches: sinon.match.array, + invalid: sinon.match.array, }); - expect(nvimRes.matches.length).toBeGreaterThan(0); - expect(nvimRes.matches[0]).toEqual({ - nvimVersion: expect.any(String), - path: expect.any(String), - buildType: expect.any(String), - luaJitVersion: expect.any(String), + assert(nvimRes.matches.length > 0); + sinon.assert.match(nvimRes.matches[0], { + nvimVersion: sinon.match.string, + path: sinon.match.string, + buildType: sinon.match.string, + luaJitVersion: sinon.match.string, error: undefined, }); - expect(nvimRes.invalid.length).toEqual(0); + assert.strictEqual(nvimRes.invalid.length, 0); } it('gets Nvim satisfying given min version', () => { @@ -118,33 +127,33 @@ describe('findNvim', () => { it('collects invalid matches separately', () => { const nvimRes = findNvim({ minVersion: '9999.0.0' }); - expect(nvimRes).toEqual({ + sinon.assert.match(nvimRes, { matches: [], - invalid: expect.any(Array), + invalid: sinon.match.array, }); - expect(nvimRes.matches.length).toEqual(0); - expect(nvimRes.invalid.length).toBeGreaterThan(0); - expect(nvimRes.invalid[0]).toEqual({ - nvimVersion: expect.any(String), - path: expect.any(String), - buildType: expect.any(String), - luaJitVersion: expect.any(String), + assert.strictEqual(nvimRes.matches.length, 0); + assert(nvimRes.invalid.length > 0); + sinon.assert.match(nvimRes.invalid[0], { + nvimVersion: sinon.match.string, + path: sinon.match.string, + buildType: sinon.match.string, + luaJitVersion: sinon.match.string, error: undefined, }); }); it('stops searching on first match when firstMatch is True', () => { const nvimRes = findNvim({ minVersion: '0.3.0', firstMatch: true }); - expect(nvimRes).toEqual({ - matches: expect.any(Array), - invalid: expect.any(Array), + sinon.assert.match(nvimRes, { + matches: sinon.match.array, + invalid: sinon.match.array, }); - expect(nvimRes.matches.length).toEqual(1); - expect(nvimRes.matches[0]).toEqual({ - nvimVersion: expect.any(String), - path: expect.any(String), - buildType: expect.any(String), - luaJitVersion: expect.any(String), + assert.strictEqual(nvimRes.matches.length, 1); + sinon.assert.match(nvimRes.matches[0], { + nvimVersion: sinon.match.string, + path: sinon.match.string, + buildType: sinon.match.string, + luaJitVersion: sinon.match.string, error: undefined, }); }); @@ -157,21 +166,19 @@ describe('findNvim', () => { ].map(normalizePath); const nvimRes = findNvim({ paths: customPaths }); - expect(nvimRes.matches.length).toBeGreaterThanOrEqual(1); - - expect(nvimRes.invalid.length).toBe(3); + assert(nvimRes.matches.length >= 1); + assert.strictEqual(nvimRes.invalid.length, 3); const invalidPaths = nvimRes.invalid.map(i => i.path); - expect(invalidPaths).toEqual(customPaths); + assert.deepStrictEqual(invalidPaths, customPaths); }); it('searches in additional custom dirs', () => { const customDirs = [testDir, '/non/existent/dir'].map(normalizePath); const nvimRes = findNvim({ dirs: customDirs }); - expect(nvimRes.matches.length).toBeGreaterThanOrEqual(1); - - expect(nvimRes.invalid.length).toBe(1); - expect(nvimRes.invalid[0].path).toBe(nvimExecutablePath); + assert(nvimRes.matches.length >= 1); + assert.strictEqual(nvimRes.invalid.length, 1); + assert.strictEqual(nvimRes.invalid[0].path, nvimExecutablePath); }); }); diff --git a/packages/neovim/src/utils/transport.test.ts b/packages/neovim/src/utils/transport.test.ts index 46aa399f..1d2c5433 100644 --- a/packages/neovim/src/utils/transport.test.ts +++ b/packages/neovim/src/utils/transport.test.ts @@ -1,7 +1,7 @@ import { EventEmitter } from 'node:events'; import { Readable, Writable } from 'node:stream'; import * as msgpack from '@msgpack/msgpack'; -import expect from 'expect'; +import assert from 'node:assert'; import { attach } from '../attach/attach'; import { exportsForTesting } from './transport'; @@ -10,7 +10,8 @@ describe('transport', () => { const invalidPayload = { bogus: 'nonsense' }; const onTransportFail: EventEmitter = exportsForTesting.onTransportFail; onTransportFail.on('fail', (errMsg: string) => { - expect(errMsg).toEqual( + assert.strictEqual( + errMsg, "invalid msgpack-RPC message: expected array, got: { bogus: 'nonsense' }" ); done();