Permalink
Browse files

feat(filterFilter): compare object with custom `toString()` to primitive

Closes #10464
Closes #10548
  • Loading branch information...
m7r authored and petebacondarwin committed Dec 22, 2014
1 parent 4501da3 commit f8c421617096a8d613f4eb6d0f5b098ee149c029
Showing with 32 additions and 2 deletions.
  1. +9 −2 src/ng/filter/filter.js
  2. +23 −0 test/ng/filter/filterSpec.js
View
@@ -54,6 +54,9 @@
* - `false|undefined`: A short hand for a function which will look for a substring match in case
* insensitive way.
*
* Primitive values are converted to strings. Objects are not compared against primitives,
* unless they have a custom `toString` method (e.g. `Date` objects).
*
* @example
<example>
<file name="index.html">
@@ -156,6 +159,10 @@ function filterFilter() {
};
}
function hasCustomToString(obj) {
return isFunction(obj.toString) && obj.toString !== Object.prototype.toString;
}
// Helper functions for `filterFilter`
function createPredicateFn(expression, comparator, matchAgainstAnyProp) {
var shouldMatchPrimitives = isObject(expression) && ('$' in expression);
@@ -165,8 +172,8 @@ function createPredicateFn(expression, comparator, matchAgainstAnyProp) {
comparator = equals;
} else if (!isFunction(comparator)) {
comparator = function(actual, expected) {
if (isObject(actual) || isObject(expected)) {
// Prevent an object to be considered equal to a string like `'[object'`
if (isObject(expected) || (isObject(actual) && !hasCustomToString(actual))) {
// Should not compare primitives against objects, unless they have custom `toString` method
return false;
}
@@ -472,6 +472,29 @@ describe('Filter: filter', function() {
});
it('should consider custom `toString()` in non-strict comparison', function() {
var obj = new Date(1970, 0);
var items = [{test: obj}];
expect(filter(items, '1970').length).toBe(1);
expect(filter(items, 1970).length).toBe(1);
obj = {};
obj.toString = function() { return 'custom'; };
items = [{test: obj}];
expect(filter(items, 'custom').length).toBe(1);
});
it('should not throw on missing `toString()` in non-strict comparison', function() {
var obj = Object.create(null);
var items = [{test: obj}];
expect(function() {
filter(items, 'foo');
}).not.toThrow();
expect(filter(items, 'foo').length).toBe(0);
});
it('as equality when true', function() {
var items = ['misko', 'adam', 'adamson'];
var expr = 'adam';

0 comments on commit f8c4216

Please sign in to comment.