UNPKG

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