removed jest

This commit is contained in:
Bojan Kucera 2025-06-04 12:48:09 -04:00
parent fb22815450
commit 68592619f9
7 changed files with 242 additions and 203 deletions

View file

@ -7,23 +7,37 @@
"valibot": "^1.1.0",
},
"devDependencies": {
"@jest/globals": "^29.7.0",
"@testcontainers/mongodb": "^10.7.2",
"@testcontainers/postgresql": "^10.7.2",
"@types/jest": "^29.5.12",
"@types/node": "^20.12.12",
"@types/supertest": "^6.0.2",
"jest": "^29.7.0",
"jest-extended": "^4.0.2",
"jest-mock-extended": "^3.0.5",
"bun-types": "^1.2.15",
"mongodb-memory-server": "^9.1.6",
"pg-mem": "^2.8.1",
"supertest": "^6.3.4",
"ts-jest": "^29.1.2",
"turbo": "^2.5.4",
"typescript": "^5.4.5",
},
},
"apps/integration-services/ib-websocket-gateway": {
"name": "@stock-bot/ib-websocket-gateway",
"version": "1.0.0",
"dependencies": {
"@hono/node-server": "^1.12.2",
"@stock-bot/logger": "workspace:*",
"eventemitter3": "^5.0.1",
"hono": "^4.6.8",
"uuid": "^10.0.0",
"ws": "^8.18.0",
},
"devDependencies": {
"@types/node": "^20.12.12",
"@types/uuid": "^10.0.0",
"@types/ws": "^8.5.12",
"tsx": "^4.19.1",
"typescript": "^5.4.5",
},
},
"apps/interface-services/trading-dashboard": {
"name": "trading-dashboard",
"version": "0.0.0",
@ -397,6 +411,8 @@
"@grpc/proto-loader": ["@grpc/proto-loader@0.7.15", "", { "dependencies": { "lodash.camelcase": "^4.3.0", "long": "^5.0.0", "protobufjs": "^7.2.5", "yargs": "^17.7.2" }, "bin": { "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" } }, "sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ=="],
"@hono/node-server": ["@hono/node-server@1.14.3", "", { "peerDependencies": { "hono": "^4" } }, "sha512-KuDMwwghtFYSmIpr4WrKs1VpelTrptvJ+6x6mbUcZnFcc213cumTF5BdqfHyW93B19TNI4Vaev14vOI2a0Ie3w=="],
"@humanwhocodes/config-array": ["@humanwhocodes/config-array@0.13.0", "", { "dependencies": { "@humanwhocodes/object-schema": "^2.0.3", "debug": "^4.3.1", "minimatch": "^3.0.5" } }, "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw=="],
"@humanwhocodes/module-importer": ["@humanwhocodes/module-importer@1.0.1", "", {}, "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="],
@ -695,6 +711,8 @@
"@stock-bot/http-client": ["@stock-bot/http-client@workspace:libs/http-client"],
"@stock-bot/ib-websocket-gateway": ["@stock-bot/ib-websocket-gateway@workspace:apps/integration-services/ib-websocket-gateway"],
"@stock-bot/logger": ["@stock-bot/logger@workspace:libs/logger"],
"@stock-bot/mongodb-client": ["@stock-bot/mongodb-client@workspace:libs/mongodb-client"],
@ -795,10 +813,14 @@
"@types/supertest": ["@types/supertest@6.0.3", "", { "dependencies": { "@types/methods": "^1.1.4", "@types/superagent": "^8.1.0" } }, "sha512-8WzXq62EXFhJ7QsH3Ocb/iKQ/Ty9ZVWnVzoTKc9tyyFRRF3a74Tk2+TLFgaFFw364Ere+npzHKEJ6ga2LzIL7w=="],
"@types/uuid": ["@types/uuid@10.0.0", "", {}, "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ=="],
"@types/webidl-conversions": ["@types/webidl-conversions@7.0.3", "", {}, "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA=="],
"@types/whatwg-url": ["@types/whatwg-url@11.0.5", "", { "dependencies": { "@types/webidl-conversions": "*" } }, "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ=="],
"@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="],
"@types/yargs": ["@types/yargs@17.0.33", "", { "dependencies": { "@types/yargs-parser": "*" } }, "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA=="],
"@types/yargs-parser": ["@types/yargs-parser@21.0.3", "", {}, "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ=="],
@ -1263,6 +1285,8 @@
"get-stream": ["get-stream@6.0.1", "", {}, "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg=="],
"get-tsconfig": ["get-tsconfig@4.10.1", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ=="],
"glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="],
"glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
@ -1291,6 +1315,8 @@
"help-me": ["help-me@5.0.0", "", {}, "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg=="],
"hono": ["hono@4.7.11", "", {}, "sha512-rv0JMwC0KALbbmwJDEnxvQCeJh+xbS3KEWW5PC9cMJ08Ur9xgatI0HmtgYZfOdOSOeYsp5LO2cOhdI8cLEbDEQ=="],
"hosted-git-info": ["hosted-git-info@8.1.0", "", { "dependencies": { "lru-cache": "^10.0.1" } }, "sha512-Rw/B2DNQaPBICNXEm8balFz9a6WpZrkCGpcWFpy7nCj+NyhSdqXipmfvtmWt9xGfp0wZnBxB+iVpLmQMYt47Tw=="],
"html-escaper": ["html-escaper@2.0.2", "", {}, "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg=="],
@ -1401,8 +1427,6 @@
"jest-environment-node": ["jest-environment-node@29.7.0", "", { "dependencies": { "@jest/environment": "^29.7.0", "@jest/fake-timers": "^29.7.0", "@jest/types": "^29.6.3", "@types/node": "*", "jest-mock": "^29.7.0", "jest-util": "^29.7.0" } }, "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw=="],
"jest-extended": ["jest-extended@4.0.2", "", { "dependencies": { "jest-diff": "^29.0.0", "jest-get-type": "^29.0.0" }, "peerDependencies": { "jest": ">=27.2.5" }, "optionalPeers": ["jest"] }, "sha512-FH7aaPgtGYHc9mRjriS0ZEHYM5/W69tLrFTIdzm+yJgeoCmmrSB/luSfMSqWP9O29QWHPEmJ4qmU6EwsZideog=="],
"jest-get-type": ["jest-get-type@29.6.3", "", {}, "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw=="],
"jest-haste-map": ["jest-haste-map@29.7.0", "", { "dependencies": { "@jest/types": "^29.6.3", "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "graceful-fs": "^4.2.9", "jest-regex-util": "^29.6.3", "jest-util": "^29.7.0", "jest-worker": "^29.7.0", "micromatch": "^4.0.4", "walker": "^1.0.8" }, "optionalDependencies": { "fsevents": "^2.3.2" } }, "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA=="],
@ -1415,8 +1439,6 @@
"jest-mock": ["jest-mock@29.7.0", "", { "dependencies": { "@jest/types": "^29.6.3", "@types/node": "*", "jest-util": "^29.7.0" } }, "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw=="],
"jest-mock-extended": ["jest-mock-extended@3.0.7", "", { "dependencies": { "ts-essentials": "^10.0.0" }, "peerDependencies": { "jest": "^24.0.0 || ^25.0.0 || ^26.0.0 || ^27.0.0 || ^28.0.0 || ^29.0.0", "typescript": "^3.0.0 || ^4.0.0 || ^5.0.0" } }, "sha512-7lsKdLFcW9B9l5NzZ66S/yTQ9k8rFtnwYdCNuRU/81fqDWicNDVhitTSPnrGmNeNm0xyw0JHexEOShrIKRCIRQ=="],
"jest-pnp-resolver": ["jest-pnp-resolver@1.2.3", "", { "peerDependencies": { "jest-resolve": "*" }, "optionalPeers": ["jest-resolve"] }, "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w=="],
"jest-regex-util": ["jest-regex-util@29.6.3", "", {}, "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg=="],
@ -1857,6 +1879,8 @@
"resolve-from": ["resolve-from@5.0.0", "", {}, "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw=="],
"resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="],
"resolve.exports": ["resolve.exports@2.0.3", "", {}, "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A=="],
"restore-cursor": ["restore-cursor@5.1.0", "", { "dependencies": { "onetime": "^7.0.0", "signal-exit": "^4.1.0" } }, "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA=="],
@ -2033,12 +2057,12 @@
"ts-api-utils": ["ts-api-utils@1.4.3", "", { "peerDependencies": { "typescript": ">=4.2.0" } }, "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw=="],
"ts-essentials": ["ts-essentials@10.0.4", "", { "peerDependencies": { "typescript": ">=4.5.0" }, "optionalPeers": ["typescript"] }, "sha512-lwYdz28+S4nicm+jFi6V58LaAIpxzhg9rLdgNC1VsdP/xiFBseGhF1M/shwCk6zMmwahBZdXcl34LVHrEang3A=="],
"ts-jest": ["ts-jest@29.3.4", "", { "dependencies": { "bs-logger": "^0.2.6", "ejs": "^3.1.10", "fast-json-stable-stringify": "^2.1.0", "jest-util": "^29.0.0", "json5": "^2.2.3", "lodash.memoize": "^4.1.2", "make-error": "^1.3.6", "semver": "^7.7.2", "type-fest": "^4.41.0", "yargs-parser": "^21.1.1" }, "peerDependencies": { "@babel/core": ">=7.0.0-beta.0 <8", "@jest/transform": "^29.0.0", "@jest/types": "^29.0.0", "babel-jest": "^29.0.0", "jest": "^29.0.0", "typescript": ">=4.3 <6" }, "optionalPeers": ["@babel/core", "@jest/transform", "@jest/types", "babel-jest"], "bin": { "ts-jest": "cli.js" } }, "sha512-Iqbrm8IXOmV+ggWHOTEbjwyCf2xZlUMv5npExksXohL+tk8va4Fjhb+X2+Rt9NBmgO7bJ8WpnMLOwih/DnMlFA=="],
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
"tsx": ["tsx@4.19.4", "", { "dependencies": { "esbuild": "~0.25.0", "get-tsconfig": "^4.7.5" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "bin": { "tsx": "dist/cli.mjs" } }, "sha512-gK5GVzDkJK1SI1zwHf32Mqxf2tSJkNx+eYcNly5+nHvWqXUJYUkWBQtKauoESz3ymezAI++ZwT855x5p5eop+Q=="],
"tuf-js": ["tuf-js@3.0.1", "", { "dependencies": { "@tufjs/models": "3.0.1", "debug": "^4.3.6", "make-fetch-happen": "^14.0.1" } }, "sha512-+68OP1ZzSF84rTckf3FA95vJ1Zlx/uaXyiiKyPd1pA4rZNkpEvDAKmsu1xUSmbF/chCRYgZ6UZkDwC7PmzmAyA=="],
"turbo": ["turbo@2.5.4", "", { "optionalDependencies": { "turbo-darwin-64": "2.5.4", "turbo-darwin-arm64": "2.5.4", "turbo-linux-64": "2.5.4", "turbo-linux-arm64": "2.5.4", "turbo-windows-64": "2.5.4", "turbo-windows-arm64": "2.5.4" }, "bin": { "turbo": "bin/turbo" } }, "sha512-kc8ZibdRcuWUG1pbYSBFWqmIjynlD8Lp7IB6U3vIzvOv9VG+6Sp8bzyeBWE3Oi8XV5KsQrznyRTBPvrf99E4mA=="],
@ -2127,7 +2151,7 @@
"write-file-atomic": ["write-file-atomic@4.0.2", "", { "dependencies": { "imurmurhash": "^0.1.4", "signal-exit": "^3.0.7" } }, "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg=="],
"ws": ["ws@8.17.1", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ=="],
"ws": ["ws@8.18.2", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ=="],
"xtend": ["xtend@4.0.2", "", {}, "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="],
@ -2267,6 +2291,8 @@
"engine.io/debug": ["debug@4.3.7", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ=="],
"engine.io/ws": ["ws@8.17.1", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ=="],
"ent/punycode": ["punycode@1.4.1", "", {}, "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ=="],
"envalid/tslib": ["tslib@2.6.2", "", {}, "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="],
@ -2369,6 +2395,8 @@
"socket.io-adapter/debug": ["debug@4.3.7", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ=="],
"socket.io-adapter/ws": ["ws@8.17.1", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ=="],
"socket.io-parser/debug": ["debug@4.3.7", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ=="],
"ssh-remote-port-forward/@types/ssh2": ["@types/ssh2@0.5.52", "", { "dependencies": { "@types/node": "*", "@types/ssh2-streams": "*" } }, "sha512-lbLLlXxdCZOSJMCInKH2+9V/77ET2J6NPQHpFI0kda61Dd1KglJs+fPQBchizmzYSOJBgdTajhPqBO1xxLywvg=="],

20
bunfig.toml Normal file
View file

@ -0,0 +1,20 @@
# Root bunfig.toml for Stock Bot Trading Platform
# Configures Bun for the entire monorepo workspace
[test]
# Configure coverage and test behavior
coverage = true
timeout = "30s"
# Configure test environment
preload = ["./test/setup.ts"]
# Environment variables for tests
[test.env]
NODE_ENV = "test"
# Module path resolution
[bun]
paths = {
"@stock-bot/*" = ["./libs/*/src"]
}

View file

@ -1,159 +0,0 @@
/**
* Jest Setup File for Stock Bot Trading Platform
*
* Global test configuration and utilities available across all tests.
* This file is executed before each test file runs.
*/
import 'jest-extended';
// Increase test timeout for integration tests
jest.setTimeout(30000);
// Mock console methods to reduce noise during tests
// but allow them to be restored if needed
const originalConsole = global.console;
global.console = {
...originalConsole,
log: jest.fn(),
debug: jest.fn(),
info: jest.fn(),
warn: jest.fn(),
error: jest.fn(),
};
// Global test utilities available in all test files
declare global {
var testHelpers: {
sleep: (ms: number) => Promise<void>;
mockTimestamp: () => Date;
generateTestOHLCV: (symbol?: string, overrides?: any) => any;
generateTestTrade: (symbol?: string, overrides?: any) => any;
generateTestQuote: (symbol?: string, overrides?: any) => any;
mockLogger: () => any;
restoreConsole: () => void;
};
}
global.testHelpers = {
/**
* Sleep utility for async tests
*/
sleep: (ms: number) => new Promise(resolve => setTimeout(resolve, ms)),
/**
* Consistent mock timestamp for tests
*/
mockTimestamp: () => new Date('2024-01-01T12:00:00Z'),
/**
* Generate test OHLCV data
*/
generateTestOHLCV: (symbol: string = 'AAPL', overrides: any = {}) => ({
symbol,
timestamp: new Date('2024-01-01T12:00:00Z'),
open: 150.00,
high: 152.00,
low: 149.50,
close: 151.50,
volume: 1000000,
source: 'test',
...overrides
}),
/**
* Generate test trade data
*/
generateTestTrade: (symbol: string = 'AAPL', overrides: any = {}) => ({
symbol,
timestamp: new Date('2024-01-01T12:00:00Z'),
price: 151.50,
quantity: 100,
side: 'buy',
trade_id: 'test_trade_1',
source: 'test',
...overrides
}),
/**
* Generate test quote data
*/
generateTestQuote: (symbol: string = 'AAPL', overrides: any = {}) => ({
symbol,
timestamp: new Date('2024-01-01T12:00:00Z'),
bid_price: 151.49,
ask_price: 151.51,
bid_size: 100,
ask_size: 200,
source: 'test',
...overrides
}),
/**
* Create a mock logger
*/
mockLogger: () => ({
info: jest.fn(),
error: jest.fn(),
warn: jest.fn(),
debug: jest.fn(),
trace: jest.fn()
}),
/**
* Restore original console methods
*/
restoreConsole: () => {
global.console = originalConsole;
}
};
// Environment setup for tests
process.env.NODE_ENV = 'test';
process.env.LOG_LEVEL = 'error';
// Set default test environment variables
process.env.QUESTDB_HOST = process.env.QUESTDB_HOST || 'localhost';
process.env.QUESTDB_HTTP_PORT = process.env.QUESTDB_HTTP_PORT || '9000';
process.env.QUESTDB_PG_PORT = process.env.QUESTDB_PG_PORT || '8812';
process.env.QUESTDB_INFLUX_PORT = process.env.QUESTDB_INFLUX_PORT || '9009';
process.env.POSTGRES_HOST = process.env.POSTGRES_HOST || 'localhost';
process.env.POSTGRES_PORT = process.env.POSTGRES_PORT || '5432';
process.env.POSTGRES_DB = process.env.POSTGRES_DB || 'trading_bot_test';
process.env.POSTGRES_USER = process.env.POSTGRES_USER || 'trading_admin';
process.env.POSTGRES_PASSWORD = process.env.POSTGRES_PASSWORD || 'trading_pass_test';
process.env.MONGODB_HOST = process.env.MONGODB_HOST || 'localhost';
process.env.MONGODB_PORT = process.env.MONGODB_PORT || '27017';
process.env.MONGODB_DATABASE = process.env.MONGODB_DATABASE || 'trading_bot_test';
process.env.MONGODB_USERNAME = process.env.MONGODB_USERNAME || 'trading_admin';
process.env.MONGODB_PASSWORD = process.env.MONGODB_PASSWORD || 'trading_mongo_test';
// Mock Date.now() for consistent test results
const mockNow = new Date('2024-01-01T12:00:00Z').getTime();
jest.spyOn(Date, 'now').mockReturnValue(mockNow);
// Global test cleanup
beforeEach(() => {
// Clear all mocks before each test
jest.clearAllMocks();
});
afterEach(() => {
// Reset any module mocks after each test
jest.resetModules();
});
// Handle unhandled promise rejections in tests
process.on('unhandledRejection', (reason, promise) => {
console.error('Unhandled Rejection at:', promise, 'reason:', reason);
throw reason;
});
// Handle uncaught exceptions in tests
process.on('uncaughtException', (error) => {
console.error('Uncaught Exception:', error);
throw error;
});

View file

@ -0,0 +1,14 @@
# QuestDB Client Library Bun Test Configuration
[test]
# Configure path mapping for tests
preload = ["./test/setup.ts"]
# Test configuration
timeout = 5000
# Enable TypeScript paths resolution
[bun]
paths = {
"@/*" = ["./src/*"]
}

View file

@ -45,7 +45,8 @@ beforeAll(() => {
return result;
}
}); // Mock QuestDB HTTP client
(global as any).fetch = jest.fn();
(global as any).fetch = () => {}; // Using Bun's built-in spyOn utilities
global.spyOn(global, 'fetch');
});
beforeEach(() => {
@ -63,7 +64,7 @@ beforeEach(() => {
}
} // Reset fetch mock
if ((global as any).fetch) {
((global as any).fetch as jest.Mock).mockClear();
((global as any).fetch as any).mockClear?.();
}
});
@ -85,7 +86,7 @@ export const questdbTestHelpers = {
/**
* Mock successful QuestDB HTTP response
*/ mockQuestDBHttpSuccess: (data: any) => {
((global as any).fetch as jest.Mock).mockResolvedValueOnce({
((global as any).fetch as any).mockResolvedValue?.({
ok: true,
status: 200,
json: async () => data,
@ -95,9 +96,8 @@ export const questdbTestHelpers = {
/**
* Mock QuestDB HTTP error
*/
mockQuestDBHttpError: (status: number, message: string) => {
((global as any).fetch as jest.Mock).mockResolvedValueOnce({
*/ mockQuestDBHttpError: (status: number, message: string) => {
((global as any).fetch as any).mockResolvedValue?.({
ok: false,
status,
json: async () => ({ error: message }),
@ -107,9 +107,8 @@ export const questdbTestHelpers = {
/**
* Mock InfluxDB line protocol response
*/
mockInfluxDBSuccess: () => {
((global as any).fetch as jest.Mock).mockResolvedValueOnce({
*/ mockInfluxDBSuccess: () => {
((global as any).fetch as any).mockResolvedValue?.({
ok: true,
status: 204,
text: async () => ''
@ -201,15 +200,21 @@ export const questdbTestHelpers = {
/**
* Mock connection pool
*/
createMockPool: () => ({
connect: jest.fn().mockResolvedValue({
query: jest.fn().mockResolvedValue({ rows: [], rowCount: 0 }),
release: jest.fn()
}),
end: jest.fn().mockResolvedValue(undefined),
*/ createMockPool: () => {
const mockQuery = () => Promise.resolve({ rows: [], rowCount: 0 });
const mockRelease = () => {};
const mockConnect = () => Promise.resolve({
query: mockQuery,
release: mockRelease
});
const mockEnd = () => Promise.resolve(undefined);
return {
connect: mockConnect,
end: mockEnd,
totalCount: 0,
idleCount: 0,
waitingCount: 0
})
};
}
};

View file

@ -8,11 +8,11 @@
"build": "turbo run build",
"build:libs": "pwsh ./scripts/build-libs.ps1",
"test": "turbo run test",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage",
"test:unit": "jest --testPathPattern=unit",
"test:integration": "jest --testPathPattern=integration",
"test:e2e": "jest --testPathPattern=e2e",
"test:watch": "bun test --watch",
"test:coverage": "bun test --coverage",
"test:unit": "bun test test/unit",
"test:integration": "bun test test/integration",
"test:e2e": "bun test test/e2e",
"test:libs": "turbo run test --filter=./libs/*",
"test:apps": "turbo run test --filter=./apps/*/*",
"lint": "turbo run lint",
@ -41,12 +41,7 @@
"@types/node": "^20.12.12",
"turbo": "^2.5.4",
"typescript": "^5.4.5",
"@types/jest": "^29.5.12",
"jest": "^29.7.0",
"ts-jest": "^29.1.2",
"@jest/globals": "^29.7.0",
"jest-extended": "^4.0.2",
"jest-mock-extended": "^3.0.5",
"bun-types": "^1.2.15",
"@testcontainers/postgresql": "^10.7.2",
"@testcontainers/mongodb": "^10.7.2",
"mongodb-memory-server": "^9.1.6",

136
test/setup.ts Normal file
View file

@ -0,0 +1,136 @@
/**
* Bun Test Setup File for Stock Bot Trading Platform
*
* Global test configuration and utilities available across all tests.
* This file is executed before each test via bunfig.toml preload.
*/
// Increase test timeout if needed (already configured in bunfig.toml)
// Bun.timeout = 30000;
// Store original console methods to allow restoration
const originalConsole = global.console;
// Mock console methods to reduce noise during tests
// These can be restored with testHelpers.restoreConsole()
console.log = () => {};
console.debug = () => {};
console.info = () => {};
console.warn = () => {};
console.error = () => {};
// Global test utilities available in all test files
declare global {
var testHelpers: {
sleep: (ms: number) => Promise<void>;
mockTimestamp: () => Date;
generateTestOHLCV: (symbol?: string, overrides?: any) => any;
generateTestTrade: (symbol?: string, overrides?: any) => any;
generateTestQuote: (symbol?: string, overrides?: any) => any;
mockLogger: () => any;
restoreConsole: () => void;
};
}
global.testHelpers = {
/**
* Sleep utility for async tests
*/
sleep: (ms: number) => new Promise(resolve => setTimeout(resolve, ms)),
/**
* Consistent mock timestamp for tests
*/
mockTimestamp: () => new Date('2024-01-01T12:00:00Z'),
/**
* Generate test OHLCV data
*/
generateTestOHLCV: (symbol = 'AAPL', overrides = {}) => ({
symbol,
open: 150.0,
high: 153.0,
low: 149.0,
close: 152.5,
volume: 10000,
timestamp: global.testHelpers.mockTimestamp(),
...overrides
}),
/**
* Generate test trade data
*/
generateTestTrade: (symbol = 'AAPL', overrides = {}) => ({
symbol,
price: 152.5,
size: 100,
timestamp: global.testHelpers.mockTimestamp(),
exchange: 'NASDAQ',
conditions: ['@', 'T'],
...overrides
}),
/**
* Generate test quote data
*/
generateTestQuote: (symbol = 'AAPL', overrides = {}) => ({
symbol,
bidPrice: 152.45,
bidSize: 200,
askPrice: 152.55,
askSize: 150,
timestamp: global.testHelpers.mockTimestamp(),
...overrides
}),
/**
* Create a mock logger
*/
mockLogger: () => ({
debug: () => {},
info: () => {},
warn: () => {},
error: () => {},
critical: () => {},
}),
/**
* Restore console methods
*/
restoreConsole: () => {
global.console = originalConsole;
}
};
// Set up spyOn utilities
// Similar to jest.spyOn but using Bun's built-in spy functionality
// This makes it easier to migrate from Jest
global.spyOn = function(object: any, method: string) {
const original = object[method];
const mock = function(...args: any[]) {
mock.mock.calls.push(args);
return mock.mockImplementation ? mock.mockImplementation(...args) : original.apply(object, args);
};
mock.mock = { calls: [] };
mock.mockClear = () => { mock.mock.calls = []; return mock; };
mock.mockReset = () => {
mock.mock.calls = [];
mock.mockImplementation = null;
return mock;
};
mock.mockImplementation = null;
mock.mockReturnValue = (value: any) => {
mock.mockImplementation = () => value;
return mock;
};
mock.mockResolvedValue = (value: any) => {
return mock.mockReturnValue(Promise.resolve(value));
};
mock.mockRejectedValue = (value: any) => {
return mock.mockReturnValue(Promise.reject(value));
};
object[method] = mock;
return mock;
};