Comparing version 0.1.0 to 0.2.0
@@ -0,1 +1,3 @@ | ||
'use strict'; | ||
var events = require('events'); | ||
@@ -33,9 +35,13 @@ | ||
Promise.prototype.state = function () { | ||
var result; | ||
if (this.resolved) { | ||
return 'fulfilled'; | ||
result = 'fulfilled'; | ||
} else if (this.rejected) { | ||
return 'rejected'; | ||
result = 'rejected'; | ||
} else { | ||
return 'pending'; | ||
result = 'pending'; | ||
} | ||
return result; | ||
}; | ||
@@ -108,2 +114,10 @@ | ||
this.onRejected(function (reason) { | ||
promise.reject(reason); | ||
}); | ||
other.onRejected(function (reason) { | ||
promise.reject(reason); | ||
}); | ||
return promise; | ||
@@ -157,9 +171,11 @@ }; | ||
/* Determine whether a value is "thenable" in Promises/A+ terminology. */ | ||
var thenable = function (x) { | ||
return x !== null && typeof x === 'object' && | ||
typeof x.then === 'function'; | ||
}; | ||
/* Compatibility with the Promises/A+ specification. */ | ||
Promise.prototype.then = function (onFulfilled, onRejected) { | ||
var promise = new Promise(), | ||
isPromise = function (x) { | ||
return x !== null && typeof x === 'object' && | ||
typeof x.then === 'function'; | ||
}; | ||
var promise = new Promise(); | ||
@@ -171,3 +187,3 @@ if (typeof onFulfilled === 'function') { | ||
if (isPromise(value)) { | ||
if (thenable(value)) { | ||
value.then(function (x) { | ||
@@ -194,5 +210,5 @@ promise.resolve(x); | ||
try { | ||
var reason = onRejected(reason); | ||
reason = onRejected(reason); | ||
if (isPromise(reason)) { | ||
if (thenable(reason)) { | ||
reason.then(function (x) { | ||
@@ -232,4 +248,4 @@ promise.resolve(x); | ||
return ''; | ||
} | ||
}; | ||
exports.Promise = Promise; |
@@ -7,3 +7,3 @@ { | ||
"keywords": ["promises", "monad", "functor", "promises-aplus"], | ||
"version": "0.1.0", | ||
"version": "0.2.0", | ||
"main": "./lib/pacta.js", | ||
@@ -10,0 +10,0 @@ "dependencies": {}, |
# pacta [![Build Status](https://travis-ci.org/mudge/pacta.png?branch=master)](https://travis-ci.org/mudge/pacta) | ||
```javascript | ||
{ 'pacta': '0.1.0' } | ||
{ 'pacta': '0.2.0' } | ||
``` | ||
@@ -40,2 +40,6 @@ | ||
Concretely, a promise can be represented by the following deterministic finite automaton: | ||
<p align="center"><img src="images/dfa.png" width="275" height="192" alt=""></p> | ||
For a worked example of using promises, see the | ||
@@ -73,3 +77,3 @@ [two](https://github.com/mudge/pacta/blob/master/example/codenames.js) | ||
[`Promise#resolve`](#promiseresolvex) and rejected with | ||
[`Promise#rejectreason`](#promiserejectreason). | ||
[`Promise#reject`](#promiserejectreason). | ||
@@ -304,2 +308,6 @@ To execute code on rejection without using | ||
If either of the original two promises is rejected, the resulting concatenated | ||
promise will also be rejected. Note that only the first rejection will count | ||
as further rejections will be ignored. | ||
See also [`Promise#conjoin`](#promiseconjoinp) and | ||
@@ -430,2 +438,4 @@ [`Promise#append`](#promiseappendp). | ||
[![Fantasy Land](images/fantasy-land.png)][Fantasy Land] [![Promises/A+](images/promises-aplus.png)][A+] | ||
## License | ||
@@ -432,0 +442,0 @@ |
@@ -0,1 +1,3 @@ | ||
'use strict'; | ||
/* An adapter for the Promises/A+ compatibility suite. */ | ||
@@ -2,0 +4,0 @@ var Promise = require('../lib/pacta').Promise; |
@@ -0,1 +1,4 @@ | ||
/*global describe, it, beforeEach */ | ||
'use strict'; | ||
var assert = require('assert'), | ||
@@ -6,3 +9,3 @@ Promise = require('../lib/pacta').Promise, | ||
describe('Promise', function () { | ||
var p, p2, p3, p4; | ||
var p, p2, p3; | ||
@@ -24,4 +27,2 @@ beforeEach(function () { | ||
}, 75); | ||
p4 = Promise.of('quux'); | ||
}); | ||
@@ -121,3 +122,3 @@ | ||
p = new Promise(); | ||
p.onRejected(function (reason) { | ||
p.onRejected(function () { | ||
triggered = true; | ||
@@ -134,3 +135,3 @@ done(); | ||
p = Promise.of(1); | ||
p.onRejected(function (reason) { | ||
p.onRejected(function () { | ||
triggered = true; | ||
@@ -165,3 +166,3 @@ }); | ||
it('yields the value after resolution', function (done) { | ||
p.map(function (x) { | ||
p.map(function () { | ||
/* Promise is now resolved so map again... */ | ||
@@ -258,11 +259,11 @@ p.map(function (x) { | ||
it('returns a fulfilled promise with the return value of onRejected', function (done) { | ||
var p = new Promise(); | ||
var p = new Promise(), p2; | ||
p.reject('foo'); | ||
var p2 = p.then(function (value) { | ||
return 1; | ||
}, function (reason) { | ||
return 'error'; | ||
}); | ||
p2 = p.then(function () { | ||
return 1; | ||
}, function () { | ||
return 'error'; | ||
}); | ||
@@ -278,5 +279,5 @@ p2.map(function (x) { | ||
var p = Promise.of('foo'), | ||
p2 = p.then(function (value) { | ||
p2 = p.then(function () { | ||
return 1; | ||
}, function (reason) { | ||
}, function () { | ||
return 'error'; | ||
@@ -339,2 +340,27 @@ }); | ||
}); | ||
it('is rejected if the first promise is rejected', function (done) { | ||
p.reject('Foo'); | ||
p.concat(p2).onRejected(function (reason) { | ||
assert.equal('Foo', reason); | ||
done(); | ||
}); | ||
}); | ||
it('is rejected if the second promise is rejected', function (done) { | ||
p2.reject('Foo'); | ||
p.concat(p2).onRejected(function (reason) { | ||
assert.equal('Foo', reason); | ||
done(); | ||
}); | ||
}); | ||
it('takes the first rejection if both promises are rejected', function (done) { | ||
p.reject('Foo'); | ||
p2.reject('Bar'); | ||
p.concat(p2).onRejected(function (reason) { | ||
assert.equal('Foo', reason); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
@@ -341,0 +367,0 @@ |
70474
15
813
443