From 1e5e8f8964fbc23abb13e6c95781640901abb43e Mon Sep 17 00:00:00 2001 From: Ronan-Yann Lorin Date: Sat, 9 Mar 2024 05:59:11 +0100 Subject: [PATCH 1/4] placeOrder test suite improved --- .codeclimate.yml | 2 +- package.json | 12 +-- src/core/api-next/subscription-registry.ts | 43 +++++---- src/core/io/decoder.ts | 13 +-- src/tests/unit/api/order/placeOrder.test.ts | 101 ++++++++++++++++---- yarn.lock | 55 ++++++----- 6 files changed, 150 insertions(+), 76 deletions(-) diff --git a/.codeclimate.yml b/.codeclimate.yml index 451f14f3..86a05adc 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -1,3 +1,3 @@ exclude_patterns: - "ref/" - - "src/tests" + - "src/tests/" diff --git a/package.json b/package.json index 75ba1f12..1a6e9d8b 100644 --- a/package.json +++ b/package.json @@ -68,26 +68,26 @@ "dependencies": { "colors": "^1.4.0", "command-buffer": "^0.1.0", - "dotenv": "^16.3.1", + "dotenv": "^16.4.4", "eventemitter3": "^5.0.1", "function-rate-limit": "^1.1.0", "rxjs": "^7.8.1" }, "devDependencies": { - "@types/jest": "^29.5.11", - "@types/node": "^18.17.15", + "@types/jest": "^29.5.12", + "@types/node": "^18.19.15", "@types/source-map-support": "^0.5.10", "@typescript-eslint/eslint-plugin": "^6.18.1", "@typescript-eslint/parser": "^6.18.1", "ajv": "^8.12.0", "eslint": "^8.56.0", - "eslint-plugin-jest": "^27.6.2", + "eslint-plugin-jest": "^27.8.0", "eslint-plugin-rxjs": "^5.0.3", "jest": "^29.7.0", "jest-environment-node": "^29.7.0", "jest-junit": "^16.0.0", - "ts-jest": "^29.1.1", - "typedoc": "^0.25.7", + "ts-jest": "^29.1.2", + "typedoc": "^0.25.8", "typescript": "^5.2.2" }, "engines": { diff --git a/src/core/api-next/subscription-registry.ts b/src/core/api-next/subscription-registry.ts index c7936b3c..e962ca6f 100644 --- a/src/core/api-next/subscription-registry.ts +++ b/src/core/api-next/subscription-registry.ts @@ -1,6 +1,6 @@ import { Observable } from "rxjs"; import { EventName } from "../.."; -import { IBApiNextError, IBApiNext, ItemListUpdate } from "../../api-next"; +import { IBApiNext, IBApiNextError, ItemListUpdate } from "../../api-next"; import { IBApiAutoConnection } from "./auto-connection"; import { IBApiNextMap } from "./map"; import { IBApiNextSubscription } from "./subscription"; @@ -31,7 +31,7 @@ class RegistryEntry { public readonly callback: ( subscriptions: Map>, ...eventArgs: unknown[] - ) => void + ) => void, ) { this.listener = (...eventArgs) => { this.callback(this.subscriptions, ...eventArgs); @@ -42,10 +42,8 @@ class RegistryEntry { public readonly listener: (...eventArgs: unknown[]) => void; /** Map of all active subscriptions, with reqId as key. */ - public readonly subscriptions: Map< - number, - IBApiNextSubscription - > = new Map(); + public readonly subscriptions: Map> = + new Map(); } /** @@ -67,8 +65,8 @@ export class IBApiNextSubscriptionRegistry { */ constructor( private readonly api: IBApiAutoConnection, - private readonly apiNext: IBApiNext - ) { } + private readonly apiNext: IBApiNext, + ) {} /** A Map containing the subscription registry, with event name as key. */ private readonly entires = new IBApiNextMap(); @@ -94,33 +92,35 @@ export class IBApiNextSubscriptionRegistry { ( subscriptions: Map>, ...eventArgs: unknown[] - ) => void + ) => void, ][], - instanceId?: string + instanceId?: string, ): Observable> { // get the existing registry entries, or add if not existing yet - const entires: RegistryEntry[] = []; + const entries: RegistryEntry[] = []; eventHandler.forEach((handler) => { const eventName = handler[0]; const callback = handler[1]; + console.log(`Add RegistryEntry getOrAdd EventName.${eventName}`); const entry = this.entires.getOrAdd(eventName, () => { const entry = new RegistryEntry(eventName, callback); this.apiNext.logger.debug( LOG_TAG, - `Add RegistryEntry for EventName.${eventName}` + `Add RegistryEntry for EventName.${eventName}`, ); + console.log(`Add RegistryEntry for EventName.${eventName}`); this.api.addListener(eventName, entry.listener); return entry; }); - entires.push(entry); + entries.push(entry); }); // lookup subscription by instance id let subscription: IBApiNextSubscription; if (instanceId) { - entires.forEach((entry) => { + entries.forEach((entry) => { const values = entry.subscriptions.values(); while (!subscription) { const it = values.next(); @@ -150,13 +150,16 @@ export class IBApiNextSubscriptionRegistry { } }, () => { - entires.forEach((entry) => { + entries.forEach((entry) => { entry.subscriptions.delete(subscription.reqId); if (!entry.subscriptions.size) { + console.log( + `Remove RegistryEntry for EventName.${entry.eventName}.`, + ); this.api.removeListener(entry.eventName, entry.listener); this.apiNext.logger.debug( LOG_TAG, - `Remove RegistryEntry for EventName.${entry.eventName}.` + `Remove RegistryEntry for EventName.${entry.eventName}.`, ); this.entires.delete(entry.eventName); } @@ -164,16 +167,16 @@ export class IBApiNextSubscriptionRegistry { this.apiNext.logger.debug( LOG_TAG, - `Deleted IBApiNextSubscription for ${subscription.reqId}.` + `Deleted IBApiNextSubscription for ${subscription.reqId}.`, ); }, - instanceId + instanceId, ); - entires.forEach((entry) => { + entries.forEach((entry) => { this.apiNext.logger.debug( LOG_TAG, - `Add IBApiNextSubscription on EventName.${entry.eventName} for ${subscription.reqId}.` + `Add IBApiNextSubscription on EventName.${entry.eventName} for ${subscription.reqId}.`, ); entry.subscriptions.set(subscription.reqId, subscription); }); diff --git a/src/core/io/decoder.ts b/src/core/io/decoder.ts index 77834816..03edda3b 100644 --- a/src/core/io/decoder.ts +++ b/src/core/io/decoder.ts @@ -499,7 +499,7 @@ export class Decoder { */ readDoubleOrUndefined(): number | undefined { const token = this.readStr(); - if (!token || token === "") { + if (!token) { return undefined; } const val = parseFloat(token); @@ -525,6 +525,7 @@ export class Decoder { * Read a token from queue and return it as integer value. * * Returns Number.MAX_VALUE if the token is empty. + * @deprecated readIntOrUndefined is probably what you are looking for */ readIntMax(): number { const token = this.readStr(); @@ -3066,7 +3067,7 @@ class OrderDecoder { readDisplaySize(): void { if (this.version >= 9) { - this.order.displaySize = this.decoder.readInt(); + this.order.displaySize = this.decoder.readIntOrUndefined(); } } @@ -3417,7 +3418,7 @@ class OrderDecoder { if (nConditions > 0) { this.order.conditions = new Array(nConditions); - + for (let i = 0; i < nConditions; i++) { const orderConditionType = this.decoder.readInt(); @@ -3645,14 +3646,14 @@ class OrderDecoder { readPostToAts(): void { if (this.serverVersion >= MIN_SERVER_VER.POST_TO_ATS) { - this.order.postToAts = this.decoder.readIntMax(); + this.order.postToAts = this.decoder.readIntOrUndefined(); } } readPegBestPegMidOrderAttributes() { if (this.serverVersion >= MIN_SERVER_VER.PEGBEST_PEGMID_OFFSETS) { - this.order.minTradeQty = this.decoder.readIntMax(); - this.order.minCompeteSize = this.decoder.readIntMax(); + this.order.minTradeQty = this.decoder.readIntOrUndefined(); + this.order.minCompeteSize = this.decoder.readIntOrUndefined(); this.order.competeAgainstBestOffset = this.decoder.readDoubleOrUndefined(); this.order.midOffsetAtWhole = this.decoder.readDoubleOrUndefined(); diff --git a/src/tests/unit/api/order/placeOrder.test.ts b/src/tests/unit/api/order/placeOrder.test.ts index 6489e893..14676181 100644 --- a/src/tests/unit/api/order/placeOrder.test.ts +++ b/src/tests/unit/api/order/placeOrder.test.ts @@ -46,8 +46,8 @@ describe("Place Orders", () => { test("Simple placeOrder", (done) => { let refId: number; - const contract: Contract = new Stock("SPY"); - const order: Order = { + const refContract: Contract = new Stock("SPY"); + const refOrder: Order = { orderType: OrderType.LMT, action: OrderAction.BUY, lmtPrice: 1, @@ -60,15 +60,14 @@ describe("Place Orders", () => { ib.once(EventName.nextValidId, (orderId: number) => { refId = orderId; - ib.placeOrder(refId, contract, order); + ib.placeOrder(refId, refContract, refOrder); }) - .on(EventName.openOrder, (orderId, contract, order, _orderState) => { - expect(orderId).toEqual(refId); - expect(contract.symbol).toEqual("AAPL"); - expect(order.totalQuantity).toEqual(2); - }) - .on(EventName.openOrderEnd, () => { - done(); + .on(EventName.openOrder, (orderId, contract, order, orderState) => { + if (orderId == refId) { + expect(contract.symbol).toEqual(refContract.symbol); + expect(order.totalQuantity).toEqual(refOrder.totalQuantity); + done(); + } }) .on( EventName.error, @@ -82,7 +81,10 @@ describe("Place Orders", () => { logger.info(error.message); } else { const msg = `[${reqId}] ${error.message} (Error #${code})`; - if (error.message.includes("Warning:")) { + if ( + error.message.includes("Warning:") || + error.message.includes("Order Message:") + ) { logger.warn(msg); } else { ib.disconnect(); @@ -99,7 +101,7 @@ describe("Place Orders", () => { let refId: number; // buy an Apple call, with a PriceCondition on underlying - const contract: Contract = new Option( + const refContract: Contract = new Option( "AAPL", "20251219", 200, @@ -113,7 +115,7 @@ describe("Place Orders", () => { true, ConjunctionConnection.OR, ); - const order: Order = { + const refOrder: Order = { orderType: OrderType.LMT, action: OrderAction.BUY, lmtPrice: 0.01, @@ -127,13 +129,71 @@ describe("Place Orders", () => { ib.once(EventName.nextValidId, (orderId: number) => { refId = orderId; - ib.placeOrder(refId, contract, order); + ib.placeOrder(refId, refContract, refOrder); }) - .on(EventName.openOrder, (orderId, _contract, _order, _orderState) => { - expect(orderId).toEqual(refId); + .on(EventName.openOrder, (orderId, contract, order, orderState) => { + if (orderId == refId) { + expect(contract.symbol).toEqual(refContract.symbol); + expect(order.totalQuantity).toEqual(refOrder.totalQuantity); + done(); + } }) - .on(EventName.openOrderEnd, () => { - done(); + .on( + EventName.error, + ( + error: Error, + code: ErrorCode, + reqId: number, + _advancedOrderReject?: unknown, + ) => { + if (reqId === -1) { + logger.info(error.message); + } else { + const msg = `[${reqId}] ${error.message} (Error #${code})`; + if ( + error.message.includes("Warning:") || + error.message.includes("Order Message:") + ) { + logger.warn(msg); + } else { + ib.disconnect(); + done(msg); + } + } + }, + ); + + ib.connect().reqOpenOrders(); + }); + + test("What if Order", (done) => { + let refId: number; + + const refContract: Contract = new Stock("SPY"); + const refOrder: Order = { + orderType: OrderType.LMT, + action: OrderAction.BUY, + lmtPrice: 1, + orderId: refId, + totalQuantity: 2, + tif: TimeInForce.DAY, + transmit: true, + whatIf: true, + }; + + ib.once(EventName.nextValidId, (orderId: number) => { + refId = orderId; + ib.placeOrder(refId, refContract, refOrder); + }) + .on(EventName.openOrder, (orderId, contract, order, orderState) => { + if (orderId == refId) { + expect(contract.symbol).toEqual(refContract.symbol); + expect(order.totalQuantity).toEqual(refOrder.totalQuantity); + if (orderState.minCommission || orderState.maxCommission) { + expect(orderState.commissionCurrency).toEqual(refContract.currency); + done(); + } + } }) .on( EventName.error, @@ -147,7 +207,10 @@ describe("Place Orders", () => { logger.info(error.message); } else { const msg = `[${reqId}] ${error.message} (Error #${code})`; - if (error.message.includes("Warning:")) { + if ( + error.message.includes("Warning:") || + error.message.includes("Order Message:") + ) { logger.warn(msg); } else { ib.disconnect(); diff --git a/yarn.lock b/yarn.lock index 92ac5015..b1a49f03 100644 --- a/yarn.lock +++ b/yarn.lock @@ -807,10 +807,10 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/jest@^29.5.11": - version "29.5.11" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.11.tgz#0c13aa0da7d0929f078ab080ae5d4ced80fa2f2c" - integrity sha512-S2mHmYIVe13vrm6q4kN6fLYYAka15ALQki/vgDC3mIukEOx8WJlv0kQPM+d4w8Gp6u0uSdKND04IlTXBv0rwnQ== +"@types/jest@^29.5.12": + version "29.5.12" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.12.tgz#7f7dc6eb4cf246d2474ed78744b05d06ce025544" + integrity sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw== dependencies: expect "^29.0.0" pretty-format "^29.0.0" @@ -825,10 +825,12 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-18.16.19.tgz#cb03fca8910fdeb7595b755126a8a78144714eea" integrity sha512-IXl7o+R9iti9eBW4Wg2hx1xQDig183jj7YLn8F7udNceyfkbn1ZxmzZXuak20gR40D7pIkIY1kYGx5VIGbaHKA== -"@types/node@^18.17.15": - version "18.17.15" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.17.15.tgz#31301a273b9ca7d568fe6d1c35ae52e0fb3f8d6a" - integrity sha512-2yrWpBk32tvV/JAd3HNHWuZn/VDN1P+72hWirHnvsvTGSqbANi+kSeuQR9yAHnbvaBvHDsoTdXV0Fe+iRtHLKA== +"@types/node@^18.19.15": + version "18.19.15" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.15.tgz#313a9d75435669a57fc28dc8694e7f4c4319f419" + integrity sha512-AMZ2UWx+woHNfM11PyAEQmfSxi05jm9OlkxczuHeEqmvwPkYj6MWv44gbzDPefYOLysTOFyI3ziiy2ONmUZfpA== + dependencies: + undici-types "~5.26.4" "@types/semver@^7.3.12", "@types/semver@^7.5.0": version "7.5.1" @@ -1438,10 +1440,10 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" -dotenv@^16.3.1: - version "16.3.1" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" - integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== +dotenv@^16.4.4: + version "16.4.4" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.4.tgz#a26e7bb95ebd36272ebb56edb80b826aecf224c1" + integrity sha512-XvPXc8XAQThSjAbY6cQ/9PcBXmFoWuw1sQ3b8HqUCR6ziGXjkTi//kB9SWa2UwqlgdAIuRqAa/9hVljzPehbYg== electron-to-chromium@^1.4.477: version "1.4.505" @@ -1494,10 +1496,10 @@ eslint-etc@^5.1.0: tsutils "^3.17.1" tsutils-etc "^1.4.1" -eslint-plugin-jest@^27.6.2: - version "27.6.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-27.6.2.tgz#8e69404fcd5dfeac03cac478f0ebb9bf2d8db56b" - integrity sha512-CI1AlKrsNhYFoP48VU8BVWOi7+qHTq4bRxyUlGjeU8SfFt8abjXhjOuDzUoMp68DoXIx17KpNpIkMrl4s4ZW0g== +eslint-plugin-jest@^27.8.0: + version "27.8.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-27.8.0.tgz#c8900c3e74e4c6b8cee67ea77dbc8de9cbd9e093" + integrity sha512-347hVFiu4ZKMYl5xFp0X81gLNwBdno0dl0CMpUMjwuAux9X/M2a7z+ab2VHmPL6XCT87q8nv1vaVzhIO4TE/hw== dependencies: "@typescript-eslint/utils" "^5.10.0" @@ -3135,10 +3137,10 @@ ts-api-utils@^1.0.1: resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.0.2.tgz#7c094f753b6705ee4faee25c3c684ade52d66d99" integrity sha512-Cbu4nIqnEdd+THNEsBdkolnOXhg0I8XteoHaEKgvsxpsbWda4IsUut2c187HxywQCvveojow0Dgw/amxtSKVkQ== -ts-jest@^29.1.1: - version "29.1.1" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.1.1.tgz#f58fe62c63caf7bfcc5cc6472082f79180f0815b" - integrity sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA== +ts-jest@^29.1.2: + version "29.1.2" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.1.2.tgz#7613d8c81c43c8cb312c6904027257e814c40e09" + integrity sha512-br6GJoH/WUX4pu7FbZXuWGKGNDuU7b8Uj77g/Sp7puZV6EXzuByl6JrECvm0MzVzSTkSHWTihsXt+5XYER5b+g== dependencies: bs-logger "0.x" fast-json-stable-stringify "2.x" @@ -3196,10 +3198,10 @@ type-fest@^0.21.3: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== -typedoc@^0.25.7: - version "0.25.7" - resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.25.7.tgz#11e3f527ca80ca3c029cb8e15f362e6d9f715e25" - integrity sha512-m6A6JjQRg39p2ZVRIN3NKXgrN8vzlHhOS+r9ymUYtcUP/TIQPvWSq7YgE5ZjASfv5Vd5BW5xrir6Gm2XNNcOow== +typedoc@^0.25.8: + version "0.25.8" + resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.25.8.tgz#7d0e1bf12d23bf1c459fd4893c82cb855911ff12" + integrity sha512-mh8oLW66nwmeB9uTa0Bdcjfis+48bAjSH3uqdzSuSawfduROQLlXw//WSNZLYDdhmMVB7YcYZicq6e8T0d271A== dependencies: lunr "^2.3.9" marked "^4.3.0" @@ -3211,6 +3213,11 @@ typescript@^5.2.2: resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.2.tgz#5ebb5e5a5b75f085f22bc3f8460fba308310fa78" integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w== +undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== + update-browserslist-db@^1.0.11: version "1.0.11" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz#9a2a641ad2907ae7b3616506f4b977851db5b940" From a7b5b647bd0022192478013f00ab2832223bf815 Mon Sep 17 00:00:00 2001 From: Ronan-Yann Lorin Date: Sat, 9 Mar 2024 06:01:04 +0100 Subject: [PATCH 2/4] Issue Security type for crypto has some white space. #210 fix --- src/api/data/enum/sec-type.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/data/enum/sec-type.ts b/src/api/data/enum/sec-type.ts index 56cfabde..2c23f76b 100644 --- a/src/api/data/enum/sec-type.ts +++ b/src/api/data/enum/sec-type.ts @@ -60,7 +60,7 @@ export enum SecType { ICS = "ICS", /** Cryptocurrency. */ - CRYPTO = "CRYPTO ", + CRYPTO = "CRYPTO", } export default SecType; From e1d5358bdb919c267fdd4be282f5edc54925d1d7 Mon Sep 17 00:00:00 2001 From: Ronan-Yann Lorin Date: Sat, 9 Mar 2024 06:14:41 +0100 Subject: [PATCH 3/4] console.log removed --- src/core/api-next/subscription-registry.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/core/api-next/subscription-registry.ts b/src/core/api-next/subscription-registry.ts index e962ca6f..f57de1a9 100644 --- a/src/core/api-next/subscription-registry.ts +++ b/src/core/api-next/subscription-registry.ts @@ -102,14 +102,12 @@ export class IBApiNextSubscriptionRegistry { eventHandler.forEach((handler) => { const eventName = handler[0]; const callback = handler[1]; - console.log(`Add RegistryEntry getOrAdd EventName.${eventName}`); const entry = this.entires.getOrAdd(eventName, () => { const entry = new RegistryEntry(eventName, callback); this.apiNext.logger.debug( LOG_TAG, `Add RegistryEntry for EventName.${eventName}`, ); - console.log(`Add RegistryEntry for EventName.${eventName}`); this.api.addListener(eventName, entry.listener); return entry; }); @@ -153,9 +151,6 @@ export class IBApiNextSubscriptionRegistry { entries.forEach((entry) => { entry.subscriptions.delete(subscription.reqId); if (!entry.subscriptions.size) { - console.log( - `Remove RegistryEntry for EventName.${entry.eventName}.`, - ); this.api.removeListener(entry.eventName, entry.listener); this.apiNext.logger.debug( LOG_TAG, From 5ac46a8f70253de73601e194ca1d05902e28ab83 Mon Sep 17 00:00:00 2001 From: Ronan-Yann Lorin Date: Sat, 9 Mar 2024 06:26:24 +0100 Subject: [PATCH 4/4] Some warnings fixed --- .github/workflows/check.yml | 8 ++++++-- .github/workflows/publish.yml | 4 ++-- src/tests/unit/api-next-live/get-contract-details.test.ts | 1 - src/tests/unit/api/order/placeOrder.test.ts | 4 ++-- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index d3b753c6..cbff5638 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -13,14 +13,18 @@ jobs: timeout-minutes: 3 steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 + - name: Setup Node.js - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: 18.17.1 + - name: Prepare run: yarn install --frozen-lockfile + - name: Type Check run: yarn type-check + - name: Lint Check run: yarn lint diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index cda434aa..ae8dd1f9 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -12,13 +12,13 @@ jobs: steps: - name: "Checkout source code" - uses: "actions/checkout@v2" + uses: "actions/checkout@v4" with: ref: ${{ github.ref }} # Setup Node.js - name: "Setup Node.js" - uses: "actions/setup-node@v3" + uses: "actions/setup-node@v4" with: node-version: 18.17.1 diff --git a/src/tests/unit/api-next-live/get-contract-details.test.ts b/src/tests/unit/api-next-live/get-contract-details.test.ts index c807f5db..12a3fc8a 100644 --- a/src/tests/unit/api-next-live/get-contract-details.test.ts +++ b/src/tests/unit/api-next-live/get-contract-details.test.ts @@ -16,7 +16,6 @@ describe("ApiNext: getContractDetails()", () => { const clientId = Math.floor(Math.random() * 32766) + 1; // ensure unique client - let subscription$: Subscription; let api: IBApiNext; let error$: Subscription; diff --git a/src/tests/unit/api/order/placeOrder.test.ts b/src/tests/unit/api/order/placeOrder.test.ts index 14676181..b40f329d 100644 --- a/src/tests/unit/api/order/placeOrder.test.ts +++ b/src/tests/unit/api/order/placeOrder.test.ts @@ -62,7 +62,7 @@ describe("Place Orders", () => { refId = orderId; ib.placeOrder(refId, refContract, refOrder); }) - .on(EventName.openOrder, (orderId, contract, order, orderState) => { + .on(EventName.openOrder, (orderId, contract, order, _orderState) => { if (orderId == refId) { expect(contract.symbol).toEqual(refContract.symbol); expect(order.totalQuantity).toEqual(refOrder.totalQuantity); @@ -131,7 +131,7 @@ describe("Place Orders", () => { refId = orderId; ib.placeOrder(refId, refContract, refOrder); }) - .on(EventName.openOrder, (orderId, contract, order, orderState) => { + .on(EventName.openOrder, (orderId, contract, order, _orderState) => { if (orderId == refId) { expect(contract.symbol).toEqual(refContract.symbol); expect(order.totalQuantity).toEqual(refOrder.totalQuantity);