@alloy-js/python 0.2.0-dev.3 → 0.2.0-dev.4
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/dist/src/builtins/python.d.ts +3 -0
- package/dist/src/builtins/python.d.ts.map +1 -1
- package/dist/src/builtins/python.js +6 -0
- package/dist/src/builtins/python.js.map +1 -1
- package/dist/src/components/CallSignature.d.ts +4 -15
- package/dist/src/components/CallSignature.d.ts.map +1 -1
- package/dist/src/components/CallSignature.js +13 -67
- package/dist/src/components/CallSignature.js.map +1 -1
- package/dist/src/components/ClassMethodDeclaration.d.ts +22 -0
- package/dist/src/components/ClassMethodDeclaration.d.ts.map +1 -0
- package/dist/src/components/ClassMethodDeclaration.js +32 -0
- package/dist/src/components/ClassMethodDeclaration.js.map +1 -0
- package/dist/src/components/ConstructorDeclaration.d.ts +21 -0
- package/dist/src/components/ConstructorDeclaration.d.ts.map +1 -0
- package/dist/src/components/ConstructorDeclaration.js +35 -0
- package/dist/src/components/ConstructorDeclaration.js.map +1 -0
- package/dist/src/components/DunderMethodDeclaration.d.ts +21 -0
- package/dist/src/components/DunderMethodDeclaration.d.ts.map +1 -0
- package/dist/src/components/DunderMethodDeclaration.js +29 -0
- package/dist/src/components/DunderMethodDeclaration.js.map +1 -0
- package/dist/src/components/EnumDeclaration.d.ts +11 -32
- package/dist/src/components/EnumDeclaration.d.ts.map +1 -1
- package/dist/src/components/EnumDeclaration.js +10 -48
- package/dist/src/components/EnumDeclaration.js.map +1 -1
- package/dist/src/components/EnumMember.js +3 -3
- package/dist/src/components/EnumMember.js.map +1 -1
- package/dist/src/components/FunctionBase.d.ts +48 -0
- package/dist/src/components/FunctionBase.d.ts.map +1 -0
- package/dist/src/components/FunctionBase.js +91 -0
- package/dist/src/components/FunctionBase.js.map +1 -0
- package/dist/src/components/FunctionDeclaration.d.ts +11 -31
- package/dist/src/components/FunctionDeclaration.d.ts.map +1 -1
- package/dist/src/components/FunctionDeclaration.js +22 -79
- package/dist/src/components/FunctionDeclaration.js.map +1 -1
- package/dist/src/components/MethodBase.d.ts +29 -0
- package/dist/src/components/MethodBase.d.ts.map +1 -0
- package/dist/src/components/MethodBase.js +32 -0
- package/dist/src/components/MethodBase.js.map +1 -0
- package/dist/src/components/MethodDeclaration.d.ts +22 -0
- package/dist/src/components/MethodDeclaration.d.ts.map +1 -0
- package/dist/src/components/MethodDeclaration.js +34 -0
- package/dist/src/components/MethodDeclaration.js.map +1 -0
- package/dist/src/components/PropertyDeclaration.d.ts +71 -0
- package/dist/src/components/PropertyDeclaration.d.ts.map +1 -0
- package/dist/src/components/PropertyDeclaration.js +227 -0
- package/dist/src/components/PropertyDeclaration.js.map +1 -0
- package/dist/src/components/PyDoc.d.ts +107 -42
- package/dist/src/components/PyDoc.d.ts.map +1 -1
- package/dist/src/components/PyDoc.js +845 -181
- package/dist/src/components/PyDoc.js.map +1 -1
- package/dist/src/components/SourceFile.d.ts +24 -0
- package/dist/src/components/SourceFile.d.ts.map +1 -1
- package/dist/src/components/SourceFile.js +28 -1
- package/dist/src/components/SourceFile.js.map +1 -1
- package/dist/src/components/StaticMethodDeclaration.d.ts +22 -0
- package/dist/src/components/StaticMethodDeclaration.d.ts.map +1 -0
- package/dist/src/components/StaticMethodDeclaration.js +32 -0
- package/dist/src/components/StaticMethodDeclaration.js.map +1 -0
- package/dist/src/components/TypeArguments.d.ts +9 -0
- package/dist/src/components/TypeArguments.d.ts.map +1 -0
- package/dist/src/components/TypeArguments.js +18 -0
- package/dist/src/components/TypeArguments.js.map +1 -0
- package/dist/src/components/TypeReference.d.ts +14 -0
- package/dist/src/components/TypeReference.d.ts.map +1 -0
- package/dist/src/components/TypeReference.js +29 -0
- package/dist/src/components/TypeReference.js.map +1 -0
- package/dist/src/components/UnionTypeExpression.d.ts +1 -2
- package/dist/src/components/UnionTypeExpression.d.ts.map +1 -1
- package/dist/src/components/UnionTypeExpression.js +3 -11
- package/dist/src/components/UnionTypeExpression.js.map +1 -1
- package/dist/src/components/VariableDeclaration.d.ts.map +1 -1
- package/dist/src/components/VariableDeclaration.js +3 -3
- package/dist/src/components/VariableDeclaration.js.map +1 -1
- package/dist/src/components/index.d.ts +10 -0
- package/dist/src/components/index.d.ts.map +1 -1
- package/dist/src/components/index.js +9 -0
- package/dist/src/components/index.js.map +1 -1
- package/dist/src/parameter-descriptor.d.ts +1 -4
- package/dist/src/parameter-descriptor.d.ts.map +1 -1
- package/dist/src/parameter-descriptor.js +7 -1
- package/dist/src/parameter-descriptor.js.map +1 -1
- package/dist/src/symbol-creation.d.ts +4 -0
- package/dist/src/symbol-creation.d.ts.map +1 -1
- package/dist/src/symbol-creation.js +12 -0
- package/dist/src/symbol-creation.js.map +1 -1
- package/dist/src/symbols/factories.d.ts +15 -0
- package/dist/src/symbols/factories.d.ts.map +1 -0
- package/dist/src/symbols/factories.js +28 -0
- package/dist/src/symbols/factories.js.map +1 -0
- package/dist/src/symbols/index.d.ts +1 -0
- package/dist/src/symbols/index.d.ts.map +1 -1
- package/dist/src/symbols/index.js +1 -0
- package/dist/src/symbols/index.js.map +1 -1
- package/dist/src/symbols/reference.d.ts +1 -1
- package/dist/src/symbols/reference.d.ts.map +1 -1
- package/dist/src/symbols/reference.js +1 -1
- package/dist/src/symbols/reference.js.map +1 -1
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/src/utils.js +1 -1
- package/dist/src/utils.js.map +1 -1
- package/dist/test/callsignatures.test.js +42 -64
- package/dist/test/callsignatures.test.js.map +1 -1
- package/dist/test/class-method-declaration.test.d.ts +2 -0
- package/dist/test/class-method-declaration.test.d.ts.map +1 -0
- package/dist/test/class-method-declaration.test.js +61 -0
- package/dist/test/class-method-declaration.test.js.map +1 -0
- package/dist/test/classdeclarations.test.js +6 -8
- package/dist/test/classdeclarations.test.js.map +1 -1
- package/dist/test/constructordeclaration.test.d.ts +2 -0
- package/dist/test/constructordeclaration.test.d.ts.map +1 -0
- package/dist/test/constructordeclaration.test.js +58 -0
- package/dist/test/constructordeclaration.test.js.map +1 -0
- package/dist/test/dundermethoddeclaration.test.d.ts +2 -0
- package/dist/test/dundermethoddeclaration.test.d.ts.map +1 -0
- package/dist/test/dundermethoddeclaration.test.js +65 -0
- package/dist/test/dundermethoddeclaration.test.js.map +1 -0
- package/dist/test/enums.test.js +14 -16
- package/dist/test/enums.test.js.map +1 -1
- package/dist/test/externals.test.js +2 -4
- package/dist/test/externals.test.js.map +1 -1
- package/dist/test/factories.test.d.ts +2 -0
- package/dist/test/factories.test.d.ts.map +1 -0
- package/dist/test/factories.test.js +78 -0
- package/dist/test/factories.test.js.map +1 -0
- package/dist/test/functiondeclaration.test.js +213 -59
- package/dist/test/functiondeclaration.test.js.map +1 -1
- package/dist/test/memberexpressions.test.js +1 -1
- package/dist/test/memberexpressions.test.js.map +1 -1
- package/dist/test/methoddeclaration.test.d.ts +2 -0
- package/dist/test/methoddeclaration.test.d.ts.map +1 -0
- package/dist/test/methoddeclaration.test.js +239 -0
- package/dist/test/methoddeclaration.test.js.map +1 -0
- package/dist/test/namepolicies.test.js +1 -2
- package/dist/test/namepolicies.test.js.map +1 -1
- package/dist/test/propertydeclaration.test.d.ts +2 -0
- package/dist/test/propertydeclaration.test.d.ts.map +1 -0
- package/dist/test/propertydeclaration.test.js +229 -0
- package/dist/test/propertydeclaration.test.js.map +1 -0
- package/dist/test/pydocs.test.js +926 -126
- package/dist/test/pydocs.test.js.map +1 -1
- package/dist/test/references.test.js +1 -5
- package/dist/test/references.test.js.map +1 -1
- package/dist/test/sourcefiles.test.js +90 -1
- package/dist/test/sourcefiles.test.js.map +1 -1
- package/dist/test/staticmethoddeclaration.test.d.ts +2 -0
- package/dist/test/staticmethoddeclaration.test.d.ts.map +1 -0
- package/dist/test/staticmethoddeclaration.test.js +61 -0
- package/dist/test/staticmethoddeclaration.test.js.map +1 -0
- package/dist/test/typereference.test.d.ts +2 -0
- package/dist/test/typereference.test.d.ts.map +1 -0
- package/dist/test/typereference.test.js +51 -0
- package/dist/test/typereference.test.js.map +1 -0
- package/dist/test/uniontypeexpression.test.js +152 -15
- package/dist/test/uniontypeexpression.test.js.map +1 -1
- package/dist/test/variables.test.js +28 -19
- package/dist/test/variables.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/builtins/python.ts +7 -0
- package/src/components/CallSignature.tsx +17 -69
- package/src/components/ClassMethodDeclaration.tsx +34 -0
- package/src/components/ConstructorDeclaration.tsx +37 -0
- package/src/components/DunderMethodDeclaration.tsx +30 -0
- package/src/components/EnumDeclaration.tsx +16 -44
- package/src/components/EnumMember.tsx +3 -3
- package/src/components/FunctionBase.tsx +88 -0
- package/src/components/FunctionDeclaration.tsx +18 -82
- package/src/components/MethodBase.tsx +53 -0
- package/src/components/MethodDeclaration.tsx +27 -0
- package/src/components/PropertyDeclaration.tsx +264 -0
- package/src/components/PyDoc.tsx +795 -195
- package/src/components/SourceFile.tsx +29 -0
- package/src/components/StaticMethodDeclaration.tsx +34 -0
- package/src/components/TypeArguments.tsx +24 -0
- package/src/components/TypeReference.tsx +33 -0
- package/src/components/UnionTypeExpression.tsx +4 -15
- package/src/components/VariableDeclaration.tsx +1 -3
- package/src/components/index.ts +10 -0
- package/src/parameter-descriptor.ts +6 -5
- package/src/symbol-creation.ts +17 -0
- package/src/symbols/factories.ts +39 -0
- package/src/symbols/index.ts +1 -0
- package/src/symbols/reference.tsx +3 -5
- package/src/utils.ts +0 -2
- package/temp/api.json +5281 -2273
- package/test/callsignatures.test.tsx +102 -74
- package/test/class-method-declaration.test.tsx +53 -0
- package/test/classdeclarations.test.tsx +7 -9
- package/test/constructordeclaration.test.tsx +48 -0
- package/test/dundermethoddeclaration.test.tsx +53 -0
- package/test/enums.test.tsx +14 -16
- package/test/externals.test.tsx +5 -7
- package/test/factories.test.tsx +72 -0
- package/test/functiondeclaration.test.tsx +196 -44
- package/test/memberexpressions.test.tsx +7 -2
- package/test/methoddeclaration.test.tsx +202 -0
- package/test/namepolicies.test.tsx +1 -2
- package/test/propertydeclaration.test.tsx +192 -0
- package/test/pydocs.test.tsx +1093 -129
- package/test/references.test.tsx +1 -1
- package/test/sourcefiles.test.tsx +100 -1
- package/test/staticmethoddeclaration.test.tsx +49 -0
- package/test/typereference.test.tsx +52 -0
- package/test/uniontypeexpression.test.tsx +169 -34
- package/test/variables.test.tsx +27 -16
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import * as py from "../src/index.js";
|
|
3
|
+
import { toSourceText } from "./utils.js";
|
|
4
|
+
|
|
5
|
+
describe("Symbol factories", () => {
|
|
6
|
+
it("createMethodSymbol throws outside class", () => {
|
|
7
|
+
expect(() => {
|
|
8
|
+
toSourceText([<py.MethodDeclaration name="m" />]);
|
|
9
|
+
}).toThrow('Method "m" must be declared inside a class (member scope)');
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it("createMethodSymbol succeeds inside class", () => {
|
|
13
|
+
const result = toSourceText([
|
|
14
|
+
<py.ClassDeclaration name="C">
|
|
15
|
+
<py.MethodDeclaration name="m" />
|
|
16
|
+
</py.ClassDeclaration>,
|
|
17
|
+
]);
|
|
18
|
+
expect(result).toContain("def m(self):");
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it("createFunctionSymbol usable in member scope (top-level function component still works nested)", () => {
|
|
22
|
+
const result = toSourceText([
|
|
23
|
+
<py.ClassDeclaration name="C">
|
|
24
|
+
<py.StatementList>
|
|
25
|
+
<py.FunctionDeclaration name="f" />
|
|
26
|
+
</py.StatementList>
|
|
27
|
+
</py.ClassDeclaration>,
|
|
28
|
+
]);
|
|
29
|
+
// Nested free functions render without self/cls
|
|
30
|
+
expect(result).toContain("def f():");
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
describe("Validation Errors", () => {
|
|
35
|
+
it("throws error when PropertyDeclaration is used outside of a class", () => {
|
|
36
|
+
expect(() => {
|
|
37
|
+
toSourceText([<py.PropertyDeclaration name="x" />]);
|
|
38
|
+
}).toThrow('Method "x" must be declared inside a class (member scope)');
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it("throws error when MethodDeclaration is used outside of a class", () => {
|
|
42
|
+
expect(() => {
|
|
43
|
+
toSourceText([<py.MethodDeclaration name="my_method" />]);
|
|
44
|
+
}).toThrow(
|
|
45
|
+
'Method "my_method" must be declared inside a class (member scope)',
|
|
46
|
+
);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it("throws error when ClassMethodDeclaration is used outside of a class", () => {
|
|
50
|
+
expect(() => {
|
|
51
|
+
toSourceText([<py.ClassMethodDeclaration name="my_class_method" />]);
|
|
52
|
+
}).toThrow(
|
|
53
|
+
'Method "my_class_method" must be declared inside a class (member scope)',
|
|
54
|
+
);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it("throws error when StaticMethodDeclaration is used outside of a class", () => {
|
|
58
|
+
expect(() => {
|
|
59
|
+
toSourceText([<py.StaticMethodDeclaration name="my_static_method" />]);
|
|
60
|
+
}).toThrow(
|
|
61
|
+
'Method "my_static_method" must be declared inside a class (member scope)',
|
|
62
|
+
);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it("throws error when DunderMethodDeclaration is used outside of a class", () => {
|
|
66
|
+
expect(() => {
|
|
67
|
+
toSourceText([<py.DunderMethodDeclaration name="__init__" />]);
|
|
68
|
+
}).toThrow(
|
|
69
|
+
'Method "__init__" must be declared inside a class (member scope)',
|
|
70
|
+
);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { namekey, refkey } from "@alloy-js/core";
|
|
1
|
+
import { code, namekey, refkey } from "@alloy-js/core";
|
|
2
2
|
import { d } from "@alloy-js/core/testing";
|
|
3
3
|
import { describe, expect, it } from "vitest";
|
|
4
4
|
import * as py from "../src/index.js";
|
|
5
|
+
import { abcModule } from "../src/index.js";
|
|
5
6
|
import {
|
|
6
7
|
assertFileContents,
|
|
7
8
|
toSourceText,
|
|
@@ -74,24 +75,6 @@ describe("Function Declaration", () => {
|
|
|
74
75
|
`);
|
|
75
76
|
});
|
|
76
77
|
|
|
77
|
-
it("renders an instance function with a body", () => {
|
|
78
|
-
const result = toSourceText([
|
|
79
|
-
<py.ClassDeclaration name="MyClass">
|
|
80
|
-
<py.FunctionDeclaration name="bar" instanceFunction={true}>
|
|
81
|
-
print('hi')
|
|
82
|
-
</py.FunctionDeclaration>
|
|
83
|
-
</py.ClassDeclaration>,
|
|
84
|
-
]);
|
|
85
|
-
expect(result).toRenderTo(d`
|
|
86
|
-
class MyClass:
|
|
87
|
-
def bar(self):
|
|
88
|
-
print('hi')
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
`);
|
|
93
|
-
});
|
|
94
|
-
|
|
95
78
|
it("renders a function with parameters", () => {
|
|
96
79
|
const result = toSourceText([
|
|
97
80
|
<py.FunctionDeclaration
|
|
@@ -120,7 +103,10 @@ describe("Function Declaration", () => {
|
|
|
120
103
|
it("renders an __init__ function with no body as 'pass'", () => {
|
|
121
104
|
const result = toSourceText([
|
|
122
105
|
<py.ClassDeclaration name="MyClass">
|
|
123
|
-
<py.
|
|
106
|
+
<py.DunderMethodDeclaration
|
|
107
|
+
name="__init__"
|
|
108
|
+
parameters={[{ name: "x" }]}
|
|
109
|
+
/>
|
|
124
110
|
</py.ClassDeclaration>,
|
|
125
111
|
]);
|
|
126
112
|
expect(result).toRenderTo(d`
|
|
@@ -144,7 +130,7 @@ describe("Function Declaration", () => {
|
|
|
144
130
|
it("can be an async function with returnType", () => {
|
|
145
131
|
expect(
|
|
146
132
|
toSourceText([
|
|
147
|
-
<py.FunctionDeclaration async name="foo" returnType="Foo" />,
|
|
133
|
+
<py.FunctionDeclaration async name="foo" returnType={"Foo"} />,
|
|
148
134
|
]),
|
|
149
135
|
).toBe(d`
|
|
150
136
|
async def foo() -> Foo:
|
|
@@ -154,6 +140,24 @@ describe("Function Declaration", () => {
|
|
|
154
140
|
});
|
|
155
141
|
|
|
156
142
|
it("can be an async function with returnType element with Reference", () => {
|
|
143
|
+
expect(
|
|
144
|
+
toSourceText([
|
|
145
|
+
<py.StatementList>
|
|
146
|
+
<py.ClassDeclaration name="Foo" refkey={refkey("Foo")} />
|
|
147
|
+
<py.FunctionDeclaration async name="foo" returnType={refkey("Foo")} />
|
|
148
|
+
</py.StatementList>,
|
|
149
|
+
]),
|
|
150
|
+
).toBe(d`
|
|
151
|
+
class Foo:
|
|
152
|
+
pass
|
|
153
|
+
|
|
154
|
+
async def foo() -> Foo:
|
|
155
|
+
pass
|
|
156
|
+
|
|
157
|
+
`);
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it("can be an async function with returnType element with list of References", () => {
|
|
157
161
|
expect(
|
|
158
162
|
toSourceText([
|
|
159
163
|
<py.StatementList>
|
|
@@ -161,7 +165,7 @@ describe("Function Declaration", () => {
|
|
|
161
165
|
<py.FunctionDeclaration
|
|
162
166
|
async
|
|
163
167
|
name="foo"
|
|
164
|
-
returnType={
|
|
168
|
+
returnType={code`list[${refkey("Foo")}]`}
|
|
165
169
|
/>
|
|
166
170
|
</py.StatementList>,
|
|
167
171
|
]),
|
|
@@ -169,15 +173,66 @@ describe("Function Declaration", () => {
|
|
|
169
173
|
class Foo:
|
|
170
174
|
pass
|
|
171
175
|
|
|
172
|
-
async def foo() -> Foo:
|
|
176
|
+
async def foo() -> list[Foo]:
|
|
173
177
|
pass
|
|
174
178
|
|
|
175
179
|
`);
|
|
176
180
|
});
|
|
177
181
|
|
|
182
|
+
it("can be an async dunder method", () => {
|
|
183
|
+
const decl = (
|
|
184
|
+
<py.StatementList>
|
|
185
|
+
<py.ClassDeclaration name="MyClass">
|
|
186
|
+
<py.StatementList>
|
|
187
|
+
<py.DunderMethodDeclaration
|
|
188
|
+
async
|
|
189
|
+
name="__aenter__"
|
|
190
|
+
returnType={"MyClass"}
|
|
191
|
+
>
|
|
192
|
+
return self
|
|
193
|
+
</py.DunderMethodDeclaration>
|
|
194
|
+
</py.StatementList>
|
|
195
|
+
</py.ClassDeclaration>
|
|
196
|
+
</py.StatementList>
|
|
197
|
+
);
|
|
198
|
+
|
|
199
|
+
expect(toSourceText([decl])).toBe(d`
|
|
200
|
+
class MyClass:
|
|
201
|
+
async def __aenter__(self) -> MyClass:
|
|
202
|
+
return self
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
`);
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
it("can be an async constructor", () => {
|
|
209
|
+
const decl = (
|
|
210
|
+
<py.StatementList>
|
|
211
|
+
<py.ClassDeclaration name="MyClass">
|
|
212
|
+
<py.StatementList>
|
|
213
|
+
<py.ConstructorDeclaration async returnType={"MyClass"}>
|
|
214
|
+
return super().__new__(cls)
|
|
215
|
+
</py.ConstructorDeclaration>
|
|
216
|
+
</py.StatementList>
|
|
217
|
+
</py.ClassDeclaration>
|
|
218
|
+
</py.StatementList>
|
|
219
|
+
);
|
|
220
|
+
|
|
221
|
+
expect(toSourceText([decl])).toBe(d`
|
|
222
|
+
class MyClass:
|
|
223
|
+
async def __new__(cls) -> MyClass:
|
|
224
|
+
return super().__new__(cls)
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
`);
|
|
228
|
+
});
|
|
229
|
+
|
|
178
230
|
it("supports parameters", () => {
|
|
179
231
|
const decl = (
|
|
180
|
-
<py.FunctionDeclaration
|
|
232
|
+
<py.FunctionDeclaration
|
|
233
|
+
name="foo"
|
|
234
|
+
parameters={[{ name: "a" }, { name: "b" }]}
|
|
235
|
+
>
|
|
181
236
|
return a + b
|
|
182
237
|
</py.FunctionDeclaration>
|
|
183
238
|
);
|
|
@@ -192,7 +247,7 @@ describe("Function Declaration", () => {
|
|
|
192
247
|
const decl = (
|
|
193
248
|
<py.FunctionDeclaration
|
|
194
249
|
name="foo"
|
|
195
|
-
parameters={["a", "b"]}
|
|
250
|
+
parameters={[{ name: "a" }, { name: "b" }]}
|
|
196
251
|
typeParameters={["T", "U"]}
|
|
197
252
|
>
|
|
198
253
|
return a + b
|
|
@@ -205,42 +260,95 @@ describe("Function Declaration", () => {
|
|
|
205
260
|
|
|
206
261
|
`);
|
|
207
262
|
});
|
|
208
|
-
it("renders
|
|
263
|
+
it("renders abstract methods", () => {
|
|
264
|
+
const parameters = [{ name: "x", type: "int" }];
|
|
265
|
+
const decl = (
|
|
266
|
+
<py.StatementList>
|
|
267
|
+
<py.ClassDeclaration name="MyClass">
|
|
268
|
+
<py.StatementList>
|
|
269
|
+
<py.MethodDeclaration
|
|
270
|
+
name="methoddef"
|
|
271
|
+
parameters={parameters}
|
|
272
|
+
abstract
|
|
273
|
+
/>
|
|
274
|
+
<py.ClassMethodDeclaration
|
|
275
|
+
name="classdef"
|
|
276
|
+
parameters={parameters}
|
|
277
|
+
abstract
|
|
278
|
+
/>
|
|
279
|
+
<py.StaticMethodDeclaration
|
|
280
|
+
name="staticdef"
|
|
281
|
+
parameters={parameters}
|
|
282
|
+
abstract
|
|
283
|
+
/>
|
|
284
|
+
</py.StatementList>
|
|
285
|
+
</py.ClassDeclaration>
|
|
286
|
+
</py.StatementList>
|
|
287
|
+
);
|
|
288
|
+
|
|
289
|
+
expect(toSourceText([decl], { externals: [abcModule] })).toBe(d`
|
|
290
|
+
from abc import abstractmethod
|
|
291
|
+
|
|
292
|
+
class MyClass:
|
|
293
|
+
@abstractmethod
|
|
294
|
+
def methoddef(self, x: int):
|
|
295
|
+
pass
|
|
296
|
+
|
|
297
|
+
@classmethod
|
|
298
|
+
@abstractmethod
|
|
299
|
+
def classdef(cls, x: int):
|
|
300
|
+
pass
|
|
301
|
+
|
|
302
|
+
@staticmethod
|
|
303
|
+
@abstractmethod
|
|
304
|
+
def staticdef(x: int):
|
|
305
|
+
pass
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
`);
|
|
309
|
+
});
|
|
310
|
+
it("renders dunder methods with parameters", () => {
|
|
209
311
|
const parameters = [{ name: "x", type: "int" }];
|
|
210
312
|
const decl = (
|
|
211
313
|
<py.ClassDeclaration name="MyClass">
|
|
212
|
-
<py.
|
|
213
|
-
name="
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
314
|
+
<py.StatementList>
|
|
315
|
+
<py.DunderMethodDeclaration name="__init__" parameters={parameters}>
|
|
316
|
+
self.attribute = "value"
|
|
317
|
+
</py.DunderMethodDeclaration>
|
|
318
|
+
<py.DunderMethodDeclaration name="__repr__" parameters={parameters}>
|
|
319
|
+
return "MyClass"
|
|
320
|
+
</py.DunderMethodDeclaration>
|
|
321
|
+
</py.StatementList>
|
|
219
322
|
</py.ClassDeclaration>
|
|
220
323
|
);
|
|
221
324
|
|
|
222
325
|
expect(toSourceText([decl])).toBe(d`
|
|
223
326
|
class MyClass:
|
|
224
|
-
def
|
|
327
|
+
def __init__(self, x: int):
|
|
225
328
|
self.attribute = "value"
|
|
226
329
|
|
|
330
|
+
def __repr__(self, x: int):
|
|
331
|
+
return "MyClass"
|
|
332
|
+
|
|
227
333
|
|
|
228
334
|
`);
|
|
229
335
|
});
|
|
230
|
-
|
|
231
|
-
|
|
336
|
+
|
|
337
|
+
it("renders dunder methods __new__", () => {
|
|
232
338
|
const decl = (
|
|
233
339
|
<py.ClassDeclaration name="MyClass">
|
|
234
|
-
<py.
|
|
235
|
-
|
|
236
|
-
|
|
340
|
+
<py.StatementList>
|
|
341
|
+
<py.ConstructorDeclaration args kwargs>
|
|
342
|
+
pass
|
|
343
|
+
</py.ConstructorDeclaration>
|
|
344
|
+
</py.StatementList>
|
|
237
345
|
</py.ClassDeclaration>
|
|
238
346
|
);
|
|
239
347
|
|
|
240
348
|
expect(toSourceText([decl])).toBe(d`
|
|
241
349
|
class MyClass:
|
|
242
|
-
def
|
|
243
|
-
|
|
350
|
+
def __new__(cls, *args, **kwargs):
|
|
351
|
+
pass
|
|
244
352
|
|
|
245
353
|
|
|
246
354
|
`);
|
|
@@ -309,12 +417,18 @@ describe("Function Declaration", () => {
|
|
|
309
417
|
async
|
|
310
418
|
name="foo"
|
|
311
419
|
parameters={[
|
|
312
|
-
{
|
|
313
|
-
|
|
420
|
+
{
|
|
421
|
+
name: "x",
|
|
422
|
+
type: refkey("A"),
|
|
423
|
+
},
|
|
424
|
+
{
|
|
425
|
+
name: "y",
|
|
426
|
+
type: refkey("B"),
|
|
427
|
+
},
|
|
314
428
|
]}
|
|
315
429
|
args={true}
|
|
316
430
|
kwargs={true}
|
|
317
|
-
returnType={
|
|
431
|
+
returnType={refkey("Foo")}
|
|
318
432
|
/>
|
|
319
433
|
</py.SourceFile>,
|
|
320
434
|
]);
|
|
@@ -345,4 +459,42 @@ describe("Function Declaration", () => {
|
|
|
345
459
|
`,
|
|
346
460
|
});
|
|
347
461
|
});
|
|
462
|
+
|
|
463
|
+
it("throws error when PropertyDeclaration is used outside of a class", () => {
|
|
464
|
+
expect(() => {
|
|
465
|
+
toSourceText([<py.PropertyDeclaration name="x" />]);
|
|
466
|
+
}).toThrow('Method "x" must be declared inside a class (member scope)');
|
|
467
|
+
});
|
|
468
|
+
|
|
469
|
+
it("throws error when MethodDeclaration is used outside of a class", () => {
|
|
470
|
+
expect(() => {
|
|
471
|
+
toSourceText([<py.MethodDeclaration name="my_method" />]);
|
|
472
|
+
}).toThrow(
|
|
473
|
+
'Method "my_method" must be declared inside a class (member scope)',
|
|
474
|
+
);
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
it("throws error when ClassMethodDeclaration is used outside of a class", () => {
|
|
478
|
+
expect(() => {
|
|
479
|
+
toSourceText([<py.ClassMethodDeclaration name="my_class_method" />]);
|
|
480
|
+
}).toThrow(
|
|
481
|
+
'Method "my_class_method" must be declared inside a class (member scope)',
|
|
482
|
+
);
|
|
483
|
+
});
|
|
484
|
+
|
|
485
|
+
it("throws error when StaticMethodDeclaration is used outside of a class", () => {
|
|
486
|
+
expect(() => {
|
|
487
|
+
toSourceText([<py.StaticMethodDeclaration name="my_static_method" />]);
|
|
488
|
+
}).toThrow(
|
|
489
|
+
'Method "my_static_method" must be declared inside a class (member scope)',
|
|
490
|
+
);
|
|
491
|
+
});
|
|
492
|
+
|
|
493
|
+
it("throws error when DunderMethodDeclaration is used outside of a class", () => {
|
|
494
|
+
expect(() => {
|
|
495
|
+
toSourceText([<py.DunderMethodDeclaration name="__init__" />]);
|
|
496
|
+
}).toThrow(
|
|
497
|
+
'Method "__init__" must be declared inside a class (member scope)',
|
|
498
|
+
);
|
|
499
|
+
});
|
|
348
500
|
});
|
|
@@ -424,7 +424,12 @@ describe("with refkeys", () => {
|
|
|
424
424
|
const fooRef = refkey();
|
|
425
425
|
const modelRef = refkey();
|
|
426
426
|
const parameters: ParameterDescriptor[] = [
|
|
427
|
-
{
|
|
427
|
+
{
|
|
428
|
+
name: "foo",
|
|
429
|
+
default: null,
|
|
430
|
+
refkey: fooRef,
|
|
431
|
+
type: modelRef,
|
|
432
|
+
},
|
|
428
433
|
];
|
|
429
434
|
const messageRef = refkey();
|
|
430
435
|
const template = (
|
|
@@ -480,7 +485,7 @@ describe("with refkeys", () => {
|
|
|
480
485
|
<VariableDeclaration
|
|
481
486
|
name="prop1"
|
|
482
487
|
refkey={interfaceMemberRefkey}
|
|
483
|
-
type=
|
|
488
|
+
type="str"
|
|
484
489
|
omitNone={true}
|
|
485
490
|
/>
|
|
486
491
|
</ClassDeclaration>
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { d } from "@alloy-js/core/testing";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
import * as py from "../src/index.js";
|
|
4
|
+
import { abcModule } from "../src/index.js";
|
|
5
|
+
import { toSourceText } from "./utils.js";
|
|
6
|
+
|
|
7
|
+
describe("Method-like Declarations", () => {
|
|
8
|
+
it("renders an instance function with a body", () => {
|
|
9
|
+
const result = toSourceText([
|
|
10
|
+
<py.ClassDeclaration name="MyClass">
|
|
11
|
+
<py.MethodDeclaration name="bar">print('hi')</py.MethodDeclaration>
|
|
12
|
+
</py.ClassDeclaration>,
|
|
13
|
+
]);
|
|
14
|
+
expect(result).toRenderTo(d`
|
|
15
|
+
class MyClass:
|
|
16
|
+
def bar(self):
|
|
17
|
+
print('hi')
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
`);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it("can be an async method", () => {
|
|
25
|
+
const decl = (
|
|
26
|
+
<py.StatementList>
|
|
27
|
+
<py.ClassDeclaration name="MyClass">
|
|
28
|
+
<py.StatementList>
|
|
29
|
+
<py.MethodDeclaration async name="my_method" returnType="str">
|
|
30
|
+
return "async result"
|
|
31
|
+
</py.MethodDeclaration>
|
|
32
|
+
</py.StatementList>
|
|
33
|
+
</py.ClassDeclaration>
|
|
34
|
+
</py.StatementList>
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
expect(toSourceText([decl])).toBe(d`
|
|
38
|
+
class MyClass:
|
|
39
|
+
async def my_method(self) -> str:
|
|
40
|
+
return "async result"
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
`);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("can be an async class method", () => {
|
|
47
|
+
const decl = (
|
|
48
|
+
<py.StatementList>
|
|
49
|
+
<py.ClassDeclaration name="MyClass">
|
|
50
|
+
<py.StatementList>
|
|
51
|
+
<py.ClassMethodDeclaration
|
|
52
|
+
async
|
|
53
|
+
name="create_async"
|
|
54
|
+
returnType={"MyClass"}
|
|
55
|
+
>
|
|
56
|
+
return cls()
|
|
57
|
+
</py.ClassMethodDeclaration>
|
|
58
|
+
</py.StatementList>
|
|
59
|
+
</py.ClassDeclaration>
|
|
60
|
+
</py.StatementList>
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
expect(toSourceText([decl])).toBe(d`
|
|
64
|
+
class MyClass:
|
|
65
|
+
@classmethod
|
|
66
|
+
async def create_async(cls) -> MyClass:
|
|
67
|
+
return cls()
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
`);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it("can be an async static method", () => {
|
|
74
|
+
const decl = (
|
|
75
|
+
<py.StatementList>
|
|
76
|
+
<py.ClassDeclaration name="MyClass">
|
|
77
|
+
<py.StatementList>
|
|
78
|
+
<py.StaticMethodDeclaration async name="utility" returnType="str">
|
|
79
|
+
return "utility result"
|
|
80
|
+
</py.StaticMethodDeclaration>
|
|
81
|
+
</py.StatementList>
|
|
82
|
+
</py.ClassDeclaration>
|
|
83
|
+
</py.StatementList>
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
expect(toSourceText([decl])).toBe(d`
|
|
87
|
+
class MyClass:
|
|
88
|
+
@staticmethod
|
|
89
|
+
async def utility() -> str:
|
|
90
|
+
return "utility result"
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
`);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it("renders method with parameters", () => {
|
|
97
|
+
const parameters = [{ name: "x", type: "int" }];
|
|
98
|
+
const decl = (
|
|
99
|
+
<py.ClassDeclaration name="MyClass">
|
|
100
|
+
<py.MethodDeclaration name="foo" parameters={parameters}>
|
|
101
|
+
self.attribute = "value"
|
|
102
|
+
</py.MethodDeclaration>
|
|
103
|
+
</py.ClassDeclaration>
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
expect(toSourceText([decl])).toBe(d`
|
|
107
|
+
class MyClass:
|
|
108
|
+
def foo(self, x: int):
|
|
109
|
+
self.attribute = "value"
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
`);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it("renders class method with parameters", () => {
|
|
116
|
+
const parameters = [{ name: "x", type: "int" }];
|
|
117
|
+
const decl = (
|
|
118
|
+
<py.ClassDeclaration name="MyClass">
|
|
119
|
+
<py.ClassMethodDeclaration name="foo" parameters={parameters}>
|
|
120
|
+
self.attribute = "value"
|
|
121
|
+
</py.ClassMethodDeclaration>
|
|
122
|
+
</py.ClassDeclaration>
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
expect(toSourceText([decl])).toBe(d`
|
|
126
|
+
class MyClass:
|
|
127
|
+
@classmethod
|
|
128
|
+
def foo(cls, x: int):
|
|
129
|
+
self.attribute = "value"
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
`);
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it("renders static method with parameters", () => {
|
|
136
|
+
const parameters = [{ name: "x", type: "int" }];
|
|
137
|
+
const decl = (
|
|
138
|
+
<py.ClassDeclaration name="MyClass">
|
|
139
|
+
<py.StaticMethodDeclaration name="foo" parameters={parameters}>
|
|
140
|
+
attribute = "value"
|
|
141
|
+
</py.StaticMethodDeclaration>
|
|
142
|
+
</py.ClassDeclaration>
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
expect(toSourceText([decl])).toBe(d`
|
|
146
|
+
class MyClass:
|
|
147
|
+
@staticmethod
|
|
148
|
+
def foo(x: int):
|
|
149
|
+
attribute = "value"
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
`);
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
it("renders abstract methods", () => {
|
|
156
|
+
const parameters = [{ name: "x", type: "int" }];
|
|
157
|
+
const decl = (
|
|
158
|
+
<py.StatementList>
|
|
159
|
+
<py.ClassDeclaration name="MyClass">
|
|
160
|
+
<py.StatementList>
|
|
161
|
+
<py.MethodDeclaration
|
|
162
|
+
name="methoddef"
|
|
163
|
+
parameters={parameters}
|
|
164
|
+
abstract
|
|
165
|
+
/>
|
|
166
|
+
<py.ClassMethodDeclaration
|
|
167
|
+
name="classdef"
|
|
168
|
+
parameters={parameters}
|
|
169
|
+
abstract
|
|
170
|
+
/>
|
|
171
|
+
<py.StaticMethodDeclaration
|
|
172
|
+
name="staticdef"
|
|
173
|
+
parameters={parameters}
|
|
174
|
+
abstract
|
|
175
|
+
/>
|
|
176
|
+
</py.StatementList>
|
|
177
|
+
</py.ClassDeclaration>
|
|
178
|
+
</py.StatementList>
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
expect(toSourceText([decl], { externals: [abcModule] })).toBe(d`
|
|
182
|
+
from abc import abstractmethod
|
|
183
|
+
|
|
184
|
+
class MyClass:
|
|
185
|
+
@abstractmethod
|
|
186
|
+
def methoddef(self, x: int):
|
|
187
|
+
pass
|
|
188
|
+
|
|
189
|
+
@classmethod
|
|
190
|
+
@abstractmethod
|
|
191
|
+
def classdef(cls, x: int):
|
|
192
|
+
pass
|
|
193
|
+
|
|
194
|
+
@staticmethod
|
|
195
|
+
@abstractmethod
|
|
196
|
+
def staticdef(x: int):
|
|
197
|
+
pass
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
`);
|
|
201
|
+
});
|
|
202
|
+
});
|
|
@@ -20,9 +20,8 @@ it("correct formatting of class name", () => {
|
|
|
20
20
|
it("correct formatting of Enum name and EnumMember names", () => {
|
|
21
21
|
const result = toSourceText(
|
|
22
22
|
[
|
|
23
|
-
<py.
|
|
23
|
+
<py.FunctionalEnumDeclaration
|
|
24
24
|
name="priority"
|
|
25
|
-
style="functional"
|
|
26
25
|
members={[
|
|
27
26
|
{ name: "high", value: 1 },
|
|
28
27
|
{ name: "Medium", value: 2 },
|