Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

Commit

Permalink
fix(angular.equals): add support for regular expressions
Browse files Browse the repository at this point in the history
Regular expression objects didn't used to be considered to be equal when using
'angular.equals'. Dirty checking therefore failed to recognize a
property modification.

Closes #2685

Conflicts:

	test/AngularSpec.js
  • Loading branch information
bripkens authored and IgorMinar committed Jul 14, 2013
1 parent 332a3c7 commit a357649
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 4 deletions.
25 changes: 21 additions & 4 deletions src/Angular.js
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,18 @@ function isArray(value) {
function isFunction(value){return typeof value == 'function';}


/**
* Determines if a value is a regular expression object.
*
* @private
* @param {*} value Reference to check.
* @returns {boolean} True if `value` is a `RegExp`.
*/
function isRegExp(value) {
return toString.apply(value) == '[object RegExp]';
}


/**
* Checks if `obj` is a window object.
*
Expand Down Expand Up @@ -622,14 +634,17 @@ function shallowCopy(src, dst) {
* @function
*
* @description
* Determines if two objects or two values are equivalent. Supports value types, arrays and
* Determines if two objects or two values are equivalent. Supports value types, regular expressions, arrays and
* objects.
*
* Two objects or values are considered equivalent if at least one of the following is true:
*
* * Both objects or values pass `===` comparison.
* * Both objects or values are of the same type and all of their properties pass `===` comparison.
* * Both values are NaN. (In JavasScript, NaN == NaN => false. But we consider two NaN as equal)
* * Both values represent the same regular expression (In JavasScript,
* /abc/ == /abc/ => false. But we consider two regular expressions as equal when their textual
* representation matches).
*
* During a property comparision, properties of `function` type and properties with names
* that begin with `$` are ignored.
Expand All @@ -656,6 +671,8 @@ function equals(o1, o2) {
}
} else if (isDate(o1)) {
return isDate(o2) && o1.getTime() == o2.getTime();
} else if (isRegExp(o1) && isRegExp(o2)) {
return o1.toString() == o2.toString();
} else {
if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2)) return false;
keySet = {};
Expand Down Expand Up @@ -912,9 +929,9 @@ function encodeUriQuery(val, pctEncodeSpaces) {
* one ngApp directive can be used per HTML document. The directive
* designates the root of the application and is typically placed
* at the root of the page.
*
* The first ngApp found in the document will be auto-bootstrapped. To use multiple applications in an
* HTML document you must manually bootstrap them using {@link angular.bootstrap}.
*
* The first ngApp found in the document will be auto-bootstrapped. To use multiple applications in an
* HTML document you must manually bootstrap them using {@link angular.bootstrap}.
* Applications cannot be nested.
*
* In the example below if the `ngApp` directive would not be placed
Expand Down
28 changes: 28 additions & 0 deletions test/AngularSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,17 @@ describe('angular', function() {
expect(equals(new Date(0), 0)).toBe(false);
expect(equals(0, new Date(0))).toBe(false);
});

it('should compare regular expressions', function() {
expect(equals(/abc/, /abc/)).toBe(true);
expect(equals(/abc/i, new RegExp('abc', 'i'))).toBe(true);
expect(equals(new RegExp('abc', 'i'), new RegExp('abc', 'i'))).toBe(true);
expect(equals(new RegExp('abc', 'i'), new RegExp('abc'))).toBe(false);
expect(equals(/abc/i, /abc/)).toBe(false);
expect(equals(/abc/, /def/)).toBe(false);
expect(equals(/^abc/, /abc/)).toBe(false);
expect(equals(/^abc/, '/^abc/')).toBe(false);
});
});

describe('size', function() {
Expand Down Expand Up @@ -625,6 +636,23 @@ describe('angular', function() {
});
});


describe('isRegExp', function() {
it('should return true for RegExp object', function() {
expect(isRegExp(/^foobar$/)).toBe(true);
expect(isRegExp(new RegExp('^foobar$/'))).toBe(true);
});

it('should return false for non RegExp objects', function() {
expect(isRegExp([])).toBe(false);
expect(isRegExp('')).toBe(false);
expect(isRegExp(23)).toBe(false);
expect(isRegExp({})).toBe(false);
expect(isRegExp(new Date())).toBe(false);
});
});


describe('compile', function() {
it('should link to existing node and create scope', inject(function($rootScope, $compile) {
var template = angular.element('<div>{{greeting = "hello world"}}</div>');
Expand Down

0 comments on commit a357649

Please sign in to comment.