(actual, expected, comparator, matchAgainstAnyProp, dontMatchWholeObject)
| 18457 | } |
| 18458 | |
| 18459 | function deepCompare(actual, expected, comparator, matchAgainstAnyProp, dontMatchWholeObject) { |
| 18460 | var actualType = getTypeForFilter(actual); |
| 18461 | var expectedType = getTypeForFilter(expected); |
| 18462 | |
| 18463 | if ((expectedType === 'string') && (expected.charAt(0) === '!')) { |
| 18464 | return !deepCompare(actual, expected.substring(1), comparator, matchAgainstAnyProp); |
| 18465 | } else if (isArray(actual)) { |
| 18466 | // In case `actual` is an array, consider it a match |
| 18467 | // if ANY of it's items matches `expected` |
| 18468 | return actual.some(function(item) { |
| 18469 | return deepCompare(item, expected, comparator, matchAgainstAnyProp); |
| 18470 | }); |
| 18471 | } |
| 18472 | |
| 18473 | switch (actualType) { |
| 18474 | case 'object': |
| 18475 | var key; |
| 18476 | if (matchAgainstAnyProp) { |
| 18477 | for (key in actual) { |
| 18478 | if ((key.charAt(0) !== '$') && deepCompare(actual[key], expected, comparator, true)) { |
| 18479 | return true; |
| 18480 | } |
| 18481 | } |
| 18482 | return dontMatchWholeObject ? false : deepCompare(actual, expected, comparator, false); |
| 18483 | } else if (expectedType === 'object') { |
| 18484 | for (key in expected) { |
| 18485 | var expectedVal = expected[key]; |
| 18486 | if (isFunction(expectedVal) || isUndefined(expectedVal)) { |
| 18487 | continue; |
| 18488 | } |
| 18489 | |
| 18490 | var matchAnyProperty = key === '$'; |
| 18491 | var actualVal = matchAnyProperty ? actual : actual[key]; |
| 18492 | if (!deepCompare(actualVal, expectedVal, comparator, matchAnyProperty, matchAnyProperty)) { |
| 18493 | return false; |
| 18494 | } |
| 18495 | } |
| 18496 | return true; |
| 18497 | } else { |
| 18498 | return comparator(actual, expected); |
| 18499 | } |
| 18500 | break; |
| 18501 | case 'function': |
| 18502 | return false; |
| 18503 | default: |
| 18504 | return comparator(actual, expected); |
| 18505 | } |
| 18506 | } |
| 18507 | |
| 18508 | // Used for easily differentiating between `null` and actual `object` |
| 18509 | function getTypeForFilter(val) { |
no test coverage detected