2
2
3
3
const path = require ( 'path' )
4
4
5
+ const fsSystem = jest . requireActual ( 'fs-extra' )
5
6
// 存储文件信息,包括文件路径和对应的内容
6
7
const oriFileMap = new Map ( )
7
8
8
9
// 保存转换后的文件
9
10
const resFileMap = new Map ( )
10
11
12
+ /**
13
+ * 输出模拟文件的所有path结构
14
+ */
15
+ const flatteningFile = ( file , path = '' , result = { } ) => {
16
+ for ( const filePath in file ) {
17
+ if ( typeof file [ filePath ] === 'object' && file [ filePath ] !== null ) {
18
+ result [ path + filePath ] = file [ filePath ]
19
+ flatteningFile ( file [ filePath ] , path + filePath , result )
20
+ } else {
21
+ result [ path + filePath ] = file [ filePath ]
22
+ }
23
+ }
24
+ }
25
+
11
26
/**
12
27
* 保存文件信息
13
28
*
14
29
* @param { string } root 工程根目录
15
30
* @param { map } newMockFiles
16
31
*/
17
32
function setMockFiles ( root , newMockFiles ) {
18
- for ( const file in newMockFiles ) {
19
- oriFileMap . set ( normalizePath ( path . join ( root , file ) ) , newMockFiles [ file ] )
33
+ const flatteningFileRes = { }
34
+ flatteningFile ( newMockFiles , '' , flatteningFileRes )
35
+ for ( const file in flatteningFileRes ) {
36
+ oriFileMap . set ( normalizePath ( path . join ( root , file ) ) , flatteningFileRes [ file ] )
20
37
}
38
+ oriFileMap . set ( root , newMockFiles )
21
39
}
22
40
23
41
@@ -36,8 +54,10 @@ function getMockFiles () {
36
54
* @param { map } updateFiles
37
55
*/
38
56
function updateMockFiles ( root , updateFiles ) {
39
- for ( const file in updateFiles ) {
40
- oriFileMap . set ( normalizePath ( path . join ( root , file ) ) , updateFiles [ file ] )
57
+ const flatteningFileRes = { }
58
+ flatteningFile ( updateFiles , '' , flatteningFileRes )
59
+ for ( const file in flatteningFileRes ) {
60
+ oriFileMap . set ( normalizePath ( path . join ( root , file ) ) , flatteningFileRes [ file ] )
41
61
}
42
62
}
43
63
@@ -70,40 +90,55 @@ function deleteMockFiles (key) {
70
90
* @param { 文件路径 } path
71
91
* @returns
72
92
*/
73
- function readFileSyncMock ( path ) {
93
+ function readFileSyncMock ( path , type ) {
74
94
if ( path === undefined || path === null || path === '' ) {
75
95
throw new Error ( `文件路径异常,path:${ path } ` )
76
96
}
77
97
78
98
path = normalizePath ( path )
79
-
99
+
80
100
if ( ! existsSyncMock ( path ) ) {
81
101
throw new Error ( `文件不存在,path:${ path } ` )
82
102
}
103
+ const fileMap = oriFileMap . has ( path ) ? oriFileMap : resFileMap
104
+ const content = fileMap . get ( path )
83
105
84
- return oriFileMap . get ( path )
106
+ return content !== undefined ? content : fsSystem . readFileSync ( path , type )
85
107
}
86
108
87
109
/**
88
110
* 判断文件是否存在
89
111
*
90
112
*/
91
- function existsSyncMock ( path ) {
92
- if ( typeof path !== 'string' || path === '' ) {
113
+ function existsSyncMock ( pathParam ) {
114
+ /**
115
+ * 针对于测试 generateConfigFiles 函数需要,因为 generateConfigFiles 中会查找 taro 子包中的文件
116
+ * jest.requireActual('fs-extra') 操作使用的是真实fs-extra模块,非模拟,所以会查找真实路径
117
+ */
118
+ if ( fsSystem . existsSync ( pathParam ) && path . isAbsolute ( pathParam ) ) return true
119
+
120
+ if ( typeof pathParam !== 'string' || pathParam === '' ) {
93
121
return false
94
122
}
95
123
96
- path = normalizePath ( path )
124
+ pathParam = normalizePath ( pathParam )
97
125
98
- const parts = path . split ( '/' )
126
+ const parts = pathParam . split ( '/' )
99
127
// 根据是否有后缀名判断为文件
100
128
if ( parts [ parts . length - 1 ] . includes ( '.' ) ) {
101
- if ( oriFileMap . get ( path ) === undefined ) {
102
- return false
129
+ let isFile = true
130
+ if ( oriFileMap . get ( pathParam ) === undefined ) {
131
+ isFile = false
132
+ }
133
+ if ( resFileMap . get ( pathParam ) ) {
134
+ isFile = true
103
135
}
136
+ return isFile
137
+ }
138
+ // 判断文件夹
139
+ if ( oriFileMap . get ( pathParam ) && ! parts [ parts . length - 1 ] . includes ( '.' ) ) {
104
140
return true
105
141
}
106
-
107
142
// 文件夹内默认不存在
108
143
return false
109
144
}
@@ -122,7 +157,8 @@ function ensureDirSyncMock () {
122
157
*
123
158
* @returns 默认存在
124
159
*/
125
- function ensureDirMock ( ) {
160
+ function ensureDirMock ( path ) {
161
+ resFileMap . set ( path , '' )
126
162
return true
127
163
}
128
164
@@ -131,7 +167,9 @@ function ensureDirMock () {
131
167
*
132
168
* @returns
133
169
*/
134
- function mkdirSyncMock ( ) {
170
+ function mkdirSyncMock ( path ) {
171
+ path = normalizePath ( path )
172
+ resFileMap . set ( path , '' )
135
173
return true
136
174
}
137
175
@@ -148,11 +186,11 @@ function appendFileMock (path, appendContent) {
148
186
}
149
187
150
188
path = normalizePath ( path )
151
- if ( oriFileMap . get ( path ) ) {
152
- const newContent = oriFileMap . get ( path ) + appendContent
153
- oriFileMap . set ( path , newContent )
189
+ if ( resFileMap . get ( path ) ) {
190
+ const newContent = resFileMap . get ( path ) + appendContent
191
+ resFileMap . set ( path , newContent )
154
192
}
155
- oriFileMap . set ( path , appendContent )
193
+ resFileMap . set ( path , appendContent )
156
194
}
157
195
158
196
/**
@@ -169,6 +207,8 @@ function writeFileSyncMock (path, data) {
169
207
170
208
path = normalizePath ( path )
171
209
210
+ data = Buffer . isBuffer ( data ) ? Buffer . from ( data ) . toString ( 'utf8' ) : data
211
+
172
212
resFileMap . set ( path , data )
173
213
}
174
214
@@ -228,7 +268,7 @@ function isDir (path) {
228
268
}
229
269
230
270
/**
231
- * 获取状态
271
+ * 获取文件或目录状态,在处理路径为符号链接时返回链接指向的文件或目录的状态
232
272
*/
233
273
function statSyncMock ( path ) {
234
274
if ( typeof path !== 'string' || path === '' ) {
@@ -243,14 +283,64 @@ function statSyncMock (path) {
243
283
}
244
284
}
245
285
286
+ /**
287
+ * 获取文件或目录状态,在处理路径为符号链接时返回链接自身的文件或目录的状态
288
+ */
289
+ function lstatSyncMock ( path ) {
290
+ if ( typeof path !== 'string' || path === '' ) {
291
+ return
292
+ }
293
+
294
+ path = normalizePath ( path )
295
+ // 返回包含状态信息的对象
296
+ return {
297
+ isFile : ( ) => customIsFile ( path ) ,
298
+ isDirectory : ( ) => customIsDirectory ( path ) ,
299
+ isSymbolicLink : ( ) => false
300
+ }
301
+ }
302
+
303
+ /**
304
+ * 读取文件夹下的内容
305
+ */
306
+ function readdirSyncMock ( source ) {
307
+ source = normalizePath ( source )
308
+ const parts = source . split ( '/' )
309
+ if ( oriFileMap . get ( source ) && ! parts [ parts . length - 1 ] . includes ( '.' ) ) {
310
+ const fileName = [ ]
311
+ Object . keys ( oriFileMap . get ( source ) ) . forEach ( ( item ) => {
312
+ fileName . push ( item )
313
+ } )
314
+ return fileName
315
+ } else {
316
+ return fsSystem . readdirSync ( source )
317
+ }
318
+ }
319
+
320
+ /**
321
+ * 文件复制
322
+ */
323
+ function copyFileSyncMock ( sourcePath , destinationPath ) {
324
+ resFileMap . set ( destinationPath , oriFileMap . get ( sourcePath ) )
325
+ }
326
+
327
+ function copyFileMock ( sourcePath , destinationPath ) {
328
+ resFileMap . set ( destinationPath , oriFileMap . get ( sourcePath ) )
329
+ }
330
+
246
331
// 自定义的 isFile 函数
247
332
function customIsFile ( path ) {
248
- return oriFileMap . get ( path )
333
+ let isFileRes = false
334
+ const fileMap = oriFileMap . has ( path ) ? oriFileMap : resFileMap
335
+ if ( fileMap . has ( path ) ) {
336
+ isFileRes = typeof fileMap . get ( path ) === 'string'
337
+ }
338
+ return isFileRes
249
339
}
250
340
251
341
// 自定义的 isDirectory 函数
252
342
function customIsDirectory ( path ) {
253
- if ( typeof path !== 'string' || path === '' ) {
343
+ if ( typeof path === 'string' && path . includes ( '.' ) && path . indexOf ( '.' ) !== 0 ) {
254
344
return false
255
345
}
256
346
return true
@@ -267,21 +357,28 @@ function normalizePath (path) {
267
357
}
268
358
269
359
module . exports = {
270
- ...jest . requireActual ( 'fs-extra' ) ,
271
- readFileSync : jest . fn ( ( content ) => readFileSyncMock ( content ) ) ,
360
+ ...fsSystem ,
361
+ readFileSync : jest . fn ( ( content , type ) => readFileSyncMock ( content , type ) ) ,
272
362
existsSync : jest . fn ( ( path ) => existsSyncMock ( path ) ) ,
273
363
ensureDirSync : jest . fn ( ( ) => ensureDirSyncMock ( ) ) ,
274
364
ensureDir : jest . fn ( ( ) => ensureDirMock ( ) ) ,
275
- mkdirSync : jest . fn ( ( ) => mkdirSyncMock ( ) ) ,
365
+ mkdirSync : jest . fn ( ( path ) => mkdirSyncMock ( path ) ) ,
276
366
appendFile : jest . fn ( ( path , appendContent ) => appendFileMock ( path , appendContent ) ) ,
277
367
writeFileSync : jest . fn ( ( path , data ) => writeFileSyncMock ( path , data ) ) ,
278
368
copySync : jest . fn ( ( from , to ) => copySyncMock ( from , to ) ) ,
279
369
statSync : jest . fn ( ( path ) => statSyncMock ( path ) ) ,
370
+ lstatSync : jest . fn ( ( path ) => lstatSyncMock ( path ) ) ,
371
+ readdirSync :jest . fn ( ( source ) => readdirSyncMock ( source ) ) ,
372
+ copyFileSync :jest . fn ( ( sourcePath , destinationPath ) => copyFileSyncMock ( sourcePath , destinationPath ) ) ,
373
+ copyFile :jest . fn ( ( sourcePath , destinationPath ) => copyFileMock ( sourcePath , destinationPath ) ) ,
374
+ writeJSONSync :jest . fn ( ( ) => true )
280
375
}
281
376
282
377
module . exports . setMockFiles = setMockFiles
283
378
module . exports . getMockFiles = getMockFiles
284
379
module . exports . clearMockFiles = clearMockFiles
285
380
module . exports . getResMapFile = getResMapFile
286
381
module . exports . updateMockFiles = updateMockFiles
287
- module . exports . deleteMockFiles = deleteMockFiles
382
+ module . exports . deleteMockFiles = deleteMockFiles
383
+ module . exports . resFileMap = resFileMap
384
+ module . exports . normalizePath = normalizePath
0 commit comments