Comparing version 3.0.1 to 3.1.0
261
index.js
'use strict' | ||
module.exports = match | ||
function isArguments (obj) { | ||
@@ -7,152 +9,157 @@ return Object.prototype.toString.call(obj) === '[object Arguments]' | ||
module.exports = match | ||
function regexpSame (a, b) { | ||
return a.source === b.source && | ||
a.global === b.global && | ||
a.multiline === b.multiline && | ||
a.lastIndex === b.lastIndex && | ||
a.ignoreCase === b.ignoreCase | ||
} | ||
function match (obj, pattern) { | ||
return match_(obj, pattern, [], []) | ||
function arrayFrom (obj) { | ||
return Array.isArray(obj) ? obj | ||
: Array.from ? Array.from(obj) | ||
: Array.prototype.slice.call(obj) | ||
} | ||
/* istanbul ignore next */ | ||
var log = (/\btmatch\b/.test(process.env.NODE_DEBUG || '')) ? | ||
console.error : function () {} | ||
var hasSet = typeof Set === 'function' | ||
function match_ (obj, pattern, ca, cb) { | ||
log('TMATCH', typeof obj, pattern) | ||
if (obj == pattern) { | ||
log('TMATCH same object or simple value, or problem') | ||
// if one is object, and the other isn't, then this is bogus | ||
if (obj === null || pattern === null) { | ||
return true | ||
function isSet (object) { | ||
return hasSet && (object instanceof Set) | ||
} | ||
} else if (typeof obj === 'object' && typeof pattern === 'object') { | ||
return true | ||
function isMap (object) { | ||
return hasSet && (object instanceof Map) | ||
} | ||
} else if (typeof obj === 'object' && typeof pattern !== 'object') { | ||
return false | ||
} else if (typeof obj !== 'object' && typeof pattern === 'object') { | ||
return false | ||
} else { | ||
return true | ||
function bufferSame (a, b) { | ||
var ret | ||
if (a.equals) { | ||
ret = a.equals(b) | ||
} else if (a.length !== b.length) { | ||
ret = false | ||
} else { | ||
ret = true | ||
for (var j = 0; j < a.length && ret; j++) { | ||
if (a[j] != b[j]) | ||
ret = false | ||
} | ||
} | ||
return ret | ||
} | ||
} else if (obj === null || pattern === null) { | ||
log('TMATCH null test, already failed ==') | ||
return false | ||
function match (obj, pattern) { | ||
return match_(obj, pattern, [], []) | ||
} | ||
} else if (pattern instanceof RegExp) { | ||
if (typeof obj === 'string') { | ||
log('TMATCH string~=regexp test') | ||
return pattern.test(obj) | ||
} else if (obj instanceof RegExp) { | ||
log('TMATCH regexp~=regexp test') | ||
return obj.source === pattern.source && | ||
obj.global === pattern.global && | ||
obj.multiline === pattern.multiline && | ||
obj.lastIndex === pattern.lastIndex && | ||
obj.ignoreCase === pattern.ignoreCase | ||
} else { | ||
log('TMATCH stringify~=regexp test') | ||
return pattern.test('' + obj) | ||
} | ||
} else if (typeof obj === 'string' && typeof pattern === 'string' && pattern) { | ||
log('TMATCH string~=string test') | ||
return obj.indexOf(pattern) !== -1 | ||
function setMatch (obj, pattern) { | ||
var ret = true | ||
if (!isSet(obj)) | ||
ret = false | ||
else if (pattern.size === 0) | ||
ret = true | ||
else { | ||
pattern.forEach(function (entry) { | ||
if (ret) | ||
ret = obj.has(entry) | ||
}) | ||
} | ||
return ret | ||
} | ||
} else if (obj instanceof Date && pattern instanceof Date) { | ||
log('TMATCH date test') | ||
return obj.getTime() === pattern.getTime() | ||
function mapMatch (obj, pattern, ca, cb) { | ||
var ret = true | ||
if (!isMap(obj)) | ||
ret = false | ||
else if (pattern.size === 0) | ||
ret = true | ||
else { | ||
pattern.forEach(function (value, key) { | ||
if (ret) | ||
ret = obj.has(key) | ||
if (ret) | ||
ret = match_(value, obj.get(key), ca, cb) | ||
}) | ||
} | ||
return ret | ||
} | ||
} else if (obj instanceof Date && typeof pattern === 'string') { | ||
log('TMATCH date~=string test') | ||
return obj.getTime() === new Date(pattern).getTime() | ||
} else if (isArguments(obj) || isArguments(pattern)) { | ||
log('TMATCH arguments test') | ||
var slice = Array.prototype.slice | ||
return match_(slice.call(obj), slice.call(pattern), ca, cb) | ||
function match_ (obj, pattern, ca, cb) { | ||
return obj == pattern ? ( | ||
obj === null || pattern === null ? true | ||
: typeof obj === 'object' && typeof pattern === 'object' ? true | ||
: typeof obj === 'object' && typeof pattern !== 'object' ? false | ||
: typeof obj !== 'object' && typeof pattern === 'object' ? false | ||
: true | ||
) | ||
: obj === null || pattern === null ? false | ||
: pattern instanceof RegExp ? ( | ||
typeof obj === 'string' ? pattern.test(obj) | ||
: obj instanceof RegExp ? regexpSame(obj, pattern) | ||
: pattern.test('' + obj) | ||
) | ||
: isSet(pattern) ? setMatch(obj, pattern) | ||
: isMap(pattern) ? mapMatch(obj, pattern, ca, cb) | ||
: typeof obj === 'string' && typeof pattern === 'string' && pattern ? | ||
obj.indexOf(pattern) !== -1 | ||
: obj instanceof Date && pattern instanceof Date ? | ||
obj.getTime() === pattern.getTime() | ||
: obj instanceof Date && typeof pattern === 'string' ? | ||
obj.getTime() === new Date(pattern).getTime() | ||
: isArguments(obj) || isArguments(pattern) ? | ||
match_(arrayFrom(obj), arrayFrom(pattern), ca, cb) | ||
: pattern === Buffer ? Buffer.isBuffer(obj) | ||
: pattern === Function ? typeof obj === 'function' | ||
: pattern === Number ? | ||
typeof obj === 'number' && obj === obj && isFinite(obj) | ||
: pattern !== pattern ? obj !== obj | ||
: pattern === String ? typeof obj === 'string' | ||
: pattern === Boolean ? typeof obj === 'boolean' | ||
: pattern === Array ? Array.isArray(obj) | ||
: typeof pattern === 'function' && typeof obj === 'object' ? | ||
obj instanceof pattern | ||
: typeof obj !== 'object' || typeof pattern !== 'object' ? false | ||
: Buffer.isBuffer(obj) && Buffer.isBuffer(pattern) ? | ||
bufferSame(obj, pattern) | ||
: matchObj(obj, pattern, Object.keys(obj), Object.keys(pattern), ca, cb) | ||
} | ||
} else if (pattern === Buffer) { | ||
log('TMATCH Buffer ctor') | ||
return Buffer.isBuffer(obj) | ||
function matchObj (obj, pattern, kobj, kpat, ca, cb) { | ||
var ret = true | ||
} else if (pattern === Function) { | ||
log('TMATCH Function ctor') | ||
return typeof obj === 'function' | ||
} else if (pattern === Number) { | ||
log('TMATCH Number ctor (finite, not NaN)') | ||
return typeof obj === 'number' && obj === obj && isFinite(obj) | ||
} else if (pattern !== pattern) { | ||
log('TMATCH NaN') | ||
return obj !== obj | ||
} else if (pattern === String) { | ||
log('TMATCH String ctor') | ||
return typeof obj === 'string' | ||
} else if (pattern === Boolean) { | ||
log('TMATCH Boolean ctor') | ||
return typeof obj === 'boolean' | ||
} else if (pattern === Array) { | ||
log('TMATCH Array ctor', pattern, Array.isArray(obj)) | ||
return Array.isArray(obj) | ||
} else if (typeof pattern === 'function' && typeof obj === 'object') { | ||
log('TMATCH object~=function') | ||
return obj instanceof pattern | ||
} else if (typeof obj !== 'object' || typeof pattern !== 'object') { | ||
log('TMATCH obj is not object, pattern is not object, false') | ||
return false | ||
} else if (Buffer.isBuffer(obj) && Buffer.isBuffer(pattern)) { | ||
log('TMATCH buffer test') | ||
if (obj.equals) { | ||
return obj.equals(pattern) | ||
} else { | ||
if (obj.length !== pattern.length) return false | ||
for (var j = 0; j < obj.length; j++) if (obj[j] != pattern[j]) return false | ||
return true | ||
} | ||
} else { | ||
// both are objects. interesting case! | ||
log('TMATCH object~=object test') | ||
var kobj = Object.keys(obj) | ||
var kpat = Object.keys(pattern) | ||
log(' TMATCH patternkeys=%j objkeys=%j', kpat, kobj) | ||
// don't bother with stack acrobatics if there's nothing there | ||
if (kobj.length === 0 && kpat.length === 0) return true | ||
// don't bother with stack acrobatics if there's nothing there | ||
if (kobj.length === 0 && kpat.length === 0) | ||
ret = true | ||
else { | ||
// if we've seen this exact pattern and object already, then | ||
// it means that pattern and obj have matching cyclicalness | ||
// however, non-cyclical patterns can match cyclical objects | ||
log(' TMATCH check seen objects...') | ||
var cal = ca.length | ||
while (cal--) if (ca[cal] === obj && cb[cal] === pattern) return true | ||
ca.push(obj); cb.push(pattern) | ||
log(' TMATCH not seen previously') | ||
var key | ||
for (var l = kpat.length - 1; l >= 0; l--) { | ||
key = kpat[l] | ||
log(' TMATCH test obj[%j]', key, obj[key], pattern[key]) | ||
if (!match_(obj[key], pattern[key], ca, cb)) return false | ||
var go = true | ||
while (cal-- && go) { | ||
if (ca[cal] === obj && cb[cal] === pattern) { | ||
ret = true | ||
go = false | ||
} | ||
} | ||
ca.pop() | ||
cb.pop() | ||
if (go) { | ||
ca.push(obj) | ||
cb.push(pattern) | ||
log(' TMATCH object pass') | ||
return true | ||
var key | ||
for (var l = kpat.length - 1; l >= 0 && ret; l--) { | ||
key = kpat[l] | ||
if (!match_(obj[key], pattern[key], ca, cb)) | ||
ret = false | ||
} | ||
if (ret) { | ||
ca.pop() | ||
cb.pop() | ||
} | ||
} | ||
} | ||
/* istanbul ignore next */ | ||
throw new Error('impossible to reach this point') | ||
return ret | ||
} |
{ | ||
"name": "tmatch", | ||
"version": "3.0.1", | ||
"version": "3.1.0", | ||
"description": "This module exists to facilitate the `t.match()` method in [`tap`](http://npm.im/tap).", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "tap --100 test/*.js", | ||
"test": "tap --100 test/*.js -J", | ||
"preversion": "npm test", | ||
@@ -9,0 +9,0 @@ "postversion": "npm publish", |
@@ -52,29 +52,33 @@ # tmatch | ||
already a string. | ||
4. If the object is a string and the pattern is a non-empty string, | ||
4. If the pattern is a `Set`, then return true if all the keys in | ||
`pattern` appear in `object`. | ||
5. If the pattern is a `Map`, then return true if all the keys in | ||
`pattern` are in `object`, and the values match as well. | ||
6. If the object is a string and the pattern is a non-empty string, | ||
then return true if the string occurs within the object. | ||
5. If the object and the pattern are both Date objects, then return | ||
7. If the object and the pattern are both Date objects, then return | ||
true if they represent the same date. | ||
6. If the object is a Date object, and the pattern is a string, then | ||
8. If the object is a Date object, and the pattern is a string, then | ||
return true if the pattern is parseable as a date that is the same | ||
date as the object. | ||
7. If the object is an `arguments` object, or the pattern is an | ||
9. If the object is an `arguments` object, or the pattern is an | ||
`arguments` object, then cast them to arrays and compare their | ||
contents. | ||
8. If the pattern is the `Buffer` constructor, then return true if the | ||
object is a Buffer. | ||
9. If the pattern is the `Function` constructor, then return true if | ||
the object is a function. | ||
10. If the pattern is the String constructor, then return true if the | ||
10. If the pattern is the `Buffer` constructor, then return true if | ||
the object is a Buffer. | ||
11. If the pattern is the `Function` constructor, then return true if | ||
the object is a function. | ||
12. If the pattern is the String constructor, then return true if the | ||
pattern is a string. | ||
11. If the pattern is the Boolean constructor, then return true if the | ||
13. If the pattern is the Boolean constructor, then return true if the | ||
pattern is a boolean. | ||
12. If the pattern is the Array constructor, then return true if the | ||
14. If the pattern is the Array constructor, then return true if the | ||
pattern is an array. | ||
13. If the pattern is any function, and then object is an object, then | ||
15. If the pattern is any function, and then object is an object, then | ||
return true if the object is an `instanceof` the pattern. | ||
14. At this point, if the object or the pattern are not objects, then | ||
16. At this point, if the object or the pattern are not objects, then | ||
return false (because they would have matched earlier). | ||
15. If the object is a buffer, and the pattern is also a buffer, then | ||
17. If the object is a buffer, and the pattern is also a buffer, then | ||
return true if they contain the same bytes. | ||
16. At this point, both object and pattern are object type values, so | ||
18. At this point, both object and pattern are object type values, so | ||
compare their keys: | ||
@@ -81,0 +85,0 @@ 1. Get list of all iterable keys in pattern and object. If both |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
97
17321
9
440
1