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

Skip to content

Commit ca709ed

Browse files
committed
added __with__ function according to proposed syntax in issue jhnns#29
1 parent 74dcfec commit ca709ed

File tree

3 files changed

+102
-5
lines changed

3 files changed

+102
-5
lines changed

lib/__set__.js

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,21 @@ function __set__() {
4646
};
4747
}
4848

49-
module.exports = __set__;
49+
function __with__() {
50+
var args = arguments;
51+
return function(callback) {
52+
if (typeof callback !== "function") {
53+
throw new TypeError("__with__ expects a callback function")
54+
}
55+
56+
var undo = __set__.apply(null, args)
57+
try {
58+
callback();
59+
}
60+
finally {
61+
undo();
62+
}
63+
}
64+
}
65+
66+
module.exports = {"__set__": __set__, "__with__": __with__}

lib/rewire.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
var Module = require("module"),
22
fs = require("fs"),
33
__get__ = require("./__get__.js"),
4-
__set__ = require("./__set__.js"),
4+
setModule = require ("./__set__.js"),
5+
__set__ = setModule["__set__"],
6+
__with__ = setModule["__with__"],
57
getImportGlobalsSrc = require("./getImportGlobalsSrc.js"),
68
detectStrictMode = require("./detectStrictMode.js"),
79
moduleEnv = require("./moduleEnv.js");
810

911
var __get__Src = __get__.toString(),
10-
__set__Src = __set__.toString();
12+
__set__Src = __set__.toString(),
13+
__with_Src = __with__.toString();
1114

1215
/**
1316
* Does actual rewiring the module. For further documentation @see index.js
@@ -44,6 +47,7 @@ function internalRewire(parentModulePath, targetPath) {
4447
appendix = "\n";
4548
appendix += "module.exports.__set__ = " + __set__Src + "; ";
4649
appendix += "module.exports.__get__ = " + __get__Src + "; ";
50+
appendix += "module.exports.__with__ = " + __with_Src + "; ";
4751

4852
// Check if the module uses the strict mode.
4953
// If so we must ensure that "use strict"; stays at the beginning of the module.
@@ -58,4 +62,4 @@ function internalRewire(parentModulePath, targetPath) {
5862
return targetModule.exports;
5963
}
6064

61-
module.exports = internalRewire;
65+
module.exports = internalRewire;

test/__set__.test.js

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
var expect = require("expect.js"),
2-
__set__ = require("../lib/__set__.js"),
2+
setModule = require("../lib/__set__.js")
3+
__set__ = setModule["__set__"],
4+
__with__ = setModule["__with__"],
35
vm = require("vm"),
46

57
expectReferenceError = expectError(ReferenceError),
@@ -125,3 +127,77 @@ describe("__set__", function () {
125127
}).to.throwException(expectTypeError);
126128
});
127129
});
130+
131+
describe("__with__", function() {
132+
var moduleFake;
133+
134+
beforeEach(function () {
135+
moduleFake = {
136+
myValue: 0, // copy by value
137+
myReference: {} // copy by reference
138+
};
139+
140+
//__with__ requires __set__ to be in scope
141+
vm.runInNewContext(
142+
"__set__ = " + __set__.toString() + "; " +
143+
"__with__ = " + __with__.toString() + "; " +
144+
"getValue = function () { return myValue; }; " +
145+
"getReference = function () { return myReference; }; ",
146+
moduleFake
147+
);
148+
});
149+
150+
it("should return a function that can be invoked with a callback which guarantees __sets__ undo function is called for you at the end", function () {
151+
var newObj = { hello: "hello" };
152+
153+
expect(moduleFake.getValue()).to.be(0);
154+
expect(moduleFake.getReference()).to.eql({});
155+
156+
moduleFake.__with__({
157+
myValue: 2,
158+
myReference: newObj
159+
})(function() {
160+
//changes will be visible from within this callback function
161+
expect(moduleFake.getValue()).to.be(2);
162+
expect(moduleFake.getReference()).to.be(newObj);
163+
})
164+
165+
//undo will automatically get called for you after returning from your callback function
166+
expect(moduleFake.getValue()).to.be(0);
167+
expect(moduleFake.getReference()).to.eql({});
168+
});
169+
170+
it("should still revert values if the callback throws an exception", function(){
171+
var newObj = { hello: "hello" };
172+
function withError(){
173+
moduleFake.__with__({
174+
myValue: 2,
175+
myReference: newObj
176+
})(function() {
177+
throw new Error("something went wrong...");
178+
})
179+
}
180+
expect(withError).to.throwError();
181+
expect(moduleFake.getValue()).to.be(0);
182+
expect(moduleFake.getReference()).to.eql({});
183+
});
184+
185+
it("should throw an error if something other than a function is passed as the callback", function() {
186+
var newObj = { hello: "hello" },
187+
withFunction = moduleFake.__with__({
188+
myValue: 2,
189+
myReference: newObj
190+
})
191+
callWithFunction = function(){
192+
var args = arguments;
193+
return function() {
194+
withFunction.apply(null, args);
195+
};
196+
};
197+
198+
expect(callWithFunction(1)).to.throwError();
199+
expect(callWithFunction("a string")).to.throwError();
200+
expect(callWithFunction({})).to.throwError();
201+
expect(callWithFunction(function(){})).to.not.throwError();
202+
});
203+
});

0 commit comments

Comments
 (0)