Skip to content

Commit e444431

Browse files
authored
Add e2e tests for embeddings.generate() method (#60)
2 parents f6c1933 + 0b2b95a commit e444431

File tree

2 files changed

+169
-1
lines changed

2 files changed

+169
-1
lines changed

tests/e2e/README.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,19 @@ The e2e test suite includes:
6161
- Testing the beta responses endpoint
6262
- Note: This endpoint is in alpha/beta and may require updates
6363

64+
### Embeddings Tests (`embeddings.test.ts`)
65+
- **Embeddings generation:**
66+
- Generating embeddings for single text input
67+
- Generating embeddings for multiple text inputs (batch processing)
68+
- Verifying consistent embedding dimensions
69+
- Handling edge cases (empty strings)
70+
- Model information validation
71+
- Support for both array and base64 encoded embeddings
72+
6473
## Notes
6574

6675
- Tests make real API calls to OpenRouter, so you need a valid API key
6776
- Tests may consume API credits
68-
- Some tests use the `openai/gpt-3.5-turbo` model by default
77+
- Chat tests use the `meta-llama/llama-3.2-1b-instruct` model by default
78+
- Embeddings tests use the `openai/text-embedding-3-small` model by default
6979
- The beta responses endpoint has limited test coverage as it's still in development

tests/e2e/embeddings.test.ts

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
import { beforeAll, describe, expect, it } from "vitest";
2+
import { OpenRouter } from "../../src/sdk/sdk.js";
3+
4+
describe("Embeddings E2E Tests", () => {
5+
let client: OpenRouter;
6+
7+
beforeAll(() => {
8+
const apiKey = process.env.OPENROUTER_API_KEY;
9+
if (!apiKey) {
10+
throw new Error(
11+
"OPENROUTER_API_KEY environment variable is required for e2e tests"
12+
);
13+
}
14+
15+
client = new OpenRouter({
16+
apiKey,
17+
});
18+
});
19+
20+
describe("embeddings.generate()", () => {
21+
it("should successfully generate embeddings for a single text input", async () => {
22+
const response = await client.embeddings.generate({
23+
input: "The quick brown fox jumps over the lazy dog",
24+
model: "openai/text-embedding-3-small",
25+
});
26+
27+
expect(response).toBeDefined();
28+
29+
// Check if response is an object (not a string)
30+
if (typeof response === "object") {
31+
expect(response.data).toBeDefined();
32+
expect(Array.isArray(response.data)).toBe(true);
33+
expect(response.data.length).toBeGreaterThan(0);
34+
35+
const firstEmbedding = response.data[0];
36+
expect(firstEmbedding).toBeDefined();
37+
expect(firstEmbedding?.embedding).toBeDefined();
38+
39+
// Handle both array and base64 string embeddings
40+
if (Array.isArray(firstEmbedding?.embedding)) {
41+
expect(firstEmbedding.embedding.length).toBeGreaterThan(0);
42+
// Verify embedding values are numbers
43+
const firstValue = firstEmbedding.embedding[0];
44+
expect(typeof firstValue).toBe("number");
45+
} else {
46+
expect(typeof firstEmbedding?.embedding).toBe("string");
47+
}
48+
49+
// Verify usage information if available
50+
if (response.usage) {
51+
expect(response.usage.totalTokens).toBeGreaterThan(0);
52+
}
53+
}
54+
});
55+
56+
it("should generate embeddings for multiple text inputs", async () => {
57+
const inputs = [
58+
"Hello, world!",
59+
"OpenRouter is amazing",
60+
"Embeddings are vector representations of text",
61+
];
62+
63+
const response = await client.embeddings.generate({
64+
input: inputs,
65+
model: "openai/text-embedding-3-small",
66+
});
67+
68+
expect(response).toBeDefined();
69+
70+
if (typeof response === "object") {
71+
expect(response.data).toBeDefined();
72+
expect(Array.isArray(response.data)).toBe(true);
73+
expect(response.data.length).toBe(inputs.length);
74+
75+
// Verify each embedding
76+
response.data.forEach((embedding, index) => {
77+
expect(embedding).toBeDefined();
78+
expect(embedding?.embedding).toBeDefined();
79+
80+
if (Array.isArray(embedding?.embedding)) {
81+
expect(embedding.embedding.length).toBeGreaterThan(0);
82+
} else {
83+
expect(typeof embedding?.embedding).toBe("string");
84+
}
85+
86+
expect(embedding?.index).toBe(index);
87+
});
88+
}
89+
});
90+
91+
it("should generate consistent embedding dimensions", async () => {
92+
const response = await client.embeddings.generate({
93+
input: ["First text", "Second text"],
94+
model: "openai/text-embedding-3-small",
95+
});
96+
97+
expect(response).toBeDefined();
98+
99+
if (typeof response === "object") {
100+
expect(response.data.length).toBe(2);
101+
102+
const firstEmbedding = response.data[0]?.embedding;
103+
const secondEmbedding = response.data[1]?.embedding;
104+
105+
// Only check dimensions if both are arrays
106+
if (Array.isArray(firstEmbedding) && Array.isArray(secondEmbedding)) {
107+
const firstDimension = firstEmbedding.length;
108+
const secondDimension = secondEmbedding.length;
109+
110+
expect(firstDimension).toBe(secondDimension);
111+
expect(firstDimension).toBeGreaterThan(0);
112+
}
113+
}
114+
});
115+
116+
it("should handle empty string input gracefully", async () => {
117+
const response = await client.embeddings.generate({
118+
input: "",
119+
model: "openai/text-embedding-3-small",
120+
});
121+
122+
expect(response).toBeDefined();
123+
124+
if (typeof response === "object") {
125+
expect(response.data).toBeDefined();
126+
expect(Array.isArray(response.data)).toBe(true);
127+
128+
if (response.data.length > 0) {
129+
const embedding = response.data[0];
130+
expect(embedding?.embedding).toBeDefined();
131+
}
132+
}
133+
});
134+
135+
it("should include model information in response", async () => {
136+
const modelName = "openai/text-embedding-3-small";
137+
const response = await client.embeddings.generate({
138+
input: "Test input for model verification",
139+
model: modelName,
140+
});
141+
142+
expect(response).toBeDefined();
143+
144+
if (typeof response === "object") {
145+
expect(response.model).toBeDefined();
146+
expect(typeof response.model).toBe("string");
147+
148+
if (response.usage) {
149+
expect(response.usage.promptTokens).toBeDefined();
150+
expect(response.usage.totalTokens).toBeDefined();
151+
expect(typeof response.usage.promptTokens).toBe("number");
152+
expect(typeof response.usage.totalTokens).toBe("number");
153+
expect(response.usage.totalTokens).toBeGreaterThan(0);
154+
}
155+
}
156+
});
157+
});
158+
});

0 commit comments

Comments
 (0)