mirror of
https://github.com/keymanapp/keyman.git
synced 2026-09-07 08:07:43 +00:00
chore(core): merge actions test data for unit tests
Merge actions test data struct and some of the data for the actions API unit tests. actions_update_app_context_nfu.tests.cpp data has not been merged because the expected results are different, as it does not do normalization, unlike actions_get_api and actions_normalize. Merging of that data could be done, but would require adding extra fields to each test result, which would make the data considerably harder to read! Thus I have left it alone for now, just merged the struct, which is still a win. Fixes: #15913
This commit is contained in:
parent
a3de441eda
commit
82f4c954a5
6 changed files with 466 additions and 652 deletions
|
|
@ -15,73 +15,26 @@
|
|||
#include "context.hpp"
|
||||
|
||||
#include "../helpers/core_test_helpers.h"
|
||||
#include "./actions_test_data.h"
|
||||
|
||||
struct TestData {
|
||||
const char* test_name;
|
||||
|
||||
/**
|
||||
* the app context stored in the state, _before_ transform is applied -- NFU
|
||||
*/
|
||||
const km_core_cu *initial_app_context;
|
||||
|
||||
/**
|
||||
* cached context _after_ actions have been applied -- guaranteed NFD
|
||||
* (essentially, this is initial_cached_context -
|
||||
* actions_code_points_to_delete + actions_output) - no markers supported
|
||||
*/
|
||||
const km_core_cu *final_cached_context;
|
||||
|
||||
/**
|
||||
* number of NFD code points that the keyboard processor has asked to remove
|
||||
* in its actions
|
||||
*/
|
||||
int actions_code_points_to_delete;
|
||||
|
||||
/**
|
||||
* NFD string that the keyboard processor has asked to insert in its actions
|
||||
*/
|
||||
const std::u32string actions_output;
|
||||
|
||||
/**
|
||||
* expected: NFU code points to ask app to remove
|
||||
*/
|
||||
const unsigned int expected_delete;
|
||||
|
||||
/**
|
||||
* expected: adjusted NFC output to insert into the app
|
||||
*/
|
||||
const std::u32string expected_output;
|
||||
|
||||
/**
|
||||
* expected: NFU adjusted final app context, which will be NFC from the
|
||||
* boundary of the transform, but will not have been modified prior to that.
|
||||
* Should match char-for-char what the app ends up with in its text buffer.
|
||||
*/
|
||||
const km_core_cu *expected_final_app_context;
|
||||
|
||||
/**
|
||||
* expected: the characters deleted from the context
|
||||
*/
|
||||
const std::u32string expected_deleted_context;
|
||||
};
|
||||
|
||||
std::string GenerateTestName(const testing::TestParamInfo<TestData>& info) {
|
||||
return info.param.test_name;
|
||||
}
|
||||
|
||||
class GetActionApiTest : public testing::TestWithParam<TestData> {
|
||||
class GetActionApiTest : public testing::TestWithParam<ActionsTestData> {
|
||||
protected:
|
||||
km_core_keyboard * test_kb = nullptr;
|
||||
km_core_state * test_state = nullptr;
|
||||
km_core_actions * test_actions = nullptr;
|
||||
|
||||
void Initialize(TestData const& data) {
|
||||
void Initialize(ActionsTestData const& data) {
|
||||
if(data.final_cached_context_string == nullptr) {
|
||||
// We skip the shared tests that don't have a input context string
|
||||
return;
|
||||
}
|
||||
|
||||
km::core::path path = km::core::path::join(test_dir, "..", "ldml", "fixtures", "keyboards", "17.0", "k_001_tiny.kmx");
|
||||
auto blob = km::tests::load_kmx_file(path.native().c_str());
|
||||
ASSERT_STATUS_OK(km_core_keyboard_load_from_blob(path.stem().c_str(), blob.data(), blob.size(), &test_kb));
|
||||
ASSERT_STATUS_OK(km_core_state_create(test_kb, test_empty_env_opts, &test_state));
|
||||
|
||||
ASSERT_STATUS_OK(set_context_from_string(km_core_state_context(test_state), data.final_cached_context));
|
||||
ASSERT_STATUS_OK(set_context_from_string(km_core_state_context(test_state), data.final_cached_context_string));
|
||||
ASSERT_STATUS_OK(set_context_from_string(km_core_state_app_context(test_state), data.initial_app_context));
|
||||
|
||||
test_actions = new km_core_actions;
|
||||
|
|
@ -132,6 +85,11 @@ TEST_P(GetActionApiTest, TestActionsApi) {
|
|||
auto data = GetParam();
|
||||
ASSERT_NO_FATAL_FAILURE(Initialize(data));
|
||||
|
||||
if(data.final_cached_context_string == nullptr) {
|
||||
// We skip the shared tests that don't have a input context string
|
||||
return;
|
||||
}
|
||||
|
||||
// setup(initial_app_context, final_cached_context, actions_code_points_to_delete, actions_output);
|
||||
|
||||
auto actual_actions = km_core_state_get_actions(test_state);
|
||||
|
|
@ -162,184 +120,6 @@ TEST_P(GetActionApiTest, TestActionsApi) {
|
|||
delete [] actual_final_app_context;
|
||||
}
|
||||
|
||||
const TestData values[] = {
|
||||
// Null boundary tests
|
||||
// Note that .final_cached_context_items is not used in these tests
|
||||
|
||||
{
|
||||
"Noop",
|
||||
/* app context pre transform: */ u"",
|
||||
/* cached context post transform: */ u"",
|
||||
/* action del, output: */ 0, U"",
|
||||
// ---- results ----
|
||||
/* action del, output: */ 0, U"",
|
||||
/* app_context: */ u"",
|
||||
/* expected del */ U""
|
||||
},
|
||||
|
||||
{
|
||||
"NoOutput",
|
||||
/* app context pre transform: */ u"abc",
|
||||
/* cached context post transform: */ u"abc",
|
||||
/* action del, output: */ 0, U"",
|
||||
// ---- results ----
|
||||
/* action del, output: */ 0, U"",
|
||||
/* app_context: */ u"abc",
|
||||
/* expected del */ U""
|
||||
},
|
||||
|
||||
{
|
||||
"NoContext",
|
||||
/* app context pre transform: */ u"",
|
||||
/* cached context post transform: */ u"def",
|
||||
/* action del, output: */ 0, U"def",
|
||||
// ---- results ----
|
||||
/* action del, output: */ 0, U"def",
|
||||
/* app_context: */ u"def",
|
||||
/* expected del */ U""
|
||||
},
|
||||
|
||||
// Simple tests -- no deletions involved
|
||||
|
||||
{
|
||||
"NoNormalization",
|
||||
/* app context pre transform: */ u"abc",
|
||||
/* cached context post transform: */ u"abcdef",
|
||||
/* action del, output: */ 0, U"def",
|
||||
// ---- results ----
|
||||
/* action del, output: */ 0, U"def",
|
||||
/* app_context: */ u"abcdef",
|
||||
/* expected del */ U""
|
||||
},
|
||||
|
||||
{
|
||||
"OutputToNfcBasic",
|
||||
/* app context pre transform: */ u"abc",
|
||||
/* cached context post transform: */ u"abcde\u0300f",
|
||||
/* action del, output: */ 0, U"de\u0300f",
|
||||
// ---- results ----
|
||||
/* action del, output: */ 0, U"dèf",
|
||||
/* app_context: */ u"abcdèf",
|
||||
/* expected del */ U""
|
||||
},
|
||||
|
||||
{
|
||||
"OutputToNfcHefty",
|
||||
/* app context pre transform: */ u"abc",
|
||||
/* cached context post transform: */ u"abcA\u0300" u"e\u0316\u0301" u"\u0073\u0323\u0307" u"\u0041\u030a" u"\U000114B9\U000114B0",
|
||||
/* action del, output: */ 0, U"A\u0300" U"e\u0316\u0301" U"\u0073\u0323\u0307" U"\u0041\u030a" U"\U000114B9\U000114B0",
|
||||
// ---- results ----
|
||||
/* action del, output: */ 0, U"À" U"é̖" U"\u1e69" U"\u00c5" U"\U000114BC",
|
||||
/* app_context: */ u"abcÀé̖\u1e69\u00c5\U000114BC",
|
||||
/* expected del */ U""
|
||||
},
|
||||
|
||||
// Interaction with input context when not on normalization boundary
|
||||
|
||||
{
|
||||
"BacktrackOneCharacterToCombineAsNfc",
|
||||
/* app context pre transform: */ u"XYZA",
|
||||
/* cached context post transform: */ u"XYZA\u0300abc",
|
||||
/* action del, output: */ 0, U"\u0300abc",
|
||||
// ---- results ----
|
||||
/* action del, output: */ 1, U"Àabc",
|
||||
/* app_context: */ u"XYZÀabc",
|
||||
/* expected del */ U"A"
|
||||
},
|
||||
|
||||
{
|
||||
"BacktrackECombCirc2CharsToCombineAsNfc",
|
||||
/* app context pre transform: */ u"abce\u0302",
|
||||
/* cached context post transform: */ u"abce\u0323\u0302",
|
||||
/* action del, output: */ 1, U"\u0323\u0302",
|
||||
// ---- results ----
|
||||
/* action del, output: */ 2, U"ệ",
|
||||
/* app_context: */ u"abcệ",
|
||||
/* expected del */ U"e\u0302"
|
||||
},
|
||||
|
||||
{
|
||||
"OneBackspaceForNfdConvertsIntoOneCharInNfcAndRecombine",
|
||||
/* app context pre transform: */ u"abcê",
|
||||
/* cached context post transform: */ u"abce\u0323\u0302",
|
||||
/* action del, output: */ 1, U"\u0323\u0302", // NFD input; delete 1: \u0302
|
||||
// ---- results ----
|
||||
/* action del, output: */ 1, U"ệ", // NFC output; delete 1: ê
|
||||
/* app_context: */ u"abcệ",
|
||||
/* expected del */ U"ê"
|
||||
},
|
||||
|
||||
// a\u0300 should not be normalized because it is not otherwise impacted by
|
||||
// the action.
|
||||
{
|
||||
"AvoidEditingTooFarBackInContextWhenFindingNormalizationBoundary",
|
||||
/* app context pre transform: */ u"a\u0300bcê",
|
||||
/* cached context post transform: */ u"a\u0300bce\u0323\u0302",
|
||||
/* action del, output: */ 1, U"\u0323\u0302", // NFD input; delete 1: \u0302
|
||||
// ---- results ----
|
||||
/* action del, output: */ 1, U"ệ", // NFC output; delete 1: ê
|
||||
/* app_context: */ u"a\u0300bcệ",
|
||||
/* expected del */ U"ê"
|
||||
},
|
||||
|
||||
// If we don't reach a normalization boundary, we still should continue to work
|
||||
{
|
||||
"NormalizableLettersAtStartOfContext",
|
||||
/* app context pre transform: */ u"\u0300",
|
||||
/* cached context post transform: */ u"\u0323\u0300\u0302",
|
||||
/* action del, output: */ 1, U"\u0323\u0300\u0302", // NFD input;
|
||||
// ---- results ----
|
||||
/* action del, output: */ 1, U"\u0323\u0300\u0302", // NFC output is still decomposed because there is no base
|
||||
/* app_context: */ u"\u0323\u0300\u0302",
|
||||
/* expected del */ U"\u0300"
|
||||
},
|
||||
|
||||
// Modifies the base as well as diacritic
|
||||
|
||||
{
|
||||
"TwoBackspacesForNfdConvertsIntoOneCharInNfcAndRecombine",
|
||||
/* app context pre transform: */ u"abcê",
|
||||
/* cached context post transform: */ u"abca\u0323\u0302",
|
||||
/* action del, output: */ 2, U"a\u0323\u0302", // NFD input; delete 2: e\u0302
|
||||
// ---- results ----
|
||||
/* action del, output: */ 1, U"ậ", // NFC output; delete 1: ê
|
||||
/* app_context: */ u"abcậ",
|
||||
/* expected del */ U"ê"
|
||||
},
|
||||
|
||||
// surrogate pair tests
|
||||
|
||||
{
|
||||
"SurrogatePairInContext",
|
||||
/* app context pre transform: */ u"abc\U0001F607ê",
|
||||
/* cached context post transform: */ u"abc\U0001F607a\u0323\u0302",
|
||||
/* action del, output: */ 2, U"a\u0323\u0302",
|
||||
// ---- results ----
|
||||
/* action del, output: */ 1, U"ậ",
|
||||
/* app_context: */ u"abc\U0001F607ậ",
|
||||
/* expected del */ U"ê"
|
||||
},
|
||||
|
||||
{
|
||||
"SurrogatePairInOutput",
|
||||
/* app context pre transform: */ u"abc",
|
||||
/* cached context post transform: */ u"abc\U0001F607",
|
||||
/* action del, output: */ 0, U"\U0001F607",
|
||||
// ---- results ----
|
||||
/* action del, output: */ 0, U"\U0001F607",
|
||||
/* app_context: */ u"abc\U0001F607",
|
||||
/* expected del */ U""
|
||||
},
|
||||
|
||||
{
|
||||
"SurrogatePairsInBothContextAndOutput",
|
||||
/* app context pre transform: */ u"a\U0001F607bcê",
|
||||
/* cached context post transform: */ u"a\U0001F607bca\U0001F60E",
|
||||
/* action del, output: */ 2, U"a\U0001F60E",
|
||||
// ---- results ----
|
||||
/* action del, output: */ 1, U"a\U0001F60E",
|
||||
/* app_context: */ u"a\U0001F607bca\U0001F60E",
|
||||
/* expected del */ U"ê"
|
||||
}
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(KeymanCore, GetActionApiTest, testing::ValuesIn(values), GenerateTestName);
|
||||
INSTANTIATE_TEST_SUITE_P(KeymanCore, GetActionApiTest, testing::ValuesIn(actionsTestData), GenerateTestName);
|
||||
|
|
|
|||
|
|
@ -15,68 +15,15 @@
|
|||
#include "context.hpp"
|
||||
|
||||
#include "../helpers/core_test_helpers.h"
|
||||
#include "./actions_test_data.h"
|
||||
|
||||
struct TestData {
|
||||
const char* test_name;
|
||||
|
||||
/**
|
||||
* the app context stored in the state, _before_ transform is applied -- NFU
|
||||
*/
|
||||
const km_core_cu *initial_app_context;
|
||||
|
||||
/**
|
||||
* cached context _after_ actions have been applied -- guaranteed NFD
|
||||
* (essentially, this is initial_cached_context -
|
||||
* actions_code_points_to_delete + actions_output) - no markers supported
|
||||
*/
|
||||
const km_core_cu *final_cached_context_string;
|
||||
|
||||
/**
|
||||
* cached context _after_ actions have been applied -- guaranteed NFD
|
||||
* (essentially, this is initial_cached_context -
|
||||
* actions_code_points_to_delete + actions_output) - markers supported
|
||||
*/
|
||||
const km_core_context_item *final_cached_context_items;
|
||||
|
||||
/**
|
||||
* number of NFD code points that the keyboard processor has asked to remove in its actions
|
||||
*/
|
||||
int actions_code_points_to_delete;
|
||||
|
||||
/**
|
||||
* NFD string that the keyboard processor has asked to insert in its actions
|
||||
*/
|
||||
const std::u32string actions_output;
|
||||
|
||||
/**
|
||||
* expected: NFU code points to ask app to remove
|
||||
*/
|
||||
const unsigned int expected_delete;
|
||||
|
||||
/**
|
||||
* expected: adjusted NFC output to insert into the app
|
||||
*/
|
||||
const std::u32string expected_output;
|
||||
|
||||
/**
|
||||
* expected: NFU adjusted final app context, which will be NFC from the
|
||||
* boundary of the transform, but will not have been modified prior to that.
|
||||
* Should match char-for-char what the app ends up with in its text buffer.
|
||||
*/
|
||||
const km_core_cu *expected_final_app_context;
|
||||
};
|
||||
|
||||
std::string GenerateTestName(const testing::TestParamInfo<TestData>& info) {
|
||||
return info.param.test_name;
|
||||
}
|
||||
|
||||
class ActionsNormalizeApiTest : public testing::TestWithParam<TestData> {
|
||||
class ActionsNormalizeApiTest : public testing::TestWithParam<ActionsTestData> {
|
||||
protected:
|
||||
km_core_keyboard * test_kb = nullptr;
|
||||
km_core_state * test_state = nullptr;
|
||||
km_core_actions test_actions = {0};
|
||||
|
||||
void Initialize(TestData const& data) {
|
||||
void Initialize(ActionsTestData const& data) {
|
||||
km::core::path path = km::core::path::join(test_dir, "..", "ldml", "fixtures", "keyboards", "17.0", "k_001_tiny.kmx");
|
||||
auto blob = km::tests::load_kmx_file(path.native().c_str());
|
||||
ASSERT_STATUS_OK(km_core_keyboard_load_from_blob(path.stem().c_str(), blob.data(), blob.size(), &test_kb));
|
||||
|
|
@ -143,282 +90,4 @@ TEST_P(ActionsNormalizeApiTest, TestActionsNormalize) {
|
|||
ASSERT_NO_FATAL_FAILURE(km::tests::compare_context(km_core_state_app_context(test_state), data.expected_final_app_context));
|
||||
}
|
||||
|
||||
const km_core_context_item items_1[] = { //u"a\U0001F607b\uFFFF\u0008\u0001ca\U0001F60E",
|
||||
{ KM_CORE_CT_CHAR, {0,}, { 0x0061 } },
|
||||
{ KM_CORE_CT_CHAR, {0,}, { 0x1F607 } },
|
||||
{ KM_CORE_CT_CHAR, {0,}, { 0x0062 } },
|
||||
{ KM_CORE_CT_MARKER, {0,}, { 0x1 } },
|
||||
{ KM_CORE_CT_CHAR, {0,}, { 0x0063 } },
|
||||
{ KM_CORE_CT_CHAR, {0,}, { 0x0061 } },
|
||||
{ KM_CORE_CT_CHAR, {0,}, { 0x1F60E } },
|
||||
KM_CORE_CONTEXT_ITEM_END
|
||||
};
|
||||
|
||||
const km_core_context_item items_2[] = { //u"a\U0001F607bca\U0001F60E\uFFFF\u0008\u0001",
|
||||
{ KM_CORE_CT_CHAR, {0,}, { 0x0061 } },
|
||||
{ KM_CORE_CT_CHAR, {0,}, { 0x1F607 } },
|
||||
{ KM_CORE_CT_CHAR, {0,}, { 0x0062 } },
|
||||
{ KM_CORE_CT_CHAR, {0,}, { 0x0063 } },
|
||||
{ KM_CORE_CT_CHAR, {0,}, { 0x0061 } },
|
||||
{ KM_CORE_CT_CHAR, {0,}, { 0x1F60E } },
|
||||
{ KM_CORE_CT_MARKER, {0,}, { 0x1 } },
|
||||
KM_CORE_CONTEXT_ITEM_END
|
||||
};
|
||||
|
||||
const km_core_context_item items_11067[] = {
|
||||
{ KM_CORE_CT_CHAR, {0,}, { U'𐒻' } },
|
||||
{ KM_CORE_CT_CHAR, {0,}, { U'𐒷' } },
|
||||
KM_CORE_CONTEXT_ITEM_END
|
||||
};
|
||||
|
||||
const TestData values[] = {
|
||||
// Null boundary tests
|
||||
{
|
||||
"Noop",
|
||||
/* app context pre transform: */ u"",
|
||||
/* cached context post transform: */ u"",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 0, U"",
|
||||
// ---- results ----
|
||||
/* action del, output: */ 0, U"",
|
||||
/* app_context: */ u""
|
||||
},
|
||||
|
||||
{
|
||||
"NoOutput",
|
||||
/* app context pre transform: */ u"abc",
|
||||
/* cached context post transform: */ u"abc",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 0, U"",
|
||||
// ---- results ----
|
||||
/* action del, output: */ 0, U"",
|
||||
/* app_context: */ u"abc"
|
||||
},
|
||||
|
||||
{
|
||||
"NoContext",
|
||||
/* app context pre transform: */ u"",
|
||||
/* cached context post transform: */ u"def",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 0, U"def",
|
||||
// ---- results ----
|
||||
/* action del, output: */ 0, U"def",
|
||||
/* app_context: */ u"def"
|
||||
},
|
||||
|
||||
// Simple tests -- no deletions involved
|
||||
|
||||
{
|
||||
"NoNormalization",
|
||||
/* app context pre transform: */ u"abc",
|
||||
/* cached context post transform: */ u"abcdef",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 0, U"def",
|
||||
// ---- results ----
|
||||
/* action del, output: */ 0, U"def",
|
||||
/* app_context: */ u"abcdef"
|
||||
},
|
||||
|
||||
{
|
||||
"OutputToNfcBasic",
|
||||
/* app context pre transform: */ u"abc",
|
||||
/* cached context post transform: */ u"abcde\u0300f",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 0, U"de\u0300f",
|
||||
// ---- results ----
|
||||
/* action del, output: */ 0, U"dèf",
|
||||
/* app_context: */ u"abcdèf"
|
||||
},
|
||||
|
||||
{
|
||||
"OutputToNfcHefty",
|
||||
/* app context pre transform: */ u"abc",
|
||||
/* cached context post transform: */ u"abcA\u0300" u"e\u0316\u0301" u"\u0073\u0323\u0307" u"\u0041\u030a" u"\U000114B9\U000114B0",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 0, U"A\u0300" U"e\u0316\u0301" U"\u0073\u0323\u0307" U"\u0041\u030a" U"\U000114B9\U000114B0",
|
||||
// ---- results ----
|
||||
/* action del, output: */ 0, U"À" U"é̖" U"\u1e69" U"\u00c5" U"\U000114BC",
|
||||
/* app_context: */ u"abcÀé̖\u1e69\u00c5\U000114BC"
|
||||
},
|
||||
|
||||
// Interaction with input context when not on normalization boundary
|
||||
|
||||
{
|
||||
"BacktrackOneCharacterToCombineAsNfc",
|
||||
/* app context pre transform: */ u"XYZA",
|
||||
/* cached context post transform: */ u"XYZA\u0300abc",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 0, U"\u0300abc",
|
||||
// ---- results ----
|
||||
/* action del, output: */ 1, U"Àabc",
|
||||
/* app_context: */ u"XYZÀabc"
|
||||
},
|
||||
|
||||
{
|
||||
"BacktrackEcombCirc2CharsToCombineAsNfc",
|
||||
/* app context pre transform: */ u"abce\u0302",
|
||||
/* cached context post transform: */ u"abce\u0323\u0302",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 1, U"\u0323\u0302",
|
||||
// ---- results ----
|
||||
/* action del, output: */ 2, U"ệ",
|
||||
/* app_context: */ u"abcệ"
|
||||
},
|
||||
|
||||
{
|
||||
"OneBackspaceToDeleteLastNfdCharacter15487",
|
||||
/* app context pre transform: */ u"abcê", // NFC
|
||||
/* cached context post transform: */ u"abce",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 1, U"", // NFD input; delete 1: \u0302
|
||||
// ---- results ----
|
||||
/* action del, output: */ 1, U"e", // NFC output; delete 1: e
|
||||
/* app_context: */ u"abce"
|
||||
},
|
||||
|
||||
{
|
||||
"OneBackspaceToDeleteLastNfdCharacterWithNfcAppContext15487",
|
||||
/* app context pre transform: */ u"abce\u0302", // NFD
|
||||
/* cached context post transform: */ u"abce",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 1, U"", // NFD input; delete 1: \u0302
|
||||
// ---- results ----
|
||||
/* action del, output: */ 1, U"", // NFC output; delete 1: e
|
||||
/* app_context: */ u"abce"
|
||||
},
|
||||
|
||||
{
|
||||
"OneBackspaceForNfdConvertsIntoOneCharInNfcAndRecombine",
|
||||
/* app context pre transform: */ u"abcê",
|
||||
/* cached context post transform: */ u"abce\u0323\u0302",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 1, U"\u0323\u0302", // NFD input; delete 1: \u0302
|
||||
// ---- results ----
|
||||
/* action del, output: */ 1, U"ệ", // NFC output; delete 1: ê
|
||||
/* app_context: */ u"abcệ"
|
||||
},
|
||||
|
||||
// a\u0300 should not be normalized because it is not otherwise impacted by
|
||||
// the action.
|
||||
{
|
||||
"AvoidEditingTooFarBackInContextWhenFindingNormalizationBoundary",
|
||||
/* app context pre transform: */ u"a\u0300bcê",
|
||||
/* cached context post transform: */ u"a\u0300bce\u0323\u0302",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 1, U"\u0323\u0302", // NFD input; delete 1: \u0302
|
||||
// ---- results ----
|
||||
/* action del, output: */ 1, U"ệ", // NFC output; delete 1: ê
|
||||
/* app_context: */ u"a\u0300bcệ"
|
||||
},
|
||||
|
||||
// If we don't reach a normalization boundary, we still should continue to work
|
||||
{
|
||||
"NormalizableLettersAtStartOfContext",
|
||||
/* app context pre transform: */ u"\u0300",
|
||||
/* cached context post transform: */ u"\u0323\u0300\u0302",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 1, U"\u0323\u0300\u0302", // NFD input;
|
||||
// ---- results ----
|
||||
/* action del, output: */ 1, U"\u0323\u0300\u0302", // NFC output is still decomposed because there is no base
|
||||
/* app_context: */ u"\u0323\u0300\u0302"
|
||||
},
|
||||
|
||||
// #15505 - normalization of Bengali characters
|
||||
{
|
||||
"BengaliNormalizationOfU09C7U09D7U09CC",
|
||||
/* app context pre transform: */ u"\u0995\u09C7",
|
||||
/* cached context post transform: */ u"\u0995\u09C7\u09D7",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 0, U"\u09D7",
|
||||
// ---- results ----
|
||||
/* action del, output: */ 1, U"\u09CC",
|
||||
/* app_context: */ u"\u0995\u09CC"
|
||||
},
|
||||
|
||||
// Modifies the base as well as diacritic
|
||||
|
||||
{
|
||||
"TwoBackspacesForNfdConvertsIntoOneCharInNfcAndRecombine",
|
||||
/* app context pre transform: */ u"abcê",
|
||||
/* cached context post transform: */ u"abca\u0323\u0302",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 2, U"a\u0323\u0302", // NFD input; delete 2: e\u0302
|
||||
// ---- results ----
|
||||
/* action del, output: */ 1, U"ậ", // NFC output; delete 1: ê
|
||||
/* app_context: */ u"abcậ"
|
||||
},
|
||||
|
||||
// surrogate pair tests
|
||||
|
||||
{
|
||||
"SurrogatePairInContext",
|
||||
/* app context pre transform: */ u"abc\U0001F607ê",
|
||||
/* cached context post transform: */ u"abc\U0001F607a\u0323\u0302",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 2, U"a\u0323\u0302",
|
||||
// ---- results ----
|
||||
/* action del, output: */ 1, U"ậ",
|
||||
/* app_context: */ u"abc\U0001F607ậ"
|
||||
},
|
||||
|
||||
{
|
||||
"SurrogatePairInOutput",
|
||||
/* app context pre transform: */ u"abc",
|
||||
/* cached context post transform: */ u"abc\U0001F607",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 0, U"\U0001F607",
|
||||
// ---- results ----
|
||||
/* action del, output: */ 0, U"\U0001F607",
|
||||
/* app_context: */ u"abc\U0001F607"
|
||||
},
|
||||
|
||||
{
|
||||
"SurrogatePairsInBothContextAndOutput",
|
||||
/* app context pre transform: */ u"a\U0001F607bcê",
|
||||
/* cached context post transform: */ u"a\U0001F607bca\U0001F60E",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 2, U"a\U0001F60E",
|
||||
// ---- results ----
|
||||
/* action del, output: */ 1, U"a\U0001F60E",
|
||||
/* app_context: */ u"a\U0001F607bca\U0001F60E"
|
||||
},
|
||||
|
||||
// Marker tests
|
||||
|
||||
{
|
||||
"AMarkerInTheCachedContextShouldNotShowUpInAppContext",
|
||||
/* app context pre transform: */ u"a\U0001F607bcê",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* cached context post transform: */ &items_1[0],
|
||||
|
||||
/* action del, output: */ 2, U"a\U0001F60E",
|
||||
// ---- results ----
|
||||
/* action del, output: */ 1, U"a\U0001F60E",
|
||||
/* app_context: */ u"a\U0001F607bca\U0001F60E"
|
||||
},
|
||||
|
||||
{
|
||||
"AMarkerInTheModifiedSectionOfCachedContextShouldNotShowUpInAppContext",
|
||||
/* app context pre transform: */ u"a\U0001F607bcê",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* cached context post transform: */ &items_2[0],
|
||||
/* action del, output: */ 2, U"a\U0001F60E",
|
||||
// ---- results ----
|
||||
/* action del, output: */ 1, U"a\U0001F60E",
|
||||
/* app_context: */ u"a\U0001F607bca\U0001F60E"
|
||||
},
|
||||
|
||||
// regression #11067
|
||||
{
|
||||
"ANonBmpCharInContext11067",
|
||||
/* app context pre transform: */ u"𐒻",
|
||||
/* cached context post transform: */ u"𐒻𐒷",
|
||||
/* cached context post transform: */ &items_11067[0],
|
||||
/* action del, output: */ 0, U"𐒻𐒷",
|
||||
// ---- results ----
|
||||
/* action del, output: */ 1, U"𐒻𐒷",
|
||||
/* app_context: */ u"𐒻𐒷"
|
||||
}
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(KeymanCore, ActionsNormalizeApiTest, testing::ValuesIn(values), GenerateTestName);
|
||||
INSTANTIATE_TEST_SUITE_P(KeymanCore, ActionsNormalizeApiTest, testing::ValuesIn(actionsTestData), GenerateTestName);
|
||||
|
|
|
|||
306
core/tests/unit/api/actions_test_data.cpp
Normal file
306
core/tests/unit/api/actions_test_data.cpp
Normal file
|
|
@ -0,0 +1,306 @@
|
|||
|
||||
#include "./actions_test_data.h"
|
||||
|
||||
const km_core_context_item items_1[] = { //u"a\U0001F607b\uFFFF\u0008\u0001ca\U0001F60E",
|
||||
{ KM_CORE_CT_CHAR, {0,}, { 0x0061 } },
|
||||
{ KM_CORE_CT_CHAR, {0,}, { 0x1F607 } },
|
||||
{ KM_CORE_CT_CHAR, {0,}, { 0x0062 } },
|
||||
{ KM_CORE_CT_MARKER, {0,}, { 0x1 } },
|
||||
{ KM_CORE_CT_CHAR, {0,}, { 0x0063 } },
|
||||
{ KM_CORE_CT_CHAR, {0,}, { 0x0061 } },
|
||||
{ KM_CORE_CT_CHAR, {0,}, { 0x1F60E } },
|
||||
KM_CORE_CONTEXT_ITEM_END
|
||||
};
|
||||
|
||||
const km_core_context_item items_2[] = { //u"a\U0001F607bca\U0001F60E\uFFFF\u0008\u0001",
|
||||
{ KM_CORE_CT_CHAR, {0,}, { 0x0061 } },
|
||||
{ KM_CORE_CT_CHAR, {0,}, { 0x1F607 } },
|
||||
{ KM_CORE_CT_CHAR, {0,}, { 0x0062 } },
|
||||
{ KM_CORE_CT_CHAR, {0,}, { 0x0063 } },
|
||||
{ KM_CORE_CT_CHAR, {0,}, { 0x0061 } },
|
||||
{ KM_CORE_CT_CHAR, {0,}, { 0x1F60E } },
|
||||
{ KM_CORE_CT_MARKER, {0,}, { 0x1 } },
|
||||
KM_CORE_CONTEXT_ITEM_END
|
||||
};
|
||||
|
||||
const km_core_context_item items_11067[] = {
|
||||
{ KM_CORE_CT_CHAR, {0,}, { U'𐒻' } },
|
||||
{ KM_CORE_CT_CHAR, {0,}, { U'𐒷' } },
|
||||
KM_CORE_CONTEXT_ITEM_END
|
||||
};
|
||||
|
||||
const std::vector<ActionsTestData> actionsTestData = {
|
||||
// Null boundary tests
|
||||
|
||||
{
|
||||
"Noop",
|
||||
/* app context pre transform: */ u"",
|
||||
/* cached context post transform: */ u"",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 0, U"",
|
||||
// ---- results ----
|
||||
/* expected action del, output: */ 0, U"",
|
||||
/* expected app_context: */ u"",
|
||||
/* expected del */ U""
|
||||
},
|
||||
|
||||
{
|
||||
"NoOutput",
|
||||
/* app context pre transform: */ u"abc",
|
||||
/* cached context post transform: */ u"abc",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 0, U"",
|
||||
// ---- results ----
|
||||
/* expected action del, output: */ 0, U"",
|
||||
/* expected app_context: */ u"abc",
|
||||
/* expected del */ U""
|
||||
},
|
||||
|
||||
{
|
||||
"NoContext",
|
||||
/* app context pre transform: */ u"",
|
||||
/* cached context post transform: */ u"def",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 0, U"def",
|
||||
// ---- results ----
|
||||
/* expected action del, output: */ 0, U"def",
|
||||
/* expected app_context: */ u"def",
|
||||
/* expected del */ U""
|
||||
},
|
||||
|
||||
// Simple tests -- no deletions involved
|
||||
|
||||
{
|
||||
"NoNormalization",
|
||||
/* app context pre transform: */ u"abc",
|
||||
/* cached context post transform: */ u"abcdef",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 0, U"def",
|
||||
// ---- results ----
|
||||
/* expected action del, output: */ 0, U"def",
|
||||
/* expected app_context: */ u"abcdef",
|
||||
/* expected del */ U""
|
||||
},
|
||||
|
||||
{
|
||||
"OutputToNfcBasic",
|
||||
/* app context pre transform: */ u"abc",
|
||||
/* cached context post transform: */ u"abcde\u0300f",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 0, U"de\u0300f",
|
||||
// ---- results ----
|
||||
/* expected action del, output: */ 0, U"dèf",
|
||||
/* expected app_context: */ u"abcdèf",
|
||||
/* expected del */ U""
|
||||
},
|
||||
|
||||
{
|
||||
"OutputToNfcHefty",
|
||||
/* app context pre transform: */ u"abc",
|
||||
/* cached context post transform: */ u"abcA\u0300" u"e\u0316\u0301" u"\u0073\u0323\u0307" u"\u0041\u030a" u"\U000114B9\U000114B0",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 0, U"A\u0300" U"e\u0316\u0301" U"\u0073\u0323\u0307" U"\u0041\u030a" U"\U000114B9\U000114B0",
|
||||
// ---- results ----
|
||||
/* expected action del, output: */ 0, U"À" U"é̖" U"\u1e69" U"\u00c5" U"\U000114BC",
|
||||
/* expected app_context: */ u"abcÀé̖\u1e69\u00c5\U000114BC",
|
||||
/* expected del */ U""
|
||||
},
|
||||
|
||||
// Interaction with input context when not on normalization boundary
|
||||
|
||||
{
|
||||
"BacktrackOneCharacterToCombineAsNfc",
|
||||
/* app context pre transform: */ u"XYZA",
|
||||
/* cached context post transform: */ u"XYZA\u0300abc",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 0, U"\u0300abc",
|
||||
// ---- results ----
|
||||
/* expected action del, output: */ 1, U"Àabc",
|
||||
/* expected app_context: */ u"XYZÀabc",
|
||||
/* expected del */ U"A"
|
||||
},
|
||||
|
||||
{
|
||||
"BacktrackECombCirc2CharsToCombineAsNfc",
|
||||
/* app context pre transform: */ u"abce\u0302",
|
||||
/* cached context post transform: */ u"abce\u0323\u0302",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 1, U"\u0323\u0302",
|
||||
// ---- results ----
|
||||
/* expected action del, output: */ 2, U"ệ",
|
||||
/* expected app_context: */ u"abcệ",
|
||||
/* expected del */ U"e\u0302"
|
||||
},
|
||||
|
||||
{
|
||||
"OneBackspaceToDeleteLastNfdCharacter15487",
|
||||
/* app context pre transform: */ u"abcê", // NFC
|
||||
/* cached context post transform: */ u"abce",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 1, U"", // NFD input; delete 1: \u0302
|
||||
// ---- results ----
|
||||
/* expected action del, output: */ 1, U"e", // NFC output; delete 1: e
|
||||
/* expected app_context: */ u"abce",
|
||||
/* expected del */ U"ê"
|
||||
},
|
||||
|
||||
{
|
||||
"OneBackspaceToDeleteLastNfdCharacterWithNfdAppContext15487",
|
||||
/* app context pre transform: */ u"abce\u0302", // NFD
|
||||
/* cached context post transform: */ u"abce",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 1, U"", // NFD input; delete 1: \u0302
|
||||
// ---- results ----
|
||||
/* expected action del, output: */ 1, U"", // NFC output; delete 1: e
|
||||
/* expected app_context: */ u"abce",
|
||||
/* expected del */ U"\u0302"
|
||||
},
|
||||
|
||||
{
|
||||
"OneBackspaceForNfdConvertsIntoOneCharInNfcAndRecombine",
|
||||
/* app context pre transform: */ u"abcê",
|
||||
/* cached context post transform: */ u"abce\u0323\u0302",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 1, U"\u0323\u0302", // NFD input; delete 1: \u0302
|
||||
// ---- results ----
|
||||
/* expected action del, output: */ 1, U"ệ", // NFC output; delete 1: ê
|
||||
/* expected app_context: */ u"abcệ",
|
||||
/* expected del */ U"ê"
|
||||
},
|
||||
|
||||
// a\u0300 should not be normalized because it is not otherwise impacted by
|
||||
// the action.
|
||||
{
|
||||
"AvoidEditingTooFarBackInContextWhenFindingNormalizationBoundary",
|
||||
/* app context pre transform: */ u"a\u0300bcê",
|
||||
/* cached context post transform: */ u"a\u0300bce\u0323\u0302",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 1, U"\u0323\u0302", // NFD input; delete 1: \u0302
|
||||
// ---- results ----
|
||||
/* expected action del, output: */ 1, U"ệ", // NFC output; delete 1: ê
|
||||
/* expected app_context: */ u"a\u0300bcệ",
|
||||
/* expected del */ U"ê"
|
||||
},
|
||||
|
||||
// If we don't reach a normalization boundary, we still should continue to work
|
||||
{
|
||||
"NormalizableLettersAtStartOfContext",
|
||||
/* app context pre transform: */ u"\u0300",
|
||||
/* cached context post transform: */ u"\u0323\u0300\u0302",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 1, U"\u0323\u0300\u0302", // NFD input;
|
||||
// ---- results ----
|
||||
/* expected action del, output: */ 1, U"\u0323\u0300\u0302", // NFC output is still decomposed because there is no base
|
||||
/* expected app_context: */ u"\u0323\u0300\u0302",
|
||||
/* expected del */ U"\u0300"
|
||||
},
|
||||
|
||||
// #15505 - normalization of Bengali characters
|
||||
{
|
||||
"BengaliNormalizationOfU09C7U09D7U09CC",
|
||||
/* app context pre transform: */ u"\u0995\u09C7",
|
||||
/* cached context post transform: */ u"\u0995\u09C7\u09D7",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 0, U"\u09D7",
|
||||
// ---- results ----
|
||||
/* expected action del, output: */ 1, U"\u09CC",
|
||||
/* expected app_context: */ u"\u0995\u09CC",
|
||||
/* expected del */ U"\u09C7"
|
||||
},
|
||||
|
||||
// Modifies the base as well as diacritic
|
||||
|
||||
{
|
||||
"TwoBackspacesForNfdConvertsIntoOneCharInNfcAndRecombine",
|
||||
/* app context pre transform: */ u"abcê",
|
||||
/* cached context post transform: */ u"abca\u0323\u0302",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 2, U"a\u0323\u0302", // NFD input; delete 2: e\u0302
|
||||
// ---- results ----
|
||||
/* expected action del, output: */ 1, U"ậ", // NFC output; delete 1: ê
|
||||
/* expected app_context: */ u"abcậ",
|
||||
/* expected del */ U"ê"
|
||||
},
|
||||
|
||||
// surrogate pair tests
|
||||
|
||||
{
|
||||
"SurrogatePairInContext",
|
||||
/* app context pre transform: */ u"abc\U0001F607ê",
|
||||
/* cached context post transform: */ u"abc\U0001F607a\u0323\u0302",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 2, U"a\u0323\u0302",
|
||||
// ---- results ----
|
||||
/* expected action del, output: */ 1, U"ậ",
|
||||
/* expected app_context: */ u"abc\U0001F607ậ",
|
||||
/* expected del */ U"ê"
|
||||
},
|
||||
|
||||
{
|
||||
"SurrogatePairInOutput",
|
||||
/* app context pre transform: */ u"abc",
|
||||
/* cached context post transform: */ u"abc\U0001F607",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 0, U"\U0001F607",
|
||||
// ---- results ----
|
||||
/* expected action del, output: */ 0, U"\U0001F607",
|
||||
/* expected app_context: */ u"abc\U0001F607",
|
||||
/* expected del */ U""
|
||||
},
|
||||
|
||||
{
|
||||
"SurrogatePairsInBothContextAndOutput",
|
||||
/* app context pre transform: */ u"a\U0001F607bcê",
|
||||
/* cached context post transform: */ u"a\U0001F607bca\U0001F60E",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 2, U"a\U0001F60E",
|
||||
// ---- results ----
|
||||
/* expected action del, output: */ 1, U"a\U0001F60E",
|
||||
/* expected app_context: */ u"a\U0001F607bca\U0001F60E",
|
||||
/* expected del */ U"ê"
|
||||
},
|
||||
|
||||
// Marker tests
|
||||
|
||||
{
|
||||
"AMarkerInTheCachedContextShouldNotShowUpInAppContext",
|
||||
/* app context pre transform: */ u"a\U0001F607bcê",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* cached context post transform: */ &items_1[0],
|
||||
|
||||
/* action del, output: */ 2, U"a\U0001F60E",
|
||||
// ---- results ----
|
||||
/* expected action del, output: */ 1, U"a\U0001F60E",
|
||||
/* expected app_context: */ u"a\U0001F607bca\U0001F60E",
|
||||
/* expected del */ U"ê"
|
||||
},
|
||||
|
||||
{
|
||||
"AMarkerInTheModifiedSectionOfCachedContextShouldNotShowUpInAppContext",
|
||||
/* app context pre transform: */ u"a\U0001F607bcê",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* cached context post transform: */ &items_2[0],
|
||||
/* action del, output: */ 2, U"a\U0001F60E",
|
||||
// ---- results ----
|
||||
/* expected action del, output: */ 1, U"a\U0001F60E",
|
||||
/* expected app_context: */ u"a\U0001F607bca\U0001F60E",
|
||||
/* expected del */ U"ê"
|
||||
},
|
||||
|
||||
// regression #11067
|
||||
{
|
||||
"ANonBmpCharInContext11067",
|
||||
/* app context pre transform: */ u"𐒻",
|
||||
/* cached context post transform: */ u"𐒻𐒷",
|
||||
/* cached context post transform: */ &items_11067[0],
|
||||
/* action del, output: */ 0, U"𐒻𐒷",
|
||||
// ---- results ----
|
||||
/* expected action del, output: */ 1, U"𐒻𐒷",
|
||||
/* expected app_context: */ u"𐒻𐒷",
|
||||
/* expected del: */ U"\x104BB"
|
||||
}
|
||||
};
|
||||
|
||||
std::string GenerateTestName(const testing::TestParamInfo<ActionsTestData>& info) {
|
||||
return info.param.test_name;
|
||||
}
|
||||
64
core/tests/unit/api/actions_test_data.h
Normal file
64
core/tests/unit/api/actions_test_data.h
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <gtest/gtest.h>
|
||||
#include "keyman_core.h"
|
||||
|
||||
struct ActionsTestData {
|
||||
const char* test_name;
|
||||
|
||||
/**
|
||||
* the app context stored in the state, _before_ transform is applied -- NFU
|
||||
*/
|
||||
const km_core_cu *initial_app_context;
|
||||
|
||||
/**
|
||||
* cached context _after_ actions have been applied -- guaranteed NFD
|
||||
* (essentially, this is initial_cached_context -
|
||||
* actions_code_points_to_delete + actions_output) - no markers supported
|
||||
*/
|
||||
const km_core_cu *final_cached_context_string;
|
||||
|
||||
/**
|
||||
* cached context _after_ actions have been applied -- guaranteed NFD
|
||||
* (essentially, this is initial_cached_context -
|
||||
* actions_code_points_to_delete + actions_output) - markers supported
|
||||
*/
|
||||
const km_core_context_item *final_cached_context_items;
|
||||
|
||||
/**
|
||||
* number of NFD code points that the keyboard processor has asked to remove in its actions
|
||||
*/
|
||||
int actions_code_points_to_delete;
|
||||
|
||||
/**
|
||||
* NFD string that the keyboard processor has asked to insert in its actions
|
||||
*/
|
||||
const std::u32string actions_output;
|
||||
|
||||
/**
|
||||
* expected: NFU code points to ask app to remove
|
||||
*/
|
||||
const unsigned int expected_delete;
|
||||
|
||||
/**
|
||||
* expected: adjusted NFC output to insert into the app
|
||||
*/
|
||||
const std::u32string expected_output;
|
||||
|
||||
/**
|
||||
* expected: NFU adjusted final app context, which will be NFC from the
|
||||
* boundary of the transform, but will not have been modified prior to that.
|
||||
* Should match char-for-char what the app ends up with in its text buffer.
|
||||
*/
|
||||
const km_core_cu *expected_final_app_context;
|
||||
|
||||
/**
|
||||
* expected: the characters deleted from the context
|
||||
*/
|
||||
const std::u32string expected_deleted_context;
|
||||
};
|
||||
|
||||
extern const std::vector<ActionsTestData> actionsTestData;
|
||||
|
||||
std::string GenerateTestName(const testing::TestParamInfo<ActionsTestData>& info);
|
||||
|
|
@ -15,72 +15,15 @@
|
|||
#include "context.hpp"
|
||||
|
||||
#include "../helpers/core_test_helpers.h"
|
||||
#include "./actions_test_data.h"
|
||||
|
||||
// TODO-WEB-CORE: merge with actions_normalize.tests.cpp? These are identical;
|
||||
// note that actions_get_api and actions_set_api data are subtly different,
|
||||
// opportunity to merge those too?
|
||||
|
||||
struct TestData {
|
||||
const char* test_name;
|
||||
|
||||
/**
|
||||
* the app context stored in the state, _before_ transform is applied -- NFU
|
||||
*/
|
||||
const km_core_cu *initial_app_context;
|
||||
|
||||
/**
|
||||
* cached context _after_ actions have been applied -- guaranteed NFD
|
||||
* (essentially, this is initial_cached_context -
|
||||
* actions_code_points_to_delete + actions_output) - no markers supported
|
||||
*/
|
||||
const km_core_cu *final_cached_context_string;
|
||||
|
||||
/**
|
||||
* cached context _after_ actions have been applied -- guaranteed NFD
|
||||
* (essentially, this is initial_cached_context -
|
||||
* actions_code_points_to_delete + actions_output) - markers supported
|
||||
*/
|
||||
const km_core_context_item *final_cached_context_items;
|
||||
|
||||
/**
|
||||
* number of NFD code points that the keyboard processor has asked to remove in its actions
|
||||
*/
|
||||
int actions_code_points_to_delete;
|
||||
|
||||
/**
|
||||
* NFD string that the keyboard processor has asked to insert in its actions
|
||||
*/
|
||||
const std::u32string actions_output;
|
||||
|
||||
/**
|
||||
* expected: NFU code points to ask app to remove
|
||||
*/
|
||||
const unsigned int expected_delete;
|
||||
|
||||
/**
|
||||
* expected: adjusted NFC output to insert into the app
|
||||
*/
|
||||
const std::u32string expected_output;
|
||||
|
||||
/**
|
||||
* expected: NFU adjusted final app context, which will be NFC from the
|
||||
* boundary of the transform, but will not have been modified prior to that.
|
||||
* Should match char-for-char what the app ends up with in its text buffer.
|
||||
*/
|
||||
const km_core_cu *expected_final_app_context;
|
||||
};
|
||||
|
||||
std::string GenerateTestName(const testing::TestParamInfo<TestData>& info) {
|
||||
return info.param.test_name;
|
||||
}
|
||||
|
||||
class ActionsUpdateAppContextNfuApiTest : public testing::TestWithParam<TestData> {
|
||||
class ActionsUpdateAppContextNfuApiTest : public testing::TestWithParam<ActionsTestData> {
|
||||
protected:
|
||||
km_core_keyboard * test_kb = nullptr;
|
||||
km_core_state * test_state = nullptr;
|
||||
km_core_actions test_actions = {0};
|
||||
|
||||
void Initialize(TestData const& data) {
|
||||
void Initialize(ActionsTestData const& data) {
|
||||
km::core::path path = km::core::path::join(test_dir, "..", "ldml", "fixtures", "keyboards", "17.0", "k_001_tiny.kmx");
|
||||
auto blob = km::tests::load_kmx_file(path.native().c_str());
|
||||
ASSERT_STATUS_OK(km_core_keyboard_load_from_blob(path.stem().c_str(), blob.data(), blob.size(), &test_kb));
|
||||
|
|
@ -172,7 +115,23 @@ const km_core_context_item items_2[] = { //u"a\U0001F607bca\U0001F60E\uFFFF\u000
|
|||
KM_CORE_CONTEXT_ITEM_END
|
||||
};
|
||||
|
||||
const TestData values[] = {
|
||||
const km_core_context_item items_11067[] = {
|
||||
{ KM_CORE_CT_CHAR, {0,}, { U'𐒻' } },
|
||||
{ KM_CORE_CT_CHAR, {0,}, { U'𐒷' } },
|
||||
KM_CORE_CONTEXT_ITEM_END
|
||||
};
|
||||
|
||||
/**
|
||||
* Test cases for non-normalized app context update. These look superficially
|
||||
* similar to the data in `actionsTestData`, but diverge when taking into
|
||||
* account normalization of output. Several normalization-related tests in
|
||||
* `actionsTestData` are therefore also currently excluded here.
|
||||
*
|
||||
* @todo: (low priority) `actionsTestData` and `actionsTestDataNFU` could be
|
||||
* combined with additional entries for each NFU result.
|
||||
*/
|
||||
|
||||
const std::vector<ActionsTestData> actionsTestDataNFU = {
|
||||
// Null boundary tests
|
||||
|
||||
{
|
||||
|
|
@ -182,8 +141,9 @@ const TestData values[] = {
|
|||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 0, U"",
|
||||
// ---- results ----
|
||||
/* action del, output: */ 0, U"",
|
||||
/* app_context: */ u""
|
||||
/* expected action del, output: */ 0, U"",
|
||||
/* expected app_context: */ u"",
|
||||
/* expected del */ U""
|
||||
},
|
||||
|
||||
{
|
||||
|
|
@ -193,8 +153,9 @@ const TestData values[] = {
|
|||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 0, U"",
|
||||
// ---- results ----
|
||||
/* action del, output: */ 0, U"",
|
||||
/* app_context: */ u"abc"
|
||||
/* expected action del, output: */ 0, U"",
|
||||
/* expected app_context: */ u"abc",
|
||||
/* expected del */ U""
|
||||
},
|
||||
|
||||
{
|
||||
|
|
@ -204,10 +165,26 @@ const TestData values[] = {
|
|||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 0, U"def",
|
||||
// ---- results ----
|
||||
/* action del, output: */ 0, U"def",
|
||||
/* app_context: */ u"def"
|
||||
/* expected action del, output: */ 0, U"def",
|
||||
/* expected app_context: */ u"def",
|
||||
/* expected del */ U""
|
||||
},
|
||||
|
||||
// Simple tests -- no deletions involved
|
||||
|
||||
{
|
||||
"NoNormalization",
|
||||
/* app context pre transform: */ u"abc",
|
||||
/* cached context post transform: */ u"abcdef",
|
||||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 0, U"def",
|
||||
// ---- results ----
|
||||
/* expected action del, output: */ 0, U"def",
|
||||
/* expected app_context: */ u"abcdef",
|
||||
/* expected del */ U""
|
||||
},
|
||||
|
||||
|
||||
// surrogate pair tests
|
||||
|
||||
{
|
||||
|
|
@ -217,8 +194,9 @@ const TestData values[] = {
|
|||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 1, U"a\u0323\u0302",
|
||||
// ---- results ----
|
||||
/* action del, output: */ 1, U"a\u0323\u0302",
|
||||
/* app_context: */ u"abc\U0001F607a\u0323\u0302"
|
||||
/* expected action del, output: */ 1, U"a\u0323\u0302",
|
||||
/* expected app_context: */ u"abc\U0001F607a\u0323\u0302",
|
||||
/* expected del */ U"ê"
|
||||
},
|
||||
|
||||
{
|
||||
|
|
@ -228,8 +206,9 @@ const TestData values[] = {
|
|||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 0, U"\U0001F607",
|
||||
// ---- results ----
|
||||
/* action del, output: */ 0, U"\U0001F607",
|
||||
/* app_context: */ u"abc\U0001F607"
|
||||
/* expected action del, output: */ 0, U"\U0001F607",
|
||||
/* expected app_context: */ u"abc\U0001F607",
|
||||
/* expected del */ U""
|
||||
},
|
||||
|
||||
{
|
||||
|
|
@ -239,8 +218,9 @@ const TestData values[] = {
|
|||
/* cached context post transform: */ nullptr,
|
||||
/* action del, output: */ 1, U"a\U0001F60E",
|
||||
// ---- results ----
|
||||
/* action del, output: */ 1, U"a\U0001F60E",
|
||||
/* app_context: */ u"a\U0001F607bca\U0001F60E"
|
||||
/* expected action del, output: */ 1, U"a\U0001F60E",
|
||||
/* expected app_context: */ u"a\U0001F607bca\U0001F60E",
|
||||
/* expected del */ U"ê"
|
||||
},
|
||||
|
||||
// Marker tests
|
||||
|
|
@ -252,8 +232,9 @@ const TestData values[] = {
|
|||
/* cached context post transform: */ &items_1[0],
|
||||
/* action del, output: */ 1, U"a\U0001F60E",
|
||||
// ---- results ----
|
||||
/* action del, output: */ 1, U"a\U0001F60E",
|
||||
/* app_context: */ u"a\U0001F607bca\U0001F60E"
|
||||
/* expected action del, output: */ 1, U"a\U0001F60E",
|
||||
/* expected app_context: */ u"a\U0001F607bca\U0001F60E",
|
||||
/* expected del */ U"ê"
|
||||
},
|
||||
|
||||
{
|
||||
|
|
@ -263,9 +244,23 @@ const TestData values[] = {
|
|||
/* cached context post transform: */ &items_2[0],
|
||||
/* action del, output: */ 1, U"a\U0001F60E",
|
||||
// ---- results ----
|
||||
/* action del, output: */ 1, U"a\U0001F60E",
|
||||
/* app_context: */ u"a\U0001F607bca\U0001F60E"
|
||||
/* expected action del, output: */ 1, U"a\U0001F60E",
|
||||
/* expected app_context: */ u"a\U0001F607bca\U0001F60E",
|
||||
/* expected del */ U"ê"
|
||||
},
|
||||
|
||||
// regression #11067
|
||||
{
|
||||
"ANonBmpCharInContext11067",
|
||||
/* app context pre transform: */ u"𐒻",
|
||||
/* cached context post transform: */ u"𐒻𐒷",
|
||||
/* cached context post transform: */ &items_11067[0],
|
||||
/* action del, output: */ 1, U"𐒻𐒷",
|
||||
// ---- results ----
|
||||
/* expected action del, output: */ 1, U"𐒻𐒷",
|
||||
/* expected app_context: */ u"𐒻𐒷",
|
||||
/* expected del: */ U"\x104BB"
|
||||
}
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(KeymanCore, ActionsUpdateAppContextNfuApiTest, testing::ValuesIn(values), GenerateTestName);
|
||||
INSTANTIATE_TEST_SUITE_P(KeymanCore, ActionsUpdateAppContextNfuApiTest, testing::ValuesIn(actionsTestDataNFU), GenerateTestName);
|
||||
|
|
|
|||
|
|
@ -40,15 +40,15 @@ tests = [
|
|||
['debug-api-tests', 'debug_api.tests.cpp'],
|
||||
['kmx_xstring-tests', 'kmx_xstring.tests.cpp'],
|
||||
['kmx_context-tests', 'kmx_context.tests.cpp'],
|
||||
['actions_normalize-tests', 'actions_normalize.tests.cpp'],
|
||||
['actions_normalize-tests', ['actions_normalize.tests.cpp', 'actions_test_data.cpp']],
|
||||
|
||||
# renamed to avoid heuristic that causes "update" in a filename to require
|
||||
# elevation on Windows! this could also be avoided by adding a manifest
|
||||
# resource to each executable (e.g. with mt.exe)
|
||||
# https://learn.microsoft.com/en-us/windows/security/application-security/application-control/user-account-control/architecture#installer-detection-technology
|
||||
['actions_updatx_app_context_nfu-tests', 'actions_update_app_context_nfu.tests.cpp'],
|
||||
['actions_updatx_app_context_nfu-tests', ['actions_update_app_context_nfu.tests.cpp', 'actions_test_data.cpp']],
|
||||
|
||||
['actions_get_api-tests', 'actions_get_api.tests.cpp'],
|
||||
['actions_get_api-tests', ['actions_get_api.tests.cpp', 'actions_test_data.cpp']],
|
||||
['km_core_keyboard_api-tests', 'km_core_keyboard_api.tests.cpp'],
|
||||
['km_core_process_event-tests', 'km_core_process_event.tests.cpp'],
|
||||
['key_list-tests', 'kmx_key_list.tests.cpp'],
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue