-
-
Notifications
You must be signed in to change notification settings - Fork 568
/
Copy pathShadowRealmTests.cs
127 lines (101 loc) · 4.73 KB
/
ShadowRealmTests.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
using Jint.Native.Object;
namespace Jint.Tests.PublicInterface;
public class ShadowRealmTests
{
[Fact]
public void CanUseViaEngineMethods()
{
var engine = new Engine(options => options.EnableModules(GetBasePath()));
var shadowRealm = engine.Intrinsics.ShadowRealm.Construct();
// lexically scoped (let/const) are visible during single call
Assert.Equal(123, shadowRealm.Evaluate("const s = 123; const f = () => s; f();"));
Assert.Equal(true, shadowRealm.Evaluate("typeof f === 'undefined'"));
// vars hold longer
Assert.Equal(456, shadowRealm.Evaluate("function foo() { return 456; }; foo();"));
Assert.Equal(456, shadowRealm.Evaluate("foo();"));
// not visible in global engine though
Assert.Equal(true, engine.Evaluate("typeof foo === 'undefined'"));
// modules
var importValue = shadowRealm.ImportValue("./modules/format-name.js", "formatName");
var formatName = (ObjectInstance) importValue.UnwrapIfPromise();
var result = engine.Invoke(formatName, "John", "Doe").AsString();
Assert.Equal("John Doe", result);
}
[Fact]
public void MultipleShadowRealmsDoNotInterfere()
{
var engine = new Engine(options => options.EnableModules(GetBasePath()));
engine.SetValue("message", "world");
engine.Evaluate("function hello() {return message}");
Assert.Equal("world", engine.Evaluate("hello();"));
var shadowRealm = engine.Intrinsics.ShadowRealm.Construct();
shadowRealm.SetValue("message", "realm 1");
shadowRealm.Evaluate("function hello() {return message}");
var shadowRealm2 = engine.Intrinsics.ShadowRealm.Construct();
shadowRealm2.SetValue("message", "realm 2");
shadowRealm2.Evaluate("function hello() {return message}");
// Act & Assert
Assert.Equal("realm 1", shadowRealm.Evaluate("hello();"));
Assert.Equal("realm 2", shadowRealm2.Evaluate("hello();"));
}
[Fact]
public void MultipleShadowRealm_SettingGlobalVariable_DoNotInterfere()
{
var engine = new Engine(options => options.EnableModules(GetBasePath()));
engine.SetValue("message", "hello ");
engine.Evaluate("(function hello() {message += \"engine\"})();");
var shadowRealm = engine.Intrinsics.ShadowRealm.Construct();
shadowRealm.SetValue("message", "hello ");
shadowRealm.Evaluate("(function hello() {message += \"realm 1\"})();");
var shadowRealm2 = engine.Intrinsics.ShadowRealm.Construct();
shadowRealm2.SetValue("message", "hello ");
shadowRealm2.Evaluate("(function hello() {message += \"realm 2\"})();");
// Act & Assert
Assert.Equal("hello engine", engine.Evaluate("message"));
Assert.Equal("hello realm 1", shadowRealm.Evaluate("message"));
Assert.Equal("hello realm 2", shadowRealm2.Evaluate("message"));
}
[Fact]
public void CanReuseScriptWithShadowRealm()
{
var engine = new Engine(options => options.EnableModules(GetBasePath()));
engine.SetValue("message", "engine");
var shadowRealm = engine.Intrinsics.ShadowRealm.Construct();
shadowRealm.SetValue("message", "realm 1");
var shadowRealm2 = engine.Intrinsics.ShadowRealm.Construct();
shadowRealm2.SetValue("message", "realm 2");
var script = Engine.PrepareScript("(function hello() {return \"hello \" + message})();");
// Act & Assert
Assert.Equal("hello engine", engine.Evaluate(script));
Assert.Equal("hello realm 1", shadowRealm.Evaluate(script));
Assert.Equal("hello realm 2", shadowRealm2.Evaluate(script));
}
private static string GetBasePath()
{
var assemblyDirectory = new DirectoryInfo(AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory);
var current = assemblyDirectory;
var binDirectory = $"{Path.DirectorySeparatorChar}bin{Path.DirectorySeparatorChar}";
while (current is not null)
{
if (current.FullName.Contains(binDirectory) || current.Name == "bin")
{
current = current.Parent;
continue;
}
var testDirectory = current.GetDirectories("Jint.Tests").FirstOrDefault();
if (testDirectory == null)
{
current = current.Parent;
continue;
}
// found it
current = testDirectory;
break;
}
if (current is null)
{
throw new NullReferenceException($"Could not find tests base path, assemblyPath: {assemblyDirectory}");
}
return Path.Combine(current.FullName, "Runtime", "Scripts");
}
}