Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 70841d9

Browse files
committed
Add promise feature to __with__
1 parent d044f04 commit 70841d9

File tree

2 files changed

+79
-3
lines changed

2 files changed

+79
-3
lines changed

lib/__with__.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ function __with__() {
1515
var args = arguments;
1616

1717
return function (callback) {
18-
var undo;
18+
var undo,
19+
returned,
20+
isPromise;
1921

2022
if (typeof callback !== "function") {
2123
throw new TypeError("__with__ expects a callback function");
@@ -24,9 +26,16 @@ function __with__() {
2426
undo = module.exports.__set__.apply(null, args);
2527

2628
try {
27-
callback();
29+
returned = callback();
30+
isPromise = returned && typeof returned.then === "function";
31+
if (isPromise) {
32+
returned.then(undo, undo);
33+
return returned;
34+
}
2835
} finally {
29-
undo();
36+
if (!isPromise) {
37+
undo();
38+
}
3039
}
3140
};
3241
}

test/__with__.test.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,4 +111,71 @@ describe("__with__", function() {
111111
expect(callWithFunction({})).to.throwError(expectTypeError);
112112
expect(callWithFunction(function(){})).to.not.throwError(expectTypeError);
113113
});
114+
115+
describe("using promises", function () {
116+
var promiseFake;
117+
118+
beforeEach(function () {
119+
promiseFake = {
120+
then: function (onResolve, onReject) {
121+
promiseFake.onResolve = onResolve;
122+
promiseFake.onReject = onReject;
123+
}
124+
};
125+
});
126+
127+
it("should pass the returned promise through", function () {
128+
var fn = moduleFake.__with__({});
129+
130+
expect(fn(function () {
131+
return promiseFake;
132+
})).to.equal(promiseFake);
133+
});
134+
135+
it("should not undo any changes until the promise has been resolved", function () {
136+
expect(moduleFake.getValue()).to.be(0);
137+
expect(moduleFake.getReference()).to.eql({});
138+
139+
moduleFake.__with__({
140+
myValue: 2,
141+
myReference: newObj
142+
})(function () {
143+
return promiseFake;
144+
});
145+
146+
// the change should still be present at this point
147+
expect(moduleFake.getValue()).to.be(2);
148+
expect(moduleFake.getReference()).to.be(newObj);
149+
150+
promiseFake.onResolve();
151+
152+
// now everything should be back to normal
153+
expect(moduleFake.getValue()).to.be(0);
154+
expect(moduleFake.getReference()).to.eql({});
155+
});
156+
157+
it("should also undo any changes if the promise has been rejected", function () {
158+
expect(moduleFake.getValue()).to.be(0);
159+
expect(moduleFake.getReference()).to.eql({});
160+
161+
moduleFake.__with__({
162+
myValue: 2,
163+
myReference: newObj
164+
})(function () {
165+
return promiseFake;
166+
});
167+
168+
// the change should still be present at this point
169+
expect(moduleFake.getValue()).to.be(2);
170+
expect(moduleFake.getReference()).to.be(newObj);
171+
172+
promiseFake.onReject();
173+
174+
// now everything should be back to normal
175+
expect(moduleFake.getValue()).to.be(0);
176+
expect(moduleFake.getReference()).to.eql({});
177+
});
178+
179+
});
180+
114181
});

0 commit comments

Comments
 (0)