@alloy-js/python 0.5.0-dev.1 → 0.5.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.
Files changed (217) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/dev/src/components/CallSignature.js +2 -2
  3. package/dist/dev/src/components/CallSignature.js.map +1 -1
  4. package/dist/dev/src/components/ConstructorDeclaration.js +1 -1
  5. package/dist/dev/src/components/ConstructorDeclaration.js.map +1 -1
  6. package/dist/dev/src/components/DataclassDeclaration.js +5 -5
  7. package/dist/dev/src/components/DataclassDeclaration.js.map +1 -1
  8. package/dist/dev/src/components/FunctionBase.js +9 -9
  9. package/dist/dev/src/components/FunctionBase.js.map +1 -1
  10. package/dist/dev/src/components/PropertyDeclaration.js +8 -8
  11. package/dist/dev/src/components/PropertyDeclaration.js.map +1 -1
  12. package/dist/dev/src/components/PyDoc.js +64 -64
  13. package/dist/dev/src/components/PyDoc.js.map +1 -1
  14. package/dist/dev/src/components/PydanticClassDeclaration.js +5 -5
  15. package/dist/dev/src/components/PydanticClassDeclaration.js.map +1 -1
  16. package/dist/dev/src/components/SourceFile.js +44 -32
  17. package/dist/dev/src/components/SourceFile.js.map +1 -1
  18. package/dist/dev/src/symbols/python-output-symbol.js.map +1 -1
  19. package/dist/dev/test/callsignatures.test.js +471 -297
  20. package/dist/dev/test/callsignatures.test.js.map +1 -1
  21. package/dist/dev/test/class-method-declaration.test.js +21 -10
  22. package/dist/dev/test/class-method-declaration.test.js.map +1 -1
  23. package/dist/dev/test/classdeclarations.test.js +459 -393
  24. package/dist/dev/test/classdeclarations.test.js.map +1 -1
  25. package/dist/dev/test/classinstantiations.test.js +201 -168
  26. package/dist/dev/test/classinstantiations.test.js.map +1 -1
  27. package/dist/dev/test/constructordeclaration.test.js +22 -11
  28. package/dist/dev/test/constructordeclaration.test.js.map +1 -1
  29. package/dist/dev/test/dataclassdeclarations.test.js +322 -368
  30. package/dist/dev/test/dataclassdeclarations.test.js.map +1 -1
  31. package/dist/dev/test/decoratorlist.test.js +96 -49
  32. package/dist/dev/test/decoratorlist.test.js.map +1 -1
  33. package/dist/dev/test/dundermethoddeclaration.test.js +22 -11
  34. package/dist/dev/test/dundermethoddeclaration.test.js.map +1 -1
  35. package/dist/dev/test/enums.test.js +218 -184
  36. package/dist/dev/test/enums.test.js.map +1 -1
  37. package/dist/dev/test/externals.test.js +57 -45
  38. package/dist/dev/test/externals.test.js.map +1 -1
  39. package/dist/dev/test/factories.test.js +124 -50
  40. package/dist/dev/test/factories.test.js.map +1 -1
  41. package/dist/dev/test/functioncallexpressions.test.js +199 -164
  42. package/dist/dev/test/functioncallexpressions.test.js.map +1 -1
  43. package/dist/dev/test/functiondeclaration.test.js +439 -272
  44. package/dist/dev/test/functiondeclaration.test.js.map +1 -1
  45. package/dist/dev/test/imports.test.js +273 -221
  46. package/dist/dev/test/imports.test.js.map +1 -1
  47. package/dist/dev/test/memberexpressions.test.js +1237 -972
  48. package/dist/dev/test/memberexpressions.test.js.map +1 -1
  49. package/dist/dev/test/methoddeclaration.test.js +142 -78
  50. package/dist/dev/test/methoddeclaration.test.js.map +1 -1
  51. package/dist/dev/test/namepolicies.test.js +130 -94
  52. package/dist/dev/test/namepolicies.test.js.map +1 -1
  53. package/dist/dev/test/propertydeclaration.test.js +88 -59
  54. package/dist/dev/test/propertydeclaration.test.js.map +1 -1
  55. package/dist/dev/test/pydanticclassdeclarations.test.js +299 -347
  56. package/dist/dev/test/pydanticclassdeclarations.test.js.map +1 -1
  57. package/dist/dev/test/pydocs.test.js +888 -715
  58. package/dist/dev/test/pydocs.test.js.map +1 -1
  59. package/dist/dev/test/references.test.js +42 -35
  60. package/dist/dev/test/references.test.js.map +1 -1
  61. package/dist/dev/test/sourcefiles.test.js +1109 -841
  62. package/dist/dev/test/sourcefiles.test.js.map +1 -1
  63. package/dist/dev/test/staticmethoddeclaration.test.js +21 -10
  64. package/dist/dev/test/staticmethoddeclaration.test.js.map +1 -1
  65. package/dist/dev/test/type-checking-imports.test.js +408 -359
  66. package/dist/dev/test/type-checking-imports.test.js.map +1 -1
  67. package/dist/dev/test/typereference.test.js +55 -40
  68. package/dist/dev/test/typereference.test.js.map +1 -1
  69. package/dist/dev/test/uniontypeexpression.test.js +222 -146
  70. package/dist/dev/test/uniontypeexpression.test.js.map +1 -1
  71. package/dist/dev/test/utils.js +39 -77
  72. package/dist/dev/test/utils.js.map +1 -1
  73. package/dist/dev/test/values.test.js +237 -101
  74. package/dist/dev/test/values.test.js.map +1 -1
  75. package/dist/dev/test/variables.test.js +321 -203
  76. package/dist/dev/test/variables.test.js.map +1 -1
  77. package/dist/dev/test/vitest.setup.js +2 -0
  78. package/dist/dev/test/vitest.setup.js.map +1 -0
  79. package/dist/src/components/CallSignature.d.ts.map +1 -1
  80. package/dist/src/components/CallSignature.js.map +1 -1
  81. package/dist/src/components/ConstructorDeclaration.d.ts.map +1 -1
  82. package/dist/src/components/ConstructorDeclaration.js.map +1 -1
  83. package/dist/src/components/DataclassDeclaration.d.ts.map +1 -1
  84. package/dist/src/components/DataclassDeclaration.js.map +1 -1
  85. package/dist/src/components/FunctionBase.d.ts.map +1 -1
  86. package/dist/src/components/FunctionBase.js.map +1 -1
  87. package/dist/src/components/PropertyDeclaration.d.ts.map +1 -1
  88. package/dist/src/components/PropertyDeclaration.js.map +1 -1
  89. package/dist/src/components/PyDoc.d.ts.map +1 -1
  90. package/dist/src/components/PyDoc.js.map +1 -1
  91. package/dist/src/components/PydanticClassDeclaration.d.ts.map +1 -1
  92. package/dist/src/components/PydanticClassDeclaration.js.map +1 -1
  93. package/dist/src/components/SourceFile.d.ts +2 -2
  94. package/dist/src/components/SourceFile.d.ts.map +1 -1
  95. package/dist/src/components/SourceFile.js +12 -0
  96. package/dist/src/components/SourceFile.js.map +1 -1
  97. package/dist/src/symbols/python-output-symbol.d.ts.map +1 -1
  98. package/dist/src/symbols/python-output-symbol.js.map +1 -1
  99. package/dist/test/callsignatures.test.js +346 -272
  100. package/dist/test/callsignatures.test.js.map +1 -1
  101. package/dist/test/class-method-declaration.test.js +7 -4
  102. package/dist/test/class-method-declaration.test.js.map +1 -1
  103. package/dist/test/classdeclarations.test.js +302 -288
  104. package/dist/test/classdeclarations.test.js.map +1 -1
  105. package/dist/test/classinstantiations.test.js +112 -103
  106. package/dist/test/classinstantiations.test.js.map +1 -1
  107. package/dist/test/constructordeclaration.test.js +7 -4
  108. package/dist/test/constructordeclaration.test.js.map +1 -1
  109. package/dist/test/dataclassdeclarations.test.js +134 -184
  110. package/dist/test/dataclassdeclarations.test.js.map +1 -1
  111. package/dist/test/decoratorlist.test.js +59 -36
  112. package/dist/test/decoratorlist.test.js.map +1 -1
  113. package/dist/test/dundermethoddeclaration.test.js +7 -4
  114. package/dist/test/dundermethoddeclaration.test.js.map +1 -1
  115. package/dist/test/enums.test.js +161 -159
  116. package/dist/test/enums.test.js.map +1 -1
  117. package/dist/test/externals.test.js +24 -24
  118. package/dist/test/externals.test.js.map +1 -1
  119. package/dist/test/factories.test.js +75 -33
  120. package/dist/test/factories.test.js.map +1 -1
  121. package/dist/test/functioncallexpressions.test.js +117 -106
  122. package/dist/test/functioncallexpressions.test.js.map +1 -1
  123. package/dist/test/functiondeclaration.test.js +247 -180
  124. package/dist/test/functiondeclaration.test.js.map +1 -1
  125. package/dist/test/imports.test.js +171 -143
  126. package/dist/test/imports.test.js.map +1 -1
  127. package/dist/test/memberexpressions.test.js +582 -453
  128. package/dist/test/memberexpressions.test.js.map +1 -1
  129. package/dist/test/methoddeclaration.test.js +66 -46
  130. package/dist/test/methoddeclaration.test.js.map +1 -1
  131. package/dist/test/namepolicies.test.js +90 -78
  132. package/dist/test/namepolicies.test.js.map +1 -1
  133. package/dist/test/propertydeclaration.test.js +25 -20
  134. package/dist/test/propertydeclaration.test.js.map +1 -1
  135. package/dist/test/pydanticclassdeclarations.test.js +134 -190
  136. package/dist/test/pydanticclassdeclarations.test.js.map +1 -1
  137. package/dist/test/pydocs.test.js +573 -532
  138. package/dist/test/pydocs.test.js.map +1 -1
  139. package/dist/test/references.test.js +31 -28
  140. package/dist/test/references.test.js.map +1 -1
  141. package/dist/test/sourcefiles.test.js +700 -580
  142. package/dist/test/sourcefiles.test.js.map +1 -1
  143. package/dist/test/staticmethoddeclaration.test.js +7 -4
  144. package/dist/test/staticmethoddeclaration.test.js.map +1 -1
  145. package/dist/test/type-checking-imports.test.js +297 -284
  146. package/dist/test/type-checking-imports.test.js.map +1 -1
  147. package/dist/test/typereference.test.js +29 -22
  148. package/dist/test/typereference.test.js.map +1 -1
  149. package/dist/test/uniontypeexpression.test.js +124 -88
  150. package/dist/test/uniontypeexpression.test.js.map +1 -1
  151. package/dist/test/utils.d.ts +10 -17
  152. package/dist/test/utils.d.ts.map +1 -1
  153. package/dist/test/utils.js +32 -74
  154. package/dist/test/utils.js.map +1 -1
  155. package/dist/test/values.test.js +135 -67
  156. package/dist/test/values.test.js.map +1 -1
  157. package/dist/test/variables.test.js +201 -151
  158. package/dist/test/variables.test.js.map +1 -1
  159. package/dist/test/vitest.setup.d.ts +2 -0
  160. package/dist/test/vitest.setup.d.ts.map +1 -0
  161. package/dist/test/vitest.setup.js +2 -0
  162. package/dist/test/vitest.setup.js.map +1 -0
  163. package/dist/tsconfig.tsbuildinfo +1 -1
  164. package/docs/api/components/FunctionalEnumDeclaration.md +3 -6
  165. package/docs/api/components/MemberExpression.md +1 -5
  166. package/docs/api/components/SourceFile.md +20 -8
  167. package/docs/api/components/index.md +0 -2
  168. package/docs/api/functions/isTypeRefContext.md +1 -1
  169. package/docs/api/index.md +2 -2
  170. package/docs/api/types/ReferenceProps.md +7 -0
  171. package/docs/api/types/TypeRefContextProps.md +7 -0
  172. package/docs/api/types/index.md +2 -0
  173. package/package.json +11 -10
  174. package/src/components/CallSignature.tsx +4 -2
  175. package/src/components/ConstructorDeclaration.tsx +4 -2
  176. package/src/components/DataclassDeclaration.tsx +1 -2
  177. package/src/components/FunctionBase.tsx +1 -2
  178. package/src/components/PropertyDeclaration.tsx +8 -4
  179. package/src/components/PyDoc.tsx +12 -6
  180. package/src/components/PydanticClassDeclaration.tsx +1 -2
  181. package/src/components/SourceFile.tsx +6 -1
  182. package/src/symbols/python-output-symbol.ts +1 -2
  183. package/temp/api.json +107 -61
  184. package/test/callsignatures.test.tsx +309 -283
  185. package/test/class-method-declaration.test.tsx +3 -4
  186. package/test/classdeclarations.test.tsx +263 -248
  187. package/test/classinstantiations.test.tsx +115 -109
  188. package/test/constructordeclaration.test.tsx +9 -6
  189. package/test/dataclassdeclarations.test.tsx +243 -361
  190. package/test/decoratorlist.test.tsx +78 -59
  191. package/test/dundermethoddeclaration.test.tsx +3 -4
  192. package/test/enums.test.tsx +65 -81
  193. package/test/externals.test.tsx +25 -25
  194. package/test/factories.test.tsx +64 -22
  195. package/test/functioncallexpressions.test.tsx +123 -109
  196. package/test/functiondeclaration.test.tsx +209 -148
  197. package/test/imports.test.tsx +119 -91
  198. package/test/memberexpressions.test.tsx +265 -207
  199. package/test/methoddeclaration.test.tsx +84 -63
  200. package/test/namepolicies.test.tsx +69 -69
  201. package/test/propertydeclaration.test.tsx +7 -8
  202. package/test/pydanticclassdeclarations.test.tsx +355 -487
  203. package/test/pydocs.test.tsx +531 -579
  204. package/test/references.test.tsx +24 -23
  205. package/test/sourcefiles.test.tsx +527 -492
  206. package/test/staticmethoddeclaration.test.tsx +3 -4
  207. package/test/type-checking-imports.test.tsx +206 -218
  208. package/test/typereference.test.tsx +15 -12
  209. package/test/uniontypeexpression.test.tsx +74 -61
  210. package/test/utils.tsx +26 -110
  211. package/test/values.test.tsx +82 -32
  212. package/test/variables.test.tsx +162 -142
  213. package/test/vitest.setup.ts +1 -0
  214. package/tsdoc-metadata.json +1 -1
  215. package/vitest.config.ts +4 -0
  216. package/docs/api/components/Reference.md +0 -31
  217. package/docs/api/components/TypeRefContext.md +0 -41
@@ -1,27 +1,17 @@
1
- import { Prose, namekey, refkey } from "@alloy-js/core";
2
- import { d } from "@alloy-js/core/testing";
1
+ import { Prose, namekey, refkey, render } from "@alloy-js/core";
3
2
  import { describe, expect, it } from "vitest";
4
3
  import { dataclassesModule } from "../src/builtins/python.js";
5
4
  import * as py from "../src/index.js";
6
- import {
7
- assertFileContents,
8
- toSourceText,
9
- toSourceTextMultiple,
10
- } from "./utils.jsx";
5
+ import { TestOutput, TestOutputDirectory } from "./utils.js";
11
6
 
12
7
  describe("DataclassDeclaration", () => {
13
8
  it("stacks user decorators above @dataclass", () => {
14
- const res = toSourceText(
15
- [
16
- <py.SourceFile path="user.py">
17
- <py.DataclassDeclaration name="User" frozen decorators={["@final"]} />
18
- </py.SourceFile>,
19
- ],
20
- { externals: [dataclassesModule] },
21
- );
22
-
23
- expect(res).toRenderTo(
24
- d`
9
+ expect(
10
+ <TestOutput path="user.py" externals={[dataclassesModule]}>
11
+ <py.DataclassDeclaration name="User" frozen decorators={["@final"]} />
12
+ </TestOutput>,
13
+ ).toRenderTo(
14
+ `
25
15
  from dataclasses import dataclass
26
16
 
27
17
 
@@ -30,7 +20,6 @@ describe("DataclassDeclaration", () => {
30
20
  class User:
31
21
  pass
32
22
 
33
-
34
23
  `,
35
24
  );
36
25
  });
@@ -39,17 +28,12 @@ describe("DataclassDeclaration", () => {
39
28
  const doc = (
40
29
  <py.ClassDoc description={[<Prose>Represents a user.</Prose>]} />
41
30
  );
42
- const res = toSourceText(
43
- [
44
- <py.SourceFile path="user.py">
45
- <py.DataclassDeclaration name="User" doc={doc} />
46
- </py.SourceFile>,
47
- ],
48
- { externals: [dataclassesModule] },
49
- );
50
-
51
- expect(res).toRenderTo(
52
- d`
31
+ expect(
32
+ <TestOutput path="user.py" externals={[dataclassesModule]}>
33
+ <py.DataclassDeclaration name="User" doc={doc} />
34
+ </TestOutput>,
35
+ ).toRenderTo(
36
+ `
53
37
  from dataclasses import dataclass
54
38
 
55
39
 
@@ -61,42 +45,36 @@ describe("DataclassDeclaration", () => {
61
45
 
62
46
  pass
63
47
 
64
-
65
48
  `,
66
49
  );
67
50
  });
68
51
 
69
52
  it("Creates a dataclass with fields and defaults", () => {
70
- const res = toSourceText(
71
- [
72
- <py.SourceFile path="user.py">
73
- <py.DataclassDeclaration name="User">
74
- <py.VariableDeclaration
75
- instanceVariable
76
- omitNone
77
- name="id"
78
- type="int"
79
- />
80
- <py.VariableDeclaration
81
- instanceVariable
82
- name={namekey("_", { ignoreNamePolicy: true })}
83
- type={dataclassesModule["."].KW_ONLY}
84
- omitNone
85
- />
86
- <py.VariableDeclaration
87
- instanceVariable
88
- name="name"
89
- type="str"
90
- initializer={"Anonymous"}
91
- />
92
- </py.DataclassDeclaration>
93
- </py.SourceFile>,
94
- ],
95
- { externals: [dataclassesModule] },
96
- );
97
-
98
- expect(res).toRenderTo(
99
- d`
53
+ expect(
54
+ <TestOutput path="user.py" externals={[dataclassesModule]}>
55
+ <py.DataclassDeclaration name="User">
56
+ <py.VariableDeclaration
57
+ instanceVariable
58
+ omitNone
59
+ name="id"
60
+ type="int"
61
+ />
62
+ <py.VariableDeclaration
63
+ instanceVariable
64
+ name={namekey("_", { ignoreNamePolicy: true })}
65
+ type={dataclassesModule["."].KW_ONLY}
66
+ omitNone
67
+ />
68
+ <py.VariableDeclaration
69
+ instanceVariable
70
+ name="name"
71
+ type="str"
72
+ initializer={"Anonymous"}
73
+ />
74
+ </py.DataclassDeclaration>
75
+ </TestOutput>,
76
+ ).toRenderTo(
77
+ `
100
78
  from dataclasses import dataclass
101
79
  from typing import TYPE_CHECKING
102
80
 
@@ -110,30 +88,24 @@ describe("DataclassDeclaration", () => {
110
88
  _: KW_ONLY
111
89
  name: str = "Anonymous"
112
90
 
113
-
114
91
  `,
115
92
  );
116
93
  });
117
94
 
118
95
  it("Creates a dataclass with keyword arguments", () => {
119
- const res = toSourceText(
120
- [
121
- <py.SourceFile path="user.py">
122
- <py.DataclassDeclaration name="User" frozen slots kwOnly>
123
- <py.VariableDeclaration
124
- instanceVariable
125
- omitNone
126
- name="id"
127
- type="int"
128
- />
129
- </py.DataclassDeclaration>
130
- </py.SourceFile>,
131
- ],
132
- { externals: [dataclassesModule] },
133
- );
134
-
135
- expect(res).toRenderTo(
136
- d`
96
+ expect(
97
+ <TestOutput path="user.py" externals={[dataclassesModule]}>
98
+ <py.DataclassDeclaration name="User" frozen slots kwOnly>
99
+ <py.VariableDeclaration
100
+ instanceVariable
101
+ omitNone
102
+ name="id"
103
+ type="int"
104
+ />
105
+ </py.DataclassDeclaration>
106
+ </TestOutput>,
107
+ ).toRenderTo(
108
+ `
137
109
  from dataclasses import dataclass
138
110
 
139
111
 
@@ -141,35 +113,29 @@ describe("DataclassDeclaration", () => {
141
113
  class User:
142
114
  id: int
143
115
 
144
-
145
116
  `,
146
117
  );
147
118
  });
148
119
 
149
120
  it("Creates a dataclass with all keyword arguments", () => {
150
- const res = toSourceText(
151
- [
152
- <py.SourceFile path="user.py">
153
- <py.DataclassDeclaration
154
- name="User"
155
- init
156
- repr={false}
157
- eq
158
- order={false}
159
- unsafeHash
160
- frozen
161
- matchArgs={false}
162
- kwOnly
163
- slots
164
- weakrefSlot={false}
165
- />
166
- </py.SourceFile>,
167
- ],
168
- { externals: [dataclassesModule] },
169
- );
170
-
171
- expect(res).toRenderTo(
172
- d`
121
+ expect(
122
+ <TestOutput path="user.py" externals={[dataclassesModule]}>
123
+ <py.DataclassDeclaration
124
+ name="User"
125
+ init
126
+ repr={false}
127
+ eq
128
+ order={false}
129
+ unsafeHash
130
+ frozen
131
+ matchArgs={false}
132
+ kwOnly
133
+ slots
134
+ weakrefSlot={false}
135
+ />
136
+ </TestOutput>,
137
+ ).toRenderTo(
138
+ `
173
139
  from dataclasses import dataclass
174
140
 
175
141
 
@@ -177,20 +143,16 @@ describe("DataclassDeclaration", () => {
177
143
  class User:
178
144
  pass
179
145
 
180
-
181
146
  `,
182
147
  );
183
148
  });
184
149
 
185
150
  it("Throws error when weakref_slot=True without slots=True", () => {
186
151
  expect(() =>
187
- toSourceText(
188
- [
189
- <py.SourceFile path="user.py">
190
- <py.DataclassDeclaration name="User" weakrefSlot />
191
- </py.SourceFile>,
192
- ],
193
- { externals: [dataclassesModule] },
152
+ render(
153
+ <TestOutput path="user.py" externals={[dataclassesModule]}>
154
+ <py.DataclassDeclaration name="User" weakrefSlot />
155
+ </TestOutput>,
194
156
  ),
195
157
  ).toThrowError(
196
158
  /weakref_slot=True requires slots=True in @dataclass decorator/,
@@ -198,16 +160,12 @@ describe("DataclassDeclaration", () => {
198
160
  });
199
161
 
200
162
  it("Allows weakref_slot=True when slots=True", () => {
201
- const res = toSourceText(
202
- [
203
- <py.SourceFile path="user.py">
204
- <py.DataclassDeclaration name="User" slots weakrefSlot />
205
- </py.SourceFile>,
206
- ],
207
- { externals: [dataclassesModule] },
208
- );
209
- expect(res).toRenderTo(
210
- d`
163
+ expect(
164
+ <TestOutput path="user.py" externals={[dataclassesModule]}>
165
+ <py.DataclassDeclaration name="User" slots weakrefSlot />
166
+ </TestOutput>,
167
+ ).toRenderTo(
168
+ `
211
169
  from dataclasses import dataclass
212
170
 
213
171
 
@@ -215,35 +173,27 @@ describe("DataclassDeclaration", () => {
215
173
  class User:
216
174
  pass
217
175
 
218
-
219
176
  `,
220
177
  );
221
178
  });
222
179
 
223
180
  it("Throws error when order=True and eq=False", () => {
224
181
  expect(() =>
225
- toSourceText(
226
- [
227
- <py.SourceFile path="user.py">
228
- <py.DataclassDeclaration name="User" order eq={false} />
229
- </py.SourceFile>,
230
- ],
231
- { externals: [dataclassesModule] },
182
+ render(
183
+ <TestOutput path="user.py" externals={[dataclassesModule]}>
184
+ <py.DataclassDeclaration name="User" order eq={false} />
185
+ </TestOutput>,
232
186
  ),
233
187
  ).toThrowError(/order=True requires eq=True/);
234
188
  });
235
189
 
236
190
  it("Creates a dataclass with order=True and no conflicting methods", () => {
237
- const res = toSourceText(
238
- [
239
- <py.SourceFile path="user.py">
240
- <py.DataclassDeclaration name="User" order />
241
- </py.SourceFile>,
242
- ],
243
- { externals: [dataclassesModule] },
244
- );
245
- expect(res).toRenderTo(
246
- d`
191
+ expect(
192
+ <TestOutput path="user.py" externals={[dataclassesModule]}>
193
+ <py.DataclassDeclaration name="User" order />
194
+ </TestOutput>,
195
+ ).toRenderTo(
196
+ `
247
197
  from dataclasses import dataclass
248
198
 
249
199
 
@@ -251,22 +201,18 @@ describe("DataclassDeclaration", () => {
251
201
  class User:
252
202
  pass
253
203
 
254
-
255
204
  `,
256
205
  );
257
206
  });
258
207
 
259
208
  it("Throws error when order=True and class defines __lt__", () => {
260
209
  expect(() =>
261
- toSourceText(
262
- [
263
- <py.SourceFile path="user.py">
264
- <py.DataclassDeclaration name="User" order>
265
- <py.DunderMethodDeclaration name="__lt__" />
266
- </py.DataclassDeclaration>
267
- </py.SourceFile>,
268
- ],
269
- { externals: [dataclassesModule] },
210
+ render(
211
+ <TestOutput path="user.py" externals={[dataclassesModule]}>
212
+ <py.DataclassDeclaration name="User" order>
213
+ <py.DunderMethodDeclaration name="__lt__" />
214
+ </py.DataclassDeclaration>
215
+ </TestOutput>,
270
216
  ),
271
217
  ).toThrowError(
272
218
  /Cannot specify order=True when the class already defines __lt__\(\)/,
@@ -275,15 +221,12 @@ describe("DataclassDeclaration", () => {
275
221
 
276
222
  it("Throws error when order=True and class defines __le__", () => {
277
223
  expect(() =>
278
- toSourceText(
279
- [
280
- <py.SourceFile path="user.py">
281
- <py.DataclassDeclaration name="User" order>
282
- <py.DunderMethodDeclaration name="__le__" />
283
- </py.DataclassDeclaration>
284
- </py.SourceFile>,
285
- ],
286
- { externals: [dataclassesModule] },
224
+ render(
225
+ <TestOutput path="user.py" externals={[dataclassesModule]}>
226
+ <py.DataclassDeclaration name="User" order>
227
+ <py.DunderMethodDeclaration name="__le__" />
228
+ </py.DataclassDeclaration>
229
+ </TestOutput>,
287
230
  ),
288
231
  ).toThrowError(
289
232
  /Cannot specify order=True when the class already defines __le__\(\)/,
@@ -292,15 +235,12 @@ describe("DataclassDeclaration", () => {
292
235
 
293
236
  it("Throws error when order=True and class defines __gt__", () => {
294
237
  expect(() =>
295
- toSourceText(
296
- [
297
- <py.SourceFile path="user.py">
298
- <py.DataclassDeclaration name="User" order>
299
- <py.DunderMethodDeclaration name="__gt__" />
300
- </py.DataclassDeclaration>
301
- </py.SourceFile>,
302
- ],
303
- { externals: [dataclassesModule] },
238
+ render(
239
+ <TestOutput path="user.py" externals={[dataclassesModule]}>
240
+ <py.DataclassDeclaration name="User" order>
241
+ <py.DunderMethodDeclaration name="__gt__" />
242
+ </py.DataclassDeclaration>
243
+ </TestOutput>,
304
244
  ),
305
245
  ).toThrowError(
306
246
  /Cannot specify order=True when the class already defines __gt__\(\)/,
@@ -309,15 +249,12 @@ describe("DataclassDeclaration", () => {
309
249
 
310
250
  it("Throws error when order=True and class defines __ge__", () => {
311
251
  expect(() =>
312
- toSourceText(
313
- [
314
- <py.SourceFile path="user.py">
315
- <py.DataclassDeclaration name="User" order>
316
- <py.DunderMethodDeclaration name="__ge__" />
317
- </py.DataclassDeclaration>
318
- </py.SourceFile>,
319
- ],
320
- { externals: [dataclassesModule] },
252
+ render(
253
+ <TestOutput path="user.py" externals={[dataclassesModule]}>
254
+ <py.DataclassDeclaration name="User" order>
255
+ <py.DunderMethodDeclaration name="__ge__" />
256
+ </py.DataclassDeclaration>
257
+ </TestOutput>,
321
258
  ),
322
259
  ).toThrowError(
323
260
  /Cannot specify order=True when the class already defines __ge__\(\)/,
@@ -329,15 +266,12 @@ describe("DataclassDeclaration", () => {
329
266
  return <py.DunderMethodDeclaration name="__lt__" />;
330
267
  }
331
268
  expect(() =>
332
- toSourceText(
333
- [
334
- <py.SourceFile path="user.py">
335
- <py.DataclassDeclaration name="User" order>
336
- <Wrapper />
337
- </py.DataclassDeclaration>
338
- </py.SourceFile>,
339
- ],
340
- { externals: [dataclassesModule] },
269
+ render(
270
+ <TestOutput path="user.py" externals={[dataclassesModule]}>
271
+ <py.DataclassDeclaration name="User" order>
272
+ <Wrapper />
273
+ </py.DataclassDeclaration>
274
+ </TestOutput>,
341
275
  ),
342
276
  ).toThrowError(
343
277
  /Cannot specify order=True when the class already defines __lt__\(\)/,
@@ -346,15 +280,12 @@ describe("DataclassDeclaration", () => {
346
280
 
347
281
  it("Throws error when unsafe_hash=True and class defines __hash__", () => {
348
282
  expect(() =>
349
- toSourceText(
350
- [
351
- <py.SourceFile path="user.py">
352
- <py.DataclassDeclaration name="User" unsafeHash>
353
- <py.DunderMethodDeclaration name="__hash__" />
354
- </py.DataclassDeclaration>
355
- </py.SourceFile>,
356
- ],
357
- { externals: [dataclassesModule] },
283
+ render(
284
+ <TestOutput path="user.py" externals={[dataclassesModule]}>
285
+ <py.DataclassDeclaration name="User" unsafeHash>
286
+ <py.DunderMethodDeclaration name="__hash__" />
287
+ </py.DataclassDeclaration>
288
+ </TestOutput>,
358
289
  ),
359
290
  ).toThrowError(
360
291
  /Cannot specify unsafe_hash=True when the class already defines __hash__\(\)/,
@@ -363,15 +294,12 @@ describe("DataclassDeclaration", () => {
363
294
 
364
295
  it("Throws error when frozen=True and class defines __setattr__", () => {
365
296
  expect(() =>
366
- toSourceText(
367
- [
368
- <py.SourceFile path="user.py">
369
- <py.DataclassDeclaration name="User" frozen>
370
- <py.DunderMethodDeclaration name="__setattr__" />
371
- </py.DataclassDeclaration>
372
- </py.SourceFile>,
373
- ],
374
- { externals: [dataclassesModule] },
297
+ render(
298
+ <TestOutput path="user.py" externals={[dataclassesModule]}>
299
+ <py.DataclassDeclaration name="User" frozen>
300
+ <py.DunderMethodDeclaration name="__setattr__" />
301
+ </py.DataclassDeclaration>
302
+ </TestOutput>,
375
303
  ),
376
304
  ).toThrowError(
377
305
  /Cannot specify frozen=True when the class already defines __setattr__\(\)/,
@@ -380,15 +308,12 @@ describe("DataclassDeclaration", () => {
380
308
 
381
309
  it("Throws errorwhen frozen=True and class defines __delattr__", () => {
382
310
  expect(() =>
383
- toSourceText(
384
- [
385
- <py.SourceFile path="user.py">
386
- <py.DataclassDeclaration name="User" frozen>
387
- <py.DunderMethodDeclaration name="__delattr__" />
388
- </py.DataclassDeclaration>
389
- </py.SourceFile>,
390
- ],
391
- { externals: [dataclassesModule] },
311
+ render(
312
+ <TestOutput path="user.py" externals={[dataclassesModule]}>
313
+ <py.DataclassDeclaration name="User" frozen>
314
+ <py.DunderMethodDeclaration name="__delattr__" />
315
+ </py.DataclassDeclaration>
316
+ </TestOutput>,
392
317
  ),
393
318
  ).toThrowError(
394
319
  /Cannot specify frozen=True when the class already defines __delattr__\(\)/,
@@ -397,15 +322,12 @@ describe("DataclassDeclaration", () => {
397
322
 
398
323
  it("Throws error when slots=True and class defines __slots__", () => {
399
324
  expect(() =>
400
- toSourceText(
401
- [
402
- <py.SourceFile path="user.py">
403
- <py.DataclassDeclaration name="User" slots>
404
- <py.DunderMethodDeclaration name="__slots__" />
405
- </py.DataclassDeclaration>
406
- </py.SourceFile>,
407
- ],
408
- { externals: [dataclassesModule] },
325
+ render(
326
+ <TestOutput path="user.py" externals={[dataclassesModule]}>
327
+ <py.DataclassDeclaration name="User" slots>
328
+ <py.DunderMethodDeclaration name="__slots__" />
329
+ </py.DataclassDeclaration>
330
+ </TestOutput>,
409
331
  ),
410
332
  ).toThrowError(
411
333
  /Cannot specify slots=True when the class already defines __slots__\(\)/,
@@ -413,23 +335,19 @@ describe("DataclassDeclaration", () => {
413
335
  });
414
336
 
415
337
  it("Creates a dataclass with kw_only=True on decorator (sentinel not used)", () => {
416
- const res = toSourceText(
417
- [
418
- <py.SourceFile path="user.py">
419
- <py.DataclassDeclaration name="User" kwOnly>
420
- <py.VariableDeclaration
421
- instanceVariable
422
- omitNone
423
- name="id"
424
- type="int"
425
- />
426
- </py.DataclassDeclaration>
427
- </py.SourceFile>,
428
- ],
429
- { externals: [dataclassesModule] },
430
- );
431
- expect(res).toRenderTo(
432
- d`
338
+ expect(
339
+ <TestOutput path="user.py" externals={[dataclassesModule]}>
340
+ <py.DataclassDeclaration name="User" kwOnly>
341
+ <py.VariableDeclaration
342
+ instanceVariable
343
+ omitNone
344
+ name="id"
345
+ type="int"
346
+ />
347
+ </py.DataclassDeclaration>
348
+ </TestOutput>,
349
+ ).toRenderTo(
350
+ `
433
351
  from dataclasses import dataclass
434
352
 
435
353
 
@@ -437,23 +355,17 @@ describe("DataclassDeclaration", () => {
437
355
  class User:
438
356
  id: int
439
357
 
440
-
441
358
  `,
442
359
  );
443
360
  });
444
361
 
445
362
  it("Creates a dataclass with base classes", () => {
446
- const res = toSourceText(
447
- [
448
- <py.SourceFile path="user.py">
449
- <py.DataclassDeclaration name="User" bases={["Base"]} />
450
- </py.SourceFile>,
451
- ],
452
- { externals: [dataclassesModule] },
453
- );
454
-
455
- expect(res).toRenderTo(
456
- d`
363
+ expect(
364
+ <TestOutput path="user.py" externals={[dataclassesModule]}>
365
+ <py.DataclassDeclaration name="User" bases={["Base"]} />
366
+ </TestOutput>,
367
+ ).toRenderTo(
368
+ `
457
369
  from dataclasses import dataclass
458
370
 
459
371
 
@@ -461,82 +373,68 @@ describe("DataclassDeclaration", () => {
461
373
  class User(Base):
462
374
  pass
463
375
 
464
-
465
376
  `,
466
377
  );
467
378
  });
468
379
 
469
380
  it("Throws error when more than one KW_ONLY sentinel is present", () => {
470
381
  expect(() =>
471
- toSourceText(
472
- [
473
- <py.SourceFile path="user.py">
474
- <py.DataclassDeclaration name="User">
475
- <py.VariableDeclaration
476
- instanceVariable
477
- name={namekey("_", { ignoreNamePolicy: true })}
478
- type={dataclassesModule["."].KW_ONLY}
479
- omitNone
480
- />
481
- <py.VariableDeclaration
482
- instanceVariable
483
- name={namekey("_", { ignoreNamePolicy: true })}
484
- type={dataclassesModule["."].KW_ONLY}
485
- omitNone
486
- />
487
- </py.DataclassDeclaration>
488
- </py.SourceFile>,
489
- ],
490
- { externals: [dataclassesModule] },
382
+ render(
383
+ <TestOutput path="user.py" externals={[dataclassesModule]}>
384
+ <py.DataclassDeclaration name="User">
385
+ <py.VariableDeclaration
386
+ instanceVariable
387
+ name={namekey("_", { ignoreNamePolicy: true })}
388
+ type={dataclassesModule["."].KW_ONLY}
389
+ omitNone
390
+ />
391
+ <py.VariableDeclaration
392
+ instanceVariable
393
+ name={namekey("_", { ignoreNamePolicy: true })}
394
+ type={dataclassesModule["."].KW_ONLY}
395
+ omitNone
396
+ />
397
+ </py.DataclassDeclaration>
398
+ </TestOutput>,
491
399
  ),
492
400
  ).toThrowError(/Only one KW_ONLY sentinel is allowed per dataclass body/);
493
401
  });
494
402
 
495
403
  it("Will raise arg validation errors first over member conflicts", () => {
496
404
  expect(() =>
497
- toSourceText(
498
- [
499
- <py.SourceFile path="user.py">
500
- <py.DataclassDeclaration name="User" order eq={false}>
501
- <py.DunderMethodDeclaration name="__lt__" />
502
- </py.DataclassDeclaration>
503
- </py.SourceFile>,
504
- ],
505
- { externals: [dataclassesModule] },
405
+ render(
406
+ <TestOutput path="user.py" externals={[dataclassesModule]}>
407
+ <py.DataclassDeclaration name="User" order eq={false}>
408
+ <py.DunderMethodDeclaration name="__lt__" />
409
+ </py.DataclassDeclaration>
410
+ </TestOutput>,
506
411
  ),
507
412
  ).toThrowError(/order=True requires eq=True/);
508
413
  });
509
414
 
510
415
  it("Does not raise errors for member conflict checks without the equivalent kwargs", () => {
511
416
  expect(() =>
512
- toSourceText(
513
- [
514
- <py.SourceFile path="user.py">
515
- <py.DataclassDeclaration name="User">
516
- <py.DunderMethodDeclaration name="__lt__" />
517
- <py.DunderMethodDeclaration name="__slots__" />
518
- <py.DunderMethodDeclaration name="__hash__" />
519
- <py.DunderMethodDeclaration name="__setattr__" />
520
- <py.DunderMethodDeclaration name="__delattr__" />
521
- </py.DataclassDeclaration>
522
- </py.SourceFile>,
523
- ],
524
- { externals: [dataclassesModule] },
417
+ render(
418
+ <TestOutput path="user.py" externals={[dataclassesModule]}>
419
+ <py.DataclassDeclaration name="User">
420
+ <py.DunderMethodDeclaration name="__lt__" />
421
+ <py.DunderMethodDeclaration name="__slots__" />
422
+ <py.DunderMethodDeclaration name="__hash__" />
423
+ <py.DunderMethodDeclaration name="__setattr__" />
424
+ <py.DunderMethodDeclaration name="__delattr__" />
425
+ </py.DataclassDeclaration>
426
+ </TestOutput>,
525
427
  ),
526
428
  ).not.toThrow();
527
429
  });
528
430
 
529
431
  it("Allows unsafe_hash=True when no __hash__ is defined", () => {
530
- const res = toSourceText(
531
- [
532
- <py.SourceFile path="user.py">
533
- <py.DataclassDeclaration name="User" unsafeHash />
534
- </py.SourceFile>,
535
- ],
536
- { externals: [dataclassesModule] },
537
- );
538
- expect(res).toRenderTo(
539
- d`
432
+ expect(
433
+ <TestOutput path="user.py" externals={[dataclassesModule]}>
434
+ <py.DataclassDeclaration name="User" unsafeHash />
435
+ </TestOutput>,
436
+ ).toRenderTo(
437
+ `
540
438
  from dataclasses import dataclass
541
439
 
542
440
 
@@ -544,7 +442,6 @@ describe("DataclassDeclaration", () => {
544
442
  class User:
545
443
  pass
546
444
 
547
-
548
445
  `,
549
446
  );
550
447
  });
@@ -561,36 +458,29 @@ describe("DataclassDeclaration", () => {
561
458
  );
562
459
  }
563
460
  expect(() =>
564
- toSourceText(
565
- [
566
- <py.SourceFile path="user.py">
567
- <py.DataclassDeclaration name="User">
568
- <py.VariableDeclaration
569
- instanceVariable
570
- name={namekey("_", { ignoreNamePolicy: true })}
571
- type={dataclassesModule["."].KW_ONLY}
572
- omitNone
573
- />
574
- <Wrapper />
575
- </py.DataclassDeclaration>
576
- </py.SourceFile>,
577
- ],
578
- { externals: [dataclassesModule] },
461
+ render(
462
+ <TestOutput path="user.py" externals={[dataclassesModule]}>
463
+ <py.DataclassDeclaration name="User">
464
+ <py.VariableDeclaration
465
+ instanceVariable
466
+ name={namekey("_", { ignoreNamePolicy: true })}
467
+ type={dataclassesModule["."].KW_ONLY}
468
+ omitNone
469
+ />
470
+ <Wrapper />
471
+ </py.DataclassDeclaration>
472
+ </TestOutput>,
579
473
  ),
580
474
  ).toThrowError(/Only one KW_ONLY sentinel is allowed per dataclass body/);
581
475
  });
582
476
 
583
477
  it("Allows frozen=True when no conflicting dunders exist", () => {
584
- const res = toSourceText(
585
- [
586
- <py.SourceFile path="user.py">
587
- <py.DataclassDeclaration name="User" frozen />
588
- </py.SourceFile>,
589
- ],
590
- { externals: [dataclassesModule] },
591
- );
592
- expect(res).toRenderTo(
593
- d`
478
+ expect(
479
+ <TestOutput path="user.py" externals={[dataclassesModule]}>
480
+ <py.DataclassDeclaration name="User" frozen />
481
+ </TestOutput>,
482
+ ).toRenderTo(
483
+ `
594
484
  from dataclasses import dataclass
595
485
 
596
486
 
@@ -598,22 +488,17 @@ describe("DataclassDeclaration", () => {
598
488
  class User:
599
489
  pass
600
490
 
601
-
602
491
  `,
603
492
  );
604
493
  });
605
494
 
606
495
  it("Allows slots=True when no __slots__ is defined", () => {
607
- const res = toSourceText(
608
- [
609
- <py.SourceFile path="user.py">
610
- <py.DataclassDeclaration name="User" slots />
611
- </py.SourceFile>,
612
- ],
613
- { externals: [dataclassesModule] },
614
- );
615
- expect(res).toRenderTo(
616
- d`
496
+ expect(
497
+ <TestOutput path="user.py" externals={[dataclassesModule]}>
498
+ <py.DataclassDeclaration name="User" slots />
499
+ </TestOutput>,
500
+ ).toRenderTo(
501
+ `
617
502
  from dataclasses import dataclass
618
503
 
619
504
 
@@ -621,15 +506,14 @@ describe("DataclassDeclaration", () => {
621
506
  class User:
622
507
  pass
623
508
 
624
-
625
509
  `,
626
510
  );
627
511
  });
628
512
 
629
513
  it("Forwards refkey prop for symbol resolution in type references", () => {
630
514
  const userRefkey = refkey();
631
- const res = toSourceTextMultiple(
632
- [
515
+ expect(
516
+ <TestOutputDirectory externals={[dataclassesModule]}>
633
517
  <py.SourceFile path="models.py">
634
518
  <py.DataclassDeclaration name="User" refkey={userRefkey}>
635
519
  <py.VariableDeclaration
@@ -645,7 +529,7 @@ describe("DataclassDeclaration", () => {
645
529
  type="str"
646
530
  />
647
531
  </py.DataclassDeclaration>
648
- </py.SourceFile>,
532
+ </py.SourceFile>
649
533
  <py.SourceFile path="services.py">
650
534
  <py.FunctionDeclaration name="get_user" returnType={userRefkey}>
651
535
  <py.VariableDeclaration
@@ -661,30 +545,28 @@ describe("DataclassDeclaration", () => {
661
545
  <hbr />
662
546
  {"return user"}
663
547
  </py.FunctionDeclaration>
664
- </py.SourceFile>,
665
- ],
666
- { externals: [dataclassesModule] },
667
- );
668
- assertFileContents(res, {
548
+ </py.SourceFile>
549
+ </TestOutputDirectory>,
550
+ ).toRenderTo({
669
551
  "models.py": `
670
- from dataclasses import dataclass
552
+ from dataclasses import dataclass
671
553
 
672
554
 
673
- @dataclass
674
- class User:
675
- id: int
676
- name: str
555
+ @dataclass
556
+ class User:
557
+ id: int
558
+ name: str
677
559
 
678
- `,
560
+ `,
679
561
  "services.py": `
680
- from models import User
562
+ from models import User
681
563
 
682
564
 
683
- def get_user() -> User:
684
- user: User = User(1, "Alice")
685
- return user
565
+ def get_user() -> User:
566
+ user: User = User(1, "Alice")
567
+ return user
686
568
 
687
- `,
569
+ `,
688
570
  });
689
571
  });
690
572
  });