Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
81144 views
1
var Contextify = require('../lib/contextify.js');
2
3
exports['basic tests'] = {
4
// Creating a context shouldn't fail.
5
'blank context' : function (test) {
6
var ctx = Contextify({});
7
test.notEqual(ctx, null);
8
test.notEqual(ctx, undefined);
9
test.done();
10
},
11
12
// Creating a context with sandbox shouldn't change existing sandbox
13
// properties.
14
'basic context' : function (test) {
15
var sandbox = {
16
prop1 : 'prop1',
17
prop2 : 'prop2'
18
};
19
Contextify(sandbox);
20
test.equal(sandbox.prop1, 'prop1');
21
test.equal(sandbox.prop2, 'prop2');
22
test.done();
23
},
24
25
'basic createContext' : function (test) {
26
var sandbox = {
27
prop1: 'prop1',
28
prop2: 'prop2'
29
};
30
var context = Contextify.createContext(sandbox);
31
test.equal(sandbox.prop1, 'prop1');
32
test.equal(sandbox.prop2, 'prop2');
33
test.done();
34
},
35
36
// Ensure that the correct properties exist on a wrapped sandbox.
37
'test contextified object extra properties' : function (test) {
38
var sandbox = Contextify({});
39
test.notEqual(sandbox.run, undefined);
40
test.notEqual(sandbox.getGlobal, undefined);
41
test.notEqual(sandbox.dispose, undefined);
42
test.done();
43
},
44
45
'createContext should not modify the sandbox' : function (test) {
46
var sandbox = {};
47
Contextify.createContext(sandbox);
48
test.equal(sandbox.run, undefined);
49
test.equal(sandbox.getGlobal, undefined);
50
test.equal(sandbox.dispose, undefined);
51
test.done();
52
},
53
54
// Passing undefined should create an empty context.
55
'test undefined sandbox' : function (test) {
56
// Should return an empty object.
57
test.notEqual(Contextify(undefined, undefined), undefined);
58
test.notEqual(Contextify(), undefined);
59
test.done();
60
},
61
62
'sandbox prototype properties should be searched' : function (test) {
63
var sandbox = {};
64
sandbox.__proto__ = {
65
prop1 : 'test'
66
};
67
Contextify(sandbox);
68
test.equal(sandbox.getGlobal().prop1, 'test');
69
test.done();
70
},
71
72
// Make sure properties that aren't there...aren't there.
73
'test for nonexistent properties' : function (test) {
74
var global = Contextify({}).getGlobal();
75
test.equal(global.test1, undefined);
76
test.done();
77
},
78
79
// Make sure properties with value "undefined" are there.
80
'test for "undefined" properties' : function (test) {
81
var sandbox = { x: undefined };
82
Contextify(sandbox);
83
sandbox.run("_x = x");
84
test.equal(sandbox._x, undefined);
85
test.done();
86
},
87
88
'test for "undefined" properties with createContext' : function (test) {
89
var sandbox = { x: undefined };
90
var context = Contextify.createContext(sandbox);
91
context.run("_x = x");
92
test.equal(sandbox._x, undefined);
93
test.done();
94
},
95
96
'test for "undefined" variables' : function (test) {
97
var sandbox = { };
98
Contextify(sandbox);
99
// In JavaScript a declared variable is set to 'undefined'.
100
sandbox.run("var y; (function() { var _y ; y = _y })()");
101
test.equal(sandbox._y, undefined);
102
// This should apply to top-level variables (global properties).
103
sandbox.run("var z; _z = z");
104
test.equal(sandbox._z, undefined);
105
// Make sure nothing wacky happens when accessing global declared but
106
// undefined variables.
107
test.equal(sandbox.getGlobal().z, undefined);
108
test.done();
109
},
110
111
// Make sure run can be called with a filename parameter.
112
'test run with filename' : function (test) {
113
var sandbox = Contextify();
114
sandbox.run('var x = 3', "test.js");
115
test.equal(sandbox.x, 3);
116
test.done();
117
},
118
119
// Make sure run can be called on a context
120
'test run with createContext' : function (test) {
121
var sandbox = {};
122
var context = Contextify.createContext(sandbox);
123
context.run('var x = 3', "test.js");
124
test.equal(sandbox.x, 3);
125
test.done();
126
},
127
128
// Make sure getters/setters on the sandbox object are used.
129
'test accessors on sandbox' : function (test) {
130
var sandbox = {};
131
sandbox.__defineGetter__('test', function () { return 3;});
132
sandbox.__defineSetter__('test2', function (val) { this.x = val;});
133
Contextify(sandbox);
134
var global = sandbox.getGlobal();
135
test.equal(global.test, 3);
136
sandbox.test2 = 5;
137
test.equal(sandbox.x, 5);
138
global.test2 = 7;
139
test.equal(global.x, 7);
140
test.equal(sandbox.x, 7);
141
test.done();
142
},
143
144
// Make sure dispose cleans up the sandbox.
145
'test dispose' : function (test) {
146
var sandbox = Contextify();
147
test.notEqual(sandbox.run, undefined);
148
test.notEqual(sandbox.getGlobal, undefined);
149
test.notEqual(sandbox.dispose, undefined);
150
sandbox.dispose();
151
test.throws(function () {
152
sandbox.run();
153
}, Error);
154
test.throws(function () {
155
sandbox.getGlobal();
156
}, Error);
157
test.throws(function () {
158
sandbox.dispose();
159
}, Error);
160
test.done();
161
}
162
};
163
164
exports['synchronous script tests'] = {
165
// Synchronous context script execution:
166
// Ensure that global variables are put on the sandbox object.
167
'global variables in scripts should go on sandbox' : function (test) {
168
var sandbox = {
169
prop1 : 'prop1',
170
prop2 : 'prop2'
171
};
172
Contextify(sandbox);
173
sandbox.run('x = 3');
174
test.equal(sandbox.x, 3);
175
test.done();
176
},
177
178
// Synchronous context script execution:
179
// Ensure that sandbox properties can be accessed as global variables.
180
'sandbox properties should be globals' : function (test) {
181
var sandbox = {
182
prop1 : 'prop1',
183
prop2 : 'prop2'
184
};
185
Contextify(sandbox);
186
sandbox.run("test1 = (prop1 == 'prop1');" +
187
"test2 = (prop2 == 'prop2');");
188
test.ok(sandbox.test1);
189
test.ok(sandbox.test2);
190
test.done();
191
}
192
};
193
194
exports['asynchronous script tests'] = {
195
// Asynchronous context script execution:
196
// Ensure that global variables are put on the sandbox object.
197
'global variables in scripts should go on sandbox' : function (test) {
198
var sandbox = {
199
setTimeout : setTimeout,
200
prop1 : 'prop1',
201
prop2 : 'prop2'
202
};
203
Contextify(sandbox);
204
sandbox.run('setTimeout(function () {x = 3}, 0);');
205
test.equal(sandbox.x, undefined);
206
setTimeout(function () {
207
test.equal(sandbox.x, 3);
208
test.done();
209
}, 0);
210
},
211
212
// Asynchronous context script execution:
213
// Ensure that sandbox properties can be accessed as global variables.
214
'sandbox properties should be globals' : function (test) {
215
var sandbox = {
216
setTimeout : setTimeout,
217
prop1 : 'prop1',
218
prop2 : 'prop2'
219
};
220
Contextify(sandbox);
221
sandbox.run("setTimeout(function () {" +
222
"test1 = (prop1 == 'prop1');" +
223
"test2 = (prop2 == 'prop2');" +
224
"}, 0)");
225
test.equal(sandbox.test1, undefined);
226
test.equal(sandbox.test2, undefined);
227
setTimeout(function () {
228
test.ok(sandbox.test1);
229
test.ok(sandbox.test2);
230
test.done();
231
}, 0);
232
},
233
234
// Asynchronous context script execution:
235
// Ensure that sandbox properties can be accessed as global variables.
236
'createContext: sandbox properties should be globals' : function (test) {
237
var sandbox = {
238
setTimeout : setTimeout,
239
prop1 : 'prop1',
240
prop2 : 'prop2'
241
};
242
var context = Contextify.createContext(sandbox);
243
context.run("setTimeout(function () {" +
244
"test1 = (prop1 == 'prop1');" +
245
"test2 = (prop2 == 'prop2');" +
246
"}, 0)");
247
test.equal(sandbox.test1, undefined);
248
test.equal(sandbox.test2, undefined);
249
setTimeout(function () {
250
test.ok(sandbox.test1);
251
test.ok(sandbox.test2);
252
test.done();
253
}, 0);
254
},
255
256
// Asynchronous context script execution:
257
// Ensure that async execution is safely executed after dispose
258
'setTimeout should not fail after dispose' : function (test) {
259
var sandbox = {
260
test: test,
261
setTimeout : setTimeout,
262
prop1 : 'prop1',
263
prop2 : 'prop2'
264
};
265
Contextify(sandbox);
266
sandbox.run("setTimeout(function () {" +
267
"test.ok(prop1 == 'prop1');" +
268
"test.ok(prop2 == 'prop2');" +
269
"test.done();" +
270
"}, 10)");
271
test.equal(sandbox.test1, undefined);
272
test.equal(sandbox.test2, undefined);
273
sandbox.dispose();
274
}
275
};
276
277
exports['test global'] = {
278
// Make sure getGlobal() works.
279
'basic test' : function (test) {
280
var sandbox = {
281
prop1 : 'prop1',
282
prop2 : 'prop2'
283
};
284
Contextify(sandbox);
285
var global = sandbox.getGlobal();
286
test.notDeepEqual(global, null);
287
test.notDeepEqual(global, undefined);
288
// Make sure global is forwarding properly.
289
test.equal(global.prop1, 'prop1');
290
test.equal(global.prop2, 'prop2');
291
global.prop3 = 'prop3';
292
test.equal(sandbox.prop3, 'prop3');
293
test.done();
294
},
295
296
// Make sure that references to the global are correct.
297
'self references to the global object' : function (test) {
298
var sandbox = Contextify({});
299
var global = sandbox.getGlobal();
300
sandbox.ref1 = global;
301
sandbox.ref2 = {
302
ref2 : global
303
};
304
sandbox.run("test1 = (this == ref1);" +
305
"test2 = (this == ref2.ref2);");
306
test.ok(sandbox.test1);
307
test.ok(sandbox.test2);
308
test.done();
309
},
310
311
// Make sure the enumerator is enumerating correctly.
312
'test enumerator' : function (test) {
313
var sandbox = {
314
prop1 : 'prop1',
315
prop2 : 'prop2'
316
};
317
var global = Contextify(sandbox).getGlobal();
318
var globalProps = Object.keys(global);
319
test.equal(globalProps.length, 5);
320
test.ok(globalProps.indexOf('prop1') != -1);
321
test.ok(globalProps.indexOf('prop2') != -1);
322
test.ok(globalProps.indexOf('run') != -1);
323
test.ok(globalProps.indexOf('getGlobal') != -1);
324
test.ok(globalProps.indexOf('dispose') != -1);
325
test.done();
326
},
327
328
// Make sure deleter is working.
329
'test deleter' : function (test) {
330
var sandbox = {
331
prop1 : 'prop1',
332
prop2 : 'prop2'
333
};
334
var global = Contextify(sandbox).getGlobal();
335
test.equal(Object.keys(global).length, 5);
336
test.equal(Object.keys(sandbox).length, 5);
337
delete global.prop1;
338
test.equal(Object.keys(global).length, 4);
339
test.equal(Object.keys(sandbox).length, 4);
340
delete global.prop2;
341
test.equal(Object.keys(global).length, 3);
342
test.equal(Object.keys(sandbox).length, 3);
343
delete global.run;
344
test.equal(Object.keys(global).length, 2);
345
test.equal(Object.keys(sandbox).length, 2);
346
delete global.getGlobal;
347
test.equal(Object.keys(global).length, 1);
348
test.equal(Object.keys(sandbox).length, 1);
349
delete global.dispose;
350
test.equal(Object.keys(global).length, 0);
351
test.equal(Object.keys(sandbox).length, 0);
352
test.done();
353
},
354
355
// Make sure the global's class name is the same as the sandbox.
356
'test global class name' : function (test) {
357
function DOMWindow () {};
358
var sandbox = Contextify(new DOMWindow());
359
var global = sandbox.getGlobal();
360
test.equal(sandbox.constructor.name, 'DOMWindow');
361
test.equal(sandbox.constructor.name, global.constructor.name);
362
sandbox.run('thisName = this.constructor.name');
363
test.equal(sandbox.thisName, sandbox.constructor.name);
364
test.done();
365
},
366
367
// Make sure functions in global scope are accessible through global.
368
'test global functions' : function (test) {
369
var sandbox = Contextify();
370
var global = sandbox.getGlobal();
371
sandbox.run("function testing () {}");
372
test.notEqual(global.testing, undefined);
373
test.done();
374
},
375
376
// Make sure global can be a receiver for run().
377
'test global.run()' : function (test) {
378
var global = Contextify().getGlobal();
379
global.run("x = 5");
380
test.equal(global.x, 5);
381
test.done();
382
},
383
384
// Make sure global can be a receiver for getGlobal().
385
'test global.getGlobal()' : function (test) {
386
var global = Contextify().getGlobal();
387
test.deepEqual(global, global.getGlobal());
388
test.done();
389
},
390
391
//Make sure global can be a receiver for dispose().
392
'test global.dispose()' : function (test) {
393
var sandbox = Contextify();
394
var global = sandbox.getGlobal();
395
test.notEqual(global.run, undefined);
396
test.notEqual(global.getGlobal, undefined);
397
test.notEqual(global.dispose, undefined);
398
global.dispose();
399
// It's not safe to use the global after disposing.
400
test.throws(function () {
401
sandbox.run();
402
}, Error);
403
test.throws(function () {
404
sandbox.getGlobal();
405
}, Error);
406
test.throws(function () {
407
sandbox.dispose();
408
}, Error);
409
test.done();
410
},
411
412
'test context delete global' : function (test) {
413
var sandbox = Contextify({});
414
sandbox.global = sandbox.getGlobal();
415
sandbox.run('delete global.global;');
416
test.ok(!sandbox.global);
417
sandbox.dispose();
418
test.done();
419
},
420
421
'test context delete unwritable global' : function (test) {
422
var sandbox = Contextify({});
423
Object.defineProperty(sandbox, 'global', {
424
enumerable: false,
425
configurable: false,
426
writable: false,
427
value: sandbox.getGlobal()
428
});
429
430
sandbox.run('delete global.global;');
431
test.ok(sandbox.global);
432
test.ok(sandbox.global.global);
433
sandbox.dispose();
434
test.done();
435
}
436
};
437
438
439
// Test that multiple contexts don't interfere with each other.
440
exports['test multiple contexts'] = function (test) {
441
var sandbox1 = {
442
prop1 : 'prop1',
443
prop2 : 'prop2'
444
};
445
var sandbox2 = {
446
prop1 : 'prop1',
447
prop2 : 'prop2'
448
};
449
var global1 = Contextify(sandbox1).getGlobal();
450
var global2 = Contextify(sandbox2).getGlobal();
451
test.equal(global1.prop1, 'prop1');
452
test.equal(global2.prop1, 'prop1');
453
sandbox1.run('test = 3');
454
sandbox2.run('test = 4');
455
test.equal(sandbox1.test, 3);
456
test.equal(global1.test, 3);
457
test.equal(sandbox2.test, 4);
458
test.equal(global2.test, 4);
459
test.done();
460
};
461
462
// Test console - segfaults in REPL.
463
exports['test console'] = function (test) {
464
var sandbox = {
465
console : console,
466
prop1 : 'prop1'
467
};
468
Contextify(sandbox);
469
test.doesNotThrow(function () {
470
sandbox.run('console.log(prop1);');
471
});
472
test.done();
473
};
474
475
476
// Test eval scope.
477
exports['test eval'] = {
478
'basic test' : function (test) {
479
var sandbox = Contextify();
480
sandbox.run('eval("test1 = 1")');
481
test.equal(sandbox.test1, 1);
482
sandbox.run('(function() { eval("test2 = 2") })()');
483
test.equal(sandbox.test2, 2);
484
test.done();
485
},
486
487
'this test' : function (test) {
488
var sandbox = Contextify();
489
sandbox.run('e = eval ; e("test1 = 1")');
490
test.equal(sandbox.test1, 1);
491
sandbox.run('var t = 1 ; (function() { var t = 2; test2 = eval("t") })()');
492
test.equal(sandbox.test2, 2);
493
sandbox.run('t = 1 ; (function() { var t = 2; e = eval; test3 = e("t") })()');
494
test.equal(sandbox.test3, 1);
495
sandbox.run('var t = 1 ; global = this; (function() { var t = 2; e = eval; test4 = global.eval.call(global, "t") })()');
496
test.equal(sandbox.test4, 1);
497
test.done();
498
}
499
};
500
501
502
// Make sure exceptions get thrown for invalid scripts.
503
exports['test exceptions'] = {
504
'basic test' : function (test) {
505
var sandbox = Contextify();
506
// Exceptions thrown from "run" will be from the Contextified context.
507
var ReferenceError = sandbox.run('ReferenceError');
508
var SyntaxError = sandbox.run('SyntaxError');
509
test.throws(function () {
510
sandbox.run('doh');
511
}, ReferenceError);
512
test.throws(function () {
513
sandbox.run('x = y');
514
}, ReferenceError);
515
test.throws(function () {
516
sandbox.run('function ( { (( }{);');
517
}, SyntaxError);
518
test.done();
519
},
520
521
'test double dispose() - sandbox' : function (test) {
522
var sandbox = Contextify();
523
test.doesNotThrow(function () {
524
sandbox.dispose();
525
});
526
test.throws(function () {
527
sandbox.dispose();
528
}, 'Called dispose() twice.');
529
test.done();
530
},
531
532
'test double dispose - global' : function (test) {
533
var sandbox = Contextify();
534
var global = sandbox.getGlobal();
535
test.doesNotThrow(function () {
536
global.dispose();
537
});
538
test.throws(function () {
539
global.dispose();
540
}, 'Called dispose() twice.');
541
test.done();
542
},
543
544
'test run() after dispose()' : function (test) {
545
var sandbox = Contextify();
546
test.doesNotThrow(function () {
547
sandbox.dispose();
548
});
549
test.throws(function () {
550
sandbox.run('var x = 3');
551
}, 'Called run() after dispose().');
552
test.done();
553
},
554
555
'test getGlobal() after dispose()' : function (test) {
556
var sandbox = Contextify();
557
test.doesNotThrow(function () {
558
sandbox.dispose();
559
});
560
test.throws(function () {
561
var g = sandbox.getGlobal();
562
}, 'Called getGlobal() after dispose().');
563
test.done();
564
}
565
};
566
567
exports['test scripts'] = {
568
'test createScript()' : function (test) {
569
var script = Contextify.createScript('var x = 3', 'test.js');
570
test.equal(typeof script.runInContext, 'function');
571
test.done();
572
},
573
574
'test createScript() without code' : function (test) {
575
test.throws(function () {
576
Contextify.createScript();
577
});
578
test.throws(function () {
579
Contextify.createScript(true);
580
});
581
test.throws(function () {
582
Contextify.createScript(null);
583
});
584
test.throws(function () {
585
Contextify.createScript(1);
586
});
587
test.done();
588
},
589
590
'test runInContext' : function (test) {
591
var sandbox = {};
592
var script = Contextify.createScript('var x = 3', 'test.js');
593
var context = Contextify.createContext(sandbox);
594
script.runInContext(context);
595
test.equal(sandbox.x, 3);
596
test.done();
597
}
598
};
599
600