mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-31 04:37:41 +00:00
feat(core): infrastructure for normalization of output
Relates to #9999. Establishes functions, unit test sources, normalization entry point and an effectively no-op unit test for normalization support.
This commit is contained in:
parent
ba1f5921cf
commit
e39affe93b
9 changed files with 172 additions and 9 deletions
|
|
@ -116,7 +116,7 @@ km_core_context_items_dispose(km_core_context_item *context_items);
|
|||
*/
|
||||
KMN_API
|
||||
km_core_context *
|
||||
km_core_state_context(km_core_state *state);
|
||||
km_core_state_context(km_core_state const *state);
|
||||
|
||||
/**
|
||||
* Get access to the state object's application context.
|
||||
|
|
@ -127,7 +127,7 @@ km_core_state_context(km_core_state *state);
|
|||
*/
|
||||
KMN_API
|
||||
km_core_context *
|
||||
km_core_state_app_context(km_core_state *state);
|
||||
km_core_state_app_context(km_core_state const *state);
|
||||
|
||||
/*
|
||||
```
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
#include "state.hpp"
|
||||
#include "option.hpp"
|
||||
|
||||
km_core_actions const * km::core::action_item_list_to_actions_object(
|
||||
km_core_actions * km::core::action_item_list_to_actions_object(
|
||||
km_core_action_item const *action_items
|
||||
) {
|
||||
assert(action_items != nullptr);
|
||||
|
|
|
|||
|
|
@ -14,8 +14,14 @@
|
|||
namespace km {
|
||||
namespace core
|
||||
{
|
||||
km_core_actions const *action_item_list_to_actions_object(
|
||||
km_core_actions *action_item_list_to_actions_object(
|
||||
km_core_action_item const *action_items
|
||||
);
|
||||
|
||||
bool actions_normalize(
|
||||
km_core_context const *cached_context,
|
||||
km_core_context const *app_context,
|
||||
km_core_actions *actions
|
||||
);
|
||||
} // namespace core
|
||||
} // namespace km
|
||||
|
|
|
|||
34
core/src/actions_normalize.cpp
Normal file
34
core/src/actions_normalize.cpp
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
Copyright: © 2024 SIL International.
|
||||
Description: Implementation of the action output normalization.
|
||||
Create Date: 16 Jan 2024
|
||||
Authors: Marc Durdin (MCD)
|
||||
History: 16 Jan 2024 - MCD - Initial implementation from #9999
|
||||
*/
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <memory>
|
||||
|
||||
#include "action.hpp"
|
||||
#include "state.hpp"
|
||||
#include "option.hpp"
|
||||
|
||||
bool km::core::actions_normalize(
|
||||
km_core_context const *cached_context,
|
||||
km_core_context const *app_context,
|
||||
km_core_actions *actions
|
||||
) {
|
||||
assert(actions != nullptr);
|
||||
assert(cached_context != nullptr);
|
||||
assert(app_context != nullptr);
|
||||
if(actions == nullptr || cached_context == nullptr || app_context == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Normalize output to NFC
|
||||
//TODO
|
||||
// actions->code_points_to_delete++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -33,7 +33,16 @@ km_core_actions const * km_core_state_get_actions(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
return action_item_list_to_actions_object(action_items);
|
||||
km_core_actions * result = action_item_list_to_actions_object(action_items);
|
||||
|
||||
if(state->processor().supports_normalization()) {
|
||||
// Normalize to NFC for those keyboard processors that support it
|
||||
if(!actions_normalize(km_core_state_context(state), km_core_state_app_context(state), result)) {
|
||||
km_core_actions_dispose(result);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
km_core_status km_core_actions_dispose(
|
||||
|
|
|
|||
|
|
@ -65,20 +65,20 @@ void km_core_state_dispose(km_core_state *state)
|
|||
}
|
||||
|
||||
|
||||
km_core_context *km_core_state_context(km_core_state *state)
|
||||
km_core_context *km_core_state_context(km_core_state const *state)
|
||||
{
|
||||
assert(state);
|
||||
if (!state) return nullptr;
|
||||
|
||||
return static_cast<km_core_context *>(&state->context());
|
||||
return static_cast<km_core_context *>(&(const_cast<km_core_state *>(state)->context()));
|
||||
}
|
||||
|
||||
km_core_context *km_core_state_app_context(km_core_state *state)
|
||||
km_core_context *km_core_state_app_context(km_core_state const *state)
|
||||
{
|
||||
assert(state);
|
||||
if (!state) return nullptr;
|
||||
|
||||
return static_cast<km_core_context *>(&state->app_context());
|
||||
return static_cast<km_core_context *>(&(const_cast<km_core_state *>(state)->app_context()));
|
||||
}
|
||||
|
||||
km_core_status km_core_state_get_intermediate_context(
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ endif
|
|||
|
||||
|
||||
kmx_files = files(
|
||||
'actions_normalize.cpp',
|
||||
'action.cpp',
|
||||
'option.cpp',
|
||||
'keyboard.cpp',
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ tests = [
|
|||
['debug-api', 'debug_api.cpp'],
|
||||
['kmx_xstring', 'test_kmx_xstring.cpp'],
|
||||
['kmx_context', 'test_kmx_context.cpp'],
|
||||
['test_actions_normalize', 'test_actions_normalize.cpp'],
|
||||
]
|
||||
|
||||
test_path = join_paths(meson.current_build_dir(), '..', 'kmx')
|
||||
|
|
|
|||
112
core/tests/unit/kmnkbd/test_actions_normalize.cpp
Normal file
112
core/tests/unit/kmnkbd/test_actions_normalize.cpp
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
Copyright: © 2018 SIL International.
|
||||
Description: Tests for the context API family of functions.
|
||||
Create Date: 23 Oct 2023
|
||||
Authors: Marc Durdin
|
||||
History: 23 Oct 2023 - MCD - Initial implementation.
|
||||
*/
|
||||
#include <string>
|
||||
#include "keyman_core.h"
|
||||
|
||||
#include "path.hpp"
|
||||
#include "action.hpp"
|
||||
|
||||
#include <test_assert.h>
|
||||
#include "../emscripten_filesystem.h"
|
||||
|
||||
km_core_option_item test_env_opts[] =
|
||||
{
|
||||
KM_CORE_OPTIONS_END
|
||||
};
|
||||
|
||||
km_core_keyboard * test_kb = nullptr;
|
||||
km_core_state * test_state = nullptr;
|
||||
km_core_actions * test_actions = nullptr;
|
||||
std::string arg_path;
|
||||
|
||||
void teardown() {
|
||||
if(test_state) {
|
||||
km_core_state_dispose(test_state);
|
||||
test_state = nullptr;
|
||||
}
|
||||
if(test_kb) {
|
||||
km_core_keyboard_dispose(test_kb);
|
||||
test_kb = nullptr;
|
||||
}
|
||||
if(test_actions) {
|
||||
delete [] test_actions->output;
|
||||
delete test_actions;
|
||||
test_actions = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void setup(const km_core_cp *context, int actions_code_points_to_delete, const std::u32string actions_output) {
|
||||
teardown();
|
||||
|
||||
km::core::path path = km::core::path::join(arg_path, "..", "ldml", "keyboards", "k_001_tiny.kmx");
|
||||
try_status(km_core_keyboard_load(path.native().c_str(), &test_kb));
|
||||
try_status(km_core_state_create(test_kb, test_env_opts, &test_state));
|
||||
|
||||
assert(km_core_state_context_set_if_needed(test_state, context) == KM_CORE_CONTEXT_STATUS_UPDATED);
|
||||
|
||||
test_actions = new km_core_actions;
|
||||
test_actions->code_points_to_delete = actions_code_points_to_delete;
|
||||
test_actions->output = new km_core_usv[actions_output.length() + 1];
|
||||
actions_output.copy(test_actions->output, actions_output.length());
|
||||
test_actions->output[actions_output.length()] = 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
|
||||
void test_no_normalization() {
|
||||
setup(u"abc", 0, U"def");
|
||||
const int expected_delete = 0;
|
||||
const std::u32string expected_output = U"def";
|
||||
|
||||
assert(km::core::actions_normalize(km_core_state_context(test_state), km_core_state_app_context(test_state), test_actions));
|
||||
|
||||
assert(expected_delete == test_actions->code_points_to_delete);
|
||||
assert(expected_output == test_actions->output);
|
||||
|
||||
teardown();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
// Launcher
|
||||
//-------------------------------------------------------------------------------------
|
||||
|
||||
constexpr const auto help_str = "\
|
||||
test_actions_normalize [--color] <BUILD_PATH>\n\
|
||||
\n\
|
||||
--color Force color output\n\
|
||||
BUILD_PATH Path where test_actions_normalize.exe is found; kmx files are\n\
|
||||
located relative to this path.\n";
|
||||
|
||||
int error_args() {
|
||||
std::cerr << "test_actions_normalize: Invalid arguments." << std::endl;
|
||||
std::cout << help_str;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv []) {
|
||||
|
||||
if(argc < 2) {
|
||||
return error_args();
|
||||
}
|
||||
|
||||
auto arg_color = std::string(argv[1]) == "--color";
|
||||
if(arg_color && argc < 3) {
|
||||
return error_args();
|
||||
}
|
||||
console_color::enabled = console_color::isaterminal() || arg_color;
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
arg_path = get_wasm_file_path(argv[arg_color ? 2 : 1]);
|
||||
#else
|
||||
arg_path = argv[arg_color ? 2 : 1];
|
||||
#endif
|
||||
|
||||
// actions
|
||||
test_no_normalization();
|
||||
}
|
||||
|
||||
Loading…
Add table
Reference in a new issue