diff --git a/.eslintrc.yml b/.eslintrc.yml index 87dca16cf..1a7cf0adf 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -2,6 +2,7 @@ env: browser: true es2021: true jest: true + mocha: true extends: standard parserOptions: ecmaVersion: latest @@ -26,7 +27,8 @@ rules: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -plugins: ["headers"] + no-unused-expressions: off +plugins: ["headers", "mocha"] overrides: - files: ["*.mjs"] parserOptions: diff --git a/.mocharc.js b/.mocharc.js new file mode 100644 index 000000000..9b4f77796 --- /dev/null +++ b/.mocharc.js @@ -0,0 +1,32 @@ +/** + * Copyright (C) 2024 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the ""License""); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an ""AS IS"" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +const config = { + extension: ['js', 'mjs'], + spec: [ + '**/__tests__/**/*.spec.js', + '**/*.spec.js', + '**/*.test.js', + '**/*.test.mjs', + ], + recursive: true, + reporter: 'spec', + timeout: 5000, + require: ['test/setup.mjs', 'jest-expect-message'], +}; + +export default config \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index b5b482b0a..2a0d658df 100644 --- a/package-lock.json +++ b/package-lock.json @@ -46,17 +46,22 @@ "devDependencies": { "@jest/globals": "^29.7.0", "@jest/test-sequencer": "^29.7.0", + "chai": "^5.1.1", + "chai-as-promised": "^8.0.0", "cross-env": "^7.0.3", "eslint": "^8.57.1", "eslint-config-standard": "^17.1.0", "eslint-plugin-headers": "^1.1.2", "eslint-plugin-import": "^2.30.0", + "eslint-plugin-mocha": "^10.5.0", "eslint-plugin-n": "^16.6.2", "eslint-plugin-promise": "^6.6.0", "jest": "^29.7.0", "jest-environment-steps": "^1.1.1", "jest-expect-message": "^1.1.3", "jest-junit": "^16.0.0", + "jest-mock": "^29.7.0", + "mocha": "^10.7.3", "nyc": "^17.1.0", "remark-cli": "^12.0.1", "remark-lint-list-item-indent": "^4.0.0", @@ -3100,6 +3105,16 @@ "node": ">=0.8" } }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, "node_modules/async": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", @@ -3388,6 +3403,13 @@ "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true, + "license": "ISC" + }, "node_modules/browserslist": { "version": "4.23.1", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", @@ -3662,6 +3684,36 @@ "node": ">= 10" } }, + "node_modules/chai": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.1.tgz", + "integrity": "sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/chai-as-promised": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-8.0.0.tgz", + "integrity": "sha512-sMsGXTrS3FunP/wbqh/KxM8Kj/aLPXQGkNtvE5wPfSToq8wkkvBpTZo1LIiEVmC4BwkKpag+l5h/20lBMk6nUg==", + "dev": true, + "license": "WTFPL", + "dependencies": { + "check-error": "^2.0.0" + }, + "peerDependencies": { + "chai": ">= 2.1.2 < 6" + } + }, "node_modules/chalk": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", @@ -3727,6 +3779,16 @@ "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" }, + "node_modules/check-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, "node_modules/chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -4213,12 +4275,13 @@ } }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, + "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -4229,12 +4292,6 @@ } } }, - "node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "node_modules/decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", @@ -4296,6 +4353,16 @@ } } }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -4407,6 +4474,16 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/diff-sequences": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", @@ -4961,6 +5038,53 @@ "semver": "bin/semver.js" } }, + "node_modules/eslint-plugin-mocha": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.5.0.tgz", + "integrity": "sha512-F2ALmQVPT1GoP27O1JTZGrV9Pqg8k79OeIuvw63UxMtQKREZtmkK1NFgkZQ2TW7L2JSSFKHFPTtHu5z8R9QNRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-utils": "^3.0.0", + "globals": "^13.24.0", + "rambda": "^7.4.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-plugin-mocha/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-plugin-mocha/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/eslint-plugin-n": { "version": "16.6.2", "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.6.2.tgz", @@ -5047,6 +5171,35 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10" + } + }, "node_modules/eslint-visitor-keys": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", @@ -5481,6 +5634,16 @@ "node": ">=8" } }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, "node_modules/flat-cache": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", @@ -5692,6 +5855,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, "node_modules/get-intrinsic": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", @@ -6018,6 +6191,16 @@ "node": ">= 0.4" } }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, "node_modules/help-me": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/help-me/-/help-me-4.2.0.tgz", @@ -6669,6 +6852,19 @@ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-weakref": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", @@ -7282,6 +7478,7 @@ "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", "dev": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", "@types/node": "*", @@ -8044,6 +8241,40 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/log-update": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", @@ -8209,6 +8440,16 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/loupe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.1.tgz", + "integrity": "sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.1" + } + }, "node_modules/lowercase-keys": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", @@ -9088,6 +9329,223 @@ "node": ">=10" } }, + "node_modules/mocha": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.3.tgz", + "integrity": "sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.3", + "browser-stdout": "^1.3.1", + "chokidar": "^3.5.3", + "debug": "^4.3.5", + "diff": "^5.2.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^8.1.0", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^5.1.6", + "ms": "^2.1.3", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^6.5.1", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9", + "yargs-unparser": "^2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/mocha/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/mocha/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/mocha/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/mocha/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/mocha/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -9725,6 +10183,16 @@ "node": "14 || >=16.14" } }, + "node_modules/pathval": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", + "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -10097,6 +10565,23 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/rambda": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/rambda/-/rambda-7.5.0.tgz", + "integrity": "sha512-y/M9weqWAH4iopRd7EHDEQQvpFPHj1AA3oHozE9tfITHUtTR7Z9PSlIRRG2l1GuW7sefC1cXFfIcF+cgnShdBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, "node_modules/react-is": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", @@ -11191,6 +11676,16 @@ "node": ">=10" } }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", @@ -12710,6 +13205,13 @@ "node": ">= 12.0.0" } }, + "node_modules/workerpool": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -12839,6 +13341,58 @@ "node": ">=12" } }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs-unparser/node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs-unparser/node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index 60c6e6a82..4731c826d 100644 --- a/package.json +++ b/package.json @@ -56,9 +56,9 @@ "got": "^14.4.2", "inquirer": "^11.1.0", "ip": "^2.0.1", - "jsdoc": "^4.0.3", "js-base64": "^3.7.7", "js-yaml": "^4.1.0", + "jsdoc": "^4.0.3", "listr2": "^8.2.4", "semver": "^7.6.3", "stream-buffers": "^3.0.3", @@ -71,17 +71,22 @@ "devDependencies": { "@jest/globals": "^29.7.0", "@jest/test-sequencer": "^29.7.0", + "chai": "^5.1.1", + "chai-as-promised": "^8.0.0", "cross-env": "^7.0.3", "eslint": "^8.57.1", "eslint-config-standard": "^17.1.0", "eslint-plugin-headers": "^1.1.2", "eslint-plugin-import": "^2.30.0", + "eslint-plugin-mocha": "^10.5.0", "eslint-plugin-n": "^16.6.2", "eslint-plugin-promise": "^6.6.0", "jest": "^29.7.0", "jest-environment-steps": "^1.1.1", "jest-expect-message": "^1.1.3", "jest-junit": "^16.0.0", + "jest-mock": "^29.7.0", + "mocha": "^10.7.3", "nyc": "^17.1.0", "remark-cli": "^12.0.1", "remark-lint-list-item-indent": "^4.0.0", diff --git a/test/setup.mjs b/test/setup.mjs new file mode 100644 index 000000000..26c788492 --- /dev/null +++ b/test/setup.mjs @@ -0,0 +1,23 @@ +/** + * Copyright (C) 2024 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the ""License""); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an ""AS IS"" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +'use strict' +import chai from 'chai' +import chaiAsPromised from 'chai-as-promised' + +// eslint-disable-next-line no-unused-vars +const expect = chai.expect +chai.use(chaiAsPromised) diff --git a/test/test_add.mjs b/test/test_add.mjs index 320253bb7..f9bbcfd2b 100644 --- a/test/test_add.mjs +++ b/test/test_add.mjs @@ -13,9 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * @jest-environment steps + * @mocha-environment steps */ -import { afterAll, describe, expect, it } from '@jest/globals' +import { describe, it, after } from 'mocha' +import { expect } from 'chai' + import { accountCreationShouldSucceed, balanceQueryShouldSucceed, @@ -33,7 +35,7 @@ export function testNodeAdd (localBuildPath ) { describe('Node add should success', () => { const suffix = localBuildPath.substring(0, 5) - const defaultTimeout = 120000 + const defaultTimeout = 120_000 const namespace = 'node-add' + suffix const argv = getDefaultArgv() argv[flags.nodeIDs.name] = 'node1,node2,node3' @@ -56,27 +58,29 @@ export function testNodeAdd (localBuildPath let existingServiceMap let existingNodeIdsPrivateKeysHash - afterAll(async () => { + after(async () => { + this.timeout(600_000) + await getNodeLogs(k8, namespace) await nodeCmd.accountManager.close() await nodeCmd.stop(argv) await networkCmd.destroy(argv) await k8.deleteNamespace(namespace) - }, 600000) + }) it('cache current version of private keys', async () => { existingServiceMap = await nodeCmd.accountManager.getNodeServiceMap(namespace) existingNodeIdsPrivateKeysHash = await getNodeIdsPrivateKeysHash(existingServiceMap, namespace, k8, getTmpDir()) - }, defaultTimeout) + }).timeout(defaultTimeout) it('should succeed with init command', async () => { const status = await accountCmd.init(argv) - expect(status).toBeTruthy() - }, 450000) + expect(status).to.be.ok + }).timeout(450_000) it('should add a new node to the network successfully', async () => { await nodeCmd.add(argv) - expect(nodeCmd.getUnusedConfigs(NodeCommand.ADD_CONFIGS_NAME)).toEqual([ + expect(nodeCmd.getUnusedConfigs(NodeCommand.ADD_CONFIGS_NAME)).to.deep.equal([ flags.app.constName, flags.chainId.constName, flags.devMode.constName, @@ -84,7 +88,7 @@ export function testNodeAdd (localBuildPath flags.adminKey.constName ]) await nodeCmd.accountManager.close() - }, 800000) + }).timeout(800_000) balanceQueryShouldSucceed(nodeCmd.accountManager, nodeCmd, namespace) @@ -97,10 +101,10 @@ export function testNodeAdd (localBuildPath const currentNodeKeyHashMap = currentNodeIdsPrivateKeysHash.get(nodeId) for (const [keyFileName, existingKeyHash] of existingKeyHashMap.entries()) { - expect(`${nodeId}:${keyFileName}:${currentNodeKeyHashMap.get(keyFileName)}`).toEqual( + expect(`${nodeId}:${keyFileName}:${currentNodeKeyHashMap.get(keyFileName)}`).to.deep.equal( `${nodeId}:${keyFileName}:${existingKeyHash}`) } } - }, defaultTimeout) + }).timeout(defaultTimeout) }) } diff --git a/test/test_util.js b/test/test_util.js index 3f453612f..65b8d87da 100644 --- a/test/test_util.js +++ b/test/test_util.js @@ -13,9 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * @jest-environment steps + * @mocha-environment steps */ -import { afterAll, beforeAll, describe, expect, it } from '@jest/globals' +import { describe, it, before, after } from 'mocha' +import { expect } from 'chai' import fs from 'fs' import os from 'os' import path from 'path' @@ -96,14 +97,14 @@ export function getDefaultArgv () { /** * Initialize common test variables * - * @param testName test name - * @param argv argv for commands - * @param k8Arg an instance of core/K8 - * @param initCmdArg an instance of command/InitCommand - * @param clusterCmdArg an instance of command/ClusterCommand - * @param networkCmdArg an instance of command/NetworkCommand - * @param nodeCmdArg an instance of command/NodeCommand - * @param accountCmdArg an instance of command/AccountCommand + * @param {string} testName + * @param {Object} argv argv for commands + * @param {K8|null} [k8Arg] + * @param {InitCommand|null} [initCmdArg] + * @param {ClusterCommand|null} [clusterCmdArg] + * @param {NetworkCommand|null} [networkCmdArg] + * @param {NodeCommand|null} [nodeCmdArg] + * @param {AccountCommand|null} [accountCmdArg] */ export function bootstrapTestVariables (testName, argv, k8Arg = null, @@ -168,15 +169,15 @@ export function bootstrapTestVariables (testName, argv, /** * Bootstrap network in a given namespace * - * @param testName test name - * @param argv argv for commands - * @param k8Arg an instance of core/K8 - * @param initCmdArg an instance of command/InitCommand - * @param clusterCmdArg an instance of command/ClusterCommand - * @param networkCmdArg an instance of command/NetworkCommand - * @param nodeCmdArg an instance of command/NodeCommand - * @param accountCmdArg an instance of command/AccountCommand - * @param startNodes start nodes after deployment, default is true + * @param {string} testName + * @param {Object} argv - argv for commands + * @param {K8|null} [k8Arg] + * @param {InitCommand|null} [initCmdArg] + * @param {ClusterCommand|null} [clusterCmdArg] + * @param {NetworkCommand|null} [networkCmdArg] + * @param {NodeCommand|null} [nodeCmdArg] + * @param {AccountCommand|null} [accountCmdArg] + * @param {boolean} [startNodes] - start nodes after deployment, default is true */ export function bootstrapNetwork (testName, argv, k8Arg = null, @@ -197,11 +198,11 @@ export function bootstrapNetwork (testName, argv, const chartManager = bootstrapResp.opts.chartManager describe(`Bootstrap network for test [release ${argv[flags.releaseTag.name]}}]`, () => { - beforeAll(() => { + before(() => { bootstrapResp.opts.logger.showUser(`------------------------- START: bootstrap (${testName}) ----------------------------`) }) - afterAll(() => { + after(() => { bootstrapResp.opts.logger.showUser(`------------------------- END: bootstrap (${testName}) ----------------------------`) }) @@ -213,29 +214,28 @@ export function bootstrapNetwork (testName, argv, while (await k8.hasNamespace(namespace)) { testLogger.debug(`Namespace ${namespace} still exist. Waiting...`) - await sleep(1500) + await sleep(1_500) } } if (!await chartManager.isChartInstalled(constants.FULLSTACK_SETUP_NAMESPACE, constants.FULLSTACK_CLUSTER_SETUP_CHART)) { await clusterCmd.setup(argv) } - }, 120000) + }).timeout(120_000) it('generate key files', async () => { - await expect(nodeCmd.keys(argv)).resolves.toBeTruthy() - expect(nodeCmd.getUnusedConfigs(NodeCommand.KEYS_CONFIGS_NAME)).toEqual([ + await expect(nodeCmd.keys(argv)).should.eventually.be.ok + expect(nodeCmd.getUnusedConfigs(NodeCommand.KEYS_CONFIGS_NAME)).to.deep.equal([ flags.cacheDir.constName, flags.devMode.constName, flags.quiet.constName ]) - }, 120000) + }).timeout(120_000) it('should succeed with network deploy', async () => { - expect.assertions(1) await networkCmd.deploy(argv) - expect(networkCmd.getUnusedConfigs(NetworkCommand.DEPLOY_CONFIGS_NAME)).toEqual([ + expect(networkCmd.getUnusedConfigs(NetworkCommand.DEPLOY_CONFIGS_NAME)).to.deep.equal([ flags.apiPermissionProperties.constName, flags.applicationEnv.constName, flags.applicationProperties.constName, @@ -247,34 +247,32 @@ export function bootstrapNetwork (testName, argv, flags.quiet.constName, flags.settingTxt.constName ]) - }, 180000) + }).timeout(180_000) if (startNodes) { it('should succeed with node setup command', async () => { - expect.assertions(2) // cache this, because `solo node setup.finalize()` will reset it to false try { - await expect(nodeCmd.setup(argv)).resolves.toBeTruthy() - expect(nodeCmd.getUnusedConfigs(NodeCommand.SETUP_CONFIGS_NAME)).toEqual([ + await expect(nodeCmd.setup(argv)).should.eventually.be.ok + expect(nodeCmd.getUnusedConfigs(NodeCommand.SETUP_CONFIGS_NAME)).to.deep.equal([ flags.app.constName, flags.appConfig.constName, flags.devMode.constName ]) } catch (e) { nodeCmd.logger.showUserError(e) - expect(e).toBeNull() + expect(e).be.null } - }, 240000) + }).timeout(240_000) it('should succeed with node start command', async () => { - expect.assertions(1) try { - await expect(nodeCmd.start(argv)).resolves.toBeTruthy() + await expect(nodeCmd.start(argv)).should.eventually.be.ok } catch (e) { nodeCmd.logger.showUserError(e) - expect(e).toBeNull() + expect(e).to.be.null } - }, 1800000) + }).timeout(1_800_000) } }) @@ -283,33 +281,29 @@ export function bootstrapNetwork (testName, argv, export function balanceQueryShouldSucceed (accountManager, cmd, namespace) { it('Balance query should succeed', async () => { - expect.assertions(3) - try { - expect(accountManager._nodeClient).toBeNull() + expect(accountManager._nodeClient).to.be.null await accountManager.loadNodeClient(namespace) - expect(accountManager._nodeClient).not.toBeNull() + expect(accountManager._nodeClient).not.to.be.null const balance = await new AccountBalanceQuery() .setAccountId(accountManager._nodeClient.getOperator().accountId) .execute(accountManager._nodeClient) - expect(balance.hbars).not.toBeNull() + expect(balance.hbars).not.be.null } catch (e) { cmd.logger.showUserError(e) - expect(e).toBeNull() + expect(e).to.be.null } await sleep(1000) - }, 120000) + }).timeout(120_000) } export function accountCreationShouldSucceed (accountManager, nodeCmd, namespace) { it('Account creation should succeed', async () => { - expect.assertions(3) - try { await accountManager.loadNodeClient(namespace) - expect(accountManager._nodeClient).not.toBeNull() + expect(accountManager._nodeClient).not.to.be.null const privateKey = PrivateKey.generate() const amount = 100 @@ -327,13 +321,13 @@ export function accountCreationShouldSucceed (accountManager, nodeCmd, namespace balance: amount } - expect(accountInfo.accountId).not.toBeNull() - expect(accountInfo.balance).toEqual(amount) + expect(accountInfo.accountId).not.to.be.null + expect(accountInfo.balance).to.equal(amount) } catch (e) { nodeCmd.logger.showUserError(e) - expect(e).toBeNull() + expect(e).to.be.null } - }, 120000) + }).timeout(120_000) } export async function getNodeIdsPrivateKeysHash (networkNodeServicesMap, namespace, k8, destDir) { diff --git a/test/unit/commands/base.test.mjs b/test/unit/commands/base.test.mjs index 7c637f0bc..f61fd69dc 100644 --- a/test/unit/commands/base.test.mjs +++ b/test/unit/commands/base.test.mjs @@ -14,7 +14,9 @@ * limitations under the License. * */ -import { expect, it, describe } from '@jest/globals' +import { it, describe } from 'mocha' +import { expect } from 'chai' + import { HelmDependencyManager, DependencyManager } from '../../../src/core/dependency_managers/index.mjs' import { ChartManager, @@ -54,10 +56,10 @@ describe('BaseCommand', () => { describe('runShell', () => { it('should fail during invalid program check', async () => { - await expect(baseCmd.run('INVALID_PROGRAM')).rejects.toThrowError() + await baseCmd.run('INVALID_PROGRAM').should.eventually.be.rejected }) it('should succeed during valid program check', async () => { - await expect(baseCmd.run('echo')).resolves.not.toBeNull() + await baseCmd.run('echo').should.eventually.resolve.not.be.null }) it('getConfig tracks property usage', async () => { const flagsList = [ @@ -89,20 +91,20 @@ describe('BaseCommand', () => { const NEW_CLASS1_NAME = 'newClassInstance1' const newClassInstance1 = /** @type {newClassInstance} **/ baseCmd.getConfig(NEW_CLASS1_NAME, flagsList, extraVars) - expect(newClassInstance1.releaseTag).toBe('releaseTag1') - expect(newClassInstance1.tlsClusterIssuerType).toBe('type2') - expect(newClassInstance1.valuesFile).toBe('file3') - expect(newClassInstance1.var1).toBe('') - expect(newClassInstance1.var2).toBe('') - expect(baseCmd.getUnusedConfigs(NEW_CLASS1_NAME)).toEqual([]) + expect(newClassInstance1.releaseTag).to.equal('releaseTag1') + expect(newClassInstance1.tlsClusterIssuerType).to.equal('type2') + expect(newClassInstance1.valuesFile).to.equal('file3') + expect(newClassInstance1.var1).to.equal('') + expect(newClassInstance1.var2).to.equal('') + expect(baseCmd.getUnusedConfigs(NEW_CLASS1_NAME)).to.equal([]) const NEW_CLASS2_NAME = 'newClassInstance2' const newClassInstance2 = /** @type {newClassInstance} **/ baseCmd.getConfig(NEW_CLASS2_NAME, flagsList, extraVars) newClassInstance2.var1 = 'var1' newClassInstance2.var2 = 'var2' - expect(newClassInstance2.var1).toBe('var1') - expect(newClassInstance2.var2).toBe('var2') - expect(baseCmd.getUnusedConfigs(NEW_CLASS2_NAME)).toEqual([ + expect(newClassInstance2.var1).to.equal('var1') + expect(newClassInstance2.var2).to.equal('var2') + expect(baseCmd.getUnusedConfigs(NEW_CLASS2_NAME)).to.deep.equal([ flags.releaseTag.constName, flags.tlsClusterIssuerType.constName, flags.valuesFile.constName @@ -111,16 +113,16 @@ describe('BaseCommand', () => { const NEW_CLASS3_NAME = 'newClassInstance3' const newClassInstance3 = /** @type {newClassInstance} **/ baseCmd.getConfig(NEW_CLASS3_NAME, flagsList, extraVars) newClassInstance3.var1 = 'var1' - expect(newClassInstance3.var1).toBe('var1') - expect(newClassInstance3.tlsClusterIssuerType).toBe('type2') - expect(baseCmd.getUnusedConfigs(NEW_CLASS3_NAME)).toEqual([ + expect(newClassInstance3.var1).to.equal('var1') + expect(newClassInstance3.tlsClusterIssuerType).to.equal('type2') + expect(baseCmd.getUnusedConfigs(NEW_CLASS3_NAME)).to.deep.equal([ flags.releaseTag.constName, flags.valuesFile.constName, 'var2' ]) const newClassInstance4 = baseCmd.getConfig('newClassInstance4', []) - expect(newClassInstance4.getUnusedConfigs()).toEqual([]) + expect(newClassInstance4.getUnusedConfigs()).to.deep.equal([]) }) }) }) diff --git a/test/unit/commands/init.test.mjs b/test/unit/commands/init.test.mjs index 5521348a1..e5c2d31ee 100644 --- a/test/unit/commands/init.test.mjs +++ b/test/unit/commands/init.test.mjs @@ -14,8 +14,10 @@ * limitations under the License. * */ +import { it, describe } from 'mocha' +import { expect } from 'chai' + import { InitCommand } from '../../../src/commands/init.mjs' -import { expect, describe, it } from '@jest/globals' import { HelmDependencyManager, DependencyManager, @@ -51,27 +53,21 @@ describe('InitCommand', () => { const k8 = getK8Instance(configManager) const initCmd = new InitCommand({ - logger: testLogger, - helm, - k8, - chartManager, - configManager, - depManager, - keyManager + logger: testLogger, helm, k8, chartManager, configManager, depManager, keyManager }) describe('commands', () => { it('init execution should succeed', async () => { - await expect(initCmd.init({})).resolves.toBe(true) - }, 20000) + await expect(initCmd.init({})).should.eventually.resolve.to.equal(true) + }).timeout(20_000) }) describe('static', () => { it('command definition should return a valid command def', async () => { const def = InitCommand.getCommandDefinition(initCmd) - expect(def.name).not.toBeNull() - expect(def.desc).not.toBeNull() - expect(def.handler).not.toBeNull() + expect(def.name).not.to.be.null + expect(def.desc).not.to.be.null + expect(def.handler).not.to.be.null }) }) }) diff --git a/test/unit/commands/node.test.mjs b/test/unit/commands/node.test.mjs index 245719956..6b7c1fb87 100644 --- a/test/unit/commands/node.test.mjs +++ b/test/unit/commands/node.test.mjs @@ -14,55 +14,51 @@ * limitations under the License. * */ -import { - beforeEach, - describe, - expect, - it, - jest -} from '@jest/globals' +import jest from 'jest-mock' +import { it, describe, before } from 'mocha' +import { expect } from 'chai' import { NodeCommand } from '../../../src/commands/node.mjs' function getBaseCommandOpts () { - const opts = {} - opts.logger = jest.fn() - opts.helm = jest.fn() - opts.k8 = jest.fn() - opts.chartManager = jest.fn() - opts.configManager = jest.fn() - opts.depManager = jest.fn() - return opts + return { + logger: jest.fn(), + helm: jest.fn(), + k8: jest.fn(), + chartManager: jest.fn(), + configManager: jest.fn(), + depManager: jest.fn() + } } describe('NodeCommand unit tests', () => { describe('constructor error handling', () => { let opts - beforeEach(() => { + before(() => { opts = getBaseCommandOpts() }) it('should throw an error if downloader is not provided', () => { - expect(() => new NodeCommand(opts)).toThrow('An instance of core/PackageDownloader is required') + expect(() => new NodeCommand(opts)).to.throw('An instance of core/PackageDownloader is required') }) it('should throw an error if platformInstaller is not provided', () => { opts.downloader = jest.fn() - expect(() => new NodeCommand(opts)).toThrow('An instance of core/PlatformInstaller is required') + expect(() => new NodeCommand(opts)).to.throw('An instance of core/PlatformInstaller is required') }) it('should throw an error if keyManager is not provided', () => { opts.downloader = jest.fn() opts.platformInstaller = jest.fn() - expect(() => new NodeCommand(opts)).toThrow('An instance of core/KeyManager is required') + expect(() => new NodeCommand(opts)).to.throw('An instance of core/KeyManager is required') }) it('should throw an error if accountManager is not provided', () => { opts.downloader = jest.fn() opts.platformInstaller = jest.fn() opts.keyManager = jest.fn() - expect(() => new NodeCommand(opts)).toThrow('An instance of core/AccountManager is required') + expect(() => new NodeCommand(opts)).to.throw('An instance of core/AccountManager is required') }) it('should throw an error if keytoolDepManager is not provided', () => { @@ -70,7 +66,7 @@ describe('NodeCommand unit tests', () => { opts.platformInstaller = jest.fn() opts.keyManager = jest.fn() opts.accountManager = jest.fn() - expect(() => new NodeCommand(opts)).toThrow('An instance of KeytoolDependencyManager is required') + expect(() => new NodeCommand(opts)).to.throw('An instance of KeytoolDependencyManager is required') }) }) }) diff --git a/test/unit/core/config_manager.test.mjs b/test/unit/core/config_manager.test.mjs index a506fe3c2..e192e558c 100644 --- a/test/unit/core/config_manager.test.mjs +++ b/test/unit/core/config_manager.test.mjs @@ -14,7 +14,9 @@ * limitations under the License. * */ -import { afterAll, describe, expect, it } from '@jest/globals' +import { it, describe, after } from 'mocha' +import { expect } from 'chai' + import os from 'os' import path from 'path' import { ConfigManager } from '../../../src/core/index.mjs' @@ -29,20 +31,20 @@ describe('ConfigManager', () => { const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'config-')) const tmpFile = path.join(tmpDir, 'test.yaml') - expect(fs.existsSync(tmpFile)).toBeFalsy() + expect(fs.existsSync(tmpFile)).to.not.be.ok const cm = new ConfigManager(testLogger, tmpFile) cm.persist() - expect(fs.existsSync(tmpFile)).toBeTruthy() + expect(fs.existsSync(tmpFile)).to.be.ok const cachedConfig = yamlToObject(tmpFile) - expect(cachedConfig.version).toStrictEqual(helpers.packageVersion()) - expect(cachedConfig.flags).toStrictEqual({}) - expect(cachedConfig.updatedAt).not.toStrictEqual('') + expect(cachedConfig.version).to.equal(helpers.packageVersion()) + expect(cachedConfig.flags).to.deep.equal({}) + expect(cachedConfig.updatedAt).not.to.equal('') - expect(cachedConfig.updatedAt).toStrictEqual(cm.getUpdatedAt()) - expect(cachedConfig.version).toStrictEqual(cm.getVersion()) - expect(cachedConfig.flags).toStrictEqual(cm.config.flags) + expect(cachedConfig.updatedAt).to.equal(cm.getUpdatedAt()) + expect(cachedConfig.version).to.equal(cm.getVersion()) + expect(cachedConfig.flags).to.deep.equal(cm.config.flags) fs.rmSync(tmpDir, { recursive: true }) }) @@ -57,14 +59,14 @@ describe('ConfigManager', () => { argv[flags.releaseTag.name] = 'v0.42.5' cm.update(argv) - expect(cm.getFlag(flags.releaseTag)).toStrictEqual(argv[flags.releaseTag.name]) + expect(cm.getFlag(flags.releaseTag)).to.equal(argv[flags.releaseTag.name]) // ensure non-string values are converted to string cm.reset() argv[flags.releaseTag.name] = true cm.update(argv) - expect(cm.getFlag(flags.releaseTag)).not.toStrictEqual(argv[flags.releaseTag.name]) - expect(cm.getFlag(flags.releaseTag)).toStrictEqual(`${argv[flags.releaseTag.name]}`) + expect(cm.getFlag(flags.releaseTag)).not.to.deep.equal(argv[flags.releaseTag.name]) + expect(cm.getFlag(flags.releaseTag)).to.deep.equal(`${argv[flags.releaseTag.name]}`) }) it('should update number flag value', () => { @@ -73,14 +75,14 @@ describe('ConfigManager', () => { argv[flags.replicaCount.name] = 1 cm.update(argv) - expect(cm.getFlag(flags.replicaCount)).toStrictEqual(argv[flags.replicaCount.name]) + expect(cm.getFlag(flags.replicaCount)).to.deep.equal(argv[flags.replicaCount.name]) // ensure string values are converted to integer cm.reset() argv[flags.replicaCount.name] = '1' cm.update(argv) - expect(cm.getFlag(flags.replicaCount)).not.toStrictEqual(argv[flags.replicaCount.name]) - expect(cm.getFlag(flags.replicaCount)).toStrictEqual(Number.parseInt(argv[flags.replicaCount.name])) + expect(cm.getFlag(flags.replicaCount)).not.to.deep.equal(argv[flags.replicaCount.name]) + expect(cm.getFlag(flags.replicaCount)).to.deep.equal(Number.parseInt(argv[flags.replicaCount.name])) }) it('should update boolean flag value', () => { @@ -90,24 +92,24 @@ describe('ConfigManager', () => { const argv = {} argv[flags.devMode.name] = true cm.update(argv) - expect(cm.getFlag(flags.devMode)).toStrictEqual(argv[flags.devMode.name]) + expect(cm.getFlag(flags.devMode)).to.deep.equal(argv[flags.devMode.name]) // ensure string "false" is converted to boolean cm.reset() argv[flags.devMode.name] = 'false' cm.update(argv) - expect(cm.getFlag(flags.devMode)).not.toStrictEqual(argv[flags.devMode.name]) - expect(cm.getFlag(flags.devMode)).toStrictEqual(false) + expect(cm.getFlag(flags.devMode)).not.to.deep.equal(argv[flags.devMode.name]) + expect(cm.getFlag(flags.devMode)).to.equal(false) // ensure string "true" is converted to boolean cm.reset() argv[flags.devMode.name] = 'true' cm.update(argv) - expect(cm.getFlag(flags.devMode)).not.toStrictEqual(argv[flags.devMode.name]) - expect(cm.getFlag(flags.devMode)).toStrictEqual(true) + expect(cm.getFlag(flags.devMode)).not.to.deep.equal(argv[flags.devMode.name]) + expect(cm.getFlag(flags.devMode)).to.equal(true) }) - afterAll(() => { + after(() => { fs.rmdirSync(tmpDir, { recursive: true }) }) }) @@ -123,14 +125,14 @@ describe('ConfigManager', () => { // Expected: argv should retain the value const cm = new ConfigManager(testLogger, tmpFile) cm.setFlag(flags.devMode, false) - expect(cm.getFlag(flags.devMode)).toBeFalsy() + expect(cm.getFlag(flags.devMode)).not.to.be.ok const argv = {} argv[flags.devMode.name] = true // devMode flag is set in argv but cached config has it const argv2 = cm.applyPrecedence(argv, aliases) - expect(cm.getFlag(flags.devMode)).toBeFalsy() // shouldn't have changed the config yet - expect(argv2[flags.devMode.name]).toBeTruthy() // retain the value + expect(cm.getFlag(flags.devMode)).to.not.be.ok // shouldn't have changed the config yet + expect(argv2[flags.devMode.name]).to.be.ok // retain the value }) it('should take cached config as the second preference', () => { @@ -139,27 +141,27 @@ describe('ConfigManager', () => { const cm = new ConfigManager(testLogger, tmpFile) cm.setFlag(flags.devMode, false) - expect(cm.getFlag(flags.devMode)).toBeFalsy() + expect(cm.getFlag(flags.devMode)).to.not.be.ok const argv = {} // devMode flag is not set in argv const argv2 = cm.applyPrecedence(argv, aliases) - expect(cm.getFlag(flags.devMode)).toBeFalsy() // shouldn't have changed - expect(argv2[flags.devMode.name]).toStrictEqual(cm.getFlag(flags.devMode)) // should inherit from config + expect(cm.getFlag(flags.devMode)).to.not.be.ok // shouldn't have changed + expect(argv2[flags.devMode.name]).to.deep.equal(cm.getFlag(flags.devMode)) // should inherit from config }) it('should take default as the last preference', () => { // Given: neither config nor argv has the flag value set // Expected: argv should inherit the default flag value const cm = new ConfigManager(testLogger, tmpFile) - expect(cm.hasFlag(flags.devMode)).toBeFalsy() // shouldn't have set + expect(cm.hasFlag(flags.devMode)).not.to.be.ok // shouldn't have set const argv = {} // devMode flag is not set in argv and cached config doesn't have it either const argv2 = cm.applyPrecedence(argv, aliases) - expect(cm.hasFlag(flags.devMode)).toBeFalsy() // shouldn't have set - expect(argv2[flags.devMode.name]).toBeFalsy() // should have set from the default + expect(cm.hasFlag(flags.devMode)).to.not.be.ok // shouldn't have set + expect(argv2[flags.devMode.name]).to.not.be.ok // should have set from the default }) - afterAll(() => { + after(() => { fs.rmdirSync(tmpDir, { recursive: true }) }) }) @@ -170,51 +172,51 @@ describe('ConfigManager', () => { cm.load() it('config file match: dev=false', () => { - expect(cm.config.flags[flags.devMode.name]).toBeFalsy() + expect(cm.config.flags[flags.devMode.name]).to.not.be.ok }) it('config file match: namespace=solo-user', () => { - expect(cm.config.flags[flags.namespace.name]).toBe('solo-user') + expect(cm.config.flags[flags.namespace.name]).to.equal('solo-user') }) it('config file match: chartDirectory is empty', () => { - expect(cm.config.flags[flags.chartDirectory.name]).toBe('') + expect(cm.config.flags[flags.chartDirectory.name]).to.equal('') }) it('config file match: clusterName=kind-kind', () => { - expect(cm.config.flags[flags.clusterName.name]).toBe('kind-kind') + expect(cm.config.flags[flags.clusterName.name]).to.equal('kind-kind') }) it('config file match: deployPrometheusStack=false', () => { - expect(cm.config.flags[flags.deployPrometheusStack.name]).toBeFalsy() + expect(cm.config.flags[flags.deployPrometheusStack.name]).to.not.be.ok }) it('config file match: deployMinio=false', () => { - expect(cm.config.flags[flags.deployMinio.name]).toBeFalsy() + expect(cm.config.flags[flags.deployMinio.name]).to.not.be.ok }) it('config file match: deployCertManager=false', () => { - expect(cm.config.flags[flags.deployCertManager.name]).toBeFalsy() + expect(cm.config.flags[flags.deployCertManager.name]).to.not.be.ok }) it('config file match: deployCertManagerCrds=false', () => { - expect(cm.config.flags[flags.deployCertManagerCrds.name]).toBeFalsy() + expect(cm.config.flags[flags.deployCertManagerCrds.name]).to.not.be.ok }) it('not set, it should be undefined', () => { - expect(cm.config.flags[flags.enablePrometheusSvcMonitor.name]).toBeUndefined() + expect(cm.config.flags[flags.enablePrometheusSvcMonitor.name]).to.be.undefined }) it('not set, it should be undefined', () => { - expect(cm.config.flags[flags.enableHederaExplorerTls.name]).toBeUndefined() + expect(cm.config.flags[flags.enableHederaExplorerTls.name]).to.be.undefined }) it('not set, it should be undefined', () => { - expect(cm.config.flags[flags.hederaExplorerTlsHostName.name]).toBeUndefined() + expect(cm.config.flags[flags.hederaExplorerTlsHostName.name]).to.be.undefined }) it('not set, it should be undefined', () => { - expect(cm.config.flags[flags.deletePvcs.name]).toBeUndefined() + expect(cm.config.flags[flags.deletePvcs.name]).to.be.undefined }) }) @@ -225,44 +227,44 @@ describe('ConfigManager', () => { it('override config using argv', () => { cm.load() - expect(cm.getFlag(flags.clusterName)).toBe(cachedConfig.flags[flags.clusterName.name]) - expect(cm.getFlag(flags.namespace)).toBe(cachedConfig.flags[flags.namespace.name]) + expect(cm.getFlag(flags.clusterName)).to.equal(cachedConfig.flags[flags.clusterName.name]) + expect(cm.getFlag(flags.namespace)).to.equal(cachedConfig.flags[flags.namespace.name]) const argv = {} argv[flags.clusterName.name] = 'new-cluster' argv[flags.namespace.name] = 'new-namespace' cm.update(argv) - expect(cm.getFlag(flags.clusterName)).toBe(argv[flags.clusterName.name]) - expect(cm.getFlag(flags.namespace)).toBe(argv[flags.namespace.name]) + expect(cm.getFlag(flags.clusterName)).to.equal(argv[flags.clusterName.name]) + expect(cm.getFlag(flags.namespace)).to.equal(argv[flags.namespace.name]) }) it('config file takes precedence over empty namespace', () => { cm.load() - expect(cm.getFlag(flags.clusterName)).toBe(cachedConfig.flags[flags.clusterName.name]) - expect(cm.getFlag(flags.namespace)).toBe(cachedConfig.flags[flags.namespace.name]) + expect(cm.getFlag(flags.clusterName)).to.equal(cachedConfig.flags[flags.clusterName.name]) + expect(cm.getFlag(flags.namespace)).to.equal(cachedConfig.flags[flags.namespace.name]) const argv = {} argv[flags.clusterName.name] = 'new-cluster' argv[flags.namespace.name] = '' cm.update(argv) - expect(cm.getFlag(flags.clusterName)).toBe(argv[flags.clusterName.name]) - expect(cm.getFlag(flags.namespace)).not.toBe(argv[flags.namespace.name]) - expect(cm.getFlag(flags.namespace)).toBe(cachedConfig.flags[flags.namespace.name]) + expect(cm.getFlag(flags.clusterName)).to.equal(argv[flags.clusterName.name]) + expect(cm.getFlag(flags.namespace)).not.to.equal(argv[flags.namespace.name]) + expect(cm.getFlag(flags.namespace)).to.equal(cachedConfig.flags[flags.namespace.name]) }) it('config file takes precedence over empty cluster name', () => { cm.load() - expect(cm.getFlag(flags.clusterName)).toBe(cachedConfig.flags[flags.clusterName.name]) - expect(cm.getFlag(flags.namespace)).toBe(cachedConfig.flags[flags.namespace.name]) + expect(cm.getFlag(flags.clusterName)).to.equal(cachedConfig.flags[flags.clusterName.name]) + expect(cm.getFlag(flags.namespace)).to.equal(cachedConfig.flags[flags.namespace.name]) const argv = {} argv[flags.clusterName.name] = '' argv[flags.namespace.name] = 'new-namespace' cm.update(argv) - expect(cm.getFlag(flags.clusterName)).not.toBe(argv[flags.clusterName.name]) - expect(cm.getFlag(flags.clusterName)).toBe(cachedConfig.flags[flags.clusterName.name]) - expect(cm.getFlag(flags.namespace)).toBe(argv[flags.namespace.name]) + expect(cm.getFlag(flags.clusterName)).not.to.equal(argv[flags.clusterName.name]) + expect(cm.getFlag(flags.clusterName)).to.equal(cachedConfig.flags[flags.clusterName.name]) + expect(cm.getFlag(flags.namespace)).to.equal(argv[flags.namespace.name]) }) }) })