-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update dependencies and add new tests for createClient function
- Loading branch information
Showing
3 changed files
with
136 additions
and
71 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,70 +1,124 @@ | ||
import { assert } from "https://deno.land/[email protected]/assert/mod.ts"; | ||
import { websocket } from "../api/marketData.ts"; | ||
import { assert } from "https://deno.land/[email protected]/assert/assert.ts"; | ||
import { assertThrows } from "https://deno.land/[email protected]/assert/assert_throws.ts"; | ||
import { mockFetch } from "../utils/mockFetch.ts"; | ||
import { createClient } from "./createClient.ts"; | ||
|
||
Deno.test("creates a client with trade and marketData APIs", () => { | ||
const { trade, marketData } = createClient({ | ||
keyId: "test", | ||
secretKey: "test", | ||
Deno.test("should create a trade client with valid options", () => { | ||
const client = createClient({ | ||
baseURL: "https://paper-api.alpaca.markets", | ||
keyId: "EXAMPLE_KEY_ID", | ||
secretKey: "EXAMPLE_KEY_SECRET", | ||
}); | ||
|
||
assert(trade !== undefined, "trade"); | ||
assert(websocket !== undefined, "marketData"); | ||
assert( | ||
typeof trade.rest.v2.account.get === "function", | ||
"trade.v2.account.get" | ||
); | ||
assert( | ||
typeof marketData.rest.v2.stocks.getConditionCodes === "function", | ||
"marketData.v2.stocks.getConditionCodes" | ||
assert(client.account !== undefined); | ||
assert(client.orders.create !== undefined); | ||
}); | ||
|
||
Deno.test("should create a market data client with valid options", () => { | ||
const client = createClient({ | ||
baseURL: "https://data.alpaca.markets", | ||
keyId: "EXAMPLE_KEY_ID", | ||
secretKey: "EXAMPLE_KEY_SECRET", | ||
}); | ||
|
||
assert(client.rest.v1beta1 !== undefined); | ||
assert(client.rest.v1beta3 !== undefined); | ||
}); | ||
|
||
Deno.test("should throw an error with an invalid base URL", () => { | ||
assertThrows( | ||
() => { | ||
createClient({ | ||
// deno-lint-ignore ban-ts-comment | ||
// @ts-expect-error | ||
baseURL: "https://invalid-url.com", | ||
keyId: "EXAMPLE_KEY_ID", | ||
secretKey: "EXAMPLE_KEY_SECRET", | ||
}); | ||
}, | ||
Error, | ||
"invalid base URL" | ||
); | ||
}); | ||
|
||
// Deno.test("createClient - request handles parameters and data", async () => { | ||
// const client = createClient({ | ||
// keyId: "testKeyId", | ||
// secretKey: "testSecretKey", | ||
// baseURL: "https://example.com", | ||
// }); | ||
|
||
// const response = await client.rest.trade({ | ||
// path: "/test/{param}", | ||
// params: { param: "value" }, | ||
// data: { test: "data" }, | ||
// }); | ||
|
||
// assertEquals(response.finalPath, "/test/value"); | ||
// assertEquals(response.data, { test: "data" }); | ||
// }); | ||
|
||
// Deno.test("createClient - throws error on API call failure", async () => { | ||
// const client = createClient({ | ||
// keyId: "testKeyId", | ||
// secretKey: "testSecretKey", | ||
// baseURL: "https://example.com", | ||
// }); | ||
|
||
// await assertRejects( | ||
// () => | ||
// client.rest.trade({ | ||
// path: "/invalid-endpoint", | ||
// }), | ||
// Error, | ||
// "API call failed" | ||
// ); | ||
// }); | ||
|
||
// Deno.test("createClient - constructs websocket clients correctly", () => { | ||
// const { websocket } = createClient({ | ||
// keyId: "PK1OHDJBZQ6J5HQJZBXX", | ||
// secretKey: "7ntdrZayazQkRxINbLWcn4ib0Nv58AlTQH0IqzbQ", | ||
// baseURL: "https://paper-api.alpaca.markets", | ||
// }); | ||
|
||
// assert(websocket.trade instanceof TradeWebSocket); | ||
// assert(websocket.marketData.stock instanceof StockDataWebSocket); | ||
// assert(websocket.marketData.crypto instanceof CryptoWebSocket); | ||
// assert(websocket.marketData.news instanceof NewsWebSocket); | ||
// assert(websocket.marketData.options instanceof OptionsWebSocket); | ||
// }); | ||
Deno.test("should use the provided token bucket options", () => { | ||
const tokenBucketOptions = { | ||
capacity: 100, | ||
fillRate: 2, | ||
}; | ||
|
||
const client = createClient({ | ||
baseURL: "https://paper-api.alpaca.markets", | ||
keyId: "EXAMPLE_KEY_ID", | ||
secretKey: "EXAMPLE_KEY_SECRET", | ||
tokenBucket: tokenBucketOptions, | ||
}); | ||
|
||
assert(client._context.options.tokenBucket === tokenBucketOptions); | ||
}); | ||
|
||
Deno.test("should use default token bucket options if not provided", () => { | ||
const client = createClient({ | ||
baseURL: "https://paper-api.alpaca.markets", | ||
keyId: "EXAMPLE_KEY_ID", | ||
secretKey: "EXAMPLE_KEY_SECRET", | ||
}); | ||
|
||
assert(client._context.options.tokenBucket === undefined); | ||
}); | ||
|
||
Deno.test("should make a request with the correct options", async () => { | ||
const mockResponse = { mock: "data" }; | ||
const originalFetch = globalThis.fetch; | ||
// deno-lint-ignore ban-ts-comment | ||
// @ts-expect-error | ||
globalThis.fetch = mockFetch(mockResponse); | ||
|
||
const client = createClient({ | ||
baseURL: "https://paper-api.alpaca.markets", | ||
keyId: "EXAMPLE_KEY_ID", | ||
secretKey: "EXAMPLE_KEY_SECRET", | ||
}); | ||
|
||
const response = await client._context.request({ | ||
path: "/v2/account", | ||
}); | ||
|
||
assert(response === mockResponse); | ||
|
||
globalThis.fetch = originalFetch; | ||
}); | ||
|
||
Deno.test("should throttle requests based on token bucket", async () => { | ||
const mockResponse = { mock: "data" }; | ||
const originalFetch = globalThis.fetch; | ||
|
||
// deno-lint-ignore ban-ts-comment | ||
// @ts-expect-error | ||
globalThis.fetch = mockFetch(mockResponse); | ||
|
||
const client = createClient({ | ||
baseURL: "https://paper-api.alpaca.markets", | ||
keyId: "EXAMPLE_KEY_ID", | ||
secretKey: "EXAMPLE_KEY_SECRET", | ||
tokenBucket: { | ||
capacity: 2, | ||
fillRate: 1, | ||
}, | ||
}); | ||
|
||
const startTime = Date.now(); | ||
|
||
await Promise.all([ | ||
client._context.request({ path: "/v2/account" }), | ||
client._context.request({ path: "/v2/account" }), | ||
client._context.request({ path: "/v2/account" }), | ||
]); | ||
|
||
const endTime = Date.now(); | ||
const elapsedTime = endTime - startTime; | ||
|
||
assert(elapsedTime >= 2000, "Requests should be throttled"); | ||
|
||
globalThis.fetch = originalFetch; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
export const mockFetch = | ||
// deno-lint-ignore no-explicit-any | ||
(response: any) => (_url: string, _init?: RequestInit) => { | ||
return Promise.resolve({ | ||
ok: true, | ||
json: () => Promise.resolve(response), | ||
} as Response); | ||
}; |