mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[embedder][glfw] Add support for locales to glfw shell (flutter/engine#22657)
The other linux shell (and all the other embedding) have support for getting the locales from the system and sending them over the flutter/localization channel. The glfw shell does not have that which is causing a crash on an assert now that Locale is no longer nullable in Platform. This adds a similar approach to what is going on over in the other linux shell.
This commit is contained in:
parent
f611b85a5b
commit
ebdd79df0d
@ -4,6 +4,7 @@
|
||||
|
||||
import("//flutter/common/config.gni")
|
||||
import("//flutter/shell/platform/config.gni")
|
||||
import("//flutter/shell/platform/glfw/config.gni")
|
||||
import("//flutter/testing/testing.gni")
|
||||
|
||||
# Whether to build the dartdevc sdk, libraries, and source files
|
||||
@ -140,6 +141,10 @@ group("flutter") {
|
||||
if (is_linux) {
|
||||
public_deps +=
|
||||
[ "//flutter/shell/platform/linux:flutter_linux_unittests" ]
|
||||
if (build_glfw_shell) {
|
||||
public_deps +=
|
||||
[ "//flutter/shell/platform/glfw:flutter_glfw_unittests" ]
|
||||
}
|
||||
}
|
||||
|
||||
if (is_mac) {
|
||||
|
||||
@ -1298,6 +1298,9 @@ FILE: ../../../flutter/shell/platform/glfw/keyboard_hook_handler.h
|
||||
FILE: ../../../flutter/shell/platform/glfw/platform_handler.cc
|
||||
FILE: ../../../flutter/shell/platform/glfw/platform_handler.h
|
||||
FILE: ../../../flutter/shell/platform/glfw/public/flutter_glfw.h
|
||||
FILE: ../../../flutter/shell/platform/glfw/system_utils.cc
|
||||
FILE: ../../../flutter/shell/platform/glfw/system_utils.h
|
||||
FILE: ../../../flutter/shell/platform/glfw/system_utils_test.cc
|
||||
FILE: ../../../flutter/shell/platform/glfw/text_input_plugin.cc
|
||||
FILE: ../../../flutter/shell/platform/glfw/text_input_plugin.h
|
||||
FILE: ../../../flutter/shell/platform/linux/egl_utils.cc
|
||||
|
||||
@ -2,6 +2,8 @@
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
import("//flutter/testing/testing.gni")
|
||||
|
||||
_public_headers = [ "public/flutter_glfw.h" ]
|
||||
|
||||
# Any files that are built by clients (client_wrapper code, library headers for
|
||||
@ -28,6 +30,8 @@ source_set("flutter_glfw_headers") {
|
||||
}
|
||||
|
||||
source_set("flutter_glfw") {
|
||||
public = [ "system_utils.h" ]
|
||||
|
||||
sources = [
|
||||
"event_loop.cc",
|
||||
"event_loop.h",
|
||||
@ -41,6 +45,7 @@ source_set("flutter_glfw") {
|
||||
"keyboard_hook_handler.h",
|
||||
"platform_handler.cc",
|
||||
"platform_handler.h",
|
||||
"system_utils.cc",
|
||||
"text_input_plugin.cc",
|
||||
"text_input_plugin.h",
|
||||
]
|
||||
@ -71,6 +76,21 @@ source_set("flutter_glfw") {
|
||||
}
|
||||
}
|
||||
|
||||
test_fixtures("flutter_glfw_fixtures") {
|
||||
fixtures = []
|
||||
}
|
||||
|
||||
executable("flutter_glfw_unittests") {
|
||||
testonly = true
|
||||
sources = [ "system_utils_test.cc" ]
|
||||
deps = [
|
||||
":flutter_glfw",
|
||||
":flutter_glfw_fixtures",
|
||||
"//flutter/shell/platform/embedder:embedder_headers",
|
||||
"//flutter/testing",
|
||||
]
|
||||
}
|
||||
|
||||
copy("publish_headers_glfw") {
|
||||
sources = _public_headers
|
||||
outputs = [ "$root_out_dir/{{source_file_part}}" ]
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
#include "flutter/shell/platform/glfw/key_event_handler.h"
|
||||
#include "flutter/shell/platform/glfw/keyboard_hook_handler.h"
|
||||
#include "flutter/shell/platform/glfw/platform_handler.h"
|
||||
#include "flutter/shell/platform/glfw/system_utils.h"
|
||||
#include "flutter/shell/platform/glfw/text_input_plugin.h"
|
||||
|
||||
// GLFW_TRUE & GLFW_FALSE are introduced since libglfw-3.3,
|
||||
@ -690,6 +691,27 @@ static bool RunFlutterEngine(
|
||||
return true;
|
||||
}
|
||||
|
||||
// Passes locale information to the Flutter engine.
|
||||
static void SetUpLocales(FlutterDesktopEngineState* state) {
|
||||
std::vector<flutter::LanguageInfo> languages =
|
||||
flutter::GetPreferredLanguageInfo();
|
||||
std::vector<FlutterLocale> flutter_locales =
|
||||
flutter::ConvertToFlutterLocale(languages);
|
||||
// Convert the locale list to the locale pointer list that must be provided.
|
||||
std::vector<const FlutterLocale*> flutter_locale_list;
|
||||
flutter_locale_list.reserve(flutter_locales.size());
|
||||
std::transform(
|
||||
flutter_locales.begin(), flutter_locales.end(),
|
||||
std::back_inserter(flutter_locale_list),
|
||||
[](const auto& arg) -> const auto* { return &arg; });
|
||||
FlutterEngineResult result = FlutterEngineUpdateLocales(
|
||||
state->flutter_engine, flutter_locale_list.data(),
|
||||
flutter_locale_list.size());
|
||||
if (result != kSuccess) {
|
||||
std::cerr << "Failed to set up Flutter locales." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Populates |state|'s helper object fields that are common to normal and
|
||||
// headless mode.
|
||||
//
|
||||
@ -713,6 +735,8 @@ static void SetUpCommonEngineState(FlutterDesktopEngineState* state,
|
||||
// System channel handler.
|
||||
state->platform_handler = std::make_unique<flutter::PlatformHandler>(
|
||||
state->internal_plugin_registrar->messenger(), window);
|
||||
|
||||
SetUpLocales(state);
|
||||
}
|
||||
|
||||
bool FlutterDesktopInit() {
|
||||
|
||||
154
engine/src/flutter/shell/platform/glfw/system_utils.cc
Normal file
154
engine/src/flutter/shell/platform/glfw/system_utils.cc
Normal file
@ -0,0 +1,154 @@
|
||||
// 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/glfw/system_utils.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
|
||||
namespace flutter {
|
||||
|
||||
namespace {
|
||||
|
||||
const char* GetLocaleStringFromEnvironment() {
|
||||
const char* retval;
|
||||
retval = getenv("LANGUAGE");
|
||||
if ((retval != NULL) && (retval[0] != '\0')) {
|
||||
return retval;
|
||||
}
|
||||
retval = getenv("LC_ALL");
|
||||
if ((retval != NULL) && (retval[0] != '\0')) {
|
||||
return retval;
|
||||
}
|
||||
retval = getenv("LC_MESSAGES");
|
||||
if ((retval != NULL) && (retval[0] != '\0')) {
|
||||
return retval;
|
||||
}
|
||||
retval = getenv("LANG");
|
||||
if ((retval != NULL) && (retval[0] != '\0')) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// The least specific to most specific components of a locale.
|
||||
enum Component {
|
||||
kCodeset = 1 << 0,
|
||||
kTerritory = 1 << 1,
|
||||
kModifier = 1 << 2,
|
||||
};
|
||||
|
||||
// Construct a mask indicating which of the components in |info| are set.
|
||||
int ComputeVariantMask(const LanguageInfo& info) {
|
||||
int mask = 0;
|
||||
if (!info.territory.empty()) {
|
||||
mask |= kTerritory;
|
||||
}
|
||||
if (!info.codeset.empty()) {
|
||||
mask |= kCodeset;
|
||||
}
|
||||
if (!info.modifier.empty()) {
|
||||
mask |= kModifier;
|
||||
}
|
||||
return mask;
|
||||
}
|
||||
|
||||
// Appends most specific to least specific variants of |info| to |languages|.
|
||||
// For example, "de_DE@euro" would append "de_DE@euro", "de@euro", "de_DE",
|
||||
// and "de".
|
||||
void AppendLocaleVariants(std::vector<LanguageInfo>& languages,
|
||||
LanguageInfo info) {
|
||||
int mask = ComputeVariantMask(info);
|
||||
for (int i = mask; i >= 0; --i) {
|
||||
if ((i & ~mask) == 0) {
|
||||
LanguageInfo variant;
|
||||
variant.language = info.language;
|
||||
|
||||
if (i & kTerritory) {
|
||||
variant.territory = info.territory;
|
||||
}
|
||||
if (i & kCodeset) {
|
||||
variant.codeset = info.codeset;
|
||||
}
|
||||
if (i & kModifier) {
|
||||
variant.modifier = info.modifier;
|
||||
}
|
||||
languages.push_back(variant);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Parses a locale into its components.
|
||||
LanguageInfo ParseLocale(const std::string& locale) {
|
||||
// Locales are of the form "language[_territory][.codeset][@modifier]"
|
||||
LanguageInfo result;
|
||||
std::string::size_type end = locale.size();
|
||||
std::string::size_type modifier_pos = locale.rfind('@');
|
||||
if (modifier_pos != std::string::npos) {
|
||||
result.modifier = locale.substr(modifier_pos + 1, end - modifier_pos - 1);
|
||||
end = modifier_pos;
|
||||
}
|
||||
|
||||
std::string::size_type codeset_pos = locale.rfind('.', end);
|
||||
if (codeset_pos != std::string::npos) {
|
||||
result.codeset = locale.substr(codeset_pos + 1, end - codeset_pos - 1);
|
||||
end = codeset_pos;
|
||||
}
|
||||
|
||||
std::string::size_type territory_pos = locale.rfind('_', end);
|
||||
if (territory_pos != std::string::npos) {
|
||||
result.territory =
|
||||
locale.substr(territory_pos + 1, end - territory_pos - 1);
|
||||
end = territory_pos;
|
||||
}
|
||||
|
||||
result.language = locale.substr(0, end);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
std::vector<LanguageInfo> GetPreferredLanguageInfo() {
|
||||
const char* locale_string;
|
||||
locale_string = GetLocaleStringFromEnvironment();
|
||||
if (!locale_string || locale_string[0] == '\0') {
|
||||
// This is the default locale if none is specified according to ISO C.
|
||||
locale_string = "C";
|
||||
}
|
||||
std::istringstream locales_stream(locale_string);
|
||||
std::vector<LanguageInfo> languages;
|
||||
std::string s;
|
||||
while (getline(locales_stream, s, ':')) {
|
||||
LanguageInfo info = ParseLocale(s);
|
||||
AppendLocaleVariants(languages, info);
|
||||
}
|
||||
return languages;
|
||||
}
|
||||
|
||||
std::vector<FlutterLocale> ConvertToFlutterLocale(
|
||||
const std::vector<LanguageInfo>& languages) {
|
||||
std::vector<FlutterLocale> flutter_locales;
|
||||
flutter_locales.reserve(languages.size());
|
||||
for (const auto& info : languages) {
|
||||
FlutterLocale locale = {};
|
||||
locale.struct_size = sizeof(FlutterLocale);
|
||||
locale.language_code = info.language.c_str();
|
||||
if (!info.territory.empty()) {
|
||||
locale.country_code = info.territory.c_str();
|
||||
}
|
||||
if (!info.codeset.empty()) {
|
||||
locale.script_code = info.codeset.c_str();
|
||||
}
|
||||
if (!info.modifier.empty()) {
|
||||
locale.variant_code = info.modifier.c_str();
|
||||
}
|
||||
flutter_locales.push_back(locale);
|
||||
}
|
||||
|
||||
return flutter_locales;
|
||||
}
|
||||
|
||||
} // namespace flutter
|
||||
35
engine/src/flutter/shell/platform/glfw/system_utils.h
Normal file
35
engine/src/flutter/shell/platform/glfw/system_utils.h
Normal file
@ -0,0 +1,35 @@
|
||||
// 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_GLFW_SYSTEM_UTILS_H_
|
||||
#define FLUTTER_SHELL_PLATFORM_GLFW_SYSTEM_UTILS_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "flutter/shell/platform/embedder/embedder.h"
|
||||
|
||||
namespace flutter {
|
||||
|
||||
// Components of a system language/locale.
|
||||
struct LanguageInfo {
|
||||
std::string language;
|
||||
std::string territory;
|
||||
std::string codeset;
|
||||
std::string modifier;
|
||||
};
|
||||
|
||||
// Returns the list of user-preferred languages, in preference order,
|
||||
// parsed into LanguageInfo structures.
|
||||
std::vector<LanguageInfo> GetPreferredLanguageInfo();
|
||||
|
||||
// Converts a vector of LanguageInfo structs to a vector of FlutterLocale
|
||||
// structs. |languages| must outlive the returned value, since the returned
|
||||
// elements have pointers into it.
|
||||
std::vector<FlutterLocale> ConvertToFlutterLocale(
|
||||
const std::vector<LanguageInfo>& languages);
|
||||
|
||||
} // namespace flutter
|
||||
|
||||
#endif // FLUTTER_SHELL_PLATFORM_GLFW_SYSTEM_UTILS_H_
|
||||
292
engine/src/flutter/shell/platform/glfw/system_utils_test.cc
Normal file
292
engine/src/flutter/shell/platform/glfw/system_utils_test.cc
Normal file
@ -0,0 +1,292 @@
|
||||
// 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/glfw/system_utils.h"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace flutter {
|
||||
namespace {
|
||||
|
||||
// This is a helper for setting up the different environment variables to
|
||||
// specific strings, calling GetPreferredLanguageInfo, and then restoring those
|
||||
// environment variables to any previously existing values.
|
||||
std::vector<LanguageInfo> SetAndRestoreLanguageAroundGettingLanguageInfo(
|
||||
const char* language,
|
||||
const char* lc_all,
|
||||
const char* lc_messages,
|
||||
const char* lang) {
|
||||
std::vector<const char*> env_vars{
|
||||
"LANGUAGE",
|
||||
"LC_ALL",
|
||||
"LC_MESSAGES",
|
||||
"LANG",
|
||||
};
|
||||
std::map<const char*, const char*> new_values{
|
||||
{env_vars[0], language},
|
||||
{env_vars[1], lc_all},
|
||||
{env_vars[2], lc_messages},
|
||||
{env_vars[3], lang},
|
||||
};
|
||||
std::map<const char*, const char*> prior_values;
|
||||
for (auto var : env_vars) {
|
||||
const char* value = getenv(var);
|
||||
if (value != nullptr) {
|
||||
prior_values.emplace(var, value);
|
||||
}
|
||||
const char* new_value = new_values.at(var);
|
||||
if (new_value != nullptr) {
|
||||
setenv(var, new_value, 1);
|
||||
} else {
|
||||
unsetenv(var);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<LanguageInfo> languages = GetPreferredLanguageInfo();
|
||||
|
||||
for (auto [var, value] : prior_values) {
|
||||
setenv(var, value, 1);
|
||||
}
|
||||
|
||||
return languages;
|
||||
}
|
||||
|
||||
TEST(FlutterGlfwSystemUtilsTest, GetPreferredLanuageInfoFull) {
|
||||
const char* locale_string = "en_GB.ISO-8859-1@euro:en_US:sv:zh_CN.UTF-8";
|
||||
|
||||
std::vector<LanguageInfo> languages =
|
||||
SetAndRestoreLanguageAroundGettingLanguageInfo(locale_string, nullptr,
|
||||
nullptr, nullptr);
|
||||
|
||||
EXPECT_EQ(languages.size(), 15UL);
|
||||
|
||||
EXPECT_STREQ(languages[0].language.c_str(), "en");
|
||||
EXPECT_STREQ(languages[0].territory.c_str(), "GB");
|
||||
EXPECT_STREQ(languages[0].codeset.c_str(), "ISO-8859-1");
|
||||
EXPECT_STREQ(languages[0].modifier.c_str(), "euro");
|
||||
|
||||
EXPECT_STREQ(languages[1].language.c_str(), "en");
|
||||
EXPECT_STREQ(languages[1].territory.c_str(), "GB");
|
||||
EXPECT_STREQ(languages[1].codeset.c_str(), "");
|
||||
EXPECT_STREQ(languages[1].modifier.c_str(), "euro");
|
||||
|
||||
EXPECT_STREQ(languages[2].language.c_str(), "en");
|
||||
EXPECT_STREQ(languages[2].territory.c_str(), "");
|
||||
EXPECT_STREQ(languages[2].codeset.c_str(), "ISO-8859-1");
|
||||
EXPECT_STREQ(languages[2].modifier.c_str(), "euro");
|
||||
|
||||
EXPECT_STREQ(languages[3].language.c_str(), "en");
|
||||
EXPECT_STREQ(languages[3].territory.c_str(), "");
|
||||
EXPECT_STREQ(languages[3].codeset.c_str(), "");
|
||||
EXPECT_STREQ(languages[3].modifier.c_str(), "euro");
|
||||
|
||||
EXPECT_STREQ(languages[4].language.c_str(), "en");
|
||||
EXPECT_STREQ(languages[4].territory.c_str(), "GB");
|
||||
EXPECT_STREQ(languages[4].codeset.c_str(), "ISO-8859-1");
|
||||
EXPECT_STREQ(languages[4].modifier.c_str(), "");
|
||||
|
||||
EXPECT_STREQ(languages[5].language.c_str(), "en");
|
||||
EXPECT_STREQ(languages[5].territory.c_str(), "GB");
|
||||
EXPECT_STREQ(languages[5].codeset.c_str(), "");
|
||||
EXPECT_STREQ(languages[5].modifier.c_str(), "");
|
||||
|
||||
EXPECT_STREQ(languages[6].language.c_str(), "en");
|
||||
EXPECT_STREQ(languages[6].territory.c_str(), "");
|
||||
EXPECT_STREQ(languages[6].codeset.c_str(), "ISO-8859-1");
|
||||
EXPECT_STREQ(languages[6].modifier.c_str(), "");
|
||||
|
||||
EXPECT_STREQ(languages[7].language.c_str(), "en");
|
||||
EXPECT_STREQ(languages[7].territory.c_str(), "");
|
||||
EXPECT_STREQ(languages[7].codeset.c_str(), "");
|
||||
EXPECT_STREQ(languages[7].modifier.c_str(), "");
|
||||
|
||||
EXPECT_STREQ(languages[8].language.c_str(), "en");
|
||||
EXPECT_STREQ(languages[8].territory.c_str(), "US");
|
||||
EXPECT_STREQ(languages[8].codeset.c_str(), "");
|
||||
EXPECT_STREQ(languages[8].modifier.c_str(), "");
|
||||
|
||||
EXPECT_STREQ(languages[9].language.c_str(), "en");
|
||||
EXPECT_STREQ(languages[9].territory.c_str(), "");
|
||||
EXPECT_STREQ(languages[9].codeset.c_str(), "");
|
||||
EXPECT_STREQ(languages[9].modifier.c_str(), "");
|
||||
|
||||
EXPECT_STREQ(languages[10].language.c_str(), "sv");
|
||||
EXPECT_STREQ(languages[10].territory.c_str(), "");
|
||||
EXPECT_STREQ(languages[10].codeset.c_str(), "");
|
||||
EXPECT_STREQ(languages[10].modifier.c_str(), "");
|
||||
|
||||
EXPECT_STREQ(languages[11].language.c_str(), "zh");
|
||||
EXPECT_STREQ(languages[11].territory.c_str(), "CN");
|
||||
EXPECT_STREQ(languages[11].codeset.c_str(), "UTF-8");
|
||||
EXPECT_STREQ(languages[11].modifier.c_str(), "");
|
||||
|
||||
EXPECT_STREQ(languages[12].language.c_str(), "zh");
|
||||
EXPECT_STREQ(languages[12].territory.c_str(), "CN");
|
||||
EXPECT_STREQ(languages[12].codeset.c_str(), "");
|
||||
EXPECT_STREQ(languages[12].modifier.c_str(), "");
|
||||
|
||||
EXPECT_STREQ(languages[13].language.c_str(), "zh");
|
||||
EXPECT_STREQ(languages[13].territory.c_str(), "");
|
||||
EXPECT_STREQ(languages[13].codeset.c_str(), "UTF-8");
|
||||
EXPECT_STREQ(languages[13].modifier.c_str(), "");
|
||||
|
||||
EXPECT_STREQ(languages[14].language.c_str(), "zh");
|
||||
EXPECT_STREQ(languages[14].territory.c_str(), "");
|
||||
EXPECT_STREQ(languages[14].codeset.c_str(), "");
|
||||
EXPECT_STREQ(languages[14].modifier.c_str(), "");
|
||||
}
|
||||
|
||||
TEST(FlutterGlfwSystemUtilsTest, GetPreferredLanuageInfoWeird) {
|
||||
const char* locale_string = "tt_RU@iqtelif.UTF-8";
|
||||
std::vector<LanguageInfo> languages =
|
||||
SetAndRestoreLanguageAroundGettingLanguageInfo(locale_string, nullptr,
|
||||
nullptr, nullptr);
|
||||
|
||||
EXPECT_EQ(languages.size(), 4UL);
|
||||
|
||||
EXPECT_STREQ(languages[0].language.c_str(), "tt");
|
||||
EXPECT_STREQ(languages[0].territory.c_str(), "RU");
|
||||
EXPECT_STREQ(languages[0].codeset.c_str(), "");
|
||||
EXPECT_STREQ(languages[0].modifier.c_str(), "iqtelif.UTF-8");
|
||||
|
||||
EXPECT_STREQ(languages[1].language.c_str(), "tt");
|
||||
EXPECT_STREQ(languages[1].territory.c_str(), "");
|
||||
EXPECT_STREQ(languages[1].codeset.c_str(), "");
|
||||
EXPECT_STREQ(languages[1].modifier.c_str(), "iqtelif.UTF-8");
|
||||
|
||||
EXPECT_STREQ(languages[2].language.c_str(), "tt");
|
||||
EXPECT_STREQ(languages[2].territory.c_str(), "RU");
|
||||
EXPECT_STREQ(languages[2].codeset.c_str(), "");
|
||||
EXPECT_STREQ(languages[2].modifier.c_str(), "");
|
||||
|
||||
EXPECT_STREQ(languages[3].language.c_str(), "tt");
|
||||
EXPECT_STREQ(languages[3].territory.c_str(), "");
|
||||
EXPECT_STREQ(languages[3].codeset.c_str(), "");
|
||||
EXPECT_STREQ(languages[3].modifier.c_str(), "");
|
||||
}
|
||||
|
||||
TEST(FlutterGlfwSystemUtilsTest, GetPreferredLanuageInfoEmpty) {
|
||||
const char* locale_string = "";
|
||||
std::vector<LanguageInfo> languages =
|
||||
SetAndRestoreLanguageAroundGettingLanguageInfo(
|
||||
locale_string, locale_string, locale_string, locale_string);
|
||||
|
||||
EXPECT_EQ(languages.size(), 1UL);
|
||||
|
||||
EXPECT_STREQ(languages[0].language.c_str(), "C");
|
||||
EXPECT_TRUE(languages[0].territory.empty());
|
||||
EXPECT_TRUE(languages[0].codeset.empty());
|
||||
EXPECT_TRUE(languages[0].modifier.empty());
|
||||
}
|
||||
|
||||
TEST(FlutterGlfwSystemUtilsTest, GetPreferredLanuageInfoEnvVariableOrdering1) {
|
||||
const char* language = "de";
|
||||
const char* lc_all = "en";
|
||||
const char* lc_messages = "zh";
|
||||
const char* lang = "tt";
|
||||
|
||||
std::vector<LanguageInfo> languages =
|
||||
SetAndRestoreLanguageAroundGettingLanguageInfo(language, lc_all,
|
||||
lc_messages, lang);
|
||||
|
||||
EXPECT_EQ(languages.size(), 1UL);
|
||||
EXPECT_STREQ(languages[0].language.c_str(), language);
|
||||
}
|
||||
|
||||
TEST(FlutterGlfwSystemUtilsTest, GetPreferredLanuageInfoEnvVariableOrdering2) {
|
||||
const char* lc_all = "en";
|
||||
const char* lc_messages = "zh";
|
||||
const char* lang = "tt";
|
||||
|
||||
std::vector<LanguageInfo> languages =
|
||||
SetAndRestoreLanguageAroundGettingLanguageInfo(nullptr, lc_all,
|
||||
lc_messages, lang);
|
||||
|
||||
EXPECT_EQ(languages.size(), 1UL);
|
||||
EXPECT_STREQ(languages[0].language.c_str(), lc_all);
|
||||
}
|
||||
|
||||
TEST(FlutterGlfwSystemUtilsTest, GetPreferredLanuageInfoEnvVariableOrdering3) {
|
||||
const char* lc_messages = "zh";
|
||||
const char* lang = "tt";
|
||||
|
||||
std::vector<LanguageInfo> languages =
|
||||
SetAndRestoreLanguageAroundGettingLanguageInfo(nullptr, nullptr,
|
||||
lc_messages, lang);
|
||||
|
||||
EXPECT_EQ(languages.size(), 1UL);
|
||||
EXPECT_STREQ(languages[0].language.c_str(), lc_messages);
|
||||
}
|
||||
|
||||
TEST(FlutterGlfwSystemUtilsTest, GetPreferredLanuageInfoEnvVariableOrdering4) {
|
||||
const char* lang = "tt";
|
||||
|
||||
std::vector<LanguageInfo> languages =
|
||||
SetAndRestoreLanguageAroundGettingLanguageInfo(nullptr, nullptr, nullptr,
|
||||
lang);
|
||||
|
||||
EXPECT_EQ(languages.size(), 1UL);
|
||||
EXPECT_STREQ(languages[0].language.c_str(), lang);
|
||||
}
|
||||
|
||||
TEST(FlutterGlfwSystemUtilsTest, GetPreferredLanuageInfoEnvVariableOrdering5) {
|
||||
std::vector<LanguageInfo> languages =
|
||||
SetAndRestoreLanguageAroundGettingLanguageInfo(nullptr, nullptr, nullptr,
|
||||
nullptr);
|
||||
|
||||
EXPECT_EQ(languages.size(), 1UL);
|
||||
EXPECT_STREQ(languages[0].language.c_str(), "C");
|
||||
}
|
||||
|
||||
TEST(FlutterGlfwSystemUtilsTest, ConvertToFlutterLocaleEmpty) {
|
||||
std::vector<LanguageInfo> languages;
|
||||
|
||||
std::vector<FlutterLocale> locales = ConvertToFlutterLocale(languages);
|
||||
|
||||
EXPECT_TRUE(locales.empty());
|
||||
}
|
||||
|
||||
TEST(FlutterGlfwSystemUtilsTest, ConvertToFlutterLocaleNonEmpty) {
|
||||
std::vector<LanguageInfo> languages;
|
||||
languages.push_back(LanguageInfo{"en", "US", "", ""});
|
||||
languages.push_back(LanguageInfo{"tt", "RU", "", "iqtelif.UTF-8"});
|
||||
languages.push_back(LanguageInfo{"sv", "", "", ""});
|
||||
languages.push_back(LanguageInfo{"de", "DE", "UTF-8", "euro"});
|
||||
languages.push_back(LanguageInfo{"zh", "CN", "UTF-8", ""});
|
||||
|
||||
std::vector<FlutterLocale> locales = ConvertToFlutterLocale(languages);
|
||||
|
||||
EXPECT_EQ(locales.size(), 5UL);
|
||||
|
||||
EXPECT_EQ(locales[0].struct_size, sizeof(FlutterLocale));
|
||||
EXPECT_STREQ(locales[0].language_code, "en");
|
||||
EXPECT_STREQ(locales[0].country_code, "US");
|
||||
EXPECT_EQ(locales[0].script_code, nullptr);
|
||||
EXPECT_EQ(locales[0].variant_code, nullptr);
|
||||
|
||||
EXPECT_STREQ(locales[1].language_code, "tt");
|
||||
EXPECT_STREQ(locales[1].country_code, "RU");
|
||||
EXPECT_EQ(locales[1].script_code, nullptr);
|
||||
EXPECT_STREQ(locales[1].variant_code, "iqtelif.UTF-8");
|
||||
|
||||
EXPECT_STREQ(locales[2].language_code, "sv");
|
||||
EXPECT_EQ(locales[2].country_code, nullptr);
|
||||
EXPECT_EQ(locales[2].script_code, nullptr);
|
||||
EXPECT_EQ(locales[2].variant_code, nullptr);
|
||||
|
||||
EXPECT_STREQ(locales[3].language_code, "de");
|
||||
EXPECT_STREQ(locales[3].country_code, "DE");
|
||||
EXPECT_STREQ(locales[3].script_code, "UTF-8");
|
||||
EXPECT_STREQ(locales[3].variant_code, "euro");
|
||||
|
||||
EXPECT_STREQ(locales[4].language_code, "zh");
|
||||
EXPECT_STREQ(locales[4].country_code, "CN");
|
||||
EXPECT_STREQ(locales[4].script_code, "UTF-8");
|
||||
EXPECT_EQ(locales[4].variant_code, nullptr);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace flutter
|
||||
@ -161,6 +161,7 @@ def RunCCTests(build_dir, filter):
|
||||
|
||||
if IsLinux():
|
||||
RunEngineExecutable(build_dir, 'flutter_linux_unittests', filter, non_repeatable_shuffle_flags)
|
||||
RunEngineExecutable(build_dir, 'flutter_glfw_unittests', filter, non_repeatable_shuffle_flags)
|
||||
|
||||
|
||||
def RunEngineBenchmarks(build_dir, filter):
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user