diff --git a/.gitignore b/.gitignore index de4d1f0..35a86a0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ -dist -node_modules +/.nyc_output/ +/coverage/ +/dist/ +/node_modules/ diff --git a/package.json b/package.json index 55ae646..e32ae52 100644 --- a/package.json +++ b/package.json @@ -4,15 +4,21 @@ "description": "An open source collection and playground of algorithms, data structures and related documentation to brush up your knowledge of computer science fundamentals, or learn it from scratch.", "type": "module", "scripts": { - "clean": "rm -rf dist", - "build": "pnpm clean && tsc", - "watch": "pnpm clean && tsc --watch" + "clean": "rm -rf .nyc_output coverage dist", + "test": "nyc mocha 'src/**/*.test.ts' --require=tsx", + "coverage": "nyc report --reporter html && open coverage/index.html", + "coverage:check": "nyc check-coverage --lines 90 --branches 80 --statements 90" }, "packageManager": "pnpm@10.12.1", "devDependencies": { + "@types/chai": "^5.2.2", + "@types/mocha": "^10.0.10", + "@types/sinon": "^17.0.4", + "chai": "^5.2.1", "mocha": "^11.7.1", "nyc": "^17.1.0", "sinon": "^21.0.0", + "tsx": "^4.20.3", "typescript": "^5.8.3" }, "repository": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b8f9e44..6341df8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,18 @@ importers: .: devDependencies: + '@types/chai': + specifier: ^5.2.2 + version: 5.2.2 + '@types/mocha': + specifier: ^10.0.10 + version: 10.0.10 + '@types/sinon': + specifier: ^17.0.4 + version: 17.0.4 + chai: + specifier: ^5.2.1 + version: 5.2.1 mocha: specifier: ^11.7.1 version: 11.7.1 @@ -17,6 +29,9 @@ importers: sinon: specifier: ^21.0.0 version: 21.0.0 + tsx: + specifier: ^4.20.3 + version: 4.20.3 typescript: specifier: ^5.8.3 version: 5.8.3 @@ -94,6 +109,162 @@ packages: resolution: {integrity: sha512-x0LvFTekgSX+83TI28Y9wYPUfzrnl2aT5+5QLnO6v7mSJYtEEevuDRN0F0uSHRk1G1IWZC43o00Y0xDDrpBGPQ==} engines: {node: '>=6.9.0'} + '@esbuild/aix-ppc64@0.25.6': + resolution: {integrity: sha512-ShbM/3XxwuxjFiuVBHA+d3j5dyac0aEVVq1oluIDf71hUw0aRF59dV/efUsIwFnR6m8JNM2FjZOzmaZ8yG61kw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.25.6': + resolution: {integrity: sha512-hd5zdUarsK6strW+3Wxi5qWws+rJhCCbMiC9QZyzoxfk5uHRIE8T287giQxzVpEvCwuJ9Qjg6bEjcRJcgfLqoA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.25.6': + resolution: {integrity: sha512-S8ToEOVfg++AU/bHwdksHNnyLyVM+eMVAOf6yRKFitnwnbwwPNqKr3srzFRe7nzV69RQKb5DgchIX5pt3L53xg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.25.6': + resolution: {integrity: sha512-0Z7KpHSr3VBIO9A/1wcT3NTy7EB4oNC4upJ5ye3R7taCc2GUdeynSLArnon5G8scPwaU866d3H4BCrE5xLW25A==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.25.6': + resolution: {integrity: sha512-FFCssz3XBavjxcFxKsGy2DYK5VSvJqa6y5HXljKzhRZ87LvEi13brPrf/wdyl/BbpbMKJNOr1Sd0jtW4Ge1pAA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.25.6': + resolution: {integrity: sha512-GfXs5kry/TkGM2vKqK2oyiLFygJRqKVhawu3+DOCk7OxLy/6jYkWXhlHwOoTb0WqGnWGAS7sooxbZowy+pK9Yg==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.25.6': + resolution: {integrity: sha512-aoLF2c3OvDn2XDTRvn8hN6DRzVVpDlj2B/F66clWd/FHLiHaG3aVZjxQX2DYphA5y/evbdGvC6Us13tvyt4pWg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.25.6': + resolution: {integrity: sha512-2SkqTjTSo2dYi/jzFbU9Plt1vk0+nNg8YC8rOXXea+iA3hfNJWebKYPs3xnOUf9+ZWhKAaxnQNUf2X9LOpeiMQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.25.6': + resolution: {integrity: sha512-b967hU0gqKd9Drsh/UuAm21Khpoh6mPBSgz8mKRq4P5mVK8bpA+hQzmm/ZwGVULSNBzKdZPQBRT3+WuVavcWsQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.25.6': + resolution: {integrity: sha512-SZHQlzvqv4Du5PrKE2faN0qlbsaW/3QQfUUc6yO2EjFcA83xnwm91UbEEVx4ApZ9Z5oG8Bxz4qPE+HFwtVcfyw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.25.6': + resolution: {integrity: sha512-aHWdQ2AAltRkLPOsKdi3xv0mZ8fUGPdlKEjIEhxCPm5yKEThcUjHpWB1idN74lfXGnZ5SULQSgtr5Qos5B0bPw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.25.6': + resolution: {integrity: sha512-VgKCsHdXRSQ7E1+QXGdRPlQ/e08bN6WMQb27/TMfV+vPjjTImuT9PmLXupRlC90S1JeNNW5lzkAEO/McKeJ2yg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.25.6': + resolution: {integrity: sha512-WViNlpivRKT9/py3kCmkHnn44GkGXVdXfdc4drNmRl15zVQ2+D2uFwdlGh6IuK5AAnGTo2qPB1Djppj+t78rzw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.25.6': + resolution: {integrity: sha512-wyYKZ9NTdmAMb5730I38lBqVu6cKl4ZfYXIs31Baf8aoOtB4xSGi3THmDYt4BTFHk7/EcVixkOV2uZfwU3Q2Jw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.25.6': + resolution: {integrity: sha512-KZh7bAGGcrinEj4qzilJ4hqTY3Dg2U82c8bv+e1xqNqZCrCyc+TL9AUEn5WGKDzm3CfC5RODE/qc96OcbIe33w==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.25.6': + resolution: {integrity: sha512-9N1LsTwAuE9oj6lHMyyAM+ucxGiVnEqUdp4v7IaMmrwb06ZTEVCIs3oPPplVsnjPfyjmxwHxHMF8b6vzUVAUGw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.25.6': + resolution: {integrity: sha512-A6bJB41b4lKFWRKNrWoP2LHsjVzNiaurf7wyj/XtFNTsnPuxwEBWHLty+ZE0dWBKuSK1fvKgrKaNjBS7qbFKig==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.25.6': + resolution: {integrity: sha512-IjA+DcwoVpjEvyxZddDqBY+uJ2Snc6duLpjmkXm/v4xuS3H+3FkLZlDm9ZsAbF9rsfP3zeA0/ArNDORZgrxR/Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.25.6': + resolution: {integrity: sha512-dUXuZr5WenIDlMHdMkvDc1FAu4xdWixTCRgP7RQLBOkkGgwuuzaGSYcOpW4jFxzpzL1ejb8yF620UxAqnBrR9g==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.25.6': + resolution: {integrity: sha512-l8ZCvXP0tbTJ3iaqdNf3pjaOSd5ex/e6/omLIQCVBLmHTlfXW3zAxQ4fnDmPLOB1x9xrcSi/xtCWFwCZRIaEwg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.25.6': + resolution: {integrity: sha512-hKrmDa0aOFOr71KQ/19JC7az1P0GWtCN1t2ahYAf4O007DHZt/dW8ym5+CUdJhQ/qkZmI1HAF8KkJbEFtCL7gw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.25.6': + resolution: {integrity: sha512-+SqBcAWoB1fYKmpWoQP4pGtx+pUUC//RNYhFdbcSA16617cchuryuhOCRpPsjCblKukAckWsV+aQ3UKT/RMPcA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.25.6': + resolution: {integrity: sha512-dyCGxv1/Br7MiSC42qinGL8KkG4kX0pEsdb0+TKhmJZgCUDBGmyo1/ArCjNGiOLiIAgdbWgmWgib4HoCi5t7kA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.25.6': + resolution: {integrity: sha512-42QOgcZeZOvXfsCBJF5Afw73t4veOId//XD3i+/9gSkhSV6Gk3VPlWncctI+JcOyERv85FUo7RxuxGy+z8A43Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.25.6': + resolution: {integrity: sha512-4AWhgXmDuYN7rJI6ORB+uU9DHLq/erBbuMoAuB4VWJTu5KtCgcKYPynF0YI1VkBNuEfjNlLrFr9KZPJzrtLkrQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.25.6': + resolution: {integrity: sha512-NgJPHHbEpLQgDH2MjQu90pzW/5vvXIZ7KOnPyNBm92A6WgZ/7b6fJyUBjoumLqeOQQGqY2QjQxRo97ah4Sj0cA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -132,6 +303,21 @@ packages: '@sinonjs/samsam@8.0.2': resolution: {integrity: sha512-v46t/fwnhejRSFTGqbpn9u+LQ9xJDse10gNnPgAcxgdoCDMXj/G2asWAC/8Qs+BAZDicX+MNZouXT1A7c83kVw==} + '@types/chai@5.2.2': + resolution: {integrity: sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==} + + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + + '@types/mocha@10.0.10': + resolution: {integrity: sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==} + + '@types/sinon@17.0.4': + resolution: {integrity: sha512-RHnIrhfPO3+tJT0s7cFaXGZvsL4bbR3/k7z3P312qMS4JaS2Tk+KiwiLx1S0rQ56ERj00u1/BtdyVd0FY+Pdew==} + + '@types/sinonjs__fake-timers@8.1.5': + resolution: {integrity: sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==} + aggregate-error@3.1.0: resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} engines: {node: '>=8'} @@ -165,6 +351,10 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -197,10 +387,18 @@ packages: caniuse-lite@1.0.30001727: resolution: {integrity: sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==} + chai@5.2.1: + resolution: {integrity: sha512-5nFxhUrX0PqtyogoYOA8IPswy5sZFTOsBFl/9bNsmDLgsxYTzSZQJDPppDnZPTQbzSEm0hqGjWPzRemQCYbD6A==} + engines: {node: '>=18'} + chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} + check-error@2.1.1: + resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} + engines: {node: '>= 16'} + chokidar@4.0.3: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} @@ -256,6 +454,10 @@ packages: resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} engines: {node: '>=10'} + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} + engines: {node: '>=6'} + default-require-extensions@3.0.1: resolution: {integrity: sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==} engines: {node: '>=8'} @@ -279,6 +481,11 @@ packages: es6-error@4.1.1: resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==} + esbuild@0.25.6: + resolution: {integrity: sha512-GVuzuUwtdsghE3ocJ9Bs8PNoF13HNQ5TXbEi2AhvVb8xU1Iwt9Fos9FEamfoee+u/TOsn7GUWc04lz46n2bbTg==} + engines: {node: '>=18'} + hasBin: true + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -322,6 +529,11 @@ packages: fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} @@ -334,6 +546,9 @@ packages: resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} engines: {node: '>=8.0.0'} + get-tsconfig@4.10.1: + resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==} + glob@10.4.5: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} hasBin: true @@ -472,6 +687,9 @@ packages: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} + loupe@3.1.4: + resolution: {integrity: sha512-wJzkKwJrheKtknCOKNEtDK4iqg/MxmZheEMtSTYvnzRdEYaZzmgH976nenp8WdJRdx5Vc1X/9MO0Oszl6ezeXg==} + lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} @@ -567,6 +785,10 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} + pathval@2.0.1: + resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} + engines: {node: '>= 14.16'} + picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -600,6 +822,9 @@ packages: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} engines: {node: '>=8'} + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} deprecated: Rimraf versions prior to v4 are no longer supported @@ -688,6 +913,11 @@ packages: resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} engines: {node: '>=8'} + tsx@4.20.3: + resolution: {integrity: sha512-qjbnuR9Tr+FJOMBqJCW5ehvIo/buZq7vH7qD7JziU98h6l3qGy0a/yPFjwO+y0/T7GFpNgNAvEcPPVfyT8rrPQ==} + engines: {node: '>=18.0.0'} + hasBin: true + type-detect@4.0.8: resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} engines: {node: '>=4'} @@ -888,6 +1118,84 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 + '@esbuild/aix-ppc64@0.25.6': + optional: true + + '@esbuild/android-arm64@0.25.6': + optional: true + + '@esbuild/android-arm@0.25.6': + optional: true + + '@esbuild/android-x64@0.25.6': + optional: true + + '@esbuild/darwin-arm64@0.25.6': + optional: true + + '@esbuild/darwin-x64@0.25.6': + optional: true + + '@esbuild/freebsd-arm64@0.25.6': + optional: true + + '@esbuild/freebsd-x64@0.25.6': + optional: true + + '@esbuild/linux-arm64@0.25.6': + optional: true + + '@esbuild/linux-arm@0.25.6': + optional: true + + '@esbuild/linux-ia32@0.25.6': + optional: true + + '@esbuild/linux-loong64@0.25.6': + optional: true + + '@esbuild/linux-mips64el@0.25.6': + optional: true + + '@esbuild/linux-ppc64@0.25.6': + optional: true + + '@esbuild/linux-riscv64@0.25.6': + optional: true + + '@esbuild/linux-s390x@0.25.6': + optional: true + + '@esbuild/linux-x64@0.25.6': + optional: true + + '@esbuild/netbsd-arm64@0.25.6': + optional: true + + '@esbuild/netbsd-x64@0.25.6': + optional: true + + '@esbuild/openbsd-arm64@0.25.6': + optional: true + + '@esbuild/openbsd-x64@0.25.6': + optional: true + + '@esbuild/openharmony-arm64@0.25.6': + optional: true + + '@esbuild/sunos-x64@0.25.6': + optional: true + + '@esbuild/win32-arm64@0.25.6': + optional: true + + '@esbuild/win32-ia32@0.25.6': + optional: true + + '@esbuild/win32-x64@0.25.6': + optional: true + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -938,6 +1246,20 @@ snapshots: lodash.get: 4.4.2 type-detect: 4.1.0 + '@types/chai@5.2.2': + dependencies: + '@types/deep-eql': 4.0.2 + + '@types/deep-eql@4.0.2': {} + + '@types/mocha@10.0.10': {} + + '@types/sinon@17.0.4': + dependencies: + '@types/sinonjs__fake-timers': 8.1.5 + + '@types/sinonjs__fake-timers@8.1.5': {} + aggregate-error@3.1.0: dependencies: clean-stack: 2.2.0 @@ -965,6 +1287,8 @@ snapshots: argparse@2.0.1: {} + assertion-error@2.0.1: {} + balanced-match@1.0.2: {} brace-expansion@1.1.12: @@ -998,11 +1322,21 @@ snapshots: caniuse-lite@1.0.30001727: {} + chai@5.2.1: + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.1 + deep-eql: 5.0.2 + loupe: 3.1.4 + pathval: 2.0.1 + chalk@4.1.2: dependencies: ansi-styles: 4.3.0 supports-color: 7.2.0 + check-error@2.1.1: {} + chokidar@4.0.3: dependencies: readdirp: 4.1.2 @@ -1051,6 +1385,8 @@ snapshots: decamelize@4.0.0: {} + deep-eql@5.0.2: {} + default-require-extensions@3.0.1: dependencies: strip-bom: 4.0.0 @@ -1067,6 +1403,35 @@ snapshots: es6-error@4.1.1: {} + esbuild@0.25.6: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.6 + '@esbuild/android-arm': 0.25.6 + '@esbuild/android-arm64': 0.25.6 + '@esbuild/android-x64': 0.25.6 + '@esbuild/darwin-arm64': 0.25.6 + '@esbuild/darwin-x64': 0.25.6 + '@esbuild/freebsd-arm64': 0.25.6 + '@esbuild/freebsd-x64': 0.25.6 + '@esbuild/linux-arm': 0.25.6 + '@esbuild/linux-arm64': 0.25.6 + '@esbuild/linux-ia32': 0.25.6 + '@esbuild/linux-loong64': 0.25.6 + '@esbuild/linux-mips64el': 0.25.6 + '@esbuild/linux-ppc64': 0.25.6 + '@esbuild/linux-riscv64': 0.25.6 + '@esbuild/linux-s390x': 0.25.6 + '@esbuild/linux-x64': 0.25.6 + '@esbuild/netbsd-arm64': 0.25.6 + '@esbuild/netbsd-x64': 0.25.6 + '@esbuild/openbsd-arm64': 0.25.6 + '@esbuild/openbsd-x64': 0.25.6 + '@esbuild/openharmony-arm64': 0.25.6 + '@esbuild/sunos-x64': 0.25.6 + '@esbuild/win32-arm64': 0.25.6 + '@esbuild/win32-ia32': 0.25.6 + '@esbuild/win32-x64': 0.25.6 + escalade@3.2.0: {} escape-string-regexp@4.0.0: {} @@ -1105,12 +1470,19 @@ snapshots: fs.realpath@1.0.0: {} + fsevents@2.3.3: + optional: true + gensync@1.0.0-beta.2: {} get-caller-file@2.0.5: {} get-package-type@0.1.0: {} + get-tsconfig@4.10.1: + dependencies: + resolve-pkg-maps: 1.0.0 + glob@10.4.5: dependencies: foreground-child: 3.3.1 @@ -1249,6 +1621,8 @@ snapshots: chalk: 4.1.2 is-unicode-supported: 0.1.0 + loupe@3.1.4: {} + lru-cache@10.4.3: {} lru-cache@5.1.1: @@ -1382,6 +1756,8 @@ snapshots: lru-cache: 10.4.3 minipass: 7.1.2 + pathval@2.0.1: {} + picocolors@1.1.1: {} pkg-dir@4.2.0: @@ -1408,6 +1784,8 @@ snapshots: resolve-from@5.0.0: {} + resolve-pkg-maps@1.0.0: {} + rimraf@3.0.2: dependencies: glob: 7.2.3 @@ -1493,6 +1871,13 @@ snapshots: glob: 7.2.3 minimatch: 3.1.2 + tsx@4.20.3: + dependencies: + esbuild: 0.25.6 + get-tsconfig: 4.10.1 + optionalDependencies: + fsevents: 2.3.3 + type-detect@4.0.8: {} type-detect@4.1.0: {} diff --git a/src/algorithms/dynamic-programming/fibonacci.test.ts b/src/algorithms/dynamic-programming/fibonacci.test.ts index fb93b17..f0df5f6 100644 --- a/src/algorithms/dynamic-programming/fibonacci.test.ts +++ b/src/algorithms/dynamic-programming/fibonacci.test.ts @@ -1,29 +1,34 @@ -import fibonacci from './fibonacci'; +import { expect } from 'chai'; +import fibonacci from './fibonacci.ts'; -const parameters = [ - { n: -1, expected: 0 }, - { n: 0, expected: 0 }, - { n: 1, expected: 1 }, - { n: 2, expected: 1 }, - { n: 3, expected: 2 }, - { n: 4, expected: 3 }, - { n: 5, expected: 5 }, - { n: 6, expected: 8 }, - { n: 7, expected: 13 }, - { n: 8, expected: 21 }, - { n: 9, expected: 34 }, - { n: 10, expected: 55 }, - { n: 20, expected: 6765 }, - { n: 30, expected: 832040 }, - { n: 40, expected: 102334155 }, - { n: 50, expected: 12586269025 }, - { n: 60, expected: 1548008755920 }, - { n: 70, expected: 190392490709135 }, - { n: 80, expected: 23416728348467684 }, - { n: 90, expected: 2880067194370816000 }, - { n: 100, expected: 354224848179262000000 }, -]; +describe("fibonacci", function () { + const tests = [ + { n: -1, expected: 0 }, + { n: 0, expected: 0 }, + { n: 1, expected: 1 }, + { n: 2, expected: 1 }, + { n: 3, expected: 2 }, + { n: 4, expected: 3 }, + { n: 5, expected: 5 }, + { n: 6, expected: 8 }, + { n: 7, expected: 13 }, + { n: 8, expected: 21 }, + { n: 9, expected: 34 }, + { n: 10, expected: 55 }, + { n: 20, expected: 6765 }, + { n: 30, expected: 832040 }, + { n: 40, expected: 102334155 }, + { n: 50, expected: 12586269025 }, + { n: 60, expected: 1548008755920 }, + { n: 70, expected: 190392490709135 }, + { n: 80, expected: 23416728348467684 }, + { n: 90, expected: 2880067194370816000 }, + { n: 100, expected: 354224848179262000000 }, + ]; -test.each(parameters)('fibonacci($n) = $expected', ({ n, expected }) => { - expect(fibonacci(n)).toBe(expected); + tests.forEach(({ n, expected }) => { + it(`fibonacci(${n}) should return ${expected}`, function () { + expect(fibonacci(n)).to.equal(expected); + }); + }); }); diff --git a/src/algorithms/dynamic-programming/grid-traveller.test.ts b/src/algorithms/dynamic-programming/grid-traveller.test.ts index 12a26b8..0176be1 100644 --- a/src/algorithms/dynamic-programming/grid-traveller.test.ts +++ b/src/algorithms/dynamic-programming/grid-traveller.test.ts @@ -1,51 +1,53 @@ -import gridTraveller from './grid-traveller'; +import { expect } from 'chai'; +import gridTraveller from './grid-traveller.ts'; -const parameters = [ - { rows: 0, columns: 0, expected: 0 }, - { rows: 0, columns: 1, expected: 0 }, - { rows: 1, columns: 0, expected: 0 }, - { rows: 1, columns: 1, expected: 1 }, - { rows: 1, columns: 2, expected: 1 }, - { rows: 2, columns: 1, expected: 1 }, - { rows: 2, columns: 2, expected: 2 }, - { rows: 2, columns: 3, expected: 3 }, - { rows: 3, columns: 2, expected: 3 }, - { rows: 3, columns: 3, expected: 6 }, - { rows: 3, columns: 4, expected: 10 }, - { rows: 4, columns: 3, expected: 10 }, - { rows: 4, columns: 4, expected: 20 }, - { rows: 4, columns: 5, expected: 35 }, - { rows: 5, columns: 4, expected: 35 }, - { rows: 5, columns: 5, expected: 70 }, - { rows: 5, columns: 6, expected: 126 }, - { rows: 6, columns: 5, expected: 126 }, - { rows: 6, columns: 6, expected: 252 }, - { rows: 6, columns: 7, expected: 462 }, - { rows: 7, columns: 6, expected: 462 }, - { rows: 7, columns: 7, expected: 924 }, - { rows: 7, columns: 8, expected: 1716 }, - { rows: 8, columns: 7, expected: 1716 }, - { rows: 8, columns: 8, expected: 3432 }, - { rows: 8, columns: 9, expected: 6435 }, - { rows: 9, columns: 8, expected: 6435 }, - { rows: 9, columns: 9, expected: 12870 }, - { rows: 9, columns: 10, expected: 24310 }, - { rows: 10, columns: 9, expected: 24310 }, - { rows: 10, columns: 10, expected: 48620 }, - { rows: 20, columns: 20, expected: 35345263800 }, - { rows: 30, columns: 30, expected: 30067266499541040 }, - { rows: 40, columns: 40, expected: 2.7217014869199036e22 }, - { rows: 50, columns: 50, expected: 2.5477612258980867e28 }, - { rows: 60, columns: 60, expected: 2.4356699707654625e34 }, - { rows: 70, columns: 70, expected: 2.362398517571512e40 }, - { rows: 80, columns: 80, expected: 2.3156006494021195e46 }, - { rows: 90, columns: 90, expected: 2.288017424736007e52 }, - { rows: 100, columns: 100, expected: 2.2750883079422938e58 }, -]; +describe('gridTraveller', () => { + const tests = [ + { rows: 0, columns: 0, expected: 0 }, + { rows: 0, columns: 1, expected: 0 }, + { rows: 1, columns: 0, expected: 0 }, + { rows: 1, columns: 1, expected: 1 }, + { rows: 1, columns: 2, expected: 1 }, + { rows: 2, columns: 1, expected: 1 }, + { rows: 2, columns: 2, expected: 2 }, + { rows: 2, columns: 3, expected: 3 }, + { rows: 3, columns: 2, expected: 3 }, + { rows: 3, columns: 3, expected: 6 }, + { rows: 3, columns: 4, expected: 10 }, + { rows: 4, columns: 3, expected: 10 }, + { rows: 4, columns: 4, expected: 20 }, + { rows: 4, columns: 5, expected: 35 }, + { rows: 5, columns: 4, expected: 35 }, + { rows: 5, columns: 5, expected: 70 }, + { rows: 5, columns: 6, expected: 126 }, + { rows: 6, columns: 5, expected: 126 }, + { rows: 6, columns: 6, expected: 252 }, + { rows: 6, columns: 7, expected: 462 }, + { rows: 7, columns: 6, expected: 462 }, + { rows: 7, columns: 7, expected: 924 }, + { rows: 7, columns: 8, expected: 1716 }, + { rows: 8, columns: 7, expected: 1716 }, + { rows: 8, columns: 8, expected: 3432 }, + { rows: 8, columns: 9, expected: 6435 }, + { rows: 9, columns: 8, expected: 6435 }, + { rows: 9, columns: 9, expected: 12870 }, + { rows: 9, columns: 10, expected: 24310 }, + { rows: 10, columns: 9, expected: 24310 }, + { rows: 10, columns: 10, expected: 48620 }, + { rows: 20, columns: 20, expected: 35345263800 }, + { rows: 30, columns: 30, expected: 30067266499541040 }, + { rows: 40, columns: 40, expected: 2.7217014869199036e22 }, + { rows: 50, columns: 50, expected: 2.5477612258980867e28 }, + { rows: 60, columns: 60, expected: 2.4356699707654625e34 }, + { rows: 70, columns: 70, expected: 2.362398517571512e40 }, + { rows: 80, columns: 80, expected: 2.3156006494021195e46 }, + { rows: 90, columns: 90, expected: 2.288017424736007e52 }, + { rows: 100, columns: 100, expected: 2.2750883079422938e58 }, + ]; -test.each(parameters)( - 'gridTraveller($rows, $columns) = $expected', - ({ rows, columns, expected }) => { - expect(gridTraveller(rows, columns)).toEqual(expected); - }, -); + tests.forEach(({ rows, columns, expected }) => { + it(`gridTraveller(${rows}, ${columns}) should return ${expected}`, () => { + expect(gridTraveller(rows, columns)).to.equal(expected); + }); + }); +}); diff --git a/src/algorithms/dynamic-programming/sum/can-sum.test.ts b/src/algorithms/dynamic-programming/sum/can-sum.test.ts index d34df26..dcee154 100644 --- a/src/algorithms/dynamic-programming/sum/can-sum.test.ts +++ b/src/algorithms/dynamic-programming/sum/can-sum.test.ts @@ -1,61 +1,63 @@ -import canSum from './can-sum'; +import { expect } from 'chai'; +import canSum from './can-sum.ts'; -const parameters = [ - { - targetSum: -5, - numbers: [10, 1, 0], - expected: false, - }, - { - targetSum: -1, - numbers: [], - expected: false, - }, - { - targetSum: 0, - numbers: [3, 7, 0], - expected: true, - }, - { - targetSum: 0, - numbers: [1], - expected: true, - }, - { - targetSum: 0, - numbers: [], - expected: true, - }, - { - targetSum: 55, - numbers: [], - expected: false, - }, - { - targetSum: 12, - numbers: [2, 4, 6, 12], - expected: true, - }, - { - targetSum: 12, - numbers: [1], - expected: true, - }, - { - targetSum: 12, - numbers: [7, 11, 8], - expected: false, - }, - { - targetSum: 300, - numbers: [2, 3, 30, 5, 10], - expected: true, - }, -]; +describe("canSum", function () { + const tests = [ + { + targetSum: -5, + numbers: [10, 1, 0], + expected: false, + }, + { + targetSum: -1, + numbers: [], + expected: false, + }, + { + targetSum: 0, + numbers: [3, 7, 0], + expected: true, + }, + { + targetSum: 0, + numbers: [1], + expected: true, + }, + { + targetSum: 0, + numbers: [], + expected: true, + }, + { + targetSum: 55, + numbers: [], + expected: false, + }, + { + targetSum: 12, + numbers: [2, 4, 6, 12], + expected: true, + }, + { + targetSum: 12, + numbers: [1], + expected: true, + }, + { + targetSum: 12, + numbers: [7, 11, 8], + expected: false, + }, + { + targetSum: 300, + numbers: [2, 3, 30, 5, 10], + expected: true, + }, + ]; -test.each(parameters)( - 'canSum($targetSum, $numbers) = $expected', - ({ targetSum, numbers, expected }) => { - expect(canSum(targetSum, numbers)).toBe(expected); - }, -); + tests.forEach(({ targetSum, numbers, expected }) => { + it(`${targetSum} and [${numbers}] should return ${expected}`, function () { + expect(canSum(targetSum, numbers)).equal(expected); + }); + }); +}); diff --git a/src/algorithms/dynamic-programming/sum/how-sum.test.ts b/src/algorithms/dynamic-programming/sum/how-sum.test.ts index fcff337..8f32b85 100644 --- a/src/algorithms/dynamic-programming/sum/how-sum.test.ts +++ b/src/algorithms/dynamic-programming/sum/how-sum.test.ts @@ -1,18 +1,20 @@ -import howSum from './how-sum'; +import { expect } from 'chai'; +import howSum from './how-sum.ts'; -const parameters = [ - { targetSum: 10, numbers: [5, 7, 3, 2, 1], expected: [5, 5] }, - { targetSum: 3, numbers: [1, 3], expected: [1, 1, 1] }, - { targetSum: 3, numbers: [3, 1], expected: [3] }, - { targetSum: 7, numbers: [2, 4, 6], expected: null }, - { targetSum: 0, numbers: [3, 8, 9], expected: [] }, - { targetSum: -1, numbers: [5, 10, 22], expected: null }, - { targetSum: 11, numbers: [], expected: null }, -]; +describe("howSum", function () { + const tests = [ + { targetSum: 10, numbers: [5, 7, 3, 2, 1], expected: [5, 5] }, + { targetSum: 3, numbers: [1, 3], expected: [1, 1, 1] }, + { targetSum: 3, numbers: [3, 1], expected: [3] }, + { targetSum: 7, numbers: [2, 4, 6], expected: null }, + { targetSum: 0, numbers: [3, 8, 9], expected: [] }, + { targetSum: -1, numbers: [5, 10, 22], expected: null }, + { targetSum: 11, numbers: [], expected: null }, + ]; -test.each(parameters)( - 'howSum($targetSum, $numbers) = $expected', - ({ targetSum, numbers, expected }) => { - expect(howSum(targetSum, numbers)).toEqual(expected); - }, -); + tests.forEach(({ targetSum, numbers, expected }) => { + it(`${targetSum} and [${numbers}] should return [${expected}]`, function () { + expect(howSum(targetSum, numbers)).to.deep.equal(expected); + }); + }); +}); diff --git a/src/algorithms/dynamic-programming/sum/shortest-sum.test.ts b/src/algorithms/dynamic-programming/sum/shortest-sum.test.ts index 5ef7b6b..a899e25 100644 --- a/src/algorithms/dynamic-programming/sum/shortest-sum.test.ts +++ b/src/algorithms/dynamic-programming/sum/shortest-sum.test.ts @@ -1,19 +1,21 @@ -import shortestSum from './shortest-sum'; +import { expect } from 'chai'; +import shortestSum from './shortest-sum.ts'; -const parameters = [ - { targetSum: 8, numbers: [2, 3, 5], expected: [5, 3] }, - { targetSum: 10, numbers: [6, 2, 7, 3, 1, 9], expected: [3, 7] }, - { targetSum: 3, numbers: [1, 3], expected: [3] }, - { targetSum: 3, numbers: [3, 1], expected: [3] }, - { targetSum: 7, numbers: [2, 4, 6], expected: null }, - { targetSum: 0, numbers: [3, 8, 9], expected: [] }, - { targetSum: -1, numbers: [5, 10, 22], expected: null }, - { targetSum: 11, numbers: [], expected: null }, -]; +describe("shortestSum", function () { + const tests = [ + { targetSum: 8, numbers: [2, 3, 5], expected: [5, 3] }, + { targetSum: 10, numbers: [6, 2, 7, 3, 1, 9], expected: [3, 7] }, + { targetSum: 3, numbers: [1, 3], expected: [3] }, + { targetSum: 3, numbers: [3, 1], expected: [3] }, + { targetSum: 7, numbers: [2, 4, 6], expected: null }, + { targetSum: 0, numbers: [3, 8, 9], expected: [] }, + { targetSum: -1, numbers: [5, 10, 22], expected: null }, + { targetSum: 11, numbers: [], expected: null }, + ]; -test.each(parameters)( - 'shortestSum($targetSum, $numbers) = $expected', - ({ targetSum, numbers, expected }) => { - expect(shortestSum(targetSum, numbers)).toEqual(expected); - }, -); + tests.forEach(({ targetSum, numbers, expected }) => { + it(`${targetSum} and [${numbers}] should return [${expected}]`, function () { + expect(shortestSum(targetSum, numbers)).to.deep.equal(expected); + }); + }); +}); diff --git a/src/algorithms/matrices.test.ts b/src/algorithms/matrices.test.ts index ccc2eb9..b46f3bb 100644 --- a/src/algorithms/matrices.test.ts +++ b/src/algorithms/matrices.test.ts @@ -1,24 +1,27 @@ -import { sum, sumDiagonal, sumAntiDiagonal, sumFrame } from 'src/algorithms/matrices'; +import { expect } from 'chai'; +import { sum, sumDiagonal, sumAntiDiagonal, sumFrame } from './matrices.js'; -const matrix = [ - [7, 3, 1, 0], - [9, 6, 4, 5], - [1, 9, 5, 4], - [6, 8, 2, 3], -]; +describe("Matrix Operations", function () { + const matrix = [ + [7, 3, 1, 0], + [9, 6, 4, 5], + [1, 9, 5, 4], + [6, 8, 2, 3], + ]; -test('sum', () => { - expect(sum(matrix)).toBe(73); -}); + it('sum', () => { + expect(sum(matrix)).equal(73); + }); -test('sumDiagonal', () => { - expect(sumDiagonal(matrix)).toBe(21); -}); + it('sumDiagonal', () => { + expect(sumDiagonal(matrix)).equal(21); + }); -test('sumAntiDiagonal', () => { - expect(sumAntiDiagonal(matrix)).toBe(19); -}); + it('sumAntiDiagonal', () => { + expect(sumAntiDiagonal(matrix)).equal(19); + }); -test('sumFrame', () => { - expect(sumFrame(matrix)).toBe(49); + it('sumFrame', () => { + expect(sumFrame(matrix)).equal(49); + }); }); diff --git a/src/algorithms/search.test.ts b/src/algorithms/search.test.ts index de774ee..da73784 100644 --- a/src/algorithms/search.test.ts +++ b/src/algorithms/search.test.ts @@ -1,24 +1,27 @@ -import { linearSearch, binarySearch } from 'src/algorithms/search'; +import { expect } from 'chai'; +import { linearSearch, binarySearch } from '@src/algorithms/search.ts'; -const unsortedSequence = [11, 3, 10, 9, 1, 23, 12, 7, 113, 39, 2, 948, 5, 82, 49, 33]; -const sortedSequence = [1, 2, 3, 5, 7, 9, 10, 11, 12, 23, 33, 39, 49, 82, 113, 948]; +describe('Search', () => { + const unsortedSequence = [11, 3, 10, 9, 1, 23, 12, 7, 113, 39, 2, 948, 5, 82, 49, 33]; + const sortedSequence = [1, 2, 3, 5, 7, 9, 10, 11, 12, 23, 33, 39, 49, 82, 113, 948]; -describe('Linear Search', () => { - test('should find 11', () => { - expect(linearSearch(11, unsortedSequence)).toBe(true); - }); + describe('Linear Search', () => { + it('should find 11', () => { + expect(linearSearch(11, unsortedSequence)).equal(true); + }); - test('should not find 0', () => { - expect(linearSearch(0, unsortedSequence)).toBe(false); + it('should not find 0', () => { + expect(linearSearch(0, unsortedSequence)).equal(false); + }); }); -}); -describe('Binary Search', () => { - test('should find 11', () => { - expect(binarySearch(11, sortedSequence)).toBe(true); - }); + describe('Binary Search', () => { + it('should find 11', () => { + expect(binarySearch(11, sortedSequence)).equal(true); + }); - test('should not find 0', () => { - expect(binarySearch(0, sortedSequence)).toBe(false); + it('should not find 0', () => { + expect(binarySearch(0, sortedSequence)).equal(false); + }); }); }); diff --git a/src/algorithms/sorting/merge-sort.test.ts b/src/algorithms/sorting/merge-sort.test.ts index 5ebf6cd..1dd5cbc 100644 --- a/src/algorithms/sorting/merge-sort.test.ts +++ b/src/algorithms/sorting/merge-sort.test.ts @@ -1,49 +1,54 @@ -import mergeSort from 'src/algorithms/sorting/merge-sort'; -import SortingOrder from 'src/util/SortingOrder'; +import { expect } from 'chai'; +import mergeSort from '@src/algorithms/sorting/merge-sort.ts'; +import SortingOrder from '@src/util/SortingOrder.ts'; -const parameters = [ - { - input: null, - sortingOrder: SortingOrder.Ascending, - expected: null, - }, - { - input: [], - sortingOrder: SortingOrder.Ascending, - expected: [], - }, - { - input: [], - sortingOrder: SortingOrder.Descending, - expected: [], - }, - { - input: [3], - sortingOrder: SortingOrder.Ascending, - expected: [3], - }, - { - input: [9], - sortingOrder: SortingOrder.Descending, - expected: [9], - }, - { - input: [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5], - sortingOrder: SortingOrder.Ascending, - expected: [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], - }, - { - input: [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], - sortingOrder: SortingOrder.Descending, - expected: [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5], - }, - { - input: [7, 7, 7, 7, 7, 1], - sortingOrder: SortingOrder.Ascending, - expected: [1, 7, 7, 7, 7, 7], - }, -]; +describe("mergeSort", function () { + const tests = [ + { + input: null, + sortingOrder: SortingOrder.Ascending, + expected: null, + }, + { + input: [], + sortingOrder: SortingOrder.Ascending, + expected: [], + }, + { + input: [], + sortingOrder: SortingOrder.Descending, + expected: [], + }, + { + input: [3], + sortingOrder: SortingOrder.Ascending, + expected: [3], + }, + { + input: [9], + sortingOrder: SortingOrder.Descending, + expected: [9], + }, + { + input: [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5], + sortingOrder: SortingOrder.Ascending, + expected: [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + }, + { + input: [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + sortingOrder: SortingOrder.Descending, + expected: [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5], + }, + { + input: [7, 7, 7, 7, 7, 1], + sortingOrder: SortingOrder.Ascending, + expected: [1, 7, 7, 7, 7, 7], + }, + ]; -test.each(parameters)('mergeSort($input, $sortingOrder)', ({ input, sortingOrder, expected }) => { - expect(mergeSort(input, sortingOrder)).toEqual(expected); + tests.forEach(({ input, sortingOrder, expected }) => { + it(`mergeSort(${JSON.stringify(input)}, ${sortingOrder}) should return ${JSON.stringify(expected)}`, function () { + expect(mergeSort(input, sortingOrder)).to.deep.equal(expected); + }); + }); }); diff --git a/src/algorithms/sorting/merge-sort.ts b/src/algorithms/sorting/merge-sort.ts index 886fdc7..cbd998c 100644 --- a/src/algorithms/sorting/merge-sort.ts +++ b/src/algorithms/sorting/merge-sort.ts @@ -67,7 +67,7 @@ function merge(left: Array, right: Array, order: SortingOrder): * @param input the array of numbers to sort. * @param order specify the order of sorting: ascending or descending. */ -export default function mergeSort(input: Array, order: SortingOrder): Array { +export default function mergeSort(input: Array | null, order: SortingOrder): Array | null { if (!Array.isArray(input) || input.length <= 1) return input; const splitInput: Split = split(input); diff --git a/src/algorithms/tree-traversal.test.ts b/src/algorithms/tree-traversal.test.ts index b116263..16d91ca 100644 --- a/src/algorithms/tree-traversal.test.ts +++ b/src/algorithms/tree-traversal.test.ts @@ -1,3 +1,4 @@ +import { expect } from 'chai'; import { recursivePreOrderTraversal, iterativePreOrderTraversal, @@ -8,8 +9,8 @@ import { recursivePostOrderTraversal, iterativePostOrderTraversal, breadthFirstTraversal, -} from 'src/algorithms/tree-traversal'; -import BinaryTree from 'src/data-structures/BinaryTree'; +} from '@src/algorithms/tree-traversal.ts'; +import BinaryTree from '@src/data-structures/BinaryTree.ts'; /* Given the following rooted tree @@ -28,78 +29,80 @@ import BinaryTree from 'src/data-structures/BinaryTree'; use DFS and BFS to traverse it */ -const preOrder = [1, 2, 4, 3, 5, 7, 8, 6]; -const inOrder = [4, 2, 1, 7, 5, 8, 3, 6]; -const postOrder = [4, 2, 7, 8, 5, 6, 3, 1]; -const bfs = [1, 2, 3, 4, 5, 6, 7, 8]; +describe('Tree Traversal Algorithms', () => { + const preOrder = [1, 2, 4, 3, 5, 7, 8, 6]; + const inOrder = [4, 2, 1, 7, 5, 8, 3, 6]; + const postOrder = [4, 2, 7, 8, 5, 6, 3, 1]; + const bfs = [1, 2, 3, 4, 5, 6, 7, 8]; -const tree: BinaryTree = new BinaryTree(1); + const tree: BinaryTree = new BinaryTree(1); -tree.leftChild = new BinaryTree(2); -tree.rightChild = new BinaryTree(3); + tree.leftChild = new BinaryTree(2); + tree.rightChild = new BinaryTree(3); -tree.leftChild.leftChild = new BinaryTree(4); + tree.leftChild.leftChild = new BinaryTree(4); -tree.rightChild.leftChild = new BinaryTree(5); -tree.rightChild.rightChild = new BinaryTree(6); + tree.rightChild.leftChild = new BinaryTree(5); + tree.rightChild.rightChild = new BinaryTree(6); -tree.rightChild.leftChild.leftChild = new BinaryTree(7); -tree.rightChild.leftChild.rightChild = new BinaryTree(8); + tree.rightChild.leftChild.leftChild = new BinaryTree(7); + tree.rightChild.leftChild.rightChild = new BinaryTree(8); -describe('Depth-first traversal', () => { - describe('Pre-order Traversal', () => { - describe('Recursive Algorithm', () => { - test('recursivePreOrderTraversal', () => { - expect(recursivePreOrderTraversal(tree)).toEqual(preOrder); + describe('Depth-first Approach', () => { + describe('Pre-order Traversal', () => { + describe('Recursive Algorithm', () => { + it('recursivePreOrderTraversal', () => { + expect(recursivePreOrderTraversal(tree)).to.deep.equal(preOrder); + }); }); - }); - describe('Iterative Algorithm', () => { - test('iterativePreOrderTraversal', () => { - expect(iterativePreOrderTraversal(tree)).toEqual(preOrder); - }); + describe('Iterative Algorithm', () => { + it('iterativePreOrderTraversal', () => { + expect(iterativePreOrderTraversal(tree)).to.deep.equal(preOrder); + }); - test('iterativePreOrderTraversalRightChildOnly', () => { - expect(iterativePreOrderTraversalRightChildOnly(tree)).toEqual(preOrder); + it('iterativePreOrderTraversalRightChildOnly', () => { + expect(iterativePreOrderTraversalRightChildOnly(tree)).to.deep.equal(preOrder); + }); }); }); - }); - describe('In-order Traversal', () => { - describe('Recursive Algorithm', () => { - test('recursiveInOrderTraversal', () => { - expect(recursiveInOrderTraversal(tree)).toEqual(inOrder); + describe('In-order Traversal', () => { + describe('Recursive Algorithm', () => { + it('recursiveInOrderTraversal', () => { + expect(recursiveInOrderTraversal(tree)).to.deep.equal(inOrder); + }); }); - }); - describe('Iterative Algorithm', () => { - test('iterativeInOrderTraversal', () => { - expect(iterativeInOrderTraversal(tree)).toEqual(inOrder); - }); + describe('Iterative Algorithm', () => { + it('iterativeInOrderTraversal', () => { + expect(iterativeInOrderTraversal(tree)).to.deep.equal(inOrder); + }); - test('iterativeInOrderTraversalWithDoubleWhile', () => { - expect(iterativeInOrderTraversalWithDoubleWhile(tree)).toEqual(inOrder); + it('iterativeInOrderTraversalWithDoubleWhile', () => { + expect(iterativeInOrderTraversalWithDoubleWhile(tree)).to.deep.equal(inOrder); + }); }); }); - }); - describe('Post-order Traversal', () => { - describe('Recursive Algorithm', () => { - test('recursivePostOrderTraversal', () => { - expect(recursivePostOrderTraversal(tree)).toEqual(postOrder); + describe('Post-order Traversal', () => { + describe('Recursive Algorithm', () => { + it('recursivePostOrderTraversal', () => { + expect(recursivePostOrderTraversal(tree)).to.deep.equal(postOrder); + }); }); - }); - describe('Iterative Algorithm', () => { - test('iterativePostOrderTraversal', () => { - expect(iterativePostOrderTraversal(tree)).toEqual(postOrder); + describe('Iterative Algorithm', () => { + it('iterativePostOrderTraversal', () => { + expect(iterativePostOrderTraversal(tree)).to.deep.equal(postOrder); + }); }); }); }); -}); -describe('Breadth-first traversal', () => { - test('breadthFirstTraversal', () => { - expect(breadthFirstTraversal(tree)).toEqual(bfs); + describe('Breadth-first traversal', () => { + it('breadthFirstTraversal', () => { + expect(breadthFirstTraversal(tree)).to.deep.equal(bfs); + }); }); }); diff --git a/src/exercises/cache/cache.test.ts b/src/exercises/cache/cache.test.ts deleted file mode 100644 index 0b180eb..0000000 --- a/src/exercises/cache/cache.test.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { TimeLimitedCache } from 'src/exercises/cache'; - -async function sleep(time) { - return new Promise((r) => setTimeout(r, time)); -} - -test('Test 1', async () => { - const timeLimitedCache = new TimeLimitedCache(); - - const duration = 1000; - - expect(timeLimitedCache.set(1, 42, duration)).toBe(false); - expect(timeLimitedCache.get(1)).toBe(42); - expect(timeLimitedCache.count()).toBe(1); - - await sleep(duration); - - expect(timeLimitedCache.count()).toBe(0); -}); - -test('Test 2', async () => { - const timeLimitedCache = new TimeLimitedCache(); - - expect(timeLimitedCache.set(1, 42, 1000)).toBe(false); - expect(timeLimitedCache.set(1, 100, 2000)).toBe(true); - expect(timeLimitedCache.get(1)).toBe(100); -}); - -test('Test 3', async () => { - const timeLimitedCache = new TimeLimitedCache(); - - const duration = 500; - - expect(timeLimitedCache.set(1, 42, duration)).toBe(false); - expect(timeLimitedCache.set(2, 100, duration)).toBe(false); - - await sleep(duration + 200); - - expect(timeLimitedCache.count()).toBe(0); -}); - -test('Test 4', async () => { - const timeLimitedCache = new TimeLimitedCache(); - - expect(timeLimitedCache.set(1, 42, 1000)).toBe(false); - expect(timeLimitedCache.set(2, 100, 1000)).toBe(false); - expect(timeLimitedCache.set(3, 100, 1000)).toBe(false); - expect(timeLimitedCache.count()).toBe(3); -}); - -test('Test 5', async () => { - const timeLimitedCache = new TimeLimitedCache(); - - expect(timeLimitedCache.count()).toBe(0); -}); - -test('Test 6', async () => { - const timeLimitedCache = new TimeLimitedCache(); - - expect(timeLimitedCache.get(1)).toBe(-1); -}); diff --git a/src/exercises/cache/index.ts b/src/exercises/cache/index.ts deleted file mode 100644 index 3841fed..0000000 --- a/src/exercises/cache/index.ts +++ /dev/null @@ -1,54 +0,0 @@ -interface Cache { - value: number; - duration: number; - startTime: number; -} - -export class TimeLimitedCache { - private map: Map; - - constructor() { - this.map = new Map(); - } - - private isUnexpired(cache: Cache) { - const endTime = performance.now(); - - if (cache && endTime - cache.startTime < cache.duration) { - return true; - } - - return false; - } - - set(key: number, value: number, duration: number): boolean { - const cache = this.map.get(key); - - const startTime = performance.now(); - this.map.set(key, { value, duration, startTime }); - - return this.isUnexpired(cache); - } - - get(key: number): number { - const cache = this.map.get(key); - - if (this.isUnexpired(cache)) { - return cache.value; - } - - return -1; - } - - count(): number { - let counter = 0; - - for (const cache of this.map.values()) { - if (this.isUnexpired(cache)) { - counter++; - } - } - - return counter; - } -} diff --git a/src/exercises/majority-elements/index.test.ts b/src/exercises/majority-elements/index.test.ts index e4e634a..f62f3c7 100644 --- a/src/exercises/majority-elements/index.test.ts +++ b/src/exercises/majority-elements/index.test.ts @@ -1,5 +1,24 @@ -import { majority } from '.'; +import { expect } from 'chai'; +import { majority } from '@src/exercises/majority-elements/index.ts'; -test('majority()', () => { - expect(majority([1, 2, 2, 2, 3])).toBe(2); +describe('Majority Elements Exercise', () => { + it('majority()', () => { + expect(majority([1, 2, 2, 2, 3])).equal(2); + }); + + it('majority() with empty array', () => { + expect(majority([])).to.be.undefined; + }); + + it('majority() with no majority element', () => { + expect(majority([1, 2, 3, 4])).to.be.undefined; + }); + + it('majority() with single element', () => { + expect(majority([1])).equal(1); + }); + + it('majority() with all same elements', () => { + expect(majority([2, 2, 2, 2])).equal(2); + }); }); diff --git a/src/exercises/palindrome/index.test.ts b/src/exercises/palindrome/index.test.ts index abdf8e5..774773d 100644 --- a/src/exercises/palindrome/index.test.ts +++ b/src/exercises/palindrome/index.test.ts @@ -1,32 +1,37 @@ -import { isPalindrome } from 'src/exercises/palindrome'; +import { expect } from 'chai'; +import { isPalindrome } from '@src/exercises/palindrome/index.ts'; -const parameters = [ - { - input: '', - output: true, - }, - { - input: 'a', - output: true, - }, - { - input: 'aa', - output: true, - }, - { - input: 'ab', - output: false, - }, - { - input: 'aba', - output: true, - }, - { - input: 'abc', - output: false, - }, -]; +describe('Palindrome Exercise', () => { + const tests = [ + { + input: '', + output: true, + }, + { + input: 'a', + output: true, + }, + { + input: 'aa', + output: true, + }, + { + input: 'ab', + output: false, + }, + { + input: 'aba', + output: true, + }, + { + input: 'abc', + output: false, + }, + ]; -test.each(parameters)('isPalindrome', ({ input, output }) => { - expect(isPalindrome(input)).toBe(output); + tests.forEach(({ input, output }) => { + it(`isPalindrome("${input}") should return ${output}`, () => { + expect(isPalindrome(input)).to.equal(output); + }); + }); }); diff --git a/src/exercises/rotational-cipher/index.test.ts b/src/exercises/rotational-cipher/index.test.ts index bc090fd..c89062d 100644 --- a/src/exercises/rotational-cipher/index.test.ts +++ b/src/exercises/rotational-cipher/index.test.ts @@ -1,19 +1,23 @@ -import { rotationalCipher } from '.'; +import { expect } from 'chai'; +import { rotationalCipher } from '@src/exercises/rotational-cipher/index.ts'; -const parameters = [ - { - input: 'All-convoYs-9-be:Alert1.', - rotationFactor: 4, - expected: 'Epp-gsrzsCw-3-fi:Epivx5.', - }, - { - input: 'abcdZXYzxy-999.@', - rotationFactor: 200, - expected: 'stuvRPQrpq-999.@', - }, -]; +describe('Rotational Cipher Exercise', () => { + const tests = [ + { + input: 'All-convoYs-9-be:Alert1.', + rotationFactor: 4, + expected: 'Epp-gsrzsCw-3-fi:Epivx5.', + }, + { + input: 'abcdZXYzxy-999.@', + rotationFactor: 200, + expected: 'stuvRPQrpq-999.@', + }, + ]; -test.each(parameters)('rotationalCipher("$input", $rotationFactor)', (props) => { - const { input, rotationFactor, expected } = props; - expect(rotationalCipher(input, rotationFactor)).toBe(expected); + tests.forEach(({ input, rotationFactor, expected }) => { + it(`rotationalCipher("${input}", ${rotationFactor}) should return "${expected}"`, () => { + expect(rotationalCipher(input, rotationFactor)).to.equal(expected); + }); + }); }); diff --git a/src/exercises/sliding-window-maximum/index.test.ts b/src/exercises/sliding-window-maximum/index.test.ts index fbb331a..16d82db 100644 --- a/src/exercises/sliding-window-maximum/index.test.ts +++ b/src/exercises/sliding-window-maximum/index.test.ts @@ -1,38 +1,43 @@ +import { expect } from 'chai'; import { maxSlidingWindow } from '.'; -const params = [ - { - nums: [1, 3, -1, -3, 5, 3, 6, 7], - k: 3, - expected: [3, 3, 5, 5, 6, 7], - }, - { - nums: [-10], - k: 1, - expected: [-10], - }, - { - nums: [7, 11], - k: 5, - expected: [11], - }, - { - nums: [ - 1, 3, -1, -3, 5, 3, 6, 7, -7, 11, 20, -73, 83, 234, -44, -1, 0, -111, 428, 6, 85, 70, 91, 77, - 1, 96, 62, 36, 59, 36, 12, 45, 74, 13, 85, 79, 49, 2, 12, 15, 25, 62, 41, 76, 89, 46, 55, 85, - 22, 25, 56, 51, 67, 6, 42, 33, 65, 58, 92, 5, 90, 5, 51, 81, 12, 81, 32, 75, 17, 21, -33, 54, - -82, 57, 36, 86, 60, 51, 97, 3, 21, 41, 45, 34, 33, 20, 64, 77, 66, 25, 9, - ], - k: 8, - expected: [ - 7, 7, 11, 20, 20, 83, 234, 234, 234, 234, 234, 428, 428, 428, 428, 428, 428, 428, 428, 96, 96, - 96, 96, 96, 96, 96, 74, 85, 85, 85, 85, 85, 85, 85, 85, 79, 76, 89, 89, 89, 89, 89, 89, 89, - 89, 85, 85, 85, 67, 67, 67, 92, 92, 92, 92, 92, 92, 92, 92, 90, 90, 81, 81, 81, 81, 81, 75, - 75, 86, 86, 86, 97, 97, 97, 97, 97, 97, 97, 97, 64, 77, 77, 77, 77, - ], - }, -]; +describe('Sliding Window Maximum Exercise', () => { + const tests = [ + { + nums: [1, 3, -1, -3, 5, 3, 6, 7], + k: 3, + expected: [3, 3, 5, 5, 6, 7], + }, + { + nums: [-10], + k: 1, + expected: [-10], + }, + { + nums: [7, 11], + k: 5, + expected: [11], + }, + { + nums: [ + 1, 3, -1, -3, 5, 3, 6, 7, -7, 11, 20, -73, 83, 234, -44, -1, 0, -111, 428, 6, 85, 70, 91, 77, + 1, 96, 62, 36, 59, 36, 12, 45, 74, 13, 85, 79, 49, 2, 12, 15, 25, 62, 41, 76, 89, 46, 55, 85, + 22, 25, 56, 51, 67, 6, 42, 33, 65, 58, 92, 5, 90, 5, 51, 81, 12, 81, 32, 75, 17, 21, -33, 54, + -82, 57, 36, 86, 60, 51, 97, 3, 21, 41, 45, 34, 33, 20, 64, 77, 66, 25, 9, + ], + k: 8, + expected: [ + 7, 7, 11, 20, 20, 83, 234, 234, 234, 234, 234, 428, 428, 428, 428, 428, 428, 428, 428, 96, 96, + 96, 96, 96, 96, 96, 74, 85, 85, 85, 85, 85, 85, 85, 85, 79, 76, 89, 89, 89, 89, 89, 89, 89, + 89, 85, 85, 85, 67, 67, 67, 92, 92, 92, 92, 92, 92, 92, 92, 90, 90, 81, 81, 81, 81, 81, 75, + 75, 86, 86, 86, 97, 97, 97, 97, 97, 97, 97, 97, 64, 77, 77, 77, 77, + ], + }, + ]; -test.each(params)('maxSlidingWindow($nums, $k) => $expected', ({ nums, k, expected }) => { - expect(maxSlidingWindow(nums, k)).toEqual(expected); + tests.forEach(({ nums, k, expected }) => { + it(`maxSlidingWindow(${JSON.stringify(nums)}, ${k}) should return ${JSON.stringify(expected)}`, () => { + expect(maxSlidingWindow(nums, k)).to.deep.equal(expected); + }); + }); }); diff --git a/src/exercises/uniform-integers/index.test.ts b/src/exercises/uniform-integers/index.test.ts index c70e68e..28a76d6 100644 --- a/src/exercises/uniform-integers/index.test.ts +++ b/src/exercises/uniform-integers/index.test.ts @@ -1,82 +1,84 @@ -import { getUniformIntegerCountInInterval } from '.'; +import { expect } from 'chai'; +import { getUniformIntegerCountInInterval } from '@src/exercises/uniform-integers/index.ts'; -const parameters = [ - { - start: 75, - end: 300, - expected: 5, - }, - { - start: 11, - end: 99, - expected: 9, - }, - { - start: 999999999999, - end: 999999999999, - expected: 1, - }, - { - start: 2, - end: 8, - expected: 7, - }, - { - start: 7, - end: 11, - expected: 4, - }, - { - start: 2, - end: 2, - expected: 1, - }, - { - start: 10, - end: 11, - expected: 1, - }, - { - start: 55, - end: 11, - expected: 0, - }, - { - start: 99, - end: 459, - expected: 5, - }, - { - start: 79, - end: 311, - expected: 4, - }, - { - start: 0, - end: 1, - expected: 0, - }, - { - start: -3, - end: 0, - expected: 0, - }, - { - start: 3.2, - end: 11, - isException: true, - }, -]; +describe('Uniform Integers Exercise', () => { + const tests = [ + { + start: 75, + end: 300, + expected: 5, + }, + { + start: 11, + end: 99, + expected: 9, + }, + { + start: 999999999999, + end: 999999999999, + expected: 1, + }, + { + start: 2, + end: 8, + expected: 7, + }, + { + start: 7, + end: 11, + expected: 4, + }, + { + start: 2, + end: 2, + expected: 1, + }, + { + start: 10, + end: 11, + expected: 1, + }, + { + start: 55, + end: 11, + expected: 0, + }, + { + start: 99, + end: 459, + expected: 5, + }, + { + start: 79, + end: 311, + expected: 4, + }, + { + start: 0, + end: 1, + expected: 0, + }, + { + start: -3, + end: 0, + expected: 0, + }, + { + start: 3.2, + end: 11, + isException: true, + }, + ]; -test.each(parameters)( - 'rotationalCipher("$start", $end) => $expected', - ({ start, end, isException, expected }) => { - if (isException) { - expect(() => getUniformIntegerCountInInterval(start, end)).toThrow( - 'The two numbers in input must be integers', - ); - } else { - expect(getUniformIntegerCountInInterval(start, end)).toBe(expected); - } - }, -); + tests.forEach(({ start, end, expected, isException }) => { + it(`getUniformIntegerCountInInterval(${start}, ${end}) should return ${expected}`, () => { + if (isException) { + expect(() => getUniformIntegerCountInInterval(start, end)).to.throw( + 'The two numbers in input must be integers', + ); + } else { + expect(getUniformIntegerCountInInterval(start, end)).to.equal(expected); + } + }); + }); +}); diff --git a/src/exercises/valid-binary-search-tree/index.test.ts b/src/exercises/valid-binary-search-tree/index.test.ts index 5fbf090..ff003f3 100644 --- a/src/exercises/valid-binary-search-tree/index.test.ts +++ b/src/exercises/valid-binary-search-tree/index.test.ts @@ -1,23 +1,28 @@ -import { isValidBST } from 'src/exercises/valid-binary-search-tree'; -import BinaryTree from 'src/data-structures/BinaryTree'; +import { expect } from 'chai'; +import { isValidBST } from '@src/exercises/valid-binary-search-tree/index.ts'; +import BinaryTree from '@src/data-structures/BinaryTree.ts'; -const root1 = new BinaryTree(4); -root1.leftChild = new BinaryTree(2); -root1.rightChild = new BinaryTree(5); -root1.leftChild.leftChild = new BinaryTree(1); -root1.leftChild.rightChild = new BinaryTree(3); +describe('Valid Binary Search Tree Exercise', () => { + const root1 = new BinaryTree(4); + root1.leftChild = new BinaryTree(2); + root1.rightChild = new BinaryTree(5); + root1.leftChild.leftChild = new BinaryTree(1); + root1.leftChild.rightChild = new BinaryTree(3); -const parameters = [ - { - tree: null, - expected: true, - }, - { - tree: root1, - expected: true, - }, -]; + const tests = [ + { + tree: null, + expected: true, + }, + { + tree: root1, + expected: true, + }, + ]; -test.each(parameters)('isValidBST', ({ tree, expected }) => { - expect(isValidBST(tree)).toBe(expected); + tests.forEach(({ tree, expected }) => { + it(`isValidBST(${JSON.stringify(tree)}) should return ${expected}`, () => { + expect(isValidBST(tree)).to.equal(expected); + }); + }); }); diff --git a/tsconfig.json b/tsconfig.json index c6869be..13281fe 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,18 +2,16 @@ "compilerOptions": { "module": "nodenext", "target": "es2022", - "outDir": "dist", + "paths": { + "@src/*": ["./src/*"] + }, "strict": true, "esModuleInterop": true, "skipLibCheck": true, - "moduleResolution": "node16" + "moduleResolution": "nodenext", + "allowImportingTsExtensions": true, + "noEmit": true }, - "include": [ - "src/**/*", - "tests/**/*" - ], - "exclude": [ - "node_modules", - "dist" - ] + "include": ["src/**/*.ts"], + "exclude": [".nyc_output", "coverage", "node_modules"] }