Skip to content

Commit eb00860

Browse files
committed
allow additional arguments to feature functions
1 parent 419cd29 commit eb00860

3 files changed

Lines changed: 117 additions & 4 deletions

File tree

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2+
3+
exports[`allows additional arguments 1`] = `
4+
[
5+
Node {
6+
"argument": "foo",
7+
"arguments": [
8+
Node {
9+
"end": 20,
10+
"raw": ""foo"",
11+
"start": 15,
12+
"type": "Literal",
13+
"value": "foo",
14+
},
15+
Node {
16+
"end": 57,
17+
"properties": [
18+
Node {
19+
"computed": false,
20+
"end": 56,
21+
"key": Node {
22+
"end": 28,
23+
"name": "since",
24+
"start": 23,
25+
"type": "Identifier",
26+
},
27+
"kind": "init",
28+
"method": false,
29+
"shorthand": false,
30+
"start": 23,
31+
"type": "Property",
32+
"value": Node {
33+
"end": 56,
34+
"raw": ""2021-01-01T12:34:56.789Z"",
35+
"start": 30,
36+
"type": "Literal",
37+
"value": "2021-01-01T12:34:56.789Z",
38+
},
39+
},
40+
],
41+
"start": 22,
42+
"type": "ObjectExpression",
43+
},
44+
],
45+
"callee": Node {
46+
"end": 14,
47+
"name": "DatabaseClient",
48+
"start": 0,
49+
"type": "Identifier",
50+
},
51+
"end": 58,
52+
"optional": false,
53+
"start": 0,
54+
"type": "CallExpression",
55+
},
56+
]
57+
`;
58+
59+
exports[`finds databases 1`] = `
60+
[
61+
Node {
62+
"argument": "foo",
63+
"arguments": [
64+
Node {
65+
"end": 20,
66+
"raw": ""foo"",
67+
"start": 15,
68+
"type": "Literal",
69+
"value": "foo",
70+
},
71+
],
72+
"callee": Node {
73+
"end": 14,
74+
"name": "DatabaseClient",
75+
"start": 0,
76+
"type": "Identifier",
77+
},
78+
"end": 21,
79+
"optional": false,
80+
"start": 0,
81+
"type": "CallExpression",
82+
},
83+
]
84+
`;

src/javascript/databases.test.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import {expect, test} from "vitest";
2+
import {parseJavaScript} from "./parse.js";
3+
import type {FeatureExpression} from "./features.js";
4+
5+
function find(input: string): FeatureExpression[] {
6+
return parseJavaScript(input).databases;
7+
}
8+
9+
test("finds databases", () => {
10+
expect(find(`DatabaseClient("foo")`)).toMatchSnapshot();
11+
});
12+
13+
test("allows additional arguments", () => {
14+
expect(find(`DatabaseClient("foo", {since: "2021-01-01T12:34:56.789Z"})`)).toMatchSnapshot();
15+
});
16+
17+
test("disallows dynamic arguments", () => {
18+
expect(() => find(`DatabaseClient("foo" + bar)`)).toThrow(/literal string/);
19+
});
20+
21+
test("ignores shadowed references", () => {
22+
expect(find(`const DatabaseClient = () => {};\nDatabaseClient("foo");`)).toStrictEqual([]);
23+
expect(find(`DatabaseClient("foo");\nconst DatabaseClient = () => {};`)).toStrictEqual([]);
24+
expect(find(`DatabaseClient("foo");\nvar DatabaseClient = () => {};`)).toStrictEqual([]);
25+
expect(find(`function DatabaseClient() {}\nDatabaseClient("foo");`)).toStrictEqual([]);
26+
expect(find(`function DatabaseClient() {}\nDatabaseClient("foo" + Math.random());`)).toStrictEqual([]); // prettier-ignore
27+
});
28+
29+
test("ignores aliased references", () => {
30+
expect(find(`const D = DatabaseClient;\nD("foo");`)).toStrictEqual([]);
31+
});

src/javascript/features.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,8 @@ export function findFeatures(name: string, body: Node, input: string): FeatureEx
2020
CallExpression(node) {
2121
const {callee} = node;
2222
if (callee.type !== "Identifier" || !references.has(callee)) return;
23-
const args = node.arguments;
24-
if (args.length !== 1) throw syntaxError(`${name} requires a single literal string argument`, node, input); // prettier-ignore
25-
const [arg] = args;
26-
if (!isStringLiteral(arg)) throw syntaxError(`${name} requires a single literal string argument`, node, input); // prettier-ignore
23+
const [arg] = node.arguments;
24+
if (!arg || !isStringLiteral(arg)) throw syntaxError(`${name} requires a literal string argument`, node, input); // prettier-ignore
2725
calls.push(Object.assign(node, {argument: getStringLiteralValue(arg)}));
2826
}
2927
});

0 commit comments

Comments
 (0)