Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Windows] Add engine builder to simplify tests #38546

Merged
merged 2 commits into from
Dec 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions shell/platform/windows/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,8 @@ executable("flutter_windows_unittests") {
"testing/engine_modifier.h",
"testing/flutter_window_test.cc",
"testing/flutter_window_test.h",
"testing/flutter_windows_engine_builder.cc",
"testing/flutter_windows_engine_builder.h",
"testing/mock_direct_manipulation.h",
"testing/mock_gl_functions.h",
"testing/mock_text_input_manager.cc",
Expand Down
97 changes: 39 additions & 58 deletions shell/platform/windows/flutter_windows_engine_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "flutter/shell/platform/embedder/test_utils/proc_table_replacement.h"
#include "flutter/shell/platform/windows/flutter_windows_view.h"
#include "flutter/shell/platform/windows/testing/engine_modifier.h"
#include "flutter/shell/platform/windows/testing/flutter_windows_engine_builder.h"
#include "flutter/shell/platform/windows/testing/mock_window_binding_handler.h"
#include "flutter/shell/platform/windows/testing/test_keyboard.h"
#include "flutter/shell/platform/windows/testing/windows_test.h"
Expand All @@ -21,34 +22,14 @@
namespace flutter {
namespace testing {

namespace {

// Returns an engine instance configured with dummy project path values.
std::unique_ptr<FlutterWindowsEngine> GetTestEngine() {
FlutterDesktopEngineProperties properties = {};
properties.assets_path = L"C:\\foo\\flutter_assets";
properties.icu_data_path = L"C:\\foo\\icudtl.dat";
properties.aot_library_path = L"C:\\foo\\aot.so";

std::vector<const char*> test_arguments = {"arg1", "arg2"};
properties.dart_entrypoint_argc = test_arguments.size();
properties.dart_entrypoint_argv = test_arguments.data();

FlutterProjectBundle project(properties);
auto engine = std::make_unique<FlutterWindowsEngine>(project);

EngineModifier modifier(engine.get());
// Force the non-AOT path unless overridden by the test.
modifier.embedder_api().RunsAOTCompiledDartCode = []() { return false; };

return engine;
}
} // namespace

class FlutterWindowsEngineTest : public WindowsTest {};

TEST_F(FlutterWindowsEngineTest, RunDoesExpectedInitialization) {
std::unique_ptr<FlutterWindowsEngine> engine = GetTestEngine();
FlutterWindowsEngineBuilder builder{GetContext()};
builder.AddDartEntrypointArgument("arg1");
builder.AddDartEntrypointArgument("arg2");

std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
EngineModifier modifier(engine.get());

// The engine should be run with expected configuration values.
Expand All @@ -67,8 +48,8 @@ TEST_F(FlutterWindowsEngineTest, RunDoesExpectedInitialization) {
EXPECT_EQ(config->type, kOpenGL);
EXPECT_EQ(user_data, engine_instance);
// Spot-check arguments.
EXPECT_STREQ(args->assets_path, "C:\\foo\\flutter_assets");
EXPECT_STREQ(args->icu_data_path, "C:\\foo\\icudtl.dat");
EXPECT_NE(args->assets_path, nullptr);
EXPECT_NE(args->icu_data_path, nullptr);
Copy link
Member Author

@loic-sharma loic-sharma Dec 29, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These paths are now in your build's out directory

EXPECT_EQ(args->dart_entrypoint_argc, 2U);
EXPECT_EQ(strcmp(args->dart_entrypoint_argv[0], "arg1"), 0);
EXPECT_EQ(strcmp(args->dart_entrypoint_argv[1], "arg2"), 0);
Expand Down Expand Up @@ -159,7 +140,8 @@ TEST_F(FlutterWindowsEngineTest, RunDoesExpectedInitialization) {
}

TEST_F(FlutterWindowsEngineTest, ConfiguresFrameVsync) {
std::unique_ptr<FlutterWindowsEngine> engine = GetTestEngine();
FlutterWindowsEngineBuilder builder{GetContext()};
std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
EngineModifier modifier(engine.get());
bool on_vsync_called = false;

Expand All @@ -185,7 +167,8 @@ TEST_F(FlutterWindowsEngineTest, ConfiguresFrameVsync) {
}

TEST_F(FlutterWindowsEngineTest, RunWithoutANGLEUsesSoftware) {
std::unique_ptr<FlutterWindowsEngine> engine = GetTestEngine();
FlutterWindowsEngineBuilder builder{GetContext()};
std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
EngineModifier modifier(engine.get());

modifier.embedder_api().NotifyDisplayUpdate =
Expand Down Expand Up @@ -237,7 +220,8 @@ TEST_F(FlutterWindowsEngineTest, RunWithoutANGLEUsesSoftware) {
}

TEST_F(FlutterWindowsEngineTest, SendPlatformMessageWithoutResponse) {
std::unique_ptr<FlutterWindowsEngine> engine = GetTestEngine();
FlutterWindowsEngineBuilder builder{GetContext()};
std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
EngineModifier modifier(engine.get());

const char* channel = "test";
Expand All @@ -263,14 +247,10 @@ TEST_F(FlutterWindowsEngineTest, SendPlatformMessageWithoutResponse) {
}

TEST_F(FlutterWindowsEngineTest, PlatformMessageRoundTrip) {
FlutterDesktopEngineProperties properties = {};
properties.assets_path = GetContext().GetAssetsPath().c_str();
properties.icu_data_path = GetContext().GetIcuDataPath().c_str();
properties.dart_entrypoint = "hiPlatformChannels";

FlutterProjectBundle project(properties);
auto engine = std::make_unique<FlutterWindowsEngine>(project);
FlutterWindowsEngineBuilder builder{GetContext()};
builder.SetDartEntrypoint("hiPlatformChannels");

std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
EngineModifier modifier(engine.get());
modifier.embedder_api().RunsAOTCompiledDartCode = []() { return false; };

Expand Down Expand Up @@ -312,13 +292,10 @@ TEST_F(FlutterWindowsEngineTest, PlatformMessageRoundTrip) {
}

TEST_F(FlutterWindowsEngineTest, PlatformMessageRespondOnDifferentThread) {
FlutterDesktopEngineProperties properties = {};
properties.assets_path = GetContext().GetAssetsPath().c_str();
properties.icu_data_path = GetContext().GetIcuDataPath().c_str();
properties.dart_entrypoint = "hiPlatformChannels";
FlutterWindowsEngineBuilder builder{GetContext()};
builder.SetDartEntrypoint("hiPlatformChannels");

FlutterProjectBundle project(properties);
auto engine = std::make_unique<FlutterWindowsEngine>(project);
std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();

EngineModifier modifier(engine.get());
modifier.embedder_api().RunsAOTCompiledDartCode = []() { return false; };
Expand Down Expand Up @@ -366,7 +343,8 @@ TEST_F(FlutterWindowsEngineTest, PlatformMessageRespondOnDifferentThread) {
}

TEST_F(FlutterWindowsEngineTest, SendPlatformMessageWithResponse) {
std::unique_ptr<FlutterWindowsEngine> engine = GetTestEngine();
FlutterWindowsEngineBuilder builder{GetContext()};
std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
EngineModifier modifier(engine.get());

const char* channel = "test";
Expand Down Expand Up @@ -424,7 +402,8 @@ TEST_F(FlutterWindowsEngineTest, SendPlatformMessageWithResponse) {
}

TEST_F(FlutterWindowsEngineTest, DispatchSemanticsAction) {
std::unique_ptr<FlutterWindowsEngine> engine = GetTestEngine();
FlutterWindowsEngineBuilder builder{GetContext()};
std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
EngineModifier modifier(engine.get());

bool called = false;
Expand Down Expand Up @@ -469,7 +448,8 @@ TEST_F(FlutterWindowsEngineTest, SetsThreadPriority) {
}

TEST_F(FlutterWindowsEngineTest, AddPluginRegistrarDestructionCallback) {
std::unique_ptr<FlutterWindowsEngine> engine = GetTestEngine();
FlutterWindowsEngineBuilder builder{GetContext()};
std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
EngineModifier modifier(engine.get());

MockEmbedderApiForKeyboard(modifier,
Expand Down Expand Up @@ -499,7 +479,8 @@ TEST_F(FlutterWindowsEngineTest, AddPluginRegistrarDestructionCallback) {
}

TEST_F(FlutterWindowsEngineTest, ScheduleFrame) {
std::unique_ptr<FlutterWindowsEngine> engine = GetTestEngine();
FlutterWindowsEngineBuilder builder{GetContext()};
std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
EngineModifier modifier(engine.get());

bool called = false;
Expand All @@ -514,7 +495,8 @@ TEST_F(FlutterWindowsEngineTest, ScheduleFrame) {
}

TEST_F(FlutterWindowsEngineTest, SetNextFrameCallback) {
std::unique_ptr<FlutterWindowsEngine> engine = GetTestEngine();
FlutterWindowsEngineBuilder builder{GetContext()};
std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
EngineModifier modifier(engine.get());

bool called = false;
Expand All @@ -529,14 +511,16 @@ TEST_F(FlutterWindowsEngineTest, SetNextFrameCallback) {
}

TEST_F(FlutterWindowsEngineTest, GetExecutableName) {
std::unique_ptr<FlutterWindowsEngine> engine = GetTestEngine();
FlutterWindowsEngineBuilder builder{GetContext()};
std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
EXPECT_EQ(engine->GetExecutableName(), "flutter_windows_unittests.exe");
}

// Ensure that after setting or resetting the high contrast feature,
// the corresponding status flag can be retrieved from the engine.
TEST_F(FlutterWindowsEngineTest, UpdateHighContrastFeature) {
std::unique_ptr<FlutterWindowsEngine> engine = GetTestEngine();
FlutterWindowsEngineBuilder builder{GetContext()};
std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
EngineModifier modifier(engine.get());

bool called = false;
Expand All @@ -561,7 +545,8 @@ TEST_F(FlutterWindowsEngineTest, UpdateHighContrastFeature) {
}

TEST_F(FlutterWindowsEngineTest, PostRasterThreadTask) {
std::unique_ptr<FlutterWindowsEngine> engine = GetTestEngine();
FlutterWindowsEngineBuilder builder{GetContext()};
std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
EngineModifier modifier(engine.get());

modifier.embedder_api().PostRenderThreadTask = MOCK_ENGINE_PROC(
Expand All @@ -586,20 +571,16 @@ class MockFlutterWindowsView : public FlutterWindowsView {
};

TEST_F(FlutterWindowsEngineTest, AlertPlatformMessage) {
FlutterDesktopEngineProperties properties = {};
properties.assets_path = GetContext().GetAssetsPath().c_str();
properties.icu_data_path = GetContext().GetIcuDataPath().c_str();
properties.dart_entrypoint = "alertPlatformChannel";

FlutterProjectBundle project(properties);
FlutterWindowsEngineBuilder builder{GetContext()};
builder.SetDartEntrypoint("alertPlatformChannel");

auto window_binding_handler =
std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
AccessibilityRootNode* root_node = AccessibilityRootNode::Create();
ON_CALL(*window_binding_handler, GetAccessibilityRootNode)
.WillByDefault(::testing::Return(root_node));
MockFlutterWindowsView view(std::move(window_binding_handler));
view.SetEngine(std::make_unique<FlutterWindowsEngine>(project));
view.SetEngine(builder.Build());
FlutterWindowsEngine* engine = view.GetEngine();

EngineModifier modifier(engine);
Expand Down
18 changes: 8 additions & 10 deletions shell/platform/windows/platform_handler_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@

#include "flutter/shell/platform/common/json_method_codec.h"
#include "flutter/shell/platform/windows/flutter_windows_view.h"
#include "flutter/shell/platform/windows/testing/flutter_windows_engine_builder.h"
#include "flutter/shell/platform/windows/testing/mock_window_binding_handler.h"
#include "flutter/shell/platform/windows/testing/test_binary_messenger.h"
#include "flutter/shell/platform/windows/testing/windows_test.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "rapidjson/document.h"
Expand Down Expand Up @@ -95,26 +97,22 @@ std::string SimulatePlatformMessage(TestBinaryMessenger* messenger,

} // namespace

class PlatformHandlerTest : public ::testing::Test {
class PlatformHandlerTest : public WindowsTest {
protected:
FlutterWindowsEngine* engine() { return engine_.get(); }

void use_headless_engine() {
// Set properties required to create the engine.
FlutterDesktopEngineProperties properties = {};
properties.assets_path = L"C:\\foo\\flutter_assets";
properties.icu_data_path = L"C:\\foo\\icudtl.dat";
properties.aot_library_path = L"C:\\foo\\aot.so";
FlutterProjectBundle project(properties);

engine_ = std::make_unique<FlutterWindowsEngine>(project);
FlutterWindowsEngineBuilder builder{GetContext()};

engine_ = builder.Build();
}

void use_engine_with_view() {
use_headless_engine();
FlutterWindowsEngineBuilder builder{GetContext()};

auto window = std::make_unique<NiceMock<MockWindowBindingHandler>>();
view_ = std::make_unique<FlutterWindowsView>(std::move(window));
engine_ = builder.Build();

engine_->SetView(view_.get());
}
Expand Down
51 changes: 51 additions & 0 deletions shell/platform/windows/testing/flutter_windows_engine_builder.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// 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 "flutter/shell/platform/windows/testing/flutter_windows_engine_builder.h"

namespace flutter {
namespace testing {

FlutterWindowsEngineBuilder::FlutterWindowsEngineBuilder(
WindowsTestContext& context)
: context_(context) {
properties_.assets_path = context.GetAssetsPath().c_str();
properties_.icu_data_path = context.GetIcuDataPath().c_str();
properties_.aot_library_path = context.GetAotLibraryPath().c_str();
}

FlutterWindowsEngineBuilder::~FlutterWindowsEngineBuilder() = default;

void FlutterWindowsEngineBuilder::SetDartEntrypoint(std::string entrypoint) {
dart_entrypoint_ = std::move(entrypoint);
properties_.dart_entrypoint = dart_entrypoint_.c_str();
}

void FlutterWindowsEngineBuilder::AddDartEntrypointArgument(std::string arg) {
dart_entrypoint_arguments_.emplace_back(std::move(arg));
}

std::unique_ptr<FlutterWindowsEngine> FlutterWindowsEngineBuilder::Build() {
std::vector<const char*> dart_args;
dart_args.reserve(dart_entrypoint_arguments_.size());

for (const auto& arg : dart_entrypoint_arguments_) {
dart_args.push_back(arg.c_str());
}

if (!dart_args.empty()) {
properties_.dart_entrypoint_argv = dart_args.data();
properties_.dart_entrypoint_argc = dart_args.size();
} else {
properties_.dart_entrypoint_argv = nullptr;
properties_.dart_entrypoint_argc = 0;
}

FlutterProjectBundle project(properties_);

return std::make_unique<FlutterWindowsEngine>(project);
}

} // namespace testing
} // namespace flutter
43 changes: 43 additions & 0 deletions shell/platform/windows/testing/flutter_windows_engine_builder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// 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.

#ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_TESTING_FLUTTER_WINDOWS_ENGINE_BUILDER_H_
#define FLUTTER_SHELL_PLATFORM_WINDOWS_TESTING_FLUTTER_WINDOWS_ENGINE_BUILDER_H_

#include <memory>

#include "flutter/shell/platform/windows/flutter_windows_engine.h"
#include "flutter/shell/platform/windows/public/flutter_windows.h"
#include "flutter/shell/platform/windows/testing/windows_test_context.h"

namespace flutter {
namespace testing {

class FlutterWindowsEngineBuilder {
public:
explicit FlutterWindowsEngineBuilder(WindowsTestContext& context);
~FlutterWindowsEngineBuilder();

void SetDartEntrypoint(std::string entrypoint);

void AddDartEntrypointArgument(std::string arg);

std::unique_ptr<FlutterWindowsEngine> Build();

// Prevent copying.
FlutterWindowsEngineBuilder(FlutterWindowsEngineBuilder const&) = delete;
FlutterWindowsEngineBuilder& operator=(FlutterWindowsEngineBuilder const&) =
delete;

private:
WindowsTestContext& context_;
FlutterDesktopEngineProperties properties_ = {};
std::string dart_entrypoint_;
std::vector<std::string> dart_entrypoint_arguments_;
};

} // namespace testing
} // namespace flutter

#endif // FLUTTER_SHELL_PLATFORM_WINDOWS_TESTING_FLUTTER_WINDOWS_ENGINE_BUILDER_H_
4 changes: 4 additions & 0 deletions shell/platform/windows/testing/windows_test_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ const std::wstring& WindowsTestContext::GetIcuDataPath() const {
return icu_data_path_;
}

const std::wstring& WindowsTestContext::GetAotLibraryPath() const {
return aot_library_path_;
}

void WindowsTestContext::AddNativeFunction(std::string_view name,
Dart_NativeFunction function) {
native_resolver_->AddNativeCallback(std::string{name}, function);
Expand Down
Loading