@alloy-js/python 0.0.1

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 (206) hide show
  1. package/CHANGELOG.md +3 -0
  2. package/LICENSE +7 -0
  3. package/api-extractor.json +4 -0
  4. package/dist/src/builtins/python.d.ts +9 -0
  5. package/dist/src/builtins/python.d.ts.map +1 -0
  6. package/dist/src/builtins/python.js +17 -0
  7. package/dist/src/components/Atom.d.ts +19 -0
  8. package/dist/src/components/Atom.d.ts.map +1 -0
  9. package/dist/src/components/Atom.js +82 -0
  10. package/dist/src/components/CallSignature.d.ts +79 -0
  11. package/dist/src/components/CallSignature.d.ts.map +1 -0
  12. package/dist/src/components/CallSignature.js +201 -0
  13. package/dist/src/components/ClassDeclaration.d.ts +37 -0
  14. package/dist/src/components/ClassDeclaration.d.ts.map +1 -0
  15. package/dist/src/components/ClassDeclaration.js +83 -0
  16. package/dist/src/components/ClassInstantiation.d.ts +24 -0
  17. package/dist/src/components/ClassInstantiation.d.ts.map +1 -0
  18. package/dist/src/components/ClassInstantiation.js +35 -0
  19. package/dist/src/components/Declaration.d.ts +48 -0
  20. package/dist/src/components/Declaration.d.ts.map +1 -0
  21. package/dist/src/components/Declaration.js +37 -0
  22. package/dist/src/components/EnumDeclaration.d.ts +164 -0
  23. package/dist/src/components/EnumDeclaration.d.ts.map +1 -0
  24. package/dist/src/components/EnumDeclaration.js +278 -0
  25. package/dist/src/components/EnumMember.d.ts +46 -0
  26. package/dist/src/components/EnumMember.d.ts.map +1 -0
  27. package/dist/src/components/EnumMember.js +67 -0
  28. package/dist/src/components/FunctionCallExpression.d.ts +19 -0
  29. package/dist/src/components/FunctionCallExpression.d.ts.map +1 -0
  30. package/dist/src/components/FunctionCallExpression.js +40 -0
  31. package/dist/src/components/FunctionDeclaration.d.ts +47 -0
  32. package/dist/src/components/FunctionDeclaration.d.ts.map +1 -0
  33. package/dist/src/components/FunctionDeclaration.js +107 -0
  34. package/dist/src/components/ImportStatement.d.ts +39 -0
  35. package/dist/src/components/ImportStatement.d.ts.map +1 -0
  36. package/dist/src/components/ImportStatement.js +104 -0
  37. package/dist/src/components/MemberExpression.d.ts +97 -0
  38. package/dist/src/components/MemberExpression.d.ts.map +1 -0
  39. package/dist/src/components/MemberExpression.js +308 -0
  40. package/dist/src/components/NoNamePolicy.d.ts +23 -0
  41. package/dist/src/components/NoNamePolicy.d.ts.map +1 -0
  42. package/dist/src/components/NoNamePolicy.js +27 -0
  43. package/dist/src/components/PyDoc.d.ts +90 -0
  44. package/dist/src/components/PyDoc.d.ts.map +1 -0
  45. package/dist/src/components/PyDoc.js +280 -0
  46. package/dist/src/components/PythonBlock.d.ts +23 -0
  47. package/dist/src/components/PythonBlock.d.ts.map +1 -0
  48. package/dist/src/components/PythonBlock.js +31 -0
  49. package/dist/src/components/Reference.d.ts +13 -0
  50. package/dist/src/components/Reference.d.ts.map +1 -0
  51. package/dist/src/components/Reference.js +18 -0
  52. package/dist/src/components/SourceFile.d.ts +46 -0
  53. package/dist/src/components/SourceFile.d.ts.map +1 -0
  54. package/dist/src/components/SourceFile.js +75 -0
  55. package/dist/src/components/StatementList.d.ts +25 -0
  56. package/dist/src/components/StatementList.d.ts.map +1 -0
  57. package/dist/src/components/StatementList.js +29 -0
  58. package/dist/src/components/VariableDeclaration.d.ts +62 -0
  59. package/dist/src/components/VariableDeclaration.d.ts.map +1 -0
  60. package/dist/src/components/VariableDeclaration.js +131 -0
  61. package/dist/src/components/index.d.ts +19 -0
  62. package/dist/src/components/index.d.ts.map +1 -0
  63. package/dist/src/components/index.js +18 -0
  64. package/dist/src/create-module.d.ts +16 -0
  65. package/dist/src/create-module.d.ts.map +1 -0
  66. package/dist/src/create-module.js +64 -0
  67. package/dist/src/index.d.ts +8 -0
  68. package/dist/src/index.d.ts.map +1 -0
  69. package/dist/src/index.js +7 -0
  70. package/dist/src/name-policy.d.ts +5 -0
  71. package/dist/src/name-policy.d.ts.map +1 -0
  72. package/dist/src/name-policy.js +47 -0
  73. package/dist/src/parameter-descriptor.d.ts +31 -0
  74. package/dist/src/parameter-descriptor.d.ts.map +1 -0
  75. package/dist/src/parameter-descriptor.js +1 -0
  76. package/dist/src/symbol-creation.d.ts +4 -0
  77. package/dist/src/symbol-creation.d.ts.map +1 -0
  78. package/dist/src/symbol-creation.js +24 -0
  79. package/dist/src/symbols/custom-output-scope.d.ts +10 -0
  80. package/dist/src/symbols/custom-output-scope.d.ts.map +1 -0
  81. package/dist/src/symbols/custom-output-scope.js +25 -0
  82. package/dist/src/symbols/index.d.ts +7 -0
  83. package/dist/src/symbols/index.d.ts.map +1 -0
  84. package/dist/src/symbols/index.js +6 -0
  85. package/dist/src/symbols/python-member-scope.d.ts +7 -0
  86. package/dist/src/symbols/python-member-scope.d.ts.map +1 -0
  87. package/dist/src/symbols/python-member-scope.js +9 -0
  88. package/dist/src/symbols/python-module-scope.d.ts +25 -0
  89. package/dist/src/symbols/python-module-scope.d.ts.map +1 -0
  90. package/dist/src/symbols/python-module-scope.js +52 -0
  91. package/dist/src/symbols/python-output-symbol.d.ts +19 -0
  92. package/dist/src/symbols/python-output-symbol.d.ts.map +1 -0
  93. package/dist/src/symbols/python-output-symbol.js +22 -0
  94. package/dist/src/symbols/reference.d.ts +4 -0
  95. package/dist/src/symbols/reference.d.ts.map +1 -0
  96. package/dist/src/symbols/reference.js +60 -0
  97. package/dist/src/symbols/scopes.d.ts +5 -0
  98. package/dist/src/symbols/scopes.d.ts.map +1 -0
  99. package/dist/src/symbols/scopes.js +4 -0
  100. package/dist/src/utils.d.ts +7 -0
  101. package/dist/src/utils.d.ts.map +1 -0
  102. package/dist/src/utils.js +12 -0
  103. package/dist/test/callsignatures.test.d.ts +2 -0
  104. package/dist/test/callsignatures.test.d.ts.map +1 -0
  105. package/dist/test/callsignatures.test.js +276 -0
  106. package/dist/test/classdeclarations.test.d.ts +2 -0
  107. package/dist/test/classdeclarations.test.d.ts.map +1 -0
  108. package/dist/test/classdeclarations.test.js +397 -0
  109. package/dist/test/classinstantiations.test.d.ts +2 -0
  110. package/dist/test/classinstantiations.test.d.ts.map +1 -0
  111. package/dist/test/classinstantiations.test.js +168 -0
  112. package/dist/test/enums.test.d.ts +2 -0
  113. package/dist/test/enums.test.d.ts.map +1 -0
  114. package/dist/test/enums.test.js +211 -0
  115. package/dist/test/externals.test.d.ts +2 -0
  116. package/dist/test/externals.test.d.ts.map +1 -0
  117. package/dist/test/externals.test.js +219 -0
  118. package/dist/test/functioncallexpressions.test.d.ts +2 -0
  119. package/dist/test/functioncallexpressions.test.d.ts.map +1 -0
  120. package/dist/test/functioncallexpressions.test.js +156 -0
  121. package/dist/test/functiondeclaration.test.d.ts +2 -0
  122. package/dist/test/functiondeclaration.test.d.ts.map +1 -0
  123. package/dist/test/functiondeclaration.test.js +363 -0
  124. package/dist/test/imports.test.d.ts +2 -0
  125. package/dist/test/imports.test.d.ts.map +1 -0
  126. package/dist/test/imports.test.js +262 -0
  127. package/dist/test/memberexpressions.test.d.ts +2 -0
  128. package/dist/test/memberexpressions.test.d.ts.map +1 -0
  129. package/dist/test/memberexpressions.test.js +879 -0
  130. package/dist/test/namepolicies.test.d.ts +2 -0
  131. package/dist/test/namepolicies.test.d.ts.map +1 -0
  132. package/dist/test/namepolicies.test.js +109 -0
  133. package/dist/test/pydocs.test.d.ts +2 -0
  134. package/dist/test/pydocs.test.d.ts.map +1 -0
  135. package/dist/test/pydocs.test.js +500 -0
  136. package/dist/test/references.test.d.ts +2 -0
  137. package/dist/test/references.test.d.ts.map +1 -0
  138. package/dist/test/references.test.js +49 -0
  139. package/dist/test/sourcefiles.test.d.ts +2 -0
  140. package/dist/test/sourcefiles.test.d.ts.map +1 -0
  141. package/dist/test/sourcefiles.test.js +198 -0
  142. package/dist/test/utils.d.ts +23 -0
  143. package/dist/test/utils.d.ts.map +1 -0
  144. package/dist/test/utils.js +88 -0
  145. package/dist/test/values.test.d.ts +2 -0
  146. package/dist/test/values.test.d.ts.map +1 -0
  147. package/dist/test/values.test.js +78 -0
  148. package/dist/test/variables.test.d.ts +2 -0
  149. package/dist/test/variables.test.d.ts.map +1 -0
  150. package/dist/test/variables.test.js +173 -0
  151. package/dist/tsconfig.tsbuildinfo +1 -0
  152. package/package.json +39 -0
  153. package/src/builtins/python.ts +20 -0
  154. package/src/components/Atom.tsx +76 -0
  155. package/src/components/CallSignature.tsx +251 -0
  156. package/src/components/ClassDeclaration.tsx +98 -0
  157. package/src/components/ClassInstantiation.tsx +54 -0
  158. package/src/components/Declaration.tsx +91 -0
  159. package/src/components/EnumDeclaration.tsx +291 -0
  160. package/src/components/EnumMember.tsx +92 -0
  161. package/src/components/FunctionCallExpression.tsx +36 -0
  162. package/src/components/FunctionDeclaration.tsx +121 -0
  163. package/src/components/ImportStatement.tsx +134 -0
  164. package/src/components/MemberExpression.tsx +456 -0
  165. package/src/components/NoNamePolicy.tsx +31 -0
  166. package/src/components/PyDoc.tsx +331 -0
  167. package/src/components/PythonBlock.tsx +26 -0
  168. package/src/components/Reference.tsx +21 -0
  169. package/src/components/SourceFile.tsx +93 -0
  170. package/src/components/StatementList.tsx +28 -0
  171. package/src/components/VariableDeclaration.tsx +180 -0
  172. package/src/components/index.ts +18 -0
  173. package/src/create-module.ts +102 -0
  174. package/src/index.ts +7 -0
  175. package/src/name-policy.ts +101 -0
  176. package/src/parameter-descriptor.ts +36 -0
  177. package/src/symbol-creation.ts +36 -0
  178. package/src/symbols/custom-output-scope.ts +35 -0
  179. package/src/symbols/index.ts +6 -0
  180. package/src/symbols/python-member-scope.ts +12 -0
  181. package/src/symbols/python-module-scope.ts +89 -0
  182. package/src/symbols/python-output-symbol.ts +36 -0
  183. package/src/symbols/reference.ts +99 -0
  184. package/src/symbols/scopes.ts +9 -0
  185. package/src/utils.ts +27 -0
  186. package/temp/api.json +7207 -0
  187. package/test/callsignatures.test.tsx +256 -0
  188. package/test/classdeclarations.test.tsx +320 -0
  189. package/test/classinstantiations.test.tsx +159 -0
  190. package/test/enums.test.tsx +203 -0
  191. package/test/externals.test.tsx +190 -0
  192. package/test/functioncallexpressions.test.tsx +145 -0
  193. package/test/functiondeclaration.test.tsx +327 -0
  194. package/test/imports.test.tsx +214 -0
  195. package/test/memberexpressions.test.tsx +725 -0
  196. package/test/namepolicies.test.tsx +109 -0
  197. package/test/pydocs.test.tsx +528 -0
  198. package/test/references.test.tsx +36 -0
  199. package/test/sourcefiles.test.tsx +131 -0
  200. package/test/utils.tsx +131 -0
  201. package/test/values.test.tsx +61 -0
  202. package/test/variables.test.tsx +153 -0
  203. package/tsconfig.json +12 -0
  204. package/tsdoc-metadata.json +11 -0
  205. package/vitest.config.ts +10 -0
  206. package/vitest.setup.ts +1 -0
@@ -0,0 +1,879 @@
1
+ import { createComponent as _$createComponent, memo as _$memo, createIntrinsic as _$createIntrinsic } from "@alloy-js/core/jsx-runtime";
2
+ import { code, memberRefkey, refkey } from "@alloy-js/core";
3
+ import { d } from "@alloy-js/core/testing";
4
+ import { describe, expect, it } from "vitest";
5
+ import * as py from "../src/index.js";
6
+ import { ClassDeclaration, FunctionDeclaration, SourceFile, VariableDeclaration } from "../src/index.js";
7
+ import { assertFileContents, toSourceText, toSourceTextMultiple } from "./utils.js";
8
+ it("renders basic member expression with dot notation", () => {
9
+ expect(toSourceText([_$createComponent(py.MemberExpression, {
10
+ get children() {
11
+ return [_$createComponent(py.MemberExpression.Part, {
12
+ id: "obj"
13
+ }), _$createComponent(py.MemberExpression.Part, {
14
+ id: "property"
15
+ })];
16
+ }
17
+ })])).toBe(d`
18
+ obj.property
19
+ `);
20
+ });
21
+ it("renders basic member expression with key", () => {
22
+ expect(toSourceText([_$createComponent(py.MemberExpression, {
23
+ get children() {
24
+ return [_$createComponent(py.MemberExpression.Part, {
25
+ id: "arr"
26
+ }), _$createComponent(py.MemberExpression.Part, {
27
+ key: 12345
28
+ }), _$createComponent(py.MemberExpression.Part, {
29
+ id: "foo-bar"
30
+ })];
31
+ }
32
+ })])).toBe(d`
33
+ arr[12345].foo-bar
34
+ `);
35
+ });
36
+ it("renders basic member expression with key with reference", () => {
37
+ const rk1 = refkey();
38
+ expect(toSourceText([_$createComponent(py.StatementList, {
39
+ get children() {
40
+ return [_$createComponent(py.VariableDeclaration, {
41
+ name: "test1",
42
+ refkey: rk1,
43
+ initializer: 1
44
+ }), _$createComponent(py.MemberExpression, {
45
+ get children() {
46
+ return [_$createComponent(py.MemberExpression.Part, {
47
+ id: "arr"
48
+ }), _$createComponent(py.MemberExpression.Part, {
49
+ key: rk1
50
+ }), _$createComponent(py.MemberExpression.Part, {
51
+ id: "foo-bar"
52
+ })];
53
+ }
54
+ })];
55
+ }
56
+ })])).toBe(d`
57
+ test1 = 1
58
+ arr[test1].foo-bar
59
+ `);
60
+ });
61
+ it("renders basic member expression with keys", () => {
62
+ expect(toSourceText([_$createComponent(py.MemberExpression, {
63
+ get children() {
64
+ return [_$createComponent(py.MemberExpression.Part, {
65
+ id: "arr"
66
+ }), _$createComponent(py.MemberExpression.Part, {
67
+ keys: [1, 2]
68
+ }), _$createComponent(py.MemberExpression.Part, {
69
+ id: "foo-bar"
70
+ })];
71
+ }
72
+ })])).toBe(d`
73
+ arr[1, 2].foo-bar
74
+ `);
75
+ });
76
+ it("renders basic member expression with keys with references", () => {
77
+ const rk1 = refkey();
78
+ const rk2 = refkey();
79
+ expect(toSourceText([_$createComponent(py.StatementList, {
80
+ get children() {
81
+ return [_$createComponent(py.VariableDeclaration, {
82
+ name: "test1",
83
+ refkey: rk1,
84
+ initializer: 1
85
+ }), _$createComponent(py.VariableDeclaration, {
86
+ name: "test2",
87
+ refkey: rk2,
88
+ initializer: 2
89
+ }), _$createComponent(py.MemberExpression, {
90
+ get children() {
91
+ return [_$createComponent(py.MemberExpression.Part, {
92
+ id: "arr"
93
+ }), _$createComponent(py.MemberExpression.Part, {
94
+ keys: [rk1, rk2]
95
+ }), _$createComponent(py.MemberExpression.Part, {
96
+ id: "foo-bar"
97
+ })];
98
+ }
99
+ })];
100
+ }
101
+ })])).toBe(d`
102
+ test1 = 1
103
+ test2 = 2
104
+ arr[test1, test2].foo-bar
105
+ `);
106
+ });
107
+ it("renders basic member expression with slice - 1", () => {
108
+ expect(toSourceText([_$createComponent(py.MemberExpression, {
109
+ get children() {
110
+ return [_$createComponent(py.MemberExpression.Part, {
111
+ id: "arr"
112
+ }), _$createComponent(py.MemberExpression.Part, {
113
+ slice: {
114
+ start: 1,
115
+ stop: 3,
116
+ step: 2
117
+ }
118
+ }), _$createComponent(py.MemberExpression.Part, {
119
+ id: "foo-bar"
120
+ })];
121
+ }
122
+ })])).toBe(d`
123
+ arr[1:3:2].foo-bar
124
+ `);
125
+ });
126
+ it("renders basic member expression with slice - 1 with references", () => {
127
+ const rk1 = refkey();
128
+ const rk2 = refkey();
129
+ const rk3 = refkey();
130
+ expect(toSourceText([_$createComponent(py.StatementList, {
131
+ get children() {
132
+ return [_$createComponent(py.VariableDeclaration, {
133
+ name: "test1",
134
+ refkey: rk1,
135
+ initializer: 1
136
+ }), _$createComponent(py.VariableDeclaration, {
137
+ name: "test2",
138
+ refkey: rk2,
139
+ initializer: 3
140
+ }), _$createComponent(py.VariableDeclaration, {
141
+ name: "test3",
142
+ refkey: rk3,
143
+ initializer: 2
144
+ }), _$createComponent(py.MemberExpression, {
145
+ get children() {
146
+ return [_$createComponent(py.MemberExpression.Part, {
147
+ id: "arr"
148
+ }), _$createComponent(py.MemberExpression.Part, {
149
+ slice: {
150
+ start: rk1,
151
+ stop: rk2,
152
+ step: rk3
153
+ }
154
+ }), _$createComponent(py.MemberExpression.Part, {
155
+ id: "foo-bar"
156
+ })];
157
+ }
158
+ })];
159
+ }
160
+ })])).toBe(d`
161
+ test1 = 1
162
+ test2 = 3
163
+ test3 = 2
164
+ arr[test1:test2:test3].foo-bar
165
+ `);
166
+ });
167
+ it("renders basic member expression with slice - 2", () => {
168
+ expect(toSourceText([_$createComponent(py.MemberExpression, {
169
+ get children() {
170
+ return [_$createComponent(py.MemberExpression.Part, {
171
+ id: "arr"
172
+ }), _$createComponent(py.MemberExpression.Part, {
173
+ slice: {
174
+ stop: 3
175
+ }
176
+ }), _$createComponent(py.MemberExpression.Part, {
177
+ id: "foo-bar"
178
+ })];
179
+ }
180
+ })])).toBe(d`
181
+ arr[:3].foo-bar
182
+ `);
183
+ });
184
+ it("renders basic member expression with slice - 3", () => {
185
+ expect(toSourceText([_$createComponent(py.MemberExpression, {
186
+ get children() {
187
+ return [_$createComponent(py.MemberExpression.Part, {
188
+ id: "arr"
189
+ }), _$createComponent(py.MemberExpression.Part, {
190
+ slice: {
191
+ step: 2
192
+ }
193
+ }), _$createComponent(py.MemberExpression.Part, {
194
+ id: "foo-bar"
195
+ })];
196
+ }
197
+ })])).toBe(d`
198
+ arr[::2].foo-bar
199
+ `);
200
+ });
201
+ it("renders basic member expression with slice - 4", () => {
202
+ expect(toSourceText([_$createComponent(py.MemberExpression, {
203
+ get children() {
204
+ return [_$createComponent(py.MemberExpression.Part, {
205
+ id: "arr"
206
+ }), _$createComponent(py.MemberExpression.Part, {
207
+ slice: {
208
+ start: 1
209
+ }
210
+ }), _$createComponent(py.MemberExpression.Part, {
211
+ id: "foo-bar"
212
+ })];
213
+ }
214
+ })])).toBe(d`
215
+ arr[1:].foo-bar
216
+ `);
217
+ });
218
+ it("renders basic member expression with slice - 5", () => {
219
+ expect(toSourceText([_$createComponent(py.MemberExpression, {
220
+ get children() {
221
+ return [_$createComponent(py.MemberExpression.Part, {
222
+ id: "arr"
223
+ }), _$createComponent(py.MemberExpression.Part, {
224
+ slice: {
225
+ start: 1,
226
+ step: 2
227
+ }
228
+ }), _$createComponent(py.MemberExpression.Part, {
229
+ id: "foo-bar"
230
+ })];
231
+ }
232
+ })])).toBe(d`
233
+ arr[1::2].foo-bar
234
+ `);
235
+ });
236
+ it("renders basic member expression with an expression index - 1", () => {
237
+ const xRefkey = refkey();
238
+ expect(toSourceText([_$createComponent(py.StatementList, {
239
+ get children() {
240
+ return [_$createComponent(py.VariableDeclaration, {
241
+ name: "x",
242
+ initializer: 1,
243
+ refkey: xRefkey
244
+ }), _$createComponent(py.MemberExpression, {
245
+ get children() {
246
+ return [_$createComponent(py.MemberExpression.Part, {
247
+ id: "arr"
248
+ }), _$createComponent(py.MemberExpression.Part, {
249
+ key: code`${xRefkey} + 1`
250
+ }), _$createComponent(py.MemberExpression.Part, {
251
+ id: "foo-bar"
252
+ })];
253
+ }
254
+ })];
255
+ }
256
+ })])).toBe(d`
257
+ x = 1
258
+ arr[x + 1].foo-bar
259
+ `);
260
+ });
261
+ it("renders basic member expression with an expression index - 2", () => {
262
+ expect(toSourceText([_$createComponent(py.StatementList, {
263
+ get children() {
264
+ return _$createComponent(py.MemberExpression, {
265
+ get children() {
266
+ return [_$createComponent(py.MemberExpression.Part, {
267
+ id: "arr"
268
+ }), _$createComponent(py.MemberExpression.Part, {
269
+ key: code`"foo" + 1`
270
+ }), _$createComponent(py.MemberExpression.Part, {
271
+ id: "foo-bar"
272
+ })];
273
+ }
274
+ });
275
+ }
276
+ })])).toBe(d`
277
+ arr["foo" + 1].foo-bar
278
+ `);
279
+ });
280
+ it("throws an error for invalid identifiers with quotes", () => {
281
+ expect(() => toSourceText([_$createComponent(py.MemberExpression, {
282
+ get children() {
283
+ return [_$createComponent(py.MemberExpression.Part, {
284
+ id: "obj"
285
+ }), _$createComponent(py.MemberExpression.Part, {
286
+ id: `property-"name"`
287
+ })];
288
+ }
289
+ })])).toThrowError(/Invalid identifier: property-"name"/);
290
+ });
291
+ it("supports multiple levels of nesting", () => {
292
+ expect(toSourceText([_$createComponent(py.MemberExpression, {
293
+ get children() {
294
+ return [_$createComponent(py.MemberExpression.Part, {
295
+ id: "a"
296
+ }), _$createComponent(py.MemberExpression.Part, {
297
+ id: "b"
298
+ }), _$createComponent(py.MemberExpression.Part, {
299
+ id: "c"
300
+ }), _$createComponent(py.MemberExpression.Part, {
301
+ id: "d"
302
+ })];
303
+ }
304
+ })])).toBe(d`
305
+ a.b.c.d
306
+ `);
307
+ });
308
+ it("handles a mix of dot and bracket notation", () => {
309
+ expect(toSourceText([_$createComponent(py.MemberExpression, {
310
+ get children() {
311
+ return [_$createComponent(py.MemberExpression.Part, {
312
+ id: "obj"
313
+ }), _$createComponent(py.MemberExpression.Part, {
314
+ id: "normalProp"
315
+ }), _$createComponent(py.MemberExpression.Part, {
316
+ key: "special-prop"
317
+ }), _$createComponent(py.MemberExpression.Part, {
318
+ key: "123"
319
+ })];
320
+ }
321
+ })])).toBe(d`
322
+ obj.normalProp["special-prop"]["123"]
323
+ `);
324
+ });
325
+ it("throws an error when providing conflicting part props", () => {
326
+ expect(() => toSourceText([_$createComponent(py.MemberExpression, {
327
+ get children() {
328
+ return [_$createComponent(py.MemberExpression.Part, {
329
+ id: "obj"
330
+ }), _$createComponent(py.MemberExpression.Part, {
331
+ id: "property",
332
+ args: [1, 2]
333
+ })];
334
+ }
335
+ })])).toThrowError(`Only one of args, id can be used for a MemberExpression part at a time`);
336
+ });
337
+ it("throws an error when providing an empty slice", () => {
338
+ expect(() => toSourceText([_$createComponent(py.MemberExpression, {
339
+ get children() {
340
+ return [_$createComponent(py.MemberExpression.Part, {
341
+ id: "obj"
342
+ }), _$createComponent(py.MemberExpression.Part, {
343
+ slice: {}
344
+ })];
345
+ }
346
+ })])).toThrowError(`MemberExpression.Part: slice object cannot be empty`);
347
+ });
348
+ it("throws an error when providing an empty array", () => {
349
+ expect(() => toSourceText([_$createComponent(py.MemberExpression, {
350
+ get children() {
351
+ return [_$createComponent(py.MemberExpression.Part, {
352
+ id: "obj"
353
+ }), _$createComponent(py.MemberExpression.Part, {
354
+ keys: []
355
+ })];
356
+ }
357
+ })])).toThrowError(`MemberExpression.Part: keys array cannot be empty`);
358
+ });
359
+ it("takes children for the id part", () => {
360
+ expect(toSourceText([_$createComponent(py.StatementList, {
361
+ get children() {
362
+ return [_$createComponent(py.MemberExpression, {
363
+ get children() {
364
+ return [_$createComponent(py.MemberExpression.Part, {
365
+ id: "child1"
366
+ }), _$createComponent(py.MemberExpression.Part, {
367
+ key: "child1"
368
+ })];
369
+ }
370
+ }), _$createComponent(py.MemberExpression, {
371
+ get children() {
372
+ return [_$createComponent(py.MemberExpression.Part, {
373
+ id: "child1"
374
+ }), _$createComponent(py.MemberExpression.Part, {
375
+ key: "child2"
376
+ }), _$createComponent(py.MemberExpression.Part, {
377
+ args: true
378
+ }), _$createComponent(py.MemberExpression.Part, {
379
+ key: "child3"
380
+ }), _$createComponent(py.MemberExpression.Part, {
381
+ args: true
382
+ }), _$createComponent(py.MemberExpression.Part, {
383
+ key: code`"foo" + 1`
384
+ }), _$createComponent(py.MemberExpression.Part, {
385
+ args: true
386
+ })];
387
+ }
388
+ })];
389
+ }
390
+ })])).toBe(d`
391
+ child1["child1"]
392
+ child1["child2"]()["child3"]()["foo" + 1]()
393
+ `);
394
+ });
395
+ describe("with refkeys", () => {
396
+ it("handles symbols correctly", () => {
397
+ const rk1 = refkey();
398
+ const rk2 = refkey();
399
+ expect(toSourceText([_$createComponent(py.StatementList, {
400
+ get children() {
401
+ return [_$createComponent(py.VariableDeclaration, {
402
+ name: "test1",
403
+ refkey: rk1,
404
+ initializer: 1
405
+ }), _$createComponent(py.VariableDeclaration, {
406
+ name: "test1",
407
+ refkey: rk2,
408
+ initializer: 2
409
+ }), _$createComponent(py.MemberExpression, {
410
+ get children() {
411
+ return [_$createComponent(py.MemberExpression.Part, {
412
+ refkey: rk1
413
+ }), _$createComponent(py.MemberExpression.Part, {
414
+ refkey: rk2
415
+ })];
416
+ }
417
+ })];
418
+ }
419
+ })])).toBe(d`
420
+ test1 = 1
421
+ test1_2_test = 2
422
+ test1.test1_2_test
423
+ `);
424
+ });
425
+ it("Correctly resolves member expressions from 2 different classes", () => {
426
+ const model1Ref = refkey();
427
+ const model2Ref = refkey();
428
+ const classMethod1Ref = refkey();
429
+ const classMethod2Ref = refkey();
430
+ const v1Rk = refkey();
431
+ const v2Rk = refkey();
432
+ const template = _$createComponent(py.StatementList, {
433
+ get children() {
434
+ return [_$createComponent(ClassDeclaration, {
435
+ name: "Model1",
436
+ refkey: model1Ref,
437
+ get children() {
438
+ return _$createComponent(VariableDeclaration, {
439
+ name: "foo",
440
+ refkey: classMethod1Ref,
441
+ type: "str",
442
+ omitNone: true,
443
+ instanceVariable: true
444
+ });
445
+ }
446
+ }), _$createComponent(ClassDeclaration, {
447
+ name: "Model2",
448
+ refkey: model2Ref,
449
+ get children() {
450
+ return _$createComponent(VariableDeclaration, {
451
+ name: "bar",
452
+ refkey: classMethod2Ref,
453
+ type: "str",
454
+ omitNone: true,
455
+ instanceVariable: true
456
+ });
457
+ }
458
+ }), _$createComponent(py.VariableDeclaration, {
459
+ name: "model1_instance",
460
+ refkey: v1Rk,
461
+ type: model1Ref,
462
+ get initializer() {
463
+ return _$createComponent(py.MemberExpression, {
464
+ get children() {
465
+ return [_$createComponent(py.MemberExpression.Part, {
466
+ refkey: model1Ref
467
+ }), _$createComponent(py.MemberExpression.Part, {
468
+ args: true
469
+ })];
470
+ }
471
+ });
472
+ }
473
+ }), _$createComponent(py.VariableDeclaration, {
474
+ name: "model2_instance",
475
+ refkey: v2Rk,
476
+ type: model2Ref,
477
+ get initializer() {
478
+ return _$createComponent(py.MemberExpression, {
479
+ get children() {
480
+ return [_$createComponent(py.MemberExpression.Part, {
481
+ refkey: model2Ref
482
+ }), _$createComponent(py.MemberExpression.Part, {
483
+ args: true
484
+ })];
485
+ }
486
+ });
487
+ }
488
+ }), [_$memo(() => memberRefkey(v1Rk, classMethod1Ref))], [_$memo(() => memberRefkey(v2Rk, classMethod2Ref))]];
489
+ }
490
+ });
491
+ expect(toSourceText([template])).toBe(d`
492
+ class Model1:
493
+ foo: str
494
+
495
+ class Model2:
496
+ bar: str
497
+
498
+ model1_instance: Model1 = Model1()
499
+ model2_instance: Model2 = Model2()
500
+ model1_instance.foo
501
+ model2_instance.bar
502
+ `);
503
+ });
504
+ it("handles optional parameters correctly", () => {
505
+ const fooRef = refkey();
506
+ const modelRef = refkey();
507
+ const parameters = [{
508
+ name: "foo",
509
+ optional: true,
510
+ refkey: fooRef,
511
+ type: modelRef
512
+ }];
513
+ const messageRef = refkey();
514
+ const template = _$createComponent(py.StatementList, {
515
+ get children() {
516
+ return [_$createComponent(ClassDeclaration, {
517
+ name: "Model",
518
+ refkey: modelRef,
519
+ get children() {
520
+ return _$createComponent(VariableDeclaration, {
521
+ name: "bar",
522
+ get refkey() {
523
+ return refkey();
524
+ },
525
+ type: "str",
526
+ omitNone: true
527
+ });
528
+ }
529
+ }), _$createComponent(FunctionDeclaration, {
530
+ name: "fooFunction",
531
+ parameters: parameters,
532
+ get children() {
533
+ return _$createComponent(py.StatementList, {
534
+ get children() {
535
+ return [_$createComponent(py.VariableDeclaration, {
536
+ name: "message",
537
+ refkey: messageRef,
538
+ get initializer() {
539
+ return _$createComponent(py.MemberExpression, {
540
+ get children() {
541
+ return [_$createComponent(py.MemberExpression.Part, {
542
+ refkey: fooRef
543
+ }), _$createComponent(py.MemberExpression.Part, {
544
+ id: "bar"
545
+ })];
546
+ }
547
+ });
548
+ }
549
+ }), ["print(", messageRef, ")"]];
550
+ }
551
+ });
552
+ }
553
+ })];
554
+ }
555
+ });
556
+ expect(toSourceText([template])).toBe(d`
557
+ class Model:
558
+ bar: str
559
+
560
+ def foo_function(foo: Model = None):
561
+ message = foo.bar
562
+ print(message)
563
+
564
+ `);
565
+ });
566
+ it("handles class member correctly", () => {
567
+ const classRefkey = refkey();
568
+ const interfaceRefkey = refkey();
569
+ const interfaceMemberRefkey = refkey();
570
+ const classMethodRefkey = refkey();
571
+ const classMemberRefkey = refkey();
572
+ const instanceRefkey = refkey();
573
+ expect(toSourceText([_$createComponent(py.StatementList, {
574
+ get children() {
575
+ return [_$createComponent(ClassDeclaration, {
576
+ name: "Bar",
577
+ refkey: interfaceRefkey,
578
+ get children() {
579
+ return _$createComponent(VariableDeclaration, {
580
+ name: "prop1",
581
+ refkey: interfaceMemberRefkey,
582
+ type: "str",
583
+ omitNone: true
584
+ });
585
+ }
586
+ }), _$createComponent(ClassDeclaration, {
587
+ name: "Foo",
588
+ refkey: classRefkey,
589
+ get children() {
590
+ return [_$createComponent(VariableDeclaration, {
591
+ name: "test1",
592
+ refkey: classMemberRefkey,
593
+ type: interfaceRefkey
594
+ }), _$createIntrinsic("br", {}), _$createComponent(FunctionDeclaration, {
595
+ name: "testMethod",
596
+ parameters: [],
597
+ refkey: classMethodRefkey,
598
+ returnType: interfaceRefkey
599
+ })];
600
+ }
601
+ }), _$createComponent(py.VariableDeclaration, {
602
+ name: "inst",
603
+ refkey: instanceRefkey,
604
+ initializer: code`${classRefkey}()`
605
+ }), _$createComponent(py.MemberExpression, {
606
+ get children() {
607
+ return [_$createComponent(py.MemberExpression.Part, {
608
+ refkey: instanceRefkey
609
+ }), _$createComponent(py.MemberExpression.Part, {
610
+ refkey: classMemberRefkey
611
+ }), _$createComponent(py.MemberExpression.Part, {
612
+ refkey: interfaceMemberRefkey
613
+ })];
614
+ }
615
+ }), _$createComponent(py.MemberExpression, {
616
+ get children() {
617
+ return [_$createComponent(py.MemberExpression.Part, {
618
+ refkey: instanceRefkey
619
+ }), _$createComponent(py.MemberExpression.Part, {
620
+ refkey: classMethodRefkey
621
+ }), _$createComponent(py.MemberExpression.Part, {
622
+ args: []
623
+ })];
624
+ }
625
+ })];
626
+ }
627
+ })])).toBe(d`
628
+ class Bar:
629
+ prop1: str
630
+
631
+ class Foo:
632
+ test1: Bar = None
633
+ def test_method() -> Bar:
634
+ pass
635
+
636
+
637
+ inst = Foo()
638
+ inst.test1.prop1
639
+ inst.test_method()
640
+ `);
641
+ });
642
+ it("handles late resolved refkeys correctly", () => {
643
+ const rk1 = refkey();
644
+ const rk2 = refkey();
645
+ expect(toSourceText([_$createComponent(py.StatementList, {
646
+ get children() {
647
+ return [_$createComponent(py.MemberExpression, {
648
+ get children() {
649
+ return [_$createComponent(py.MemberExpression.Part, {
650
+ refkey: rk1
651
+ }), _$createComponent(py.MemberExpression.Part, {
652
+ refkey: rk2
653
+ })];
654
+ }
655
+ }), _$createComponent(py.VariableDeclaration, {
656
+ name: "test1",
657
+ refkey: rk1,
658
+ initializer: 1
659
+ }), _$createComponent(py.VariableDeclaration, {
660
+ name: "test1",
661
+ refkey: rk2,
662
+ initializer: 2
663
+ })];
664
+ }
665
+ })])).toBe(d`
666
+ test1.test1_2_test
667
+ test1 = 1
668
+ test1_2_test = 2
669
+ `);
670
+ });
671
+ it("creates a full reference to the first refkey", () => {
672
+ const rk1 = refkey();
673
+ const res = toSourceTextMultiple([_$createComponent(SourceFile, {
674
+ path: "source.py",
675
+ get children() {
676
+ return _$createComponent(py.VariableDeclaration, {
677
+ name: "importMe",
678
+ refkey: rk1
679
+ });
680
+ }
681
+ }), _$createComponent(SourceFile, {
682
+ path: "index.py",
683
+ get children() {
684
+ return _$createComponent(py.StatementList, {
685
+ get children() {
686
+ return _$createComponent(py.MemberExpression, {
687
+ get children() {
688
+ return [_$createComponent(py.MemberExpression.Part, {
689
+ refkey: rk1
690
+ }), _$createComponent(py.MemberExpression.Part, {
691
+ id: "foo"
692
+ })];
693
+ }
694
+ });
695
+ }
696
+ });
697
+ }
698
+ })]);
699
+ assertFileContents(res, {
700
+ "index.py": d`
701
+ from source import import_me
702
+
703
+ import_me.foo
704
+ `
705
+ });
706
+ });
707
+ });
708
+ describe("with function calls", () => {
709
+ it("handles simple function calls correctly", () => {
710
+ expect(toSourceText([_$createComponent(py.MemberExpression, {
711
+ get children() {
712
+ return [_$createComponent(py.MemberExpression.Part, {
713
+ id: "myFunction"
714
+ }), _$createComponent(py.MemberExpression.Part, {
715
+ args: [1, 2]
716
+ })];
717
+ }
718
+ })])).toBe(d`
719
+ myFunction(1, 2)
720
+ `);
721
+ });
722
+ it("handles function calls with references correctly", () => {
723
+ const xRefkey = refkey();
724
+ const yRefkey = refkey();
725
+ expect(toSourceText([_$createComponent(py.StatementList, {
726
+ get children() {
727
+ return [_$createComponent(py.VariableDeclaration, {
728
+ name: "x",
729
+ initializer: 1,
730
+ refkey: xRefkey
731
+ }), _$createComponent(py.VariableDeclaration, {
732
+ name: "y",
733
+ initializer: 2,
734
+ refkey: yRefkey
735
+ }), _$createComponent(py.MemberExpression, {
736
+ get children() {
737
+ return [_$createComponent(py.MemberExpression.Part, {
738
+ id: "myFunction"
739
+ }), _$createComponent(py.MemberExpression.Part, {
740
+ args: [xRefkey, yRefkey]
741
+ })];
742
+ }
743
+ })];
744
+ }
745
+ })])).toBe(d`
746
+ x = 1
747
+ y = 2
748
+ myFunction(x, y)
749
+ `);
750
+ });
751
+ it("handles method calls correctly", () => {
752
+ expect(toSourceText([_$createComponent(py.MemberExpression, {
753
+ get children() {
754
+ return [_$createComponent(py.MemberExpression.Part, {
755
+ id: "method1"
756
+ }), _$createComponent(py.MemberExpression.Part, {
757
+ args: [1, 2]
758
+ }), _$createComponent(py.MemberExpression.Part, {
759
+ args: []
760
+ }), _$createComponent(py.MemberExpression.Part, {
761
+ id: "method2"
762
+ }), _$createComponent(py.MemberExpression.Part, {
763
+ args: []
764
+ }), _$createComponent(py.MemberExpression.Part, {
765
+ id: "prop"
766
+ })];
767
+ }
768
+ })])).toBe(d`
769
+ method1(1, 2)().method2().prop
770
+ `);
771
+ });
772
+ it("handles function calls correctly", () => {
773
+ expect(toSourceText([_$createComponent(py.MemberExpression, {
774
+ get children() {
775
+ return [_$createComponent(py.MemberExpression.Part, {
776
+ id: "myFunction"
777
+ }), _$createComponent(py.MemberExpression.Part, {
778
+ args: [1, 2]
779
+ }), _$createComponent(py.MemberExpression.Part, {
780
+ id: "prop"
781
+ })];
782
+ }
783
+ })])).toBe(d`
784
+ myFunction(1, 2).prop
785
+ `);
786
+ });
787
+ it("handles function calls correctly", () => {
788
+ expect(toSourceText([_$createComponent(py.MemberExpression, {
789
+ get children() {
790
+ return [_$createComponent(py.MemberExpression.Part, {
791
+ id: "myFunction"
792
+ }), _$createComponent(py.MemberExpression.Part, {
793
+ args: [1, 2]
794
+ }), _$createComponent(py.MemberExpression.Part, {
795
+ id: "prop"
796
+ })];
797
+ }
798
+ })])).toBe(d`
799
+ myFunction(1, 2).prop
800
+ `);
801
+ });
802
+ });
803
+ describe("formatting", () => {
804
+ describe("simple chains", () => {
805
+ it("just dots", () => {
806
+ expect(toSourceText([_$createComponent(py.MemberExpression, {
807
+ get children() {
808
+ return [_$createComponent(py.MemberExpression.Part, {
809
+ id: "four"
810
+ }), _$createComponent(py.MemberExpression.Part, {
811
+ id: "four"
812
+ }), _$createComponent(py.MemberExpression.Part, {
813
+ id: "two"
814
+ }), _$createComponent(py.MemberExpression.Part, {
815
+ id: "two"
816
+ }), _$createComponent(py.MemberExpression.Part, {
817
+ id: "two"
818
+ }), _$createComponent(py.MemberExpression.Part, {
819
+ id: "two"
820
+ })];
821
+ }
822
+ })], {
823
+ printOptions: {
824
+ printWidth: 14
825
+ }
826
+ })).toBe(d`
827
+ four.four \\
828
+ .two.two \\
829
+ .two.two
830
+ `);
831
+ });
832
+ it("bracket breaks", () => {
833
+ expect(toSourceText([_$createComponent(py.MemberExpression, {
834
+ get children() {
835
+ return [_$createComponent(py.MemberExpression.Part, {
836
+ id: "obj"
837
+ }), _$createComponent(py.MemberExpression.Part, {
838
+ key: "property-name"
839
+ }), _$createComponent(py.MemberExpression.Part, {
840
+ id: "prop"
841
+ })];
842
+ }
843
+ })], {
844
+ printOptions: {
845
+ printWidth: 12
846
+ }
847
+ })).toBe(d`
848
+ obj[
849
+ "property-name"
850
+ ].prop
851
+ `);
852
+ });
853
+ });
854
+ describe("call chains", () => {
855
+ it("renders multiple calls on the same line when there are no breaks and they fit", () => {
856
+ expect(toSourceText([_$createComponent(py.MemberExpression, {
857
+ get children() {
858
+ return [_$createComponent(py.MemberExpression.Part, {
859
+ id: "z"
860
+ }), _$createComponent(py.MemberExpression.Part, {
861
+ id: "object"
862
+ }), _$createComponent(py.MemberExpression.Part, {
863
+ args: true
864
+ }), _$createComponent(py.MemberExpression.Part, {
865
+ id: "partial"
866
+ }), _$createComponent(py.MemberExpression.Part, {
867
+ args: true
868
+ }), _$createComponent(py.MemberExpression.Part, {
869
+ id: "optional"
870
+ }), _$createComponent(py.MemberExpression.Part, {
871
+ args: true
872
+ })];
873
+ }
874
+ })])).toBe(d`
875
+ z.object().partial().optional()
876
+ `);
877
+ });
878
+ });
879
+ });