@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,14 +1,14 @@
1
1
  import { createComponent as _$createComponent } from "@alloy-js/core/jsx-runtime";
2
2
  import { Prose, code, refkey } from "@alloy-js/core";
3
- import { d } from "@alloy-js/core/testing";
4
3
  import { describe, expect, it } from "vitest";
5
4
  import { pydanticModule, pydanticSettingsModule, typingModule } from "../src/builtins/python.js";
6
5
  import * as py from "../src/index.js";
7
- import { assertFileContents, toSourceText, toSourceTextMultiple } from "./utils.js";
6
+ import { TestOutput, TestOutputDirectory } from "./utils.js";
8
7
  describe("PydanticClassDeclaration", () => {
9
8
  it("forwards class-level decorators above `class`", () => {
10
- const res = toSourceText([_$createComponent(py.SourceFile, {
9
+ expect(_$createComponent(TestOutput, {
11
10
  path: "models.py",
11
+ externals: [pydanticModule, typingModule],
12
12
  get children() {
13
13
  return _$createComponent(py.PydanticClassDeclaration, {
14
14
  name: "User",
@@ -25,10 +25,7 @@ describe("PydanticClassDeclaration", () => {
25
25
  }
26
26
  });
27
27
  }
28
- })], {
29
- externals: [pydanticModule, typingModule]
30
- });
31
- expect(res).toRenderTo(d`
28
+ })).toRenderTo(`
32
29
  from pydantic import BaseModel
33
30
  from typing import final
34
31
 
@@ -37,12 +34,12 @@ describe("PydanticClassDeclaration", () => {
37
34
  class User(BaseModel):
38
35
  id: int
39
36
 
40
-
41
37
  `);
42
38
  });
43
39
  it("emits a pydantic model with BaseModel, fields, and Field import", () => {
44
- const res = toSourceText([_$createComponent(py.SourceFile, {
40
+ expect(_$createComponent(TestOutput, {
45
41
  path: "models.py",
42
+ externals: [pydanticModule],
46
43
  get children() {
47
44
  return _$createComponent(py.PydanticClassDeclaration, {
48
45
  name: "User",
@@ -63,10 +60,7 @@ describe("PydanticClassDeclaration", () => {
63
60
  }
64
61
  });
65
62
  }
66
- })], {
67
- externals: [pydanticModule]
68
- });
69
- expect(res).toRenderTo(d`
63
+ })).toRenderTo(`
70
64
  from pydantic import BaseModel
71
65
  from pydantic import Field
72
66
 
@@ -75,13 +69,13 @@ describe("PydanticClassDeclaration", () => {
75
69
  id: int
76
70
  name: str = Field(default="anon")
77
71
 
78
-
79
72
  `);
80
73
  });
81
74
  it("inherits from another pydantic model via bases", () => {
82
75
  const baseRef = refkey();
83
- const res = toSourceText([_$createComponent(py.SourceFile, {
76
+ expect(_$createComponent(TestOutput, {
84
77
  path: "models.py",
78
+ externals: [pydanticModule],
85
79
  get children() {
86
80
  return _$createComponent(py.StatementList, {
87
81
  get children() {
@@ -111,10 +105,7 @@ describe("PydanticClassDeclaration", () => {
111
105
  }
112
106
  });
113
107
  }
114
- })], {
115
- externals: [pydanticModule]
116
- });
117
- expect(res).toRenderTo(d`
108
+ })).toRenderTo(`
118
109
  from pydantic import BaseModel
119
110
 
120
111
 
@@ -124,12 +115,12 @@ describe("PydanticClassDeclaration", () => {
124
115
  class Admin(User):
125
116
  role: str
126
117
 
127
-
128
118
  `);
129
119
  });
130
120
  it("supports required, optional, Field default, and plain default", () => {
131
- const res = toSourceText([_$createComponent(py.SourceFile, {
121
+ expect(_$createComponent(TestOutput, {
132
122
  path: "models.py",
123
+ externals: [pydanticModule],
133
124
  get children() {
134
125
  return _$createComponent(py.PydanticClassDeclaration, {
135
126
  name: "Item",
@@ -163,10 +154,7 @@ describe("PydanticClassDeclaration", () => {
163
154
  }
164
155
  });
165
156
  }
166
- })], {
167
- externals: [pydanticModule]
168
- });
169
- expect(res).toRenderTo(d`
157
+ })).toRenderTo(`
170
158
  from pydantic import BaseModel
171
159
  from pydantic import Field
172
160
 
@@ -177,7 +165,6 @@ describe("PydanticClassDeclaration", () => {
177
165
  label: str = Field(default="untitled")
178
166
  qty: int = 1
179
167
 
180
-
181
168
  `);
182
169
  });
183
170
  it("emits class docstring", () => {
@@ -188,8 +175,9 @@ describe("PydanticClassDeclaration", () => {
188
175
  })];
189
176
  }
190
177
  });
191
- const res = toSourceText([_$createComponent(py.SourceFile, {
178
+ expect(_$createComponent(TestOutput, {
192
179
  path: "models.py",
180
+ externals: [pydanticModule],
193
181
  get children() {
194
182
  return _$createComponent(py.PydanticClassDeclaration, {
195
183
  name: "RequestBody",
@@ -204,10 +192,7 @@ describe("PydanticClassDeclaration", () => {
204
192
  }
205
193
  });
206
194
  }
207
- })], {
208
- externals: [pydanticModule]
209
- });
210
- expect(res).toRenderTo(d`
195
+ })).toRenderTo(`
211
196
  from pydantic import BaseModel
212
197
 
213
198
 
@@ -218,68 +203,70 @@ describe("PydanticClassDeclaration", () => {
218
203
 
219
204
  value: str
220
205
 
221
-
222
206
  `);
223
207
  });
224
208
  it("resolves refkey across files with pydantic imports", () => {
225
209
  const modelRef = refkey();
226
- const res = toSourceTextMultiple([_$createComponent(py.SourceFile, {
227
- path: "models.py",
210
+ expect(_$createComponent(TestOutputDirectory, {
211
+ externals: [pydanticModule],
228
212
  get children() {
229
- return _$createComponent(py.PydanticClassDeclaration, {
230
- name: "User",
231
- refkey: modelRef,
213
+ return [_$createComponent(py.SourceFile, {
214
+ path: "models.py",
232
215
  get children() {
233
- return _$createComponent(py.VariableDeclaration, {
234
- instanceVariable: true,
235
- omitNone: true,
236
- name: "id",
237
- type: "int"
216
+ return _$createComponent(py.PydanticClassDeclaration, {
217
+ name: "User",
218
+ refkey: modelRef,
219
+ get children() {
220
+ return _$createComponent(py.VariableDeclaration, {
221
+ instanceVariable: true,
222
+ omitNone: true,
223
+ name: "id",
224
+ type: "int"
225
+ });
226
+ }
238
227
  });
239
228
  }
240
- });
241
- }
242
- }), _$createComponent(py.SourceFile, {
243
- path: "service.py",
244
- get children() {
245
- return _$createComponent(py.FunctionDeclaration, {
246
- name: "load_user",
247
- returnType: modelRef,
248
- parameters: [{
249
- name: "user_id",
250
- type: "int"
251
- }],
252
- children: "return User(id=user_id)"
253
- });
229
+ }), _$createComponent(py.SourceFile, {
230
+ path: "service.py",
231
+ get children() {
232
+ return _$createComponent(py.FunctionDeclaration, {
233
+ name: "load_user",
234
+ returnType: modelRef,
235
+ parameters: [{
236
+ name: "user_id",
237
+ type: "int"
238
+ }],
239
+ children: "return User(id=user_id)"
240
+ });
241
+ }
242
+ })];
254
243
  }
255
- })], {
256
- externals: [pydanticModule]
257
- });
258
- assertFileContents(res, {
244
+ })).toRenderTo({
259
245
  "models.py": `
260
- from pydantic import BaseModel
246
+ from pydantic import BaseModel
261
247
 
262
248
 
263
- class User(BaseModel):
264
- id: int
249
+ class User(BaseModel):
250
+ id: int
265
251
 
266
- `,
252
+ `,
267
253
  "service.py": `
268
- from typing import TYPE_CHECKING
254
+ from typing import TYPE_CHECKING
269
255
 
270
- if TYPE_CHECKING:
271
- from models import User
256
+ if TYPE_CHECKING:
257
+ from models import User
272
258
 
273
259
 
274
- def load_user(user_id: int) -> User:
275
- return User(id=user_id)
260
+ def load_user(user_id: int) -> User:
261
+ return User(id=user_id)
276
262
 
277
- `
263
+ `
278
264
  });
279
265
  });
280
266
  it("emits model_config = ConfigDict(...) from top-level config props", () => {
281
- const res = toSourceText([_$createComponent(py.SourceFile, {
267
+ expect(_$createComponent(TestOutput, {
282
268
  path: "models.py",
269
+ externals: [pydanticModule],
283
270
  get children() {
284
271
  return _$createComponent(py.PydanticClassDeclaration, {
285
272
  name: "User",
@@ -296,10 +283,7 @@ describe("PydanticClassDeclaration", () => {
296
283
  }
297
284
  });
298
285
  }
299
- })], {
300
- externals: [pydanticModule]
301
- });
302
- expect(res).toRenderTo(d`
286
+ })).toRenderTo(`
303
287
  from pydantic import BaseModel
304
288
  from pydantic import ConfigDict
305
289
 
@@ -308,12 +292,12 @@ describe("PydanticClassDeclaration", () => {
308
292
  model_config = ConfigDict(frozen=True, extra="forbid", validate_assignment=True)
309
293
  id: int
310
294
 
311
-
312
295
  `);
313
296
  });
314
297
  it("emits model_config = ConfigDict(...) from modelConfig", () => {
315
- const res = toSourceText([_$createComponent(py.SourceFile, {
298
+ expect(_$createComponent(TestOutput, {
316
299
  path: "models.py",
300
+ externals: [pydanticModule],
317
301
  get children() {
318
302
  return _$createComponent(py.PydanticClassDeclaration, {
319
303
  name: "User",
@@ -332,10 +316,7 @@ describe("PydanticClassDeclaration", () => {
332
316
  }
333
317
  });
334
318
  }
335
- })], {
336
- externals: [pydanticModule]
337
- });
338
- expect(res).toRenderTo(d`
319
+ })).toRenderTo(`
339
320
  from pydantic import BaseModel
340
321
  from pydantic import ConfigDict
341
322
 
@@ -344,12 +325,12 @@ describe("PydanticClassDeclaration", () => {
344
325
  model_config = ConfigDict(frozen=True, extra="forbid", validate_assignment=True)
345
326
  id: int
346
327
 
347
-
348
328
  `);
349
329
  });
350
330
  it("gives precedence to top-level config props over modelConfig", () => {
351
- const res = toSourceText([_$createComponent(py.SourceFile, {
331
+ expect(_$createComponent(TestOutput, {
352
332
  path: "models.py",
333
+ externals: [pydanticModule],
353
334
  get children() {
354
335
  return _$createComponent(py.PydanticClassDeclaration, {
355
336
  name: "User",
@@ -361,10 +342,7 @@ describe("PydanticClassDeclaration", () => {
361
342
  extra: "forbid"
362
343
  });
363
344
  }
364
- })], {
365
- externals: [pydanticModule]
366
- });
367
- expect(res).toRenderTo(d`
345
+ })).toRenderTo(`
368
346
  from pydantic import BaseModel
369
347
  from pydantic import ConfigDict
370
348
 
@@ -372,12 +350,12 @@ describe("PydanticClassDeclaration", () => {
372
350
  class User(BaseModel):
373
351
  model_config = ConfigDict(frozen=True, extra="forbid")
374
352
 
375
-
376
353
  `);
377
354
  });
378
355
  it("supports additional typed ConfigDict props", () => {
379
- const res = toSourceText([_$createComponent(py.SourceFile, {
356
+ expect(_$createComponent(TestOutput, {
380
357
  path: "models.py",
358
+ externals: [pydanticModule],
381
359
  get children() {
382
360
  return _$createComponent(py.PydanticClassDeclaration, {
383
361
  name: "User",
@@ -390,10 +368,7 @@ describe("PydanticClassDeclaration", () => {
390
368
  valJsonBytes: "hex"
391
369
  });
392
370
  }
393
- })], {
394
- externals: [pydanticModule]
395
- });
396
- expect(res).toRenderTo(d`
371
+ })).toRenderTo(`
397
372
  from pydantic import BaseModel
398
373
  from pydantic import ConfigDict
399
374
 
@@ -401,12 +376,12 @@ describe("PydanticClassDeclaration", () => {
401
376
  class User(BaseModel):
402
377
  model_config = ConfigDict(coerce_numbers_to_str=True, ser_json_bytes="base64", str_min_length=1, str_max_length=128, use_enum_values=True, val_json_bytes="hex", validate_return=True)
403
378
 
404
-
405
379
  `);
406
380
  });
407
381
  it("imports SecretStr when used as a field type", () => {
408
- const res = toSourceText([_$createComponent(py.SourceFile, {
382
+ expect(_$createComponent(TestOutput, {
409
383
  path: "models.py",
384
+ externals: [pydanticModule],
410
385
  get children() {
411
386
  return _$createComponent(py.PydanticClassDeclaration, {
412
387
  name: "Credentials",
@@ -422,10 +397,7 @@ describe("PydanticClassDeclaration", () => {
422
397
  }
423
398
  });
424
399
  }
425
- })], {
426
- externals: [pydanticModule]
427
- });
428
- expect(res).toRenderTo(d`
400
+ })).toRenderTo(`
429
401
  from pydantic import BaseModel
430
402
  from typing import TYPE_CHECKING
431
403
 
@@ -436,12 +408,12 @@ describe("PydanticClassDeclaration", () => {
436
408
  class Credentials(BaseModel):
437
409
  token: SecretStr
438
410
 
439
-
440
411
  `);
441
412
  });
442
413
  it("emits arbitrary model_config via modelConfigExpression", () => {
443
- const res = toSourceText([_$createComponent(py.SourceFile, {
414
+ expect(_$createComponent(TestOutput, {
444
415
  path: "models.py",
416
+ externals: [pydanticModule],
445
417
  get children() {
446
418
  return _$createComponent(py.PydanticClassDeclaration, {
447
419
  name: "M",
@@ -450,10 +422,7 @@ describe("PydanticClassDeclaration", () => {
450
422
  }
451
423
  });
452
424
  }
453
- })], {
454
- externals: [pydanticModule]
455
- });
456
- expect(res).toRenderTo(d`
425
+ })).toRenderTo(`
457
426
  from pydantic import BaseModel
458
427
  from pydantic import ConfigDict
459
428
 
@@ -461,12 +430,12 @@ describe("PydanticClassDeclaration", () => {
461
430
  class M(BaseModel):
462
431
  model_config = ConfigDict(frozen=True, extra="allow")
463
432
 
464
-
465
433
  `);
466
434
  });
467
435
  it("supports RootModel as explicit bases entry", () => {
468
- const res = toSourceText([_$createComponent(py.SourceFile, {
436
+ expect(_$createComponent(TestOutput, {
469
437
  path: "models.py",
438
+ externals: [pydanticModule],
470
439
  get children() {
471
440
  return _$createComponent(py.PydanticClassDeclaration, {
472
441
  name: "Tags",
@@ -475,22 +444,19 @@ describe("PydanticClassDeclaration", () => {
475
444
  }
476
445
  });
477
446
  }
478
- })], {
479
- externals: [pydanticModule]
480
- });
481
- expect(res).toRenderTo(d`
447
+ })).toRenderTo(`
482
448
  from pydantic import RootModel
483
449
 
484
450
 
485
451
  class Tags(RootModel[list[str]]):
486
452
  pass
487
453
 
488
-
489
454
  `);
490
455
  });
491
456
  it("places Pydantic validators above classmethod", () => {
492
- const res = toSourceText([_$createComponent(py.SourceFile, {
457
+ expect(_$createComponent(TestOutput, {
493
458
  path: "models.py",
459
+ externals: [pydanticModule],
494
460
  get children() {
495
461
  return _$createComponent(py.PydanticClassDeclaration, {
496
462
  name: "User",
@@ -515,10 +481,7 @@ describe("PydanticClassDeclaration", () => {
515
481
  }
516
482
  });
517
483
  }
518
- })], {
519
- externals: [pydanticModule]
520
- });
521
- expect(res).toRenderTo(d`
484
+ })).toRenderTo(`
522
485
  from pydantic import BaseModel
523
486
  from pydantic import field_validator
524
487
 
@@ -531,14 +494,14 @@ describe("PydanticClassDeclaration", () => {
531
494
  return value.strip()
532
495
 
533
496
 
534
-
535
497
  `);
536
498
  });
537
499
  });
538
500
  describe("Pydantic ecosystem emitters", () => {
539
501
  it("typing module resolves Any and similar annotations", () => {
540
- const res = toSourceText([_$createComponent(py.SourceFile, {
502
+ expect(_$createComponent(TestOutput, {
541
503
  path: "models.py",
504
+ externals: [typingModule],
542
505
  get children() {
543
506
  return _$createComponent(py.FunctionDeclaration, {
544
507
  name: "identity",
@@ -554,10 +517,7 @@ describe("Pydantic ecosystem emitters", () => {
554
517
  children: "return x"
555
518
  });
556
519
  }
557
- })], {
558
- externals: [typingModule]
559
- });
560
- expect(res).toRenderTo(d`
520
+ })).toRenderTo(`
561
521
  from typing import TYPE_CHECKING
562
522
 
563
523
  if TYPE_CHECKING:
@@ -567,12 +527,12 @@ describe("Pydantic ecosystem emitters", () => {
567
527
  def identity(x: Any) -> Any:
568
528
  return x
569
529
 
570
-
571
530
  `);
572
531
  });
573
532
  it("pydantic.types constrains field annotations", () => {
574
- const res = toSourceText([_$createComponent(py.SourceFile, {
533
+ expect(_$createComponent(TestOutput, {
575
534
  path: "models.py",
535
+ externals: [pydanticModule],
576
536
  get children() {
577
537
  return _$createComponent(py.PydanticClassDeclaration, {
578
538
  name: "Score",
@@ -588,10 +548,7 @@ describe("Pydantic ecosystem emitters", () => {
588
548
  }
589
549
  });
590
550
  }
591
- })], {
592
- externals: [pydanticModule]
593
- });
594
- expect(res).toRenderTo(d`
551
+ })).toRenderTo(`
595
552
  from pydantic import BaseModel
596
553
  from typing import TYPE_CHECKING
597
554
 
@@ -602,53 +559,56 @@ describe("Pydantic ecosystem emitters", () => {
602
559
  class Score(BaseModel):
603
560
  points: PositiveInt
604
561
 
605
-
606
562
  `);
607
563
  });
608
564
  it("postponed annotations support forward references in fields", () => {
609
- const res = toSourceText([_$createComponent(py.SourceFile, {
610
- path: "models.py",
611
- get futureImports() {
612
- return [_$createComponent(py.FutureStatement, {
613
- feature: "annotations"
614
- })];
615
- },
565
+ expect(_$createComponent(TestOutputDirectory, {
566
+ externals: [pydanticModule],
616
567
  get children() {
617
- return _$createComponent(py.PydanticClassDeclaration, {
618
- name: "Node",
619
- get children() {
620
- return [_$createComponent(py.VariableDeclaration, {
621
- instanceVariable: true,
622
- omitNone: true,
623
- name: "label",
624
- type: "str"
625
- }), _$createComponent(py.VariableDeclaration, {
626
- instanceVariable: true,
627
- name: "child",
628
- type: code`"Node" | None`
568
+ return _$createComponent(py.SourceFile, {
569
+ path: "models.py",
570
+ get futureImports() {
571
+ return [_$createComponent(py.FutureStatement, {
572
+ feature: "annotations"
629
573
  })];
574
+ },
575
+ get children() {
576
+ return _$createComponent(py.PydanticClassDeclaration, {
577
+ name: "Node",
578
+ get children() {
579
+ return [_$createComponent(py.VariableDeclaration, {
580
+ instanceVariable: true,
581
+ omitNone: true,
582
+ name: "label",
583
+ type: "str"
584
+ }), _$createComponent(py.VariableDeclaration, {
585
+ instanceVariable: true,
586
+ name: "child",
587
+ type: code`"Node" | None`
588
+ })];
589
+ }
590
+ });
630
591
  }
631
592
  });
632
593
  }
633
- })], {
634
- externals: [pydanticModule]
635
- });
636
- expect(res).toRenderTo(d`
637
- from __future__ import annotations
638
-
639
- from pydantic import BaseModel
594
+ })).toRenderTo({
595
+ "models.py": `
596
+ from __future__ import annotations
640
597
 
598
+ from pydantic import BaseModel
641
599
 
642
- class Node(BaseModel):
643
- label: str
644
- child: "Node" | None = None
645
600
 
601
+ class Node(BaseModel):
602
+ label: str
603
+ child: "Node" | None = None
646
604
 
647
- `);
605
+ `
606
+ });
648
607
  });
649
608
  it("model_config can use pydantic.alias_generators", () => {
650
- const res = toSourceText([_$createComponent(py.SourceFile, {
609
+ expect(_$createComponent(TestOutput, {
651
610
  path: "models.py",
611
+ externals: [pydanticModule],
652
612
  get children() {
653
613
  return _$createComponent(py.PydanticClassDeclaration, {
654
614
  name: "M",
@@ -657,10 +617,7 @@ describe("Pydantic ecosystem emitters", () => {
657
617
  }
658
618
  });
659
619
  }
660
- })], {
661
- externals: [pydanticModule]
662
- });
663
- expect(res).toRenderTo(d`
620
+ })).toRenderTo(`
664
621
  from pydantic import BaseModel
665
622
  from pydantic import ConfigDict
666
623
  from pydantic.alias_generators import to_camel
@@ -669,12 +626,12 @@ describe("Pydantic ecosystem emitters", () => {
669
626
  class M(BaseModel):
670
627
  model_config = ConfigDict(alias_generator=to_camel)
671
628
 
672
-
673
629
  `);
674
630
  });
675
631
  it("pydantic_settings exposes BaseSettings", () => {
676
- const res = toSourceText([_$createComponent(py.SourceFile, {
632
+ expect(_$createComponent(TestOutput, {
677
633
  path: "config.py",
634
+ externals: [pydanticSettingsModule],
678
635
  get children() {
679
636
  return _$createComponent(py.ClassDeclaration, {
680
637
  name: "AppSettings",
@@ -683,22 +640,19 @@ describe("Pydantic ecosystem emitters", () => {
683
640
  }
684
641
  });
685
642
  }
686
- })], {
687
- externals: [pydanticSettingsModule]
688
- });
689
- expect(res).toRenderTo(d`
643
+ })).toRenderTo(`
690
644
  from pydantic_settings import BaseSettings
691
645
 
692
646
 
693
647
  class AppSettings(BaseSettings):
694
648
  pass
695
649
 
696
-
697
650
  `);
698
651
  });
699
652
  it("emits @computed_field above @property via PropertyDeclaration", () => {
700
- const res = toSourceText([_$createComponent(py.SourceFile, {
653
+ expect(_$createComponent(TestOutput, {
701
654
  path: "models.py",
655
+ externals: [pydanticModule],
702
656
  get children() {
703
657
  return _$createComponent(py.PydanticClassDeclaration, {
704
658
  name: "Square",
@@ -719,10 +673,7 @@ describe("Pydantic ecosystem emitters", () => {
719
673
  }
720
674
  });
721
675
  }
722
- })], {
723
- externals: [pydanticModule]
724
- });
725
- expect(res).toRenderTo(d`
676
+ })).toRenderTo(`
726
677
  from pydantic import BaseModel
727
678
  from pydantic import computed_field
728
679
 
@@ -735,12 +686,12 @@ describe("Pydantic ecosystem emitters", () => {
735
686
  return self.width ** 2
736
687
 
737
688
 
738
-
739
689
  `);
740
690
  });
741
691
  it("emits computed_field on an instance method", () => {
742
- const res = toSourceText([_$createComponent(py.SourceFile, {
692
+ expect(_$createComponent(TestOutput, {
743
693
  path: "models.py",
694
+ externals: [pydanticModule],
744
695
  get children() {
745
696
  return _$createComponent(py.PydanticClassDeclaration, {
746
697
  name: "Square",
@@ -761,10 +712,7 @@ describe("Pydantic ecosystem emitters", () => {
761
712
  }
762
713
  });
763
714
  }
764
- })], {
765
- externals: [pydanticModule]
766
- });
767
- expect(res).toRenderTo(d`
715
+ })).toRenderTo(`
768
716
  from pydantic import BaseModel
769
717
  from pydantic import computed_field
770
718
 
@@ -776,12 +724,12 @@ describe("Pydantic ecosystem emitters", () => {
776
724
  return self.width ** 2
777
725
 
778
726
 
779
-
780
727
  `);
781
728
  });
782
729
  it("emits model_validator above classmethod", () => {
783
- const res = toSourceText([_$createComponent(py.SourceFile, {
730
+ expect(_$createComponent(TestOutput, {
784
731
  path: "models.py",
732
+ externals: [pydanticModule],
785
733
  get children() {
786
734
  return _$createComponent(py.PydanticClassDeclaration, {
787
735
  name: "Bag",
@@ -806,10 +754,7 @@ describe("Pydantic ecosystem emitters", () => {
806
754
  }
807
755
  });
808
756
  }
809
- })], {
810
- externals: [pydanticModule]
811
- });
812
- expect(res).toRenderTo(d`
757
+ })).toRenderTo(`
813
758
  from pydantic import BaseModel
814
759
  from pydantic import model_validator
815
760
 
@@ -822,7 +767,6 @@ describe("Pydantic ecosystem emitters", () => {
822
767
  return data
823
768
 
824
769
 
825
-
826
770
  `);
827
771
  });
828
772
  });