-
Notifications
You must be signed in to change notification settings - Fork 152
Expand file tree
/
Copy pathTests.JavaScript.cpp
More file actions
113 lines (90 loc) · 3.88 KB
/
Tests.JavaScript.cpp
File metadata and controls
113 lines (90 loc) · 3.88 KB
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
#include <gtest/gtest.h>
#include <Babylon/AppRuntime.h>
#include <Babylon/Graphics/Device.h>
#include <Babylon/Polyfills/XMLHttpRequest.h>
#include <Babylon/Polyfills/Console.h>
#include <Babylon/Polyfills/Window.h>
#include <Babylon/Polyfills/Canvas.h>
#include <Babylon/Polyfills/Blob.h>
#include <Babylon/Plugins/NativeEngine.h>
#include <Babylon/Plugins/NativeEncoding.h>
#include <Babylon/ScriptLoader.h>
#include <cstdlib>
extern Babylon::Graphics::Configuration g_deviceConfig;
namespace
{
const char* EnumToString(Babylon::Polyfills::Console::LogLevel logLevel)
{
switch (logLevel)
{
case Babylon::Polyfills::Console::LogLevel::Log:
return "log";
case Babylon::Polyfills::Console::LogLevel::Warn:
return "warn";
case Babylon::Polyfills::Console::LogLevel::Error:
return "error";
}
return "unknown";
}
}
TEST(JavaScript, All)
{
// Change this to true to wait for the JavaScript debugger to attach (only applies to V8)
constexpr const bool waitForDebugger = false;
Babylon::Graphics::Device device{g_deviceConfig};
std::optional<Babylon::Polyfills::Canvas> nativeCanvas;
Babylon::AppRuntime::Options options{};
options.UnhandledExceptionHandler = [](const Napi::Error& error) {
std::cerr << "[Uncaught Error] " << Napi::GetErrorString(error) << std::endl;
std::quick_exit(1);
};
if (waitForDebugger)
{
std::cout << "Waiting for debugger..." << std::endl;
options.WaitForDebugger = true;
}
Babylon::AppRuntime runtime{options};
std::promise<int32_t> exitCodePromise;
runtime.Dispatch([&exitCodePromise, &device, &nativeCanvas](Napi::Env env) {
device.AddToJavaScript(env);
Babylon::Polyfills::XMLHttpRequest::Initialize(env);
Babylon::Polyfills::Console::Initialize(env, [](const char* message, Babylon::Polyfills::Console::LogLevel logLevel) {
std::cout << "[" << EnumToString(logLevel) << "] " << message << std::endl;
});
Babylon::Polyfills::Window::Initialize(env);
Babylon::Polyfills::Blob::Initialize(env);
nativeCanvas.emplace(Babylon::Polyfills::Canvas::Initialize(env));
Babylon::Plugins::NativeEngine::Initialize(env);
Babylon::Plugins::NativeEncoding::Initialize(env);
auto setExitCodeCallback = Napi::Function::New(
env, [&exitCodePromise](const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
exitCodePromise.set_value(info[0].As<Napi::Number>().Int32Value());
},
"setExitCode");
env.Global().Set("setExitCode", setExitCodeCallback);
});
Babylon::ScriptLoader loader{runtime};
loader.Eval("location = { href: '' };", ""); // Required for Mocha.js as we do not have a location in Babylon Native
loader.LoadScript("app:///Assets/babylon.max.js");
loader.LoadScript("app:///Assets/babylonjs.materials.js");
loader.LoadScript("app:///Assets/tests.javaScript.all.js");
device.StartRenderingCurrentFrame();
device.FinishRenderingCurrentFrame();
// Pump frames while JS tests run — tests use RAF internally and
// SubmitCommands requires an active frame.
auto exitCodeFuture = exitCodePromise.get_future();
while (exitCodeFuture.wait_for(std::chrono::milliseconds(16)) != std::future_status::ready)
{
device.StartRenderingCurrentFrame();
device.FinishRenderingCurrentFrame();
}
// Keep the frame open during shutdown so any pending JS work
// (e.g., SubmitCommands acquiring a FrameCompletionScope) can complete.
device.StartRenderingCurrentFrame();
auto exitCode = exitCodeFuture.get();
EXPECT_EQ(exitCode, 0);
// Runtime destructor joins the JS thread; must happen before Finish.
nativeCanvas.reset();
device.FinishRenderingCurrentFrame();
}