fork of hey-api/openapi-ts because I need some additional things
1import { moduleSortKey } from '../render-utils';
2
3const createFile = (finalPath: string, external = false) => {
4 const parts = finalPath.split('/');
5 const filename = parts.at(-1)!;
6 const dotIndex = filename.lastIndexOf('.');
7 return {
8 extension: dotIndex > 0 ? filename.slice(dotIndex) : undefined,
9 external,
10 finalPath,
11 name: dotIndex > 0 ? filename.slice(0, dotIndex) : filename,
12 };
13};
14
15const root = '/project/src';
16
17describe('moduleSortKey', () => {
18 describe('external imports (group 0)', () => {
19 it('returns external module path unchanged', () => {
20 const file = createFile('/project/src/client.py');
21 const fromFile = createFile('httpx', true);
22
23 const [group, distance, modulePath] = moduleSortKey({
24 file,
25 fromFile,
26 preferFileExtension: '.py',
27 root,
28 });
29
30 expect(group).toBe(0);
31 expect(distance).toBe(0);
32 expect(modulePath).toBe('httpx');
33 });
34 });
35
36 describe('local imports (group 2)', () => {
37 describe('same directory', () => {
38 it('converts sibling file to relative import', () => {
39 const file = createFile('/project/src/api/client.py');
40 const fromFile = createFile('/project/src/api/types.py');
41
42 const [group, distance, modulePath] = moduleSortKey({
43 file,
44 fromFile,
45 preferFileExtension: '.py',
46 root,
47 });
48
49 expect(group).toBe(2);
50 expect(distance).toBe(0);
51 expect(modulePath).toBe('.types');
52 });
53
54 it('handles index.py as implicit module', () => {
55 const file = createFile('/project/src/api/client.py');
56 const fromFile = createFile('/project/src/api/index.py');
57
58 const [, , modulePath] = moduleSortKey({
59 file,
60 fromFile,
61 preferFileExtension: '.py',
62 root,
63 });
64
65 expect(modulePath).toBe('.');
66 });
67
68 it('handles __init__.py as implicit module', () => {
69 const file = createFile('/project/src/api/client.py');
70 const fromFile = createFile('/project/src/api/__init__.py');
71
72 const [, , modulePath] = moduleSortKey({
73 file,
74 fromFile,
75 preferFileExtension: '.py',
76 root,
77 });
78
79 expect(modulePath).toBe('.');
80 });
81 });
82
83 describe('child directory', () => {
84 it('converts nested path to dotted module', () => {
85 const file = createFile('/project/src/client.py');
86 const fromFile = createFile('/project/src/models/user.py');
87
88 const [group, distance, modulePath] = moduleSortKey({
89 file,
90 fromFile,
91 preferFileExtension: '.py',
92 root,
93 });
94
95 expect(group).toBe(2);
96 expect(distance).toBe(0);
97 expect(modulePath).toBe('.models.user');
98 });
99
100 it('handles deeply nested paths', () => {
101 const file = createFile('/project/src/client.py');
102 const fromFile = createFile('/project/src/api/v1/endpoints/users.py');
103
104 const [, , modulePath] = moduleSortKey({
105 file,
106 fromFile,
107 preferFileExtension: '.py',
108 root,
109 });
110
111 expect(modulePath).toBe('.api.v1.endpoints.users');
112 });
113
114 it('handles index.py in child directory', () => {
115 const file = createFile('/project/src/client.py');
116 const fromFile = createFile('/project/src/models/index.py');
117
118 const [, , modulePath] = moduleSortKey({
119 file,
120 fromFile,
121 preferFileExtension: '.py',
122 root,
123 });
124
125 expect(modulePath).toBe('.models');
126 });
127 });
128
129 describe('parent directory', () => {
130 it('converts single parent traversal', () => {
131 const file = createFile('/project/src/api/client.py');
132 const fromFile = createFile('/project/src/types.py');
133
134 const [group, distance, modulePath] = moduleSortKey({
135 file,
136 fromFile,
137 preferFileExtension: '.py',
138 root,
139 });
140
141 expect(group).toBe(2);
142 expect(distance).toBe(1);
143 expect(modulePath).toBe('..types');
144 });
145
146 it('converts double parent traversal', () => {
147 const file = createFile('/project/src/api/v1/client.py');
148 const fromFile = createFile('/project/src/types.py');
149
150 const [, distance, modulePath] = moduleSortKey({
151 file,
152 fromFile,
153 preferFileExtension: '.py',
154 root,
155 });
156
157 expect(distance).toBe(2);
158 expect(modulePath).toBe('...types');
159 });
160
161 it('handles index.py in parent directory', () => {
162 const file = createFile('/project/src/api/client.py');
163 const fromFile = createFile('/project/src/index.py');
164
165 const [, , modulePath] = moduleSortKey({
166 file,
167 fromFile,
168 preferFileExtension: '.py',
169 root,
170 });
171
172 expect(modulePath).toBe('..');
173 });
174 });
175
176 describe('sibling directory', () => {
177 it('converts sibling directory path', () => {
178 const file = createFile('/project/src/api/client.py');
179 const fromFile = createFile('/project/src/models/user.py');
180
181 const [, distance, modulePath] = moduleSortKey({
182 file,
183 fromFile,
184 preferFileExtension: '.py',
185 root,
186 });
187
188 expect(distance).toBe(1);
189 expect(modulePath).toBe('..models.user');
190 });
191
192 it('handles index.py in sibling directory', () => {
193 const file = createFile('/project/src/api/client.py');
194 const fromFile = createFile('/project/src/models/index.py');
195
196 const [, , modulePath] = moduleSortKey({
197 file,
198 fromFile,
199 preferFileExtension: '.py',
200 root,
201 });
202
203 expect(modulePath).toBe('..models');
204 });
205 });
206 });
207});