8 #include <wrl/client.h>
11 #include "flutter/fml/synchronization/count_down_latch.h"
12 #include "flutter/fml/synchronization/waitable_event.h"
13 #include "flutter/shell/platform/windows/testing/windows_test.h"
14 #include "flutter/shell/platform/windows/testing/windows_test_config_builder.h"
15 #include "flutter/shell/platform/windows/testing/windows_test_context.h"
16 #include "gtest/gtest.h"
17 #include "third_party/tonic/converter/dart_converter.h"
24 TEST(WindowsNoFixtureTest, GetTextureRegistrar) {
29 ASSERT_NE(engine,
nullptr);
31 EXPECT_NE(texture_registrar,
nullptr);
37 auto& context = GetContext();
38 WindowsConfigBuilder builder(context);
39 ViewControllerPtr controller{builder.Run()};
40 ASSERT_NE(controller,
nullptr);
44 TEST_F(WindowsTest, LaunchMainHasNoOutput) {
46 std::stringstream cout_buffer;
47 std::stringstream cerr_buffer;
48 std::streambuf* old_cout_buffer = std::cout.rdbuf();
49 std::streambuf* old_cerr_buffer = std::cerr.rdbuf();
50 std::cout.rdbuf(cout_buffer.rdbuf());
51 std::cerr.rdbuf(cerr_buffer.rdbuf());
53 auto& context = GetContext();
54 WindowsConfigBuilder builder(context);
55 ViewControllerPtr controller{builder.Run()};
56 ASSERT_NE(controller,
nullptr);
59 std::cout.rdbuf(old_cout_buffer);
60 std::cerr.rdbuf(old_cerr_buffer);
63 std::string cout = cout_buffer.str();
64 std::string cerr = cerr_buffer.str();
65 EXPECT_TRUE(cout.empty());
66 EXPECT_TRUE(cerr.empty());
70 TEST_F(WindowsTest, LaunchCustomEntrypoint) {
71 auto& context = GetContext();
72 WindowsConfigBuilder builder(context);
73 builder.SetDartEntrypoint(
"customEntrypoint");
74 ViewControllerPtr controller{builder.Run()};
75 ASSERT_NE(controller,
nullptr);
83 TEST_F(WindowsTest, LaunchCustomEntrypointInEngineRunInvocation) {
84 auto& context = GetContext();
85 WindowsConfigBuilder builder(context);
86 EnginePtr engine{builder.InitializeEngine()};
87 ASSERT_NE(engine,
nullptr);
93 TEST_F(WindowsTest, LaunchHeadlessEngine) {
94 auto& context = GetContext();
95 WindowsConfigBuilder builder(context);
96 EnginePtr engine{builder.InitializeEngine()};
97 ASSERT_NE(engine,
nullptr);
107 TEST_F(WindowsTest, LaunchConflictingCustomEntrypoints) {
108 auto& context = GetContext();
109 WindowsConfigBuilder builder(context);
110 builder.SetDartEntrypoint(
"customEntrypoint");
111 EnginePtr engine{builder.InitializeEngine()};
112 ASSERT_NE(engine,
nullptr);
118 TEST_F(WindowsTest, VerifyNativeFunction) {
119 auto& context = GetContext();
120 WindowsConfigBuilder builder(context);
121 builder.SetDartEntrypoint(
"verifyNativeFunction");
123 fml::AutoResetWaitableEvent latch;
125 CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) { latch.Signal(); });
126 context.AddNativeFunction(
"Signal", native_entry);
128 ViewControllerPtr controller{builder.Run()};
129 ASSERT_NE(controller,
nullptr);
137 TEST_F(WindowsTest, VerifyNativeFunctionWithParameters) {
138 auto& context = GetContext();
139 WindowsConfigBuilder builder(context);
140 builder.SetDartEntrypoint(
"verifyNativeFunctionWithParameters");
142 bool bool_value =
false;
143 fml::AutoResetWaitableEvent latch;
144 auto native_entry = CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
145 auto handle = Dart_GetNativeBooleanArgument(args, 0, &bool_value);
146 ASSERT_FALSE(Dart_IsError(handle));
149 context.AddNativeFunction(
"SignalBoolValue", native_entry);
151 ViewControllerPtr controller{builder.Run()};
152 ASSERT_NE(controller,
nullptr);
156 EXPECT_TRUE(bool_value);
160 TEST_F(WindowsTest, PlatformExecutable) {
161 auto& context = GetContext();
162 WindowsConfigBuilder builder(context);
163 builder.SetDartEntrypoint(
"readPlatformExecutable");
165 std::string executable_name;
166 fml::AutoResetWaitableEvent latch;
167 auto native_entry = CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
168 auto handle = Dart_GetNativeArgument(args, 0);
169 ASSERT_FALSE(Dart_IsError(handle));
170 executable_name = tonic::DartConverter<std::string>::FromDart(handle);
173 context.AddNativeFunction(
"SignalStringValue", native_entry);
175 ViewControllerPtr controller{builder.Run()};
176 ASSERT_NE(controller,
nullptr);
180 EXPECT_EQ(executable_name,
"flutter_windows_unittests.exe");
185 TEST_F(WindowsTest, VerifyNativeFunctionWithReturn) {
186 auto& context = GetContext();
187 WindowsConfigBuilder builder(context);
188 builder.SetDartEntrypoint(
"verifyNativeFunctionWithReturn");
190 bool bool_value_to_return =
true;
191 fml::CountDownLatch latch(2);
192 auto bool_return_entry = CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
193 Dart_SetBooleanReturnValue(args, bool_value_to_return);
196 context.AddNativeFunction(
"SignalBoolReturn", bool_return_entry);
198 bool bool_value_passed =
false;
199 auto bool_pass_entry = CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
200 auto handle = Dart_GetNativeBooleanArgument(args, 0, &bool_value_passed);
201 ASSERT_FALSE(Dart_IsError(handle));
204 context.AddNativeFunction(
"SignalBoolValue", bool_pass_entry);
206 ViewControllerPtr controller{builder.Run()};
207 ASSERT_NE(controller,
nullptr);
211 EXPECT_TRUE(bool_value_passed);
217 fml::AutoResetWaitableEvent frame_scheduled_latch;
218 fml::AutoResetWaitableEvent frame_drawn_latch;
219 std::thread::id thread_id;
223 CreateNewThread(
"test_platform_thread")->PostTask([&]() {
224 captures.thread_id = std::this_thread::get_id();
226 auto& context = GetContext();
227 WindowsConfigBuilder builder(context);
228 builder.SetDartEntrypoint(
"drawHelloWorld");
230 auto native_entry = CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
231 ASSERT_FALSE(captures.frame_drawn_latch.IsSignaledForTest());
232 captures.frame_scheduled_latch.Signal();
234 context.AddNativeFunction(
"NotifyFirstFrameScheduled", native_entry);
236 ViewControllerPtr controller{builder.Run()};
237 ASSERT_NE(controller,
nullptr);
244 auto captures =
static_cast<Captures*
>(
user_data);
246 ASSERT_TRUE(captures->frame_scheduled_latch.IsSignaledForTest());
249 ASSERT_EQ(std::this_thread::get_id(), captures->thread_id);
252 captures->frame_drawn_latch.Signal();
253 ::PostQuitMessage(0);
259 while (::GetMessage(&msg,
nullptr, 0, 0)) {
260 ::TranslateMessage(&msg);
261 ::DispatchMessage(&msg);
265 captures.frame_drawn_latch.Wait();
268 TEST_F(WindowsTest, GetGraphicsAdapter) {
269 auto& context = GetContext();
270 WindowsConfigBuilder builder(context);
271 ViewControllerPtr controller{builder.Run()};
272 ASSERT_NE(controller,
nullptr);
275 Microsoft::WRL::ComPtr<IDXGIAdapter> dxgi_adapter;
277 ASSERT_NE(dxgi_adapter,
nullptr);
278 DXGI_ADAPTER_DESC desc{};
279 ASSERT_TRUE(SUCCEEDED(dxgi_adapter->GetDesc(&desc)));