ftmocks-utils 1.2.5 → 1.3.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.
- package/package.json +1 -1
- package/src/common-utils.js +20 -42
- package/src/index.js +40 -21
- package/src/json-utils.js +55 -0
package/package.json
CHANGED
package/src/common-utils.js
CHANGED
|
@@ -1,21 +1,31 @@
|
|
|
1
1
|
const path = require("path");
|
|
2
2
|
const fs = require("fs");
|
|
3
|
+
const { FtJSON } = require("./json-utils");
|
|
3
4
|
|
|
4
5
|
const charDifference = (str1, str2) => {
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
if (str1 && str2) {
|
|
7
|
+
let count1 = {};
|
|
8
|
+
let count2 = {};
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
for (let ch of str1) count1[ch] = (count1[ch] || 0) + 1;
|
|
11
|
+
for (let ch of str2) count2[ch] = (count2[ch] || 0) + 1;
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
let diff = 0;
|
|
14
|
+
let chars = new Set([...Object.keys(count1), ...Object.keys(count2)]);
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
for (let ch of chars) {
|
|
17
|
+
diff += Math.abs((count1[ch] || 0) - (count2[ch] || 0));
|
|
18
|
+
}
|
|
17
19
|
|
|
18
|
-
|
|
20
|
+
return diff;
|
|
21
|
+
} else {
|
|
22
|
+
if (!str1 && str2) {
|
|
23
|
+
return str2.length;
|
|
24
|
+
} else if (str1 && !str2) {
|
|
25
|
+
return str1.length;
|
|
26
|
+
}
|
|
27
|
+
return 0;
|
|
28
|
+
}
|
|
19
29
|
};
|
|
20
30
|
|
|
21
31
|
const nameToFolder = (name) => {
|
|
@@ -52,37 +62,6 @@ const capitalizeHeaders = (headers) => {
|
|
|
52
62
|
);
|
|
53
63
|
};
|
|
54
64
|
|
|
55
|
-
const areJsonEqual = (jsonObj1, jsonObj2) => {
|
|
56
|
-
// Check if both are objects and not null
|
|
57
|
-
if (
|
|
58
|
-
typeof jsonObj1 === "object" &&
|
|
59
|
-
jsonObj1 !== null &&
|
|
60
|
-
typeof jsonObj2 === "object" &&
|
|
61
|
-
jsonObj2 !== null
|
|
62
|
-
) {
|
|
63
|
-
// Get the keys of both objects
|
|
64
|
-
const keys1 = Object.keys(jsonObj1);
|
|
65
|
-
const keys2 = Object.keys(jsonObj2);
|
|
66
|
-
|
|
67
|
-
// Check if the number of keys is different
|
|
68
|
-
if (keys1.length !== keys2.length) {
|
|
69
|
-
return false;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Recursively check each key-value pair
|
|
73
|
-
for (let key of keys1) {
|
|
74
|
-
if (!keys2.includes(key) || !areJsonEqual(jsonObj1[key], jsonObj2[key])) {
|
|
75
|
-
return false;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
return true;
|
|
80
|
-
} else {
|
|
81
|
-
// For non-object types, use strict equality comparison
|
|
82
|
-
return jsonObj1 === jsonObj2;
|
|
83
|
-
}
|
|
84
|
-
};
|
|
85
|
-
|
|
86
65
|
const clearNulls = (postData) => {
|
|
87
66
|
Object.keys(postData || {}).forEach((key) => {
|
|
88
67
|
if (postData[key] === null) {
|
|
@@ -162,7 +141,6 @@ module.exports = {
|
|
|
162
141
|
getFallbackDir,
|
|
163
142
|
capitalizeHeader,
|
|
164
143
|
capitalizeHeaders,
|
|
165
|
-
areJsonEqual,
|
|
166
144
|
clearNulls,
|
|
167
145
|
processURL,
|
|
168
146
|
getHeaders,
|
package/src/index.js
CHANGED
|
@@ -6,16 +6,20 @@ const {
|
|
|
6
6
|
nameToFolder,
|
|
7
7
|
getMockDir,
|
|
8
8
|
getFallbackDir,
|
|
9
|
-
areJsonEqual,
|
|
10
9
|
clearNulls,
|
|
11
10
|
processURL,
|
|
12
11
|
getHeaders,
|
|
13
12
|
countFilesInDirectory,
|
|
14
13
|
getTestByName,
|
|
15
14
|
} = require("./common-utils");
|
|
15
|
+
const { FtJSON } = require("./json-utils");
|
|
16
16
|
|
|
17
17
|
const getDefaultMockDataFromConfig = (testConfig) => {
|
|
18
|
-
const defaultPath = path.join(
|
|
18
|
+
const defaultPath = path.join(
|
|
19
|
+
getMockDir(testConfig),
|
|
20
|
+
"defaultMocks",
|
|
21
|
+
"_mock_list.json"
|
|
22
|
+
);
|
|
19
23
|
|
|
20
24
|
try {
|
|
21
25
|
const defaultData = fs.readFileSync(defaultPath, "utf8");
|
|
@@ -38,7 +42,7 @@ const getDefaultMockDataFromConfig = (testConfig) => {
|
|
|
38
42
|
});
|
|
39
43
|
return parsedData;
|
|
40
44
|
} catch (error) {
|
|
41
|
-
console.error(`Error reading or parsing default
|
|
45
|
+
console.error(`Error reading or parsing default mocks:`, error);
|
|
42
46
|
return [];
|
|
43
47
|
}
|
|
44
48
|
};
|
|
@@ -99,11 +103,11 @@ const isSameRequest = (req1, req2) => {
|
|
|
99
103
|
(!req1.postData && req2.postData) ||
|
|
100
104
|
(req1.postData && !req2.postData)
|
|
101
105
|
) {
|
|
102
|
-
matched = areJsonEqual(req1.postData || {}, req2.postData || {});
|
|
106
|
+
matched = FtJSON.areJsonEqual(req1.postData || {}, req2.postData || {});
|
|
103
107
|
} else if (
|
|
104
108
|
req1.postData &&
|
|
105
109
|
req2.postData &&
|
|
106
|
-
!areJsonEqual(req1.postData, req2.postData)
|
|
110
|
+
!FtJSON.areJsonEqual(req1.postData, req2.postData)
|
|
107
111
|
) {
|
|
108
112
|
matched = false;
|
|
109
113
|
}
|
|
@@ -127,8 +131,8 @@ const getSameRequestRank = (req1, req2) => {
|
|
|
127
131
|
rank = rank + queryDiff;
|
|
128
132
|
// Compare post data
|
|
129
133
|
const charDiff = charDifference(
|
|
130
|
-
|
|
131
|
-
|
|
134
|
+
FtJSON.stringify(req1.postData || {}),
|
|
135
|
+
FtJSON.stringify(req2.postData || {})
|
|
132
136
|
);
|
|
133
137
|
rank = rank + charDiff;
|
|
134
138
|
}
|
|
@@ -142,7 +146,7 @@ function compareMockToRequest(mock, req) {
|
|
|
142
146
|
);
|
|
143
147
|
const reqURL = processURL(req.originalUrl, mock.fileContent.ignoreParams);
|
|
144
148
|
const postData = mock.fileContent.request?.postData?.text
|
|
145
|
-
?
|
|
149
|
+
? FtJSON.parse(mock.fileContent.request?.postData?.text)
|
|
146
150
|
: mock.fileContent.request?.postData;
|
|
147
151
|
return isSameRequest(
|
|
148
152
|
{ url: mockURL, method: mock.fileContent.method, postData },
|
|
@@ -162,14 +166,14 @@ function compareMockToFetchRequest(mock, fetchReq) {
|
|
|
162
166
|
);
|
|
163
167
|
const reqURL = processURL(fetchReq.url, mock.fileContent.ignoreParams);
|
|
164
168
|
const postData = mock.fileContent.request?.postData?.text
|
|
165
|
-
?
|
|
169
|
+
? FtJSON.parse(mock.fileContent.request?.postData?.text)
|
|
166
170
|
: mock.fileContent.request?.postData;
|
|
167
171
|
return isSameRequest(
|
|
168
172
|
{ url: mockURL, method: mock.fileContent.method, postData },
|
|
169
173
|
{
|
|
170
174
|
method: fetchReq.options.method || "GET",
|
|
171
175
|
postData: fetchReq.options.body?.length
|
|
172
|
-
?
|
|
176
|
+
? FtJSON.parse(fetchReq.options.body)
|
|
173
177
|
: fetchReq.options.body,
|
|
174
178
|
url: reqURL,
|
|
175
179
|
}
|
|
@@ -189,14 +193,14 @@ function getCompareRankMockToFetchRequest(mock, fetchReq) {
|
|
|
189
193
|
);
|
|
190
194
|
const reqURL = processURL(fetchReq.url, mock.fileContent.ignoreParams);
|
|
191
195
|
const postData = mock.fileContent.request?.postData?.text
|
|
192
|
-
?
|
|
196
|
+
? FtJSON.parse(mock.fileContent.request?.postData?.text)
|
|
193
197
|
: mock.fileContent.request?.postData;
|
|
194
198
|
return getSameRequestRank(
|
|
195
199
|
{ url: mockURL, method: mock.fileContent.method, postData },
|
|
196
200
|
{
|
|
197
201
|
method: fetchReq.options.method || "GET",
|
|
198
202
|
postData: fetchReq.options.body?.length
|
|
199
|
-
?
|
|
203
|
+
? FtJSON.parse(fetchReq.options.body)
|
|
200
204
|
: fetchReq.options.body,
|
|
201
205
|
url: reqURL,
|
|
202
206
|
}
|
|
@@ -272,11 +276,18 @@ function getMatchingMockData({
|
|
|
272
276
|
}
|
|
273
277
|
// updating stats to mock file
|
|
274
278
|
if (foundMock) {
|
|
275
|
-
|
|
279
|
+
let mockFilePath = path.join(
|
|
276
280
|
getMockDir(testConfig),
|
|
277
281
|
`test_${nameToFolder(testName)}`,
|
|
278
282
|
`mock_${foundMock.id}.json`
|
|
279
283
|
);
|
|
284
|
+
if (!fs.existsSync(mockFilePath)) {
|
|
285
|
+
mockFilePath = path.join(
|
|
286
|
+
getMockDir(testConfig),
|
|
287
|
+
"defaultMocks",
|
|
288
|
+
`mock_${foundMock.id}.json`
|
|
289
|
+
);
|
|
290
|
+
}
|
|
280
291
|
foundMock.fileContent.served = true;
|
|
281
292
|
fs.writeFileSync(
|
|
282
293
|
mockFilePath,
|
|
@@ -351,12 +362,20 @@ async function initiatePlaywrightRoutes(
|
|
|
351
362
|
};
|
|
352
363
|
|
|
353
364
|
if (file) {
|
|
354
|
-
|
|
365
|
+
let filePath = path.join(
|
|
355
366
|
getMockDir(ftmocksConifg),
|
|
356
367
|
`test_${nameToFolder(testName)}`,
|
|
357
368
|
"_files",
|
|
358
369
|
file
|
|
359
370
|
);
|
|
371
|
+
if (!fs.existsSync(filePath)) {
|
|
372
|
+
filePath = path.join(
|
|
373
|
+
getMockDir(ftmocksConifg),
|
|
374
|
+
"defaultMocks",
|
|
375
|
+
"_files",
|
|
376
|
+
file
|
|
377
|
+
);
|
|
378
|
+
}
|
|
360
379
|
if (fs.existsSync(filePath) && fs.lstatSync(filePath).isFile()) {
|
|
361
380
|
const fileContent = fs.readFileSync(filePath);
|
|
362
381
|
json.body = fileContent;
|
|
@@ -511,7 +530,7 @@ async function initiateJestFetch(jest, ftmocksConifg, testName) {
|
|
|
511
530
|
return Promise.resolve({
|
|
512
531
|
status,
|
|
513
532
|
headers: new Map(Object.entries(headers)),
|
|
514
|
-
json: () => Promise.resolve(
|
|
533
|
+
json: () => Promise.resolve(FtJSON.parse(content)),
|
|
515
534
|
});
|
|
516
535
|
});
|
|
517
536
|
|
|
@@ -748,17 +767,17 @@ const isSameResponse = (req1, req2) => {
|
|
|
748
767
|
(!req1.response.content && req2.response.content) ||
|
|
749
768
|
(req1.response.content && !req2.response.content)
|
|
750
769
|
) {
|
|
751
|
-
matched = areJsonEqual(
|
|
752
|
-
|
|
753
|
-
|
|
770
|
+
matched = FtJSON.areJsonEqual(
|
|
771
|
+
FtJSON.parse(req1.response.content) || {},
|
|
772
|
+
FtJSON.parse(req2.response.content) || {}
|
|
754
773
|
);
|
|
755
774
|
// console.log('not matched at post Data 0', req1.postData, req2.postData);
|
|
756
775
|
} else if (
|
|
757
776
|
req1.response.content &&
|
|
758
777
|
req2.response.content &&
|
|
759
|
-
!areJsonEqual(
|
|
760
|
-
|
|
761
|
-
|
|
778
|
+
!FtJSON.areJsonEqual(
|
|
779
|
+
FtJSON.parse(req1.response.content) || {},
|
|
780
|
+
FtJSON.parse(req2.response.content) || {}
|
|
762
781
|
)
|
|
763
782
|
) {
|
|
764
783
|
matched = false;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
class FtJSON {
|
|
2
|
+
static parse(text, reviver, reference) {
|
|
3
|
+
try {
|
|
4
|
+
return JSON.parse(text, reviver);
|
|
5
|
+
} catch (error) {
|
|
6
|
+
console.error("FtJSON parse error:", error, reference);
|
|
7
|
+
return text;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
static stringify(value, replacer, space, reference) {
|
|
12
|
+
try {
|
|
13
|
+
return JSON.stringify(value, replacer, space);
|
|
14
|
+
} catch (error) {
|
|
15
|
+
console.error("FtJSON stringify error:", error, reference);
|
|
16
|
+
return value;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
static areJsonEqual(jsonObj1, jsonObj2) {
|
|
21
|
+
// Check if both are objects and not null
|
|
22
|
+
if (
|
|
23
|
+
typeof jsonObj1 === "object" &&
|
|
24
|
+
jsonObj1 !== null &&
|
|
25
|
+
typeof jsonObj2 === "object" &&
|
|
26
|
+
jsonObj2 !== null
|
|
27
|
+
) {
|
|
28
|
+
// Get the keys of both objects
|
|
29
|
+
const keys1 = Object.keys(jsonObj1);
|
|
30
|
+
const keys2 = Object.keys(jsonObj2);
|
|
31
|
+
|
|
32
|
+
// Check if the number of keys is different
|
|
33
|
+
if (keys1.length !== keys2.length) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Recursively check each key-value pair
|
|
38
|
+
for (let key of keys1) {
|
|
39
|
+
if (
|
|
40
|
+
!keys2.includes(key) ||
|
|
41
|
+
!FtJSON.areJsonEqual(jsonObj1[key], jsonObj2[key])
|
|
42
|
+
) {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return true;
|
|
48
|
+
} else {
|
|
49
|
+
// For non-object types, use strict equality comparison
|
|
50
|
+
return jsonObj1 === jsonObj2;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
module.exports = { FtJSON };
|