@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,18 +1,13 @@
1
1
  import { Prose } from "@alloy-js/core";
2
- import { d } from "@alloy-js/core/testing";
3
2
  import { describe, expect, it } from "vitest";
4
3
  import { enumModule } 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.jsx";
11
6
 
12
7
  describe("PyDoc", () => {
13
8
  it("formats properly", () => {
14
- const res = toSourceText(
15
- [
9
+ expect(
10
+ <TestOutput>
16
11
  <py.PyDoc>
17
12
  <Prose>
18
13
  This is an example of a long docstring that will be broken in lines.
@@ -21,13 +16,10 @@ describe("PyDoc", () => {
21
16
  <Prose>
22
17
  This is another paragraph, and there's a line break before it.
23
18
  </Prose>
24
- </py.PyDoc>,
25
- ],
26
- { printOptions: { printWidth: 40 } },
27
- );
28
-
29
- expect(res).toRenderTo(
30
- d`
19
+ </py.PyDoc>
20
+ </TestOutput>,
21
+ ).toRenderTo(
22
+ `
31
23
  """
32
24
  This is an example of a long docstring
33
25
  that will be broken in lines. We will
@@ -38,26 +30,23 @@ describe("PyDoc", () => {
38
30
  line break before it.
39
31
  """
40
32
 
41
-
42
33
  `,
34
+ { tabWidth: 4, printWidth: 40 },
43
35
  );
44
36
  });
45
37
  });
46
38
 
47
39
  describe("PyDocExample", () => {
48
40
  it("creates docstring with a code sample", () => {
49
- const res = toSourceText(
50
- [
41
+ expect(
42
+ <TestOutput>
51
43
  <py.PyDoc>
52
44
  <Prose>This is an example of a docstring with a code sample.</Prose>
53
45
  <py.PyDocExample>print("Hello world!")</py.PyDocExample>
54
- </py.PyDoc>,
55
- ],
56
- { printOptions: { printWidth: 40 } },
57
- );
58
-
59
- expect(res).toRenderTo(
60
- d`
46
+ </py.PyDoc>
47
+ </TestOutput>,
48
+ ).toRenderTo(
49
+ `
61
50
  """
62
51
  This is an example of a docstring with a
63
52
  code sample.
@@ -65,25 +54,22 @@ describe("PyDocExample", () => {
65
54
  >> print("Hello world!")
66
55
  """
67
56
 
68
-
69
57
  `,
58
+ { tabWidth: 4, printWidth: 40 },
70
59
  );
71
60
  });
72
61
 
73
62
  it("creates docstring with more than one code sample", () => {
74
- const res = toSourceText(
75
- [
63
+ expect(
64
+ <TestOutput>
76
65
  <py.PyDoc>
77
66
  <Prose>This is an example of a docstring with a code sample.</Prose>
78
67
  <py.PyDocExample>print("Hello world!")</py.PyDocExample>
79
68
  <py.PyDocExample>print("Hello world again!")</py.PyDocExample>
80
- </py.PyDoc>,
81
- ],
82
- { printOptions: { printWidth: 40 } },
83
- );
84
-
85
- expect(res).toRenderTo(
86
- d`
69
+ </py.PyDoc>
70
+ </TestOutput>,
71
+ ).toRenderTo(
72
+ `
87
73
  """
88
74
  This is an example of a docstring with a
89
75
  code sample.
@@ -93,26 +79,23 @@ describe("PyDocExample", () => {
93
79
  >> print("Hello world again!")
94
80
  """
95
81
 
96
-
97
82
  `,
83
+ { tabWidth: 4, printWidth: 40 },
98
84
  );
99
85
  });
100
86
 
101
87
  it("creates docstring with a multiline code sample", () => {
102
- const res = toSourceText(
103
- [
88
+ expect(
89
+ <TestOutput>
104
90
  <py.PyDoc>
105
91
  <Prose>This is an example of a docstring with a code sample.</Prose>
106
92
  <py.PyDocExample>
107
93
  {`print("Hello world!")\nx = "Hello"\nprint(x)`}
108
94
  </py.PyDocExample>
109
- </py.PyDoc>,
110
- ],
111
- { printOptions: { printWidth: 40 } },
112
- );
113
-
114
- expect(res).toRenderTo(
115
- d`
95
+ </py.PyDoc>
96
+ </TestOutput>,
97
+ ).toRenderTo(
98
+ `
116
99
  """
117
100
  This is an example of a docstring with a
118
101
  code sample.
@@ -122,40 +105,40 @@ describe("PyDocExample", () => {
122
105
  >> print(x)
123
106
  """
124
107
 
125
-
126
108
  `,
109
+ { tabWidth: 4, printWidth: 40 },
127
110
  );
128
111
  });
129
112
  });
130
113
 
131
114
  describe("SimpleCommentBlock", () => {
132
115
  it("renders simple comment block", () => {
133
- const res = toSourceText([
134
- <py.SimpleCommentBlock>
135
- This is a simple comment block that spans multiple lines and should be
136
- split automatically.
137
- </py.SimpleCommentBlock>,
138
- ]);
139
- expect(res).toRenderTo(
140
- d`
116
+ expect(
117
+ <TestOutput>
118
+ <py.SimpleCommentBlock>
119
+ This is a simple comment block that spans multiple lines and should be
120
+ split automatically.
121
+ </py.SimpleCommentBlock>
122
+ </TestOutput>,
123
+ ).toRenderTo(
124
+ `
141
125
  # This is a simple comment block that spans multiple lines and should be split
142
126
  # automatically.
143
-
144
127
  `,
145
128
  );
146
129
  });
147
130
 
148
131
  it("renders comment block with line breaks", () => {
149
- const res = toSourceText([
150
- <py.SimpleCommentBlock>
151
- First line of comment.\nSecond line of comment.
152
- </py.SimpleCommentBlock>,
153
- ]);
154
- expect(res).toRenderTo(
155
- d`
132
+ expect(
133
+ <TestOutput>
134
+ <py.SimpleCommentBlock>
135
+ First line of comment.\nSecond line of comment.
136
+ </py.SimpleCommentBlock>
137
+ </TestOutput>,
138
+ ).toRenderTo(
139
+ `
156
140
  # First line of comment.
157
141
  # Second line of comment.
158
-
159
142
  `,
160
143
  );
161
144
  });
@@ -163,68 +146,66 @@ describe("SimpleCommentBlock", () => {
163
146
 
164
147
  describe("SimpleInlineComment", () => {
165
148
  it("renders inline comment", () => {
166
- const res = toSourceText([
167
- <>
168
- x = 42
169
- <py.SimpleInlineComment>
170
- This is an inline comment
171
- </py.SimpleInlineComment>
172
- </>,
173
- ]);
174
- expect(res).toRenderTo(
175
- d`
176
- x = 42 # This is an inline comment
177
- `,
178
- );
149
+ expect(
150
+ <TestOutput>
151
+ {[
152
+ <>
153
+ x = 42
154
+ <py.SimpleInlineComment>
155
+ This is an inline comment
156
+ </py.SimpleInlineComment>
157
+ </>,
158
+ ]}
159
+ </TestOutput>,
160
+ ).toRenderTo(`x = 42 # This is an inline comment`);
179
161
  });
180
162
 
181
163
  it("renders inline comment with complex text", () => {
182
- const res = toSourceText([
183
- <>
184
- result = calculate()
185
- <py.SimpleInlineComment>
186
- TODO: Add error handling here
187
- </py.SimpleInlineComment>
188
- </>,
189
- ]);
190
- expect(res).toRenderTo(
191
- d`
192
- result = calculate() # TODO: Add error handling here
193
- `,
194
- );
164
+ expect(
165
+ <TestOutput>
166
+ {[
167
+ <>
168
+ result = calculate()
169
+ <py.SimpleInlineComment>
170
+ TODO: Add error handling here
171
+ </py.SimpleInlineComment>
172
+ </>,
173
+ ]}
174
+ </TestOutput>,
175
+ ).toRenderTo(`result = calculate() # TODO: Add error handling here`);
195
176
  });
196
177
  });
197
178
 
198
179
  describe("New Documentation Components", () => {
199
180
  it("ModuleDoc renders correctly", () => {
200
- const res = toSourceText([
201
- <py.ModuleDoc
202
- description={[
203
- <Prose>
204
- This module demonstrates documentation as specified by the Google
205
- Python Style Guide.
206
- </Prose>,
207
- ]}
208
- attributes={[
209
- {
210
- name: "module_level_variable1",
211
- type: "int",
212
- children: "Module level variables may be documented.",
213
- },
214
- ]}
215
- examples={[<py.PyDocExample>print("mod")</py.PyDocExample>]}
216
- seeAlso={["another_module.func", "RelatedClass"]}
217
- warning="Internal API."
218
- deprecated="Use new_module instead."
219
- todo={[
220
- "For module TODOs",
221
- "You have to also use sphinx.ext.todo extension",
222
- ]}
223
- />,
224
- ]);
225
-
226
- expect(res).toRenderTo(
227
- d`
181
+ expect(
182
+ <TestOutput>
183
+ <py.ModuleDoc
184
+ description={[
185
+ <Prose>
186
+ This module demonstrates documentation as specified by the Google
187
+ Python Style Guide.
188
+ </Prose>,
189
+ ]}
190
+ attributes={[
191
+ {
192
+ name: "module_level_variable1",
193
+ type: "int",
194
+ children: "Module level variables may be documented.",
195
+ },
196
+ ]}
197
+ examples={[<py.PyDocExample>print("mod")</py.PyDocExample>]}
198
+ seeAlso={["another_module.func", "RelatedClass"]}
199
+ warning="Internal API."
200
+ deprecated="Use new_module instead."
201
+ todo={[
202
+ "For module TODOs",
203
+ "You have to also use sphinx.ext.todo extension",
204
+ ]}
205
+ />
206
+ </TestOutput>,
207
+ ).toRenderTo(
208
+ `
228
209
  """
229
210
  This module demonstrates documentation as specified by the Google Python Style
230
211
  Guide.
@@ -250,30 +231,29 @@ describe("New Documentation Components", () => {
250
231
  * You have to also use sphinx.ext.todo extension
251
232
  """
252
233
 
253
-
254
234
  `,
255
235
  );
256
236
  });
257
237
 
258
238
  it("PropertyDoc renders correctly", () => {
259
- const res = toSourceText([
260
- <py.PropertyDoc
261
- description={[
262
- <Prose>
263
- Properties should be documented in their getter method.
264
- </Prose>,
265
- ]}
266
- returns="str: The readonly property value."
267
- examples={[<py.PyDocExample>print(obj.name)</py.PyDocExample>]}
268
- seeAlso={["other_property"]}
269
- warning="Access may be slow."
270
- deprecated="Use full_name instead."
271
- note="If the setter method contains notable behavior, it should be mentioned here."
272
- />,
273
- ]);
274
-
275
- expect(res).toRenderTo(
276
- d`
239
+ expect(
240
+ <TestOutput>
241
+ <py.PropertyDoc
242
+ description={[
243
+ <Prose>
244
+ Properties should be documented in their getter method.
245
+ </Prose>,
246
+ ]}
247
+ returns="str: The readonly property value."
248
+ examples={[<py.PyDocExample>print(obj.name)</py.PyDocExample>]}
249
+ seeAlso={["other_property"]}
250
+ warning="Access may be slow."
251
+ deprecated="Use full_name instead."
252
+ note="If the setter method contains notable behavior, it should be mentioned here."
253
+ />
254
+ </TestOutput>,
255
+ ).toRenderTo(
256
+ `
277
257
  """
278
258
  Properties should be documented in their getter method.
279
259
 
@@ -296,37 +276,36 @@ describe("New Documentation Components", () => {
296
276
  If the setter method contains notable behavior, it should be mentioned here.
297
277
  """
298
278
 
299
-
300
279
  `,
301
280
  );
302
281
  });
303
282
 
304
283
  it("GeneratorDoc renders correctly", () => {
305
- const res = toSourceText([
306
- <py.GeneratorDoc
307
- description={[
308
- <Prose>
309
- Generators have a Yields section instead of a Returns section.
310
- </Prose>,
311
- ]}
312
- parameters={[
313
- {
314
- name: "n",
315
- type: "int",
316
- doc: "The upper limit of the range to generate, from 0 to n - 1.",
317
- },
318
- ]}
319
- yields="int: The next number in the range of 0 to n - 1."
320
- examples={[<py.PyDocExample>print(next(gen))</py.PyDocExample>]}
321
- seeAlso={["make_generator"]}
322
- warning="Do not consume in tight loops without sleep."
323
- deprecated="Use new_generator instead."
324
- note="Examples should be written in doctest format."
325
- />,
326
- ]);
327
-
328
- expect(res).toRenderTo(
329
- d`
284
+ expect(
285
+ <TestOutput>
286
+ <py.GeneratorDoc
287
+ description={[
288
+ <Prose>
289
+ Generators have a Yields section instead of a Returns section.
290
+ </Prose>,
291
+ ]}
292
+ parameters={[
293
+ {
294
+ name: "n",
295
+ type: "int",
296
+ doc: "The upper limit of the range to generate, from 0 to n - 1.",
297
+ },
298
+ ]}
299
+ yields="int: The next number in the range of 0 to n - 1."
300
+ examples={[<py.PyDocExample>print(next(gen))</py.PyDocExample>]}
301
+ seeAlso={["make_generator"]}
302
+ warning="Do not consume in tight loops without sleep."
303
+ deprecated="Use new_generator instead."
304
+ note="Examples should be written in doctest format."
305
+ />
306
+ </TestOutput>,
307
+ ).toRenderTo(
308
+ `
330
309
  """
331
310
  Generators have a Yields section instead of a Returns section.
332
311
 
@@ -352,50 +331,51 @@ describe("New Documentation Components", () => {
352
331
  Examples should be written in doctest format.
353
332
  """
354
333
 
355
-
356
334
  `,
357
335
  );
358
336
  });
359
337
 
360
338
  it("ExceptionDoc renders correctly", () => {
361
- const res = toSourceText([
362
- <py.ExceptionDoc
363
- description={[
364
- <Prose>Exceptions are documented in the same way as classes.</Prose>,
365
- ]}
366
- parameters={[
367
- {
368
- name: "msg",
369
- type: "str",
370
- doc: "Human readable string describing the exception.",
371
- },
372
- {
373
- name: "code",
374
- type: "int",
375
- default: undefined,
376
- doc: "Error code.",
377
- },
378
- ]}
379
- attributes={[
380
- {
381
- name: "msg",
382
- type: "str",
383
- children: "Human readable string describing the exception.",
384
- },
385
- {
386
- name: "code",
387
- type: "int",
388
- children: "Exception error code.",
389
- },
390
- ]}
391
- seeAlso={["BaseException"]}
392
- deprecated="Use NewException instead."
393
- note="Do not include the 'self' parameter in the Args section."
394
- />,
395
- ]);
396
-
397
- expect(res).toRenderTo(
398
- d`
339
+ expect(
340
+ <TestOutput>
341
+ <py.ExceptionDoc
342
+ description={[
343
+ <Prose>
344
+ Exceptions are documented in the same way as classes.
345
+ </Prose>,
346
+ ]}
347
+ parameters={[
348
+ {
349
+ name: "msg",
350
+ type: "str",
351
+ doc: "Human readable string describing the exception.",
352
+ },
353
+ {
354
+ name: "code",
355
+ type: "int",
356
+ default: undefined,
357
+ doc: "Error code.",
358
+ },
359
+ ]}
360
+ attributes={[
361
+ {
362
+ name: "msg",
363
+ type: "str",
364
+ children: "Human readable string describing the exception.",
365
+ },
366
+ {
367
+ name: "code",
368
+ type: "int",
369
+ children: "Exception error code.",
370
+ },
371
+ ]}
372
+ seeAlso={["BaseException"]}
373
+ deprecated="Use NewException instead."
374
+ note="Do not include the 'self' parameter in the Args section."
375
+ />
376
+ </TestOutput>,
377
+ ).toRenderTo(
378
+ `
399
379
  """
400
380
  Exceptions are documented in the same way as classes.
401
381
 
@@ -419,34 +399,33 @@ describe("New Documentation Components", () => {
419
399
  Do not include the 'self' parameter in the Args section.
420
400
  """
421
401
 
422
-
423
402
  `,
424
403
  );
425
404
  });
426
405
 
427
406
  it("MethodDoc renders correctly without default note", () => {
428
- const res = toSourceText([
429
- <py.MethodDoc
430
- description={[
431
- <Prose>Class methods are similar to regular functions.</Prose>,
432
- ]}
433
- parameters={[
434
- {
435
- name: "param1",
436
- doc: "The first parameter.",
437
- },
438
- {
439
- name: "param2",
440
- doc: "The second parameter.",
441
- },
442
- ]}
443
- returns="True if successful, False otherwise."
444
- overrides="Base.method"
445
- />,
446
- ]);
447
-
448
- expect(res).toRenderTo(
449
- d`
407
+ expect(
408
+ <TestOutput>
409
+ <py.MethodDoc
410
+ description={[
411
+ <Prose>Class methods are similar to regular functions.</Prose>,
412
+ ]}
413
+ parameters={[
414
+ {
415
+ name: "param1",
416
+ doc: "The first parameter.",
417
+ },
418
+ {
419
+ name: "param2",
420
+ doc: "The second parameter.",
421
+ },
422
+ ]}
423
+ returns="True if successful, False otherwise."
424
+ overrides="Base.method"
425
+ />
426
+ </TestOutput>,
427
+ ).toRenderTo(
428
+ `
450
429
  """
451
430
  Class methods are similar to regular functions.
452
431
 
@@ -462,30 +441,29 @@ describe("New Documentation Components", () => {
462
441
  Base.method
463
442
  """
464
443
 
465
-
466
444
  `,
467
445
  );
468
446
  });
469
447
 
470
448
  it("MethodDoc renders correctly with custom note", () => {
471
- const res = toSourceText([
472
- <py.MethodDoc
473
- description={[
474
- <Prose>Class methods are similar to regular functions.</Prose>,
475
- ]}
476
- parameters={[
477
- {
478
- name: "param1",
479
- doc: "The first parameter.",
480
- },
481
- ]}
482
- returns="True if successful, False otherwise."
483
- note="This method has special behavior when called multiple times."
484
- />,
485
- ]);
486
-
487
- expect(res).toRenderTo(
488
- d`
449
+ expect(
450
+ <TestOutput>
451
+ <py.MethodDoc
452
+ description={[
453
+ <Prose>Class methods are similar to regular functions.</Prose>,
454
+ ]}
455
+ parameters={[
456
+ {
457
+ name: "param1",
458
+ doc: "The first parameter.",
459
+ },
460
+ ]}
461
+ returns="True if successful, False otherwise."
462
+ note="This method has special behavior when called multiple times."
463
+ />
464
+ </TestOutput>,
465
+ ).toRenderTo(
466
+ `
489
467
  """
490
468
  Class methods are similar to regular functions.
491
469
 
@@ -499,39 +477,41 @@ describe("New Documentation Components", () => {
499
477
  This method has special behavior when called multiple times.
500
478
  """
501
479
 
502
-
503
480
  `,
504
481
  );
505
482
  });
506
483
 
507
484
  it("ModuleDoc with minimal content", () => {
508
- const res = toSourceText([
509
- <py.ModuleDoc
510
- description={[<Prose>Simple module description.</Prose>]}
511
- />,
512
- ]);
513
-
514
- expect(res).toRenderTo(
515
- d`
485
+ expect(
486
+ <TestOutput>
487
+ <py.ModuleDoc
488
+ description={[<Prose>Simple module description.</Prose>]}
489
+ />
490
+ </TestOutput>,
491
+ ).toRenderTo(
492
+ `
516
493
  """
517
494
  Simple module description.
518
495
  """
519
496
 
520
-
521
497
  `,
522
498
  );
523
499
  });
524
500
 
525
501
  it("ModuleDoc with only todo items", () => {
526
- const res = toSourceText([
527
- <py.ModuleDoc
528
- description={[<Prose>Module with pending tasks.</Prose>]}
529
- todo={["Implement feature X", "Add more tests", "Update documentation"]}
530
- />,
531
- ]);
532
-
533
- expect(res).toRenderTo(
534
- d`
502
+ expect(
503
+ <TestOutput>
504
+ <py.ModuleDoc
505
+ description={[<Prose>Module with pending tasks.</Prose>]}
506
+ todo={[
507
+ "Implement feature X",
508
+ "Add more tests",
509
+ "Update documentation",
510
+ ]}
511
+ />
512
+ </TestOutput>,
513
+ ).toRenderTo(
514
+ `
535
515
  """
536
516
  Module with pending tasks.
537
517
 
@@ -541,45 +521,43 @@ describe("New Documentation Components", () => {
541
521
  * Update documentation
542
522
  """
543
523
 
544
-
545
524
  `,
546
525
  );
547
526
  });
548
527
 
549
528
  it("PropertyDoc minimal (description only)", () => {
550
- const res = toSourceText([
551
- <py.PropertyDoc
552
- description={[<Prose>A simple readonly property.</Prose>]}
553
- />,
554
- ]);
555
-
556
- expect(res).toRenderTo(
557
- d`
529
+ expect(
530
+ <TestOutput>
531
+ <py.PropertyDoc
532
+ description={[<Prose>A simple readonly property.</Prose>]}
533
+ />
534
+ </TestOutput>,
535
+ ).toRenderTo(
536
+ `
558
537
  """
559
538
  A simple readonly property.
560
539
  """
561
540
 
562
-
563
541
  `,
564
542
  );
565
543
  });
566
544
 
567
545
  it("PropertyDoc with getter and setter info", () => {
568
- const res = toSourceText([
569
- <py.PropertyDoc
570
- description={[
571
- <Prose>
572
- Properties with both a getter and setter should only be documented
573
- in their getter method.
574
- </Prose>,
575
- ]}
576
- returns=":obj:`list` of :obj:`str`: The property value."
577
- note="If the setter method contains notable behavior, it should be mentioned here."
578
- />,
579
- ]);
580
-
581
- expect(res).toRenderTo(
582
- d`
546
+ expect(
547
+ <TestOutput>
548
+ <py.PropertyDoc
549
+ description={[
550
+ <Prose>
551
+ Properties with both a getter and setter should only be documented
552
+ in their getter method.
553
+ </Prose>,
554
+ ]}
555
+ returns=":obj:`list` of :obj:`str`: The property value."
556
+ note="If the setter method contains notable behavior, it should be mentioned here."
557
+ />
558
+ </TestOutput>,
559
+ ).toRenderTo(
560
+ `
583
561
  """
584
562
  Properties with both a getter and setter should only be documented in their
585
563
  getter method.
@@ -591,48 +569,47 @@ describe("New Documentation Components", () => {
591
569
  If the setter method contains notable behavior, it should be mentioned here.
592
570
  """
593
571
 
594
-
595
572
  `,
596
573
  );
597
574
  });
598
575
 
599
576
  it("GeneratorDoc with complex parameters", () => {
600
- const res = toSourceText([
601
- <py.GeneratorDoc
602
- description={[
603
- <Prose>
604
- A more complex generator example with multiple parameters.
605
- </Prose>,
606
- ]}
607
- parameters={[
608
- {
609
- name: "start",
610
- type: "int",
611
- default: "0",
612
- doc: "Starting value for the sequence.",
613
- },
614
- {
615
- name: "stop",
616
- type: "int",
617
- doc: "Ending value for the sequence (exclusive).",
618
- },
619
- {
620
- name: "step",
621
- type: "int",
622
- default: "1",
623
- doc: "Step size between values.",
624
- },
625
- ]}
626
- yields="int: The next number in the sequence."
627
- raises={[
628
- "ValueError: If step is zero.",
629
- "TypeError: If parameters are not integers.",
630
- ]}
631
- />,
632
- ]);
633
-
634
- expect(res).toRenderTo(
635
- d`
577
+ expect(
578
+ <TestOutput>
579
+ <py.GeneratorDoc
580
+ description={[
581
+ <Prose>
582
+ A more complex generator example with multiple parameters.
583
+ </Prose>,
584
+ ]}
585
+ parameters={[
586
+ {
587
+ name: "start",
588
+ type: "int",
589
+ default: "0",
590
+ doc: "Starting value for the sequence.",
591
+ },
592
+ {
593
+ name: "stop",
594
+ type: "int",
595
+ doc: "Ending value for the sequence (exclusive).",
596
+ },
597
+ {
598
+ name: "step",
599
+ type: "int",
600
+ default: "1",
601
+ doc: "Step size between values.",
602
+ },
603
+ ]}
604
+ yields="int: The next number in the sequence."
605
+ raises={[
606
+ "ValueError: If step is zero.",
607
+ "TypeError: If parameters are not integers.",
608
+ ]}
609
+ />
610
+ </TestOutput>,
611
+ ).toRenderTo(
612
+ `
636
613
  """
637
614
  A more complex generator example with multiple parameters.
638
615
 
@@ -653,63 +630,62 @@ describe("New Documentation Components", () => {
653
630
  TypeError: If parameters are not integers.
654
631
  """
655
632
 
656
-
657
633
  `,
658
634
  );
659
635
  });
660
636
 
661
637
  it("ExceptionDoc with comprehensive documentation", () => {
662
- const res = toSourceText([
663
- <py.ExceptionDoc
664
- description={[
665
- <Prose>A custom exception for authentication failures.</Prose>,
666
- <Prose>
667
- This exception is raised when authentication credentials are invalid
668
- or when authentication tokens have expired.
669
- </Prose>,
670
- ]}
671
- parameters={[
672
- {
673
- name: "message",
674
- type: "str",
675
- doc: "Human readable error message describing the authentication failure.",
676
- },
677
- {
678
- name: "error_code",
679
- type: "int",
680
- default: "401",
681
- doc: "HTTP error code associated with the authentication failure.",
682
- },
683
- {
684
- name: "retry_after",
685
- type: "int",
686
- default: undefined,
687
- doc: "Number of seconds to wait before retrying authentication.",
688
- },
689
- ]}
690
- attributes={[
691
- {
692
- name: "message",
693
- type: "str",
694
- children: "The error message.",
695
- },
696
- {
697
- name: "error_code",
698
- type: "int",
699
- children: "HTTP status code.",
700
- },
701
- {
702
- name: "retry_after",
703
- type: "int",
704
- children: "Retry delay in seconds, if applicable.",
705
- },
706
- ]}
707
- note="This exception should be caught and handled gracefully in production code."
708
- />,
709
- ]);
710
-
711
- expect(res).toRenderTo(
712
- d`
638
+ expect(
639
+ <TestOutput>
640
+ <py.ExceptionDoc
641
+ description={[
642
+ <Prose>A custom exception for authentication failures.</Prose>,
643
+ <Prose>
644
+ This exception is raised when authentication credentials are
645
+ invalid or when authentication tokens have expired.
646
+ </Prose>,
647
+ ]}
648
+ parameters={[
649
+ {
650
+ name: "message",
651
+ type: "str",
652
+ doc: "Human readable error message describing the authentication failure.",
653
+ },
654
+ {
655
+ name: "error_code",
656
+ type: "int",
657
+ default: "401",
658
+ doc: "HTTP error code associated with the authentication failure.",
659
+ },
660
+ {
661
+ name: "retry_after",
662
+ type: "int",
663
+ default: undefined,
664
+ doc: "Number of seconds to wait before retrying authentication.",
665
+ },
666
+ ]}
667
+ attributes={[
668
+ {
669
+ name: "message",
670
+ type: "str",
671
+ children: "The error message.",
672
+ },
673
+ {
674
+ name: "error_code",
675
+ type: "int",
676
+ children: "HTTP status code.",
677
+ },
678
+ {
679
+ name: "retry_after",
680
+ type: "int",
681
+ children: "Retry delay in seconds, if applicable.",
682
+ },
683
+ ]}
684
+ note="This exception should be caught and handled gracefully in production code."
685
+ />
686
+ </TestOutput>,
687
+ ).toRenderTo(
688
+ `
713
689
  """
714
690
  A custom exception for authentication failures.
715
691
 
@@ -736,35 +712,34 @@ describe("New Documentation Components", () => {
736
712
  This exception should be caught and handled gracefully in production code.
737
713
  """
738
714
 
739
-
740
715
  `,
741
716
  );
742
717
  });
743
718
 
744
719
  it("MethodDoc with raises but no returns", () => {
745
- const res = toSourceText([
746
- <py.MethodDoc
747
- description={[
748
- <Prose>
749
- A method that performs an action but doesn't return a value.
750
- </Prose>,
751
- ]}
752
- parameters={[
753
- {
754
- name: "data",
755
- type: "bytes",
756
- doc: "Raw data to process.",
757
- },
758
- ]}
759
- raises={[
760
- "ValueError: If data is empty or invalid.",
761
- "IOError: If processing fails due to I/O issues.",
762
- ]}
763
- />,
764
- ]);
765
-
766
- expect(res).toRenderTo(
767
- d`
720
+ expect(
721
+ <TestOutput>
722
+ <py.MethodDoc
723
+ description={[
724
+ <Prose>
725
+ A method that performs an action but doesn't return a value.
726
+ </Prose>,
727
+ ]}
728
+ parameters={[
729
+ {
730
+ name: "data",
731
+ type: "bytes",
732
+ doc: "Raw data to process.",
733
+ },
734
+ ]}
735
+ raises={[
736
+ "ValueError: If data is empty or invalid.",
737
+ "IOError: If processing fails due to I/O issues.",
738
+ ]}
739
+ />
740
+ </TestOutput>,
741
+ ).toRenderTo(
742
+ `
768
743
  """
769
744
  A method that performs an action but doesn't return a value.
770
745
 
@@ -778,24 +753,23 @@ describe("New Documentation Components", () => {
778
753
  IOError: If processing fails due to I/O issues.
779
754
  """
780
755
 
781
-
782
756
  `,
783
757
  );
784
758
  });
785
759
 
786
760
  it("MethodDoc with no parameters", () => {
787
- const res = toSourceText([
788
- <py.MethodDoc
789
- description={[
790
- <Prose>A simple method with no parameters (except self).</Prose>,
791
- ]}
792
- returns="bool: True if the operation was successful."
793
- note="This is a parameterless method that only operates on instance state."
794
- />,
795
- ]);
796
-
797
- expect(res).toRenderTo(
798
- d`
761
+ expect(
762
+ <TestOutput>
763
+ <py.MethodDoc
764
+ description={[
765
+ <Prose>A simple method with no parameters (except self).</Prose>,
766
+ ]}
767
+ returns="bool: True if the operation was successful."
768
+ note="This is a parameterless method that only operates on instance state."
769
+ />
770
+ </TestOutput>,
771
+ ).toRenderTo(
772
+ `
799
773
  """
800
774
  A simple method with no parameters (except self).
801
775
 
@@ -806,57 +780,55 @@ describe("New Documentation Components", () => {
806
780
  This is a parameterless method that only operates on instance state.
807
781
  """
808
782
 
809
-
810
783
  `,
811
784
  );
812
785
  });
813
786
 
814
787
  it("AttributeDoc standalone usage", () => {
815
- const res = toSourceText([
816
- <py.PyDoc>
817
- <py.AttributeDoc name="connection_timeout" type="float">
818
- Maximum time in seconds to wait for a connection to be established.
819
- </py.AttributeDoc>
820
- </py.PyDoc>,
821
- ]);
822
-
823
- expect(res).toRenderTo(
824
- d`
788
+ expect(
789
+ <TestOutput>
790
+ <py.PyDoc>
791
+ <py.AttributeDoc name="connection_timeout" type="float">
792
+ Maximum time in seconds to wait for a connection to be established.
793
+ </py.AttributeDoc>
794
+ </py.PyDoc>
795
+ </TestOutput>,
796
+ ).toRenderTo(
797
+ `
825
798
  """
826
799
  connection_timeout (float): Maximum time in seconds to wait for a connection to
827
800
  be established.
828
801
  """
829
802
 
830
-
831
803
  `,
832
804
  );
833
805
  });
834
806
 
835
807
  it("GeneratorDoc with examples in description", () => {
836
- const res = toSourceText([
837
- <py.GeneratorDoc
838
- description={[
839
- <Prose>
840
- Generators have a Yields section instead of a Returns section.
841
- </Prose>,
842
- <py.PyDocExample>
843
- {`print([i for i in example_generator(4)])\n[0, 1, 2, 3]`}
844
- </py.PyDocExample>,
845
- ]}
846
- parameters={[
847
- {
848
- name: "n",
849
- type: "int",
850
- doc: "The upper limit of the range to generate, from 0 to n - 1.",
851
- },
852
- ]}
853
- yields="int: The next number in the range of 0 to n - 1."
854
- note="Examples should be written in doctest format, and should illustrate how to use the function."
855
- />,
856
- ]);
857
-
858
- expect(res).toRenderTo(
859
- d`
808
+ expect(
809
+ <TestOutput>
810
+ <py.GeneratorDoc
811
+ description={[
812
+ <Prose>
813
+ Generators have a Yields section instead of a Returns section.
814
+ </Prose>,
815
+ <py.PyDocExample>
816
+ {`print([i for i in example_generator(4)])\n[0, 1, 2, 3]`}
817
+ </py.PyDocExample>,
818
+ ]}
819
+ parameters={[
820
+ {
821
+ name: "n",
822
+ type: "int",
823
+ doc: "The upper limit of the range to generate, from 0 to n - 1.",
824
+ },
825
+ ]}
826
+ yields="int: The next number in the range of 0 to n - 1."
827
+ note="Examples should be written in doctest format, and should illustrate how to use the function."
828
+ />
829
+ </TestOutput>,
830
+ ).toRenderTo(
831
+ `
860
832
  """
861
833
  Generators have a Yields section instead of a Returns section.
862
834
 
@@ -873,7 +845,6 @@ describe("New Documentation Components", () => {
873
845
  Examples should be written in doctest format, and should illustrate how to use the function.
874
846
  """
875
847
 
876
-
877
848
  `,
878
849
  );
879
850
  });
@@ -925,8 +896,9 @@ describe("Full example", () => {
925
896
  style="google"
926
897
  />
927
898
  );
928
- const res = toSourceText(
929
- [
899
+
900
+ expect(
901
+ <TestOutput>
930
902
  <py.ClassDeclaration name="A" doc={doc}>
931
903
  <py.StatementList>
932
904
  <py.VariableDeclaration name="just_name" />
@@ -937,13 +909,10 @@ describe("Full example", () => {
937
909
  initializer={12}
938
910
  />
939
911
  </py.StatementList>
940
- </py.ClassDeclaration>,
941
- ],
942
- { printOptions: { printWidth: 80, tabWidth: 4 } },
943
- );
944
-
945
- expect(res).toRenderTo(
946
- d`
912
+ </py.ClassDeclaration>
913
+ </TestOutput>,
914
+ ).toRenderTo(
915
+ `
947
916
  class A:
948
917
  """
949
918
  This is an example of a long docstring that will be broken in lines. We will
@@ -964,7 +933,7 @@ describe("Full example", () => {
964
933
  nickname, or even a codename (e.g., 'Agent X'). It's used primarily
965
934
  for display purposes, logging, or greeting messages and is not
966
935
  required to be unique or validated unless specified by the caller.
967
- Defaults to \"John Doe\".
936
+ Defaults to "John Doe".
968
937
 
969
938
  somebody2 (str): Somebody's name. This can be any string representing a
970
939
  person, whether it's a first name, full name, nickname, or even a
@@ -993,7 +962,6 @@ describe("Full example", () => {
993
962
  name_and_type: int = None
994
963
  name_type_and_value: int = 12
995
964
 
996
-
997
965
  `,
998
966
  );
999
967
  });
@@ -1030,8 +998,9 @@ describe("Full example", () => {
1030
998
  style="google"
1031
999
  />
1032
1000
  );
1033
- const res = toSourceText(
1034
- [
1001
+
1002
+ expect(
1003
+ <TestOutput>
1035
1004
  <py.FunctionDeclaration name="some_function" doc={doc}>
1036
1005
  <py.StatementList>
1037
1006
  <py.VariableDeclaration name="just_name" />
@@ -1042,13 +1011,10 @@ describe("Full example", () => {
1042
1011
  initializer={12}
1043
1012
  />
1044
1013
  </py.StatementList>
1045
- </py.FunctionDeclaration>,
1046
- ],
1047
- { printOptions: { printWidth: 80, tabWidth: 4 } },
1048
- );
1049
-
1050
- expect(res).toRenderTo(
1051
- d`
1014
+ </py.FunctionDeclaration>
1015
+ </TestOutput>,
1016
+ ).toRenderTo(
1017
+ `
1052
1018
  def some_function():
1053
1019
  """
1054
1020
  This is an example of a long docstring that will be broken in lines. We will
@@ -1064,7 +1030,7 @@ describe("Full example", () => {
1064
1030
  nickname, or even a codename (e.g., 'Agent X'). It's used primarily
1065
1031
  for display purposes, logging, or greeting messages and is not
1066
1032
  required to be unique or validated unless specified by the caller.
1067
- Defaults to \"John Doe\".
1033
+ Defaults to "John Doe".
1068
1034
 
1069
1035
  somebody2 (str): Somebody's name. This can be any string representing a
1070
1036
  person, whether it's a first name, full name, nickname, or even a
@@ -1088,25 +1054,21 @@ describe("Full example", () => {
1088
1054
  name_and_type: number = None
1089
1055
  name_type_and_value: number = 12
1090
1056
 
1091
-
1092
1057
  `,
1093
1058
  );
1094
1059
  });
1095
1060
 
1096
1061
  it("renders correctly in a Variable", () => {
1097
- const res = toSourceText(
1098
- [
1062
+ expect(
1063
+ <TestOutput>
1099
1064
  <py.VariableDeclaration
1100
1065
  name="myVar"
1101
1066
  initializer={42}
1102
1067
  doc="This is a very long docstring that will be broken in two lines when rendered. This part of the docstring will be in the second line."
1103
- />,
1104
- ],
1105
- { printOptions: { printWidth: 80, tabWidth: 4 } },
1106
- );
1107
-
1108
- expect(res).toRenderTo(
1109
- d`
1068
+ />
1069
+ </TestOutput>,
1070
+ ).toRenderTo(
1071
+ `
1110
1072
  # This is a very long docstring that will be broken in two lines when rendered.
1111
1073
  # This part of the docstring will be in the second line.
1112
1074
  my_var = 42
@@ -1120,8 +1082,8 @@ describe("Full example", () => {
1120
1082
  description={[<Prose>An enum representing colors.</Prose>]}
1121
1083
  />
1122
1084
  );
1123
- const result = toSourceText(
1124
- [
1085
+ expect(
1086
+ <TestOutput externals={[enumModule]}>
1125
1087
  <py.ClassEnumDeclaration
1126
1088
  name="Color"
1127
1089
  baseType="IntEnum"
@@ -1131,11 +1093,10 @@ describe("Full example", () => {
1131
1093
  { name: "BLUE", value: "3", doc: "The color blue." },
1132
1094
  ]}
1133
1095
  doc={doc}
1134
- />,
1135
- ],
1136
- { externals: [enumModule] },
1137
- );
1138
- const expected = d`
1096
+ />
1097
+ </TestOutput>,
1098
+ ).toRenderTo(
1099
+ `
1139
1100
  from enum import IntEnum
1140
1101
 
1141
1102
 
@@ -1157,9 +1118,8 @@ describe("Full example", () => {
1157
1118
  The color blue.
1158
1119
  """
1159
1120
 
1160
-
1161
- `;
1162
- expect(result).toRenderTo(expected);
1121
+ `,
1122
+ );
1163
1123
  });
1164
1124
 
1165
1125
  it("ModuleDoc with SourceFile integration", () => {
@@ -1188,47 +1148,40 @@ describe("Full example", () => {
1188
1148
  />
1189
1149
  );
1190
1150
 
1191
- const content = (
1192
- <py.SourceFile path="utils.py" doc={moduleDoc}>
1193
- <py.VariableDeclaration name="DEFAULT_TIMEOUT" initializer={30} />
1194
- <py.VariableDeclaration name="MAX_RETRIES" initializer={3} />
1195
- <py.FunctionDeclaration name="process_data">
1196
- pass
1197
- </py.FunctionDeclaration>
1198
- </py.SourceFile>
1199
- );
1200
-
1201
- const res = toSourceTextMultiple([content]);
1202
- const file = res.contents.find(
1203
- (f) => f.kind === "file" && f.path === "utils.py",
1204
- );
1205
- expect(file).toBeDefined();
1206
-
1207
- assertFileContents(res, {
1208
- "utils.py": d`
1209
- """
1210
- This module provides utility functions for data processing. It includes
1211
- functions for validation, transformation, and analysis.
1212
-
1213
- Attributes:
1214
- DEFAULT_TIMEOUT (int): Default timeout value in seconds.
1151
+ expect(
1152
+ <TestOutputDirectory>
1153
+ <py.SourceFile path="utils.py" doc={moduleDoc}>
1154
+ <py.VariableDeclaration name="DEFAULT_TIMEOUT" initializer={30} />
1155
+ <py.VariableDeclaration name="MAX_RETRIES" initializer={3} />
1156
+ <py.FunctionDeclaration name="process_data">
1157
+ pass
1158
+ </py.FunctionDeclaration>
1159
+ </py.SourceFile>
1160
+ </TestOutputDirectory>,
1161
+ ).toRenderTo({
1162
+ "utils.py": `
1163
+ """
1164
+ This module provides utility functions for data processing. It includes
1165
+ functions for validation, transformation, and analysis.
1215
1166
 
1216
- MAX_RETRIES (int): Maximum number of retry attempts.
1167
+ Attributes:
1168
+ DEFAULT_TIMEOUT (int): Default timeout value in seconds.
1217
1169
 
1218
- Todo:
1219
- * Add caching functionality
1220
- * Improve error messages
1221
- """
1170
+ MAX_RETRIES (int): Maximum number of retry attempts.
1222
1171
 
1223
- default_timeout = 30
1172
+ Todo:
1173
+ * Add caching functionality
1174
+ * Improve error messages
1175
+ """
1224
1176
 
1225
- max_retries = 3
1177
+ default_timeout = 30
1226
1178
 
1227
- def process_data():
1228
- pass
1179
+ max_retries = 3
1229
1180
 
1181
+ def process_data():
1182
+ pass
1230
1183
 
1231
- `,
1184
+ `,
1232
1185
  });
1233
1186
  });
1234
1187
 
@@ -1253,14 +1206,14 @@ describe("Full example", () => {
1253
1206
  />
1254
1207
  );
1255
1208
 
1256
- const result = toSourceText([
1257
- <py.FunctionDeclaration name="fibonacci_generator" doc={generatorDoc}>
1258
- yield 0
1259
- </py.FunctionDeclaration>,
1260
- ]);
1261
-
1262
- expect(result).toRenderTo(
1263
- d`
1209
+ expect(
1210
+ <TestOutput>
1211
+ <py.FunctionDeclaration name="fibonacci_generator" doc={generatorDoc}>
1212
+ yield 0
1213
+ </py.FunctionDeclaration>
1214
+ </TestOutput>,
1215
+ ).toRenderTo(
1216
+ `
1264
1217
  def fibonacci_generator():
1265
1218
  """
1266
1219
  A generator function that yields fibonacci numbers. This is an efficient way
@@ -1274,7 +1227,6 @@ describe("Full example", () => {
1274
1227
  """
1275
1228
  yield 0
1276
1229
 
1277
-
1278
1230
  `,
1279
1231
  );
1280
1232
  });
@@ -1304,21 +1256,21 @@ describe("Full example", () => {
1304
1256
  />
1305
1257
  );
1306
1258
 
1307
- const result = toSourceText([
1308
- <py.ClassDeclaration
1309
- name="ValidationError"
1310
- bases={["Exception"]}
1311
- doc={exceptionDoc}
1312
- >
1313
- <py.StatementList>
1314
- <py.VariableDeclaration name="field_name" type="str" />
1315
- <py.VariableDeclaration name="error_code" type="int" />
1316
- </py.StatementList>
1317
- </py.ClassDeclaration>,
1318
- ]);
1319
-
1320
- expect(result).toRenderTo(
1321
- d`
1259
+ expect(
1260
+ <TestOutput>
1261
+ <py.ClassDeclaration
1262
+ name="ValidationError"
1263
+ bases={["Exception"]}
1264
+ doc={exceptionDoc}
1265
+ >
1266
+ <py.StatementList>
1267
+ <py.VariableDeclaration name="field_name" type="str" />
1268
+ <py.VariableDeclaration name="error_code" type="int" />
1269
+ </py.StatementList>
1270
+ </py.ClassDeclaration>
1271
+ </TestOutput>,
1272
+ ).toRenderTo(
1273
+ `
1322
1274
  class ValidationError(Exception):
1323
1275
  """
1324
1276
  Custom exception raised when data validation fails. This exception includes
@@ -1333,7 +1285,6 @@ describe("Full example", () => {
1333
1285
  field_name: str = None
1334
1286
  error_code: int = None
1335
1287
 
1336
-
1337
1288
  `,
1338
1289
  );
1339
1290
  });
@@ -1351,15 +1302,16 @@ describe("Full example", () => {
1351
1302
  />
1352
1303
  );
1353
1304
 
1354
- const result = toSourceText([
1355
- <py.ClassDeclaration name="Person">
1356
- <py.PropertyDeclaration name="full_name" doc={propertyDoc} type="str">
1357
- return "John Doe"
1358
- </py.PropertyDeclaration>
1359
- </py.ClassDeclaration>,
1360
- ]);
1361
-
1362
- expect(result).toRenderTo(`
1305
+ expect(
1306
+ <TestOutput>
1307
+ <py.ClassDeclaration name="Person">
1308
+ <py.PropertyDeclaration name="full_name" doc={propertyDoc} type="str">
1309
+ return "John Doe"
1310
+ </py.PropertyDeclaration>
1311
+ </py.ClassDeclaration>
1312
+ </TestOutput>,
1313
+ ).toRenderTo(
1314
+ `
1363
1315
  class Person:
1364
1316
  @property
1365
1317
  def full_name(self) -> str:
@@ -1370,7 +1322,8 @@ describe("Full example", () => {
1370
1322
  return "John Doe"
1371
1323
 
1372
1324
 
1373
- `);
1325
+ `,
1326
+ );
1374
1327
  });
1375
1328
 
1376
1329
  it("MethodDoc with FunctionDeclaration (inside class) integration", () => {
@@ -1402,24 +1355,24 @@ describe("Full example", () => {
1402
1355
  />
1403
1356
  );
1404
1357
 
1405
- const result = toSourceText([
1406
- <py.ClassDeclaration name="DataValidator">
1407
- <py.MethodDeclaration
1408
- name="validate"
1409
- doc={methodDoc}
1410
- parameters={[
1411
- { name: "data", type: "dict" },
1412
- { name: "strict", type: "bool", default: true },
1413
- ]}
1414
- returnType="bool"
1415
- >
1416
- return self.validate(data, strict)
1417
- </py.MethodDeclaration>
1418
- </py.ClassDeclaration>,
1419
- ]);
1420
-
1421
- expect(result).toRenderTo(
1422
- d`
1358
+ expect(
1359
+ <TestOutput>
1360
+ <py.ClassDeclaration name="DataValidator">
1361
+ <py.MethodDeclaration
1362
+ name="validate"
1363
+ doc={methodDoc}
1364
+ parameters={[
1365
+ { name: "data", type: "dict" },
1366
+ { name: "strict", type: "bool", default: true },
1367
+ ]}
1368
+ returnType="bool"
1369
+ >
1370
+ return self.validate(data, strict)
1371
+ </py.MethodDeclaration>
1372
+ </py.ClassDeclaration>
1373
+ </TestOutput>,
1374
+ ).toRenderTo(
1375
+ `
1423
1376
  class DataValidator:
1424
1377
  def validate(self, data: dict, strict: bool = True) -> bool:
1425
1378
  """
@@ -1444,7 +1397,6 @@ describe("Full example", () => {
1444
1397
  return self.validate(data, strict)
1445
1398
 
1446
1399
 
1447
-
1448
1400
  `,
1449
1401
  );
1450
1402
  });