https://github.com/dfkaye/vm-shim
working browser polyfill for node.js vm#runInContext() methods
https://github.com/dfkaye/vm-shim
Last synced: 5 months ago
JSON representation
working browser polyfill for node.js vm#runInContext() methods
- Host: GitHub
- URL: https://github.com/dfkaye/vm-shim
- Owner: dfkaye
- License: other
- Created: 2013-09-17T20:16:47.000Z (over 11 years ago)
- Default Branch: master
- Last Pushed: 2014-10-09T19:53:34.000Z (over 10 years ago)
- Last Synced: 2024-12-12T22:49:00.050Z (5 months ago)
- Language: JavaScript
- Homepage:
- Size: 523 KB
- Stars: 21
- Watchers: 2
- Forks: 3
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
vm-shim
=======[](https://travis-ci.org/dfkaye/vm-shim)
This began as a wan attempt to reproduce/polyfill/infill the Node.JS
`vm#runInContext()` methods in browsers. It has transformed
into the present tan muscular self-assured and smiling project before you.I'd wanted to show that shimming `vm` in the browser really could be done
directly, partly to avoid iframes (which
[vm-browserify](https://github.com/substack/vm-browserify) uses) to create and
clone globals and contexts, and partly to side-step Node.js's
*contra-normative* implementations of `runInContext` methods.It's actually a "why didn't I think of that?" solution to problems such as -
+ why don't `vm` methods accept *functions* as arguments, not just strings?
+ why don't `eval()` and `Function()` accept *functions* as arguments?
+ why do `eval()` and `Function()` leak un-var'd symbols to the global scope, in
browser & node.js environments?
+ how can we inspect items defined in closures?
+ how can we override (or mock) them?methods provided (so far)
----------------+ `vm#runInContext(code, context)`
+ `vm#runInNewContext(code, context)`
+ `vm#runInThisContext(code)`not provided (yet)
------------+ `vm#.createContext`
+ `vm#.createScript`
+ `script.runInThisContext()`
+ `script.runInNewContext([sandbox])`install
-------npm install vm-shim
git clone https://github.com/dfkaye/vm-shim.git
implementation
--------------Starting with `vm.runInContext(code, context)`, the `Function()` constructor is
at the core. The *code* param may be either a string __or a function__. The
*context* param is a simple object with key-value mappings. For any key on the
context, a new *var* for that key is prefixed to the code. The code is passed
in to `Function()` so that the keynames can't leak outside the new function's
scope.Refactored [8 Nov 2013]: a lot of little things involved - biggest is that
`runInThisContext` now uses `eval()` internally, and the other two use `with()`
inside of `Function()`. Who says you can't use `with()`?[10 Nov] Having discovered that eval() leaks globals (!?!) if symbols are not
var'd, all methods rely on a helper method to scrape EVERY global added by its
internal `eval()` (or `Function()`) call.[10 Dec]: removed use of `with`.
example tests
-------------The unit tests demonstrate how `runInContext` and `runInNewContext` methods work
by passing a `context` param containing a reference to the test's expectation
object or function.Example runInContext test passes the `expect` function via context argument:
it("overrides external scope vars with context attrs", function() {var attr = "shouldn't see this";
var context = {
attr: 'ok',
expect: expect // <-- pass expect here
};
vm.runInContext(function(){
expect(attr).toBe('ok');
expect(attr).not.toBe('should not see this');
}, context);
});Example runInNewContext test to verify context is returned:
it('should return context object', function () {
var context = { name: 'test' };
var result = vm.runInNewContext('', context);
expect(result).toBe(context);
expect(result.name).toBe('test');
});
Example runInThisContext test to verify accidental is not placed on global scope:
it("should not leak accidental (un-var'd) globals", function() {
vm.runInThisContext(function(){
accidental = 'defined';
});
expect(global.accidental).not.toBeDefined();
});node tests
----------Using Misko Hevery's [jasmine-node](https://github.com/mhevery/jasmine-node) to
run command line tests on node (even though this project initially aimed at a
browser shim).The `package.json` file defines three test script commands to run the tests via
jasmine-node without the browsers:npm test
# => jasmine-node --verbose ./test/suite.spec.jsnpm run test-vm
# => jasmine-node --verbose ./test/vm-shim.spec.jsbrowser tests
-------------Using @pivotallabs'
jasmine-2.0.0 for
the browser suite.__The *jasmine2* browser test page is viewable on
rawgit.__
Using Toby Ho's MAGNIFICENT [testemjs](https://github.com/airportyh/testem) to
drive tests in multiple browsers for jasmine-2.0.0 (see how to
[hack testem for jasmine 2](https://github.com/dfkaye/testem-jasmine2)), as well
as jasmine-node. The `testem.json` file uses the standalone test page above,
and also uses a custom launcher for jasmine-node (v 1.3.1).View both test types at the console by running:
testem -l j
history
-------------
Just noting for the record:+ Original idea emerged late at night 17 SEPT 2013
+ First implemented with rawgit approach 18 SEPT,
+ Full success including objects as properties of the context argument 19 SEPT.
+ Breaking the usual TDD procedure:
+ Started with console statements and prayer ~ removed both for real unit tests
+ Tape tests added 20 SEPT.
+ Jasmine tests/page added 20 SEPT.
+ Error, and leakage tests added 21 SEPT.
+ runInNewContext, runInThisContext methods added; runInContext refactored 4 OCT 2013
+ CoffeeScript test with jasmine-node added 6 OCT
+ tape test written in CoffeeScript test added 7 OCT
+ scope injection tests started 21 OCT
+ scope injection: spec started, tests updated, testem.json added 6 NOV 2013
+ massive refactoring 8 NOV 2013
- certain cases were just wrong (needed 'eval()' for 'runInThisContext()', e.g.)
- new/completed bdd specs for both vm-shim and scope mocking (temp name is 'mockScope')
+ last global leakage fixed 10 NOV
+ deleted CoffeeScript and tape tests (fun but extra work for now) 11 NOV
+ rawgit-viewable test page that also works with testem 12 NOV
+ moved mock scope stuff to metafunction project 18 NOV