@alloy-js/python 0.3.0-dev.5 → 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 +15 -0
- package/dist/src/components/FutureStatement.d.ts +35 -0
- package/dist/src/components/FutureStatement.d.ts.map +1 -0
- package/dist/src/components/FutureStatement.js +31 -0
- package/dist/src/components/FutureStatement.js.map +1 -0
- package/dist/src/components/SourceFile.d.ts +8 -2
- package/dist/src/components/SourceFile.d.ts.map +1 -1
- package/dist/src/components/SourceFile.js +124 -8
- package/dist/src/components/SourceFile.js.map +1 -1
- package/dist/src/components/index.d.ts +1 -0
- package/dist/src/components/index.d.ts.map +1 -1
- package/dist/src/components/index.js +1 -0
- package/dist/src/components/index.js.map +1 -1
- package/dist/test/classdeclarations.test.js +2 -0
- package/dist/test/classdeclarations.test.js.map +1 -1
- package/dist/test/dataclassdeclarations.test.js +13 -0
- package/dist/test/dataclassdeclarations.test.js.map +1 -1
- package/dist/test/enums.test.js +7 -0
- package/dist/test/enums.test.js.map +1 -1
- package/dist/test/externals.test.js +2 -0
- package/dist/test/externals.test.js.map +1 -1
- package/dist/test/functiondeclaration.test.js +2 -0
- package/dist/test/functiondeclaration.test.js.map +1 -1
- package/dist/test/methoddeclaration.test.js +1 -0
- package/dist/test/methoddeclaration.test.js.map +1 -1
- package/dist/test/namepolicies.test.js +1 -0
- package/dist/test/namepolicies.test.js.map +1 -1
- package/dist/test/propertydeclaration.test.js +1 -0
- package/dist/test/propertydeclaration.test.js.map +1 -1
- package/dist/test/pydocs.test.js +1 -1
- package/dist/test/pydocs.test.js.map +1 -1
- package/dist/test/sourcefiles.test.js +921 -39
- package/dist/test/sourcefiles.test.js.map +1 -1
- package/dist/test/utils.d.ts +2 -2
- package/dist/test/utils.d.ts.map +1 -1
- package/dist/test/utils.js +9 -9
- package/dist/test/utils.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -6
- package/src/components/FutureStatement.tsx +38 -0
- package/src/components/SourceFile.tsx +128 -8
- package/src/components/index.ts +1 -0
- package/temp/api.json +122 -2
- package/test/classdeclarations.test.tsx +2 -0
- package/test/dataclassdeclarations.test.tsx +13 -0
- package/test/enums.test.tsx +7 -0
- package/test/externals.test.tsx +2 -0
- package/test/functiondeclaration.test.tsx +2 -0
- package/test/methoddeclaration.test.tsx +1 -0
- package/test/namepolicies.test.tsx +1 -0
- package/test/propertydeclaration.test.tsx +1 -0
- package/test/pydocs.test.tsx +1 -1
- package/test/sourcefiles.test.tsx +754 -48
- package/test/utils.tsx +10 -5
|
@@ -2,11 +2,8 @@ import { Prose } from "@alloy-js/core";
|
|
|
2
2
|
import { d } from "@alloy-js/core/testing";
|
|
3
3
|
import { expect, it } from "vitest";
|
|
4
4
|
import * as py from "../src/index.js";
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
toSourceText,
|
|
8
|
-
toSourceTextMultiple,
|
|
9
|
-
} from "./utils.jsx";
|
|
5
|
+
import { dataclassesModule } from "../src/index.js";
|
|
6
|
+
import { toSourceText } from "./utils.jsx";
|
|
10
7
|
|
|
11
8
|
/**
|
|
12
9
|
* toSourceText wraps the children in a SourceFile component
|
|
@@ -14,11 +11,10 @@ import {
|
|
|
14
11
|
*/
|
|
15
12
|
it("renders an empty source file", () => {
|
|
16
13
|
const result = toSourceText([]);
|
|
17
|
-
|
|
14
|
+
expect(result).toRenderTo(d`
|
|
18
15
|
|
|
19
16
|
|
|
20
|
-
|
|
21
|
-
expect(result).toRenderTo(expected);
|
|
17
|
+
`);
|
|
22
18
|
});
|
|
23
19
|
|
|
24
20
|
it("correct formatting of source file", () => {
|
|
@@ -99,7 +95,7 @@ it("correct formatting of source file", () => {
|
|
|
99
95
|
<py.MemberExpression.Part key={"special-prop"} />
|
|
100
96
|
</py.MemberExpression>,
|
|
101
97
|
]);
|
|
102
|
-
|
|
98
|
+
expect(result).toRenderTo(d`
|
|
103
99
|
class SomeClass:
|
|
104
100
|
def some_method() -> str:
|
|
105
101
|
x: int = 42
|
|
@@ -131,8 +127,7 @@ it("correct formatting of source file", () => {
|
|
|
131
127
|
|
|
132
128
|
a.b["special-prop"]
|
|
133
129
|
|
|
134
|
-
|
|
135
|
-
expect(result).toRenderTo(expected);
|
|
130
|
+
`);
|
|
136
131
|
});
|
|
137
132
|
|
|
138
133
|
it("renders module documentation correctly", () => {
|
|
@@ -162,69 +157,780 @@ it("renders module documentation correctly", () => {
|
|
|
162
157
|
);
|
|
163
158
|
|
|
164
159
|
const content = (
|
|
165
|
-
<py.SourceFile path="
|
|
160
|
+
<py.SourceFile path="test.py" doc={moduleDoc}>
|
|
166
161
|
<py.VariableDeclaration name="DEFAULT_TIMEOUT" initializer={30} />
|
|
167
162
|
<py.VariableDeclaration name="MAX_RETRIES" initializer={3} />
|
|
168
163
|
<py.FunctionDeclaration name="process_data">pass</py.FunctionDeclaration>
|
|
169
164
|
</py.SourceFile>
|
|
170
165
|
);
|
|
171
166
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
expect(file).toBeDefined();
|
|
177
|
-
|
|
178
|
-
assertFileContents(res, {
|
|
179
|
-
"utils.py": d`
|
|
180
|
-
"""
|
|
181
|
-
This module provides utility functions for data processing. It includes
|
|
182
|
-
functions for validation, transformation, and analysis.
|
|
183
|
-
|
|
184
|
-
Attributes:
|
|
185
|
-
DEFAULT_TIMEOUT (int): Default timeout value in seconds.
|
|
167
|
+
expect(toSourceText(content)).toRenderTo(d`
|
|
168
|
+
"""
|
|
169
|
+
This module provides utility functions for data processing. It includes
|
|
170
|
+
functions for validation, transformation, and analysis.
|
|
186
171
|
|
|
187
|
-
|
|
172
|
+
Attributes:
|
|
173
|
+
DEFAULT_TIMEOUT (int): Default timeout value in seconds.
|
|
188
174
|
|
|
189
|
-
|
|
190
|
-
* Add caching functionality
|
|
191
|
-
* Improve error messages
|
|
192
|
-
"""
|
|
175
|
+
MAX_RETRIES (int): Maximum number of retry attempts.
|
|
193
176
|
|
|
177
|
+
Todo:
|
|
178
|
+
* Add caching functionality
|
|
179
|
+
* Improve error messages
|
|
180
|
+
"""
|
|
194
181
|
|
|
195
|
-
|
|
182
|
+
default_timeout = 30
|
|
196
183
|
|
|
197
|
-
|
|
184
|
+
max_retries = 3
|
|
198
185
|
|
|
199
|
-
|
|
200
|
-
|
|
186
|
+
def process_data():
|
|
187
|
+
pass
|
|
201
188
|
|
|
202
189
|
|
|
203
|
-
|
|
204
|
-
});
|
|
190
|
+
`);
|
|
205
191
|
});
|
|
206
192
|
|
|
207
193
|
it("renders source file without documentation correctly", () => {
|
|
208
194
|
const content = (
|
|
209
|
-
<py.SourceFile path="
|
|
195
|
+
<py.SourceFile path="test.py">
|
|
210
196
|
<py.FunctionDeclaration name="hello_world">
|
|
211
197
|
print("Hello, World!")
|
|
212
198
|
</py.FunctionDeclaration>
|
|
213
199
|
</py.SourceFile>
|
|
214
200
|
);
|
|
215
201
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
202
|
+
expect(toSourceText(content)).toRenderTo(d`
|
|
203
|
+
def hello_world():
|
|
204
|
+
print("Hello, World!")
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
`);
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
it("nothing before top-level definition", () => {
|
|
211
|
+
const content = (
|
|
212
|
+
<py.SourceFile path="test.py">
|
|
213
|
+
<py.FunctionDeclaration name="hello">pass</py.FunctionDeclaration>
|
|
214
|
+
</py.SourceFile>
|
|
215
|
+
);
|
|
216
|
+
|
|
217
|
+
expect(toSourceText(content)).toRenderTo(d`
|
|
218
|
+
def hello():
|
|
219
|
+
pass
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
`);
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
it("nothing before non-definition", () => {
|
|
226
|
+
const content = (
|
|
227
|
+
<py.SourceFile path="test.py">
|
|
228
|
+
<py.VariableDeclaration name="x" initializer={42} />
|
|
229
|
+
</py.SourceFile>
|
|
230
|
+
);
|
|
231
|
+
|
|
232
|
+
expect(toSourceText(content)).toRenderTo("x = 42");
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
it("only doc before definition", () => {
|
|
236
|
+
const moduleDoc = (
|
|
237
|
+
<py.ModuleDoc description={[<Prose>Module description.</Prose>]} />
|
|
238
|
+
);
|
|
239
|
+
|
|
240
|
+
const content = (
|
|
241
|
+
<py.SourceFile path="test.py" doc={moduleDoc}>
|
|
242
|
+
<py.FunctionDeclaration name="hello">pass</py.FunctionDeclaration>
|
|
243
|
+
</py.SourceFile>
|
|
244
|
+
);
|
|
245
|
+
|
|
246
|
+
expect(toSourceText(content)).toRenderTo(d`
|
|
247
|
+
"""
|
|
248
|
+
Module description.
|
|
249
|
+
"""
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
def hello():
|
|
253
|
+
pass
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
`);
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
it("only doc before non-definition", () => {
|
|
260
|
+
const moduleDoc = (
|
|
261
|
+
<py.ModuleDoc description={[<Prose>Module description.</Prose>]} />
|
|
262
|
+
);
|
|
263
|
+
|
|
264
|
+
const content = (
|
|
265
|
+
<py.SourceFile path="test.py" doc={moduleDoc}>
|
|
266
|
+
<py.VariableDeclaration name="x" initializer={42} />
|
|
267
|
+
</py.SourceFile>
|
|
268
|
+
);
|
|
269
|
+
|
|
270
|
+
expect(toSourceText(content)).toRenderTo(d`
|
|
271
|
+
"""
|
|
272
|
+
Module description.
|
|
273
|
+
"""
|
|
274
|
+
|
|
275
|
+
x = 42`);
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
it("only header before definition", () => {
|
|
279
|
+
const content = (
|
|
280
|
+
<py.SourceFile path="test.py" header="#!/usr/bin/env python3">
|
|
281
|
+
<py.FunctionDeclaration name="hello">pass</py.FunctionDeclaration>
|
|
282
|
+
</py.SourceFile>
|
|
283
|
+
);
|
|
284
|
+
|
|
285
|
+
// 2 blank lines before definition (PEP 8)
|
|
286
|
+
expect(toSourceText(content)).toRenderTo(d`
|
|
287
|
+
#!/usr/bin/env python3
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
def hello():
|
|
291
|
+
pass
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
`);
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
it("only header before non-definition", () => {
|
|
298
|
+
const content = (
|
|
299
|
+
<py.SourceFile path="test.py" header="#!/usr/bin/env python3">
|
|
300
|
+
<py.VariableDeclaration name="x" initializer={42} />
|
|
301
|
+
</py.SourceFile>
|
|
302
|
+
);
|
|
303
|
+
|
|
304
|
+
// 1 blank line for non-definition
|
|
305
|
+
expect(toSourceText(content)).toRenderTo(d`
|
|
306
|
+
#!/usr/bin/env python3
|
|
307
|
+
|
|
308
|
+
x = 42`);
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
it("only futureImports before definition", () => {
|
|
312
|
+
const content = (
|
|
313
|
+
<py.SourceFile
|
|
314
|
+
path="test.py"
|
|
315
|
+
futureImports={<py.FutureStatement feature="annotations" />}
|
|
316
|
+
>
|
|
317
|
+
<py.FunctionDeclaration name="hello">pass</py.FunctionDeclaration>
|
|
318
|
+
</py.SourceFile>
|
|
319
|
+
);
|
|
320
|
+
|
|
321
|
+
expect(toSourceText(content)).toRenderTo(d`
|
|
322
|
+
from __future__ import annotations
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
def hello():
|
|
326
|
+
pass
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
`);
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
it("only futureImports before non-definition", () => {
|
|
333
|
+
const content = (
|
|
334
|
+
<py.SourceFile
|
|
335
|
+
path="test.py"
|
|
336
|
+
futureImports={<py.FutureStatement feature="annotations" />}
|
|
337
|
+
>
|
|
338
|
+
<py.VariableDeclaration name="x" initializer={42} />
|
|
339
|
+
</py.SourceFile>
|
|
340
|
+
);
|
|
341
|
+
|
|
342
|
+
expect(toSourceText(content)).toRenderTo(d`
|
|
343
|
+
from __future__ import annotations
|
|
344
|
+
|
|
345
|
+
x = 42`);
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
it("only imports before definition", () => {
|
|
349
|
+
const content = (
|
|
350
|
+
<py.SourceFile path="test.py">
|
|
351
|
+
<py.DataclassDeclaration name="User">
|
|
352
|
+
<py.VariableDeclaration name="name" type="str" />
|
|
353
|
+
</py.DataclassDeclaration>
|
|
354
|
+
</py.SourceFile>
|
|
355
|
+
);
|
|
356
|
+
|
|
357
|
+
expect(toSourceText(content, { externals: [dataclassesModule] }))
|
|
358
|
+
.toRenderTo(d`
|
|
359
|
+
from dataclasses import dataclass
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
@dataclass
|
|
363
|
+
class User:
|
|
364
|
+
name: str = None
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
`);
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
it("only imports before non-definition", () => {
|
|
371
|
+
const content = (
|
|
372
|
+
<py.SourceFile path="test.py">
|
|
373
|
+
<py.VariableDeclaration
|
|
374
|
+
name="x"
|
|
375
|
+
initializer={<py.Reference refkey={dataclassesModule["."].dataclass} />}
|
|
376
|
+
/>
|
|
377
|
+
</py.SourceFile>
|
|
378
|
+
);
|
|
379
|
+
|
|
380
|
+
expect(toSourceText(content, { externals: [dataclassesModule] }))
|
|
381
|
+
.toRenderTo(d`
|
|
382
|
+
from dataclasses import dataclass
|
|
383
|
+
|
|
384
|
+
x = dataclass`);
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
it("doc + futureImports before definition", () => {
|
|
388
|
+
const moduleDoc = (
|
|
389
|
+
<py.ModuleDoc description={[<Prose>Module description.</Prose>]} />
|
|
390
|
+
);
|
|
391
|
+
|
|
392
|
+
const content = (
|
|
393
|
+
<py.SourceFile
|
|
394
|
+
path="test.py"
|
|
395
|
+
doc={moduleDoc}
|
|
396
|
+
futureImports={<py.FutureStatement feature="annotations" />}
|
|
397
|
+
>
|
|
398
|
+
<py.FunctionDeclaration name="hello">pass</py.FunctionDeclaration>
|
|
399
|
+
</py.SourceFile>
|
|
400
|
+
);
|
|
401
|
+
|
|
402
|
+
expect(toSourceText(content)).toRenderTo(d`
|
|
403
|
+
"""
|
|
404
|
+
Module description.
|
|
405
|
+
"""
|
|
406
|
+
|
|
407
|
+
from __future__ import annotations
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
def hello():
|
|
411
|
+
pass
|
|
412
|
+
|
|
413
|
+
|
|
414
|
+
`);
|
|
415
|
+
});
|
|
416
|
+
|
|
417
|
+
it("doc + futureImports before non-definition", () => {
|
|
418
|
+
const moduleDoc = (
|
|
419
|
+
<py.ModuleDoc description={[<Prose>Module description.</Prose>]} />
|
|
420
|
+
);
|
|
421
|
+
|
|
422
|
+
const content = (
|
|
423
|
+
<py.SourceFile
|
|
424
|
+
path="test.py"
|
|
425
|
+
doc={moduleDoc}
|
|
426
|
+
futureImports={<py.FutureStatement feature="annotations" />}
|
|
427
|
+
>
|
|
428
|
+
<py.VariableDeclaration name="x" initializer={42} />
|
|
429
|
+
</py.SourceFile>
|
|
430
|
+
);
|
|
431
|
+
|
|
432
|
+
expect(toSourceText(content)).toRenderTo(d`
|
|
433
|
+
"""
|
|
434
|
+
Module description.
|
|
435
|
+
"""
|
|
436
|
+
|
|
437
|
+
from __future__ import annotations
|
|
438
|
+
|
|
439
|
+
x = 42`);
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
it("doc + imports before definition", () => {
|
|
443
|
+
const moduleDoc = (
|
|
444
|
+
<py.ModuleDoc description={[<Prose>Module description.</Prose>]} />
|
|
445
|
+
);
|
|
446
|
+
|
|
447
|
+
const content = (
|
|
448
|
+
<py.SourceFile path="test.py" doc={moduleDoc}>
|
|
449
|
+
<py.DataclassDeclaration name="User">
|
|
450
|
+
<py.VariableDeclaration name="name" type="str" />
|
|
451
|
+
</py.DataclassDeclaration>
|
|
452
|
+
</py.SourceFile>
|
|
453
|
+
);
|
|
454
|
+
|
|
455
|
+
expect(toSourceText(content, { externals: [dataclassesModule] }))
|
|
456
|
+
.toRenderTo(d`
|
|
457
|
+
"""
|
|
458
|
+
Module description.
|
|
459
|
+
"""
|
|
460
|
+
|
|
461
|
+
from dataclasses import dataclass
|
|
462
|
+
|
|
463
|
+
|
|
464
|
+
@dataclass
|
|
465
|
+
class User:
|
|
466
|
+
name: str = None
|
|
467
|
+
|
|
468
|
+
|
|
469
|
+
`);
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
it("doc + imports before non-definition", () => {
|
|
473
|
+
const moduleDoc = (
|
|
474
|
+
<py.ModuleDoc description={[<Prose>Module description.</Prose>]} />
|
|
475
|
+
);
|
|
476
|
+
|
|
477
|
+
const content = (
|
|
478
|
+
<py.SourceFile path="test.py" doc={moduleDoc}>
|
|
479
|
+
<py.VariableDeclaration
|
|
480
|
+
name="x"
|
|
481
|
+
initializer={<py.Reference refkey={dataclassesModule["."].dataclass} />}
|
|
482
|
+
/>
|
|
483
|
+
</py.SourceFile>
|
|
484
|
+
);
|
|
485
|
+
|
|
486
|
+
expect(toSourceText(content, { externals: [dataclassesModule] }))
|
|
487
|
+
.toRenderTo(d`
|
|
488
|
+
"""
|
|
489
|
+
Module description.
|
|
490
|
+
"""
|
|
491
|
+
|
|
492
|
+
from dataclasses import dataclass
|
|
493
|
+
|
|
494
|
+
x = dataclass`);
|
|
495
|
+
});
|
|
496
|
+
|
|
497
|
+
it("futureImports + imports before definition", () => {
|
|
498
|
+
const content = (
|
|
499
|
+
<py.SourceFile
|
|
500
|
+
path="test.py"
|
|
501
|
+
futureImports={<py.FutureStatement feature="annotations" />}
|
|
502
|
+
>
|
|
503
|
+
<py.DataclassDeclaration name="User">
|
|
504
|
+
<py.VariableDeclaration name="name" type="str" />
|
|
505
|
+
</py.DataclassDeclaration>
|
|
506
|
+
</py.SourceFile>
|
|
507
|
+
);
|
|
508
|
+
|
|
509
|
+
expect(toSourceText(content, { externals: [dataclassesModule] }))
|
|
510
|
+
.toRenderTo(d`
|
|
511
|
+
from __future__ import annotations
|
|
512
|
+
|
|
513
|
+
from dataclasses import dataclass
|
|
514
|
+
|
|
515
|
+
|
|
516
|
+
@dataclass
|
|
517
|
+
class User:
|
|
518
|
+
name: str = None
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
`);
|
|
522
|
+
});
|
|
523
|
+
|
|
524
|
+
it("futureImports + imports before non-definition", () => {
|
|
525
|
+
const content = (
|
|
526
|
+
<py.SourceFile
|
|
527
|
+
path="test.py"
|
|
528
|
+
futureImports={<py.FutureStatement feature="annotations" />}
|
|
529
|
+
>
|
|
530
|
+
<py.VariableDeclaration
|
|
531
|
+
name="x"
|
|
532
|
+
initializer={<py.Reference refkey={dataclassesModule["."].dataclass} />}
|
|
533
|
+
/>
|
|
534
|
+
</py.SourceFile>
|
|
535
|
+
);
|
|
536
|
+
|
|
537
|
+
expect(toSourceText(content, { externals: [dataclassesModule] }))
|
|
538
|
+
.toRenderTo(d`
|
|
539
|
+
from __future__ import annotations
|
|
540
|
+
|
|
541
|
+
from dataclasses import dataclass
|
|
542
|
+
|
|
543
|
+
x = dataclass`);
|
|
544
|
+
});
|
|
545
|
+
|
|
546
|
+
it("doc + futureImports + imports before definition", () => {
|
|
547
|
+
const moduleDoc = (
|
|
548
|
+
<py.ModuleDoc description={[<Prose>Module description.</Prose>]} />
|
|
549
|
+
);
|
|
550
|
+
|
|
551
|
+
const content = (
|
|
552
|
+
<py.SourceFile
|
|
553
|
+
path="test.py"
|
|
554
|
+
doc={moduleDoc}
|
|
555
|
+
futureImports={<py.FutureStatement feature="annotations" />}
|
|
556
|
+
>
|
|
557
|
+
<py.DataclassDeclaration name="User">
|
|
558
|
+
<py.VariableDeclaration name="name" type="str" />
|
|
559
|
+
</py.DataclassDeclaration>
|
|
560
|
+
</py.SourceFile>
|
|
561
|
+
);
|
|
562
|
+
|
|
563
|
+
expect(toSourceText(content, { externals: [dataclassesModule] }))
|
|
564
|
+
.toRenderTo(d`
|
|
565
|
+
"""
|
|
566
|
+
Module description.
|
|
567
|
+
"""
|
|
568
|
+
|
|
569
|
+
from __future__ import annotations
|
|
570
|
+
|
|
571
|
+
from dataclasses import dataclass
|
|
572
|
+
|
|
573
|
+
|
|
574
|
+
@dataclass
|
|
575
|
+
class User:
|
|
576
|
+
name: str = None
|
|
577
|
+
|
|
578
|
+
|
|
579
|
+
`);
|
|
580
|
+
});
|
|
581
|
+
|
|
582
|
+
it("doc + futureImports + imports before non-definition", () => {
|
|
583
|
+
const moduleDoc = (
|
|
584
|
+
<py.ModuleDoc description={[<Prose>Module description.</Prose>]} />
|
|
585
|
+
);
|
|
586
|
+
|
|
587
|
+
const content = (
|
|
588
|
+
<py.SourceFile
|
|
589
|
+
path="test.py"
|
|
590
|
+
doc={moduleDoc}
|
|
591
|
+
futureImports={<py.FutureStatement feature="annotations" />}
|
|
592
|
+
>
|
|
593
|
+
<py.VariableDeclaration
|
|
594
|
+
name="x"
|
|
595
|
+
initializer={<py.Reference refkey={dataclassesModule["."].dataclass} />}
|
|
596
|
+
/>
|
|
597
|
+
</py.SourceFile>
|
|
598
|
+
);
|
|
599
|
+
|
|
600
|
+
expect(toSourceText(content, { externals: [dataclassesModule] }))
|
|
601
|
+
.toRenderTo(d`
|
|
602
|
+
"""
|
|
603
|
+
Module description.
|
|
604
|
+
"""
|
|
605
|
+
|
|
606
|
+
from __future__ import annotations
|
|
607
|
+
|
|
608
|
+
from dataclasses import dataclass
|
|
609
|
+
|
|
610
|
+
x = dataclass`);
|
|
611
|
+
});
|
|
612
|
+
|
|
613
|
+
it("only doc in file (no children)", () => {
|
|
614
|
+
const moduleDoc = (
|
|
615
|
+
<py.ModuleDoc description={[<Prose>Module description.</Prose>]} />
|
|
616
|
+
);
|
|
617
|
+
|
|
618
|
+
const content = <py.SourceFile path="test.py" doc={moduleDoc} />;
|
|
619
|
+
|
|
620
|
+
expect(toSourceText(content)).toRenderTo(d`
|
|
621
|
+
"""
|
|
622
|
+
Module description.
|
|
623
|
+
"""
|
|
624
|
+
|
|
625
|
+
|
|
626
|
+
`);
|
|
627
|
+
});
|
|
628
|
+
|
|
629
|
+
it("only header in file (no children)", () => {
|
|
630
|
+
const content = (
|
|
631
|
+
<py.SourceFile path="test.py" header="#!/usr/bin/env python3" />
|
|
632
|
+
);
|
|
633
|
+
|
|
634
|
+
expect(toSourceText(content)).toRenderTo(d`
|
|
635
|
+
#!/usr/bin/env python3
|
|
636
|
+
|
|
637
|
+
|
|
638
|
+
`);
|
|
639
|
+
});
|
|
640
|
+
|
|
641
|
+
it("only futureImports in file (no children)", () => {
|
|
642
|
+
const content = (
|
|
643
|
+
<py.SourceFile
|
|
644
|
+
path="test.py"
|
|
645
|
+
futureImports={<py.FutureStatement feature="annotations" />}
|
|
646
|
+
/>
|
|
647
|
+
);
|
|
648
|
+
|
|
649
|
+
expect(toSourceText(content)).toRenderTo(d`
|
|
650
|
+
from __future__ import annotations
|
|
651
|
+
|
|
652
|
+
`);
|
|
653
|
+
});
|
|
654
|
+
|
|
655
|
+
it("doc + futureImports in file (no children)", () => {
|
|
656
|
+
const moduleDoc = (
|
|
657
|
+
<py.ModuleDoc description={[<Prose>Module description.</Prose>]} />
|
|
658
|
+
);
|
|
659
|
+
|
|
660
|
+
const content = (
|
|
661
|
+
<py.SourceFile
|
|
662
|
+
path="test.py"
|
|
663
|
+
doc={moduleDoc}
|
|
664
|
+
futureImports={<py.FutureStatement feature="annotations" />}
|
|
665
|
+
/>
|
|
666
|
+
);
|
|
667
|
+
|
|
668
|
+
expect(toSourceText(content)).toRenderTo(d`
|
|
669
|
+
"""
|
|
670
|
+
Module description.
|
|
671
|
+
"""
|
|
672
|
+
|
|
673
|
+
from __future__ import annotations
|
|
674
|
+
|
|
675
|
+
`);
|
|
676
|
+
});
|
|
677
|
+
|
|
678
|
+
// headerComment tests
|
|
679
|
+
it("only headerComment before definition", () => {
|
|
680
|
+
const content = (
|
|
681
|
+
<py.SourceFile path="test.py" headerComment="Copyright 2024 My Company">
|
|
682
|
+
<py.FunctionDeclaration name="hello">pass</py.FunctionDeclaration>
|
|
683
|
+
</py.SourceFile>
|
|
684
|
+
);
|
|
685
|
+
|
|
686
|
+
// 2 blank lines before definition (PEP 8)
|
|
687
|
+
expect(toSourceText(content)).toRenderTo(d`
|
|
688
|
+
# Copyright 2024 My Company
|
|
689
|
+
|
|
690
|
+
|
|
691
|
+
def hello():
|
|
692
|
+
pass
|
|
693
|
+
|
|
694
|
+
|
|
695
|
+
`);
|
|
696
|
+
});
|
|
697
|
+
|
|
698
|
+
it("only headerComment before non-definition", () => {
|
|
699
|
+
const content = (
|
|
700
|
+
<py.SourceFile path="test.py" headerComment="Copyright 2024 My Company">
|
|
701
|
+
<py.VariableDeclaration name="x" initializer={42} />
|
|
702
|
+
</py.SourceFile>
|
|
219
703
|
);
|
|
220
|
-
expect(file).toBeDefined();
|
|
221
704
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
705
|
+
expect(toSourceText(content)).toRenderTo(d`
|
|
706
|
+
# Copyright 2024 My Company
|
|
707
|
+
|
|
708
|
+
x = 42`);
|
|
709
|
+
});
|
|
710
|
+
|
|
711
|
+
it("headerComment + doc before definition", () => {
|
|
712
|
+
const moduleDoc = (
|
|
713
|
+
<py.ModuleDoc description={[<Prose>Module description.</Prose>]} />
|
|
714
|
+
);
|
|
715
|
+
|
|
716
|
+
const content = (
|
|
717
|
+
<py.SourceFile
|
|
718
|
+
path="test.py"
|
|
719
|
+
headerComment="Copyright 2024 My Company"
|
|
720
|
+
doc={moduleDoc}
|
|
721
|
+
>
|
|
722
|
+
<py.FunctionDeclaration name="hello">pass</py.FunctionDeclaration>
|
|
723
|
+
</py.SourceFile>
|
|
724
|
+
);
|
|
725
|
+
|
|
726
|
+
// headerComment and doc adjacent, then PEP 8 spacing before definition
|
|
727
|
+
expect(toSourceText(content)).toRenderTo(d`
|
|
728
|
+
# Copyright 2024 My Company
|
|
729
|
+
"""
|
|
730
|
+
Module description.
|
|
731
|
+
"""
|
|
732
|
+
|
|
733
|
+
|
|
734
|
+
def hello():
|
|
735
|
+
pass
|
|
736
|
+
|
|
737
|
+
|
|
738
|
+
`);
|
|
739
|
+
});
|
|
740
|
+
|
|
741
|
+
it("headerComment + futureImports before definition", () => {
|
|
742
|
+
const content = (
|
|
743
|
+
<py.SourceFile
|
|
744
|
+
path="test.py"
|
|
745
|
+
headerComment="Copyright 2024 My Company"
|
|
746
|
+
futureImports={<py.FutureStatement feature="annotations" />}
|
|
747
|
+
>
|
|
748
|
+
<py.FunctionDeclaration name="hello">pass</py.FunctionDeclaration>
|
|
749
|
+
</py.SourceFile>
|
|
750
|
+
);
|
|
751
|
+
|
|
752
|
+
// headerComment and futureImports adjacent, then PEP 8 spacing
|
|
753
|
+
expect(toSourceText(content)).toRenderTo(d`
|
|
754
|
+
# Copyright 2024 My Company
|
|
755
|
+
|
|
756
|
+
from __future__ import annotations
|
|
757
|
+
|
|
758
|
+
|
|
759
|
+
def hello():
|
|
760
|
+
pass
|
|
761
|
+
|
|
762
|
+
|
|
763
|
+
`);
|
|
764
|
+
});
|
|
765
|
+
|
|
766
|
+
it("headerComment + imports before definition", () => {
|
|
767
|
+
const content = (
|
|
768
|
+
<py.SourceFile path="test.py" headerComment="Copyright 2024 My Company">
|
|
769
|
+
<py.DataclassDeclaration name="User">
|
|
770
|
+
<py.VariableDeclaration name="name" type="str" />
|
|
771
|
+
</py.DataclassDeclaration>
|
|
772
|
+
</py.SourceFile>
|
|
773
|
+
);
|
|
774
|
+
|
|
775
|
+
expect(toSourceText(content, { externals: [dataclassesModule] }))
|
|
776
|
+
.toRenderTo(d`
|
|
777
|
+
# Copyright 2024 My Company
|
|
778
|
+
|
|
779
|
+
from dataclasses import dataclass
|
|
780
|
+
|
|
781
|
+
|
|
782
|
+
@dataclass
|
|
783
|
+
class User:
|
|
784
|
+
name: str = None
|
|
785
|
+
|
|
786
|
+
|
|
787
|
+
`);
|
|
788
|
+
});
|
|
789
|
+
|
|
790
|
+
it("headerComment + doc + futureImports before definition", () => {
|
|
791
|
+
const moduleDoc = (
|
|
792
|
+
<py.ModuleDoc description={[<Prose>Module description.</Prose>]} />
|
|
793
|
+
);
|
|
794
|
+
|
|
795
|
+
const content = (
|
|
796
|
+
<py.SourceFile
|
|
797
|
+
path="test.py"
|
|
798
|
+
headerComment="Copyright 2024 My Company"
|
|
799
|
+
doc={moduleDoc}
|
|
800
|
+
futureImports={<py.FutureStatement feature="annotations" />}
|
|
801
|
+
>
|
|
802
|
+
<py.FunctionDeclaration name="hello">pass</py.FunctionDeclaration>
|
|
803
|
+
</py.SourceFile>
|
|
804
|
+
);
|
|
805
|
+
|
|
806
|
+
expect(toSourceText(content)).toRenderTo(d`
|
|
807
|
+
# Copyright 2024 My Company
|
|
808
|
+
"""
|
|
809
|
+
Module description.
|
|
810
|
+
"""
|
|
811
|
+
|
|
812
|
+
from __future__ import annotations
|
|
813
|
+
|
|
814
|
+
|
|
815
|
+
def hello():
|
|
816
|
+
pass
|
|
817
|
+
|
|
818
|
+
|
|
819
|
+
`);
|
|
820
|
+
});
|
|
821
|
+
|
|
822
|
+
it("headerComment + doc + futureImports + imports before definition", () => {
|
|
823
|
+
const moduleDoc = (
|
|
824
|
+
<py.ModuleDoc description={[<Prose>Module description.</Prose>]} />
|
|
825
|
+
);
|
|
826
|
+
|
|
827
|
+
const content = (
|
|
828
|
+
<py.SourceFile
|
|
829
|
+
path="test.py"
|
|
830
|
+
headerComment="Copyright 2024 My Company"
|
|
831
|
+
doc={moduleDoc}
|
|
832
|
+
futureImports={<py.FutureStatement feature="annotations" />}
|
|
833
|
+
>
|
|
834
|
+
<py.DataclassDeclaration name="User">
|
|
835
|
+
<py.VariableDeclaration name="name" type="str" />
|
|
836
|
+
</py.DataclassDeclaration>
|
|
837
|
+
</py.SourceFile>
|
|
838
|
+
);
|
|
839
|
+
|
|
840
|
+
expect(toSourceText(content, { externals: [dataclassesModule] }))
|
|
841
|
+
.toRenderTo(d`
|
|
842
|
+
# Copyright 2024 My Company
|
|
843
|
+
"""
|
|
844
|
+
Module description.
|
|
845
|
+
"""
|
|
846
|
+
|
|
847
|
+
from __future__ import annotations
|
|
848
|
+
|
|
849
|
+
from dataclasses import dataclass
|
|
850
|
+
|
|
851
|
+
|
|
852
|
+
@dataclass
|
|
853
|
+
class User:
|
|
854
|
+
name: str = None
|
|
855
|
+
|
|
856
|
+
|
|
857
|
+
`);
|
|
858
|
+
});
|
|
859
|
+
|
|
860
|
+
it("only headerComment in file (no children)", () => {
|
|
861
|
+
const content = (
|
|
862
|
+
<py.SourceFile path="test.py" headerComment="Copyright 2024 My Company" />
|
|
863
|
+
);
|
|
864
|
+
|
|
865
|
+
expect(toSourceText(content)).toRenderTo(d`
|
|
866
|
+
# Copyright 2024 My Company
|
|
867
|
+
|
|
868
|
+
`);
|
|
869
|
+
});
|
|
870
|
+
|
|
871
|
+
it("header + headerComment before definition", () => {
|
|
872
|
+
const content = (
|
|
873
|
+
<py.SourceFile
|
|
874
|
+
path="test.py"
|
|
875
|
+
header="#!/usr/bin/env python3"
|
|
876
|
+
headerComment="Copyright 2024 My Company"
|
|
877
|
+
>
|
|
878
|
+
<py.FunctionDeclaration name="hello">pass</py.FunctionDeclaration>
|
|
879
|
+
</py.SourceFile>
|
|
880
|
+
);
|
|
881
|
+
|
|
882
|
+
// 2 blank lines before definition (PEP 8)
|
|
883
|
+
expect(toSourceText(content)).toRenderTo(d`
|
|
884
|
+
#!/usr/bin/env python3
|
|
885
|
+
# Copyright 2024 My Company
|
|
886
|
+
|
|
887
|
+
|
|
888
|
+
def hello():
|
|
889
|
+
pass
|
|
890
|
+
|
|
891
|
+
|
|
892
|
+
`);
|
|
893
|
+
});
|
|
894
|
+
|
|
895
|
+
it("header + headerComment before class definition", () => {
|
|
896
|
+
const content = (
|
|
897
|
+
<py.SourceFile
|
|
898
|
+
path="test.py"
|
|
899
|
+
header="#!/usr/bin/env python3"
|
|
900
|
+
headerComment="Copyright 2024 My Company"
|
|
901
|
+
>
|
|
902
|
+
<py.ClassDeclaration name="MyClass">pass</py.ClassDeclaration>
|
|
903
|
+
</py.SourceFile>
|
|
904
|
+
);
|
|
905
|
+
|
|
906
|
+
// 2 blank lines before definition (PEP 8)
|
|
907
|
+
expect(toSourceText(content)).toRenderTo(d`
|
|
908
|
+
#!/usr/bin/env python3
|
|
909
|
+
# Copyright 2024 My Company
|
|
910
|
+
|
|
911
|
+
|
|
912
|
+
class MyClass:
|
|
913
|
+
pass
|
|
914
|
+
|
|
915
|
+
|
|
916
|
+
`);
|
|
917
|
+
});
|
|
918
|
+
|
|
919
|
+
it("header + headerComment before non-definition", () => {
|
|
920
|
+
const content = (
|
|
921
|
+
<py.SourceFile
|
|
922
|
+
path="test.py"
|
|
923
|
+
header="#!/usr/bin/env python3"
|
|
924
|
+
headerComment="Copyright 2024 My Company"
|
|
925
|
+
>
|
|
926
|
+
<py.VariableDeclaration name="x" initializer={42} />
|
|
927
|
+
</py.SourceFile>
|
|
928
|
+
);
|
|
226
929
|
|
|
930
|
+
// 1 blank line for non-definition
|
|
931
|
+
expect(toSourceText(content)).toRenderTo(d`
|
|
932
|
+
#!/usr/bin/env python3
|
|
933
|
+
# Copyright 2024 My Company
|
|
227
934
|
|
|
228
|
-
|
|
229
|
-
});
|
|
935
|
+
x = 42`);
|
|
230
936
|
});
|