(actual, expected, comparator, matchAgainstAnyProp)
| 16681 | } |
| 16682 | |
| 16683 | function deepCompare(actual, expected, comparator, matchAgainstAnyProp) { |
| 16684 | var actualType = typeof actual; |
| 16685 | var expectedType = typeof expected; |
| 16686 | |
| 16687 | if ((expectedType === 'string') && (expected.charAt(0) === '!')) { |
| 16688 | return !deepCompare(actual, expected.substring(1), comparator, matchAgainstAnyProp); |
| 16689 | } else if (actualType === 'array') { |
| 16690 | // In case `actual` is an array, consider it a match |
| 16691 | // if ANY of it's items matches `expected` |
| 16692 | return actual.some(function(item) { |
| 16693 | return deepCompare(item, expected, comparator, matchAgainstAnyProp); |
| 16694 | }); |
| 16695 | } |
| 16696 | |
| 16697 | switch (actualType) { |
| 16698 | case 'object': |
| 16699 | var key; |
| 16700 | if (matchAgainstAnyProp) { |
| 16701 | for (key in actual) { |
| 16702 | if ((key.charAt(0) !== '$') && deepCompare(actual[key], expected, comparator)) { |
| 16703 | return true; |
| 16704 | } |
| 16705 | } |
| 16706 | return false; |
| 16707 | } else if (expectedType === 'object') { |
| 16708 | for (key in expected) { |
| 16709 | var expectedVal = expected[key]; |
| 16710 | if (isFunction(expectedVal)) { |
| 16711 | continue; |
| 16712 | } |
| 16713 | |
| 16714 | var keyIsDollar = key === '$'; |
| 16715 | var actualVal = keyIsDollar ? actual : actual[key]; |
| 16716 | if (!deepCompare(actualVal, expectedVal, comparator, keyIsDollar)) { |
| 16717 | return false; |
| 16718 | } |
| 16719 | } |
| 16720 | return true; |
| 16721 | } else { |
| 16722 | return comparator(actual, expected); |
| 16723 | } |
| 16724 | break; |
| 16725 | case 'function': |
| 16726 | return false; |
| 16727 | default: |
| 16728 | return comparator(actual, expected); |
| 16729 | } |
| 16730 | } |
| 16731 | |
| 16732 | /** |
| 16733 | * @ngdoc filter |
no test coverage detected