-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathdicts.test.ts
More file actions
140 lines (127 loc) · 3.52 KB
/
Copy pathdicts.test.ts
File metadata and controls
140 lines (127 loc) · 3.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import { transpileString } from "./utils";
describe("transpiling dictionaries types", () => {
it("can transpile dicts", async () => {
const result = await transpileString(`export type A = {
foo: string,
bar: number,
}`);
expect(result).toContain(`class A(TypedDict):\n foo: str\n bar: float`);
});
it("keeps docstrings", async () => {
const result = await transpileString(`
/** This is A */
export type A = {
/** this is foo */
foo: string,
/** this is bar */
bar: number,
}
`);
expect(result).toContain(
`class A(TypedDict):
"""
This is A
"""
foo: str
"""
this is foo
"""
bar: float
"""
this is bar
"""`,
);
});
it("can transpile nested dicts", async () => {
const result = await transpileString(`export type A = {
outer: {
inner: string
},
extra: number,
}`);
expect(result).toContain(
`class Ts2Py_FOZhdT9ykh(TypedDict):
inner: str
class A(TypedDict):
outer: Ts2Py_FOZhdT9ykh
extra: float`,
);
});
it("can transpile intersections", async () => {
const result = await transpileString(
`export type A = { foo: string } & { bar: number }`,
);
expect(result).toContain(`class A(TypedDict):\n foo: str\n bar: float`);
});
it("transpiles optional values as NotRequired[T]", async () => {
const result = await transpileString(`export type A = { foo?: string }`);
expect(result).toContain(`class A(TypedDict):\n foo: NotRequired[str]`);
});
it("transpiles optional values as NotRequired[T] in strict mode", async () => {
const result = await transpileString(
`export type A = { foo?: string }`,
{},
{ strict: true },
);
expect(result).toContain(`class A(TypedDict):\n foo: NotRequired[str]`);
});
it("transpiles optional values with non-null optionals as NotRequired[Optional[T]]", async () => {
const result = await transpileString(`export type A = { foo?: string }`, {
nullableOptionals: true,
});
expect(result).toContain(
`class A(TypedDict):\n foo: NotRequired[Optional[str]]`,
);
});
it("transpiles records as dicts", async () => {
const result = await transpileString(
`export type A = Record<"foo" | "bar", number>`,
);
expect(result).toContain(`class A(TypedDict):\n foo: float\n bar: float`);
});
it("falls back to the functional syntax if keys are unsupported", async () => {
const result = await transpileString(`export type A = {
"foo.bar"?: string,
}`);
expect(result).toEqual(
`from typing_extensions import NotRequired, TypedDict
A = TypedDict("A", {
"foo.bar": NotRequired[str]
})`,
);
});
it("ignores empty string property names in functional dicts", async () => {
const result = await transpileString(`export type A = {
"": string,
"foo.bar"?: string,
}`);
expect(result).toContain(
`A = TypedDict("A", {
"foo.bar": NotRequired[str]
})`,
);
});
it("moves the key/value docstrings to the object docstring in the functional syntax", async () => {
const result = await transpileString(`
/** This is A */
export type A = {
/** this is foo.bar */
"foo.bar": string,
/** this is a/b */
"a/b": number,
"undocumented": string,
}
`);
expect(result).toContain(`A = TypedDict("A", {
"foo.bar": str,
"a/b": float,
"undocumented": str
})
"""
This is A
## Entries
"foo.bar": this is foo.bar
"a/b": this is a/b
"""`);
});
});