@nudojs/parser 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +31 -0
- package/LICENSE +21 -0
- package/README.md +25 -0
- package/dist/index.d.ts +51 -7
- package/dist/index.js +337 -14603
- package/package.json +24 -2
- package/src/__tests__/directives-inline.test.ts +95 -0
- package/src/__tests__/directives-phase3.test.ts +0 -18
- package/src/__tests__/directives.test.ts +285 -3
- package/src/__tests__/mock-directive.test.ts +115 -0
- package/src/__tests__/sinon-directive.test.ts +200 -0
- package/src/directives.ts +458 -16
- package/src/index.ts +11 -1
- package/src/parse.ts +12 -7
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { parse, extractDirectives, type MockDirective } from "../index.ts";
|
|
3
|
+
|
|
4
|
+
describe("Sinon Expression Support", () => {
|
|
5
|
+
describe("sinon.stub()", () => {
|
|
6
|
+
it("parses sinon.stub()", () => {
|
|
7
|
+
const code = `
|
|
8
|
+
// @nudo:mock fetch = sinon.stub()
|
|
9
|
+
function getData() {
|
|
10
|
+
return fetch("/api/data");
|
|
11
|
+
}
|
|
12
|
+
`;
|
|
13
|
+
const ast = parse(code);
|
|
14
|
+
const directives = extractDirectives(ast);
|
|
15
|
+
expect(directives.length).toBe(1);
|
|
16
|
+
|
|
17
|
+
const mockDirectives = directives[0].directives.filter(
|
|
18
|
+
(d): d is MockDirective => d.kind === "mock"
|
|
19
|
+
);
|
|
20
|
+
expect(mockDirectives.length).toBe(1);
|
|
21
|
+
expect(mockDirectives[0].name).toBe("fetch");
|
|
22
|
+
expect(mockDirectives[0].sinonExpr).toBeDefined();
|
|
23
|
+
expect(mockDirectives[0].sinonExpr!.type).toBe("stub");
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("parses sinon.stub().returns()", () => {
|
|
27
|
+
const code = `
|
|
28
|
+
// @nudo:mock fetch = sinon.stub().returns({ data: "test" })
|
|
29
|
+
function getData() {
|
|
30
|
+
return fetch("/api/data");
|
|
31
|
+
}
|
|
32
|
+
`;
|
|
33
|
+
const ast = parse(code);
|
|
34
|
+
const directives = extractDirectives(ast);
|
|
35
|
+
const mockDirectives = directives[0].directives.filter(
|
|
36
|
+
(d): d is MockDirective => d.kind === "mock"
|
|
37
|
+
);
|
|
38
|
+
expect(mockDirectives[0].sinonExpr).toBeDefined();
|
|
39
|
+
expect(mockDirectives[0].sinonExpr!.type).toBe("stub");
|
|
40
|
+
expect(mockDirectives[0].sinonExpr!.returnValue).toBeDefined();
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it("parses sinon.stub().resolves()", () => {
|
|
44
|
+
const code = `
|
|
45
|
+
// @nudo:mock fetch = sinon.stub().resolves({ data: "test" })
|
|
46
|
+
function getData() {
|
|
47
|
+
return fetch("/api/data");
|
|
48
|
+
}
|
|
49
|
+
`;
|
|
50
|
+
const ast = parse(code);
|
|
51
|
+
const directives = extractDirectives(ast);
|
|
52
|
+
const mockDirectives = directives[0].directives.filter(
|
|
53
|
+
(d): d is MockDirective => d.kind === "mock"
|
|
54
|
+
);
|
|
55
|
+
expect(mockDirectives[0].sinonExpr).toBeDefined();
|
|
56
|
+
expect(mockDirectives[0].sinonExpr!.type).toBe("stub");
|
|
57
|
+
expect(mockDirectives[0].sinonExpr!.resolvedValue).toBeDefined();
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it("parses sinon.stub().rejects()", () => {
|
|
61
|
+
const code = `
|
|
62
|
+
// @nudo:mock fetch = sinon.stub().rejects(new Error("fail"))
|
|
63
|
+
function getData() {
|
|
64
|
+
return fetch("/api/data");
|
|
65
|
+
}
|
|
66
|
+
`;
|
|
67
|
+
const ast = parse(code);
|
|
68
|
+
const directives = extractDirectives(ast);
|
|
69
|
+
const mockDirectives = directives[0].directives.filter(
|
|
70
|
+
(d): d is MockDirective => d.kind === "mock"
|
|
71
|
+
);
|
|
72
|
+
expect(mockDirectives[0].sinonExpr).toBeDefined();
|
|
73
|
+
expect(mockDirectives[0].sinonExpr!.type).toBe("stub");
|
|
74
|
+
expect(mockDirectives[0].sinonExpr!.rejectedValue).toBeDefined();
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
describe("sinon.spy()", () => {
|
|
79
|
+
it("parses sinon.spy()", () => {
|
|
80
|
+
const code = `
|
|
81
|
+
// @nudo:mock handler = sinon.spy()
|
|
82
|
+
function processEvent(handler) {
|
|
83
|
+
handler("event");
|
|
84
|
+
}
|
|
85
|
+
`;
|
|
86
|
+
const ast = parse(code);
|
|
87
|
+
const directives = extractDirectives(ast);
|
|
88
|
+
const mockDirectives = directives[0].directives.filter(
|
|
89
|
+
(d): d is MockDirective => d.kind === "mock"
|
|
90
|
+
);
|
|
91
|
+
expect(mockDirectives[0].sinonExpr).toBeDefined();
|
|
92
|
+
expect(mockDirectives[0].sinonExpr!.type).toBe("spy");
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
describe("sinon.mock()", () => {
|
|
97
|
+
it("parses sinon.mock()", () => {
|
|
98
|
+
const code = `
|
|
99
|
+
// @nudo:mock service = sinon.mock()
|
|
100
|
+
function useService(service) {
|
|
101
|
+
service.doSomething();
|
|
102
|
+
}
|
|
103
|
+
`;
|
|
104
|
+
const ast = parse(code);
|
|
105
|
+
const directives = extractDirectives(ast);
|
|
106
|
+
const mockDirectives = directives[0].directives.filter(
|
|
107
|
+
(d): d is MockDirective => d.kind === "mock"
|
|
108
|
+
);
|
|
109
|
+
expect(mockDirectives[0].sinonExpr).toBeDefined();
|
|
110
|
+
expect(mockDirectives[0].sinonExpr!.type).toBe("mock");
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
describe("Complex sinon chains", () => {
|
|
115
|
+
it("parses sinon.stub().onFirstCall().returns()", () => {
|
|
116
|
+
const code = `
|
|
117
|
+
// @nudo:mock fetch = sinon.stub().onFirstCall().returns({ data: "first" })
|
|
118
|
+
function getData() {
|
|
119
|
+
return fetch("/api/data");
|
|
120
|
+
}
|
|
121
|
+
`;
|
|
122
|
+
const ast = parse(code);
|
|
123
|
+
const directives = extractDirectives(ast);
|
|
124
|
+
const mockDirectives = directives[0].directives.filter(
|
|
125
|
+
(d): d is MockDirective => d.kind === "mock"
|
|
126
|
+
);
|
|
127
|
+
expect(mockDirectives[0].sinonExpr).toBeDefined();
|
|
128
|
+
expect(mockDirectives[0].sinonExpr!.type).toBe("stub");
|
|
129
|
+
expect(mockDirectives[0].sinonExpr!.returnValue).toBeDefined();
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it("parses sinon.stub().onSecondCall().returns()", () => {
|
|
133
|
+
const code = `
|
|
134
|
+
// @nudo:mock fetch = sinon.stub().onSecondCall().returns({ data: "second" })
|
|
135
|
+
function getData() {
|
|
136
|
+
return fetch("/api/data");
|
|
137
|
+
}
|
|
138
|
+
`;
|
|
139
|
+
const ast = parse(code);
|
|
140
|
+
const directives = extractDirectives(ast);
|
|
141
|
+
const mockDirectives = directives[0].directives.filter(
|
|
142
|
+
(d): d is MockDirective => d.kind === "mock"
|
|
143
|
+
);
|
|
144
|
+
expect(mockDirectives[0].sinonExpr).toBeDefined();
|
|
145
|
+
expect(mockDirectives[0].sinonExpr!.type).toBe("stub");
|
|
146
|
+
expect(mockDirectives[0].sinonExpr!.returnValue).toBeDefined();
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
it("parses sinon.stub().onCall(n).returns()", () => {
|
|
150
|
+
const code = `
|
|
151
|
+
// @nudo:mock fetch = sinon.stub().onCall(5).returns({ data: "fifth" })
|
|
152
|
+
function getData() {
|
|
153
|
+
return fetch("/api/data");
|
|
154
|
+
}
|
|
155
|
+
`;
|
|
156
|
+
const ast = parse(code);
|
|
157
|
+
const directives = extractDirectives(ast);
|
|
158
|
+
const mockDirectives = directives[0].directives.filter(
|
|
159
|
+
(d): d is MockDirective => d.kind === "mock"
|
|
160
|
+
);
|
|
161
|
+
expect(mockDirectives[0].sinonExpr).toBeDefined();
|
|
162
|
+
expect(mockDirectives[0].sinonExpr!.type).toBe("stub");
|
|
163
|
+
expect(mockDirectives[0].sinonExpr!.returnValue).toBeDefined();
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
it("parses sinon.stub().withArgs().returns()", () => {
|
|
167
|
+
const code = `
|
|
168
|
+
// @nudo:mock fetch = sinon.stub().withArgs("/api/data").returns({ data: "test" })
|
|
169
|
+
function getData() {
|
|
170
|
+
return fetch("/api/data");
|
|
171
|
+
}
|
|
172
|
+
`;
|
|
173
|
+
const ast = parse(code);
|
|
174
|
+
const directives = extractDirectives(ast);
|
|
175
|
+
const mockDirectives = directives[0].directives.filter(
|
|
176
|
+
(d): d is MockDirective => d.kind === "mock"
|
|
177
|
+
);
|
|
178
|
+
expect(mockDirectives[0].sinonExpr).toBeDefined();
|
|
179
|
+
expect(mockDirectives[0].sinonExpr!.type).toBe("stub");
|
|
180
|
+
expect(mockDirectives[0].sinonExpr!.returnValue).toBeDefined();
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
it("parses sinon.stub().callsFake()", () => {
|
|
184
|
+
const code = `
|
|
185
|
+
// @nudo:mock fetch = sinon.stub().callsFake((url) => ({ data: url }))
|
|
186
|
+
function getData() {
|
|
187
|
+
return fetch("/api/data");
|
|
188
|
+
}
|
|
189
|
+
`;
|
|
190
|
+
const ast = parse(code);
|
|
191
|
+
const directives = extractDirectives(ast);
|
|
192
|
+
const mockDirectives = directives[0].directives.filter(
|
|
193
|
+
(d): d is MockDirective => d.kind === "mock"
|
|
194
|
+
);
|
|
195
|
+
expect(mockDirectives[0].sinonExpr).toBeDefined();
|
|
196
|
+
expect(mockDirectives[0].sinonExpr!.type).toBe("stub");
|
|
197
|
+
expect(mockDirectives[0].sinonExpr!.returnValue).toBeDefined();
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
});
|