// Copyright 2013 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include #include "embedder.h" #include "flutter/fml/file.h" #include "flutter/fml/mapping.h" #include "flutter/fml/synchronization/waitable_event.h" #include "flutter/shell/platform/embedder/tests/embedder_config_builder.h" #include "flutter/shell/platform/embedder/tests/embedder_test.h" #include "flutter/testing/testing.h" namespace shell { namespace testing { using EmbedderTest = testing::EmbedderTest; TEST(EmbedderTestNoFixture, MustNotRunWithInvalidArgs) { EmbedderContext context; EmbedderConfigBuilder builder( context, EmbedderConfigBuilder::InitializationPreference::kNoInitialize); auto engine = builder.LaunchEngine(); ASSERT_FALSE(engine.is_valid()); } TEST_F(EmbedderTest, CanLaunchAndShutdownWithValidProjectArgs) { auto& context = GetEmbedderContext(); fml::AutoResetWaitableEvent latch; context.AddIsolateCreateCallback([&latch]() { latch.Signal(); }); EmbedderConfigBuilder builder(context); auto engine = builder.LaunchEngine(); ASSERT_TRUE(engine.is_valid()); // Wait for the root isolate to launch. latch.Wait(); engine.reset(); } TEST_F(EmbedderTest, CanLaunchAndShutdownMultipleTimes) { EmbedderConfigBuilder builder(GetEmbedderContext()); for (size_t i = 0; i < 3; ++i) { auto engine = builder.LaunchEngine(); ASSERT_TRUE(engine.is_valid()); FML_LOG(INFO) << "Engine launch count: " << i + 1; } } TEST_F(EmbedderTest, CanInvokeCustomEntrypoint) { auto& context = GetEmbedderContext(); static fml::AutoResetWaitableEvent latch; Dart_NativeFunction entrypoint = [](Dart_NativeArguments args) { latch.Signal(); }; context.AddNativeCallback("SayHiFromCustomEntrypoint", entrypoint); EmbedderConfigBuilder builder(context); builder.SetDartEntrypoint("customEntrypoint"); auto engine = builder.LaunchEngine(); latch.Wait(); ASSERT_TRUE(engine.is_valid()); } TEST_F(EmbedderTest, CanInvokeCustomEntrypointMacro) { auto& context = GetEmbedderContext(); fml::AutoResetWaitableEvent latch1; fml::AutoResetWaitableEvent latch2; fml::AutoResetWaitableEvent latch3; // Can be defined separately. auto entry1 = [&latch1](Dart_NativeArguments args) { FML_LOG(ERROR) << "In Callback 1"; latch1.Signal(); }; auto native_entry1 = CREATE_NATIVE_ENTRY(entry1); context.AddNativeCallback("SayHiFromCustomEntrypoint1", native_entry1); // Can be wrapped in in the args. auto entry2 = [&latch2](Dart_NativeArguments args) { FML_LOG(ERROR) << "In Callback 2"; latch2.Signal(); }; context.AddNativeCallback("SayHiFromCustomEntrypoint2", CREATE_NATIVE_ENTRY(entry2)); // Everything can be inline. context.AddNativeCallback( "SayHiFromCustomEntrypoint3", CREATE_NATIVE_ENTRY([&latch3](Dart_NativeArguments args) { FML_LOG(ERROR) << "In Callback 3"; latch3.Signal(); })); EmbedderConfigBuilder builder(context); builder.SetDartEntrypoint("customEntrypoint1"); auto engine = builder.LaunchEngine(); latch1.Wait(); latch2.Wait(); latch3.Wait(); ASSERT_TRUE(engine.is_valid()); } } // namespace testing } // namespace shell