@alloy-js/python 0.4.0-dev.2 → 0.4.0-dev.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dev/src/builtins/python.js +30 -0
- package/dist/dev/src/builtins/python.js.map +1 -0
- package/dist/dev/src/components/Atom.js +122 -0
- package/dist/dev/src/components/Atom.js.map +1 -0
- package/dist/dev/src/components/CallSignature.js +195 -0
- package/dist/dev/src/components/CallSignature.js.map +1 -0
- package/dist/dev/src/components/ClassDeclaration.js +112 -0
- package/dist/dev/src/components/ClassDeclaration.js.map +1 -0
- package/dist/dev/src/components/ClassInstantiation.js +40 -0
- package/dist/dev/src/components/ClassInstantiation.js.map +1 -0
- package/dist/dev/src/components/ClassMethodDeclaration.js +40 -0
- package/dist/dev/src/components/ClassMethodDeclaration.js.map +1 -0
- package/dist/dev/src/components/ConstructorDeclaration.js +39 -0
- package/dist/dev/src/components/ConstructorDeclaration.js.map +1 -0
- package/dist/dev/src/components/DataclassDeclaration.js +177 -0
- package/dist/dev/src/components/DataclassDeclaration.js.map +1 -0
- package/dist/dev/src/components/Declaration.js +31 -0
- package/dist/dev/src/components/Declaration.js.map +1 -0
- package/dist/dev/src/components/DunderMethodDeclaration.js +33 -0
- package/dist/dev/src/components/DunderMethodDeclaration.js.map +1 -0
- package/dist/dev/src/components/EnumDeclaration.js +259 -0
- package/dist/dev/src/components/EnumDeclaration.js.map +1 -0
- package/dist/dev/src/components/EnumMember.js +95 -0
- package/dist/dev/src/components/EnumMember.js.map +1 -0
- package/dist/dev/src/components/FunctionBase.js +130 -0
- package/dist/dev/src/components/FunctionBase.js.map +1 -0
- package/dist/dev/src/components/FunctionCallExpression.js +53 -0
- package/dist/dev/src/components/FunctionCallExpression.js.map +1 -0
- package/dist/dev/src/components/FunctionDeclaration.js +45 -0
- package/dist/dev/src/components/FunctionDeclaration.js.map +1 -0
- package/dist/dev/src/components/FutureStatement.js +31 -0
- package/dist/dev/src/components/FutureStatement.js.map +1 -0
- package/dist/dev/src/components/ImportStatement.js +167 -0
- package/dist/dev/src/components/ImportStatement.js.map +1 -0
- package/dist/dev/src/components/LexicalScope.js +26 -0
- package/dist/dev/src/components/LexicalScope.js.map +1 -0
- package/dist/dev/src/components/MemberExpression.js +290 -0
- package/dist/dev/src/components/MemberExpression.js.map +1 -0
- package/dist/dev/src/components/MemberScope.js +23 -0
- package/dist/dev/src/components/MemberScope.js.map +1 -0
- package/dist/dev/src/components/MethodBase.js +40 -0
- package/dist/dev/src/components/MethodBase.js.map +1 -0
- package/dist/dev/src/components/MethodDeclaration.js +38 -0
- package/dist/dev/src/components/MethodDeclaration.js.map +1 -0
- package/dist/dev/src/components/PropertyDeclaration.js +287 -0
- package/dist/dev/src/components/PropertyDeclaration.js.map +1 -0
- package/dist/dev/src/components/PyDoc.js +1478 -0
- package/dist/dev/src/components/PyDoc.js.map +1 -0
- package/dist/dev/src/components/PythonBlock.js +35 -0
- package/dist/dev/src/components/PythonBlock.js.map +1 -0
- package/dist/dev/src/components/Reference.js +23 -0
- package/dist/dev/src/components/Reference.js.map +1 -0
- package/dist/dev/src/components/SourceFile.js +385 -0
- package/dist/dev/src/components/SourceFile.js.map +1 -0
- package/dist/dev/src/components/StatementList.js +34 -0
- package/dist/dev/src/components/StatementList.js.map +1 -0
- package/dist/dev/src/components/StaticMethodDeclaration.js +40 -0
- package/dist/dev/src/components/StaticMethodDeclaration.js.map +1 -0
- package/dist/dev/src/components/TypeArguments.js +22 -0
- package/dist/dev/src/components/TypeArguments.js.map +1 -0
- package/dist/dev/src/components/TypeRefContext.js +33 -0
- package/dist/dev/src/components/TypeRefContext.js.map +1 -0
- package/dist/dev/src/components/TypeReference.js +67 -0
- package/dist/dev/src/components/TypeReference.js.map +1 -0
- package/dist/dev/src/components/UnionTypeExpression.js +57 -0
- package/dist/dev/src/components/UnionTypeExpression.js.map +1 -0
- package/dist/dev/src/components/VariableDeclaration.js +150 -0
- package/dist/dev/src/components/VariableDeclaration.js.map +1 -0
- package/dist/dev/src/components/index.js +32 -0
- package/dist/dev/src/components/index.js.map +1 -0
- package/dist/dev/src/context/index.js +2 -0
- package/dist/dev/src/context/index.js.map +1 -0
- package/dist/dev/src/context/type-ref-context.js +17 -0
- package/dist/dev/src/context/type-ref-context.js.map +1 -0
- package/dist/dev/src/create-module.js +64 -0
- package/dist/dev/src/create-module.js.map +1 -0
- package/dist/dev/src/index.js +8 -0
- package/dist/dev/src/index.js.map +1 -0
- package/dist/dev/src/name-conflict-resolver.js +8 -0
- package/dist/dev/src/name-conflict-resolver.js.map +1 -0
- package/dist/dev/src/name-policy.js +48 -0
- package/dist/dev/src/name-policy.js.map +1 -0
- package/dist/dev/src/parameter-descriptor.js +8 -0
- package/dist/dev/src/parameter-descriptor.js.map +1 -0
- package/dist/dev/src/symbol-creation.js +58 -0
- package/dist/dev/src/symbol-creation.js.map +1 -0
- package/dist/dev/src/symbols/factories.js +28 -0
- package/dist/dev/src/symbols/factories.js.map +1 -0
- package/dist/dev/src/symbols/index.js +8 -0
- package/dist/dev/src/symbols/index.js.map +1 -0
- package/dist/dev/src/symbols/python-lexical-scope.js +15 -0
- package/dist/dev/src/symbols/python-lexical-scope.js.map +1 -0
- package/dist/dev/src/symbols/python-member-scope.js +7 -0
- package/dist/dev/src/symbols/python-member-scope.js.map +1 -0
- package/dist/dev/src/symbols/python-module-scope.js +86 -0
- package/dist/dev/src/symbols/python-module-scope.js.map +1 -0
- package/dist/dev/src/symbols/python-output-symbol.js +73 -0
- package/dist/dev/src/symbols/python-output-symbol.js.map +1 -0
- package/dist/dev/src/symbols/reference.js +87 -0
- package/dist/dev/src/symbols/reference.js.map +1 -0
- package/dist/dev/src/symbols/scopes.js +13 -0
- package/dist/dev/src/symbols/scopes.js.map +1 -0
- package/dist/dev/src/utils.js +13 -0
- package/dist/dev/src/utils.js.map +1 -0
- package/dist/dev/test/callsignatures.test.js +482 -0
- package/dist/dev/test/callsignatures.test.js.map +1 -0
- package/dist/dev/test/class-method-declaration.test.js +85 -0
- package/dist/dev/test/class-method-declaration.test.js.map +1 -0
- package/dist/dev/test/classdeclarations.test.js +654 -0
- package/dist/dev/test/classdeclarations.test.js.map +1 -0
- package/dist/dev/test/classinstantiations.test.js +281 -0
- package/dist/dev/test/classinstantiations.test.js.map +1 -0
- package/dist/dev/test/constructordeclaration.test.js +86 -0
- package/dist/dev/test/constructordeclaration.test.js.map +1 -0
- package/dist/dev/test/dataclassdeclarations.test.js +1068 -0
- package/dist/dev/test/dataclassdeclarations.test.js.map +1 -0
- package/dist/dev/test/dundermethoddeclaration.test.js +93 -0
- package/dist/dev/test/dundermethoddeclaration.test.js.map +1 -0
- package/dist/dev/test/enums.test.js +263 -0
- package/dist/dev/test/enums.test.js.map +1 -0
- package/dist/dev/test/externals.test.js +307 -0
- package/dist/dev/test/externals.test.js.map +1 -0
- package/dist/dev/test/factories.test.js +122 -0
- package/dist/dev/test/factories.test.js.map +1 -0
- package/dist/dev/test/functioncallexpressions.test.js +257 -0
- package/dist/dev/test/functioncallexpressions.test.js.map +1 -0
- package/dist/dev/test/functiondeclaration.test.js +817 -0
- package/dist/dev/test/functiondeclaration.test.js.map +1 -0
- package/dist/dev/test/imports.test.js +372 -0
- package/dist/dev/test/imports.test.js.map +1 -0
- package/dist/dev/test/memberexpressions.test.js +1668 -0
- package/dist/dev/test/memberexpressions.test.js.map +1 -0
- package/dist/dev/test/methoddeclaration.test.js +344 -0
- package/dist/dev/test/methoddeclaration.test.js.map +1 -0
- package/dist/dev/test/namepolicies.test.js +154 -0
- package/dist/dev/test/namepolicies.test.js.map +1 -0
- package/dist/dev/test/propertydeclaration.test.js +354 -0
- package/dist/dev/test/propertydeclaration.test.js.map +1 -0
- package/dist/dev/test/pydocs.test.js +1675 -0
- package/dist/dev/test/pydocs.test.js.map +1 -0
- package/dist/dev/test/references.test.js +66 -0
- package/dist/dev/test/references.test.js.map +1 -0
- package/dist/dev/test/sourcefiles.test.js +1802 -0
- package/dist/dev/test/sourcefiles.test.js.map +1 -0
- package/dist/dev/test/staticmethoddeclaration.test.js +85 -0
- package/dist/dev/test/staticmethoddeclaration.test.js.map +1 -0
- package/dist/dev/test/type-checking-imports.test.js +617 -0
- package/dist/dev/test/type-checking-imports.test.js.map +1 -0
- package/dist/dev/test/typereference.test.js +79 -0
- package/dist/dev/test/typereference.test.js.map +1 -0
- package/dist/dev/test/uniontypeexpression.test.js +307 -0
- package/dist/dev/test/uniontypeexpression.test.js.map +1 -0
- package/dist/dev/test/utils.js +100 -0
- package/dist/dev/test/utils.js.map +1 -0
- package/dist/dev/test/values.test.js +182 -0
- package/dist/dev/test/values.test.js.map +1 -0
- package/dist/dev/test/variables.test.js +363 -0
- package/dist/dev/test/variables.test.js.map +1 -0
- package/dist/src/components/CallSignature.d.ts.map +1 -1
- package/dist/src/components/CallSignature.js +12 -3
- package/dist/src/components/CallSignature.js.map +1 -1
- package/dist/src/components/ImportStatement.d.ts +12 -0
- package/dist/src/components/ImportStatement.d.ts.map +1 -1
- package/dist/src/components/ImportStatement.js +47 -5
- package/dist/src/components/ImportStatement.js.map +1 -1
- package/dist/src/components/MemberExpression.d.ts +1 -1
- package/dist/src/components/MemberExpression.d.ts.map +1 -1
- package/dist/src/components/MemberExpression.js +98 -180
- package/dist/src/components/MemberExpression.js.map +1 -1
- package/dist/src/components/Reference.d.ts.map +1 -1
- package/dist/src/components/Reference.js +5 -1
- package/dist/src/components/Reference.js.map +1 -1
- package/dist/src/components/SourceFile.d.ts +1 -1
- package/dist/src/components/SourceFile.d.ts.map +1 -1
- package/dist/src/components/SourceFile.js +46 -7
- package/dist/src/components/SourceFile.js.map +1 -1
- package/dist/src/components/TypeRefContext.d.ts +26 -0
- package/dist/src/components/TypeRefContext.d.ts.map +1 -0
- package/dist/src/components/TypeRefContext.js +29 -0
- package/dist/src/components/TypeRefContext.js.map +1 -0
- package/dist/src/components/TypeReference.d.ts +5 -0
- package/dist/src/components/TypeReference.d.ts.map +1 -1
- package/dist/src/components/TypeReference.js +19 -9
- package/dist/src/components/TypeReference.js.map +1 -1
- package/dist/src/components/VariableDeclaration.d.ts.map +1 -1
- package/dist/src/components/VariableDeclaration.js +7 -2
- package/dist/src/components/VariableDeclaration.js.map +1 -1
- package/dist/src/components/index.d.ts +1 -1
- package/dist/src/components/index.d.ts.map +1 -1
- package/dist/src/components/index.js +1 -1
- package/dist/src/components/index.js.map +1 -1
- package/dist/src/context/index.d.ts +2 -0
- package/dist/src/context/index.d.ts.map +1 -0
- package/dist/src/context/index.js +2 -0
- package/dist/src/context/index.js.map +1 -0
- package/dist/src/context/type-ref-context.d.ts +13 -0
- package/dist/src/context/type-ref-context.d.ts.map +1 -0
- package/dist/src/context/type-ref-context.js +17 -0
- package/dist/src/context/type-ref-context.js.map +1 -0
- package/dist/src/symbols/python-module-scope.d.ts +13 -1
- package/dist/src/symbols/python-module-scope.d.ts.map +1 -1
- package/dist/src/symbols/python-module-scope.js +36 -2
- package/dist/src/symbols/python-module-scope.js.map +1 -1
- package/dist/src/symbols/python-output-symbol.d.ts +11 -0
- package/dist/src/symbols/python-output-symbol.d.ts.map +1 -1
- package/dist/src/symbols/python-output-symbol.js +26 -2
- package/dist/src/symbols/python-output-symbol.js.map +1 -1
- package/dist/src/symbols/reference.d.ts +8 -1
- package/dist/src/symbols/reference.d.ts.map +1 -1
- package/dist/src/symbols/reference.js +4 -2
- package/dist/src/symbols/reference.js.map +1 -1
- package/dist/test/dataclassdeclarations.test.js +5 -2
- package/dist/test/dataclassdeclarations.test.js.map +1 -1
- package/dist/test/externals.test.js +8 -2
- package/dist/test/externals.test.js.map +1 -1
- package/dist/test/functiondeclaration.test.js +6 -3
- package/dist/test/functiondeclaration.test.js.map +1 -1
- package/dist/test/imports.test.js +3 -3
- package/dist/test/imports.test.js.map +1 -1
- package/dist/test/references.test.js +1 -1
- package/dist/test/references.test.js.map +1 -1
- package/dist/test/sourcefiles.test.js +26 -26
- package/dist/test/sourcefiles.test.js.map +1 -1
- package/dist/test/type-checking-imports.test.d.ts +2 -0
- package/dist/test/type-checking-imports.test.d.ts.map +1 -0
- package/dist/test/type-checking-imports.test.js +437 -0
- package/dist/test/type-checking-imports.test.js.map +1 -0
- package/dist/test/uniontypeexpression.test.js +4 -1
- package/dist/test/uniontypeexpression.test.js.map +1 -1
- package/dist/test/variables.test.js +4 -1
- package/dist/test/variables.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -4
- package/src/components/CallSignature.tsx +6 -2
- package/src/components/ImportStatement.tsx +52 -5
- package/src/components/MemberExpression.tsx +174 -298
- package/src/components/Reference.tsx +3 -1
- package/src/components/SourceFile.tsx +44 -8
- package/src/components/TypeRefContext.tsx +36 -0
- package/src/components/TypeReference.tsx +15 -7
- package/src/components/VariableDeclaration.tsx +5 -1
- package/src/components/index.ts +1 -1
- package/src/context/index.ts +1 -0
- package/src/context/type-ref-context.tsx +16 -0
- package/src/symbols/python-module-scope.ts +55 -2
- package/src/symbols/python-output-symbol.ts +32 -1
- package/src/symbols/reference.tsx +10 -0
- package/temp/api.json +443 -338
- package/test/dataclassdeclarations.test.tsx +8 -2
- package/test/externals.test.tsx +8 -2
- package/test/functiondeclaration.test.tsx +6 -3
- package/test/imports.test.tsx +6 -6
- package/test/references.test.tsx +1 -1
- package/test/sourcefiles.test.tsx +13 -13
- package/test/type-checking-imports.test.tsx +363 -0
- package/test/uniontypeexpression.test.tsx +4 -1
- package/test/variables.test.tsx +4 -1
- package/vitest.config.ts +8 -0
|
@@ -0,0 +1,1675 @@
|
|
|
1
|
+
import { createComponent as _$createComponent } from "@alloy-js/core/jsx-runtime";
|
|
2
|
+
import { Prose } from "@alloy-js/core";
|
|
3
|
+
import { d } from "@alloy-js/core/testing";
|
|
4
|
+
import { describe, expect, it } from "vitest";
|
|
5
|
+
import { enumModule } from "../src/builtins/python.js";
|
|
6
|
+
import * as py from "../src/index.js";
|
|
7
|
+
import { assertFileContents, toSourceText, toSourceTextMultiple } from "./utils.js";
|
|
8
|
+
describe("PyDoc", () => {
|
|
9
|
+
it("formats properly", () => {
|
|
10
|
+
const res = toSourceText([_$createComponent(py.PyDoc, {
|
|
11
|
+
get children() {
|
|
12
|
+
return [_$createComponent(Prose, {
|
|
13
|
+
children: "This is an example of a long docstring that will be broken in lines. We will also render another paragraph after this one."
|
|
14
|
+
}, {
|
|
15
|
+
fileName: import.meta.url,
|
|
16
|
+
lineNumber: 17,
|
|
17
|
+
columnNumber: 11
|
|
18
|
+
}), _$createComponent(Prose, {
|
|
19
|
+
children: "This is another paragraph, and there's a line break before it."
|
|
20
|
+
}, {
|
|
21
|
+
fileName: import.meta.url,
|
|
22
|
+
lineNumber: 21,
|
|
23
|
+
columnNumber: 11
|
|
24
|
+
})];
|
|
25
|
+
}
|
|
26
|
+
}, {
|
|
27
|
+
fileName: import.meta.url,
|
|
28
|
+
lineNumber: 16,
|
|
29
|
+
columnNumber: 9
|
|
30
|
+
})], {
|
|
31
|
+
printOptions: {
|
|
32
|
+
printWidth: 40
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
expect(res).toRenderTo(d`
|
|
36
|
+
"""
|
|
37
|
+
This is an example of a long docstring
|
|
38
|
+
that will be broken in lines. We will
|
|
39
|
+
also render another paragraph after this
|
|
40
|
+
one.
|
|
41
|
+
|
|
42
|
+
This is another paragraph, and there's a
|
|
43
|
+
line break before it.
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
`);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
describe("PyDocExample", () => {
|
|
51
|
+
it("creates docstring with a code sample", () => {
|
|
52
|
+
const res = toSourceText([_$createComponent(py.PyDoc, {
|
|
53
|
+
get children() {
|
|
54
|
+
return [_$createComponent(Prose, {
|
|
55
|
+
children: "This is an example of a docstring with a code sample."
|
|
56
|
+
}, {
|
|
57
|
+
fileName: import.meta.url,
|
|
58
|
+
lineNumber: 52,
|
|
59
|
+
columnNumber: 11
|
|
60
|
+
}), _$createComponent(py.PyDocExample, {
|
|
61
|
+
children: "print(\"Hello world!\")"
|
|
62
|
+
}, {
|
|
63
|
+
fileName: import.meta.url,
|
|
64
|
+
lineNumber: 53,
|
|
65
|
+
columnNumber: 11
|
|
66
|
+
})];
|
|
67
|
+
}
|
|
68
|
+
}, {
|
|
69
|
+
fileName: import.meta.url,
|
|
70
|
+
lineNumber: 51,
|
|
71
|
+
columnNumber: 9
|
|
72
|
+
})], {
|
|
73
|
+
printOptions: {
|
|
74
|
+
printWidth: 40
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
expect(res).toRenderTo(d`
|
|
78
|
+
"""
|
|
79
|
+
This is an example of a docstring with a
|
|
80
|
+
code sample.
|
|
81
|
+
|
|
82
|
+
>> print("Hello world!")
|
|
83
|
+
"""
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
`);
|
|
87
|
+
});
|
|
88
|
+
it("creates docstring with more than one code sample", () => {
|
|
89
|
+
const res = toSourceText([_$createComponent(py.PyDoc, {
|
|
90
|
+
get children() {
|
|
91
|
+
return [_$createComponent(Prose, {
|
|
92
|
+
children: "This is an example of a docstring with a code sample."
|
|
93
|
+
}, {
|
|
94
|
+
fileName: import.meta.url,
|
|
95
|
+
lineNumber: 77,
|
|
96
|
+
columnNumber: 11
|
|
97
|
+
}), _$createComponent(py.PyDocExample, {
|
|
98
|
+
children: "print(\"Hello world!\")"
|
|
99
|
+
}, {
|
|
100
|
+
fileName: import.meta.url,
|
|
101
|
+
lineNumber: 78,
|
|
102
|
+
columnNumber: 11
|
|
103
|
+
}), _$createComponent(py.PyDocExample, {
|
|
104
|
+
children: "print(\"Hello world again!\")"
|
|
105
|
+
}, {
|
|
106
|
+
fileName: import.meta.url,
|
|
107
|
+
lineNumber: 79,
|
|
108
|
+
columnNumber: 11
|
|
109
|
+
})];
|
|
110
|
+
}
|
|
111
|
+
}, {
|
|
112
|
+
fileName: import.meta.url,
|
|
113
|
+
lineNumber: 76,
|
|
114
|
+
columnNumber: 9
|
|
115
|
+
})], {
|
|
116
|
+
printOptions: {
|
|
117
|
+
printWidth: 40
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
expect(res).toRenderTo(d`
|
|
121
|
+
"""
|
|
122
|
+
This is an example of a docstring with a
|
|
123
|
+
code sample.
|
|
124
|
+
|
|
125
|
+
>> print("Hello world!")
|
|
126
|
+
|
|
127
|
+
>> print("Hello world again!")
|
|
128
|
+
"""
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
`);
|
|
132
|
+
});
|
|
133
|
+
it("creates docstring with a multiline code sample", () => {
|
|
134
|
+
const res = toSourceText([_$createComponent(py.PyDoc, {
|
|
135
|
+
get children() {
|
|
136
|
+
return [_$createComponent(Prose, {
|
|
137
|
+
children: "This is an example of a docstring with a code sample."
|
|
138
|
+
}, {
|
|
139
|
+
fileName: import.meta.url,
|
|
140
|
+
lineNumber: 105,
|
|
141
|
+
columnNumber: 11
|
|
142
|
+
}), _$createComponent(py.PyDocExample, {
|
|
143
|
+
children: `print("Hello world!")\nx = "Hello"\nprint(x)`
|
|
144
|
+
}, {
|
|
145
|
+
fileName: import.meta.url,
|
|
146
|
+
lineNumber: 106,
|
|
147
|
+
columnNumber: 11
|
|
148
|
+
})];
|
|
149
|
+
}
|
|
150
|
+
}, {
|
|
151
|
+
fileName: import.meta.url,
|
|
152
|
+
lineNumber: 104,
|
|
153
|
+
columnNumber: 9
|
|
154
|
+
})], {
|
|
155
|
+
printOptions: {
|
|
156
|
+
printWidth: 40
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
expect(res).toRenderTo(d`
|
|
160
|
+
"""
|
|
161
|
+
This is an example of a docstring with a
|
|
162
|
+
code sample.
|
|
163
|
+
|
|
164
|
+
>> print("Hello world!")
|
|
165
|
+
>> x = "Hello"
|
|
166
|
+
>> print(x)
|
|
167
|
+
"""
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
`);
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
describe("SimpleCommentBlock", () => {
|
|
174
|
+
it("renders simple comment block", () => {
|
|
175
|
+
const res = toSourceText([_$createComponent(py.SimpleCommentBlock, {
|
|
176
|
+
children: "This is a simple comment block that spans multiple lines and should be split automatically."
|
|
177
|
+
}, {
|
|
178
|
+
fileName: import.meta.url,
|
|
179
|
+
lineNumber: 134,
|
|
180
|
+
columnNumber: 7
|
|
181
|
+
})]);
|
|
182
|
+
expect(res).toRenderTo(d`
|
|
183
|
+
# This is a simple comment block that spans multiple lines and should be split
|
|
184
|
+
# automatically.
|
|
185
|
+
|
|
186
|
+
`);
|
|
187
|
+
});
|
|
188
|
+
it("renders comment block with line breaks", () => {
|
|
189
|
+
const res = toSourceText([_$createComponent(py.SimpleCommentBlock, {
|
|
190
|
+
children: "First line of comment.\\nSecond line of comment."
|
|
191
|
+
}, {
|
|
192
|
+
fileName: import.meta.url,
|
|
193
|
+
lineNumber: 150,
|
|
194
|
+
columnNumber: 7
|
|
195
|
+
})]);
|
|
196
|
+
expect(res).toRenderTo(d`
|
|
197
|
+
# First line of comment.
|
|
198
|
+
# Second line of comment.
|
|
199
|
+
|
|
200
|
+
`);
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
describe("SimpleInlineComment", () => {
|
|
204
|
+
it("renders inline comment", () => {
|
|
205
|
+
const res = toSourceText([["x = 42", _$createComponent(py.SimpleInlineComment, {
|
|
206
|
+
children: "This is an inline comment"
|
|
207
|
+
}, {
|
|
208
|
+
fileName: import.meta.url,
|
|
209
|
+
lineNumber: 169,
|
|
210
|
+
columnNumber: 9
|
|
211
|
+
})]]);
|
|
212
|
+
expect(res).toRenderTo(d`
|
|
213
|
+
x = 42 # This is an inline comment
|
|
214
|
+
`);
|
|
215
|
+
});
|
|
216
|
+
it("renders inline comment with complex text", () => {
|
|
217
|
+
const res = toSourceText([["result = calculate()", _$createComponent(py.SimpleInlineComment, {
|
|
218
|
+
children: "TODO: Add error handling here"
|
|
219
|
+
}, {
|
|
220
|
+
fileName: import.meta.url,
|
|
221
|
+
lineNumber: 185,
|
|
222
|
+
columnNumber: 9
|
|
223
|
+
})]]);
|
|
224
|
+
expect(res).toRenderTo(d`
|
|
225
|
+
result = calculate() # TODO: Add error handling here
|
|
226
|
+
`);
|
|
227
|
+
});
|
|
228
|
+
});
|
|
229
|
+
describe("New Documentation Components", () => {
|
|
230
|
+
it("ModuleDoc renders correctly", () => {
|
|
231
|
+
const res = toSourceText([_$createComponent(py.ModuleDoc, {
|
|
232
|
+
get description() {
|
|
233
|
+
return [_$createComponent(Prose, {
|
|
234
|
+
children: "This module demonstrates documentation as specified by the Google Python Style Guide."
|
|
235
|
+
}, {
|
|
236
|
+
fileName: import.meta.url,
|
|
237
|
+
lineNumber: 203,
|
|
238
|
+
columnNumber: 11
|
|
239
|
+
})];
|
|
240
|
+
},
|
|
241
|
+
attributes: [{
|
|
242
|
+
name: "module_level_variable1",
|
|
243
|
+
type: "int",
|
|
244
|
+
children: "Module level variables may be documented."
|
|
245
|
+
}],
|
|
246
|
+
get examples() {
|
|
247
|
+
return [_$createComponent(py.PyDocExample, {
|
|
248
|
+
children: "print(\"mod\")"
|
|
249
|
+
}, {
|
|
250
|
+
fileName: import.meta.url,
|
|
251
|
+
lineNumber: 215,
|
|
252
|
+
columnNumber: 20
|
|
253
|
+
})];
|
|
254
|
+
},
|
|
255
|
+
seeAlso: ["another_module.func", "RelatedClass"],
|
|
256
|
+
warning: "Internal API.",
|
|
257
|
+
deprecated: "Use new_module instead.",
|
|
258
|
+
todo: ["For module TODOs", "You have to also use sphinx.ext.todo extension"]
|
|
259
|
+
}, {
|
|
260
|
+
fileName: import.meta.url,
|
|
261
|
+
lineNumber: 201,
|
|
262
|
+
columnNumber: 7
|
|
263
|
+
})]);
|
|
264
|
+
expect(res).toRenderTo(d`
|
|
265
|
+
"""
|
|
266
|
+
This module demonstrates documentation as specified by the Google Python Style
|
|
267
|
+
Guide.
|
|
268
|
+
|
|
269
|
+
Attributes:
|
|
270
|
+
module_level_variable1 (int): Module level variables may be documented.
|
|
271
|
+
|
|
272
|
+
Examples:
|
|
273
|
+
>> print("mod")
|
|
274
|
+
|
|
275
|
+
See Also:
|
|
276
|
+
another_module.func
|
|
277
|
+
RelatedClass
|
|
278
|
+
|
|
279
|
+
Warning:
|
|
280
|
+
Internal API.
|
|
281
|
+
|
|
282
|
+
Deprecated:
|
|
283
|
+
Use new_module instead.
|
|
284
|
+
|
|
285
|
+
Todo:
|
|
286
|
+
* For module TODOs
|
|
287
|
+
* You have to also use sphinx.ext.todo extension
|
|
288
|
+
"""
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
`);
|
|
292
|
+
});
|
|
293
|
+
it("PropertyDoc renders correctly", () => {
|
|
294
|
+
const res = toSourceText([_$createComponent(py.PropertyDoc, {
|
|
295
|
+
get description() {
|
|
296
|
+
return [_$createComponent(Prose, {
|
|
297
|
+
children: "Properties should be documented in their getter method."
|
|
298
|
+
}, {
|
|
299
|
+
fileName: import.meta.url,
|
|
300
|
+
lineNumber: 262,
|
|
301
|
+
columnNumber: 11
|
|
302
|
+
})];
|
|
303
|
+
},
|
|
304
|
+
returns: "str: The readonly property value.",
|
|
305
|
+
get examples() {
|
|
306
|
+
return [_$createComponent(py.PyDocExample, {
|
|
307
|
+
children: "print(obj.name)"
|
|
308
|
+
}, {
|
|
309
|
+
fileName: import.meta.url,
|
|
310
|
+
lineNumber: 267,
|
|
311
|
+
columnNumber: 20
|
|
312
|
+
})];
|
|
313
|
+
},
|
|
314
|
+
seeAlso: ["other_property"],
|
|
315
|
+
warning: "Access may be slow.",
|
|
316
|
+
deprecated: "Use full_name instead.",
|
|
317
|
+
note: "If the setter method contains notable behavior, it should be mentioned here."
|
|
318
|
+
}, {
|
|
319
|
+
fileName: import.meta.url,
|
|
320
|
+
lineNumber: 260,
|
|
321
|
+
columnNumber: 7
|
|
322
|
+
})]);
|
|
323
|
+
expect(res).toRenderTo(d`
|
|
324
|
+
"""
|
|
325
|
+
Properties should be documented in their getter method.
|
|
326
|
+
|
|
327
|
+
Returns:
|
|
328
|
+
str: The readonly property value.
|
|
329
|
+
|
|
330
|
+
Examples:
|
|
331
|
+
>> print(obj.name)
|
|
332
|
+
|
|
333
|
+
See Also:
|
|
334
|
+
other_property
|
|
335
|
+
|
|
336
|
+
Warning:
|
|
337
|
+
Access may be slow.
|
|
338
|
+
|
|
339
|
+
Deprecated:
|
|
340
|
+
Use full_name instead.
|
|
341
|
+
|
|
342
|
+
Note:
|
|
343
|
+
If the setter method contains notable behavior, it should be mentioned here.
|
|
344
|
+
"""
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
`);
|
|
348
|
+
});
|
|
349
|
+
it("GeneratorDoc renders correctly", () => {
|
|
350
|
+
const res = toSourceText([_$createComponent(py.GeneratorDoc, {
|
|
351
|
+
get description() {
|
|
352
|
+
return [_$createComponent(Prose, {
|
|
353
|
+
children: "Generators have a Yields section instead of a Returns section."
|
|
354
|
+
}, {
|
|
355
|
+
fileName: import.meta.url,
|
|
356
|
+
lineNumber: 308,
|
|
357
|
+
columnNumber: 11
|
|
358
|
+
})];
|
|
359
|
+
},
|
|
360
|
+
parameters: [{
|
|
361
|
+
name: "n",
|
|
362
|
+
type: "int",
|
|
363
|
+
doc: "The upper limit of the range to generate, from 0 to n - 1."
|
|
364
|
+
}],
|
|
365
|
+
yields: "int: The next number in the range of 0 to n - 1.",
|
|
366
|
+
get examples() {
|
|
367
|
+
return [_$createComponent(py.PyDocExample, {
|
|
368
|
+
children: "print(next(gen))"
|
|
369
|
+
}, {
|
|
370
|
+
fileName: import.meta.url,
|
|
371
|
+
lineNumber: 320,
|
|
372
|
+
columnNumber: 20
|
|
373
|
+
})];
|
|
374
|
+
},
|
|
375
|
+
seeAlso: ["make_generator"],
|
|
376
|
+
warning: "Do not consume in tight loops without sleep.",
|
|
377
|
+
deprecated: "Use new_generator instead.",
|
|
378
|
+
note: "Examples should be written in doctest format."
|
|
379
|
+
}, {
|
|
380
|
+
fileName: import.meta.url,
|
|
381
|
+
lineNumber: 306,
|
|
382
|
+
columnNumber: 7
|
|
383
|
+
})]);
|
|
384
|
+
expect(res).toRenderTo(d`
|
|
385
|
+
"""
|
|
386
|
+
Generators have a Yields section instead of a Returns section.
|
|
387
|
+
|
|
388
|
+
Args:
|
|
389
|
+
n (int): The upper limit of the range to generate, from 0 to n - 1.
|
|
390
|
+
|
|
391
|
+
Yields:
|
|
392
|
+
int: The next number in the range of 0 to n - 1.
|
|
393
|
+
|
|
394
|
+
Examples:
|
|
395
|
+
>> print(next(gen))
|
|
396
|
+
|
|
397
|
+
See Also:
|
|
398
|
+
make_generator
|
|
399
|
+
|
|
400
|
+
Warning:
|
|
401
|
+
Do not consume in tight loops without sleep.
|
|
402
|
+
|
|
403
|
+
Deprecated:
|
|
404
|
+
Use new_generator instead.
|
|
405
|
+
|
|
406
|
+
Note:
|
|
407
|
+
Examples should be written in doctest format.
|
|
408
|
+
"""
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
`);
|
|
412
|
+
});
|
|
413
|
+
it("ExceptionDoc renders correctly", () => {
|
|
414
|
+
const res = toSourceText([_$createComponent(py.ExceptionDoc, {
|
|
415
|
+
get description() {
|
|
416
|
+
return [_$createComponent(Prose, {
|
|
417
|
+
children: "Exceptions are documented in the same way as classes."
|
|
418
|
+
}, {
|
|
419
|
+
fileName: import.meta.url,
|
|
420
|
+
lineNumber: 364,
|
|
421
|
+
columnNumber: 11
|
|
422
|
+
})];
|
|
423
|
+
},
|
|
424
|
+
parameters: [{
|
|
425
|
+
name: "msg",
|
|
426
|
+
type: "str",
|
|
427
|
+
doc: "Human readable string describing the exception."
|
|
428
|
+
}, {
|
|
429
|
+
name: "code",
|
|
430
|
+
type: "int",
|
|
431
|
+
default: undefined,
|
|
432
|
+
doc: "Error code."
|
|
433
|
+
}],
|
|
434
|
+
attributes: [{
|
|
435
|
+
name: "msg",
|
|
436
|
+
type: "str",
|
|
437
|
+
children: "Human readable string describing the exception."
|
|
438
|
+
}, {
|
|
439
|
+
name: "code",
|
|
440
|
+
type: "int",
|
|
441
|
+
children: "Exception error code."
|
|
442
|
+
}],
|
|
443
|
+
seeAlso: ["BaseException"],
|
|
444
|
+
deprecated: "Use NewException instead.",
|
|
445
|
+
note: "Do not include the 'self' parameter in the Args section."
|
|
446
|
+
}, {
|
|
447
|
+
fileName: import.meta.url,
|
|
448
|
+
lineNumber: 362,
|
|
449
|
+
columnNumber: 7
|
|
450
|
+
})]);
|
|
451
|
+
expect(res).toRenderTo(d`
|
|
452
|
+
"""
|
|
453
|
+
Exceptions are documented in the same way as classes.
|
|
454
|
+
|
|
455
|
+
Args:
|
|
456
|
+
msg (str): Human readable string describing the exception.
|
|
457
|
+
|
|
458
|
+
code (int): Error code.
|
|
459
|
+
|
|
460
|
+
Attributes:
|
|
461
|
+
msg (str): Human readable string describing the exception.
|
|
462
|
+
|
|
463
|
+
code (int): Exception error code.
|
|
464
|
+
|
|
465
|
+
See Also:
|
|
466
|
+
BaseException
|
|
467
|
+
|
|
468
|
+
Deprecated:
|
|
469
|
+
Use NewException instead.
|
|
470
|
+
|
|
471
|
+
Note:
|
|
472
|
+
Do not include the 'self' parameter in the Args section.
|
|
473
|
+
"""
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
`);
|
|
477
|
+
});
|
|
478
|
+
it("MethodDoc renders correctly without default note", () => {
|
|
479
|
+
const res = toSourceText([_$createComponent(py.MethodDoc, {
|
|
480
|
+
get description() {
|
|
481
|
+
return [_$createComponent(Prose, {
|
|
482
|
+
children: "Class methods are similar to regular functions."
|
|
483
|
+
}, {
|
|
484
|
+
fileName: import.meta.url,
|
|
485
|
+
lineNumber: 431,
|
|
486
|
+
columnNumber: 11
|
|
487
|
+
})];
|
|
488
|
+
},
|
|
489
|
+
parameters: [{
|
|
490
|
+
name: "param1",
|
|
491
|
+
doc: "The first parameter."
|
|
492
|
+
}, {
|
|
493
|
+
name: "param2",
|
|
494
|
+
doc: "The second parameter."
|
|
495
|
+
}],
|
|
496
|
+
returns: "True if successful, False otherwise.",
|
|
497
|
+
overrides: "Base.method"
|
|
498
|
+
}, {
|
|
499
|
+
fileName: import.meta.url,
|
|
500
|
+
lineNumber: 429,
|
|
501
|
+
columnNumber: 7
|
|
502
|
+
})]);
|
|
503
|
+
expect(res).toRenderTo(d`
|
|
504
|
+
"""
|
|
505
|
+
Class methods are similar to regular functions.
|
|
506
|
+
|
|
507
|
+
Args:
|
|
508
|
+
param1: The first parameter.
|
|
509
|
+
|
|
510
|
+
param2: The second parameter.
|
|
511
|
+
|
|
512
|
+
Returns:
|
|
513
|
+
True if successful, False otherwise.
|
|
514
|
+
|
|
515
|
+
Overrides:
|
|
516
|
+
Base.method
|
|
517
|
+
"""
|
|
518
|
+
|
|
519
|
+
|
|
520
|
+
`);
|
|
521
|
+
});
|
|
522
|
+
it("MethodDoc renders correctly with custom note", () => {
|
|
523
|
+
const res = toSourceText([_$createComponent(py.MethodDoc, {
|
|
524
|
+
get description() {
|
|
525
|
+
return [_$createComponent(Prose, {
|
|
526
|
+
children: "Class methods are similar to regular functions."
|
|
527
|
+
}, {
|
|
528
|
+
fileName: import.meta.url,
|
|
529
|
+
lineNumber: 474,
|
|
530
|
+
columnNumber: 11
|
|
531
|
+
})];
|
|
532
|
+
},
|
|
533
|
+
parameters: [{
|
|
534
|
+
name: "param1",
|
|
535
|
+
doc: "The first parameter."
|
|
536
|
+
}],
|
|
537
|
+
returns: "True if successful, False otherwise.",
|
|
538
|
+
note: "This method has special behavior when called multiple times."
|
|
539
|
+
}, {
|
|
540
|
+
fileName: import.meta.url,
|
|
541
|
+
lineNumber: 472,
|
|
542
|
+
columnNumber: 7
|
|
543
|
+
})]);
|
|
544
|
+
expect(res).toRenderTo(d`
|
|
545
|
+
"""
|
|
546
|
+
Class methods are similar to regular functions.
|
|
547
|
+
|
|
548
|
+
Args:
|
|
549
|
+
param1: The first parameter.
|
|
550
|
+
|
|
551
|
+
Returns:
|
|
552
|
+
True if successful, False otherwise.
|
|
553
|
+
|
|
554
|
+
Note:
|
|
555
|
+
This method has special behavior when called multiple times.
|
|
556
|
+
"""
|
|
557
|
+
|
|
558
|
+
|
|
559
|
+
`);
|
|
560
|
+
});
|
|
561
|
+
it("ModuleDoc with minimal content", () => {
|
|
562
|
+
const res = toSourceText([_$createComponent(py.ModuleDoc, {
|
|
563
|
+
get description() {
|
|
564
|
+
return [_$createComponent(Prose, {
|
|
565
|
+
children: "Simple module description."
|
|
566
|
+
}, {
|
|
567
|
+
fileName: import.meta.url,
|
|
568
|
+
lineNumber: 510,
|
|
569
|
+
columnNumber: 23
|
|
570
|
+
})];
|
|
571
|
+
}
|
|
572
|
+
}, {
|
|
573
|
+
fileName: import.meta.url,
|
|
574
|
+
lineNumber: 509,
|
|
575
|
+
columnNumber: 7
|
|
576
|
+
})]);
|
|
577
|
+
expect(res).toRenderTo(d`
|
|
578
|
+
"""
|
|
579
|
+
Simple module description.
|
|
580
|
+
"""
|
|
581
|
+
|
|
582
|
+
|
|
583
|
+
`);
|
|
584
|
+
});
|
|
585
|
+
it("ModuleDoc with only todo items", () => {
|
|
586
|
+
const res = toSourceText([_$createComponent(py.ModuleDoc, {
|
|
587
|
+
get description() {
|
|
588
|
+
return [_$createComponent(Prose, {
|
|
589
|
+
children: "Module with pending tasks."
|
|
590
|
+
}, {
|
|
591
|
+
fileName: import.meta.url,
|
|
592
|
+
lineNumber: 528,
|
|
593
|
+
columnNumber: 23
|
|
594
|
+
})];
|
|
595
|
+
},
|
|
596
|
+
todo: ["Implement feature X", "Add more tests", "Update documentation"]
|
|
597
|
+
}, {
|
|
598
|
+
fileName: import.meta.url,
|
|
599
|
+
lineNumber: 527,
|
|
600
|
+
columnNumber: 7
|
|
601
|
+
})]);
|
|
602
|
+
expect(res).toRenderTo(d`
|
|
603
|
+
"""
|
|
604
|
+
Module with pending tasks.
|
|
605
|
+
|
|
606
|
+
Todo:
|
|
607
|
+
* Implement feature X
|
|
608
|
+
* Add more tests
|
|
609
|
+
* Update documentation
|
|
610
|
+
"""
|
|
611
|
+
|
|
612
|
+
|
|
613
|
+
`);
|
|
614
|
+
});
|
|
615
|
+
it("PropertyDoc minimal (description only)", () => {
|
|
616
|
+
const res = toSourceText([_$createComponent(py.PropertyDoc, {
|
|
617
|
+
get description() {
|
|
618
|
+
return [_$createComponent(Prose, {
|
|
619
|
+
children: "A simple readonly property."
|
|
620
|
+
}, {
|
|
621
|
+
fileName: import.meta.url,
|
|
622
|
+
lineNumber: 552,
|
|
623
|
+
columnNumber: 23
|
|
624
|
+
})];
|
|
625
|
+
}
|
|
626
|
+
}, {
|
|
627
|
+
fileName: import.meta.url,
|
|
628
|
+
lineNumber: 551,
|
|
629
|
+
columnNumber: 7
|
|
630
|
+
})]);
|
|
631
|
+
expect(res).toRenderTo(d`
|
|
632
|
+
"""
|
|
633
|
+
A simple readonly property.
|
|
634
|
+
"""
|
|
635
|
+
|
|
636
|
+
|
|
637
|
+
`);
|
|
638
|
+
});
|
|
639
|
+
it("PropertyDoc with getter and setter info", () => {
|
|
640
|
+
const res = toSourceText([_$createComponent(py.PropertyDoc, {
|
|
641
|
+
get description() {
|
|
642
|
+
return [_$createComponent(Prose, {
|
|
643
|
+
children: "Properties with both a getter and setter should only be documented in their getter method."
|
|
644
|
+
}, {
|
|
645
|
+
fileName: import.meta.url,
|
|
646
|
+
lineNumber: 571,
|
|
647
|
+
columnNumber: 11
|
|
648
|
+
})];
|
|
649
|
+
},
|
|
650
|
+
returns: ":obj:`list` of :obj:`str`: The property value.",
|
|
651
|
+
note: "If the setter method contains notable behavior, it should be mentioned here."
|
|
652
|
+
}, {
|
|
653
|
+
fileName: import.meta.url,
|
|
654
|
+
lineNumber: 569,
|
|
655
|
+
columnNumber: 7
|
|
656
|
+
})]);
|
|
657
|
+
expect(res).toRenderTo(d`
|
|
658
|
+
"""
|
|
659
|
+
Properties with both a getter and setter should only be documented in their
|
|
660
|
+
getter method.
|
|
661
|
+
|
|
662
|
+
Returns:
|
|
663
|
+
:obj:\`list\` of :obj:\`str\`: The property value.
|
|
664
|
+
|
|
665
|
+
Note:
|
|
666
|
+
If the setter method contains notable behavior, it should be mentioned here.
|
|
667
|
+
"""
|
|
668
|
+
|
|
669
|
+
|
|
670
|
+
`);
|
|
671
|
+
});
|
|
672
|
+
it("GeneratorDoc with complex parameters", () => {
|
|
673
|
+
const res = toSourceText([_$createComponent(py.GeneratorDoc, {
|
|
674
|
+
get description() {
|
|
675
|
+
return [_$createComponent(Prose, {
|
|
676
|
+
children: "A more complex generator example with multiple parameters."
|
|
677
|
+
}, {
|
|
678
|
+
fileName: import.meta.url,
|
|
679
|
+
lineNumber: 603,
|
|
680
|
+
columnNumber: 11
|
|
681
|
+
})];
|
|
682
|
+
},
|
|
683
|
+
parameters: [{
|
|
684
|
+
name: "start",
|
|
685
|
+
type: "int",
|
|
686
|
+
default: "0",
|
|
687
|
+
doc: "Starting value for the sequence."
|
|
688
|
+
}, {
|
|
689
|
+
name: "stop",
|
|
690
|
+
type: "int",
|
|
691
|
+
doc: "Ending value for the sequence (exclusive)."
|
|
692
|
+
}, {
|
|
693
|
+
name: "step",
|
|
694
|
+
type: "int",
|
|
695
|
+
default: "1",
|
|
696
|
+
doc: "Step size between values."
|
|
697
|
+
}],
|
|
698
|
+
yields: "int: The next number in the sequence.",
|
|
699
|
+
raises: ["ValueError: If step is zero.", "TypeError: If parameters are not integers."]
|
|
700
|
+
}, {
|
|
701
|
+
fileName: import.meta.url,
|
|
702
|
+
lineNumber: 601,
|
|
703
|
+
columnNumber: 7
|
|
704
|
+
})]);
|
|
705
|
+
expect(res).toRenderTo(d`
|
|
706
|
+
"""
|
|
707
|
+
A more complex generator example with multiple parameters.
|
|
708
|
+
|
|
709
|
+
Args:
|
|
710
|
+
start (int, optional): Starting value for the sequence. Defaults to "0".
|
|
711
|
+
|
|
712
|
+
stop (int): Ending value for the sequence (exclusive).
|
|
713
|
+
|
|
714
|
+
step (int, optional): Step size between values. Defaults to "1".
|
|
715
|
+
|
|
716
|
+
Yields:
|
|
717
|
+
int: The next number in the sequence.
|
|
718
|
+
|
|
719
|
+
Raises:
|
|
720
|
+
ValueError: If step is zero.
|
|
721
|
+
|
|
722
|
+
Raises:
|
|
723
|
+
TypeError: If parameters are not integers.
|
|
724
|
+
"""
|
|
725
|
+
|
|
726
|
+
|
|
727
|
+
`);
|
|
728
|
+
});
|
|
729
|
+
it("ExceptionDoc with comprehensive documentation", () => {
|
|
730
|
+
const res = toSourceText([_$createComponent(py.ExceptionDoc, {
|
|
731
|
+
get description() {
|
|
732
|
+
return [_$createComponent(Prose, {
|
|
733
|
+
children: "A custom exception for authentication failures."
|
|
734
|
+
}, {
|
|
735
|
+
fileName: import.meta.url,
|
|
736
|
+
lineNumber: 665,
|
|
737
|
+
columnNumber: 11
|
|
738
|
+
}), _$createComponent(Prose, {
|
|
739
|
+
children: "This exception is raised when authentication credentials are invalid or when authentication tokens have expired."
|
|
740
|
+
}, {
|
|
741
|
+
fileName: import.meta.url,
|
|
742
|
+
lineNumber: 666,
|
|
743
|
+
columnNumber: 11
|
|
744
|
+
})];
|
|
745
|
+
},
|
|
746
|
+
parameters: [{
|
|
747
|
+
name: "message",
|
|
748
|
+
type: "str",
|
|
749
|
+
doc: "Human readable error message describing the authentication failure."
|
|
750
|
+
}, {
|
|
751
|
+
name: "error_code",
|
|
752
|
+
type: "int",
|
|
753
|
+
default: "401",
|
|
754
|
+
doc: "HTTP error code associated with the authentication failure."
|
|
755
|
+
}, {
|
|
756
|
+
name: "retry_after",
|
|
757
|
+
type: "int",
|
|
758
|
+
default: undefined,
|
|
759
|
+
doc: "Number of seconds to wait before retrying authentication."
|
|
760
|
+
}],
|
|
761
|
+
attributes: [{
|
|
762
|
+
name: "message",
|
|
763
|
+
type: "str",
|
|
764
|
+
children: "The error message."
|
|
765
|
+
}, {
|
|
766
|
+
name: "error_code",
|
|
767
|
+
type: "int",
|
|
768
|
+
children: "HTTP status code."
|
|
769
|
+
}, {
|
|
770
|
+
name: "retry_after",
|
|
771
|
+
type: "int",
|
|
772
|
+
children: "Retry delay in seconds, if applicable."
|
|
773
|
+
}],
|
|
774
|
+
note: "This exception should be caught and handled gracefully in production code."
|
|
775
|
+
}, {
|
|
776
|
+
fileName: import.meta.url,
|
|
777
|
+
lineNumber: 663,
|
|
778
|
+
columnNumber: 7
|
|
779
|
+
})]);
|
|
780
|
+
expect(res).toRenderTo(d`
|
|
781
|
+
"""
|
|
782
|
+
A custom exception for authentication failures.
|
|
783
|
+
|
|
784
|
+
This exception is raised when authentication credentials are invalid or when
|
|
785
|
+
authentication tokens have expired.
|
|
786
|
+
|
|
787
|
+
Args:
|
|
788
|
+
message (str): Human readable error message describing the authentication
|
|
789
|
+
failure.
|
|
790
|
+
|
|
791
|
+
error_code (int, optional): HTTP error code associated with the
|
|
792
|
+
authentication failure. Defaults to "401".
|
|
793
|
+
|
|
794
|
+
retry_after (int): Number of seconds to wait before retrying authentication.
|
|
795
|
+
|
|
796
|
+
Attributes:
|
|
797
|
+
message (str): The error message.
|
|
798
|
+
|
|
799
|
+
error_code (int): HTTP status code.
|
|
800
|
+
|
|
801
|
+
retry_after (int): Retry delay in seconds, if applicable.
|
|
802
|
+
|
|
803
|
+
Note:
|
|
804
|
+
This exception should be caught and handled gracefully in production code.
|
|
805
|
+
"""
|
|
806
|
+
|
|
807
|
+
|
|
808
|
+
`);
|
|
809
|
+
});
|
|
810
|
+
it("MethodDoc with raises but no returns", () => {
|
|
811
|
+
const res = toSourceText([_$createComponent(py.MethodDoc, {
|
|
812
|
+
get description() {
|
|
813
|
+
return [_$createComponent(Prose, {
|
|
814
|
+
children: "A method that performs an action but doesn't return a value."
|
|
815
|
+
}, {
|
|
816
|
+
fileName: import.meta.url,
|
|
817
|
+
lineNumber: 748,
|
|
818
|
+
columnNumber: 11
|
|
819
|
+
})];
|
|
820
|
+
},
|
|
821
|
+
parameters: [{
|
|
822
|
+
name: "data",
|
|
823
|
+
type: "bytes",
|
|
824
|
+
doc: "Raw data to process."
|
|
825
|
+
}],
|
|
826
|
+
raises: ["ValueError: If data is empty or invalid.", "IOError: If processing fails due to I/O issues."]
|
|
827
|
+
}, {
|
|
828
|
+
fileName: import.meta.url,
|
|
829
|
+
lineNumber: 746,
|
|
830
|
+
columnNumber: 7
|
|
831
|
+
})]);
|
|
832
|
+
expect(res).toRenderTo(d`
|
|
833
|
+
"""
|
|
834
|
+
A method that performs an action but doesn't return a value.
|
|
835
|
+
|
|
836
|
+
Args:
|
|
837
|
+
data (bytes): Raw data to process.
|
|
838
|
+
|
|
839
|
+
Raises:
|
|
840
|
+
ValueError: If data is empty or invalid.
|
|
841
|
+
|
|
842
|
+
Raises:
|
|
843
|
+
IOError: If processing fails due to I/O issues.
|
|
844
|
+
"""
|
|
845
|
+
|
|
846
|
+
|
|
847
|
+
`);
|
|
848
|
+
});
|
|
849
|
+
it("MethodDoc with no parameters", () => {
|
|
850
|
+
const res = toSourceText([_$createComponent(py.MethodDoc, {
|
|
851
|
+
get description() {
|
|
852
|
+
return [_$createComponent(Prose, {
|
|
853
|
+
children: "A simple method with no parameters (except self)."
|
|
854
|
+
}, {
|
|
855
|
+
fileName: import.meta.url,
|
|
856
|
+
lineNumber: 790,
|
|
857
|
+
columnNumber: 11
|
|
858
|
+
})];
|
|
859
|
+
},
|
|
860
|
+
returns: "bool: True if the operation was successful.",
|
|
861
|
+
note: "This is a parameterless method that only operates on instance state."
|
|
862
|
+
}, {
|
|
863
|
+
fileName: import.meta.url,
|
|
864
|
+
lineNumber: 788,
|
|
865
|
+
columnNumber: 7
|
|
866
|
+
})]);
|
|
867
|
+
expect(res).toRenderTo(d`
|
|
868
|
+
"""
|
|
869
|
+
A simple method with no parameters (except self).
|
|
870
|
+
|
|
871
|
+
Returns:
|
|
872
|
+
bool: True if the operation was successful.
|
|
873
|
+
|
|
874
|
+
Note:
|
|
875
|
+
This is a parameterless method that only operates on instance state.
|
|
876
|
+
"""
|
|
877
|
+
|
|
878
|
+
|
|
879
|
+
`);
|
|
880
|
+
});
|
|
881
|
+
it("AttributeDoc standalone usage", () => {
|
|
882
|
+
const res = toSourceText([_$createComponent(py.PyDoc, {
|
|
883
|
+
get children() {
|
|
884
|
+
return _$createComponent(py.AttributeDoc, {
|
|
885
|
+
name: "connection_timeout",
|
|
886
|
+
type: "float",
|
|
887
|
+
children: "Maximum time in seconds to wait for a connection to be established."
|
|
888
|
+
}, {
|
|
889
|
+
fileName: import.meta.url,
|
|
890
|
+
lineNumber: 817,
|
|
891
|
+
columnNumber: 9
|
|
892
|
+
});
|
|
893
|
+
}
|
|
894
|
+
}, {
|
|
895
|
+
fileName: import.meta.url,
|
|
896
|
+
lineNumber: 816,
|
|
897
|
+
columnNumber: 7
|
|
898
|
+
})]);
|
|
899
|
+
expect(res).toRenderTo(d`
|
|
900
|
+
"""
|
|
901
|
+
connection_timeout (float): Maximum time in seconds to wait for a connection to
|
|
902
|
+
be established.
|
|
903
|
+
"""
|
|
904
|
+
|
|
905
|
+
|
|
906
|
+
`);
|
|
907
|
+
});
|
|
908
|
+
it("GeneratorDoc with examples in description", () => {
|
|
909
|
+
const res = toSourceText([_$createComponent(py.GeneratorDoc, {
|
|
910
|
+
get description() {
|
|
911
|
+
return [_$createComponent(Prose, {
|
|
912
|
+
children: "Generators have a Yields section instead of a Returns section."
|
|
913
|
+
}, {
|
|
914
|
+
fileName: import.meta.url,
|
|
915
|
+
lineNumber: 839,
|
|
916
|
+
columnNumber: 11
|
|
917
|
+
}), _$createComponent(py.PyDocExample, {
|
|
918
|
+
children: `print([i for i in example_generator(4)])\n[0, 1, 2, 3]`
|
|
919
|
+
}, {
|
|
920
|
+
fileName: import.meta.url,
|
|
921
|
+
lineNumber: 842,
|
|
922
|
+
columnNumber: 11
|
|
923
|
+
})];
|
|
924
|
+
},
|
|
925
|
+
parameters: [{
|
|
926
|
+
name: "n",
|
|
927
|
+
type: "int",
|
|
928
|
+
doc: "The upper limit of the range to generate, from 0 to n - 1."
|
|
929
|
+
}],
|
|
930
|
+
yields: "int: The next number in the range of 0 to n - 1.",
|
|
931
|
+
note: "Examples should be written in doctest format, and should illustrate how to use the function."
|
|
932
|
+
}, {
|
|
933
|
+
fileName: import.meta.url,
|
|
934
|
+
lineNumber: 837,
|
|
935
|
+
columnNumber: 7
|
|
936
|
+
})]);
|
|
937
|
+
expect(res).toRenderTo(d`
|
|
938
|
+
"""
|
|
939
|
+
Generators have a Yields section instead of a Returns section.
|
|
940
|
+
|
|
941
|
+
>> print([i for i in example_generator(4)])
|
|
942
|
+
>> [0, 1, 2, 3]
|
|
943
|
+
|
|
944
|
+
Args:
|
|
945
|
+
n (int): The upper limit of the range to generate, from 0 to n - 1.
|
|
946
|
+
|
|
947
|
+
Yields:
|
|
948
|
+
int: The next number in the range of 0 to n - 1.
|
|
949
|
+
|
|
950
|
+
Note:
|
|
951
|
+
Examples should be written in doctest format, and should illustrate how to use the function.
|
|
952
|
+
"""
|
|
953
|
+
|
|
954
|
+
|
|
955
|
+
`);
|
|
956
|
+
});
|
|
957
|
+
});
|
|
958
|
+
describe("Full example", () => {
|
|
959
|
+
it("renders correctly in a Class", () => {
|
|
960
|
+
const doc = _$createComponent(py.ClassDoc, {
|
|
961
|
+
get description() {
|
|
962
|
+
return [_$createComponent(Prose, {
|
|
963
|
+
children: "This is an example of a long docstring that will be broken in lines. We will also render another paragraph after this one."
|
|
964
|
+
}, {
|
|
965
|
+
fileName: import.meta.url,
|
|
966
|
+
lineNumber: 887,
|
|
967
|
+
columnNumber: 11
|
|
968
|
+
}), _$createComponent(py.PyDocExample, {
|
|
969
|
+
children: `print("Hello world!")\nx = "Hello"\nprint(x)`
|
|
970
|
+
}, {
|
|
971
|
+
fileName: import.meta.url,
|
|
972
|
+
lineNumber: 891,
|
|
973
|
+
columnNumber: 11
|
|
974
|
+
})];
|
|
975
|
+
},
|
|
976
|
+
attributes: [{
|
|
977
|
+
name: "attr1",
|
|
978
|
+
type: "str",
|
|
979
|
+
children: "Description of attr1."
|
|
980
|
+
}, {
|
|
981
|
+
name: "attr2",
|
|
982
|
+
type: "int",
|
|
983
|
+
children: "Description of attr2."
|
|
984
|
+
}],
|
|
985
|
+
get examples() {
|
|
986
|
+
return [_$createComponent(py.PyDocExample, {
|
|
987
|
+
children: "print(\"class-doc\")"
|
|
988
|
+
}, {
|
|
989
|
+
fileName: import.meta.url,
|
|
990
|
+
lineNumber: 907,
|
|
991
|
+
columnNumber: 20
|
|
992
|
+
})];
|
|
993
|
+
},
|
|
994
|
+
seeAlso: ["RelatedClass", "helper_function"],
|
|
995
|
+
warning: "This class is experimental.",
|
|
996
|
+
deprecated: "Use NewClass instead.",
|
|
997
|
+
parameters: [{
|
|
998
|
+
name: "somebody",
|
|
999
|
+
type: "str",
|
|
1000
|
+
default: "John Doe",
|
|
1001
|
+
doc: "Somebody's name. This can be any string representing a person, whether it's a first name, full name, nickname, or even a codename (e.g., 'Agent X'). It's used primarily for display purposes, logging, or greeting messages and is not required to be unique or validated unless specified by the caller."
|
|
1002
|
+
}, {
|
|
1003
|
+
name: "somebody2",
|
|
1004
|
+
type: "str",
|
|
1005
|
+
doc: "Somebody's name. This can be any string representing a person, whether it's a first name, full name, nickname, or even a codename (e.g., 'Agent X'). It's used primarily for display purposes, logging, or greeting messages and is not required to be unique or validated unless specified by the caller."
|
|
1006
|
+
}],
|
|
1007
|
+
note: "Do not include the 'self' parameter in the Args section.",
|
|
1008
|
+
style: "google"
|
|
1009
|
+
}, {
|
|
1010
|
+
fileName: import.meta.url,
|
|
1011
|
+
lineNumber: 885,
|
|
1012
|
+
columnNumber: 7
|
|
1013
|
+
});
|
|
1014
|
+
const res = toSourceText([_$createComponent(py.ClassDeclaration, {
|
|
1015
|
+
name: "A",
|
|
1016
|
+
doc: doc,
|
|
1017
|
+
get children() {
|
|
1018
|
+
return _$createComponent(py.StatementList, {
|
|
1019
|
+
get children() {
|
|
1020
|
+
return [_$createComponent(py.VariableDeclaration, {
|
|
1021
|
+
name: "just_name"
|
|
1022
|
+
}, {
|
|
1023
|
+
fileName: import.meta.url,
|
|
1024
|
+
lineNumber: 932,
|
|
1025
|
+
columnNumber: 13
|
|
1026
|
+
}), _$createComponent(py.VariableDeclaration, {
|
|
1027
|
+
name: "name_and_type",
|
|
1028
|
+
type: "int"
|
|
1029
|
+
}, {
|
|
1030
|
+
fileName: import.meta.url,
|
|
1031
|
+
lineNumber: 933,
|
|
1032
|
+
columnNumber: 13
|
|
1033
|
+
}), _$createComponent(py.VariableDeclaration, {
|
|
1034
|
+
name: "name_type_and_value",
|
|
1035
|
+
type: "int",
|
|
1036
|
+
initializer: 12
|
|
1037
|
+
}, {
|
|
1038
|
+
fileName: import.meta.url,
|
|
1039
|
+
lineNumber: 934,
|
|
1040
|
+
columnNumber: 13
|
|
1041
|
+
})];
|
|
1042
|
+
}
|
|
1043
|
+
}, {
|
|
1044
|
+
fileName: import.meta.url,
|
|
1045
|
+
lineNumber: 931,
|
|
1046
|
+
columnNumber: 11
|
|
1047
|
+
});
|
|
1048
|
+
}
|
|
1049
|
+
}, {
|
|
1050
|
+
fileName: import.meta.url,
|
|
1051
|
+
lineNumber: 930,
|
|
1052
|
+
columnNumber: 9
|
|
1053
|
+
})], {
|
|
1054
|
+
printOptions: {
|
|
1055
|
+
printWidth: 80,
|
|
1056
|
+
tabWidth: 4
|
|
1057
|
+
}
|
|
1058
|
+
});
|
|
1059
|
+
expect(res).toRenderTo(d`
|
|
1060
|
+
class A:
|
|
1061
|
+
"""
|
|
1062
|
+
This is an example of a long docstring that will be broken in lines. We will
|
|
1063
|
+
also render another paragraph after this one.
|
|
1064
|
+
|
|
1065
|
+
>> print("Hello world!")
|
|
1066
|
+
>> x = "Hello"
|
|
1067
|
+
>> print(x)
|
|
1068
|
+
|
|
1069
|
+
Attributes:
|
|
1070
|
+
attr1 (str): Description of attr1.
|
|
1071
|
+
|
|
1072
|
+
attr2 (int): Description of attr2.
|
|
1073
|
+
|
|
1074
|
+
Args:
|
|
1075
|
+
somebody (str, optional): Somebody's name. This can be any string
|
|
1076
|
+
representing a person, whether it's a first name, full name,
|
|
1077
|
+
nickname, or even a codename (e.g., 'Agent X'). It's used primarily
|
|
1078
|
+
for display purposes, logging, or greeting messages and is not
|
|
1079
|
+
required to be unique or validated unless specified by the caller.
|
|
1080
|
+
Defaults to \"John Doe\".
|
|
1081
|
+
|
|
1082
|
+
somebody2 (str): Somebody's name. This can be any string representing a
|
|
1083
|
+
person, whether it's a first name, full name, nickname, or even a
|
|
1084
|
+
codename (e.g., 'Agent X'). It's used primarily for display
|
|
1085
|
+
purposes, logging, or greeting messages and is not required to be
|
|
1086
|
+
unique or validated unless specified by the caller.
|
|
1087
|
+
|
|
1088
|
+
Examples:
|
|
1089
|
+
>> print("class-doc")
|
|
1090
|
+
|
|
1091
|
+
See Also:
|
|
1092
|
+
RelatedClass
|
|
1093
|
+
helper_function
|
|
1094
|
+
|
|
1095
|
+
Warning:
|
|
1096
|
+
This class is experimental.
|
|
1097
|
+
|
|
1098
|
+
Deprecated:
|
|
1099
|
+
Use NewClass instead.
|
|
1100
|
+
|
|
1101
|
+
Note:
|
|
1102
|
+
Do not include the 'self' parameter in the Args section.
|
|
1103
|
+
"""
|
|
1104
|
+
|
|
1105
|
+
just_name = None
|
|
1106
|
+
name_and_type: int = None
|
|
1107
|
+
name_type_and_value: int = 12
|
|
1108
|
+
|
|
1109
|
+
|
|
1110
|
+
`);
|
|
1111
|
+
});
|
|
1112
|
+
it("renders correctly in a Function", () => {
|
|
1113
|
+
const doc = _$createComponent(py.FunctionDoc, {
|
|
1114
|
+
get description() {
|
|
1115
|
+
return [_$createComponent(Prose, {
|
|
1116
|
+
children: "This is an example of a long docstring that will be broken in lines. We will also render another paragraph after this one."
|
|
1117
|
+
}, {
|
|
1118
|
+
fileName: import.meta.url,
|
|
1119
|
+
lineNumber: 1005,
|
|
1120
|
+
columnNumber: 11
|
|
1121
|
+
}), _$createComponent(py.PyDocExample, {
|
|
1122
|
+
children: `print("Hello world!")\nx = "Hello"\nprint(x)`
|
|
1123
|
+
}, {
|
|
1124
|
+
fileName: import.meta.url,
|
|
1125
|
+
lineNumber: 1009,
|
|
1126
|
+
columnNumber: 11
|
|
1127
|
+
})];
|
|
1128
|
+
},
|
|
1129
|
+
parameters: [{
|
|
1130
|
+
name: "somebody",
|
|
1131
|
+
type: "str",
|
|
1132
|
+
default: "John Doe",
|
|
1133
|
+
doc: "Somebody's name. This can be any string representing a person, whether it's a first name, full name, nickname, or even a codename (e.g., 'Agent X'). It's used primarily for display purposes, logging, or greeting messages and is not required to be unique or validated unless specified by the caller."
|
|
1134
|
+
}, {
|
|
1135
|
+
name: "somebody2",
|
|
1136
|
+
type: "str",
|
|
1137
|
+
doc: "Somebody's name. This can be any string representing a person, whether it's a first name, full name, nickname, or even a codename (e.g., 'Agent X'). It's used primarily for display purposes, logging, or greeting messages and is not required to be unique or validated unless specified by the caller."
|
|
1138
|
+
}],
|
|
1139
|
+
returns: "The return value. True for success, False otherwise.",
|
|
1140
|
+
yields: "int: The next number in the sequence.",
|
|
1141
|
+
raises: ["ValueError: If somebody2 is equal to somebody."],
|
|
1142
|
+
note: "This function can be used as both a regular function and a generator.",
|
|
1143
|
+
style: "google"
|
|
1144
|
+
}, {
|
|
1145
|
+
fileName: import.meta.url,
|
|
1146
|
+
lineNumber: 1003,
|
|
1147
|
+
columnNumber: 7
|
|
1148
|
+
});
|
|
1149
|
+
const res = toSourceText([_$createComponent(py.FunctionDeclaration, {
|
|
1150
|
+
name: "some_function",
|
|
1151
|
+
doc: doc,
|
|
1152
|
+
get children() {
|
|
1153
|
+
return _$createComponent(py.StatementList, {
|
|
1154
|
+
get children() {
|
|
1155
|
+
return [_$createComponent(py.VariableDeclaration, {
|
|
1156
|
+
name: "just_name"
|
|
1157
|
+
}, {
|
|
1158
|
+
fileName: import.meta.url,
|
|
1159
|
+
lineNumber: 1037,
|
|
1160
|
+
columnNumber: 13
|
|
1161
|
+
}), _$createComponent(py.VariableDeclaration, {
|
|
1162
|
+
name: "name_and_type",
|
|
1163
|
+
type: "number"
|
|
1164
|
+
}, {
|
|
1165
|
+
fileName: import.meta.url,
|
|
1166
|
+
lineNumber: 1038,
|
|
1167
|
+
columnNumber: 13
|
|
1168
|
+
}), _$createComponent(py.VariableDeclaration, {
|
|
1169
|
+
name: "name_type_and_value",
|
|
1170
|
+
type: "number",
|
|
1171
|
+
initializer: 12
|
|
1172
|
+
}, {
|
|
1173
|
+
fileName: import.meta.url,
|
|
1174
|
+
lineNumber: 1039,
|
|
1175
|
+
columnNumber: 13
|
|
1176
|
+
})];
|
|
1177
|
+
}
|
|
1178
|
+
}, {
|
|
1179
|
+
fileName: import.meta.url,
|
|
1180
|
+
lineNumber: 1036,
|
|
1181
|
+
columnNumber: 11
|
|
1182
|
+
});
|
|
1183
|
+
}
|
|
1184
|
+
}, {
|
|
1185
|
+
fileName: import.meta.url,
|
|
1186
|
+
lineNumber: 1035,
|
|
1187
|
+
columnNumber: 9
|
|
1188
|
+
})], {
|
|
1189
|
+
printOptions: {
|
|
1190
|
+
printWidth: 80,
|
|
1191
|
+
tabWidth: 4
|
|
1192
|
+
}
|
|
1193
|
+
});
|
|
1194
|
+
expect(res).toRenderTo(d`
|
|
1195
|
+
def some_function():
|
|
1196
|
+
"""
|
|
1197
|
+
This is an example of a long docstring that will be broken in lines. We will
|
|
1198
|
+
also render another paragraph after this one.
|
|
1199
|
+
|
|
1200
|
+
>> print("Hello world!")
|
|
1201
|
+
>> x = "Hello"
|
|
1202
|
+
>> print(x)
|
|
1203
|
+
|
|
1204
|
+
Args:
|
|
1205
|
+
somebody (str, optional): Somebody's name. This can be any string
|
|
1206
|
+
representing a person, whether it's a first name, full name,
|
|
1207
|
+
nickname, or even a codename (e.g., 'Agent X'). It's used primarily
|
|
1208
|
+
for display purposes, logging, or greeting messages and is not
|
|
1209
|
+
required to be unique or validated unless specified by the caller.
|
|
1210
|
+
Defaults to \"John Doe\".
|
|
1211
|
+
|
|
1212
|
+
somebody2 (str): Somebody's name. This can be any string representing a
|
|
1213
|
+
person, whether it's a first name, full name, nickname, or even a
|
|
1214
|
+
codename (e.g., 'Agent X'). It's used primarily for display
|
|
1215
|
+
purposes, logging, or greeting messages and is not required to be
|
|
1216
|
+
unique or validated unless specified by the caller.
|
|
1217
|
+
|
|
1218
|
+
Returns:
|
|
1219
|
+
The return value. True for success, False otherwise.
|
|
1220
|
+
|
|
1221
|
+
Yields:
|
|
1222
|
+
int: The next number in the sequence.
|
|
1223
|
+
|
|
1224
|
+
Raises:
|
|
1225
|
+
ValueError: If somebody2 is equal to somebody.
|
|
1226
|
+
|
|
1227
|
+
Note:
|
|
1228
|
+
This function can be used as both a regular function and a generator.
|
|
1229
|
+
"""
|
|
1230
|
+
just_name = None
|
|
1231
|
+
name_and_type: number = None
|
|
1232
|
+
name_type_and_value: number = 12
|
|
1233
|
+
|
|
1234
|
+
|
|
1235
|
+
`);
|
|
1236
|
+
});
|
|
1237
|
+
it("renders correctly in a Variable", () => {
|
|
1238
|
+
const res = toSourceText([_$createComponent(py.VariableDeclaration, {
|
|
1239
|
+
name: "myVar",
|
|
1240
|
+
initializer: 42,
|
|
1241
|
+
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."
|
|
1242
|
+
}, {
|
|
1243
|
+
fileName: import.meta.url,
|
|
1244
|
+
lineNumber: 1099,
|
|
1245
|
+
columnNumber: 9
|
|
1246
|
+
})], {
|
|
1247
|
+
printOptions: {
|
|
1248
|
+
printWidth: 80,
|
|
1249
|
+
tabWidth: 4
|
|
1250
|
+
}
|
|
1251
|
+
});
|
|
1252
|
+
expect(res).toRenderTo(d`
|
|
1253
|
+
# This is a very long docstring that will be broken in two lines when rendered.
|
|
1254
|
+
# This part of the docstring will be in the second line.
|
|
1255
|
+
my_var = 42
|
|
1256
|
+
`);
|
|
1257
|
+
});
|
|
1258
|
+
it("classic enum with explicit values", () => {
|
|
1259
|
+
const doc = _$createComponent(py.ClassDoc, {
|
|
1260
|
+
get description() {
|
|
1261
|
+
return [_$createComponent(Prose, {
|
|
1262
|
+
children: "An enum representing colors."
|
|
1263
|
+
}, {
|
|
1264
|
+
fileName: import.meta.url,
|
|
1265
|
+
lineNumber: 1120,
|
|
1266
|
+
columnNumber: 23
|
|
1267
|
+
})];
|
|
1268
|
+
}
|
|
1269
|
+
}, {
|
|
1270
|
+
fileName: import.meta.url,
|
|
1271
|
+
lineNumber: 1119,
|
|
1272
|
+
columnNumber: 7
|
|
1273
|
+
});
|
|
1274
|
+
const result = toSourceText([_$createComponent(py.ClassEnumDeclaration, {
|
|
1275
|
+
name: "Color",
|
|
1276
|
+
baseType: "IntEnum",
|
|
1277
|
+
members: [{
|
|
1278
|
+
name: "RED",
|
|
1279
|
+
value: "1",
|
|
1280
|
+
doc: "The color red."
|
|
1281
|
+
}, {
|
|
1282
|
+
name: "GREEN",
|
|
1283
|
+
value: "2",
|
|
1284
|
+
doc: "The color green."
|
|
1285
|
+
}, {
|
|
1286
|
+
name: "BLUE",
|
|
1287
|
+
value: "3",
|
|
1288
|
+
doc: "The color blue."
|
|
1289
|
+
}],
|
|
1290
|
+
doc: doc
|
|
1291
|
+
}, {
|
|
1292
|
+
fileName: import.meta.url,
|
|
1293
|
+
lineNumber: 1125,
|
|
1294
|
+
columnNumber: 9
|
|
1295
|
+
})], {
|
|
1296
|
+
externals: [enumModule]
|
|
1297
|
+
});
|
|
1298
|
+
const expected = d`
|
|
1299
|
+
from enum import IntEnum
|
|
1300
|
+
|
|
1301
|
+
|
|
1302
|
+
class Color(IntEnum):
|
|
1303
|
+
"""
|
|
1304
|
+
An enum representing colors.
|
|
1305
|
+
"""
|
|
1306
|
+
|
|
1307
|
+
RED = 1
|
|
1308
|
+
"""
|
|
1309
|
+
The color red.
|
|
1310
|
+
"""
|
|
1311
|
+
GREEN = 2
|
|
1312
|
+
"""
|
|
1313
|
+
The color green.
|
|
1314
|
+
"""
|
|
1315
|
+
BLUE = 3
|
|
1316
|
+
"""
|
|
1317
|
+
The color blue.
|
|
1318
|
+
"""
|
|
1319
|
+
|
|
1320
|
+
|
|
1321
|
+
`;
|
|
1322
|
+
expect(result).toRenderTo(expected);
|
|
1323
|
+
});
|
|
1324
|
+
it("ModuleDoc with SourceFile integration", () => {
|
|
1325
|
+
const moduleDoc = _$createComponent(py.ModuleDoc, {
|
|
1326
|
+
get description() {
|
|
1327
|
+
return [_$createComponent(Prose, {
|
|
1328
|
+
children: "This module provides utility functions for data processing. It includes functions for validation, transformation, and analysis."
|
|
1329
|
+
}, {
|
|
1330
|
+
fileName: import.meta.url,
|
|
1331
|
+
lineNumber: 1169,
|
|
1332
|
+
columnNumber: 11
|
|
1333
|
+
})];
|
|
1334
|
+
},
|
|
1335
|
+
attributes: [{
|
|
1336
|
+
name: "DEFAULT_TIMEOUT",
|
|
1337
|
+
type: "int",
|
|
1338
|
+
children: "Default timeout value in seconds."
|
|
1339
|
+
}, {
|
|
1340
|
+
name: "MAX_RETRIES",
|
|
1341
|
+
type: "int",
|
|
1342
|
+
children: "Maximum number of retry attempts."
|
|
1343
|
+
}],
|
|
1344
|
+
todo: ["Add caching functionality", "Improve error messages"],
|
|
1345
|
+
style: "google"
|
|
1346
|
+
}, {
|
|
1347
|
+
fileName: import.meta.url,
|
|
1348
|
+
lineNumber: 1167,
|
|
1349
|
+
columnNumber: 7
|
|
1350
|
+
});
|
|
1351
|
+
const content = _$createComponent(py.SourceFile, {
|
|
1352
|
+
path: "utils.py",
|
|
1353
|
+
doc: moduleDoc,
|
|
1354
|
+
get children() {
|
|
1355
|
+
return [_$createComponent(py.VariableDeclaration, {
|
|
1356
|
+
name: "DEFAULT_TIMEOUT",
|
|
1357
|
+
initializer: 30
|
|
1358
|
+
}, {
|
|
1359
|
+
fileName: import.meta.url,
|
|
1360
|
+
lineNumber: 1193,
|
|
1361
|
+
columnNumber: 9
|
|
1362
|
+
}), _$createComponent(py.VariableDeclaration, {
|
|
1363
|
+
name: "MAX_RETRIES",
|
|
1364
|
+
initializer: 3
|
|
1365
|
+
}, {
|
|
1366
|
+
fileName: import.meta.url,
|
|
1367
|
+
lineNumber: 1194,
|
|
1368
|
+
columnNumber: 9
|
|
1369
|
+
}), _$createComponent(py.FunctionDeclaration, {
|
|
1370
|
+
name: "process_data",
|
|
1371
|
+
children: "pass"
|
|
1372
|
+
}, {
|
|
1373
|
+
fileName: import.meta.url,
|
|
1374
|
+
lineNumber: 1195,
|
|
1375
|
+
columnNumber: 9
|
|
1376
|
+
})];
|
|
1377
|
+
}
|
|
1378
|
+
}, {
|
|
1379
|
+
fileName: import.meta.url,
|
|
1380
|
+
lineNumber: 1192,
|
|
1381
|
+
columnNumber: 7
|
|
1382
|
+
});
|
|
1383
|
+
const res = toSourceTextMultiple([content]);
|
|
1384
|
+
const file = res.contents.find(f => f.kind === "file" && f.path === "utils.py");
|
|
1385
|
+
expect(file).toBeDefined();
|
|
1386
|
+
assertFileContents(res, {
|
|
1387
|
+
"utils.py": d`
|
|
1388
|
+
"""
|
|
1389
|
+
This module provides utility functions for data processing. It includes
|
|
1390
|
+
functions for validation, transformation, and analysis.
|
|
1391
|
+
|
|
1392
|
+
Attributes:
|
|
1393
|
+
DEFAULT_TIMEOUT (int): Default timeout value in seconds.
|
|
1394
|
+
|
|
1395
|
+
MAX_RETRIES (int): Maximum number of retry attempts.
|
|
1396
|
+
|
|
1397
|
+
Todo:
|
|
1398
|
+
* Add caching functionality
|
|
1399
|
+
* Improve error messages
|
|
1400
|
+
"""
|
|
1401
|
+
|
|
1402
|
+
default_timeout = 30
|
|
1403
|
+
|
|
1404
|
+
max_retries = 3
|
|
1405
|
+
|
|
1406
|
+
def process_data():
|
|
1407
|
+
pass
|
|
1408
|
+
|
|
1409
|
+
|
|
1410
|
+
`
|
|
1411
|
+
});
|
|
1412
|
+
});
|
|
1413
|
+
it("GeneratorDoc with FunctionDeclaration integration", () => {
|
|
1414
|
+
const generatorDoc = _$createComponent(py.GeneratorDoc, {
|
|
1415
|
+
get description() {
|
|
1416
|
+
return [_$createComponent(Prose, {
|
|
1417
|
+
children: "A generator function that yields fibonacci numbers. This is an efficient way to generate the sequence on demand."
|
|
1418
|
+
}, {
|
|
1419
|
+
fileName: import.meta.url,
|
|
1420
|
+
lineNumber: 1239,
|
|
1421
|
+
columnNumber: 11
|
|
1422
|
+
})];
|
|
1423
|
+
},
|
|
1424
|
+
parameters: [{
|
|
1425
|
+
name: "n",
|
|
1426
|
+
type: "int",
|
|
1427
|
+
doc: "Number of fibonacci numbers to generate."
|
|
1428
|
+
}],
|
|
1429
|
+
yields: "int: The next fibonacci number in the sequence.",
|
|
1430
|
+
style: "google"
|
|
1431
|
+
}, {
|
|
1432
|
+
fileName: import.meta.url,
|
|
1433
|
+
lineNumber: 1237,
|
|
1434
|
+
columnNumber: 7
|
|
1435
|
+
});
|
|
1436
|
+
const result = toSourceText([_$createComponent(py.FunctionDeclaration, {
|
|
1437
|
+
name: "fibonacci_generator",
|
|
1438
|
+
doc: generatorDoc,
|
|
1439
|
+
children: "yield 0"
|
|
1440
|
+
}, {
|
|
1441
|
+
fileName: import.meta.url,
|
|
1442
|
+
lineNumber: 1257,
|
|
1443
|
+
columnNumber: 7
|
|
1444
|
+
})]);
|
|
1445
|
+
expect(result).toRenderTo(d`
|
|
1446
|
+
def fibonacci_generator():
|
|
1447
|
+
"""
|
|
1448
|
+
A generator function that yields fibonacci numbers. This is an efficient way
|
|
1449
|
+
to generate the sequence on demand.
|
|
1450
|
+
|
|
1451
|
+
Args:
|
|
1452
|
+
n (int): Number of fibonacci numbers to generate.
|
|
1453
|
+
|
|
1454
|
+
Yields:
|
|
1455
|
+
int: The next fibonacci number in the sequence.
|
|
1456
|
+
"""
|
|
1457
|
+
yield 0
|
|
1458
|
+
|
|
1459
|
+
|
|
1460
|
+
`);
|
|
1461
|
+
});
|
|
1462
|
+
it("ExceptionDoc with ClassDeclaration integration", () => {
|
|
1463
|
+
const exceptionDoc = _$createComponent(py.ExceptionDoc, {
|
|
1464
|
+
get description() {
|
|
1465
|
+
return [_$createComponent(Prose, {
|
|
1466
|
+
children: "Custom exception raised when data validation fails. This exception includes details about the validation error."
|
|
1467
|
+
}, {
|
|
1468
|
+
fileName: import.meta.url,
|
|
1469
|
+
lineNumber: 1286,
|
|
1470
|
+
columnNumber: 11
|
|
1471
|
+
})];
|
|
1472
|
+
},
|
|
1473
|
+
attributes: [{
|
|
1474
|
+
name: "field_name",
|
|
1475
|
+
type: "str",
|
|
1476
|
+
children: "Name of the field that failed validation."
|
|
1477
|
+
}, {
|
|
1478
|
+
name: "error_code",
|
|
1479
|
+
type: "int",
|
|
1480
|
+
children: "Numeric error code for the validation failure."
|
|
1481
|
+
}],
|
|
1482
|
+
style: "google"
|
|
1483
|
+
}, {
|
|
1484
|
+
fileName: import.meta.url,
|
|
1485
|
+
lineNumber: 1284,
|
|
1486
|
+
columnNumber: 7
|
|
1487
|
+
});
|
|
1488
|
+
const result = toSourceText([_$createComponent(py.ClassDeclaration, {
|
|
1489
|
+
name: "ValidationError",
|
|
1490
|
+
bases: ["Exception"],
|
|
1491
|
+
doc: exceptionDoc,
|
|
1492
|
+
get children() {
|
|
1493
|
+
return _$createComponent(py.StatementList, {
|
|
1494
|
+
get children() {
|
|
1495
|
+
return [_$createComponent(py.VariableDeclaration, {
|
|
1496
|
+
name: "field_name",
|
|
1497
|
+
type: "str"
|
|
1498
|
+
}, {
|
|
1499
|
+
fileName: import.meta.url,
|
|
1500
|
+
lineNumber: 1314,
|
|
1501
|
+
columnNumber: 11
|
|
1502
|
+
}), _$createComponent(py.VariableDeclaration, {
|
|
1503
|
+
name: "error_code",
|
|
1504
|
+
type: "int"
|
|
1505
|
+
}, {
|
|
1506
|
+
fileName: import.meta.url,
|
|
1507
|
+
lineNumber: 1315,
|
|
1508
|
+
columnNumber: 11
|
|
1509
|
+
})];
|
|
1510
|
+
}
|
|
1511
|
+
}, {
|
|
1512
|
+
fileName: import.meta.url,
|
|
1513
|
+
lineNumber: 1313,
|
|
1514
|
+
columnNumber: 9
|
|
1515
|
+
});
|
|
1516
|
+
}
|
|
1517
|
+
}, {
|
|
1518
|
+
fileName: import.meta.url,
|
|
1519
|
+
lineNumber: 1308,
|
|
1520
|
+
columnNumber: 7
|
|
1521
|
+
})]);
|
|
1522
|
+
expect(result).toRenderTo(d`
|
|
1523
|
+
class ValidationError(Exception):
|
|
1524
|
+
"""
|
|
1525
|
+
Custom exception raised when data validation fails. This exception includes
|
|
1526
|
+
details about the validation error.
|
|
1527
|
+
|
|
1528
|
+
Attributes:
|
|
1529
|
+
field_name (str): Name of the field that failed validation.
|
|
1530
|
+
|
|
1531
|
+
error_code (int): Numeric error code for the validation failure.
|
|
1532
|
+
"""
|
|
1533
|
+
|
|
1534
|
+
field_name: str = None
|
|
1535
|
+
error_code: int = None
|
|
1536
|
+
|
|
1537
|
+
|
|
1538
|
+
`);
|
|
1539
|
+
});
|
|
1540
|
+
it("PropertyDoc with FunctionDeclaration (as property method) integration", () => {
|
|
1541
|
+
const propertyDoc = _$createComponent(py.PropertyDoc, {
|
|
1542
|
+
get description() {
|
|
1543
|
+
return [_$createComponent(Prose, {
|
|
1544
|
+
children: "The full name of the person, combining first and last name. This property automatically formats the name with proper capitalization."
|
|
1545
|
+
}, {
|
|
1546
|
+
fileName: import.meta.url,
|
|
1547
|
+
lineNumber: 1345,
|
|
1548
|
+
columnNumber: 11
|
|
1549
|
+
})];
|
|
1550
|
+
},
|
|
1551
|
+
style: "google"
|
|
1552
|
+
}, {
|
|
1553
|
+
fileName: import.meta.url,
|
|
1554
|
+
lineNumber: 1343,
|
|
1555
|
+
columnNumber: 7
|
|
1556
|
+
});
|
|
1557
|
+
const result = toSourceText([_$createComponent(py.ClassDeclaration, {
|
|
1558
|
+
name: "Person",
|
|
1559
|
+
get children() {
|
|
1560
|
+
return _$createComponent(py.PropertyDeclaration, {
|
|
1561
|
+
name: "full_name",
|
|
1562
|
+
doc: propertyDoc,
|
|
1563
|
+
type: "str",
|
|
1564
|
+
children: "return \"John Doe\""
|
|
1565
|
+
}, {
|
|
1566
|
+
fileName: import.meta.url,
|
|
1567
|
+
lineNumber: 1356,
|
|
1568
|
+
columnNumber: 9
|
|
1569
|
+
});
|
|
1570
|
+
}
|
|
1571
|
+
}, {
|
|
1572
|
+
fileName: import.meta.url,
|
|
1573
|
+
lineNumber: 1355,
|
|
1574
|
+
columnNumber: 7
|
|
1575
|
+
})]);
|
|
1576
|
+
expect(result).toRenderTo(`
|
|
1577
|
+
class Person:
|
|
1578
|
+
@property
|
|
1579
|
+
def full_name(self) -> str:
|
|
1580
|
+
"""
|
|
1581
|
+
The full name of the person, combining first and last name. This
|
|
1582
|
+
property automatically formats the name with proper capitalization.
|
|
1583
|
+
"""
|
|
1584
|
+
return "John Doe"
|
|
1585
|
+
|
|
1586
|
+
|
|
1587
|
+
`);
|
|
1588
|
+
});
|
|
1589
|
+
it("MethodDoc with FunctionDeclaration (inside class) integration", () => {
|
|
1590
|
+
const methodDoc = _$createComponent(py.MethodDoc, {
|
|
1591
|
+
get description() {
|
|
1592
|
+
return [_$createComponent(Prose, {
|
|
1593
|
+
children: "Validates the input data according to the defined schema. This method performs comprehensive validation including type checking."
|
|
1594
|
+
}, {
|
|
1595
|
+
fileName: import.meta.url,
|
|
1596
|
+
lineNumber: 1380,
|
|
1597
|
+
columnNumber: 11
|
|
1598
|
+
})];
|
|
1599
|
+
},
|
|
1600
|
+
parameters: [{
|
|
1601
|
+
name: "data",
|
|
1602
|
+
type: "dict",
|
|
1603
|
+
doc: "The data dictionary to validate."
|
|
1604
|
+
}, {
|
|
1605
|
+
name: "strict",
|
|
1606
|
+
type: "bool",
|
|
1607
|
+
default: "True",
|
|
1608
|
+
doc: "Whether to enforce strict validation rules."
|
|
1609
|
+
}],
|
|
1610
|
+
returns: "bool: True if validation passes, False otherwise.",
|
|
1611
|
+
raises: ["ValidationError: If data format is invalid."],
|
|
1612
|
+
note: "This method modifies the internal validation state.",
|
|
1613
|
+
style: "google"
|
|
1614
|
+
}, {
|
|
1615
|
+
fileName: import.meta.url,
|
|
1616
|
+
lineNumber: 1378,
|
|
1617
|
+
columnNumber: 7
|
|
1618
|
+
});
|
|
1619
|
+
const result = toSourceText([_$createComponent(py.ClassDeclaration, {
|
|
1620
|
+
name: "DataValidator",
|
|
1621
|
+
get children() {
|
|
1622
|
+
return _$createComponent(py.MethodDeclaration, {
|
|
1623
|
+
name: "validate",
|
|
1624
|
+
doc: methodDoc,
|
|
1625
|
+
parameters: [{
|
|
1626
|
+
name: "data",
|
|
1627
|
+
type: "dict"
|
|
1628
|
+
}, {
|
|
1629
|
+
name: "strict",
|
|
1630
|
+
type: "bool",
|
|
1631
|
+
default: true
|
|
1632
|
+
}],
|
|
1633
|
+
returnType: "bool",
|
|
1634
|
+
children: "return self.validate(data, strict)"
|
|
1635
|
+
}, {
|
|
1636
|
+
fileName: import.meta.url,
|
|
1637
|
+
lineNumber: 1407,
|
|
1638
|
+
columnNumber: 9
|
|
1639
|
+
});
|
|
1640
|
+
}
|
|
1641
|
+
}, {
|
|
1642
|
+
fileName: import.meta.url,
|
|
1643
|
+
lineNumber: 1406,
|
|
1644
|
+
columnNumber: 7
|
|
1645
|
+
})]);
|
|
1646
|
+
expect(result).toRenderTo(d`
|
|
1647
|
+
class DataValidator:
|
|
1648
|
+
def validate(self, data: dict, strict: bool = True) -> bool:
|
|
1649
|
+
"""
|
|
1650
|
+
Validates the input data according to the defined schema. This method
|
|
1651
|
+
performs comprehensive validation including type checking.
|
|
1652
|
+
|
|
1653
|
+
Args:
|
|
1654
|
+
data (dict): The data dictionary to validate.
|
|
1655
|
+
|
|
1656
|
+
strict (bool, optional): Whether to enforce strict validation rules.
|
|
1657
|
+
Defaults to "True".
|
|
1658
|
+
|
|
1659
|
+
Returns:
|
|
1660
|
+
bool: True if validation passes, False otherwise.
|
|
1661
|
+
|
|
1662
|
+
Raises:
|
|
1663
|
+
ValidationError: If data format is invalid.
|
|
1664
|
+
|
|
1665
|
+
Note:
|
|
1666
|
+
This method modifies the internal validation state.
|
|
1667
|
+
"""
|
|
1668
|
+
return self.validate(data, strict)
|
|
1669
|
+
|
|
1670
|
+
|
|
1671
|
+
|
|
1672
|
+
`);
|
|
1673
|
+
});
|
|
1674
|
+
});
|
|
1675
|
+
//# sourceMappingURL=pydocs.test.js.map
|