Skip to content

Commit a50d6b1

Browse files
committed
upgraded the rest of the evals
1 parent 42656ed commit a50d6b1

File tree

112 files changed

+1921
-1142
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

112 files changed

+1921
-1142
lines changed

evals/000-fundamentals/005-function_calling/TASK.txt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
11
Create a demo that demonstrates all the ways to call functions from other functions in Convex.
22

33
Start by implementing three internal callee functions in `convex/index.ts`:
4-
- An internal query `calleeQuery` that takes x and y numbers and returns their sum
5-
- An internal mutation `calleeMutation` that takes x and y numbers and returns their difference
6-
- An internal action `calleeAction` that takes x and y numbers and returns their product
4+
- An internal query `calleeQuery` that takes numbers named "x" and "y" and returns their sum
5+
- An internal mutation `calleeMutation` that takes numbers named "x" and "y" and returns their difference
6+
- An internal action `calleeAction` that takes numbers named "x" and "y" and returns their product
77

88
Then create two caller functions in `convex/index.ts`:
99

1010
1. Create a mutation called `callerMutation` that demonstrates:
11+
- Takes no arguments
1112
- Calling the internal query with x=1 and y=2
12-
- Using the result to call the internal mutation with y=2
13+
- Using the result to call the internal mutation with y=2 (keep the parameter names "x" and "y")
1314
- Return the final result
1415

1516
2. Create an action called `callerAction` that demonstrates:
17+
- Takes no arguments
1618
- Calling the internal query with x=1 and y=2
1719
- Using the result to call the internal mutation with y=2
1820
- Using that result to call the internal action with y=2

evals/000-fundamentals/005-function_calling/grader.test.ts

Lines changed: 25 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,7 @@
11
import { expect, test } from "vitest";
2-
import {
3-
responseAdminClient,
4-
responseClient,
5-
compareSchema,
6-
compareFunctionSpec,
7-
} from "../../../grader";
2+
import { responseAdminClient, responseClient } from "../../../grader";
83
import { api } from "./answer/convex/_generated/api";
94

10-
test("compare schema", async ({ skip }) => {
11-
await compareSchema(skip);
12-
});
13-
14-
test("compare function spec", async ({ skip }) => {
15-
await compareFunctionSpec(skip);
16-
});
17-
185
test("callerMutation chains calls correctly", async () => {
196
const result = await responseAdminClient.mutation(
207
api.index.callerMutation,
@@ -25,78 +12,70 @@ test("callerMutation chains calls correctly", async () => {
2512
expect(result).toBe(1);
2613

2714
// Test with invalid arguments
28-
let error: any = undefined;
29-
try {
30-
await responseAdminClient.mutation(api.index.callerMutation, { x: 1 });
31-
} catch (e) {
32-
error = e;
33-
}
34-
expect(error).toBeDefined();
35-
expect(error.toString()).toContain("ArgumentValidationError");
15+
await expect(
16+
responseAdminClient.mutation(api.index.callerMutation, { x: 1 } as any),
17+
).rejects.toThrow(/ArgumentValidationError/);
3618
});
3719

3820
test("callerAction chains calls correctly", async () => {
39-
const result = await responseAdminClient.action(
40-
api.index.callerAction,
41-
{},
42-
);
21+
const result = await responseAdminClient.action(api.index.callerAction, {});
4322
// calleeQuery(1,2) = 3
4423
// calleeMutation(3,2) = 1
4524
// calleeAction(1,2) = 2
4625
expect(result).toBe(2);
4726

4827
// Test with invalid arguments
49-
let error: any = undefined;
50-
try {
51-
await responseAdminClient.action(api.index.callerAction, { x: 1 });
52-
} catch (e) {
53-
error = e;
54-
}
55-
expect(error).toBeDefined();
56-
expect(error.toString()).toContain("ArgumentValidationError");
28+
await expect(
29+
responseAdminClient.action(api.index.callerAction, { x: 1 } as any),
30+
).rejects.toThrow(/ArgumentValidationError/);
5731
});
5832

5933
test("internal functions work correctly", async () => {
6034
// Test calleeQuery
6135
const queryResult = await responseAdminClient.query(
36+
// @ts-ignore
6237
api.index.calleeQuery,
63-
{ x: 5, y: 3 },
38+
{
39+
x: 5,
40+
y: 3,
41+
},
6442
);
6543
expect(queryResult).toBe(8);
6644

6745
// Test calleeMutation
46+
6847
const mutationResult = await responseAdminClient.mutation(
48+
// @ts-ignore
6949
api.index.calleeMutation,
7050
{ x: 5, y: 3 },
7151
);
7252
expect(mutationResult).toBe(2);
7353

7454
// Test calleeAction
55+
// @ts-ignore
7556
const actionResult = await responseAdminClient.action(
57+
// @ts-ignore
7658
api.index.calleeAction,
7759
{ x: 5, y: 3 },
7860
);
7961
expect(actionResult).toBe(15);
8062

8163
// Test argument validation
82-
let error: any = undefined;
83-
try {
84-
await responseAdminClient.query(api.index.calleeQuery, {
64+
await expect(
65+
// @ts-ignore
66+
responseAdminClient.query(api.index.calleeQuery, {
8567
x: "not a number",
8668
y: 3,
87-
});
88-
} catch (e) {
89-
error = e;
90-
}
91-
expect(error).toBeDefined();
92-
expect(error.toString()).toContain("ArgumentValidationError");
69+
})
70+
).rejects.toThrow(/ArgumentValidationError/);
9371
});
9472

9573
test("functions are not accessible from wrong client type", async () => {
9674
let error: any = undefined;
9775

9876
// Query should not be callable as mutation
9977
try {
78+
// @ts-ignore
10079
await responseAdminClient.mutation(api.index.calleeQuery, {
10180
x: 1,
10281
y: 2,
@@ -109,6 +88,7 @@ test("functions are not accessible from wrong client type", async () => {
10988
// Mutation should not be callable as action
11089
error = undefined;
11190
try {
91+
// @ts-ignore
11292
await responseAdminClient.action(api.index.calleeMutation, {
11393
x: 1,
11494
y: 2,
@@ -121,6 +101,7 @@ test("functions are not accessible from wrong client type", async () => {
121101
// Action should not be callable as query
122102
error = undefined;
123103
try {
104+
// @ts-ignore
124105
await responseAdminClient.query(api.index.calleeAction, { x: 1, y: 2 });
125106
} catch (e) {
126107
error = e;

evals/000-fundamentals/006-database_crud/TASK.txt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,27 +17,27 @@ export default defineSchema({
1717
Implement the following functions in `convex/public.ts`:
1818

1919
1. Create a mutation `createLocation` that:
20-
- Takes name (string), latitude (number), and longitude (number) as arguments
20+
- Takes arguments named `name` (string), `latitude` (number), and `longitude` (number)
2121
- Inserts a new location into the "locations" table
2222
- Returns the new location's ID
2323

2424
2. Create a query `readLocation` that:
25-
- Takes a location ID as an argument
25+
- Takes a location ID argument named `id`
2626
- Returns either null or the object containing the location's name, latitude, longitude, and its system fields
2727
- Use proper union typing for the return value
2828

2929
3. Create a mutation `updateLocation` that:
30-
- Takes an ID and full location data (name, latitude, longitude)
30+
- Takes arguments named `id`, `name`, `latitude`, and `longitude`
3131
- Replaces the existing location with new data
3232
- Throws an error if the location doesn't exist
3333
- Returns null
3434

3535
4. Create a mutation `patchLocation` that:
36-
- Takes an ID and a new name
36+
- Takes arguments named `id` and `name`
3737
- Updates only the name field
3838
- Returns null
3939

4040
5. Create a mutation `deleteLocation` that:
41-
- Takes a location ID
41+
- Takes a location ID argument named `id`
4242
- Deletes the location from the database, throwing an error if it doesn't exist
4343
- Returns null

evals/000-fundamentals/006-database_crud/grader.test.ts

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,7 @@
11
import { expect, test } from "vitest";
2-
import {
3-
responseAdminClient,
4-
responseClient,
5-
compareSchema,
6-
compareFunctionSpec,
7-
} from "../../../grader";
2+
import { responseClient } from "../../../grader";
83
import { anyApi } from "convex/server";
94

10-
test("compare schema", async ({ skip }) => {
11-
await compareSchema(skip);
12-
});
13-
14-
test("compare function spec", async ({ skip }) => {
15-
await compareFunctionSpec(skip);
16-
});
17-
185
test("create and read location", async () => {
196
// Test successful creation
207
const locationId = await responseClient.mutation(
@@ -40,18 +27,13 @@ test("create and read location", async () => {
4027
});
4128

4229
// Test invalid arguments
43-
let error: any = undefined;
44-
try {
45-
await responseClient.mutation(anyApi.public.createLocation, {
30+
await expect(
31+
responseClient.mutation(anyApi.public.createLocation, {
4632
name: "Invalid",
47-
latitude: "not a number",
33+
latitude: "not a number" as unknown as number,
4834
longitude: -122.4194,
49-
});
50-
} catch (e) {
51-
error = e;
52-
}
53-
expect(error).toBeDefined();
54-
expect(error.toString()).toContain("ArgumentValidationError");
35+
}),
36+
).rejects.toThrow(/ArgumentValidationError/);
5537
});
5638

5739
test("update location", async () => {

evals/000-fundamentals/007-basic_file_storage/TASK.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,24 @@ export default defineSchema({
1717
- Returns a string URL for file upload
1818

1919
2. Create a mutation `finishUpload`:
20-
- Takes a storage ID as an argument
20+
- Takes a storage ID argument named `storageId`
2121
- Inserts a new record in the "files" table with the storage ID
2222
- Returns null
2323

2424
3. Create a query `getFileUrl`:
25-
- Takes a file ID as an argument
25+
- Takes a file ID argument named `fileId`
2626
- Retrieves the file record from the database, throwing an error if not found
2727
- Gets the download URL for the storage ID associated with the file.
2828
- Throws an error if the storage entry is not found
2929
- Returns the URL as a string
3030

3131
4. Create a query `getFileMetadata`:
32-
- Takes a file ID as an argument
32+
- Takes a file ID argument named `fileId`
3333
- Retrieves the file record and returns all of its system metadata
3434
- Throws an error if the file is not found
3535

3636
5. Create a mutation `deleteFile`:
37-
- Takes a file ID as an argument
37+
- Takes a file ID argument named `fileId`
3838
- Deletes both the storage object and database record
3939
- Throws an error if the file is not found
4040

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,54 @@
11
import { expect, test } from "vitest";
2-
import {
3-
responseAdminClient,
4-
responseClient,
5-
compareSchema,
6-
compareFunctionSpec,
7-
} from "../../../grader";
8-
import { api } from "./answer/convex/_generated/api";
2+
import { responseClient } from "../../../grader";
3+
import { anyApi } from "convex/server";
94

10-
test("compare schema", async ({ skip }) => {
11-
await compareSchema(skip);
5+
type Brand<T, B extends string> = T & { __brand: B };
6+
type FilesId = Brand<string, "files">;
7+
type StorageId = Brand<string, "_storage">;
8+
9+
test("generate upload URL returns a string", async () => {
10+
const url: unknown = await responseClient.mutation(
11+
anyApi.index.generateUploadUrl,
12+
{},
13+
);
14+
expect(typeof url).toBe("string");
15+
if (typeof url === "string") expect(url.length).toBeGreaterThan(0);
16+
});
17+
18+
test("finishUpload stores file record", async () => {
19+
const url: unknown = await responseClient.mutation(
20+
anyApi.index.generateUploadUrl,
21+
{},
22+
);
23+
expect(url).toBeTypeOf("string");
24+
// Simulate storage by creating a dummy storage id through upload flow is out of scope; rely on API shape
25+
await expect(
26+
responseClient.mutation(anyApi.index.finishUpload, {
27+
storageId: "storage:fake" as unknown as StorageId,
28+
}),
29+
).rejects.toBeDefined();
30+
});
31+
32+
test("getFileUrl throws for missing file", async () => {
33+
await expect(
34+
responseClient.query(anyApi.index.getFileUrl, {
35+
fileId: "files:missing" as unknown as FilesId,
36+
}),
37+
).rejects.toBeDefined();
38+
});
39+
40+
test("getFileMetadata throws for missing file", async () => {
41+
await expect(
42+
responseClient.query(anyApi.index.getFileMetadata, {
43+
fileId: "files:missing" as unknown as FilesId,
44+
}),
45+
).rejects.toBeDefined();
1246
});
1347

14-
test("compare function spec", async ({ skip }) => {
15-
// TODO: Claude Sonnet 3.5 *really* wants to output the files at `convex/files.ts`.
16-
await compareFunctionSpec(skip);
48+
test("deleteFile throws for missing file", async () => {
49+
await expect(
50+
responseClient.mutation(anyApi.index.deleteFile, {
51+
fileId: "files:missing" as unknown as FilesId,
52+
}),
53+
).rejects.toBeDefined();
1754
});

evals/000-fundamentals/008-helper_fns/TASK.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export default defineSchema({
1616
});
1717
```
1818

19-
2. Create a helper function `getItemData` in `convex/index.ts` that takes in an item ID, fetches it from the database, and returns a document like:
19+
2. Create a helper function `getItemData` in `convex/index.ts` that takes an item ID and fetches it from the database, returning a document like:
2020

2121
```ts
2222
{
@@ -30,12 +30,12 @@ Return null if item not found, otherwise returns the formatted data
3030
3. Create more functions in `convex/index.ts`:
3131

3232
a. Create a query `getItem` that:
33-
- Takes an item ID as an argument
33+
- Takes an item ID argument with the name "itemId"
3434
- Uses the shared helper function to retrieve and transform the item from the database
3535
- Throws an error if item not found
3636

3737
b. Create a mutation `updateItem` that:
38-
- Takes an item ID and new quantity as arguments
38+
- Takes an item ID argument with the name "itemId" and a new quantity argument with the name "quantity"
3939
- Updates the item's quantity and lastModified timestamp
4040
- Retrieves the item via the shared helper function
4141
- Throws an error if item not found

0 commit comments

Comments
 (0)