Skip to content
File

Blob: src/workerd/api/tests/worker-test.js

javascript87 lines
1// Copyright (c) 2025 Cloudflare, Inc.
2// Licensed under the Apache 2.0 license found in the LICENSE file or at:
3// https://opensource.org/licenses/Apache-2.0
4import { throws, rejects, strictEqual } from 'node:assert';
5import { mock } from 'node:test';
6 
7// We allow eval and new Function() during startup (global scope evaluation).
8strictEqual(eval('1+1'), 2); // should work
9const StartupFunction = new Function('return 1+1');
10strictEqual(StartupFunction(), 2); // should work
11await Promise.resolve();
12strictEqual(eval('1+1'), 2); // should still work
13const StartupFunction2 = new Function('return 2+2');
14strictEqual(StartupFunction2(), 4); // should still work
15strictEqual((await import('module-does-eval')).default, 2); // should work
16 
17export const testStartupEval = {
18 async test() {
19 throws(() => eval('console.log("This should not work")'), {
20 message: /Code generation from strings disallowed for this context/,
21 });
22 
23 throws(() => new Function('console.log("This should not work")'), {
24 message: /Code generation from strings disallowed for this context/,
25 });
26 
27 await rejects(() => import('another-module-does-eval'), {
28 message: /Code generation from strings disallowed for this context/,
29 });
30 
31 // eval() with no args or a non-string arg is allowed (V8 returns the value
32 // as-is per spec since there is no string to compile).
33 strictEqual(eval(), undefined);
34 strictEqual(eval(undefined), undefined);
35 
36 // new Function() with params and a string body is still blocked.
37 throws(() => new Function('a', 'b', 'return a + b'), {
38 message: /Code generation from strings disallowed for this context/,
39 });
40 
41 // new Function() with params and undefined body is also blocked (the body
42 // becomes the string "undefined" via ToString).
43 throws(() => new Function('a', 'b', undefined), {
44 message: /Code generation from strings disallowed for this context/,
45 });
46 
47 // new Function() with no arguments is allowed (the synthesized source
48 // matches the known empty-body, no-parameter pattern).
49 const emptyFn = new Function();
50 strictEqual(typeof emptyFn, 'function');
51 
52 // Extending Function with super() and no arguments is also allowed.
53 class Foo extends Function {}
54 const foo = new Foo();
55 strictEqual(typeof foo, 'function');
56 },
57};
58 
59// Test verifies that explicit resource management is, in fact, enabled.
60export const disposeTest = {
61 test() {
62 const fn = mock.fn();
63 {
64 using _ = {
65 [Symbol.dispose]() {
66 fn();
67 },
68 };
69 }
70 strictEqual(fn.mock.callCount(), 1);
71 },
72};
73 
74export const asyncDisposeTest = {
75 async test() {
76 const fn = mock.fn(async () => {});
77 {
78 await using _ = {
79 async [Symbol.asyncDispose]() {
80 await fn();
81 },
82 };
83 }
84 strictEqual(fn.mock.callCount(), 1);
85 },
86};