Skip to content

Commit 0efcfeb

Browse files
NicolappsConvex, Inc.
authored andcommitted
eslint: Add tests for no-args-without-validator (#41743)
GitOrigin-RevId: c87c53cd24e25e0babf78ceabeeb519ae8f4e1df
1 parent 08f3241 commit 0efcfeb

File tree

1 file changed

+209
-0
lines changed

1 file changed

+209
-0
lines changed
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
import { RuleTester } from "@typescript-eslint/rule-tester";
2+
import { noMissingArgs } from "../lib/noMissingArgs.js";
3+
4+
const ruleTester = new RuleTester({
5+
languageOptions: {
6+
parserOptions: {
7+
ecmaVersion: 2020,
8+
sourceType: "module",
9+
projectService: {
10+
allowDefaultProject: ["*.ts*", "convex/*.ts*"],
11+
},
12+
},
13+
},
14+
});
15+
16+
ruleTester.run("no-args-without-validator", noMissingArgs, {
17+
valid: [
18+
// Query with args
19+
{
20+
code: `
21+
import { v } from "convex/values";
22+
import { query } from "./_generated/server";
23+
export const list = query({
24+
args: { limit: v.number() },
25+
handler: async (ctx, { limit }) => {
26+
return await ctx.db.query("messages").take(limit);
27+
},
28+
});
29+
`,
30+
filename: "convex/messages.ts",
31+
},
32+
// Query with empty args object
33+
{
34+
code: `
35+
import { v } from "convex/values";
36+
import { query } from "./_generated/server";
37+
export const list = query({
38+
args: {},
39+
handler: async (ctx, {}) => {
40+
return await ctx.db.query("messages").collect();
41+
},
42+
});
43+
`,
44+
filename: "convex/messages.ts",
45+
},
46+
// Query with empty args
47+
{
48+
code: `
49+
import { v } from "convex/values";
50+
import { query } from "./_generated/server";
51+
export const list = query(async (ctx, {}) => {
52+
return await ctx.db.query("messages").collect();
53+
});
54+
`,
55+
filename: "convex/messages.ts",
56+
},
57+
// Query with no args
58+
{
59+
code: `
60+
import { v } from "convex/values";
61+
import { query } from "./_generated/server";
62+
export const list = query(async (ctx) => {
63+
return await ctx.db.query("messages").collect();
64+
});
65+
`,
66+
filename: "convex/messages.ts",
67+
},
68+
// Mutation with args
69+
{
70+
code: `
71+
import { v } from "convex/values";
72+
import { mutation } from "./_generated/server";
73+
export const send = mutation({
74+
args: { body: v.string(), author: v.string() },
75+
handler: async (ctx, { body, author }) => {
76+
const message = { body, author };
77+
await ctx.db.insert("messages", message);
78+
},
79+
});
80+
`,
81+
filename: "convex/messages.ts",
82+
},
83+
// Action with args using v.any()
84+
{
85+
code: `
86+
import { v } from "convex/values";
87+
import { action } from "./_generated/server";
88+
export const fetchData = action({
89+
args: { url: v.string(), params: v.any() },
90+
handler: async (ctx, { url, params }) => {
91+
// ... action logic
92+
},
93+
});
94+
`,
95+
filename: "convex/actions.ts",
96+
},
97+
],
98+
invalid: [
99+
// Missing args in mutation with second parameter - should NOT be autofixable
100+
{
101+
code: `
102+
import { mutation } from "./_generated/server";
103+
export const send = mutation({
104+
handler: async (ctx, { body, author }) => {
105+
const message = { body, author };
106+
await ctx.db.insert("messages", message);
107+
},
108+
});
109+
`,
110+
errors: [
111+
{
112+
messageId: "missing-args",
113+
},
114+
],
115+
filename: "convex/messages.ts",
116+
},
117+
// Missing args in action with second parameter - should NOT be autofixable
118+
{
119+
code: `
120+
import { action } from "./_generated/server";
121+
export const fetchData = action({
122+
handler: async (ctx, { url }) => {
123+
// ... action logic
124+
},
125+
});
126+
`,
127+
errors: [
128+
{
129+
messageId: "missing-args",
130+
},
131+
],
132+
filename: "convex/actions.ts",
133+
},
134+
// Missing args in simple function with no second parameter - should be autofixable
135+
{
136+
code: `
137+
import { action } from "./_generated/server";
138+
139+
export const nop = action({
140+
handler: async () => {}
141+
});
142+
143+
/**
144+
* This function is not source-mappable by our current analyze because this file
145+
* include a helper function used in another entry point. That makes the bundler
146+
* stick both of these functions in deps/ file and makes this file just a
147+
* re-export of that nop function.
148+
*/
149+
150+
export function helper(a: number, b: number): number {
151+
return a + b;
152+
}
153+
`,
154+
errors: [
155+
{
156+
messageId: "missing-empty-args",
157+
},
158+
],
159+
output: `
160+
import { action } from "./_generated/server";
161+
162+
export const nop = action({
163+
args: {},
164+
165+
handler: async () => {}
166+
});
167+
168+
/**
169+
* This function is not source-mappable by our current analyze because this file
170+
* include a helper function used in another entry point. That makes the bundler
171+
* stick both of these functions in deps/ file and makes this file just a
172+
* re-export of that nop function.
173+
*/
174+
175+
export function helper(a: number, b: number): number {
176+
return a + b;
177+
}
178+
`,
179+
filename: "convex/helpers.ts",
180+
},
181+
// Additional test for a function with handler and only ctx parameter
182+
{
183+
code: `
184+
import { query } from "./_generated/server";
185+
export const listMessages = query({
186+
handler: async (ctx) => {
187+
return await ctx.db.query("messages").collect();
188+
}
189+
});
190+
`,
191+
errors: [
192+
{
193+
messageId: "missing-empty-args",
194+
},
195+
],
196+
output: `
197+
import { query } from "./_generated/server";
198+
export const listMessages = query({
199+
args: {},
200+
201+
handler: async (ctx) => {
202+
return await ctx.db.query("messages").collect();
203+
}
204+
});
205+
`,
206+
filename: "convex/messages.ts",
207+
},
208+
],
209+
});

0 commit comments

Comments
 (0)