Permalink
Browse files

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

Closes #10464
Closes #10548
  • Loading branch information...
1 parent 4501da3 commit f8c421617096a8d613f4eb6d0f5b098ee149c029 @m7r m7r committed with petebacondarwin Dec 22, 2014
Showing with 32 additions and 2 deletions.
  1. +9 −2 src/ng/filter/filter.js
  2. +23 −0 test/ng/filter/filterSpec.js
@@ -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.