ftmocks-utils 1.2.4 → 1.2.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/package.json +1 -1
- package/src/common-utils.js +171 -0
- package/src/index.js +12 -154
package/package.json
CHANGED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
const path = require("path");
|
|
2
|
+
const fs = require("fs");
|
|
3
|
+
|
|
4
|
+
const charDifference = (str1, str2) => {
|
|
5
|
+
let count1 = {},
|
|
6
|
+
count2 = {};
|
|
7
|
+
|
|
8
|
+
for (let ch of str1) count1[ch] = (count1[ch] || 0) + 1;
|
|
9
|
+
for (let ch of str2) count2[ch] = (count2[ch] || 0) + 1;
|
|
10
|
+
|
|
11
|
+
let diff = 0;
|
|
12
|
+
let chars = new Set([...Object.keys(count1), ...Object.keys(count2)]);
|
|
13
|
+
|
|
14
|
+
for (let ch of chars) {
|
|
15
|
+
diff += Math.abs((count1[ch] || 0) - (count2[ch] || 0));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return diff;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const nameToFolder = (name) => {
|
|
22
|
+
return name.replaceAll(" ", "_");
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const getMockDir = (config) => {
|
|
26
|
+
if (!path.isAbsolute(config.MOCK_DIR)) {
|
|
27
|
+
return path.resolve(process.cwd(), config.MOCK_DIR);
|
|
28
|
+
}
|
|
29
|
+
return config.MOCK_DIR;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const getFallbackDir = (config) => {
|
|
33
|
+
if (config.FALLBACK_DIR && !path.isAbsolute(config.FALLBACK_DIR)) {
|
|
34
|
+
return path.resolve(process.cwd(), config.FALLBACK_DIR);
|
|
35
|
+
}
|
|
36
|
+
return config.FALLBACK_DIR;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const capitalizeHeader = (header) => {
|
|
40
|
+
return header
|
|
41
|
+
.split("-")
|
|
42
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
|
43
|
+
.join("-");
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const capitalizeHeaders = (headers) => {
|
|
47
|
+
return Object.fromEntries(
|
|
48
|
+
Object.entries(headers).map(([key, value]) => [
|
|
49
|
+
capitalizeHeader(key),
|
|
50
|
+
value,
|
|
51
|
+
])
|
|
52
|
+
);
|
|
53
|
+
};
|
|
54
|
+
|
|
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
|
+
const clearNulls = (postData) => {
|
|
87
|
+
Object.keys(postData || {}).forEach((key) => {
|
|
88
|
+
if (postData[key] === null) {
|
|
89
|
+
delete postData[key];
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const processURL = (url, ignoreParams = []) => {
|
|
95
|
+
// Remove the hostname from the URL
|
|
96
|
+
const urlWithoutHost = url.replace(/^(https?:\/\/)?[^\/]+/, "");
|
|
97
|
+
const processedURL = new URL(`http://domain.com${urlWithoutHost}`);
|
|
98
|
+
const params = new URLSearchParams(processedURL.search);
|
|
99
|
+
if (ignoreParams?.length > 0) {
|
|
100
|
+
ignoreParams.forEach((ip) => {
|
|
101
|
+
params.delete(ip);
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
params.sort();
|
|
105
|
+
return decodeURIComponent(`${processedURL.pathname}?${params}`);
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
const getHeaders = (headers) => {
|
|
109
|
+
let res = null;
|
|
110
|
+
try {
|
|
111
|
+
res = new Map([
|
|
112
|
+
...Object.entries(headers),
|
|
113
|
+
...Object.entries(capitalizeHeaders(headers)),
|
|
114
|
+
]);
|
|
115
|
+
} catch (e) {
|
|
116
|
+
console.error("error at getHeaders", e);
|
|
117
|
+
res = new Map([
|
|
118
|
+
["Content-Type", "application/json"],
|
|
119
|
+
["content-type", "application/json"],
|
|
120
|
+
]);
|
|
121
|
+
}
|
|
122
|
+
return Object.fromEntries(res);
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
function countFilesInDirectory(directoryPath) {
|
|
126
|
+
return new Promise((resolve, reject) => {
|
|
127
|
+
fs.readdir(directoryPath, (err, files) => {
|
|
128
|
+
if (err) {
|
|
129
|
+
return reject(err); // Handle error
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Filter out directories and only count files
|
|
133
|
+
const fileCount = files.filter((file) => {
|
|
134
|
+
const filePath = path.join(directoryPath, file);
|
|
135
|
+
return fs.statSync(filePath).isFile();
|
|
136
|
+
}).length;
|
|
137
|
+
|
|
138
|
+
resolve(fileCount);
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const getTestByName = async (ftmocksConifg, testName) => {
|
|
144
|
+
const testsPath = path.join(getMockDir(ftmocksConifg), "tests.json");
|
|
145
|
+
let tests = [];
|
|
146
|
+
try {
|
|
147
|
+
// Read existing tests
|
|
148
|
+
const testsData = fs.readFileSync(testsPath, "utf8");
|
|
149
|
+
tests = JSON.parse(testsData);
|
|
150
|
+
const etest = tests.find((tst) => tst.name === testName);
|
|
151
|
+
return etest;
|
|
152
|
+
} catch (error) {
|
|
153
|
+
console.error(`\x1b[31mError reading tests.json:\x1b[0m`, error);
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
module.exports = {
|
|
159
|
+
charDifference,
|
|
160
|
+
nameToFolder,
|
|
161
|
+
getMockDir,
|
|
162
|
+
getFallbackDir,
|
|
163
|
+
capitalizeHeader,
|
|
164
|
+
capitalizeHeaders,
|
|
165
|
+
areJsonEqual,
|
|
166
|
+
clearNulls,
|
|
167
|
+
processURL,
|
|
168
|
+
getHeaders,
|
|
169
|
+
countFilesInDirectory,
|
|
170
|
+
getTestByName,
|
|
171
|
+
};
|
package/src/index.js
CHANGED
|
@@ -1,105 +1,18 @@
|
|
|
1
1
|
const fs = require("fs");
|
|
2
2
|
const path = require("path");
|
|
3
3
|
const { v4: uuidv4 } = require("uuid");
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
diff += Math.abs((count1[ch] || 0) - (count2[ch] || 0));
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
return diff;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const nameToFolder = (name) => {
|
|
23
|
-
return name.replaceAll(" ", "_");
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
const getMockDir = (config) => {
|
|
27
|
-
if (!path.isAbsolute(config.MOCK_DIR)) {
|
|
28
|
-
return path.resolve(process.cwd(), config.MOCK_DIR);
|
|
29
|
-
}
|
|
30
|
-
return config.MOCK_DIR;
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
const getFallbackDir = (config) => {
|
|
34
|
-
if (config.FALLBACK_DIR && !path.isAbsolute(config.FALLBACK_DIR)) {
|
|
35
|
-
return path.resolve(process.cwd(), config.FALLBACK_DIR);
|
|
36
|
-
}
|
|
37
|
-
return config.FALLBACK_DIR;
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
const capitalizeHeader = (header) => {
|
|
41
|
-
return header
|
|
42
|
-
.split("-")
|
|
43
|
-
.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
|
44
|
-
.join("-");
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
const capitalizeHeaders = (headers) => {
|
|
48
|
-
return Object.fromEntries(
|
|
49
|
-
Object.entries(headers).map(([key, value]) => [
|
|
50
|
-
capitalizeHeader(key),
|
|
51
|
-
value,
|
|
52
|
-
])
|
|
53
|
-
);
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
const getHeaders = (headers) => {
|
|
57
|
-
let res = null;
|
|
58
|
-
try {
|
|
59
|
-
res = new Map([
|
|
60
|
-
...Object.entries(headers),
|
|
61
|
-
...Object.entries(capitalizeHeaders(headers)),
|
|
62
|
-
]);
|
|
63
|
-
} catch (e) {
|
|
64
|
-
console.error("error at getHeaders", e);
|
|
65
|
-
res = new Map([
|
|
66
|
-
["Content-Type", "application/json"],
|
|
67
|
-
["content-type", "application/json"],
|
|
68
|
-
]);
|
|
69
|
-
}
|
|
70
|
-
return Object.fromEntries(res);
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
const areJsonEqual = (jsonObj1, jsonObj2) => {
|
|
74
|
-
// Check if both are objects and not null
|
|
75
|
-
if (
|
|
76
|
-
typeof jsonObj1 === "object" &&
|
|
77
|
-
jsonObj1 !== null &&
|
|
78
|
-
typeof jsonObj2 === "object" &&
|
|
79
|
-
jsonObj2 !== null
|
|
80
|
-
) {
|
|
81
|
-
// Get the keys of both objects
|
|
82
|
-
const keys1 = Object.keys(jsonObj1);
|
|
83
|
-
const keys2 = Object.keys(jsonObj2);
|
|
84
|
-
|
|
85
|
-
// Check if the number of keys is different
|
|
86
|
-
if (keys1.length !== keys2.length) {
|
|
87
|
-
return false;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// Recursively check each key-value pair
|
|
91
|
-
for (let key of keys1) {
|
|
92
|
-
if (!keys2.includes(key) || !areJsonEqual(jsonObj1[key], jsonObj2[key])) {
|
|
93
|
-
return false;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
return true;
|
|
98
|
-
} else {
|
|
99
|
-
// For non-object types, use strict equality comparison
|
|
100
|
-
return jsonObj1 === jsonObj2;
|
|
101
|
-
}
|
|
102
|
-
};
|
|
4
|
+
const {
|
|
5
|
+
charDifference,
|
|
6
|
+
nameToFolder,
|
|
7
|
+
getMockDir,
|
|
8
|
+
getFallbackDir,
|
|
9
|
+
areJsonEqual,
|
|
10
|
+
clearNulls,
|
|
11
|
+
processURL,
|
|
12
|
+
getHeaders,
|
|
13
|
+
countFilesInDirectory,
|
|
14
|
+
getTestByName,
|
|
15
|
+
} = require("./common-utils");
|
|
103
16
|
|
|
104
17
|
const getDefaultMockDataFromConfig = (testConfig) => {
|
|
105
18
|
const defaultPath = path.join(getMockDir(testConfig), "default.json");
|
|
@@ -174,14 +87,6 @@ const loadMockDataFromConfig = (testConfig, _testName) => {
|
|
|
174
87
|
}
|
|
175
88
|
};
|
|
176
89
|
|
|
177
|
-
const clearNulls = (postData) => {
|
|
178
|
-
Object.keys(postData || {}).forEach((key) => {
|
|
179
|
-
if (postData[key] === null) {
|
|
180
|
-
delete postData[key];
|
|
181
|
-
}
|
|
182
|
-
});
|
|
183
|
-
};
|
|
184
|
-
|
|
185
90
|
const isSameRequest = (req1, req2) => {
|
|
186
91
|
clearNulls(req1.postData);
|
|
187
92
|
clearNulls(req2.postData);
|
|
@@ -230,20 +135,6 @@ const getSameRequestRank = (req1, req2) => {
|
|
|
230
135
|
return rank;
|
|
231
136
|
};
|
|
232
137
|
|
|
233
|
-
const processURL = (url, ignoreParams = []) => {
|
|
234
|
-
// Remove the hostname from the URL
|
|
235
|
-
const urlWithoutHost = url.replace(/^(https?:\/\/)?[^\/]+/, "");
|
|
236
|
-
const processedURL = new URL(`http://domain.com${urlWithoutHost}`);
|
|
237
|
-
const params = new URLSearchParams(processedURL.search);
|
|
238
|
-
if (ignoreParams?.length > 0) {
|
|
239
|
-
ignoreParams.forEach((ip) => {
|
|
240
|
-
params.delete(ip);
|
|
241
|
-
});
|
|
242
|
-
}
|
|
243
|
-
params.sort();
|
|
244
|
-
return decodeURIComponent(`${processedURL.pathname}?${params}`);
|
|
245
|
-
};
|
|
246
|
-
|
|
247
138
|
function compareMockToRequest(mock, req) {
|
|
248
139
|
const mockURL = processURL(
|
|
249
140
|
mock.fileContent.url,
|
|
@@ -742,24 +633,6 @@ function initiateConsoleLogs(jest, ftmocksConifg, testName) {
|
|
|
742
633
|
};
|
|
743
634
|
}
|
|
744
635
|
|
|
745
|
-
function countFilesInDirectory(directoryPath) {
|
|
746
|
-
return new Promise((resolve, reject) => {
|
|
747
|
-
fs.readdir(directoryPath, (err, files) => {
|
|
748
|
-
if (err) {
|
|
749
|
-
return reject(err); // Handle error
|
|
750
|
-
}
|
|
751
|
-
|
|
752
|
-
// Filter out directories and only count files
|
|
753
|
-
const fileCount = files.filter((file) => {
|
|
754
|
-
const filePath = path.join(directoryPath, file);
|
|
755
|
-
return fs.statSync(filePath).isFile();
|
|
756
|
-
}).length;
|
|
757
|
-
|
|
758
|
-
resolve(fileCount);
|
|
759
|
-
});
|
|
760
|
-
});
|
|
761
|
-
}
|
|
762
|
-
|
|
763
636
|
const saveSnap = async (html, ftmocksConifg, testName) => {
|
|
764
637
|
const snapFolder = path.join(
|
|
765
638
|
getMockDir(ftmocksConifg),
|
|
@@ -824,21 +697,6 @@ function initiateJestEventSnaps(jest, ftmocksConifg, testName) {
|
|
|
824
697
|
});
|
|
825
698
|
}
|
|
826
699
|
|
|
827
|
-
const getTestByName = async (ftmocksConifg, testName) => {
|
|
828
|
-
const testsPath = path.join(getMockDir(ftmocksConifg), "tests.json");
|
|
829
|
-
let tests = [];
|
|
830
|
-
try {
|
|
831
|
-
// Read existing tests
|
|
832
|
-
const testsData = fs.readFileSync(testsPath, "utf8");
|
|
833
|
-
tests = JSON.parse(testsData);
|
|
834
|
-
const etest = tests.find((tst) => tst.name === testName);
|
|
835
|
-
return etest;
|
|
836
|
-
} catch (error) {
|
|
837
|
-
console.error(`\x1b[31mError reading tests.json:\x1b[0m`, error);
|
|
838
|
-
return null;
|
|
839
|
-
}
|
|
840
|
-
};
|
|
841
|
-
|
|
842
700
|
const createTest = async (ftmocksConifg, testName) => {
|
|
843
701
|
const testsPath = path.join(getMockDir(ftmocksConifg), "tests.json");
|
|
844
702
|
let tests = [];
|