Skip to content

Commit a3f7af0

Browse files
committed
merge
2 parents 7864891 + 0043f72 commit a3f7af0

File tree

6 files changed

+80
-162
lines changed

6 files changed

+80
-162
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: 'Validate SDK'
2+
description: 'Run build, typecheck, and tests for the SDK'
3+
4+
runs:
5+
using: 'composite'
6+
steps:
7+
- name: Setup Node.js
8+
uses: actions/setup-node@v4
9+
with:
10+
node-version: '22'
11+
cache: 'npm'
12+
13+
- name: Install dependencies
14+
shell: bash
15+
run: npm install
16+
17+
- name: Build SDK
18+
shell: bash
19+
run: npm run build
20+
21+
- name: Typecheck tests directory
22+
shell: bash
23+
run: npx tsc --noEmit --skipLibCheck --esModuleInterop --moduleResolution node --module esnext --target es2020 'tests/**/*.ts'
24+
25+
- name: Install examples dependencies
26+
shell: bash
27+
working-directory: examples
28+
run: npm install
29+
30+
- name: Typecheck examples root
31+
shell: bash
32+
working-directory: examples
33+
run: npx tsc --noEmit --skipLibCheck --esModuleInterop --moduleResolution node --module esnext --target es2020 '*.ts'
34+
35+
- name: Install nextjs-example dependencies
36+
shell: bash
37+
working-directory: examples/nextjs-example
38+
run: npm install
39+
40+
- name: Typecheck nextjs-example
41+
shell: bash
42+
working-directory: examples/nextjs-example
43+
run: npx tsc --noEmit
44+
45+
- name: Run tests
46+
shell: bash
47+
run: npm test
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
name: PR Validation
2+
3+
on:
4+
pull_request:
5+
paths-ignore:
6+
- .speakeasy/in.openapi.yaml
7+
8+
jobs:
9+
validate:
10+
uses: ./.github/workflows/validation-checks.yaml

.github/workflows/speakeasy_run_on_pr.yaml

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -30,36 +30,8 @@ jobs:
3030
- name: Run Speakeasy
3131
run: speakeasy run
3232

33-
- name: Setup Node.js
34-
uses: actions/setup-node@v4
35-
with:
36-
node-version: '22'
37-
cache: 'npm'
38-
39-
- name: Install dependencies
40-
run: npm install
41-
42-
- name: Build SDK
43-
run: npm run build
44-
45-
- name: Typecheck tests directory
46-
run: npx tsc --noEmit --skipLibCheck --esModuleInterop --moduleResolution node --module esnext --target es2020 'tests/**/*.ts'
47-
48-
- name: Install examples dependencies
49-
working-directory: examples
50-
run: npm install
51-
52-
- name: Typecheck examples root
53-
working-directory: examples
54-
run: npx tsc --noEmit --skipLibCheck --esModuleInterop --moduleResolution node --module esnext --target es2020 '*.ts'
55-
56-
- name: Install nextjs-example dependencies
57-
working-directory: examples/nextjs-example
58-
run: npm install
59-
60-
- name: Typecheck nextjs-example
61-
working-directory: examples/nextjs-example
62-
run: npx tsc --noEmit
33+
- name: Validate SDK
34+
uses: ./.github/actions/validate-sdk
6335

6436
- name: Commit changes
6537
run: |
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
name: Validation Checks
2+
3+
on:
4+
workflow_call:
5+
6+
jobs:
7+
validate:
8+
runs-on: ubuntu-latest
9+
steps:
10+
- name: Checkout code
11+
uses: actions/checkout@v4
12+
13+
- name: Validate SDK
14+
uses: ./.github/actions/validate-sdk

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,10 @@
5555
"scripts": {
5656
"lint": "eslint --cache --max-warnings=0 src",
5757
"build": "tsc",
58-
"prepublishOnly": "npm run build"
58+
"prepublishOnly": "npm run build",
59+
"test": "vitest run",
60+
"test:e2e": "vitest run tests/e2e",
61+
"test:watch": "vitest"
5962
},
6063
"peerDependencies": {
6164
"@tanstack/react-query": "^5",

tests/e2e/chat.test.ts

Lines changed: 3 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { beforeAll, describe, expect, it } from "vitest";
22
import { OpenRouter } from "../../src/sdk/sdk.js";
3-
import { ChatError } from "../../src/models/errors/chaterror.js";
43

54
describe("Chat E2E Tests", () => {
65
let client: OpenRouter;
@@ -115,6 +114,7 @@ describe("Chat E2E Tests", () => {
115114
const chunks: any[] = [];
116115

117116
for await (const chunk of response) {
117+
expect(chunk).toBeDefined();
118118
chunks.push(chunk);
119119
}
120120

@@ -154,7 +154,7 @@ describe("Chat E2E Tests", () => {
154154

155155
expect(chunkCount).toBeGreaterThan(0);
156156
expect(fullContent.length).toBeGreaterThan(0);
157-
});
157+
}, 10000)
158158

159159
it("should include finish_reason in final chunk", async () => {
160160
const response = await client.chat.send({
@@ -181,134 +181,6 @@ describe("Chat E2E Tests", () => {
181181
}
182182

183183
expect(foundFinishReason).toBe(true);
184-
});
185-
});
186-
187-
describe("Error Handling", () => {
188-
it("should throw ErrorResponse with 401 status code for invalid API key", async () => {
189-
const invalidClient = new OpenRouter({
190-
apiKey: "invalid-api-key-12345",
191-
});
192-
193-
try {
194-
await invalidClient.chat.send({
195-
model: "meta-llama/llama-3.2-1b-instruct",
196-
messages: [
197-
{
198-
role: "user",
199-
content: "Hello",
200-
},
201-
],
202-
stream: false,
203-
});
204-
205-
// If we reach here, the test should fail
206-
expect.fail("Expected an error to be thrown for invalid API key");
207-
} catch (error) {
208-
// Verify it's an ErrorResponse
209-
expect(error).toBeInstanceOf(ChatError);
210-
211-
if (error instanceof ChatError) {
212-
// Verify status code is 401 (Unauthorized)
213-
expect(error.statusCode).toBe(401);
214-
215-
// Verify error structure
216-
expect(error.error).toBeDefined();
217-
expect(error.error.code).toBe(401);
218-
expect(error.error.message).toBeDefined();
219-
expect(typeof error.error.message).toBe("string");
220-
221-
// Verify the error message contains relevant information
222-
expect(error.message.toLowerCase()).toMatch(/invalid|unauthorized|api key/i);
223-
}
224-
}
225-
});
226-
227-
it("should throw ErrorResponse with 400 status code for invalid model", async () => {
228-
try {
229-
await client.chat.send({
230-
model: "this-model-does-not-exist/invalid-model-name-12345",
231-
messages: [
232-
{
233-
role: "user",
234-
content: "Hello",
235-
},
236-
],
237-
stream: false,
238-
});
239-
240-
// If we reach here, the test should fail
241-
expect.fail("Expected an error to be thrown for invalid model");
242-
} catch (error) {
243-
// Verify it's an ErrorResponse
244-
expect(error).toBeInstanceOf(ChatError);
245-
246-
if (error instanceof ChatError) {
247-
// Verify status code is 400 (Bad Request)
248-
expect(error.statusCode).toBe(400);
249-
250-
// Verify error structure
251-
expect(error.error).toBeDefined();
252-
expect(error.error.code).toBe(400);
253-
expect(error.error.message).toBeDefined();
254-
expect(typeof error.error.message).toBe("string");
255-
256-
// Verify the error message contains relevant information about invalid model
257-
expect(error.message.toLowerCase()).toMatch(/model|invalid|not found/i);
258-
}
259-
}
260-
});
261-
262-
it("should throw ErrorResponse with proper structure for invalid model in streaming mode", async () => {
263-
await expect(async () => {
264-
const response = await client.chat.send({
265-
model: "this-model-does-not-exist/invalid-model-name-streaming",
266-
messages: [
267-
{
268-
role: "user",
269-
content: "Hello",
270-
},
271-
],
272-
stream: true,
273-
});
274-
275-
// Consume the stream - error may be thrown here or during iteration
276-
for await (const _chunk of response) {
277-
// If we get chunks, that's unexpected
278-
}
279-
}).rejects.toThrow();
280-
281-
// Now test the actual error details
282-
try {
283-
const response = await client.chat.send({
284-
model: "this-model-does-not-exist/invalid-model-name-streaming",
285-
messages: [
286-
{
287-
role: "user",
288-
content: "Hello",
289-
},
290-
],
291-
stream: true,
292-
});
293-
294-
for await (const _chunk of response) {
295-
// Continue consuming stream
296-
}
297-
} catch (error) {
298-
// Verify it's an ErrorResponse
299-
expect(error).toBeInstanceOf(ChatError);
300-
301-
if (error instanceof ChatError) {
302-
// Verify status code is 400 (Bad Request)
303-
expect(error.statusCode).toBe(400);
304-
305-
// Verify error structure
306-
expect(error.error).toBeDefined();
307-
expect(error.error.code).toBe(400);
308-
expect(error.error.message).toBeDefined();
309-
expect(typeof error.error.message).toBe("string");
310-
}
311-
}
312-
});
184+
}, 10000)
313185
});
314186
});

0 commit comments

Comments
 (0)