1 |
|
2 |
|
3 |
|
4 | const canSetPrototype =
|
5 | Object.setPrototypeOf || { __proto__: [] } instanceof Array;
|
6 | const greedyIntervalPacker = require('greedy-interval-packer');
|
7 |
|
8 | const setPrototypeOf =
|
9 | Object.setPrototypeOf ||
|
10 | function setPrototypeOf(obj, proto) {
|
11 | obj.__proto__ = proto;
|
12 | return obj;
|
13 | };
|
14 |
|
15 |
|
16 | const utils = (module.exports = {
|
17 | objectIs:
|
18 | Object.is ||
|
19 | ((a, b) => {
|
20 |
|
21 | if (a === 0 && b === 0) {
|
22 | return 1 / a === 1 / b;
|
23 | }
|
24 |
|
25 | if (a !== a) {
|
26 |
|
27 | return b !== b;
|
28 | }
|
29 | return a === b;
|
30 | }),
|
31 |
|
32 | checkObjectEqualityUsingType(a, b, type, isEqual) {
|
33 | if (a === b) {
|
34 | return true;
|
35 | }
|
36 |
|
37 | if (b.constructor !== a.constructor) {
|
38 | return false;
|
39 | }
|
40 |
|
41 | const actualKeys = type
|
42 | .getKeys(a)
|
43 | .filter(key => typeof type.valueForKey(a, key) !== 'undefined');
|
44 | const expectedKeys = type
|
45 | .getKeys(b)
|
46 | .filter(key => typeof type.valueForKey(b, key) !== 'undefined');
|
47 |
|
48 |
|
49 | if (actualKeys.length !== expectedKeys.length) {
|
50 | return false;
|
51 | }
|
52 |
|
53 |
|
54 | actualKeys.sort(type.keyComparator);
|
55 | expectedKeys.sort(type.keyComparator);
|
56 |
|
57 | for (let i = 0; i < actualKeys.length; i += 1) {
|
58 | if (actualKeys[i] !== expectedKeys[i]) {
|
59 | return false;
|
60 | }
|
61 | }
|
62 |
|
63 |
|
64 |
|
65 | for (let j = 0; j < actualKeys.length; j += 1) {
|
66 | const key = actualKeys[j];
|
67 | if (!isEqual(type.valueForKey(a, key), type.valueForKey(b, key))) {
|
68 | return false;
|
69 | }
|
70 | }
|
71 | return true;
|
72 | },
|
73 |
|
74 | duplicateArrayLikeUsingType(obj, type) {
|
75 | const keys = type.getKeys(obj);
|
76 |
|
77 | let numericalKeyLength = keys.length;
|
78 | if (!type.numericalPropertiesOnly) {
|
79 | let nonNumericalKeyLength = 0;
|
80 |
|
81 | for (let i = keys.length - 1; i > -1; i -= 1) {
|
82 | const key = keys[i];
|
83 | if (typeof key === 'symbol' || !utils.numericalRegExp.test(key)) {
|
84 | nonNumericalKeyLength += 1;
|
85 | } else {
|
86 | break;
|
87 | }
|
88 | }
|
89 |
|
90 | numericalKeyLength -= nonNumericalKeyLength;
|
91 | }
|
92 |
|
93 | const arr = new Array(numericalKeyLength);
|
94 |
|
95 | keys.forEach(function(key, index) {
|
96 | const isNonNumericKey = index >= numericalKeyLength;
|
97 | if (isNonNumericKey && !type.hasKey(obj, key)) {
|
98 |
|
99 |
|
100 | return;
|
101 | }
|
102 | arr[key] = type.hasKey(obj, key) ? type.valueForKey(obj, key) : undefined;
|
103 | });
|
104 |
|
105 | return arr;
|
106 | },
|
107 |
|
108 | isArray:
|
109 | Array.isArray ||
|
110 | function(obj) {
|
111 | return Object.prototype.toString.call(obj) === '[object Array]';
|
112 | },
|
113 |
|
114 | isPromise(obj) {
|
115 | return obj && typeof obj.then === 'function';
|
116 | },
|
117 |
|
118 | isRegExp(re) {
|
119 | return Object.prototype.toString.call(re) === '[object RegExp]';
|
120 | },
|
121 |
|
122 | isError(err) {
|
123 | return (
|
124 | typeof err === 'object' &&
|
125 | (Object.prototype.toString.call(err) === '[object Error]' ||
|
126 | err instanceof Error)
|
127 | );
|
128 | },
|
129 |
|
130 | extend(target) {
|
131 | for (let i = 1; i < arguments.length; i += 1) {
|
132 | const source = arguments[i];
|
133 | if (source) {
|
134 | Object.keys(source).forEach(key => {
|
135 | target[key] = source[key];
|
136 | });
|
137 | }
|
138 | }
|
139 | return target;
|
140 | },
|
141 |
|
142 | findFirst(arr, predicate) {
|
143 | for (let i = 0; i < arr.length; i += 1) {
|
144 | if (predicate(arr[i])) {
|
145 | return arr[i];
|
146 | }
|
147 | }
|
148 | return null;
|
149 | },
|
150 |
|
151 | leftPad(str, width, ch = ' ') {
|
152 | while (str.length < width) {
|
153 | str = ch + str;
|
154 | }
|
155 | return str;
|
156 | },
|
157 |
|
158 | escapeRegExpMetaChars(str) {
|
159 | return str.replace(/[[\]{}()*+?.\\^$|]/g, '\\$&');
|
160 | },
|
161 |
|
162 | escapeChar(ch) {
|
163 | if (ch === '\t') {
|
164 | return '\\t';
|
165 | } else if (ch === '\r') {
|
166 | return '\\r';
|
167 | } else {
|
168 | const charCode = ch.charCodeAt(0);
|
169 | const hexChars = charCode.toString(16).toUpperCase();
|
170 | if (charCode < 256) {
|
171 | return `\\x${utils.leftPad(hexChars, 2, '0')}`;
|
172 | } else {
|
173 | return `\\u${utils.leftPad(hexChars, 4, '0')}`;
|
174 | }
|
175 | }
|
176 | },
|
177 |
|
178 | getFunctionName(f) {
|
179 | if (typeof f.name === 'string') {
|
180 | return f.name;
|
181 | }
|
182 | const matchFunctionName = Function.prototype.toString
|
183 | .call(f)
|
184 | .match(/function ([^(]+)/);
|
185 | if (matchFunctionName) {
|
186 | return matchFunctionName[1];
|
187 | }
|
188 |
|
189 | if (f === Object) {
|
190 | return 'Object';
|
191 | }
|
192 | if (f === Function) {
|
193 | return 'Function';
|
194 | }
|
195 | return '';
|
196 | },
|
197 |
|
198 | wrapConstructorNameAroundOutput(output, obj) {
|
199 | const constructor = obj.constructor;
|
200 | const constructorName =
|
201 | constructor &&
|
202 | constructor !== Object &&
|
203 | utils.getFunctionName(constructor);
|
204 | if (constructorName && constructorName !== 'Object') {
|
205 | return output
|
206 | .clone()
|
207 | .text(`${constructorName}(`)
|
208 | .append(output)
|
209 | .text(')');
|
210 | } else {
|
211 | return output;
|
212 | }
|
213 | },
|
214 |
|
215 | setPrototypeOfOrExtend: canSetPrototype
|
216 | ? setPrototypeOf
|
217 | : function extend(target, source) {
|
218 | for (const prop in source) {
|
219 | if (Object.prototype.hasOwnProperty.call(source, prop)) {
|
220 | target[prop] = source[prop];
|
221 | }
|
222 | }
|
223 | return target;
|
224 | },
|
225 |
|
226 | uniqueStringsAndSymbols(...args) {
|
227 |
|
228 | let filterFn;
|
229 | if (typeof args[0] === 'function') {
|
230 | filterFn = args[0];
|
231 | }
|
232 | const index = {};
|
233 | const uniqueStringsAndSymbols = [];
|
234 |
|
235 | function visit(item) {
|
236 | if (Array.isArray(item)) {
|
237 | item.forEach(visit);
|
238 | } else if (
|
239 | !Object.prototype.hasOwnProperty.call(index, item) &&
|
240 | (!filterFn || filterFn(item))
|
241 | ) {
|
242 | index[item] = true;
|
243 | uniqueStringsAndSymbols.push(item);
|
244 | }
|
245 | }
|
246 |
|
247 | for (let i = filterFn ? 1 : 0; i < args.length; i += 1) {
|
248 | visit(args[i]);
|
249 | }
|
250 | return uniqueStringsAndSymbols;
|
251 | },
|
252 |
|
253 | uniqueNonNumericalStringsAndSymbols(...args) {
|
254 |
|
255 | return utils.uniqueStringsAndSymbols(
|
256 | stringOrSymbol =>
|
257 | typeof stringOrSymbol === 'symbol' ||
|
258 | !utils.numericalRegExp.test(stringOrSymbol),
|
259 | Array.prototype.slice.call(args)
|
260 | );
|
261 | },
|
262 |
|
263 | forwardFlags(testDescriptionString, flags) {
|
264 | return testDescriptionString
|
265 | .replace(/\[(!?)([^\]]+)\] ?/g, (match, negate, flag) =>
|
266 | Boolean(flags[flag]) !== Boolean(negate) ? `${flag} ` : ''
|
267 | )
|
268 | .trim();
|
269 | },
|
270 |
|
271 | numericalRegExp: /^(?:0|[1-9][0-9]*)$/,
|
272 |
|
273 | packArrows(changes) {
|
274 | const moveSourceAndTargetByActualIndex = {};
|
275 | changes.forEach((diffItem, index) => {
|
276 | if (diffItem.type === 'moveSource') {
|
277 | diffItem.changeIndex = index;
|
278 | (moveSourceAndTargetByActualIndex[diffItem.actualIndex] =
|
279 | moveSourceAndTargetByActualIndex[diffItem.actualIndex] ||
|
280 | {}).source = diffItem;
|
281 | } else if (diffItem.type === 'moveTarget') {
|
282 | diffItem.changeIndex = index;
|
283 | (moveSourceAndTargetByActualIndex[diffItem.actualIndex] =
|
284 | moveSourceAndTargetByActualIndex[diffItem.actualIndex] ||
|
285 | {}).target = diffItem;
|
286 | }
|
287 | });
|
288 | const moveIndices = Object.keys(moveSourceAndTargetByActualIndex);
|
289 | if (moveIndices.length > 0) {
|
290 | const arrowSpecs = [];
|
291 | moveIndices
|
292 | .sort(
|
293 | (
|
294 | a,
|
295 | b
|
296 | ) =>
|
297 | Math.abs(
|
298 | moveSourceAndTargetByActualIndex[b].source.changeIndex -
|
299 | moveSourceAndTargetByActualIndex[b].target.changeIndex
|
300 | ) -
|
301 | Math.abs(
|
302 | moveSourceAndTargetByActualIndex[a].source.changeIndex -
|
303 | moveSourceAndTargetByActualIndex[a].target.changeIndex
|
304 | )
|
305 | )
|
306 | .forEach((actualIndex, i, keys) => {
|
307 | const moveSourceAndMoveTarget =
|
308 | moveSourceAndTargetByActualIndex[actualIndex];
|
309 | const firstChangeIndex = Math.min(
|
310 | moveSourceAndMoveTarget.source.changeIndex,
|
311 | moveSourceAndMoveTarget.target.changeIndex
|
312 | );
|
313 | const lastChangeIndex = Math.max(
|
314 | moveSourceAndMoveTarget.source.changeIndex,
|
315 | moveSourceAndMoveTarget.target.changeIndex
|
316 | );
|
317 |
|
318 | arrowSpecs.push({
|
319 | start: firstChangeIndex,
|
320 | end: lastChangeIndex,
|
321 | direction:
|
322 | moveSourceAndMoveTarget.source.changeIndex <
|
323 | moveSourceAndMoveTarget.target.changeIndex
|
324 | ? 'down'
|
325 | : 'up'
|
326 | });
|
327 | });
|
328 |
|
329 | const packing = greedyIntervalPacker(arrowSpecs);
|
330 | while (packing.length > 3) {
|
331 |
|
332 | packing.shift().forEach(({ direction, start, end }) => {
|
333 | changes[direction === 'up' ? start : end].type = 'insert';
|
334 | changes[direction === 'up' ? end : start].type = 'remove';
|
335 | });
|
336 | }
|
337 | return packing;
|
338 | }
|
339 | },
|
340 |
|
341 | truncateSubjectStringForBegin(subject, value) {
|
342 | var contextLength = value.length + 25;
|
343 | if (subject.length <= contextLength) {
|
344 | return null;
|
345 | }
|
346 | var truncationIndex = subject.indexOf(' ', value.length + 1);
|
347 | if (truncationIndex > -1 && truncationIndex < contextLength) {
|
348 | return subject.substring(0, truncationIndex);
|
349 | } else {
|
350 | return subject.substring(0, contextLength);
|
351 | }
|
352 | },
|
353 |
|
354 | truncateSubjectStringForEnd(subject, value) {
|
355 | var contextLength = subject.length - value.length - 25;
|
356 | if (contextLength <= 0) {
|
357 | return null;
|
358 | }
|
359 | var truncationIndex = subject.lastIndexOf(' ', value.length + 1);
|
360 | if (truncationIndex > -1 && truncationIndex >= contextLength) {
|
361 | return subject.substring(truncationIndex + 1, subject.length);
|
362 | } else {
|
363 | return subject.substring(contextLength, subject.length);
|
364 | }
|
365 | },
|
366 |
|
367 | getEnv(varName) {
|
368 | if (typeof Deno === 'object') {
|
369 | try {
|
370 | return Deno.env()[varName];
|
371 | } catch (err) {
|
372 |
|
373 |
|
374 |
|
375 |
|
376 | }
|
377 | } else if (typeof process === 'object' && process.env) {
|
378 | return process.env[varName];
|
379 | }
|
380 | }
|
381 | });
|