unexpected
Version:
Extensible BDD assertion toolkit
274 lines (248 loc) • 9.99 kB
JavaScript
var _typeof2 = require('babel-runtime/helpers/typeof');
var _typeof3 = _interopRequireDefault(_typeof2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/* eslint-disable no-proto */
var canSetPrototype = Object.setPrototypeOf || { __proto__: [] } instanceof Array;
var greedyIntervalPacker = require('greedy-interval-packer');
var setPrototypeOf = Object.setPrototypeOf || function setPrototypeOf(obj, proto) {
obj.__proto__ = proto;
return obj;
};
/* eslint-enable no-proto */
var utils = module.exports = {
objectIs: Object.is || function (a, b) {
// Polyfill from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
if (a === 0 && b === 0) {
return 1 / a === 1 / b;
}
// eslint-disable-next-line no-self-compare
if (a !== a) {
// eslint-disable-next-line no-self-compare
return b !== b;
}
return a === b;
},
duplicateArrayLikeUsingType: function duplicateArrayLikeUsingType(obj, type) {
var keys = type.getKeys(obj);
var numericalKeyLength = keys.length;
if (!type.numericalPropertiesOnly) {
var nonNumericalKeyLength = 0;
// find non-numerical keys in reverse order to keep iteration minimal
for (var i = keys.length - 1; i > -1; i -= 1) {
var key = keys[i];
if ((typeof key === 'undefined' ? 'undefined' : (0, _typeof3.default)(key)) === 'symbol' || !utils.numericalRegExp.test(key)) {
nonNumericalKeyLength += 1;
} else {
break;
}
}
// remove non-numerical keys to ensure the copy is sized correctly
numericalKeyLength -= nonNumericalKeyLength;
}
var arr = new Array(numericalKeyLength);
keys.forEach(function (key, index) {
var isNonNumericKey = index >= numericalKeyLength;
if (isNonNumericKey && !type.hasKey(obj, key)) {
// do not add non-numerical keys that are not actually attached
// to the array-like to ensure they will be treated as "missing"
return;
}
arr[key] = type.hasKey(obj, key) ? type.valueForKey(obj, key) : undefined;
});
return arr;
},
isArray: function isArray(ar) {
return Object.prototype.toString.call(ar) === '[object Array]';
},
isPromise: function isPromise(obj) {
return obj && typeof obj.then === 'function';
},
isRegExp: function isRegExp(re) {
return Object.prototype.toString.call(re) === '[object RegExp]';
},
isError: function isError(err) {
return (typeof err === 'undefined' ? 'undefined' : (0, _typeof3.default)(err)) === 'object' && (Object.prototype.toString.call(err) === '[object Error]' || err instanceof Error);
},
extend: function extend(target) {
var _arguments = arguments;
var _loop = function _loop(i) {
var source = _arguments[i];
if (source) {
Object.keys(source).forEach(function (key) {
target[key] = source[key];
});
}
};
for (var i = 1; i < arguments.length; i += 1) {
_loop(i);
}
return target;
},
findFirst: function findFirst(arr, predicate) {
for (var i = 0; i < arr.length; i += 1) {
if (predicate(arr[i])) {
return arr[i];
}
}
return null;
},
leftPad: function leftPad(str, width) {
var ch = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ' ';
while (str.length < width) {
str = ch + str;
}
return str;
},
escapeRegExpMetaChars: function escapeRegExpMetaChars(str) {
return str.replace(/[[\]{}()*+?.\\^$|]/g, '\\$&');
},
escapeChar: function escapeChar(ch) {
if (ch === '\t') {
return '\\t';
} else if (ch === '\r') {
return '\\r';
} else {
var charCode = ch.charCodeAt(0);
var hexChars = charCode.toString(16).toUpperCase();
if (charCode < 256) {
return '\\x' + utils.leftPad(hexChars, 2, '0');
} else {
return '\\u' + utils.leftPad(hexChars, 4, '0');
}
}
},
getFunctionName: function getFunctionName(f) {
if (typeof f.name === 'string') {
return f.name;
}
var matchFunctionName = Function.prototype.toString.call(f).match(/function ([^(]+)/);
if (matchFunctionName) {
return matchFunctionName[1];
}
if (f === Object) {
return 'Object';
}
if (f === Function) {
return 'Function';
}
return '';
},
wrapConstructorNameAroundOutput: function wrapConstructorNameAroundOutput(output, obj) {
var constructor = obj.constructor;
var constructorName = constructor && constructor !== Object && utils.getFunctionName(constructor);
if (constructorName && constructorName !== 'Object') {
return output.clone().text(constructorName + '(').append(output).text(')');
} else {
return output;
}
},
setPrototypeOfOrExtend: canSetPrototype ? setPrototypeOf : function extend(target, source) {
for (var prop in source) {
if (source.hasOwnProperty(prop)) {
target[prop] = source[prop];
}
}
return target;
},
uniqueStringsAndSymbols: function uniqueStringsAndSymbols() {
// [filterFn], item1, item2...
var filterFn = void 0;
if (typeof (arguments.length <= 0 ? undefined : arguments[0]) === 'function') {
filterFn = arguments.length <= 0 ? undefined : arguments[0];
}
var index = {};
var uniqueStringsAndSymbols = [];
function visit(item) {
if (Array.isArray(item)) {
item.forEach(visit);
} else if (!Object.prototype.hasOwnProperty.call(index, item) && (!filterFn || filterFn(item))) {
index[item] = true;
uniqueStringsAndSymbols.push(item);
}
}
for (var i = filterFn ? 1 : 0; i < arguments.length; i += 1) {
visit(arguments.length <= i ? undefined : arguments[i]);
}
return uniqueStringsAndSymbols;
},
uniqueNonNumericalStringsAndSymbols: function uniqueNonNumericalStringsAndSymbols() {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
// ...
return utils.uniqueStringsAndSymbols(function (stringOrSymbol) {
return (typeof stringOrSymbol === 'undefined' ? 'undefined' : (0, _typeof3.default)(stringOrSymbol)) === 'symbol' || !utils.numericalRegExp.test(stringOrSymbol);
}, Array.prototype.slice.call(args));
},
forwardFlags: function forwardFlags(testDescriptionString, flags) {
return testDescriptionString.replace(/\[(!?)([^\]]+)\] ?/g, function (match, negate, flag) {
return Boolean(flags[flag]) !== Boolean(negate) ? flag + ' ' : '';
}).trim();
},
numericalRegExp: /^(?:0|[1-9][0-9]*)$/,
packArrows: function packArrows(changes) {
var moveSourceAndTargetByActualIndex = {};
changes.forEach(function (diffItem, index) {
if (diffItem.type === 'moveSource') {
diffItem.changeIndex = index;
(moveSourceAndTargetByActualIndex[diffItem.actualIndex] = moveSourceAndTargetByActualIndex[diffItem.actualIndex] || {}).source = diffItem;
} else if (diffItem.type === 'moveTarget') {
diffItem.changeIndex = index;
(moveSourceAndTargetByActualIndex[diffItem.actualIndex] = moveSourceAndTargetByActualIndex[diffItem.actualIndex] || {}).target = diffItem;
}
});
var moveIndices = Object.keys(moveSourceAndTargetByActualIndex);
if (moveIndices.length > 0) {
var arrowSpecs = [];
moveIndices.sort(function (a, b // Order by distance between change indices descending
) {
return Math.abs(moveSourceAndTargetByActualIndex[b].source.changeIndex - moveSourceAndTargetByActualIndex[b].target.changeIndex) - Math.abs(moveSourceAndTargetByActualIndex[a].source.changeIndex - moveSourceAndTargetByActualIndex[a].target.changeIndex);
}).forEach(function (actualIndex, i, keys) {
var moveSourceAndMoveTarget = moveSourceAndTargetByActualIndex[actualIndex];
var firstChangeIndex = Math.min(moveSourceAndMoveTarget.source.changeIndex, moveSourceAndMoveTarget.target.changeIndex);
var lastChangeIndex = Math.max(moveSourceAndMoveTarget.source.changeIndex, moveSourceAndMoveTarget.target.changeIndex);
arrowSpecs.push({
start: firstChangeIndex,
end: lastChangeIndex,
direction: moveSourceAndMoveTarget.source.changeIndex < moveSourceAndMoveTarget.target.changeIndex ? 'down' : 'up'
});
});
var packing = greedyIntervalPacker(arrowSpecs);
while (packing.length > 3) {
// The arrow packing takes up too many lanes. Turn the moveSource/moveTarget items into inserts and removes
packing.shift().forEach(function (_ref) {
var direction = _ref.direction,
start = _ref.start,
end = _ref.end;
changes[direction === 'up' ? start : end].type = 'insert';
changes[direction === 'up' ? end : start].type = 'remove';
});
}
return packing;
}
},
truncateSubjectStringForBegin: function truncateSubjectStringForBegin(subject, value) {
var contextLength = value.length + 25;
if (subject.length <= contextLength) {
return null;
}
var truncationIndex = subject.indexOf(' ', value.length + 1);
if (truncationIndex > -1 && truncationIndex < contextLength) {
return subject.substring(0, truncationIndex);
} else {
return subject.substring(0, contextLength);
}
},
truncateSubjectStringForEnd: function truncateSubjectStringForEnd(subject, value) {
var contextLength = subject.length - value.length - 25;
if (contextLength <= 0) {
return null;
}
var truncationIndex = subject.lastIndexOf(' ', value.length + 1);
if (truncationIndex > -1 && truncationIndex >= contextLength) {
return subject.substring(truncationIndex + 1, subject.length);
} else {
return subject.substring(contextLength, subject.length);
}
}
};