chore($q): replace plain TypeError with minErr+TypeError in cyclical resolve check

This commit is contained in:
Jeff Cross
2014-08-21 16:02:04 -07:00
parent 1b331f3729
commit 0462b688f9
3 changed files with 48 additions and 3 deletions

View File

@@ -0,0 +1,23 @@
@ngdoc error
@name $q:qcycle
@fullName Cannot resolve a promise with itself
@description
Occurs when resolving a promise with itself as the value, including returning the promise in a
function passed to `then`. The A+ 1.1 spec mandates that this behavior throw a TypeError.
https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure
```
var promise = $q.defer().promise;
//bad
promise.then(function (val) {
//Cannot return self
return promise;
});
//good
promise.then(function (val) {
return 'some other value';
});
```

View File

@@ -235,7 +235,7 @@ function $$QProvider() {
* @returns {object} Promise manager.
*/
function qFactory(nextTick, exceptionHandler) {
var $qMinErr = minErr('$q');
var $qMinErr = minErr('$q', TypeError);
function callOnce(self, resolveFn, rejectFn) {
var called = false;
function wrap(fn) {
@@ -338,8 +338,16 @@ function qFactory(nextTick, exceptionHandler) {
Deferred.prototype = {
resolve: function(val) {
if (this.promise.$$state.status) return;
if (val === this.promise) throw new TypeError('Cycle detected');
this.$$resolve(val);
if (val === this.promise) {
this.$$reject($qMinErr(
'qcycle',
"Expected promise to be resolved with value other than itself '{0}'",
val));
}
else {
this.$$resolve(val);
}
},
$$resolve: function(val) {

View File

@@ -815,6 +815,20 @@ describe('q', function() {
});
it('should complain if promise fulfilled with itself', function() {
var resolveSpy = jasmine.createSpy('resolve');
var rejectSpy = jasmine.createSpy('reject');
promise.then(resolveSpy, rejectSpy);
deferred.resolve(deferred.promise);
mockNextTick.flush();
expect(resolveSpy).not.toHaveBeenCalled();
expect(rejectSpy).toHaveBeenCalled();
expect(rejectSpy.calls[0].args[0].message).
toMatch(/\[\$q\:qcycle\] Expected promise to be resolved with value other than itself/);
});
it('should do nothing if a promise was previously resolved', function() {
promise.then(success(), error());
expect(logStr()).toBe('');