aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorCodier2011-11-15 18:45:36 -0600
committerIgor Minar2011-11-21 15:43:12 -0800
commit29f9e2665d8b771a6226870fc8fd2c4c94d7a2c0 (patch)
treec48f91fea9b97b10b13d4e1ec636e6cd7995578e /test
parent8d1944851d5bbecd9277ede8c4a354c2d43796ee (diff)
downloadangular.js-29f9e2665d8b771a6226870fc8fd2c4c94d7a2c0.tar.bz2
fix(scope): $watch (and angular.equals) should support NaN values
- since NaN !== NaN in javascript digest can get into an infinite loop when model value is set to NaN - angular.equals(NaN, NaN) should return true since that's what we expect when comparing primitives or objects containing NaN values Previously NaN because of its special === properties was used as the initial value for watches, but that results in issues when NaN is used as model value. In order to allow for model to be anything incuding undefined and NaN we need to mark the initial value differently in a way that would avoid these issues, allow us to run digest without major perf penalties and allow for clients to determine if the listener is being called because the watcher is being initialized or because the model changed. This implementation covers all of these scenarios. BREAKING CHANGE: previously to detect if the listener was called because the watcher was being initialized, it was suggested that clients check if old value is NaN. With this change, the check should be if the newVal equals the oldVal. Closes #657
Diffstat (limited to 'test')
-rw-r--r--test/AngularSpec.js4
-rw-r--r--test/service/scopeSpec.js33
2 files changed, 37 insertions, 0 deletions
diff --git a/test/AngularSpec.js b/test/AngularSpec.js
index 81a4901b..53f62f00 100644
--- a/test/AngularSpec.js
+++ b/test/AngularSpec.js
@@ -110,6 +110,10 @@ describe('angular', function() {
expect(equals(undefined, undefined)).toBe(true);
});
+
+ it('should treat two NaNs as equal', function() {
+ expect(equals(NaN, NaN)).toBe(true);
+ });
});
describe('size', function() {
diff --git a/test/service/scopeSpec.js b/test/service/scopeSpec.js
index 71a27b33..6e8d78ff 100644
--- a/test/service/scopeSpec.js
+++ b/test/service/scopeSpec.js
@@ -305,6 +305,39 @@ describe('Scope', function() {
root.$digest(); //trigger
expect(listener).not.toHaveBeenCalled();
}));
+
+
+ it('should not infinitely digest when current value is NaN', inject(function($rootScope) {
+ $rootScope.$watch(function() { return NaN;});
+
+ expect(function() {
+ $rootScope.$digest();
+ }).not.toThrow();
+ }));
+
+
+ it('should always call the watchr with newVal and oldVal equal on the first run',
+ inject(function($rootScope) {
+ var log = [];
+ function logger(scope, newVal, oldVal) {
+ var val = (newVal === oldVal || (newVal !== oldVal && oldVal !== newVal)) ? newVal : 'xxx';
+ log.push(val);
+ };
+
+ $rootScope.$watch(function() { return NaN;}, logger);
+ $rootScope.$watch(function() { return undefined;}, logger);
+ $rootScope.$watch(function() { return '';}, logger);
+ $rootScope.$watch(function() { return false;}, logger);
+ $rootScope.$watch(function() { return {};}, logger);
+ $rootScope.$watch(function() { return 23;}, logger);
+
+ $rootScope.$digest();
+ expect(isNaN(log.shift())).toBe(true); //jasmine's toBe and toEqual don't work well with NaNs
+ expect(log).toEqual([undefined, '', false, {}, 23]);
+ log = []
+ $rootScope.$digest();
+ expect(log).toEqual([]);
+ }));
});