From f8020a782ddcaee05b5eaacbde7624e3641b3db8 Mon Sep 17 00:00:00 2001 From: bailey Date: Tue, 4 Feb 2025 07:06:33 -0700 Subject: [PATCH 01/11] Revert "chore(deps-dev): bump sinon from 18.0.0 to 19.0.2 (#60)" This reverts commit b2cb8dcbc345cc4a030d5d909955f9171ac3524d. --- package-lock.json | 167 +++++++++++++++++++++------------------------- package.json | 2 +- 2 files changed, 77 insertions(+), 92 deletions(-) diff --git a/package-lock.json b/package-lock.json index 12988e0..eb763a2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,7 +23,7 @@ "mocha": "^10.7.0", "nyc": "^15.1.0", "prettier": "^3.3.3", - "sinon": "^19.0.2", + "sinon": "^18.0.0", "sinon-chai": "^3.7.0", "source-map-support": "^0.5.21", "standard-version": "^9.5.0", @@ -1033,38 +1033,38 @@ } }, "node_modules/@sinonjs/fake-timers": { - "version": "13.0.5", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz", - "integrity": "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==", + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", + "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", "dev": true, "dependencies": { - "@sinonjs/commons": "^3.0.1" + "@sinonjs/commons": "^3.0.0" } }, "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==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz", + "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==", "dev": true, "dependencies": { - "@sinonjs/commons": "^3.0.1", + "@sinonjs/commons": "^2.0.0", "lodash.get": "^4.4.2", - "type-detect": "^4.1.0" + "type-detect": "^4.0.8" } }, - "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==", + "node_modules/@sinonjs/samsam/node_modules/@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", "dev": true, - "engines": { - "node": ">=4" + "dependencies": { + "type-detect": "4.0.8" } }, "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==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", + "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", "dev": true }, "node_modules/@tsconfig/node10": { @@ -4445,16 +4445,16 @@ "dev": 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==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/nise/-/nise-6.0.0.tgz", + "integrity": "sha512-K8ePqo9BFvN31HXwEtTNGzgrPpmvgciDsFz8aztFjt4LqKO/JeFD8tBOeuDiCMXrIl/m1YvfH8auSpxfaD09wg==", "dev": true, "dependencies": { - "@sinonjs/commons": "^3.0.1", - "@sinonjs/fake-timers": "^13.0.1", - "@sinonjs/text-encoding": "^0.7.3", + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^11.2.2", + "@sinonjs/text-encoding": "^0.7.2", "just-extend": "^6.2.0", - "path-to-regexp": "^8.1.0" + "path-to-regexp": "^6.2.1" } }, "node_modules/node-preload": { @@ -4837,13 +4837,10 @@ "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" - } + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", + "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==", + "dev": true }, "node_modules/pathval": { "version": "1.1.1", @@ -5427,17 +5424,17 @@ "dev": true }, "node_modules/sinon": { - "version": "19.0.2", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-19.0.2.tgz", - "integrity": "sha512-euuToqM+PjO4UgXeLETsfQiuoyPXlqFezr6YZDFwHR3t4qaX0fZUe1MfPMznTL5f8BWrVS89KduLdMUsxFCO6g==", + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-18.0.0.tgz", + "integrity": "sha512-+dXDXzD1sBO6HlmZDd7mXZCR/y5ECiEiGCBSGuFD/kZ0bDTofPYc6JaeGmPSF+1j1MejGUWkORbYOLDyvqCWpA==", "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" + "@sinonjs/fake-timers": "^11.2.2", + "@sinonjs/samsam": "^8.0.0", + "diff": "^5.2.0", + "nise": "^6.0.0", + "supports-color": "^7" }, "funding": { "type": "opencollective", @@ -5454,15 +5451,6 @@ "sinon": ">=4.0.0" } }, - "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/sinon/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -7067,37 +7055,40 @@ } }, "@sinonjs/fake-timers": { - "version": "13.0.5", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz", - "integrity": "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==", + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", + "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", "dev": true, "requires": { - "@sinonjs/commons": "^3.0.1" + "@sinonjs/commons": "^3.0.0" } }, "@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==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz", + "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==", "dev": true, "requires": { - "@sinonjs/commons": "^3.0.1", + "@sinonjs/commons": "^2.0.0", "lodash.get": "^4.4.2", - "type-detect": "^4.1.0" + "type-detect": "^4.0.8" }, "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/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } } } }, "@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==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", + "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", "dev": true }, "@tsconfig/node10": { @@ -9569,16 +9560,16 @@ "dev": true }, "nise": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/nise/-/nise-6.1.1.tgz", - "integrity": "sha512-aMSAzLVY7LyeM60gvBS423nBmIPP+Wy7St7hsb+8/fc1HmeoHJfLO8CKse4u3BtOZvQLJghYPI2i/1WZrEj5/g==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/nise/-/nise-6.0.0.tgz", + "integrity": "sha512-K8ePqo9BFvN31HXwEtTNGzgrPpmvgciDsFz8aztFjt4LqKO/JeFD8tBOeuDiCMXrIl/m1YvfH8auSpxfaD09wg==", "dev": true, "requires": { - "@sinonjs/commons": "^3.0.1", - "@sinonjs/fake-timers": "^13.0.1", - "@sinonjs/text-encoding": "^0.7.3", + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^11.2.2", + "@sinonjs/text-encoding": "^0.7.2", "just-extend": "^6.2.0", - "path-to-regexp": "^8.1.0" + "path-to-regexp": "^6.2.1" } }, "node-preload": { @@ -9875,9 +9866,9 @@ "dev": true }, "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==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", + "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==", "dev": true }, "pathval": { @@ -10283,25 +10274,19 @@ "dev": true }, "sinon": { - "version": "19.0.2", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-19.0.2.tgz", - "integrity": "sha512-euuToqM+PjO4UgXeLETsfQiuoyPXlqFezr6YZDFwHR3t4qaX0fZUe1MfPMznTL5f8BWrVS89KduLdMUsxFCO6g==", + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-18.0.0.tgz", + "integrity": "sha512-+dXDXzD1sBO6HlmZDd7mXZCR/y5ECiEiGCBSGuFD/kZ0bDTofPYc6JaeGmPSF+1j1MejGUWkORbYOLDyvqCWpA==", "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" + "@sinonjs/fake-timers": "^11.2.2", + "@sinonjs/samsam": "^8.0.0", + "diff": "^5.2.0", + "nise": "^6.0.0", + "supports-color": "^7" }, "dependencies": { - "diff": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", - "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==", - "dev": true - }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", diff --git a/package.json b/package.json index 6a7e8e8..915e0bf 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "mocha": "^10.7.0", "nyc": "^15.1.0", "prettier": "^3.3.3", - "sinon": "^19.0.2", + "sinon": "^18.0.0", "sinon-chai": "^3.7.0", "source-map-support": "^0.5.21", "standard-version": "^9.5.0", From 0598bac20554afad8ce814fe956d83a454d47599 Mon Sep 17 00:00:00 2001 From: bailey Date: Tue, 4 Feb 2025 13:44:40 -0700 Subject: [PATCH 02/11] api changes --- test/tools/api.js | 842 +++++++++++++++++++++++++++++++++++++++++- test/unit/api.test.js | 109 ++---- 2 files changed, 876 insertions(+), 75 deletions(-) diff --git a/test/tools/api.js b/test/tools/api.js index c7987aa..7d159ed 100644 --- a/test/tools/api.js +++ b/test/tools/api.js @@ -52,7 +52,7 @@ const api = [ { className: 'OrderedBulkOperation', method: 'execute', returnType: 'Promise' }, { className: 'UnorderedBulkOperation', method: 'execute', returnType: 'Promise' }, - { className: 'ChangeStream', method: 'close', returnType: 'Promise', possibleCallbackPositions: [1, 2]}, + { className: 'ChangeStream', method: 'close', returnType: 'Promise', possibleCallbackPositions: [1, 2] }, { className: 'ChangeStream', method: 'hasNext', returnType: 'Promise' }, { className: 'ChangeStream', method: 'next', returnType: 'Promise' }, { className: 'ChangeStream', method: 'tryNext', returnType: 'Promise' }, @@ -115,7 +115,7 @@ const api = [ { className: 'Db', method: 'watch', returnType: 'ChangeStream', notAsync: true }, { className: 'FindCursor', method: 'count', returnType: 'Promise' }, - { className: 'FindCursor', method: 'explain', returnType: 'Promise', possibleCallbackPositions: [1,2,3] }, + { className: 'FindCursor', method: 'explain', returnType: 'Promise', possibleCallbackPositions: [1, 2, 3] }, { className: 'GridFSBucket', method: 'delete', returnType: 'Promise', possibleCallbackPositions: [1, 2] }, { className: 'GridFSBucket', method: 'drop', returnType: 'Promise', possibleCallbackPositions: [1, 2] }, @@ -145,3 +145,841 @@ module.exports.classNames = new Set(api.map(({ className }) => className)) module.exports.classNameToMethodList = new Map(api.map((api, _, array) => [api.className, sorted(Array.from(new Set(Array.from(array.filter(v => v.className === api.className), method => method))), (a, b) => byStrings(a.method, b.method))] )); + +module.exports.unitTestableAPI = [ + { + "className": "Admin", + "method": "buildInfo", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 2 + }, + { + "className": "Admin", + "method": "command", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 3 + }, + { + "className": "Admin", + "method": "listDatabases", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 2 + }, + { + "className": "Admin", + "method": "ping", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 2 + }, + { + "className": "Admin", + "method": "removeUser", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 3 + }, + { + "className": "Admin", + "method": "replSetGetStatus", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 2 + }, + { + "className": "Admin", + "method": "serverInfo", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 2 + }, + { + "className": "Admin", + "method": "serverStatus", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 2 + }, + { + "className": "Admin", + "method": "validateCollection", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 3 + }, + { + "className": "AggregationCursor", + "method": "close", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 2 + }, + { + "className": "AggregationCursor", + "method": "explain", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2, + 3 + ], + "functionLength": 3 + }, + { + "className": "AggregationCursor", + "method": "forEach", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1 + ], + "functionLength": 2 + }, + { + "className": "AggregationCursor", + "method": "hasNext", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1 + ], + "functionLength": 1 + }, + { + "className": "AggregationCursor", + "method": "next", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1 + ], + "functionLength": 1 + }, + { + "className": "AggregationCursor", + "method": "toArray", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1 + ], + "functionLength": 1 + }, + { + "className": "AggregationCursor", + "method": "tryNext", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1 + ], + "functionLength": 1 + }, + { + "className": "ChangeStream", + "method": "close", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 2 + }, + { + "className": "ChangeStream", + "method": "hasNext", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1 + ], + "functionLength": 1 + }, + { + "className": "ChangeStream", + "method": "next", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1 + ], + "functionLength": 1 + }, + { + "className": "ChangeStream", + "method": "tryNext", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1 + ], + "functionLength": 1 + }, + { + "className": "ClientSession", + "method": "abortTransaction", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 2 + }, + { + "className": "ClientSession", + "method": "commitTransaction", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 2 + }, + { + "className": "ClientSession", + "method": "endSession", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 2 + }, + { + "className": "Collection", + "method": "bulkWrite", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 3 + }, + { + "className": "Collection", + "method": "count", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2, + 3 + ], + "functionLength": 3 + }, + { + "className": "Collection", + "method": "countDocuments", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2, + 3 + ], + "functionLength": 3 + }, + { + "className": "Collection", + "method": "createIndex", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 3 + }, + { + "className": "Collection", + "method": "createIndexes", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 3 + }, + { + "className": "Collection", + "method": "deleteMany", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2, + 3 + ], + "functionLength": 3 + }, + { + "className": "Collection", + "method": "deleteOne", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2, + 3 + ], + "functionLength": 3 + }, + { + "className": "Collection", + "method": "distinct", + "returnType": "Promise[Key]>>>", + "possibleCallbackPositions": [ + 1, + 2, + 3 + ], + "functionLength": 4 + }, + { + "className": "Collection", + "method": "drop", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 2 + }, + { + "className": "Collection", + "method": "dropIndex", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 3 + }, + { + "className": "Collection", + "method": "dropIndexes", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 2 + }, + { + "className": "Collection", + "method": "estimatedDocumentCount", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 2 + }, + { + "className": "Collection", + "method": "findOne", + "returnType": "Promise | null>", + "possibleCallbackPositions": [ + 1, + 2, + 3 + ], + "functionLength": 3 + }, + { + "className": "Collection", + "method": "findOneAndDelete", + "returnType": "Promise>", + "possibleCallbackPositions": [ + 1, + 2, + 3 + ], + "functionLength": 3 + }, + { + "className": "Collection", + "method": "findOneAndReplace", + "returnType": "Promise>", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 4 + }, + { + "className": "Collection", + "method": "findOneAndUpdate", + "returnType": "Promise>", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 4 + }, + { + "className": "Collection", + "method": "indexes", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 2 + }, + { + "className": "Collection", + "method": "indexExists", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 3 + }, + { + "className": "Collection", + "method": "indexInformation", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 2 + }, + { + "className": "Collection", + "method": "insertMany", + "returnType": "Promise>", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 3 + }, + { + "className": "Collection", + "method": "insertOne", + "returnType": "Promise>", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 3 + }, + { + "className": "Collection", + "method": "isCapped", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 2 + }, + { + "className": "Collection", + "method": "options", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 2 + }, + { + "className": "Collection", + "method": "replaceOne", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 4 + }, + { + "className": "Collection", + "method": "updateMany", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 4 + }, + { + "className": "Collection", + "method": "updateOne", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 4 + }, + { + "className": "Db", + "method": "command", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 3 + }, + { + "className": "Db", + "method": "createIndex", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 4 + }, + { + "className": "Db", + "method": "dropCollection", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 3 + }, + { + "className": "Db", + "method": "dropDatabase", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 2 + }, + { + "className": "Db", + "method": "indexInformation", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 3 + }, + { + "className": "Db", + "method": "profilingLevel", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 2 + }, + { + "className": "Db", + "method": "removeUser", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 3 + }, + { + "className": "Db", + "method": "setProfilingLevel", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 3 + }, + { + "className": "Db", + "method": "stats", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 2 + }, + { + "className": "FindCursor", + "method": "close", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 2 + }, + { + "className": "FindCursor", + "method": "count", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 2 + }, + { + "className": "FindCursor", + "method": "explain", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2, + 3 + ], + "functionLength": 3 + }, + { + "className": "FindCursor", + "method": "forEach", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1 + ], + "functionLength": 2 + }, + { + "className": "FindCursor", + "method": "hasNext", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1 + ], + "functionLength": 1 + }, + { + "className": "FindCursor", + "method": "next", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1 + ], + "functionLength": 1 + }, + { + "className": "FindCursor", + "method": "toArray", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1 + ], + "functionLength": 1 + }, + { + "className": "FindCursor", + "method": "tryNext", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1 + ], + "functionLength": 1 + }, + { + "className": "GridFSBucket", + "method": "delete", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 3 + }, + { + "className": "GridFSBucket", + "method": "drop", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 2 + }, + { + "className": "GridFSBucket", + "method": "rename", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 4 + }, + { + "className": "GridFSBucketWriteStream", + "method": "abort", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1 + ], + "functionLength": 1 + }, + { + "className": "ListCollectionsCursor", + "method": "close", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 2 + }, + { + "className": "ListCollectionsCursor", + "method": "forEach", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1 + ], + "functionLength": 2 + }, + { + "className": "ListCollectionsCursor", + "method": "hasNext", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1 + ], + "functionLength": 1 + }, + { + "className": "ListCollectionsCursor", + "method": "next", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1 + ], + "functionLength": 1 + }, + { + "className": "ListCollectionsCursor", + "method": "toArray", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1 + ], + "functionLength": 1 + }, + { + "className": "ListCollectionsCursor", + "method": "tryNext", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1 + ], + "functionLength": 1 + }, + { + "className": "ListIndexesCursor", + "method": "close", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 2 + }, + { + "className": "ListIndexesCursor", + "method": "forEach", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1 + ], + "functionLength": 2 + }, + { + "className": "ListIndexesCursor", + "method": "hasNext", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1 + ], + "functionLength": 1 + }, + { + "className": "ListIndexesCursor", + "method": "next", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1 + ], + "functionLength": 1 + }, + { + "className": "ListIndexesCursor", + "method": "toArray", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1 + ], + "functionLength": 1 + }, + { + "className": "ListIndexesCursor", + "method": "tryNext", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1 + ], + "functionLength": 1 + }, + { + "className": "MongoClient", + "method": "close", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 2 + }, + { + "className": "OrderedBulkOperation", + "method": "execute", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 2 + }, + { + "className": "UnorderedBulkOperation", + "method": "execute", + "returnType": "Promise", + "possibleCallbackPositions": [ + 1, + 2 + ], + "functionLength": 2 + } +] \ No newline at end of file diff --git a/test/unit/api.test.js b/test/unit/api.test.js index 2fbac15..ab57d60 100644 --- a/test/unit/api.test.js +++ b/test/unit/api.test.js @@ -6,18 +6,20 @@ const { expect } = require('chai'); const mongodbDriver = require('mongodb'); const mongodbLegacy = require('../..'); const { MongoDBNamespace } = require('mongodb/lib/utils'); -const { classNameToMethodList } = require('../tools/api'); +const { classNameToMethodList, unitTestableAPI } = require('../tools/api'); const { byStrings, sorted, runMicroTask } = require('../tools/utils'); // Dummy data to help with testing const iLoveJs = 'mongodb://iLoveJavascript'; const client = new mongodbLegacy.MongoClient(iLoveJs); const db = new mongodbLegacy.Db(client, 'animals'); -const collection = new mongodbLegacy.Collection(db, 'pets'); +const collection = new mongodbLegacy.Collection(db, 'pets', {}); const namespace = MongoDBNamespace.fromString('animals.pets'); +client.connect(); + // A map to helpers that can create instances of the overridden classes for testing -const OVERRIDDEN_CLASSES_GETTER = new Map([ +const CLASS_FACTORY = new Map([ ['Admin', () => new mongodbLegacy.Admin(db)], ['AggregationCursor', () => new mongodbLegacy.AggregationCursor(client, namespace)], ['ChangeStream', () => new mongodbLegacy.ChangeStream(client)], @@ -34,11 +36,9 @@ const OVERRIDDEN_CLASSES_GETTER = new Map([ ['UnorderedBulkOperation', () => collection.initializeUnorderedBulkOp()] ]); -const classesWithGetters = sorted(OVERRIDDEN_CLASSES_GETTER.keys(), byStrings); -const listOfClasses = sorted(classNameToMethodList.keys(), byStrings); -expect(classesWithGetters).to.deep.equal(listOfClasses); - -const cleanups = []; +function makeStub(className, method, superPromise) { + return sinon.stub(mongodbDriver[className].prototype, method).returns(superPromise); +} /** * A generator that yields all programmatically-testable methods from the mongodb driver. We do this in two steps: @@ -48,71 +48,30 @@ const cleanups = []; * generator also yields all possible callback positions for each function. */ function* generateTests() { - for (const [className, getInstance] of OVERRIDDEN_CLASSES_GETTER) { - // For each of the overridden classes listed above - /** @type {{ className: string; method: string; returnType: string; special?: string; }[]} */ - let methods = classNameToMethodList.get(className); + for (const [className, getInstance] of CLASS_FACTORY) { + let methods = unitTestableAPI.filter(api => api.className === className); if (methods == null) methods = []; - for (const { - method, - special, - possibleCallbackPositions, - notAsync, - changesPromise - } of methods) { - // for each of the methods on the overridden class - if (typeof special === 'string' && special.length !== 0) { - // If there is a special handling reason this method should be manually tested elsewhere - continue; - } - - if (notAsync === true) { - // this method does not accept callbacks - continue; - } - - if (changesPromise === true) { - // this method modifies the result, it needs access to a real instance in order to call toLegacy - // this test logic does not simulate that - continue; - } + for (const object of methods) { + const { method, possibleCallbackPositions } = object; - expect(method).to.be.a('string'); - - // Make the readable API name and construct an instance for testing - const apiName = `${className}.${method}`; const instance = getInstance(); - if (className === 'ClientSession') { - cleanups.push(() => instance.endSession()); - } - if (className === 'MongoClient') { - cleanups.push(() => instance.close()); - } - if (className === 'GridFSBucketWriteStream') { - cleanups.push(() => instance.end()); - } - yield { className, method, instance, - apiName, - possibleCallbackPositions, - makeStub: superPromise => { - return sinon.stub(mongodbDriver[className].prototype, method).returns(superPromise); - } + possibleCallbackPositions }; } } } describe('wrapper API', () => { - after(async () => { - for (const cleanup of cleanups) { - await cleanup(); - } + it('all subclassed objects are tested', function () { + const classesWithGetters = sorted(CLASS_FACTORY.keys(), byStrings); + const listOfClasses = sorted(classNameToMethodList.keys(), byStrings); + expect(classesWithGetters).to.deep.equal(listOfClasses); }); afterEach(() => { @@ -120,27 +79,31 @@ describe('wrapper API', () => { }); for (const { - apiName, + className, instance, method, possibleCallbackPositions, - makeStub + apiName = `${className}.${method}` } of generateTests()) { expect(instance, apiName).to.have.property(method).that.is.a('function'); const functionLength = instance[method].length; describe(`${apiName}()`, () => { + afterEach(async function () { + if (className === 'ClientSession' && method !== 'endSession') { + await instance.endSession(); + } + if (className === 'MongoClient' && method !== 'close') { + await instance.close(); + } + if (className === 'GridFSBucketWriteStream' && method !== 'end') { + await instance.end(); + } + }); const resolveSuite = []; const rejectsSuite = []; - // Use the callback positions manually defined, or use a default of [1] / [1,2] depending on function length - const callbackPositions = - possibleCallbackPositions != null - ? possibleCallbackPositions - : functionLength < 2 - ? [1] - : [1, 2]; - - for (const argumentDecrement of callbackPositions) { + + for (const argumentDecrement of possibleCallbackPositions) { // For each callback position, we construct an array of arguments that contains the callback // at the specified position. We can then test various scenarios (success callback, success promise, error callback and error promise) // for that given overload. @@ -163,7 +126,7 @@ describe('wrapper API', () => { before('setup success stub for callback case', function () { superPromise = Promise.resolve(expectedResult); - stubbedMethod = makeStub(superPromise); + stubbedMethod = makeStub(className, method, superPromise); callback = sinon.spy(); args[callbackPosition] = callback; actualReturnValue = instance[method](...args); @@ -193,7 +156,7 @@ describe('wrapper API', () => { before('setup error stub for callback case', function () { superPromise = Promise.reject(expectedError); - stubbedMethod = makeStub(superPromise); + stubbedMethod = makeStub(className, method, superPromise); callback = sinon.spy(); args[callbackPosition] = callback; actualReturnValue = instance[method](...args); @@ -228,7 +191,7 @@ describe('wrapper API', () => { before('setup success stub for promise case', function () { superPromise = Promise.resolve(expectedResult); - stubbedMethod = makeStub(superPromise); + stubbedMethod = makeStub(className, method, superPromise); actualReturnValue = instance[method](...args); }); @@ -257,7 +220,7 @@ describe('wrapper API', () => { before('setup error stub for promise case', function () { superPromise = Promise.reject(expectedError); - stubbedMethod = makeStub(superPromise); + stubbedMethod = makeStub(className, method, superPromise); actualReturnValue = instance[method](...args); }); From 43f415b998ac06f26e2359bde253ef4b179693e5 Mon Sep 17 00:00:00 2001 From: bailey Date: Tue, 4 Feb 2025 13:49:01 -0700 Subject: [PATCH 03/11] consolidate a bit more --- test/unit/api.test.js | 77 +++++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 36 deletions(-) diff --git a/test/unit/api.test.js b/test/unit/api.test.js index ab57d60..760e21b 100644 --- a/test/unit/api.test.js +++ b/test/unit/api.test.js @@ -16,25 +16,35 @@ const db = new mongodbLegacy.Db(client, 'animals'); const collection = new mongodbLegacy.Collection(db, 'pets', {}); const namespace = MongoDBNamespace.fromString('animals.pets'); +const state = { client, db, collection, namespace }; client.connect(); -// A map to helpers that can create instances of the overridden classes for testing -const CLASS_FACTORY = new Map([ - ['Admin', () => new mongodbLegacy.Admin(db)], - ['AggregationCursor', () => new mongodbLegacy.AggregationCursor(client, namespace)], - ['ChangeStream', () => new mongodbLegacy.ChangeStream(client)], - ['ClientSession', () => client.startSession()], - ['Collection', () => new mongodbLegacy.Collection(db, 'pets')], - ['Db', () => new mongodbLegacy.Db(client, 'animals')], - ['FindCursor', () => new mongodbLegacy.FindCursor(client, namespace)], - ['GridFSBucket', () => new mongodbLegacy.GridFSBucket(db)], - ['GridFSBucketWriteStream', () => new mongodbLegacy.GridFSBucket(db).openUploadStream('file')], - ['ListCollectionsCursor', () => new mongodbLegacy.ListCollectionsCursor(db, {})], - ['ListIndexesCursor', () => new mongodbLegacy.ListIndexesCursor(collection)], - ['MongoClient', () => new mongodbLegacy.MongoClient(iLoveJs)], - ['OrderedBulkOperation', () => collection.initializeOrderedBulkOp()], - ['UnorderedBulkOperation', () => collection.initializeUnorderedBulkOp()] -]); +function makeInstance({ client, db, namespace, collection }, className) { + const CLASS_FACTORY = new Map([ + ['Admin', () => new mongodbLegacy.Admin(db)], + ['AggregationCursor', () => new mongodbLegacy.AggregationCursor(client, namespace)], + ['ChangeStream', () => new mongodbLegacy.ChangeStream(client)], + ['ClientSession', () => client.startSession()], + ['Collection', () => new mongodbLegacy.Collection(db, 'pets')], + ['Db', () => new mongodbLegacy.Db(client, 'animals')], + ['FindCursor', () => new mongodbLegacy.FindCursor(client, namespace)], + ['GridFSBucket', () => new mongodbLegacy.GridFSBucket(db)], + ['GridFSBucketWriteStream', () => new mongodbLegacy.GridFSBucket(db).openUploadStream('file')], + ['ListCollectionsCursor', () => new mongodbLegacy.ListCollectionsCursor(db, {})], + ['ListIndexesCursor', () => new mongodbLegacy.ListIndexesCursor(collection)], + ['MongoClient', () => new mongodbLegacy.MongoClient(iLoveJs)], + ['OrderedBulkOperation', () => collection.initializeOrderedBulkOp()], + ['UnorderedBulkOperation', () => collection.initializeUnorderedBulkOp()] + ]); + + const factory = + CLASS_FACTORY.get(className) ?? + (() => { + throw new Error('Unsupported classname: ' + className); + }); + + return factory(); +} function makeStub(className, method, superPromise) { return sinon.stub(mongodbDriver[className].prototype, method).returns(superPromise); @@ -48,30 +58,25 @@ function makeStub(className, method, superPromise) { * generator also yields all possible callback positions for each function. */ function* generateTests() { - for (const [className, getInstance] of CLASS_FACTORY) { - let methods = unitTestableAPI.filter(api => api.className === className); - if (methods == null) methods = []; - - for (const object of methods) { - const { method, possibleCallbackPositions } = object; - - const instance = getInstance(); - - yield { - className, - method, - instance, - possibleCallbackPositions - }; - } + for (const object of unitTestableAPI) { + const { method, className, possibleCallbackPositions } = object; + + const instance = makeInstance(state, className); + + yield { + className, + method, + instance, + possibleCallbackPositions + }; } } describe('wrapper API', () => { it('all subclassed objects are tested', function () { - const classesWithGetters = sorted(CLASS_FACTORY.keys(), byStrings); - const listOfClasses = sorted(classNameToMethodList.keys(), byStrings); - expect(classesWithGetters).to.deep.equal(listOfClasses); + // const classesWithGetters = sorted(CLASS_FACTORY.keys(), byStrings); + // const listOfClasses = sorted(classNameToMethodList.keys(), byStrings); + // expect(classesWithGetters).to.deep.equal(listOfClasses); }); afterEach(() => { From 0ab3e05f4c58402560416d0ad8bfcc8e851d9073 Mon Sep 17 00:00:00 2001 From: bailey Date: Tue, 4 Feb 2025 14:01:55 -0700 Subject: [PATCH 04/11] fix --- test/unit/api.test.js | 145 ++++++++++++++++++------------------------ 1 file changed, 61 insertions(+), 84 deletions(-) diff --git a/test/unit/api.test.js b/test/unit/api.test.js index 760e21b..31922ec 100644 --- a/test/unit/api.test.js +++ b/test/unit/api.test.js @@ -6,94 +6,39 @@ const { expect } = require('chai'); const mongodbDriver = require('mongodb'); const mongodbLegacy = require('../..'); const { MongoDBNamespace } = require('mongodb/lib/utils'); -const { classNameToMethodList, unitTestableAPI } = require('../tools/api'); -const { byStrings, sorted, runMicroTask } = require('../tools/utils'); - -// Dummy data to help with testing -const iLoveJs = 'mongodb://iLoveJavascript'; -const client = new mongodbLegacy.MongoClient(iLoveJs); -const db = new mongodbLegacy.Db(client, 'animals'); -const collection = new mongodbLegacy.Collection(db, 'pets', {}); -const namespace = MongoDBNamespace.fromString('animals.pets'); - -const state = { client, db, collection, namespace }; -client.connect(); - -function makeInstance({ client, db, namespace, collection }, className) { - const CLASS_FACTORY = new Map([ - ['Admin', () => new mongodbLegacy.Admin(db)], - ['AggregationCursor', () => new mongodbLegacy.AggregationCursor(client, namespace)], - ['ChangeStream', () => new mongodbLegacy.ChangeStream(client)], - ['ClientSession', () => client.startSession()], - ['Collection', () => new mongodbLegacy.Collection(db, 'pets')], - ['Db', () => new mongodbLegacy.Db(client, 'animals')], - ['FindCursor', () => new mongodbLegacy.FindCursor(client, namespace)], - ['GridFSBucket', () => new mongodbLegacy.GridFSBucket(db)], - ['GridFSBucketWriteStream', () => new mongodbLegacy.GridFSBucket(db).openUploadStream('file')], - ['ListCollectionsCursor', () => new mongodbLegacy.ListCollectionsCursor(db, {})], - ['ListIndexesCursor', () => new mongodbLegacy.ListIndexesCursor(collection)], - ['MongoClient', () => new mongodbLegacy.MongoClient(iLoveJs)], - ['OrderedBulkOperation', () => collection.initializeOrderedBulkOp()], - ['UnorderedBulkOperation', () => collection.initializeUnorderedBulkOp()] - ]); - - const factory = - CLASS_FACTORY.get(className) ?? - (() => { - throw new Error('Unsupported classname: ' + className); - }); - - return factory(); -} - -function makeStub(className, method, superPromise) { - return sinon.stub(mongodbDriver[className].prototype, method).returns(superPromise); -} - -/** - * A generator that yields all programmatically-testable methods from the mongodb driver. We do this in two steps: - * First, we load the exhaustive list of all methods we need to test from api.js. Second, we load the legacy driver - * and use the methods loaded from api.js to find references to each class and method we need to test. The - * generator can then yield the references to the legacy classes, so that we can programmatically test them. The - * generator also yields all possible callback positions for each function. - */ -function* generateTests() { - for (const object of unitTestableAPI) { - const { method, className, possibleCallbackPositions } = object; - - const instance = makeInstance(state, className); - - yield { - className, - method, - instance, - possibleCallbackPositions - }; - } -} +const { unitTestableAPI } = require('../tools/api'); +const { runMicroTask } = require('../tools/utils'); describe('wrapper API', () => { - it('all subclassed objects are tested', function () { - // const classesWithGetters = sorted(CLASS_FACTORY.keys(), byStrings); - // const listOfClasses = sorted(classNameToMethodList.keys(), byStrings); - // expect(classesWithGetters).to.deep.equal(listOfClasses); - }); - - afterEach(() => { - sinon.restore(); - }); - for (const { className, - instance, method, possibleCallbackPositions, + functionLength, apiName = `${className}.${method}` - } of generateTests()) { - expect(instance, apiName).to.have.property(method).that.is.a('function'); - const functionLength = instance[method].length; - + } of unitTestableAPI) { describe(`${apiName}()`, () => { + let instance, client, db, collection, namespace; + + beforeEach(function () { + client = new mongodbLegacy.MongoClient('mongodb://iLoveJavascript'); + db = new mongodbLegacy.Db(client, 'animals'); + collection = new mongodbLegacy.Collection(db, 'pets', {}); + namespace = MongoDBNamespace.fromString('animals.pets'); + + client.connect().catch(_e => {}); + + instance = makeInstance( + { + client, + db, + namespace, + collection + }, + className + ); + }); + afterEach(async function () { if (className === 'ClientSession' && method !== 'endSession') { await instance.endSession(); @@ -104,6 +49,8 @@ describe('wrapper API', () => { if (className === 'GridFSBucketWriteStream' && method !== 'end') { await instance.end(); } + + sinon.restore(); }); const resolveSuite = []; const rejectsSuite = []; @@ -129,7 +76,7 @@ describe('wrapper API', () => { let stubbedMethod; const expectedResult = { message: 'success!' }; - before('setup success stub for callback case', function () { + beforeEach('setup success stub for callback case', function () { superPromise = Promise.resolve(expectedResult); stubbedMethod = makeStub(className, method, superPromise); callback = sinon.spy(); @@ -159,7 +106,7 @@ describe('wrapper API', () => { let actualError; const expectedError = new Error('error!'); - before('setup error stub for callback case', function () { + beforeEach('setup error stub for callback case', function () { superPromise = Promise.reject(expectedError); stubbedMethod = makeStub(className, method, superPromise); callback = sinon.spy(); @@ -194,7 +141,7 @@ describe('wrapper API', () => { let stubbedMethod; let expectedResult = { message: 'success!' }; - before('setup success stub for promise case', function () { + beforeEach('setup success stub for promise case', function () { superPromise = Promise.resolve(expectedResult); stubbedMethod = makeStub(className, method, superPromise); actualReturnValue = instance[method](...args); @@ -223,7 +170,7 @@ describe('wrapper API', () => { let actualError; const expectedError = new Error('error!'); - before('setup error stub for promise case', function () { + beforeEach('setup error stub for promise case', function () { superPromise = Promise.reject(expectedError); stubbedMethod = makeStub(className, method, superPromise); actualReturnValue = instance[method](...args); @@ -257,3 +204,33 @@ describe('wrapper API', () => { }); } }); + +function makeInstance({ client, db, namespace, collection }, className) { + const CLASS_FACTORY = new Map([ + ['Admin', () => new mongodbLegacy.Admin(db)], + ['AggregationCursor', () => new mongodbLegacy.AggregationCursor(client, namespace)], + ['ChangeStream', () => new mongodbLegacy.ChangeStream(client)], + ['ClientSession', () => client.startSession()], + ['Collection', () => new mongodbLegacy.Collection(db, 'pets')], + ['Db', () => new mongodbLegacy.Db(client, 'animals')], + ['FindCursor', () => new mongodbLegacy.FindCursor(client, namespace)], + ['GridFSBucket', () => new mongodbLegacy.GridFSBucket(db)], + ['GridFSBucketWriteStream', () => new mongodbLegacy.GridFSBucket(db).openUploadStream('file')], + ['ListCollectionsCursor', () => new mongodbLegacy.ListCollectionsCursor(db, {})], + ['ListIndexesCursor', () => new mongodbLegacy.ListIndexesCursor(collection)], + ['MongoClient', () => new mongodbLegacy.MongoClient('mongodb://iLoveJavascript')], + ['OrderedBulkOperation', () => collection.initializeOrderedBulkOp()], + ['UnorderedBulkOperation', () => collection.initializeUnorderedBulkOp()] + ]); + + const _default = () => { + throw new Error('Unsupported classname: ' + className); + }; + const factory = CLASS_FACTORY.get(className) ?? _default; + + return factory(); +} + +function makeStub(className, method, superPromise) { + return sinon.stub(mongodbDriver[className].prototype, method).returns(superPromise); +} From 6ce95593515f84f2d0fe688af9a366512076641e Mon Sep 17 00:00:00 2001 From: bailey Date: Tue, 4 Feb 2025 14:02:41 -0700 Subject: [PATCH 05/11] fix --- test/unit/api.test.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/test/unit/api.test.js b/test/unit/api.test.js index 31922ec..dcd7cf4 100644 --- a/test/unit/api.test.js +++ b/test/unit/api.test.js @@ -215,7 +215,14 @@ function makeInstance({ client, db, namespace, collection }, className) { ['Db', () => new mongodbLegacy.Db(client, 'animals')], ['FindCursor', () => new mongodbLegacy.FindCursor(client, namespace)], ['GridFSBucket', () => new mongodbLegacy.GridFSBucket(db)], - ['GridFSBucketWriteStream', () => new mongodbLegacy.GridFSBucket(db).openUploadStream('file')], + [ + 'GridFSBucketWriteStream', + () => { + const stream = new mongodbLegacy.GridFSBucket(db).openUploadStream('file'); + stream.on('error', () => {}); + return stream; + } + ], ['ListCollectionsCursor', () => new mongodbLegacy.ListCollectionsCursor(db, {})], ['ListIndexesCursor', () => new mongodbLegacy.ListIndexesCursor(collection)], ['MongoClient', () => new mongodbLegacy.MongoClient('mongodb://iLoveJavascript')], From 6af181386fedb07ba601c822ceef3dc8868611a6 Mon Sep 17 00:00:00 2001 From: bailey Date: Tue, 4 Feb 2025 14:06:49 -0700 Subject: [PATCH 06/11] comment --- test/tools/api.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/tools/api.js b/test/tools/api.js index 7d159ed..61e9e70 100644 --- a/test/tools/api.js +++ b/test/tools/api.js @@ -146,6 +146,9 @@ module.exports.classNameToMethodList = new Map(api.map((api, _, array) => [api.className, sorted(Array.from(new Set(Array.from(array.filter(v => v.className === api.className), method => method))), (a, b) => byStrings(a.method, b.method))] )); +/** + * Generated from `api`, this is an exhaustive list of all methods we can unit test. + */ module.exports.unitTestableAPI = [ { "className": "Admin", From 79b632f0188ce35838e068fe195e86dbe3a3dc19 Mon Sep 17 00:00:00 2001 From: bailey Date: Tue, 4 Feb 2025 14:07:00 -0700 Subject: [PATCH 07/11] Revert "Revert "chore(deps-dev): bump sinon from 18.0.0 to 19.0.2 (#60)"" This reverts commit f8020a782ddcaee05b5eaacbde7624e3641b3db8. --- package-lock.json | 167 +++++++++++++++++++++++++--------------------- package.json | 2 +- 2 files changed, 92 insertions(+), 77 deletions(-) diff --git a/package-lock.json b/package-lock.json index eb763a2..12988e0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,7 +23,7 @@ "mocha": "^10.7.0", "nyc": "^15.1.0", "prettier": "^3.3.3", - "sinon": "^18.0.0", + "sinon": "^19.0.2", "sinon-chai": "^3.7.0", "source-map-support": "^0.5.21", "standard-version": "^9.5.0", @@ -1033,38 +1033,38 @@ } }, "node_modules/@sinonjs/fake-timers": { - "version": "11.2.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", - "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", + "version": "13.0.5", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz", + "integrity": "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==", "dev": true, "dependencies": { - "@sinonjs/commons": "^3.0.0" + "@sinonjs/commons": "^3.0.1" } }, "node_modules/@sinonjs/samsam": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz", - "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==", + "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": "^2.0.0", + "@sinonjs/commons": "^3.0.1", "lodash.get": "^4.4.2", - "type-detect": "^4.0.8" + "type-detect": "^4.1.0" } }, - "node_modules/@sinonjs/samsam/node_modules/@sinonjs/commons": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "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, - "dependencies": { - "type-detect": "4.0.8" + "engines": { + "node": ">=4" } }, "node_modules/@sinonjs/text-encoding": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", - "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", + "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": { @@ -4445,16 +4445,16 @@ "dev": true }, "node_modules/nise": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/nise/-/nise-6.0.0.tgz", - "integrity": "sha512-K8ePqo9BFvN31HXwEtTNGzgrPpmvgciDsFz8aztFjt4LqKO/JeFD8tBOeuDiCMXrIl/m1YvfH8auSpxfaD09wg==", + "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.0", - "@sinonjs/fake-timers": "^11.2.2", - "@sinonjs/text-encoding": "^0.7.2", + "@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": "^6.2.1" + "path-to-regexp": "^8.1.0" } }, "node_modules/node-preload": { @@ -4837,10 +4837,13 @@ "dev": true }, "node_modules/path-to-regexp": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", - "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==", - "dev": true + "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/pathval": { "version": "1.1.1", @@ -5424,17 +5427,17 @@ "dev": true }, "node_modules/sinon": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-18.0.0.tgz", - "integrity": "sha512-+dXDXzD1sBO6HlmZDd7mXZCR/y5ECiEiGCBSGuFD/kZ0bDTofPYc6JaeGmPSF+1j1MejGUWkORbYOLDyvqCWpA==", + "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": "^11.2.2", - "@sinonjs/samsam": "^8.0.0", - "diff": "^5.2.0", - "nise": "^6.0.0", - "supports-color": "^7" + "@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", @@ -5451,6 +5454,15 @@ "sinon": ">=4.0.0" } }, + "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/sinon/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -7055,40 +7067,37 @@ } }, "@sinonjs/fake-timers": { - "version": "11.2.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", - "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", + "version": "13.0.5", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz", + "integrity": "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==", "dev": true, "requires": { - "@sinonjs/commons": "^3.0.0" + "@sinonjs/commons": "^3.0.1" } }, "@sinonjs/samsam": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz", - "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==", + "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": "^2.0.0", + "@sinonjs/commons": "^3.0.1", "lodash.get": "^4.4.2", - "type-detect": "^4.0.8" + "type-detect": "^4.1.0" }, "dependencies": { - "@sinonjs/commons": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } + "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.2", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", - "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", + "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": { @@ -9560,16 +9569,16 @@ "dev": true }, "nise": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/nise/-/nise-6.0.0.tgz", - "integrity": "sha512-K8ePqo9BFvN31HXwEtTNGzgrPpmvgciDsFz8aztFjt4LqKO/JeFD8tBOeuDiCMXrIl/m1YvfH8auSpxfaD09wg==", + "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.0", - "@sinonjs/fake-timers": "^11.2.2", - "@sinonjs/text-encoding": "^0.7.2", + "@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": "^6.2.1" + "path-to-regexp": "^8.1.0" } }, "node-preload": { @@ -9866,9 +9875,9 @@ "dev": true }, "path-to-regexp": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", - "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==", + "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 }, "pathval": { @@ -10274,19 +10283,25 @@ "dev": true }, "sinon": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-18.0.0.tgz", - "integrity": "sha512-+dXDXzD1sBO6HlmZDd7mXZCR/y5ECiEiGCBSGuFD/kZ0bDTofPYc6JaeGmPSF+1j1MejGUWkORbYOLDyvqCWpA==", + "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": "^11.2.2", - "@sinonjs/samsam": "^8.0.0", - "diff": "^5.2.0", - "nise": "^6.0.0", - "supports-color": "^7" + "@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 + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", diff --git a/package.json b/package.json index 915e0bf..6a7e8e8 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "mocha": "^10.7.0", "nyc": "^15.1.0", "prettier": "^3.3.3", - "sinon": "^18.0.0", + "sinon": "^19.0.2", "sinon-chai": "^3.7.0", "source-map-support": "^0.5.21", "standard-version": "^9.5.0", From e08bd1a10453c697dab1c08ba84e403e7304f5c0 Mon Sep 17 00:00:00 2001 From: bailey Date: Tue, 4 Feb 2025 15:54:43 -0700 Subject: [PATCH 08/11] fix leak --- test/unit/api.test.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/test/unit/api.test.js b/test/unit/api.test.js index dcd7cf4..7b1d668 100644 --- a/test/unit/api.test.js +++ b/test/unit/api.test.js @@ -26,7 +26,7 @@ describe('wrapper API', () => { collection = new mongodbLegacy.Collection(db, 'pets', {}); namespace = MongoDBNamespace.fromString('animals.pets'); - client.connect().catch(_e => {}); + client.connect().catch(_e => { }); instance = makeInstance( { @@ -40,6 +40,8 @@ describe('wrapper API', () => { }); afterEach(async function () { + sinon.restore(); + if (className === 'ClientSession' && method !== 'endSession') { await instance.endSession(); } @@ -49,7 +51,7 @@ describe('wrapper API', () => { if (className === 'GridFSBucketWriteStream' && method !== 'end') { await instance.end(); } - + await client.close(); sinon.restore(); }); const resolveSuite = []; @@ -219,7 +221,7 @@ function makeInstance({ client, db, namespace, collection }, className) { 'GridFSBucketWriteStream', () => { const stream = new mongodbLegacy.GridFSBucket(db).openUploadStream('file'); - stream.on('error', () => {}); + stream.on('error', () => { }); return stream; } ], From 576b684fd7b6ddcec5f9d1ce1212933e2e484712 Mon Sep 17 00:00:00 2001 From: bailey Date: Tue, 4 Feb 2025 15:56:24 -0700 Subject: [PATCH 09/11] lint --- test/unit/api.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/unit/api.test.js b/test/unit/api.test.js index 7b1d668..93e5673 100644 --- a/test/unit/api.test.js +++ b/test/unit/api.test.js @@ -26,7 +26,7 @@ describe('wrapper API', () => { collection = new mongodbLegacy.Collection(db, 'pets', {}); namespace = MongoDBNamespace.fromString('animals.pets'); - client.connect().catch(_e => { }); + client.connect().catch(_e => {}); instance = makeInstance( { @@ -221,7 +221,7 @@ function makeInstance({ client, db, namespace, collection }, className) { 'GridFSBucketWriteStream', () => { const stream = new mongodbLegacy.GridFSBucket(db).openUploadStream('file'); - stream.on('error', () => { }); + stream.on('error', () => {}); return stream; } ], From 6d024c0f5dadc845e4de19b3704fad57c0400e0c Mon Sep 17 00:00:00 2001 From: bailey Date: Tue, 4 Feb 2025 15:57:07 -0700 Subject: [PATCH 10/11] ignore mongodb --- .github/dependabot.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index d3022b4..e65a4df 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -21,6 +21,8 @@ updates: versions: [">=16.0.0"] # we ignore TS as a part of quarterly dependency updates. - dependency-name: "typescript" + + - dependency-name: "mongodb" groups: development-dependencies: dependency-type: "development" From dd946a6df37d39357718ba22f56fefaa956332dd Mon Sep 17 00:00:00 2001 From: bailey Date: Wed, 5 Feb 2025 09:34:44 -0700 Subject: [PATCH 11/11] prettier + lint --- test/.eslintrc.json | 6 +- test/tools/api.js | 1708 +++++++++++++++++++++---------------------- 2 files changed, 832 insertions(+), 882 deletions(-) diff --git a/test/.eslintrc.json b/test/.eslintrc.json index 4668ae7..7eeefc3 100644 --- a/test/.eslintrc.json +++ b/test/.eslintrc.json @@ -1,5 +1,5 @@ { - "env": { - "mocha": true - } + "env": { + "mocha": true + } } diff --git a/test/tools/api.js b/test/tools/api.js index 61e9e70..de4e96f 100644 --- a/test/tools/api.js +++ b/test/tools/api.js @@ -8,12 +8,17 @@ Object.defineProperty(module.exports, '__esModule', { value: true }); const commonCursorApis = [ { className: 'AbstractCursor', method: 'close', returnType: 'Promise' }, - { className: 'AbstractCursor', method: 'forEach', returnType: 'Promise', possibleCallbackPositions: [1] }, + { + className: 'AbstractCursor', + method: 'forEach', + returnType: 'Promise', + possibleCallbackPositions: [1] + }, { className: 'AbstractCursor', method: 'hasNext', returnType: 'Promise' }, { className: 'AbstractCursor', method: 'next', returnType: 'Promise' }, { className: 'AbstractCursor', method: 'toArray', returnType: 'Promise' }, - { className: 'AbstractCursor', method: 'tryNext', returnType: 'Promise' }, -] + { className: 'AbstractCursor', method: 'tryNext', returnType: 'Promise' } +]; module.exports.commonCursorApis = commonCursorApis; const cursorClasses = [ @@ -21,12 +26,19 @@ const cursorClasses = [ 'AggregationCursor', 'ListIndexesCursor', 'ListCollectionsCursor' -] +]; module.exports.cursorClasses = cursorClasses; const api = [ // Super class of cursors, we do not directly override these but override them in the inherited classes - ...commonCursorApis.flatMap(({ method, returnType, possibleCallbackPositions }) => cursorClasses.map(cursorClass => ({ className: cursorClass, method, returnType, possibleCallbackPositions }))), + ...commonCursorApis.flatMap(({ method, returnType, possibleCallbackPositions }) => + cursorClasses.map(cursorClass => ({ + className: cursorClass, + method, + returnType, + possibleCallbackPositions + })) + ), { className: 'Admin', method: 'buildInfo', returnType: 'Promise' }, { className: 'Admin', method: 'command', returnType: 'Promise' }, @@ -38,101 +50,266 @@ const api = [ { className: 'Admin', method: 'serverStatus', returnType: 'Promise' }, { className: 'Admin', method: 'validateCollection', returnType: 'Promise' }, - { className: 'AggregationCursor', method: 'explain', returnType: 'Promise', possibleCallbackPositions: [1, 2, 3] }, - { className: 'AggregationCursor', method: 'clone', returnType: 'AggregationCursor', notAsync: true }, + { + className: 'AggregationCursor', + method: 'explain', + returnType: 'Promise', + possibleCallbackPositions: [1, 2, 3] + }, + { + className: 'AggregationCursor', + method: 'clone', + returnType: 'AggregationCursor', + notAsync: true + }, { className: 'FindCursor', method: 'clone', returnType: 'FindCursor', notAsync: true }, - { className: 'ListIndexesCursor', method: 'clone', returnType: 'ListIndexesCursor', notAsync: true }, - { className: 'ListCollectionsCursor', method: 'clone', returnType: 'ListCollectionsCursor', notAsync: true }, - + { + className: 'ListIndexesCursor', + method: 'clone', + returnType: 'ListIndexesCursor', + notAsync: true + }, + { + className: 'ListCollectionsCursor', + method: 'clone', + returnType: 'ListCollectionsCursor', + notAsync: true + }, // Super class of Unordered/Ordered Bulk operations // This is listed here as a reference for completeness, but it is tested by the subclass overrides of execute // { className: 'BulkOperationBase', method: 'execute', returnType: 'Promise' }, { className: 'OrderedBulkOperation', method: 'execute', returnType: 'Promise' }, - { className: 'UnorderedBulkOperation', method: 'execute', returnType: 'Promise' }, + { + className: 'UnorderedBulkOperation', + method: 'execute', + returnType: 'Promise' + }, - { className: 'ChangeStream', method: 'close', returnType: 'Promise', possibleCallbackPositions: [1, 2] }, + { + className: 'ChangeStream', + method: 'close', + returnType: 'Promise', + possibleCallbackPositions: [1, 2] + }, { className: 'ChangeStream', method: 'hasNext', returnType: 'Promise' }, { className: 'ChangeStream', method: 'next', returnType: 'Promise' }, { className: 'ChangeStream', method: 'tryNext', returnType: 'Promise' }, - { className: 'ClientSession', method: 'abortTransaction', returnType: 'Promise', possibleCallbackPositions: [1, 2] }, - { className: 'ClientSession', method: 'commitTransaction', returnType: 'Promise', possibleCallbackPositions: [1, 2] }, + { + className: 'ClientSession', + method: 'abortTransaction', + returnType: 'Promise', + possibleCallbackPositions: [1, 2] + }, + { + className: 'ClientSession', + method: 'commitTransaction', + returnType: 'Promise', + possibleCallbackPositions: [1, 2] + }, { className: 'ClientSession', method: 'endSession', returnType: 'Promise' }, - { className: 'ClientSession', method: 'withTransaction', returnType: 'Promise', notAsync: true }, + { + className: 'ClientSession', + method: 'withTransaction', + returnType: 'Promise', + notAsync: true + }, { className: 'Collection', method: 'bulkWrite', returnType: 'Promise' }, - { className: 'Collection', method: 'count', returnType: 'Promise', possibleCallbackPositions: [1, 2, 3] }, - { className: 'Collection', method: 'countDocuments', returnType: 'Promise', possibleCallbackPositions: [1, 2, 3] }, + { + className: 'Collection', + method: 'count', + returnType: 'Promise', + possibleCallbackPositions: [1, 2, 3] + }, + { + className: 'Collection', + method: 'countDocuments', + returnType: 'Promise', + possibleCallbackPositions: [1, 2, 3] + }, { className: 'Collection', method: 'createIndex', returnType: 'Promise' }, { className: 'Collection', method: 'createIndexes', returnType: 'Promise' }, - { className: 'Collection', method: 'deleteMany', returnType: 'Promise', possibleCallbackPositions: [1, 2, 3] }, - { className: 'Collection', method: 'deleteOne', returnType: 'Promise', possibleCallbackPositions: [1, 2, 3] }, - { className: 'Collection', method: 'distinct', returnType: 'Promise[Key]>>>', possibleCallbackPositions: [1, 2, 3] }, + { + className: 'Collection', + method: 'deleteMany', + returnType: 'Promise', + possibleCallbackPositions: [1, 2, 3] + }, + { + className: 'Collection', + method: 'deleteOne', + returnType: 'Promise', + possibleCallbackPositions: [1, 2, 3] + }, + { + className: 'Collection', + method: 'distinct', + returnType: 'Promise[Key]>>>', + possibleCallbackPositions: [1, 2, 3] + }, { className: 'Collection', method: 'drop', returnType: 'Promise' }, { className: 'Collection', method: 'dropIndex', returnType: 'Promise' }, { className: 'Collection', method: 'dropIndexes', returnType: 'Promise' }, { className: 'Collection', method: 'estimatedDocumentCount', returnType: 'Promise' }, - { className: 'Collection', method: 'findOne', returnType: 'Promise | null>', possibleCallbackPositions: [1, 2, 3] }, - { className: 'Collection', method: 'findOneAndDelete', returnType: 'Promise>', possibleCallbackPositions: [1, 2, 3] }, - { className: 'Collection', method: 'findOneAndReplace', returnType: 'Promise>' }, - { className: 'Collection', method: 'findOneAndUpdate', returnType: 'Promise>' }, + { + className: 'Collection', + method: 'findOne', + returnType: 'Promise | null>', + possibleCallbackPositions: [1, 2, 3] + }, + { + className: 'Collection', + method: 'findOneAndDelete', + returnType: 'Promise>', + possibleCallbackPositions: [1, 2, 3] + }, + { + className: 'Collection', + method: 'findOneAndReplace', + returnType: 'Promise>' + }, + { + className: 'Collection', + method: 'findOneAndUpdate', + returnType: 'Promise>' + }, { className: 'Collection', method: 'indexes', returnType: 'Promise' }, { className: 'Collection', method: 'indexExists', returnType: 'Promise' }, { className: 'Collection', method: 'indexInformation', returnType: 'Promise' }, - { className: 'Collection', method: 'insertMany', returnType: 'Promise>' }, + { + className: 'Collection', + method: 'insertMany', + returnType: 'Promise>' + }, { className: 'Collection', method: 'insertOne', returnType: 'Promise>' }, { className: 'Collection', method: 'isCapped', returnType: 'Promise' }, { className: 'Collection', method: 'options', returnType: 'Promise' }, - { className: 'Collection', method: 'rename', returnType: 'Promise', changesPromise: true }, + { + className: 'Collection', + method: 'rename', + returnType: 'Promise', + changesPromise: true + }, { className: 'Collection', method: 'replaceOne', returnType: 'Promise' }, { className: 'Collection', method: 'updateMany', returnType: 'Promise' }, { className: 'Collection', method: 'updateOne', returnType: 'Promise' }, - { className: 'Collection', method: 'initializeOrderedBulkOp', returnType: 'OrderedBulkOperation', notAsync: true }, - { className: 'Collection', method: 'initializeUnorderedBulkOp', returnType: 'UnorderedBulkOperation', notAsync: true }, + { + className: 'Collection', + method: 'initializeOrderedBulkOp', + returnType: 'OrderedBulkOperation', + notAsync: true + }, + { + className: 'Collection', + method: 'initializeUnorderedBulkOp', + returnType: 'UnorderedBulkOperation', + notAsync: true + }, { className: 'Collection', method: 'aggregate', returnType: 'AggregationCursor', notAsync: true }, { className: 'Collection', method: 'find', returnType: 'FindCursor', notAsync: true }, - { className: 'Collection', method: 'listIndexes', returnType: 'ListIndexesCursor', notAsync: true }, + { + className: 'Collection', + method: 'listIndexes', + returnType: 'ListIndexesCursor', + notAsync: true + }, { className: 'Collection', method: 'watch', returnType: 'ChangeStream', notAsync: true }, - { className: 'Db', method: 'collections', returnType: 'Promise', changesPromise: true }, + { + className: 'Db', + method: 'collections', + returnType: 'Promise', + changesPromise: true + }, { className: 'Db', method: 'command', returnType: 'Promise' }, - { className: 'Db', method: 'createCollection', returnType: 'Promise>', changesPromise: true }, + { + className: 'Db', + method: 'createCollection', + returnType: 'Promise>', + changesPromise: true + }, { className: 'Db', method: 'createIndex', returnType: 'Promise' }, { className: 'Db', method: 'dropCollection', returnType: 'Promise' }, { className: 'Db', method: 'dropDatabase', returnType: 'Promise' }, { className: 'Db', method: 'indexInformation', returnType: 'Promise' }, { className: 'Db', method: 'profilingLevel', returnType: 'Promise' }, { className: 'Db', method: 'removeUser', returnType: 'Promise' }, - { className: 'Db', method: 'renameCollection', returnType: 'Promise>', changesPromise: true }, + { + className: 'Db', + method: 'renameCollection', + returnType: 'Promise>', + changesPromise: true + }, { className: 'Db', method: 'setProfilingLevel', returnType: 'Promise' }, { className: 'Db', method: 'stats', returnType: 'Promise' }, { className: 'Db', method: 'collection', returnType: 'Collection', notAsync: true }, { className: 'Db', method: 'admin', returnType: 'Admin', notAsync: true }, { className: 'Db', method: 'aggregate', returnType: 'AggregationCursor', notAsync: true }, - { className: 'Db', method: 'listCollections', returnType: 'ListCollectionsCursor', notAsync: true }, + { + className: 'Db', + method: 'listCollections', + returnType: 'ListCollectionsCursor', + notAsync: true + }, { className: 'Db', method: 'watch', returnType: 'ChangeStream', notAsync: true }, { className: 'FindCursor', method: 'count', returnType: 'Promise' }, - { className: 'FindCursor', method: 'explain', returnType: 'Promise', possibleCallbackPositions: [1, 2, 3] }, + { + className: 'FindCursor', + method: 'explain', + returnType: 'Promise', + possibleCallbackPositions: [1, 2, 3] + }, - { className: 'GridFSBucket', method: 'delete', returnType: 'Promise', possibleCallbackPositions: [1, 2] }, - { className: 'GridFSBucket', method: 'drop', returnType: 'Promise', possibleCallbackPositions: [1, 2] }, - { className: 'GridFSBucket', method: 'rename', returnType: 'Promise', possibleCallbackPositions: [1, 2] }, - { className: 'GridFSBucket', method: 'openUploadStream', returnType: 'GridFSBucketWriteStream', notAsync: true }, - { className: 'GridFSBucket', method: 'openUploadStreamWithId', returnType: 'GridFSBucketWriteStream', notAsync: true }, + { + className: 'GridFSBucket', + method: 'delete', + returnType: 'Promise', + possibleCallbackPositions: [1, 2] + }, + { + className: 'GridFSBucket', + method: 'drop', + returnType: 'Promise', + possibleCallbackPositions: [1, 2] + }, + { + className: 'GridFSBucket', + method: 'rename', + returnType: 'Promise', + possibleCallbackPositions: [1, 2] + }, + { + className: 'GridFSBucket', + method: 'openUploadStream', + returnType: 'GridFSBucketWriteStream', + notAsync: true + }, + { + className: 'GridFSBucket', + method: 'openUploadStreamWithId', + returnType: 'GridFSBucketWriteStream', + notAsync: true + }, { className: 'GridFSBucket', method: 'find', returnType: 'FindCursor', notAsync: true }, { className: 'GridFSBucketWriteStream', method: 'abort', returnType: 'Promise' }, { className: 'MongoClient', method: 'close', returnType: 'Promise' }, - { className: 'MongoClient', method: 'connect', returnType: 'Promise', changesPromise: true }, + { + className: 'MongoClient', + method: 'connect', + returnType: 'Promise', + changesPromise: true + }, { className: 'MongoClient', method: 'startSession', returnType: 'ClientSession', notAsync: true }, { className: 'MongoClient', method: 'db', returnType: 'Db', notAsync: true }, { className: 'MongoClient', method: 'watch', returnType: 'ChangeStream', notAsync: true }, // Special case, calls toLegacy before executor callback - { className: 'MongoClient', method: 'withSession', returnType: 'Promise', notAsync: true }, + { className: 'MongoClient', method: 'withSession', returnType: 'Promise', notAsync: true } // Manually test the static version of connect // This is listed here as a reference for completeness, but it is tested manually // it is checked to exist in index.test.js @@ -141,848 +318,621 @@ const api = [ ]; module.exports.api = api; -module.exports.classNames = new Set(api.map(({ className }) => className)) -module.exports.classNameToMethodList = new Map(api.map((api, _, array) => - [api.className, sorted(Array.from(new Set(Array.from(array.filter(v => v.className === api.className), method => method))), (a, b) => byStrings(a.method, b.method))] -)); +module.exports.classNames = new Set(api.map(({ className }) => className)); +module.exports.classNameToMethodList = new Map( + api.map((api, _, array) => [ + api.className, + sorted( + Array.from( + new Set( + Array.from( + array.filter(v => v.className === api.className), + method => method + ) + ) + ), + (a, b) => byStrings(a.method, b.method) + ) + ]) +); /** * Generated from `api`, this is an exhaustive list of all methods we can unit test. */ module.exports.unitTestableAPI = [ { - "className": "Admin", - "method": "buildInfo", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 2 - }, - { - "className": "Admin", - "method": "command", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 3 - }, - { - "className": "Admin", - "method": "listDatabases", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 2 - }, - { - "className": "Admin", - "method": "ping", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 2 - }, - { - "className": "Admin", - "method": "removeUser", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 3 - }, - { - "className": "Admin", - "method": "replSetGetStatus", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 2 - }, - { - "className": "Admin", - "method": "serverInfo", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 2 - }, - { - "className": "Admin", - "method": "serverStatus", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 2 - }, - { - "className": "Admin", - "method": "validateCollection", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 3 - }, - { - "className": "AggregationCursor", - "method": "close", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 2 - }, - { - "className": "AggregationCursor", - "method": "explain", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2, - 3 - ], - "functionLength": 3 - }, - { - "className": "AggregationCursor", - "method": "forEach", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1 - ], - "functionLength": 2 - }, - { - "className": "AggregationCursor", - "method": "hasNext", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1 - ], - "functionLength": 1 - }, - { - "className": "AggregationCursor", - "method": "next", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1 - ], - "functionLength": 1 - }, - { - "className": "AggregationCursor", - "method": "toArray", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1 - ], - "functionLength": 1 - }, - { - "className": "AggregationCursor", - "method": "tryNext", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1 - ], - "functionLength": 1 - }, - { - "className": "ChangeStream", - "method": "close", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 2 - }, - { - "className": "ChangeStream", - "method": "hasNext", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1 - ], - "functionLength": 1 - }, - { - "className": "ChangeStream", - "method": "next", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1 - ], - "functionLength": 1 - }, - { - "className": "ChangeStream", - "method": "tryNext", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1 - ], - "functionLength": 1 - }, - { - "className": "ClientSession", - "method": "abortTransaction", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 2 - }, - { - "className": "ClientSession", - "method": "commitTransaction", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 2 - }, - { - "className": "ClientSession", - "method": "endSession", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 2 - }, - { - "className": "Collection", - "method": "bulkWrite", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 3 - }, - { - "className": "Collection", - "method": "count", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2, - 3 - ], - "functionLength": 3 - }, - { - "className": "Collection", - "method": "countDocuments", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2, - 3 - ], - "functionLength": 3 - }, - { - "className": "Collection", - "method": "createIndex", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 3 - }, - { - "className": "Collection", - "method": "createIndexes", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 3 - }, - { - "className": "Collection", - "method": "deleteMany", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2, - 3 - ], - "functionLength": 3 - }, - { - "className": "Collection", - "method": "deleteOne", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2, - 3 - ], - "functionLength": 3 - }, - { - "className": "Collection", - "method": "distinct", - "returnType": "Promise[Key]>>>", - "possibleCallbackPositions": [ - 1, - 2, - 3 - ], - "functionLength": 4 - }, - { - "className": "Collection", - "method": "drop", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 2 - }, - { - "className": "Collection", - "method": "dropIndex", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 3 - }, - { - "className": "Collection", - "method": "dropIndexes", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 2 - }, - { - "className": "Collection", - "method": "estimatedDocumentCount", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 2 - }, - { - "className": "Collection", - "method": "findOne", - "returnType": "Promise | null>", - "possibleCallbackPositions": [ - 1, - 2, - 3 - ], - "functionLength": 3 - }, - { - "className": "Collection", - "method": "findOneAndDelete", - "returnType": "Promise>", - "possibleCallbackPositions": [ - 1, - 2, - 3 - ], - "functionLength": 3 - }, - { - "className": "Collection", - "method": "findOneAndReplace", - "returnType": "Promise>", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 4 - }, - { - "className": "Collection", - "method": "findOneAndUpdate", - "returnType": "Promise>", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 4 - }, - { - "className": "Collection", - "method": "indexes", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 2 - }, - { - "className": "Collection", - "method": "indexExists", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 3 - }, - { - "className": "Collection", - "method": "indexInformation", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 2 - }, - { - "className": "Collection", - "method": "insertMany", - "returnType": "Promise>", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 3 - }, - { - "className": "Collection", - "method": "insertOne", - "returnType": "Promise>", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 3 - }, - { - "className": "Collection", - "method": "isCapped", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 2 - }, - { - "className": "Collection", - "method": "options", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 2 - }, - { - "className": "Collection", - "method": "replaceOne", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 4 - }, - { - "className": "Collection", - "method": "updateMany", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 4 - }, - { - "className": "Collection", - "method": "updateOne", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 4 - }, - { - "className": "Db", - "method": "command", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 3 - }, - { - "className": "Db", - "method": "createIndex", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 4 - }, - { - "className": "Db", - "method": "dropCollection", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 3 - }, - { - "className": "Db", - "method": "dropDatabase", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 2 - }, - { - "className": "Db", - "method": "indexInformation", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 3 - }, - { - "className": "Db", - "method": "profilingLevel", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 2 - }, - { - "className": "Db", - "method": "removeUser", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 3 - }, - { - "className": "Db", - "method": "setProfilingLevel", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 3 - }, - { - "className": "Db", - "method": "stats", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 2 - }, - { - "className": "FindCursor", - "method": "close", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 2 - }, - { - "className": "FindCursor", - "method": "count", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 2 - }, - { - "className": "FindCursor", - "method": "explain", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2, - 3 - ], - "functionLength": 3 - }, - { - "className": "FindCursor", - "method": "forEach", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1 - ], - "functionLength": 2 - }, - { - "className": "FindCursor", - "method": "hasNext", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1 - ], - "functionLength": 1 - }, - { - "className": "FindCursor", - "method": "next", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1 - ], - "functionLength": 1 - }, - { - "className": "FindCursor", - "method": "toArray", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1 - ], - "functionLength": 1 - }, - { - "className": "FindCursor", - "method": "tryNext", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1 - ], - "functionLength": 1 - }, - { - "className": "GridFSBucket", - "method": "delete", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 3 - }, - { - "className": "GridFSBucket", - "method": "drop", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 2 - }, - { - "className": "GridFSBucket", - "method": "rename", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 4 - }, - { - "className": "GridFSBucketWriteStream", - "method": "abort", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1 - ], - "functionLength": 1 - }, - { - "className": "ListCollectionsCursor", - "method": "close", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 2 - }, - { - "className": "ListCollectionsCursor", - "method": "forEach", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1 - ], - "functionLength": 2 - }, - { - "className": "ListCollectionsCursor", - "method": "hasNext", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1 - ], - "functionLength": 1 - }, - { - "className": "ListCollectionsCursor", - "method": "next", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1 - ], - "functionLength": 1 - }, - { - "className": "ListCollectionsCursor", - "method": "toArray", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1 - ], - "functionLength": 1 - }, - { - "className": "ListCollectionsCursor", - "method": "tryNext", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1 - ], - "functionLength": 1 - }, - { - "className": "ListIndexesCursor", - "method": "close", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 2 - }, - { - "className": "ListIndexesCursor", - "method": "forEach", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1 - ], - "functionLength": 2 - }, - { - "className": "ListIndexesCursor", - "method": "hasNext", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1 - ], - "functionLength": 1 - }, - { - "className": "ListIndexesCursor", - "method": "next", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1 - ], - "functionLength": 1 - }, - { - "className": "ListIndexesCursor", - "method": "toArray", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1 - ], - "functionLength": 1 - }, - { - "className": "ListIndexesCursor", - "method": "tryNext", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1 - ], - "functionLength": 1 - }, - { - "className": "MongoClient", - "method": "close", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 2 - }, - { - "className": "OrderedBulkOperation", - "method": "execute", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 2 - }, - { - "className": "UnorderedBulkOperation", - "method": "execute", - "returnType": "Promise", - "possibleCallbackPositions": [ - 1, - 2 - ], - "functionLength": 2 + className: 'Admin', + method: 'buildInfo', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 2 + }, + { + className: 'Admin', + method: 'command', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 3 + }, + { + className: 'Admin', + method: 'listDatabases', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 2 + }, + { + className: 'Admin', + method: 'ping', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 2 + }, + { + className: 'Admin', + method: 'removeUser', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 3 + }, + { + className: 'Admin', + method: 'replSetGetStatus', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 2 + }, + { + className: 'Admin', + method: 'serverInfo', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 2 + }, + { + className: 'Admin', + method: 'serverStatus', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 2 + }, + { + className: 'Admin', + method: 'validateCollection', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 3 + }, + { + className: 'AggregationCursor', + method: 'close', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 2 + }, + { + className: 'AggregationCursor', + method: 'explain', + returnType: 'Promise', + possibleCallbackPositions: [1, 2, 3], + functionLength: 3 + }, + { + className: 'AggregationCursor', + method: 'forEach', + returnType: 'Promise', + possibleCallbackPositions: [1], + functionLength: 2 + }, + { + className: 'AggregationCursor', + method: 'hasNext', + returnType: 'Promise', + possibleCallbackPositions: [1], + functionLength: 1 + }, + { + className: 'AggregationCursor', + method: 'next', + returnType: 'Promise', + possibleCallbackPositions: [1], + functionLength: 1 + }, + { + className: 'AggregationCursor', + method: 'toArray', + returnType: 'Promise', + possibleCallbackPositions: [1], + functionLength: 1 + }, + { + className: 'AggregationCursor', + method: 'tryNext', + returnType: 'Promise', + possibleCallbackPositions: [1], + functionLength: 1 + }, + { + className: 'ChangeStream', + method: 'close', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 2 + }, + { + className: 'ChangeStream', + method: 'hasNext', + returnType: 'Promise', + possibleCallbackPositions: [1], + functionLength: 1 + }, + { + className: 'ChangeStream', + method: 'next', + returnType: 'Promise', + possibleCallbackPositions: [1], + functionLength: 1 + }, + { + className: 'ChangeStream', + method: 'tryNext', + returnType: 'Promise', + possibleCallbackPositions: [1], + functionLength: 1 + }, + { + className: 'ClientSession', + method: 'abortTransaction', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 2 + }, + { + className: 'ClientSession', + method: 'commitTransaction', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 2 + }, + { + className: 'ClientSession', + method: 'endSession', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 2 + }, + { + className: 'Collection', + method: 'bulkWrite', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 3 + }, + { + className: 'Collection', + method: 'count', + returnType: 'Promise', + possibleCallbackPositions: [1, 2, 3], + functionLength: 3 + }, + { + className: 'Collection', + method: 'countDocuments', + returnType: 'Promise', + possibleCallbackPositions: [1, 2, 3], + functionLength: 3 + }, + { + className: 'Collection', + method: 'createIndex', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 3 + }, + { + className: 'Collection', + method: 'createIndexes', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 3 + }, + { + className: 'Collection', + method: 'deleteMany', + returnType: 'Promise', + possibleCallbackPositions: [1, 2, 3], + functionLength: 3 + }, + { + className: 'Collection', + method: 'deleteOne', + returnType: 'Promise', + possibleCallbackPositions: [1, 2, 3], + functionLength: 3 + }, + { + className: 'Collection', + method: 'distinct', + returnType: 'Promise[Key]>>>', + possibleCallbackPositions: [1, 2, 3], + functionLength: 4 + }, + { + className: 'Collection', + method: 'drop', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 2 + }, + { + className: 'Collection', + method: 'dropIndex', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 3 + }, + { + className: 'Collection', + method: 'dropIndexes', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 2 + }, + { + className: 'Collection', + method: 'estimatedDocumentCount', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 2 + }, + { + className: 'Collection', + method: 'findOne', + returnType: 'Promise | null>', + possibleCallbackPositions: [1, 2, 3], + functionLength: 3 + }, + { + className: 'Collection', + method: 'findOneAndDelete', + returnType: 'Promise>', + possibleCallbackPositions: [1, 2, 3], + functionLength: 3 + }, + { + className: 'Collection', + method: 'findOneAndReplace', + returnType: 'Promise>', + possibleCallbackPositions: [1, 2], + functionLength: 4 + }, + { + className: 'Collection', + method: 'findOneAndUpdate', + returnType: 'Promise>', + possibleCallbackPositions: [1, 2], + functionLength: 4 + }, + { + className: 'Collection', + method: 'indexes', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 2 + }, + { + className: 'Collection', + method: 'indexExists', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 3 + }, + { + className: 'Collection', + method: 'indexInformation', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 2 + }, + { + className: 'Collection', + method: 'insertMany', + returnType: 'Promise>', + possibleCallbackPositions: [1, 2], + functionLength: 3 + }, + { + className: 'Collection', + method: 'insertOne', + returnType: 'Promise>', + possibleCallbackPositions: [1, 2], + functionLength: 3 + }, + { + className: 'Collection', + method: 'isCapped', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 2 + }, + { + className: 'Collection', + method: 'options', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 2 + }, + { + className: 'Collection', + method: 'replaceOne', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 4 + }, + { + className: 'Collection', + method: 'updateMany', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 4 + }, + { + className: 'Collection', + method: 'updateOne', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 4 + }, + { + className: 'Db', + method: 'command', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 3 + }, + { + className: 'Db', + method: 'createIndex', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 4 + }, + { + className: 'Db', + method: 'dropCollection', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 3 + }, + { + className: 'Db', + method: 'dropDatabase', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 2 + }, + { + className: 'Db', + method: 'indexInformation', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 3 + }, + { + className: 'Db', + method: 'profilingLevel', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 2 + }, + { + className: 'Db', + method: 'removeUser', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 3 + }, + { + className: 'Db', + method: 'setProfilingLevel', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 3 + }, + { + className: 'Db', + method: 'stats', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 2 + }, + { + className: 'FindCursor', + method: 'close', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 2 + }, + { + className: 'FindCursor', + method: 'count', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 2 + }, + { + className: 'FindCursor', + method: 'explain', + returnType: 'Promise', + possibleCallbackPositions: [1, 2, 3], + functionLength: 3 + }, + { + className: 'FindCursor', + method: 'forEach', + returnType: 'Promise', + possibleCallbackPositions: [1], + functionLength: 2 + }, + { + className: 'FindCursor', + method: 'hasNext', + returnType: 'Promise', + possibleCallbackPositions: [1], + functionLength: 1 + }, + { + className: 'FindCursor', + method: 'next', + returnType: 'Promise', + possibleCallbackPositions: [1], + functionLength: 1 + }, + { + className: 'FindCursor', + method: 'toArray', + returnType: 'Promise', + possibleCallbackPositions: [1], + functionLength: 1 + }, + { + className: 'FindCursor', + method: 'tryNext', + returnType: 'Promise', + possibleCallbackPositions: [1], + functionLength: 1 + }, + { + className: 'GridFSBucket', + method: 'delete', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 3 + }, + { + className: 'GridFSBucket', + method: 'drop', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 2 + }, + { + className: 'GridFSBucket', + method: 'rename', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 4 + }, + { + className: 'GridFSBucketWriteStream', + method: 'abort', + returnType: 'Promise', + possibleCallbackPositions: [1], + functionLength: 1 + }, + { + className: 'ListCollectionsCursor', + method: 'close', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 2 + }, + { + className: 'ListCollectionsCursor', + method: 'forEach', + returnType: 'Promise', + possibleCallbackPositions: [1], + functionLength: 2 + }, + { + className: 'ListCollectionsCursor', + method: 'hasNext', + returnType: 'Promise', + possibleCallbackPositions: [1], + functionLength: 1 + }, + { + className: 'ListCollectionsCursor', + method: 'next', + returnType: 'Promise', + possibleCallbackPositions: [1], + functionLength: 1 + }, + { + className: 'ListCollectionsCursor', + method: 'toArray', + returnType: 'Promise', + possibleCallbackPositions: [1], + functionLength: 1 + }, + { + className: 'ListCollectionsCursor', + method: 'tryNext', + returnType: 'Promise', + possibleCallbackPositions: [1], + functionLength: 1 + }, + { + className: 'ListIndexesCursor', + method: 'close', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 2 + }, + { + className: 'ListIndexesCursor', + method: 'forEach', + returnType: 'Promise', + possibleCallbackPositions: [1], + functionLength: 2 + }, + { + className: 'ListIndexesCursor', + method: 'hasNext', + returnType: 'Promise', + possibleCallbackPositions: [1], + functionLength: 1 + }, + { + className: 'ListIndexesCursor', + method: 'next', + returnType: 'Promise', + possibleCallbackPositions: [1], + functionLength: 1 + }, + { + className: 'ListIndexesCursor', + method: 'toArray', + returnType: 'Promise', + possibleCallbackPositions: [1], + functionLength: 1 + }, + { + className: 'ListIndexesCursor', + method: 'tryNext', + returnType: 'Promise', + possibleCallbackPositions: [1], + functionLength: 1 + }, + { + className: 'MongoClient', + method: 'close', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 2 + }, + { + className: 'OrderedBulkOperation', + method: 'execute', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 2 + }, + { + className: 'UnorderedBulkOperation', + method: 'execute', + returnType: 'Promise', + possibleCallbackPositions: [1, 2], + functionLength: 2 } -] \ No newline at end of file +];