Skip to content

Commit fe15916

Browse files
committed
test: ✅ Add tests
1 parent 34829b3 commit fe15916

File tree

1 file changed

+125
-2
lines changed

1 file changed

+125
-2
lines changed

core/llm/llms/Bedrock.test.ts

Lines changed: 125 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,21 @@ import {
77
import Bedrock from "./Bedrock.js";
88

99
// Mock AWS SDK
10+
const mockSend = jest.fn();
11+
const mockMiddlewareStackAdd = jest.fn();
12+
1013
jest.mock("@aws-sdk/client-bedrock-runtime", () => ({
1114
BedrockRuntimeClient: jest.fn().mockImplementation(() => ({
12-
send: jest.fn(),
13-
middlewareStack: { add: jest.fn() },
15+
send: mockSend,
16+
middlewareStack: { add: mockMiddlewareStackAdd },
1417
})),
1518
ConverseStreamCommand: jest.fn(),
19+
ConverseCommand: jest.fn(),
1620
InvokeModelCommand: jest.fn(),
21+
ConversationRole: {
22+
USER: "user",
23+
ASSISTANT: "assistant",
24+
},
1725
}));
1826

1927
// Mock credential provider
@@ -90,6 +98,8 @@ class TestBedrock extends Bedrock {
9098
describe("Bedrock", () => {
9199
beforeEach(() => {
92100
jest.clearAllMocks();
101+
mockSend.mockReset();
102+
mockMiddlewareStackAdd.mockReset();
93103
});
94104

95105
describe("constructor", () => {
@@ -304,6 +314,119 @@ describe("Bedrock", () => {
304314
});
305315
});
306316

317+
describe("streaming vs non-streaming behavior", () => {
318+
class TestableStreamingBedrock extends Bedrock {
319+
public streamingMethodCalled = false;
320+
public nonStreamingMethodCalled = false;
321+
322+
protected async *_streamChatStreaming(
323+
messages: ChatMessage[],
324+
signal: AbortSignal,
325+
options: CompletionOptions,
326+
): AsyncGenerator<ChatMessage> {
327+
this.streamingMethodCalled = true;
328+
yield { role: "assistant", content: "Streaming response" };
329+
}
330+
331+
protected async *_streamChatNonStreaming(
332+
messages: ChatMessage[],
333+
signal: AbortSignal,
334+
options: CompletionOptions,
335+
): AsyncGenerator<ChatMessage> {
336+
this.nonStreamingMethodCalled = true;
337+
yield { role: "assistant", content: "Non-streaming response" };
338+
}
339+
}
340+
341+
let bedrock: TestableStreamingBedrock;
342+
const mockAbortSignal = new AbortController().signal;
343+
344+
beforeEach(() => {
345+
bedrock = new TestableStreamingBedrock({
346+
apiKey: "test-key",
347+
model: "anthropic.claude-3-sonnet-20240229-v1:0",
348+
region: "us-east-1",
349+
});
350+
});
351+
352+
it("should use streaming method when stream is not false", async () => {
353+
const messages: ChatMessage[] = [
354+
{ role: "user", content: "Hello" } as UserChatMessage,
355+
];
356+
357+
const options: CompletionOptions = {
358+
model: "anthropic.claude-3-sonnet-20240229-v1:0",
359+
stream: true, // Explicitly set streaming
360+
};
361+
362+
const results = [];
363+
for await (const message of bedrock["_streamChat"](
364+
messages,
365+
mockAbortSignal,
366+
options,
367+
)) {
368+
results.push(message);
369+
}
370+
371+
expect(bedrock.streamingMethodCalled).toBe(true);
372+
expect(bedrock.nonStreamingMethodCalled).toBe(false);
373+
expect(results).toEqual([
374+
{ role: "assistant", content: "Streaming response" },
375+
]);
376+
});
377+
378+
it("should use non-streaming method when stream is false", async () => {
379+
const messages: ChatMessage[] = [
380+
{ role: "user", content: "Hello" } as UserChatMessage,
381+
];
382+
383+
const options: CompletionOptions = {
384+
model: "anthropic.claude-3-sonnet-20240229-v1:0",
385+
stream: false, // Explicitly set non-streaming
386+
};
387+
388+
const results = [];
389+
for await (const message of bedrock["_streamChat"](
390+
messages,
391+
mockAbortSignal,
392+
options,
393+
)) {
394+
results.push(message);
395+
}
396+
397+
expect(bedrock.streamingMethodCalled).toBe(false);
398+
expect(bedrock.nonStreamingMethodCalled).toBe(true);
399+
expect(results).toEqual([
400+
{ role: "assistant", content: "Non-streaming response" },
401+
]);
402+
});
403+
404+
it("should default to streaming method when stream option is undefined", async () => {
405+
const messages: ChatMessage[] = [
406+
{ role: "user", content: "Hello" } as UserChatMessage,
407+
];
408+
409+
const options: CompletionOptions = {
410+
model: "anthropic.claude-3-sonnet-20240229-v1:0",
411+
// stream option is undefined, should default to streaming
412+
};
413+
414+
const results = [];
415+
for await (const message of bedrock["_streamChat"](
416+
messages,
417+
mockAbortSignal,
418+
options,
419+
)) {
420+
results.push(message);
421+
}
422+
423+
expect(bedrock.streamingMethodCalled).toBe(true);
424+
expect(bedrock.nonStreamingMethodCalled).toBe(false);
425+
});
426+
});
427+
428+
429+
307430
describe("message conversion", () => {
308431
let bedrock: TestBedrock;
309432

0 commit comments

Comments
 (0)