diff --git a/.github/workflows/deb-packaging.yml b/.github/workflows/deb-packaging.yml index 9c374f5d050..52c485aa658 100644 --- a/.github/workflows/deb-packaging.yml +++ b/.github/workflows/deb-packaging.yml @@ -116,7 +116,7 @@ jobs: strategy: fail-fast: true matrix: - dist: [focal, jammy, noble] + dist: [focal, jammy, noble, oracular] steps: - name: Checkout @@ -142,7 +142,7 @@ jobs: strategy: fail-fast: true matrix: - dist: [oracular] + dist: [plucky] steps: - name: Checkout diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4ebf41b87d1..6216a806143 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,5 +1,7 @@ # Contributing to Keyman +(Keyman team members, see also the [onboarding](https://docs.google.com/document/d/1i6fBi9K38-LitcJZiRfAvRu1-7H0iQ_op5kxDMdhSec/edit?usp=sharing) doc) + ⭐ Thank you for your contribution! ⭐ The following is a set of guidelines for contributing to Keyman, Keyman diff --git a/HISTORY.md b/HISTORY.md index 8c03d3470cd..b831dadee8a 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,97 @@ # Keyman Version History +## 18.0.152 alpha 2024-12-04 + +* refactor(mac): pass kmx data blob to keyman core instead of file path (#12760) +* fix(developer): honour provided script when checking for matching scripts (#12768) +* chore(common): rename test files (#12709) +* fix(common): rename test file (#12770) + +## 18.0.151 alpha 2024-12-03 + +* feat(android): Enhance how ENTER key is handled for FV and KMSample2 (#12745) +* feat(developer): report on mismatching lang tag scripts when building keyboard-info (#12753) + +## 18.0.150 alpha 2024-12-02 + +* fix(core,developer): use `NDEBUG` flag to disable assertions in release build (#12715) + +## 18.0.149 alpha 2024-12-01 + +* refactor(developer): unify test action (#12736) + +## 18.0.148 alpha 2024-11-29 + +* test(common/web/types): unit tests for unicodeset-parser-api (#12714) +* chore(developer): rename test files (#12707) +* feat(core,linux,developer,windows): implement loading KMX from blob (#12721) +* chore(common): add offline support for emscripten (#12740) + +## 18.0.147 alpha 2024-11-28 + +* docs(android): Add android/docs/internal/README (#12717) +* test(common/web/types): unit tests for string-list (#12702) +* docs(common): linux and macOS emscripten setup (#12701) +* refactor(developer): output number of tests when running on TC (#12710) +* refactor(common): output number of tests when running on TC (#12719) +* chore(web): rename file missed in #12704 (#12720) +* fix(core): permanently disable logging (#12724) +* fix(linux): disable assertions in release builds of ibus-keyman (#12725) +* chore(common): improve offline builds (#12739) + +## 18.0.146 alpha 2024-11-27 + +* test(developer): kmcmplib compiler unit tests 5 (#12612) +* refactor(common): move all lexical model types into `LexicalModelTypes` container (#12712) +* refactor(common): move remaining LDML keyboard types into `LdmlKeyboardTypes` (#12713) +* chore(web): rename test files and folders (#12704) +* chore(core): rename test files (#12705) +* chore(linux): rename test files (#12706) + +## 18.0.145 alpha 2024-11-26 + +* docs(windows): update emscripten bash setup (#12700) +* chore(common): Add link to onboarding doc to `CONTRIBUTING.md` (#12697) + +## 18.0.144 alpha 2024-11-25 + +* chore(deps): bump cross-spawn from 7.0.3 to 7.0.6 in /developer/src/server/src/win32/trayicon/addon-src (#12687) +* chore(developer): make package subfile description fully optional (#12665) +* fix(developer): box package compiler info fields (#12666) +* fix(developer): correct whitespace handling in virtual keys and remove partially implemented virtual key series in kmcmplib compiler (#12604) + +## 18.0.143 alpha 2024-11-22 + +* chore(deps): bump cross-spawn from 7.0.3 to 7.0.6 (#12685) + +## 18.0.142 alpha 2024-11-20 + +* chore(common): Update CODEOWNERS (#12680) + +## 18.0.141 alpha 2024-11-15 + +* chore(linux): add support for Ubuntu 25.04 Plucky Puffin (#12675) + +## 18.0.140 alpha 2024-11-13 + +* chore(common): Add 17.0.330 - 17.0.332 to version history (#12663) +* fix(developer): reconnect `--full-test` in kmcmplib build and enable for CI (#12631) +* docs(developer): kmc-generate (#12647) + +## 18.0.139 alpha 2024-11-12 + +* fix(windows): help links updated (#12646) + +## 18.0.138 alpha 2024-11-08 + +* fix(common): check for invalid markers (#12613) +* chore: update minimum versions (#12632) +* fix(windows): correct path to output file in publish step for fv keyboards (#12637) +* chore(core): move API docs from help.keyman.com (#12642) +* feat(developer): kmc generate (#11014) +* feat(developer): kmc-copy (#12555) +* feat(developer): add GitHub and Cloud support to kmc-copy (#12586) + ## 18.0.137 alpha 2024-11-07 * fix(windows): correct engine help source path for upload (#12625) @@ -948,6 +1040,27 @@ * chore(common): move to 18.0 alpha (#10713) * chore: move to 18.0 alpha +## 17.0.332 stable 2024-11-06 + +* fix(developer): create Server config directory before options save (#12609) +* fix(developer): handle merge commits when checking git log date (#12628) +* fix(linux): set environment variable for rendering of downloads dialog (#12617) + +## 17.0.331 stable 2024-10-30 + +* fix(android): Hide suggestion banner on password fields (#12466) +* fix(common): declare dep on @keymanapp/ldml-keyboard-constants (#12475) +* fix(oem/fv): Update keyboard versions and names for fv_all.kmp (#12504) +* chore(ios): renew certificate (#12513) +* fix(developer): prevent invalid string ids (#12524) +* fix(developer): ignore excess whitespace in `` attribute (#12523) + +## 17.0.330 stable 2024-09-16 + +* refactor(android): Move Sentry and APK to publish task (#12392) +* fix(developer): rewrite ldml visual keyboard compiler (#12406) +* fix(developer): check vars string usage before definition (#12407) + ## 17.0.329 stable 2024-09-09 * chore(android,ios): Add ojibwa ifinal/rdot keyboards to FirstVoices (#12020) diff --git a/VERSION.md b/VERSION.md index 2ef34fe0072..6269a6496fb 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -18.0.138 \ No newline at end of file +18.0.153 \ No newline at end of file diff --git a/android/README.md b/android/README.md index 8b32b99f543..6abb94161d5 100644 --- a/android/README.md +++ b/android/README.md @@ -34,7 +34,7 @@ analytics for Debug are associated with an App Bundle ID ### Compiling From Command Line 1. Launch a command prompt and cd to the directory **keyman/android** -2. Run the top level build script `./build.sh configure build --debug` which will: +2. Run the top level build script `./build.sh configure build:engine build:app --debug` which will: * Compile KMEA (and its KMW dependency) * Download default keyboard and dictionary resources as needed * Compile KMAPro @@ -79,7 +79,7 @@ analytics for Debug are associated with an App Bundle ID Replace `SERIAL` with the device serial number listed in step 2. ### Compiling the app's offline help -Keyman for Android help is maintained in the Markdown files in android/docs/. +Keyman for Android help is maintained in the Markdown files in android/docs/help. The script `/resources/build/build-help.inc.sh` uses the `pandoc` tool to convert the Markdown files into html. ```bash @@ -121,7 +121,7 @@ Building these projects follow the same steps as KMAPro: ## How to Build Keyman Engine for Android 1. Open a terminal or Git Bash prompt and go to the Android project folder (e.g. `cd ~/keyman/android/`) -2. Run `./build.sh --debug` +2. Run `./build.sh build:engine --debug` Keyman Engine for Android library (**keyman-engine.aar**) is now ready to be imported in any project. @@ -167,3 +167,10 @@ dependencies { ```` 5. include `import com.keyman.engine.*;` to use Keyman Engine in a class. + +### Keyman Engine for Android help content +Keyman Engine for Android help is maintained in the Markdown files in android/docs/engine/. + +## Design Documentation + +Internal design documents about features pertaining to Keyman for Android and Keyman Engine for Android are maintained in the Markdown files in android/docs/internal/. diff --git a/android/Samples/KMSample2/app/src/main/java/com/keyman/kmsample2/SystemKeyboard.java b/android/Samples/KMSample2/app/src/main/java/com/keyman/kmsample2/SystemKeyboard.java index 4ad462a76c1..438ed237dbc 100644 --- a/android/Samples/KMSample2/app/src/main/java/com/keyman/kmsample2/SystemKeyboard.java +++ b/android/Samples/KMSample2/app/src/main/java/com/keyman/kmsample2/SystemKeyboard.java @@ -130,6 +130,11 @@ public void onStartInput(EditorInfo attribute, boolean restarting) { super.onStartInput(attribute, restarting); KMManager.onStartInput(attribute, restarting); KMManager.resetContext(KeyboardType.KEYBOARD_TYPE_SYSTEM); + + // Determine special handling for ENTER key + int inputType = attribute.inputType; + KMManager.setEnterMode(attribute.imeOptions, inputType); + // User switched to a new input field so we should extract the text from input field // and pass it to Keyman Engine together with selection range InputConnection ic = getCurrentInputConnection(); diff --git a/android/docs/internal/README.md b/android/docs/internal/README.md new file mode 100644 index 00000000000..ef51df7f60f --- /dev/null +++ b/android/docs/internal/README.md @@ -0,0 +1,5 @@ +# Keyman for Android and Keyman Engine for Android + +## Internal Documents + +This folder is for storing design documents of new features pertaining to Keyman for Android and Keyman Engine for Android diff --git a/common/include/test_assert.h b/common/include/test_assert.h index 75c586bcc67..9669c16a022 100644 --- a/common/include/test_assert.h +++ b/common/include/test_assert.h @@ -12,10 +12,10 @@ #include #include "test_color.h" -#ifdef _assert_failed -#undef _assert_failed +#ifdef _test_assert_failed +#undef _test_assert_failed #endif -#define _assert_failed(result, exprText) { \ +#define _test_assert_failed(result, exprText) { \ std::wcerr << console_color::fg(console_color::BRIGHT_RED) \ << "Test failed with " << (result) \ << " at " << __FILE__ << ":" << __LINE__ << ":" \ @@ -31,23 +31,23 @@ #define try_status(expr) { \ auto __s = (expr); \ if (__s != KM_CORE_STATUS_OK) { \ - _assert_failed(__s, u ## #expr); \ + _test_assert_failed(__s, u ## #expr); \ } \ } -#ifdef assert -#undef assert +#ifdef test_assert +#undef test_assert #endif -#define assert(expr) { \ +#define test_assert(expr) { \ if (!(expr)) { \ - _assert_failed(0, u ## #expr); \ + _test_assert_failed(0, u ## #expr); \ } \ } -#ifdef assert_equal -#undef assert_equal +#ifdef test_assert_equal +#undef test_assert_equal #endif -#define assert_equal(actual, expected) { \ +#define test_assert_equal(actual, expected) { \ if ((actual) != (expected)) { \ std::wcerr << console_color::fg(console_color::BRIGHT_RED) \ << "Test failed at " << __FILE__ << ":" << __LINE__ << ":" \ @@ -59,10 +59,10 @@ } \ } -#ifdef assert_string_equal -#undef assert_string_equal +#ifdef test_assert_string_equal +#undef test_assert_string_equal #endif -#define assert_string_equal(actual, expected) { \ +#define test_assert_string_equal(actual, expected) { \ if (u16cmp((actual), (expected)) != 0) { \ std::wcerr << console_color::fg(console_color::BRIGHT_RED) \ << "Test failed at " << __FILE__ << ":" << __LINE__ << ":" \ diff --git a/common/include/test_color.h b/common/include/test_color.h index f06f94c562f..71267dc3a94 100644 --- a/common/include/test_color.h +++ b/common/include/test_color.h @@ -8,6 +8,12 @@ #include +#ifdef _MSC_VER +#include +#else +#include +#endif + namespace console_color { enum ansi_code { @@ -65,12 +71,10 @@ __define_ansi_code__(reversed, "7"); #undef __define_ansi_code__ #ifdef _MSC_VER -#include inline bool isaterminal() { return _isatty(_fileno(stdout)); } #else -#include inline bool isaterminal() { return isatty(STDOUT_FILENO); } diff --git a/common/web/types/.eslintrc.cjs b/common/web/types/.eslintrc.cjs index b28ba0941b1..4fd5954e495 100644 --- a/common/web/types/.eslintrc.cjs +++ b/common/web/types/.eslintrc.cjs @@ -1,13 +1,13 @@ module.exports = { parserOptions: { - project: ["./tsconfig.json", "./test/tsconfig.json"], + project: ["./tsconfig.json", "./tests/tsconfig.json"], }, ignorePatterns: [ ".*/*", "build/*", "coverage/*", "node_modules/*", - "test/fixtures/*", + "tests/fixtures/*", "tools/*", "src/schemas/*" ], diff --git a/common/web/types/.gitignore b/common/web/types/.gitignore index 2f943a2f4e9..dcb567b832b 100644 --- a/common/web/types/.gitignore +++ b/common/web/types/.gitignore @@ -1,2 +1,3 @@ src/schemas/ -obj/ \ No newline at end of file +obj/ +coverage/ diff --git a/common/web/types/build.sh b/common/web/types/build.sh index 7dac43dba81..418840d1a85 100755 --- a/common/web/types/build.sh +++ b/common/web/types/build.sh @@ -80,20 +80,27 @@ function do_configure() { } function do_test() { + local MOCHA_FLAGS= + + if [[ "${TEAMCITY_GIT_PATH:-}" != "" ]]; then + # we're running in TeamCity + MOCHA_FLAGS="-reporter mocha-teamcity-reporter" + fi + eslint . - tsc --build test + tsc --build tests readonly C8_THRESHOLD=60 # Excludes are defined in .c8rc.json - c8 -skip-full --reporter=lcov --reporter=text --lines $C8_THRESHOLD --statements $C8_THRESHOLD --branches $C8_THRESHOLD --functions $C8_THRESHOLD mocha "${builder_extra_params[@]}" + c8 -skip-full --reporter=lcov --reporter=text --lines $C8_THRESHOLD --statements $C8_THRESHOLD --branches $C8_THRESHOLD --functions $C8_THRESHOLD mocha ${MOCHA_FLAGS} "${builder_extra_params[@]}" builder_echo warning "Coverage thresholds are currently $C8_THRESHOLD%, which is lower than ideal." builder_echo warning "Please increase threshold in build.sh as test coverage improves." } #------------------------------------------------------------------------------------------------------------------- -builder_run_action clean rm -rf ./build/ ./tsconfig.tsbuildinfo +builder_run_action clean rm -rf ./build/ ./tsconfig.tsbuildinfo ./src/schemas/ ./node_modules/ ./obj/ builder_run_action configure do_configure builder_run_action build tsc --build builder_run_action test do_test diff --git a/common/web/types/package.json b/common/web/types/package.json index e9f7c412947..d6efc635039 100644 --- a/common/web/types/package.json +++ b/common/web/types/package.json @@ -23,7 +23,7 @@ "build": "tsc -b", "build:schema": "ajv compile", "lint": "eslint .", - "test": "npm run lint && cd test && tsc -b && cd .. && c8 --skip-full --reporter=lcov --reporter=text mocha" + "test": "npm run lint && cd tests && tsc -b && cd .. && c8 --skip-full --reporter=lcov --reporter=text mocha" }, "author": "Marc Durdin (https://github.com/mcdurdin)", "license": "MIT", @@ -48,7 +48,7 @@ "typescript": "^5.4.5" }, "mocha": { - "spec": "build/test/**/test-*.js", + "spec": "build/tests/**/*.tests.js", "require": [ "source-map-support/register" ] @@ -76,7 +76,7 @@ "src/keyman-touch-layout/keyman-touch-layout-file-writer.ts", "src/osk/osk.ts", "src/schemas/*", - "test/" + "tests/" ] }, "sideEffects": false diff --git a/common/web/types/src/kmx/kmx-plus/kmx-plus.ts b/common/web/types/src/kmx/kmx-plus/kmx-plus.ts index 0cb49e527c7..a88688f7ab7 100644 --- a/common/web/types/src/kmx/kmx-plus/kmx-plus.ts +++ b/common/web/types/src/kmx/kmx-plus/kmx-plus.ts @@ -174,12 +174,7 @@ export class Strs extends Section { */ allocString(s?: string, opts?: StrsOptions, sections?: DependencySections): StrsItem { // Run the string processing pipeline - s = Strs.processString(s, opts, sections); - - // add to the set, for testing - if (s) { - this.allProcessedStrings.add(s); - } + s = this.processString(s, opts, sections); // if it's a single char, don't push it into the strs table if (opts?.singleOk && isOneChar(s)) { @@ -196,8 +191,8 @@ export class Strs extends Section { return result; } - /** process everything according to opts */ - static processString(s: string, opts: StrsOptions, sections: DependencySections) { + /** process everything according to opts, and add the string to this.allProcessedStrings */ + private processString(s: string, opts: StrsOptions, sections: DependencySections) { s = s ?? ''; // type check everything else if (typeof s !== 'string') { @@ -215,6 +210,12 @@ export class Strs extends Section { if (opts?.unescape) { s = unescapeString(s); } + + if (s) { + // add all processed strings here, so that we catch denormalized strings in the input + this.allProcessedStrings.add(s); + } + // nfd if (opts?.nfd) { if (!sections?.meta?.normalizationDisabled) { diff --git a/common/web/types/src/main-ldml-keyboard.ts b/common/web/types/src/main-ldml-keyboard.ts new file mode 100644 index 00000000000..02bf990af26 --- /dev/null +++ b/common/web/types/src/main-ldml-keyboard.ts @@ -0,0 +1,8 @@ +/* + * Keyman is copyright (C) SIL Global. MIT License. + * + * Just a wrapper to make `LdmlKeyboardTypes` export work. + */ +export { UnicodeSetParser, UnicodeSet } from './ldml-keyboard/unicodeset-parser-api.js'; +export { VariableParser, MarkerParser } from './ldml-keyboard/pattern-parser.js'; +export { ElementString } from './kmx/kmx-plus/element-string.js'; diff --git a/common/web/types/src/main.ts b/common/web/types/src/main.ts index c3b24c5123d..071c931e9e9 100644 --- a/common/web/types/src/main.ts +++ b/common/web/types/src/main.ts @@ -25,11 +25,8 @@ export * as Schemas from './schemas.js'; export * as SchemaValidators from './schema-validators.js'; export * as KMXPlus from './kmx/kmx-plus/kmx-plus.js'; -// TODO: these exports are really not well named -export { UnicodeSetParser, UnicodeSet } from './ldml-keyboard/unicodeset-parser-api.js'; -export { VariableParser, MarkerParser } from './ldml-keyboard/pattern-parser.js'; -export { ElementString } from './kmx/kmx-plus/element-string.js'; +export * as LdmlKeyboardTypes from './main-ldml-keyboard.js'; -export { USVString, CasingForm, CasingFunction, TextWithProbability, LexiconTraversal, LexicalModel, LexicalModelPunctuation, Transform, Suggestion, Reversion, Keep, SuggestionTag, Context, Distribution, Outcome, WithOutcome, ProbabilityMass, Configuration, Capabilities, WordBreakingFunction, Span } from './lexical-model-types.js'; +export * as LexicalModelTypes from './lexical-model-types.js'; export * as KeymanWebKeyboard from './keyboard-object.js'; diff --git a/common/web/types/src/package/kmp-json-file.ts b/common/web/types/src/package/kmp-json-file.ts index ae88b5ba3e9..4a1c1c159e4 100644 --- a/common/web/types/src/package/kmp-json-file.ts +++ b/common/web/types/src/package/kmp-json-file.ts @@ -44,7 +44,7 @@ export interface KmpJsonFileInfoItem { export interface KmpJsonFileContentFile { name: string; - description: string; + description?: string; copyLocation?: number; } diff --git a/common/web/types/src/util/util.ts b/common/web/types/src/util/util.ts index 0d13505cfc9..70e1077cc5a 100644 --- a/common/web/types/src/util/util.ts +++ b/common/web/types/src/util/util.ts @@ -305,6 +305,15 @@ export function isPUA(ch: number) { (ch >= Uni_PUA_16_START && ch <= Uni_PUA_16_END)); } +/** @returns false if s is NEITHER NFC nor NFD. (Returns true for falsy) */ +export function isNormalized(s: string) : boolean { + if(!s) return true; // empty or null + const nfc = s.normalize("NFC"); + const nfd = s.normalize("NFD"); + if (s !== nfc && s !== nfd) return false; + return true; +} + class BadStringMap extends Map> { public toString() : string { if (!this.size) { diff --git a/common/web/types/test/lexical-model-types.tests.ts b/common/web/types/test/lexical-model-types.tests.ts deleted file mode 100644 index 8944342ed6e..00000000000 --- a/common/web/types/test/lexical-model-types.tests.ts +++ /dev/null @@ -1,25 +0,0 @@ -/** - * This file "tests" the exports from the main module. - * - * Since the exports are all types, the "test" here is that the type can be - * imported and compiled without any compiler errors. - */ - -import { USVString, Transform, Suggestion, SuggestionTag, Context, Capabilities, Configuration, Distribution, WordBreakingFunction, Span, LexicalModelPunctuation, ElementString, KMXPlus } from '@keymanapp/common-types'; - -export let u: USVString; -export let l: Transform -export let s: Suggestion; -export let st: SuggestionTag; -export let c: Context; -export let cap: Capabilities; -export let conf: Configuration; -export let d: Distribution; -export let wbf: WordBreakingFunction; -export let sp: Span; -export let lmp: LexicalModelPunctuation; - - -// try some of the other types - that should still work -export let elemString: ElementString; -export let section: KMXPlus.Section; diff --git a/common/web/types/test/fixtures/kmx/khmer_angkor.kmx b/common/web/types/tests/fixtures/kmx/khmer_angkor.kmx similarity index 100% rename from common/web/types/test/fixtures/kmx/khmer_angkor.kmx rename to common/web/types/tests/fixtures/kmx/khmer_angkor.kmx diff --git a/common/web/types/test/fixtures/kvk/balochi_inpage.kvk b/common/web/types/tests/fixtures/kvk/balochi_inpage.kvk similarity index 100% rename from common/web/types/test/fixtures/kvk/balochi_inpage.kvk rename to common/web/types/tests/fixtures/kvk/balochi_inpage.kvk diff --git a/common/web/types/test/fixtures/kvk/khmer_angkor.kvk b/common/web/types/tests/fixtures/kvk/khmer_angkor.kvk similarity index 100% rename from common/web/types/test/fixtures/kvk/khmer_angkor.kvk rename to common/web/types/tests/fixtures/kvk/khmer_angkor.kvk diff --git a/common/web/types/test/helpers/index.ts b/common/web/types/tests/helpers/index.ts similarity index 87% rename from common/web/types/test/helpers/index.ts rename to common/web/types/tests/helpers/index.ts index 3e305eeca8a..717b2e75191 100644 --- a/common/web/types/test/helpers/index.ts +++ b/common/web/types/tests/helpers/index.ts @@ -9,5 +9,5 @@ import { fileURLToPath } from "url"; * @param components One or more path components. */ export function makePathToFixture(...components: string[]): string { - return fileURLToPath(new URL(path.join('..', '..', '..', 'test', 'fixtures', ...components), import.meta.url)); + return fileURLToPath(new URL(path.join('..', '..', '..', 'tests', 'fixtures', ...components), import.meta.url)); } diff --git a/common/web/types/test/kmx/test-keyman-targets.ts b/common/web/types/tests/kmx/keyman-targets.tests.ts similarity index 100% rename from common/web/types/test/kmx/test-keyman-targets.ts rename to common/web/types/tests/kmx/keyman-targets.tests.ts diff --git a/common/web/types/test/kmx/test-kmx-file.ts b/common/web/types/tests/kmx/kmx-file.tests.ts similarity index 100% rename from common/web/types/test/kmx/test-kmx-file.ts rename to common/web/types/tests/kmx/kmx-file.tests.ts diff --git a/common/web/types/test/kvk/test-kvk-file.ts b/common/web/types/tests/kvk/kvk-file.tests.ts similarity index 90% rename from common/web/types/test/kvk/test-kvk-file.ts rename to common/web/types/tests/kvk/kvk-file.tests.ts index 8a1179b67b2..8e0387fefe3 100644 --- a/common/web/types/test/kvk/test-kvk-file.ts +++ b/common/web/types/tests/kvk/kvk-file.tests.ts @@ -2,7 +2,7 @@ import * as fs from 'fs'; import 'mocha'; import { makePathToFixture } from '../helpers/index.js'; import KvkFileReader from "../../src/kvk/kvk-file-reader.js"; -import { verify_balochi_inpage, verify_khmer_angkor } from './test-kvk-utils.js'; +import { verify_balochi_inpage, verify_khmer_angkor } from './kvk-utils.tests.js'; describe('kvk-file-reader', function () { it('kvk-file-reader should read a valid file', function() { diff --git a/common/web/types/test/kvk/test-kvk-utils.ts b/common/web/types/tests/kvk/kvk-utils.tests.ts similarity index 100% rename from common/web/types/test/kvk/test-kvk-utils.ts rename to common/web/types/tests/kvk/kvk-utils.tests.ts diff --git a/common/web/types/test/ldml-keyboard/test-pattern-parser.ts b/common/web/types/tests/ldml-keyboard/pattern-parser.tests.ts similarity index 100% rename from common/web/types/test/ldml-keyboard/test-pattern-parser.ts rename to common/web/types/tests/ldml-keyboard/pattern-parser.tests.ts diff --git a/common/web/types/tests/ldml-keyboard/string-list.tests.ts b/common/web/types/tests/ldml-keyboard/string-list.tests.ts new file mode 100644 index 00000000000..58365bda66b --- /dev/null +++ b/common/web/types/tests/ldml-keyboard/string-list.tests.ts @@ -0,0 +1,216 @@ +/* + * Keyman is copyright (C) SIL Global. MIT License. + * + * Created by Dr Mark C. Sinclair on 2024-11-28 + * + * Test code for string-lists.ts + */ + +import 'mocha'; +import { assert } from 'chai'; +import { StrsItem, StrsOptions, DependencySections, Strs } from '../../src/kmx/kmx-plus/kmx-plus.js'; +import { ListIndex, ListItem } from '../../src/ldml-keyboard/string-list.js'; + +describe('Test of String-List', () => { + describe('Test ListIndex', () => { + it('can construct a ListIndex', () => { + const strsItem = new StrsItem("abc"); + const actual = new ListIndex(strsItem); + assert.deepEqual(actual.value, strsItem); + }); + it('can check two ListIndex for equality', () => { + const listItemOne = new ListIndex(new StrsItem("abc")); + const listItemTwo = new ListIndex(new StrsItem("abc")); + assert.isTrue(listItemOne.isEqual(listItemTwo)); + }); + it('can check two different ListIndex are not equal', () => { + const listItemOne = new ListIndex(new StrsItem("abc")); + const listItemTwo = new ListIndex(new StrsItem("def")); + assert.isFalse(listItemOne.isEqual(listItemTwo)); + }); + it('can check a ListIndex and string for equality', () => { + const listItem = new ListIndex(new StrsItem("abc")); + const aString = "abc"; + assert.isTrue(listItem.isEqual(aString)); + }); + it('can check a ListIndex and string for inequality', () => { + const listItem = new ListIndex(new StrsItem("abc")); + const aString = "def"; + assert.isFalse(listItem.isEqual(aString)); + }); + it('can provide a correct string representation', () => { + const strsItem = new StrsItem("abc"); + const listItem = new ListIndex(strsItem); + const expected = "abc"; + assert.deepEqual(listItem.toString(), expected); + }); + }); + describe('Test ListItem', () => { + describe('Test fromStrings()', () => { + it('should return an empty ListItem if source is null', () => { + const actual = ListItem.fromStrings(null, null, null); + const expected = new ListItem(); + assert.deepEqual(actual, expected); + }); + it('should return a valid ListItem from a single source string', () => { + const source = ["abc"]; + const sections = { strs: new Strs }; + sections.strs.allocString = stubSectionsStrsAllocString; + const actual = ListItem.fromStrings(source, null, sections); + const expected = initListItem(source); + assert.deepEqual(actual, expected); + }); + it('should return a valid ListItem from a longer source', () => { + const source = ["abc", "def", "ghi"]; + const sections = { strs: new Strs }; + sections.strs.allocString = stubSectionsStrsAllocString; + const actual = ListItem.fromStrings(source, null, sections); + const expected = initListItem(source); + assert.deepEqual(actual, expected); + }); + }); + describe('Test getItemOrder()', () => { + it('should return a valid index for the first item', () => { + const listItem = initListItem(["abc", "def", "ghi"]); + const index = listItem.getItemOrder("abc"); + assert.equal(index, 0); + }); + it('should return a valid index for a later item', () => { + const listItem = initListItem(["abc", "def", "ghi"]); + const index = listItem.getItemOrder("ghi"); + assert.equal(index, 2); + }); + it('should return -1 for a missing item', () => { + const listItem = initListItem(["abc", "def", "ghi"]); + const index = listItem.getItemOrder("jkl"); + assert.equal(index, -1); + }); + }); + describe('Test isEqual()', () => { + it('should return true for two empty ListItems', () => { + const listItemOne = new ListItem(); + const listItemTwo = new ListItem(); + assert.isTrue(listItemOne.isEqual(listItemTwo)); + }); + it('should return false for empty and non-empty ListItems', () => { + const listItemOne = new ListItem(); + const listItemTwo = initListItem(["abc"]); + assert.isFalse(listItemOne.isEqual(listItemTwo)); + }); + it('should return false for non-empty and empty ListItems', () => { + const listItemOne = initListItem(["abc"]); + const listItemTwo = new ListItem(); + assert.isFalse(listItemOne.isEqual(listItemTwo)); + }); + it('should return true for identical ListItems', () => { + const listItemOne = initListItem(["abc", "def", "ghi"]); + const listItemTwo = initListItem(["abc", "def", "ghi"]); + assert.isTrue(listItemOne.isEqual(listItemTwo)); + }); + it('should return false for different ListItems', () => { + const listItemOne = initListItem(["abc", "def", "ghi"]); + const listItemTwo = initListItem(["abd", "def", "ghi"]); + assert.isFalse(listItemOne.isEqual(listItemTwo)); + }); + it('should return false for different length ListItems', () => { + const listItemOne = initListItem(["abc", "def"]); + const listItemTwo = initListItem(["abc", "def", "ghi"]); + assert.isFalse(listItemOne.isEqual(listItemTwo)); + }); + it('should return true for empty ListItem and string[]', () => { + const listItem = new ListItem(); + assert.isTrue(listItem.isEqual([])); + }); + it('should return false for empty ListItem and non-empty string[]', () => { + const listItem = new ListItem(); + assert.isFalse(listItem.isEqual(["abc"])); + }); + it('should return false for non-empty ListItem and empty string[]', () => { + const listItem = initListItem(["abc"]);; + assert.isFalse(listItem.isEqual([])); + }); + it('should return true for identical ListItem and string[]', () => { + const listItem = initListItem(["abc", "def", "ghi"]); + assert.isTrue(listItem.isEqual(["abc", "def", "ghi"])); + }); + it('should return false for different ListItem and string[]', () => { + const listItem = initListItem(["abc", "def", "ghi"]); + assert.isFalse(listItem.isEqual(["abd", "def", "ghi"])); + }); + it('should return false for different length ListItem and string[]', () => { + const listItem = initListItem(["abc", "def"]); + assert.isFalse(listItem.isEqual(["abc", "def", "ghi"])); + }); + }); + describe('Test compareTo()', () => { + it('should return 0 for identical ListItems', () => { + const listItemOne = initListItem(["abc", "def", "ghi"]); + const listItemTwo = initListItem(["abc", "def", "ghi"]); + assert.equal(listItemOne.compareTo(listItemTwo), 0); + }); + it('should return -1 for ListItems with different first items (smallest first)', () => { + const listItemOne = initListItem(["abc", "def", "ghi"]); + const listItemTwo = initListItem(["abd", "def", "ghi"]); + assert.equal(listItemOne.compareTo(listItemTwo), -1); + }); + it('should return 1 for ListItems with different first items (smallest second)', () => { + const listItemOne = initListItem(["abd", "def", "ghi"]); + const listItemTwo = initListItem(["abc", "def", "ghi"]); + assert.equal(listItemOne.compareTo(listItemTwo), 1); + }); + it('should return -1 for ListItems with different later items (smallest first)', () => { + const listItemOne = initListItem(["abc", "def", "ghi"]); + const listItemTwo = initListItem(["abc", "def", "ghj"]); + assert.equal(listItemOne.compareTo(listItemTwo), -1); + }); + it('should return 1 for ListItems with different later items (smallest second)', () => { + const listItemOne = initListItem(["abc", "def", "ghj"]); + const listItemTwo = initListItem(["abc", "def", "ghi"]); + assert.equal(listItemOne.compareTo(listItemTwo), 1); + }); + it('should return -1 for identical ListItems, except shorter first', () => { + const listItemOne = initListItem(["abc", "def", "ghi"]); + const listItemTwo = initListItem(["abc", "def", "ghi", "jkl"]); + assert.equal(listItemOne.compareTo(listItemTwo), -1); + }); + it('should return 1 for identical ListItems, except longer first', () => { + const listItemOne = initListItem(["abc", "def", "ghi", "jkl"]); + const listItemTwo = initListItem(["abc", "def", "ghi"]); + assert.equal(listItemOne.compareTo(listItemTwo), 1); + }); + }); + describe('Test toString()', () => { + it('should return correct string', () => { + const listItem = initListItem(["abc", "def", "ghi"]); + assert.deepEqual(listItem.toString(), "abc def ghi"); + }); + it('should return correct string for empty ListItem', () => { + const listItem = new ListItem; + assert.deepEqual(listItem.toString(), ""); + }); + }); + describe('Test toStringArray()', () => { + it('should return correct string[]', () => { + const source = ["abc", "def", "ghi"]; + const listItem = initListItem(source); + assert.deepEqual(listItem.toStringArray(), source); + }); + it('should return correct string[] for empty ListItem', () => { + const listItem = new ListItem; + assert.deepEqual(listItem.toStringArray(), []); + }); + }); + }); +}); + +function stubSectionsStrsAllocString(s?: string, opts?: StrsOptions, sections?: DependencySections): StrsItem { + return new StrsItem(s); +} + +function initListItem(source: Array): ListItem { + const listItem = new ListItem(); + for (const s of source) { + listItem.push(new ListIndex(new StrsItem(s))); + } + return listItem; +} diff --git a/common/web/types/tests/ldml-keyboard/unicodeset-parser-api.tests.ts b/common/web/types/tests/ldml-keyboard/unicodeset-parser-api.tests.ts new file mode 100644 index 00000000000..763bc6d5bb9 --- /dev/null +++ b/common/web/types/tests/ldml-keyboard/unicodeset-parser-api.tests.ts @@ -0,0 +1,24 @@ +/* + * Keyman is copyright (C) SIL Global. MIT License. + * + * Created by Dr Mark C. Sinclair on 2024-11-29 + * + * Test code for unicodeset-parser-api.ts + */ + +import 'mocha'; +import { assert } from 'chai'; +import { UnicodeSet } from '../../src/ldml-keyboard/unicodeset-parser-api.js'; + +describe('Test of Unicode-Parser-API', () => { + describe('Test UnicodeSet', () => { + it('can provide a correct ranges length', () => { + const unicodeSet = new UnicodeSet("[ħa-z]", [[0x41, 0x7A], [0x0127, 0x0127]]); + assert.equal(unicodeSet.length, 2); + }); + it('can provide a correct string representation', () => { + const unicodeSet = new UnicodeSet("[ħa-z]", [[0x41, 0x7A], [0x0127, 0x0127]]); + assert.deepEqual(unicodeSet.toString(), "[ħa-z]"); + }); + }); +}); diff --git a/common/web/types/tests/lexical-model-types.tests.ts b/common/web/types/tests/lexical-model-types.tests.ts new file mode 100644 index 00000000000..ef8bed28a50 --- /dev/null +++ b/common/web/types/tests/lexical-model-types.tests.ts @@ -0,0 +1,25 @@ +/** + * This file "tests" the exports from the main module. + * + * Since the exports are all types, the "test" here is that the type can be + * imported and compiled without any compiler errors. + */ + +import { KMXPlus, LdmlKeyboardTypes, LexicalModelTypes } from "@keymanapp/common-types"; + +export let u: LexicalModelTypes.USVString; +export let l: LexicalModelTypes.Transform; +export let s: LexicalModelTypes.Suggestion; +export let st: LexicalModelTypes.SuggestionTag; +export let c: LexicalModelTypes.Context; +export let cap: LexicalModelTypes.Capabilities; +export let conf: LexicalModelTypes.Configuration; +export let d: LexicalModelTypes.Distribution; +export let wbf: LexicalModelTypes.WordBreakingFunction; +export let sp: LexicalModelTypes.Span; +export let lmp: LexicalModelTypes.LexicalModelPunctuation; + + +// try some of the other types - that should still work +export let elemString: LdmlKeyboardTypes.ElementString; +export let section: KMXPlus.Section; diff --git a/common/web/types/test/tsconfig.json b/common/web/types/tests/tsconfig.json similarity index 90% rename from common/web/types/test/tsconfig.json rename to common/web/types/tests/tsconfig.json index 9678c49945f..45e5311fdc0 100644 --- a/common/web/types/test/tsconfig.json +++ b/common/web/types/tests/tsconfig.json @@ -4,13 +4,12 @@ "compilerOptions": { "rootDir": ".", "rootDirs": ["./", "../src/"], - "outDir": "../build/test", + "outDir": "../build/tests", "baseUrl": ".", "strictNullChecks": false, // TODO: get rid of this as some point "allowSyntheticDefaultImports": true }, "include": [ - "**/test-*.ts", "**/*.tests.ts", "./helpers/*.ts", ], diff --git a/common/web/types/test/util/test-unescape.ts b/common/web/types/tests/util/unescape.tests.ts similarity index 94% rename from common/web/types/test/util/test-unescape.ts rename to common/web/types/tests/util/unescape.tests.ts index 8c75b491824..3eaafd7150f 100644 --- a/common/web/types/test/util/test-unescape.ts +++ b/common/web/types/tests/util/unescape.tests.ts @@ -1,6 +1,6 @@ import 'mocha'; import {assert} from 'chai'; -import {unescapeString, UnescapeError, isOneChar, toOneChar, unescapeOneQuadString, BadStringAnalyzer, isValidUnicode, describeCodepoint, isPUA, BadStringType, unescapeStringToRegex, unescapeQuadString, NFDAnalyzer} from '../../src/util/util.js'; +import {unescapeString, UnescapeError, isOneChar, toOneChar, unescapeOneQuadString, BadStringAnalyzer, isValidUnicode, describeCodepoint, isPUA, BadStringType, unescapeStringToRegex, unescapeQuadString, NFDAnalyzer, isNormalized} from '../../src/util/util.js'; describe('test UTF32 functions()', function() { it('should properly categorize strings', () => { @@ -186,6 +186,24 @@ describe('test bad char functions', () => { assert.isTrue(isPUA(ch), describeCodepoint(ch)); } }); + describe('test isDenormalized()', () => { + it('should correctly categorize strings', () => { + [ + undefined, + null, + '', + 'ABC', + 'fa\u1E69cinating', // NFC + 'fas\u0323\u0307cinating', // NFD + 'd\u0323\u0307', // NFD + '\u1e0d\u0307', // NFC + ].map(s => assert.isTrue(isNormalized(s), `for string ${s}`)); + [ + 'd\u0307\u0323', // NFD but reversed marks + 'fas\u0307\u0323cinating', // not-NFD + ].map(s => assert.isFalse(isNormalized(s), `for string ${s}`)); + }); + }); }); describe('test BadStringAnalyzer', () => { diff --git a/common/windows/delphi/general/KeymanPaths.pas b/common/windows/delphi/general/KeymanPaths.pas index bc534b9f526..fbfa9961d70 100644 --- a/common/windows/delphi/general/KeymanPaths.pas +++ b/common/windows/delphi/general/KeymanPaths.pas @@ -436,12 +436,18 @@ class function TKeymanPaths.RunningFromSource(var keyman_root: string): Boolean; class function TKeymanPaths.KeymanCoreLibraryPath(const Filename: string): string; var keyman_root: string; + configuration: string; begin // Look up KEYMAN_ROOT development variable -- if found and executable // within that path then use that as source path if TKeymanPaths.RunningFromSource(keyman_root) then begin - Exit(keyman_root + 'core\build\x86\debug\src\' + Filename); +{$IFDEF DEBUG} + configuration := 'debug'; +{$ELSE} + configuration := 'release'; +{$ENDIF} + Exit(keyman_root + 'core\build\x86\'+configuration+'\src\' + Filename); end; Result := GetDebugPath('KeymanCoreLibraryPath', ''); diff --git a/core/docs/api/index.md b/core/docs/api/index.md index 8112d9c8793..c33246f7f44 100644 --- a/core/docs/api/index.md +++ b/core/docs/api/index.md @@ -75,6 +75,7 @@ modifiers such as Windows key are excluded from this set. Some modifiers are transient, such as Control, and others have long-lasting state, such as Caps Lock. +- __See more in__ [Keyman Glossary](https://github.com/keymanapp/keyman/wiki/Keyman-glossary) [km_core_cp]: background#km_core_cp "km_core_cp type" [km_core_usv]: background#km_core_usv "km_core_usv type" diff --git a/core/src/action.cpp b/core/src/action.cpp index 5f591444091..1ff7917575c 100644 --- a/core/src/action.cpp +++ b/core/src/action.cpp @@ -61,7 +61,9 @@ bool km::core::action_item_list_to_actions_object( if(output.empty()) { actions->code_points_to_delete++; } else { +#ifndef NDEBUG auto last_context_item = output.back(); +#endif output.pop_back(); assert(last_context_item.type == KM_CORE_CT_CHAR); assert(last_context_item.character == action_items->backspace.expected_value); @@ -71,7 +73,9 @@ bool km::core::action_item_list_to_actions_object( if(output.empty()) { // deleting a marker has no effect on the application } else { +#ifndef NDEBUG auto last_context_item = output.back(); +#endif output.pop_back(); assert(last_context_item.type == KM_CORE_CT_MARKER); assert(last_context_item.marker == action_items->backspace.expected_value); diff --git a/core/src/kmx/kmx_processevent.cpp b/core/src/kmx/kmx_processevent.cpp index 6e1e8dc2b4a..70d20102bc7 100644 --- a/core/src/kmx/kmx_processevent.cpp +++ b/core/src/kmx/kmx_processevent.cpp @@ -12,7 +12,7 @@ using namespace kmx; /* Globals */ KMX_BOOL km::core::kmx::g_debug_ToConsole = FALSE; -KMX_BOOL km::core::kmx::g_debug_KeymanLog = TRUE; +KMX_BOOL km::core::kmx::g_debug_KeymanLog = FALSE; // workaround for #12661 KMX_BOOL km::core::kmx::g_silent = FALSE; /* diff --git a/core/src/ldml/ldml_markers.cpp b/core/src/ldml/ldml_markers.cpp index 5d4fb4ff462..50c2282828d 100644 --- a/core/src/ldml/ldml_markers.cpp +++ b/core/src/ldml/ldml_markers.cpp @@ -56,15 +56,19 @@ void add_back_markers(std::u32string &str, const std::u32string &src, marker_map str.clear(); // iterator over the marker map auto marki = map2.rbegin(); +#ifndef NDEBUG // number of markers left to processnfd size_t max_markers = count_markers(map); size_t processed_markers = 0; +#endif // add any end-of-text markers while(marki != map2.rend() && marki->ch == MARKER_BEFORE_EOT) { if (!marki->end) { prepend_marker(str, marki->marker, encoding); +#ifndef NDEBUG processed_markers++; +#endif } marki->processed = true; // mark as done marki++; @@ -88,7 +92,9 @@ void add_back_markers(std::u32string &str, const std::u32string &src, marker_map break; } else { prepend_marker(str, i->marker, encoding); +#ifndef NDEBUG processed_markers++; +#endif } } } diff --git a/core/src/ldml/ldml_processor.cpp b/core/src/ldml/ldml_processor.cpp index 826c0e7f51c..548c0d76b00 100644 --- a/core/src/ldml/ldml_processor.cpp +++ b/core/src/ldml/ldml_processor.cpp @@ -410,8 +410,10 @@ ldml_event_state::remove_text(std::u32string &str, size_t length) { /** track how many context items have been removed, via push_backspace() */ size_t contextRemoved = 0; for (auto c = state->context().rbegin(); length > 0 && c != state->context().rend(); c++, contextRemoved++) { +#ifndef NDEBUG /** last char of context */ km_core_usv lastCtx = str.back(); +#endif uint8_t type = c->type; assert(type == KM_CORE_BT_CHAR || type == KM_CORE_BT_MARKER); if (type == KM_CORE_BT_CHAR) { diff --git a/core/src/meson.build b/core/src/meson.build index 3d7086b01bb..030ab0a5144 100644 --- a/core/src/meson.build +++ b/core/src/meson.build @@ -48,23 +48,27 @@ endif generated_headers = [] if cpp_compiler.get_id() == 'emscripten' - -util_normalize_table_generator = executable('util_normalize_table_generator', - ['util_normalize_table_generator.cpp'], - cpp_args: defns + warns, - include_directories: [inc], - link_args: links, - dependencies: [icu_uc, icu_i18n], - ) - -util_normalize_table_h = custom_target('util_normalize_table.h', - output: 'util_normalize_table.h', - command: [util_normalize_table_generator], - capture:true) - -generated_headers += util_normalize_table_h - - + links += [ + '-sEXPORTED_RUNTIME_METHODS=[\'UTF8ToString\',\'stringToNewUTF8\',\'wasmExports\']', + # Forcing inclusion of debug symbols + '-g', '-Wlimited-postlink-optimizations', + '-lembind' + ] + + util_normalize_table_generator = executable('util_normalize_table_generator', + ['util_normalize_table_generator.cpp'], + cpp_args: defns + warns, + include_directories: [inc], + link_args: links, + dependencies: [icu_uc, icu_i18n], + ) + + util_normalize_table_h = custom_target('util_normalize_table.h', + output: 'util_normalize_table.h', + command: [util_normalize_table_generator], + capture:true) + + generated_headers += util_normalize_table_h endif diff --git a/core/tests/kmx_test_source/kmx_test_source.cpp b/core/tests/kmx_test_source/kmx_test_source.cpp index 0464bce8832..9ba7ed36e83 100644 --- a/core/tests/kmx_test_source/kmx_test_source.cpp +++ b/core/tests/kmx_test_source/kmx_test_source.cpp @@ -18,6 +18,9 @@ #include "kmx_test_source.hpp" +#include +#include + namespace km { namespace tests { @@ -51,7 +54,7 @@ KmxTestSource::parse_source_string(std::string const &s) { if (*p == '\\') { p++; km_core_usv v; - assert(p != s.end()); + test_assert(p != s.end()); if (*p == 'u' || *p == 'U') { // Unicode value p++; @@ -59,7 +62,7 @@ KmxTestSource::parse_source_string(std::string const &s) { std::string s1 = s.substr(p - s.begin(), 8); v = std::stoul(s1, &n, 16); // Allow deadkey_number (U+0001) characters and onward - assert(v >= 0x0001 && v <= 0x10FFFF); + test_assert(v >= 0x0001 && v <= 0x10FFFF); p += n - 1; if (v < 0x10000) { t += km_core_cu(v); @@ -70,7 +73,7 @@ KmxTestSource::parse_source_string(std::string const &s) { } else if (*p == 'd') { // Deadkey // TODO, not yet supported - assert(false); + test_assert(false); } } else { t += *p; @@ -212,7 +215,7 @@ KmxTestSource::get_keyboard_options(kmx_options options) { key_event KmxTestSource::char_to_event(char ch) { - assert(ch >= 32); + test_assert(ch >= 32); return { km::core::kmx::s_char_to_vkey[(int)ch - 32].vk, (uint16_t)(km::core::kmx::s_char_to_vkey[(int)ch - 32].shifted ? KM_CORE_MODIFIER_SHIFT : 0)}; @@ -258,8 +261,8 @@ KmxTestSource::vkey_to_event(std::string const &vk_event) { } // The string should be empty at this point - assert(!std::getline(f, s, ' ')); - assert(vk != 0); + test_assert(!std::getline(f, s, ' ')); + test_assert(vk != 0); return {vk, modifier_state}; } @@ -276,7 +279,7 @@ KmxTestSource::next_key(std::string &keys) { return char_to_event(ch); } auto n = keys.find(']'); - assert(n != std::string::npos); + test_assert(n != std::string::npos); auto vkey = keys.substr(1, n - 1); keys.erase(0, n + 1); return vkey_to_event(vkey); diff --git a/core/tests/meson.build b/core/tests/meson.build index 5ad808e1b2c..1f686c260de 100644 --- a/core/tests/meson.build +++ b/core/tests/meson.build @@ -7,7 +7,7 @@ # # Note: this version of cmpfiles ignores line endings, which is better for platform independence -cmpfiles = ['-c', 'import sys; a = open(sys.argv[1], \'r\').read(); b = open(sys.argv[2], \'r\').read(); exit(not (a==b))'] +cmpfiles = ['-c', 'import sys; a = open(sys.argv[1], \'r\').read(); b = open(sys.argv[2], \'r\').read(); sys.exit(not (a==b))'] stnds = join_paths(meson.current_source_dir(), 'standards') libsrc = include_directories('../src') diff --git a/core/tests/unit/emscripten_filesystem.cpp b/core/tests/unit/emscripten_filesystem.cpp index c5e180f6bea..d51fa98f12d 100644 --- a/core/tests/unit/emscripten_filesystem.cpp +++ b/core/tests/unit/emscripten_filesystem.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include const std::string get_wasm_file_path(const std::string& filename) { // Verify that we are passing a fully-qualified path @@ -13,13 +13,13 @@ const std::string get_wasm_file_path(const std::string& filename) { std::cout << "get_wasm_file_path ENTER (" << filename << ")" << std::endl; #endif - assert( + test_assert( (filename.length() > 0 && filename.at(0) == '/') || (filename.length() > 1 && filename.at(1) == ':') ); #if _DEBUG_FOPEN - std::cout << "get_wasm_file_path assert passed " << std::endl; + std::cout << "get_wasm_file_path test_assert passed " << std::endl; #endif EM_ASM_({ diff --git a/core/tests/unit/kmnkbd/action_api.cpp b/core/tests/unit/kmnkbd/action_api.tests.cpp similarity index 61% rename from core/tests/unit/kmnkbd/action_api.cpp rename to core/tests/unit/kmnkbd/action_api.tests.cpp index 6899539d874..b4bbb1cd844 100644 --- a/core/tests/unit/kmnkbd/action_api.cpp +++ b/core/tests/unit/kmnkbd/action_api.tests.cpp @@ -35,19 +35,19 @@ void test_two_backspaces() { }; km_core_actions actions; - assert(km::core::action_item_list_to_actions_object(action_items, &actions)); + test_assert(km::core::action_item_list_to_actions_object(action_items, &actions)); - assert(actions.code_points_to_delete == 1); - assert(std::u32string(actions.output) == U""); - assert(actions.persist_options != nullptr); - assert(actions.persist_options[0].key == nullptr); - assert(actions.persist_options[0].value == nullptr); - assert(actions.persist_options[0].scope == KM_CORE_OPT_UNKNOWN); + test_assert(actions.code_points_to_delete == 1); + test_assert(std::u32string(actions.output) == U""); + test_assert(actions.persist_options != nullptr); + test_assert(actions.persist_options[0].key == nullptr); + test_assert(actions.persist_options[0].value == nullptr); + test_assert(actions.persist_options[0].scope == KM_CORE_OPT_UNKNOWN); - assert(actions.do_alert == false); - assert(actions.emit_keystroke == false); - assert(actions.new_caps_lock_state == -1); - assert(actions.deleted_context == nullptr); + test_assert(actions.do_alert == false); + test_assert(actions.emit_keystroke == false); + test_assert(actions.new_caps_lock_state == -1); + test_assert(actions.deleted_context == nullptr); km::core::actions_dispose(actions); } @@ -68,18 +68,18 @@ void test_marker_text_interleaved() { }; km_core_actions actions; - assert(km::core::action_item_list_to_actions_object(action_items, &actions)); - - assert(actions.code_points_to_delete == 0); - assert(std::u32string(actions.output) == U"ABD"); - assert(actions.persist_options != nullptr); - assert(actions.persist_options[0].key == nullptr); - assert(actions.persist_options[0].value == nullptr); - assert(actions.persist_options[0].scope == KM_CORE_OPT_UNKNOWN); - assert(actions.do_alert == false); - assert(actions.emit_keystroke == false); - assert(actions.new_caps_lock_state == -1); - assert(actions.deleted_context == nullptr); + test_assert(km::core::action_item_list_to_actions_object(action_items, &actions)); + + test_assert(actions.code_points_to_delete == 0); + test_assert(std::u32string(actions.output) == U"ABD"); + test_assert(actions.persist_options != nullptr); + test_assert(actions.persist_options[0].key == nullptr); + test_assert(actions.persist_options[0].value == nullptr); + test_assert(actions.persist_options[0].scope == KM_CORE_OPT_UNKNOWN); + test_assert(actions.do_alert == false); + test_assert(actions.emit_keystroke == false); + test_assert(actions.new_caps_lock_state == -1); + test_assert(actions.deleted_context == nullptr); km::core::actions_dispose(actions); } @@ -93,18 +93,18 @@ void test_alert() { }; km_core_actions actions; - assert(km::core::action_item_list_to_actions_object(action_items, &actions)); - - assert(actions.code_points_to_delete == 0); - assert(std::u32string(actions.output) == U""); - assert(actions.persist_options != nullptr); - assert(actions.persist_options[0].key == nullptr); - assert(actions.persist_options[0].value == nullptr); - assert(actions.persist_options[0].scope == KM_CORE_OPT_UNKNOWN); - assert(actions.do_alert == KM_CORE_TRUE); - assert(actions.emit_keystroke == KM_CORE_FALSE); - assert(actions.new_caps_lock_state == KM_CORE_CAPS_UNCHANGED); - assert(actions.deleted_context == nullptr); + test_assert(km::core::action_item_list_to_actions_object(action_items, &actions)); + + test_assert(actions.code_points_to_delete == 0); + test_assert(std::u32string(actions.output) == U""); + test_assert(actions.persist_options != nullptr); + test_assert(actions.persist_options[0].key == nullptr); + test_assert(actions.persist_options[0].value == nullptr); + test_assert(actions.persist_options[0].scope == KM_CORE_OPT_UNKNOWN); + test_assert(actions.do_alert == KM_CORE_TRUE); + test_assert(actions.emit_keystroke == KM_CORE_FALSE); + test_assert(actions.new_caps_lock_state == KM_CORE_CAPS_UNCHANGED); + test_assert(actions.deleted_context == nullptr); km::core::actions_dispose(actions); } @@ -118,18 +118,18 @@ void test_emit_keystroke() { }; km_core_actions actions; - assert(km::core::action_item_list_to_actions_object(action_items, &actions)); - - assert(actions.code_points_to_delete == 0); - assert(std::u32string(actions.output) == U""); - assert(actions.persist_options != nullptr); - assert(actions.persist_options[0].key == nullptr); - assert(actions.persist_options[0].value == nullptr); - assert(actions.persist_options[0].scope == KM_CORE_OPT_UNKNOWN); - assert(actions.do_alert == KM_CORE_FALSE); - assert(actions.emit_keystroke == KM_CORE_TRUE); - assert(actions.new_caps_lock_state == KM_CORE_CAPS_UNCHANGED); - assert(actions.deleted_context == nullptr); + test_assert(km::core::action_item_list_to_actions_object(action_items, &actions)); + + test_assert(actions.code_points_to_delete == 0); + test_assert(std::u32string(actions.output) == U""); + test_assert(actions.persist_options != nullptr); + test_assert(actions.persist_options[0].key == nullptr); + test_assert(actions.persist_options[0].value == nullptr); + test_assert(actions.persist_options[0].scope == KM_CORE_OPT_UNKNOWN); + test_assert(actions.do_alert == KM_CORE_FALSE); + test_assert(actions.emit_keystroke == KM_CORE_TRUE); + test_assert(actions.new_caps_lock_state == KM_CORE_CAPS_UNCHANGED); + test_assert(actions.deleted_context == nullptr); km::core::actions_dispose(actions); } @@ -144,18 +144,18 @@ void test_invalidate_context() { }; km_core_actions actions; - assert(km::core::action_item_list_to_actions_object(action_items, &actions)); - - assert(actions.code_points_to_delete == 0); - assert(std::u32string(actions.output) == U""); - assert(actions.persist_options != nullptr); - assert(actions.persist_options[0].key == nullptr); - assert(actions.persist_options[0].value == nullptr); - assert(actions.persist_options[0].scope == KM_CORE_OPT_UNKNOWN); - assert(actions.do_alert == KM_CORE_FALSE); - assert(actions.emit_keystroke == KM_CORE_FALSE); - assert(actions.new_caps_lock_state == KM_CORE_CAPS_UNCHANGED); - assert(actions.deleted_context == nullptr); + test_assert(km::core::action_item_list_to_actions_object(action_items, &actions)); + + test_assert(actions.code_points_to_delete == 0); + test_assert(std::u32string(actions.output) == U""); + test_assert(actions.persist_options != nullptr); + test_assert(actions.persist_options[0].key == nullptr); + test_assert(actions.persist_options[0].value == nullptr); + test_assert(actions.persist_options[0].scope == KM_CORE_OPT_UNKNOWN); + test_assert(actions.do_alert == KM_CORE_FALSE); + test_assert(actions.emit_keystroke == KM_CORE_FALSE); + test_assert(actions.new_caps_lock_state == KM_CORE_CAPS_UNCHANGED); + test_assert(actions.deleted_context == nullptr); km::core::actions_dispose(actions); } @@ -175,28 +175,28 @@ void test_persist_opt() { }; km_core_actions actions; - assert(km::core::action_item_list_to_actions_object(action_items, &actions)); + test_assert(km::core::action_item_list_to_actions_object(action_items, &actions)); - assert(actions.code_points_to_delete == 0); - assert(std::u32string(actions.output) == U""); - assert(actions.persist_options != nullptr); - assert(std::u16string(actions.persist_options[0].key) == u"key"); - assert(std::u16string(actions.persist_options[0].value) == u"value"); - assert(actions.persist_options[0].scope == KM_CORE_OPT_KEYBOARD); + test_assert(actions.code_points_to_delete == 0); + test_assert(std::u32string(actions.output) == U""); + test_assert(actions.persist_options != nullptr); + test_assert(std::u16string(actions.persist_options[0].key) == u"key"); + test_assert(std::u16string(actions.persist_options[0].value) == u"value"); + test_assert(actions.persist_options[0].scope == KM_CORE_OPT_KEYBOARD); // verify that data is copied - assert(actions.persist_options[0].key != option.key); - assert(actions.persist_options[0].value != option.value); + test_assert(actions.persist_options[0].key != option.key); + test_assert(actions.persist_options[0].value != option.value); // verify that we have a KM_CORE_OPTIONS_END term - assert(actions.persist_options[1].key == nullptr); - assert(actions.persist_options[1].value == nullptr); - assert(actions.persist_options[1].scope == KM_CORE_OPT_UNKNOWN); - - assert(actions.do_alert == KM_CORE_FALSE); - assert(actions.emit_keystroke == KM_CORE_FALSE); - assert(actions.new_caps_lock_state == KM_CORE_CAPS_UNCHANGED); - assert(actions.deleted_context == nullptr); + test_assert(actions.persist_options[1].key == nullptr); + test_assert(actions.persist_options[1].value == nullptr); + test_assert(actions.persist_options[1].scope == KM_CORE_OPT_UNKNOWN); + + test_assert(actions.do_alert == KM_CORE_FALSE); + test_assert(actions.emit_keystroke == KM_CORE_FALSE); + test_assert(actions.new_caps_lock_state == KM_CORE_CAPS_UNCHANGED); + test_assert(actions.deleted_context == nullptr); km::core::actions_dispose(actions); } diff --git a/core/tests/unit/kmnkbd/action_set_api.cpp b/core/tests/unit/kmnkbd/action_set_api.tests.cpp similarity index 93% rename from core/tests/unit/kmnkbd/action_set_api.cpp rename to core/tests/unit/kmnkbd/action_set_api.tests.cpp index 4806eb4ac94..72a2d9be531 100644 --- a/core/tests/unit/kmnkbd/action_set_api.cpp +++ b/core/tests/unit/kmnkbd/action_set_api.tests.cpp @@ -74,20 +74,20 @@ void run_test(km_core_action_item const * action_items, const km_core_actions &a int n = 0; for(auto act = set_actions.begin(); act != set_actions.end(); act++, n++) { - assert(act->type == action_items[n].type); + test_assert(act->type == action_items[n].type); // TODO: all other fields switch(act->type) { case KM_CORE_IT_ALERT: break; case KM_CORE_IT_BACK: - assert(act->backspace.expected_type == action_items[n].backspace.expected_type); - assert(act->backspace.expected_value == action_items[n].backspace.expected_value); + test_assert(act->backspace.expected_type == action_items[n].backspace.expected_type); + test_assert(act->backspace.expected_value == action_items[n].backspace.expected_value); break; case KM_CORE_IT_CAPSLOCK: - assert(act->capsLock == action_items[n].capsLock); + test_assert(act->capsLock == action_items[n].capsLock); break; case KM_CORE_IT_CHAR: - assert(act->character == action_items[n].character); + test_assert(act->character == action_items[n].character); break; case KM_CORE_IT_EMIT_KEYSTROKE: break; @@ -96,16 +96,16 @@ void run_test(km_core_action_item const * action_items, const km_core_actions &a case KM_CORE_IT_INVALIDATE_CONTEXT: break; case KM_CORE_IT_MARKER: - assert(act->marker == action_items[n].marker); + test_assert(act->marker == action_items[n].marker); break; case KM_CORE_IT_PERSIST_OPT: - assert(act->option->scope == action_items[n].option->scope); - assert(std::u16string(act->option->key) == action_items[n].option->key); - assert(std::u16string(act->option->value) == action_items[n].option->value); + test_assert(act->option->scope == action_items[n].option->scope); + test_assert(std::u16string(act->option->key) == action_items[n].option->key); + test_assert(std::u16string(act->option->value) == action_items[n].option->value); break; default: // Invalid action type - assert(false); + test_assert(false); } } } diff --git a/core/tests/unit/kmnkbd/test_actions_get_api.cpp b/core/tests/unit/kmnkbd/actions_get_api.tests.cpp similarity index 97% rename from core/tests/unit/kmnkbd/test_actions_get_api.cpp rename to core/tests/unit/kmnkbd/actions_get_api.tests.cpp index 579f02e5ced..f9b7c75dac5 100644 --- a/core/tests/unit/kmnkbd/test_actions_get_api.cpp +++ b/core/tests/unit/kmnkbd/actions_get_api.tests.cpp @@ -139,17 +139,17 @@ void test( } std::cout << std::endl; - assert(expected_delete == actual_actions->code_points_to_delete); - assert(expected_output == actual_actions->output); - assert(expected_deleted_context == actual_actions->deleted_context); + test_assert(expected_delete == actual_actions->code_points_to_delete); + test_assert(expected_output == actual_actions->output); + test_assert(expected_deleted_context == actual_actions->deleted_context); - // assert(expected_deleted_context == actual_actions->deleted_context); + // test_assert(expected_deleted_context == actual_actions->deleted_context); auto actual_final_app_context = get_context_as_string(km_core_state_app_context(test_state)); auto actual_final_app_context_string = std::u16string(actual_final_app_context); auto expected_final_app_context_string = std::u16string(expected_final_app_context); std::cout << " final app context: actual: |" << actual_final_app_context_string << "| expected: |" << expected_final_app_context_string << "|" << std::endl; - assert(actual_final_app_context_string == expected_final_app_context_string); + test_assert(actual_final_app_context_string == expected_final_app_context_string); delete [] actual_final_app_context; teardown(); diff --git a/core/tests/unit/kmnkbd/test_actions_normalize.cpp b/core/tests/unit/kmnkbd/actions_normalize.tests.cpp similarity index 98% rename from core/tests/unit/kmnkbd/test_actions_normalize.cpp rename to core/tests/unit/kmnkbd/actions_normalize.tests.cpp index aa4150ef9ad..f71ef1cd3f1 100644 --- a/core/tests/unit/kmnkbd/test_actions_normalize.cpp +++ b/core/tests/unit/kmnkbd/actions_normalize.tests.cpp @@ -121,7 +121,7 @@ void test_actions_normalize( setup(initial_app_context, final_cached_context_string, final_cached_context_items, actions_code_points_to_delete, actions_output); - assert(km::core::actions_normalize(km_core_state_context(test_state), km_core_state_app_context(test_state), test_actions)); + test_assert(km::core::actions_normalize(km_core_state_context(test_state), km_core_state_app_context(test_state), test_actions)); std::cout << "test_actions_normalize: (" << name << "): delete: " << test_actions.code_points_to_delete << " output: |" << std::u32string(test_actions.output) << "|" << std::endl; std::u32string o(test_actions.output); @@ -130,8 +130,8 @@ void test_actions_normalize( } std::cout << std::endl; - assert(expected_delete == test_actions.code_points_to_delete); - assert(expected_output == test_actions.output); + test_assert(expected_delete == test_actions.code_points_to_delete); + test_assert(expected_output == test_actions.output); auto debug = km_core_state_context_debug(test_state, KM_CORE_DEBUG_CONTEXT_APP); std::cout << " final app context: " << debug << std::endl; @@ -195,7 +195,7 @@ void test_actions_update_app_context_nfu( setup(initial_app_context, final_cached_context_string, final_cached_context_items, actions_code_points_to_delete, actions_output); - assert(km::core::actions_update_app_context_nfu(km_core_state_context(test_state), km_core_state_app_context(test_state))); + test_assert(km::core::actions_update_app_context_nfu(km_core_state_context(test_state), km_core_state_app_context(test_state))); std::cout << "test_actions_update_app_context_nfu: (" << name << "): delete: " << expected_delete << " output: |" << std::u32string(test_actions.output) << "|" << std::endl; std::u32string o(test_actions.output); @@ -204,8 +204,8 @@ void test_actions_update_app_context_nfu( } std::cout << std::endl; - assert(expected_delete == test_actions.code_points_to_delete); - assert(expected_output == test_actions.output); + test_assert(expected_delete == test_actions.code_points_to_delete); + test_assert(expected_output == test_actions.output); auto debug = km_core_state_context_debug(test_state, KM_CORE_DEBUG_CONTEXT_APP); std::cout << " final app context: " << debug << std::endl; @@ -627,7 +627,7 @@ void compare_context(km_core_context *app_context, const km_core_cu* expected_fi try_status(context_items_from_utf16(expected_final_app_context, &expected_final_app_context_items)); for(int i = 0; actual_final_app_context_items[i].type != KM_CORE_CT_END || expected_final_app_context_items[i].type != KM_CORE_CT_END; i++) { - assert( + test_assert( actual_final_app_context_items[i].type == expected_final_app_context_items[i].type && // union so testing character is sufficient to do both char + marker types actual_final_app_context_items[i].character == expected_final_app_context_items[i].character diff --git a/core/tests/unit/kmnkbd/context_api.cpp b/core/tests/unit/kmnkbd/context_api.tests.cpp similarity index 100% rename from core/tests/unit/kmnkbd/context_api.cpp rename to core/tests/unit/kmnkbd/context_api.tests.cpp diff --git a/core/tests/unit/kmnkbd/debug_api.cpp b/core/tests/unit/kmnkbd/debug_api.tests.cpp similarity index 94% rename from core/tests/unit/kmnkbd/debug_api.cpp rename to core/tests/unit/kmnkbd/debug_api.tests.cpp index 9a0d771e041..d40664436b0 100644 --- a/core/tests/unit/kmnkbd/debug_api.cpp +++ b/core/tests/unit/kmnkbd/debug_api.tests.cpp @@ -61,10 +61,10 @@ void setup(const char *keyboard) { try_status(context_items_from_utf16(u"Hello 😁", &citems)); // Pre-test sanity: ensure debugging is disabled - assert(km_core_state_debug_get(test_state) == 0); + test_assert(km_core_state_debug_get(test_state) == 0); // Ensure the pre-run debug item state is not empty - assert(debug_items(test_state, { + test_assert(debug_items(test_state, { km_core_state_debug_item{KM_CORE_DEBUG_END, {}, {}, {}} })); @@ -79,11 +79,11 @@ void test_debugging_disabled() { setup("k_000___null_keyboard.kmx"); try_status(km_core_state_debug_set(test_state, 0)); try_status(km_core_process_event(test_state, KM_CORE_VKEY_S, KM_CORE_MODIFIER_SHIFT, 1, KM_CORE_EVENT_FLAG_DEFAULT)); - assert(debug_items(test_state, { + test_assert(debug_items(test_state, { km_core_state_debug_item{KM_CORE_DEBUG_END} })); - assert(action_items(test_state, { + test_assert(action_items(test_state, { {KM_CORE_IT_CHAR, {0,}, {km_core_usv('S')}}, {KM_CORE_IT_END} })); @@ -97,14 +97,14 @@ void test_debugging_no_rule_match() { DEBUG_GROUP gp = {u"Main"}; try_status(km_core_state_debug_set(test_state, 1)); try_status(km_core_process_event(test_state, KM_CORE_VKEY_S, KM_CORE_MODIFIER_SHIFT, 1, KM_CORE_EVENT_FLAG_DEFAULT)); - assert(debug_items(test_state, { + test_assert(debug_items(test_state, { km_core_state_debug_item{KM_CORE_DEBUG_BEGIN, KM_CORE_DEBUG_FLAG_UNICODE, {KM_CORE_VKEY_S, KM_CORE_MODIFIER_SHIFT, 'S'}}, km_core_state_debug_item{KM_CORE_DEBUG_GROUP_ENTER, 0, {}, {u"", &gp}}, km_core_state_debug_item{KM_CORE_DEBUG_GROUP_EXIT, KM_CORE_DEBUG_FLAG_NOMATCH, {}, {u"", &gp, nullptr, {}, 1}}, km_core_state_debug_item{KM_CORE_DEBUG_END, 0, {}, {u"", nullptr, nullptr, {}, 1}} })); - assert(action_items(test_state, { + test_assert(action_items(test_state, { {KM_CORE_IT_CHAR, {0,}, {km_core_usv('S')}}, {KM_CORE_IT_END} })); @@ -118,14 +118,14 @@ void test_debugging_function_key() { DEBUG_GROUP gp = {u"Main"}; try_status(km_core_state_debug_set(test_state, 1)); try_status(km_core_process_event(test_state, KM_CORE_VKEY_F1, 0, 1, KM_CORE_EVENT_FLAG_DEFAULT)); - assert(debug_items(test_state, { + test_assert(debug_items(test_state, { km_core_state_debug_item{KM_CORE_DEBUG_BEGIN, KM_CORE_DEBUG_FLAG_UNICODE, {KM_CORE_VKEY_F1, 0, 0}}, km_core_state_debug_item{KM_CORE_DEBUG_GROUP_ENTER, 0, {}, {u"", &gp}}, km_core_state_debug_item{KM_CORE_DEBUG_GROUP_EXIT, KM_CORE_DEBUG_FLAG_NOMATCH, {}, {u"", &gp, nullptr, {}, 0}}, km_core_state_debug_item{KM_CORE_DEBUG_END, KM_CORE_DEBUG_FLAG_OUTPUTKEYSTROKE, {}, {u"", nullptr, nullptr, {}, 0}} })); - assert(action_items(test_state, { + test_assert(action_items(test_state, { {KM_CORE_IT_INVALIDATE_CONTEXT}, // It's a non character key that is not a modifier, so this is a hint that context may no longer be valid {KM_CORE_IT_EMIT_KEYSTROKE}, {KM_CORE_IT_END} @@ -144,33 +144,33 @@ void test_basic_rule_matches() { // 'DE' + 'F' > U+0E04 U+0E05 U+0E06 try_status(km_core_process_event(test_state, KM_CORE_VKEY_D, KM_CORE_MODIFIER_SHIFT, 1, KM_CORE_EVENT_FLAG_DEFAULT)); - assert(debug_items(test_state, { + test_assert(debug_items(test_state, { km_core_state_debug_item{KM_CORE_DEBUG_BEGIN, KM_CORE_DEBUG_FLAG_UNICODE, {KM_CORE_VKEY_D, KM_CORE_MODIFIER_SHIFT, 'D'}}, km_core_state_debug_item{KM_CORE_DEBUG_GROUP_ENTER, 0, {}, {u"", &gp}}, km_core_state_debug_item{KM_CORE_DEBUG_GROUP_EXIT, KM_CORE_DEBUG_FLAG_NOMATCH, {}, {u"", &gp, nullptr, {}, 1}}, km_core_state_debug_item{KM_CORE_DEBUG_END, 0, {}, {u"", nullptr, nullptr, {}, 1}}, // action item will emit a default 'D' })); - assert(action_items(test_state, { + test_assert(action_items(test_state, { {KM_CORE_IT_CHAR, {0,}, {km_core_usv('D')}}, {KM_CORE_IT_END} })); try_status(km_core_process_event(test_state, KM_CORE_VKEY_E, KM_CORE_MODIFIER_SHIFT, 1, KM_CORE_EVENT_FLAG_DEFAULT)); - assert(debug_items(test_state, { + test_assert(debug_items(test_state, { km_core_state_debug_item{KM_CORE_DEBUG_BEGIN, KM_CORE_DEBUG_FLAG_UNICODE, {KM_CORE_VKEY_E, KM_CORE_MODIFIER_SHIFT, 'E'}}, km_core_state_debug_item{KM_CORE_DEBUG_GROUP_ENTER, 0, {}, {u"", &gp}}, km_core_state_debug_item{KM_CORE_DEBUG_GROUP_EXIT, KM_CORE_DEBUG_FLAG_NOMATCH, {}, {u"", &gp, nullptr, {}, 1}}, km_core_state_debug_item{KM_CORE_DEBUG_END, 0, {}, {u"", nullptr, nullptr, {}, 1}}, // action item will emit a default 'E' })); - assert(action_items(test_state, { + test_assert(action_items(test_state, { {KM_CORE_IT_CHAR, {0,}, {km_core_usv('E')}}, {KM_CORE_IT_END} })); try_status(km_core_process_event(test_state, KM_CORE_VKEY_F, KM_CORE_MODIFIER_SHIFT, 1, KM_CORE_EVENT_FLAG_DEFAULT)); - assert(debug_items(test_state, { + test_assert(debug_items(test_state, { km_core_state_debug_item{KM_CORE_DEBUG_BEGIN, KM_CORE_DEBUG_FLAG_UNICODE, {KM_CORE_VKEY_F, KM_CORE_MODIFIER_SHIFT, 'F'}}, km_core_state_debug_item{KM_CORE_DEBUG_GROUP_ENTER, 0, {}, {u"", &gp}}, km_core_state_debug_item{KM_CORE_DEBUG_RULE_ENTER, 0, {}, {u"DE", &gp, &kp, {0xFFFF}}}, @@ -187,7 +187,7 @@ void test_basic_rule_matches() { bksp_e.backspace.expected_type = KM_CORE_BT_CHAR; bksp_e.backspace.expected_value = 'E'; - assert(action_items(test_state, { + test_assert(action_items(test_state, { bksp_e, bksp_d, {KM_CORE_IT_CHAR, {0,}, {km_core_usv(u'\u0E04')}}, @@ -214,7 +214,7 @@ void test_multiple_groups() { // '12' -> 'abc' try_status(km_core_process_event(test_state, KM_CORE_VKEY_1, 0, 1, KM_CORE_EVENT_FLAG_DEFAULT)); - assert(debug_items(test_state, { + test_assert(debug_items(test_state, { km_core_state_debug_item{KM_CORE_DEBUG_BEGIN, KM_CORE_DEBUG_FLAG_UNICODE, {KM_CORE_VKEY_1, 0, '1'}}, km_core_state_debug_item{KM_CORE_DEBUG_GROUP_ENTER, 0, {}, {u"", &gp}}, @@ -236,7 +236,7 @@ void test_multiple_groups() { bksp_a.backspace.expected_type = KM_CORE_BT_CHAR; bksp_a.backspace.expected_value = 'a'; - assert(action_items(test_state, { + test_assert(action_items(test_state, { {KM_CORE_IT_CHAR, {0,}, {km_core_usv('a')}}, bksp_a, {KM_CORE_IT_CHAR, {0,}, {km_core_usv('b')}}, @@ -244,7 +244,7 @@ void test_multiple_groups() { })); try_status(km_core_process_event(test_state, KM_CORE_VKEY_2, 0, 1, KM_CORE_EVENT_FLAG_DEFAULT)); - assert(debug_items(test_state, { + test_assert(debug_items(test_state, { km_core_state_debug_item{KM_CORE_DEBUG_BEGIN, KM_CORE_DEBUG_FLAG_UNICODE, {KM_CORE_VKEY_2, 0, '2'}}, km_core_state_debug_item{KM_CORE_DEBUG_GROUP_ENTER, 0, {}, {u"", &gp}}, @@ -269,7 +269,7 @@ void test_multiple_groups() { bksp_b.backspace.expected_type = KM_CORE_BT_CHAR; bksp_b.backspace.expected_value = 'b'; - assert(action_items(test_state, { + test_assert(action_items(test_state, { bksp_b, {KM_CORE_IT_CHAR, {0,}, {km_core_usv('a')}}, {KM_CORE_IT_CHAR, {0,}, {km_core_usv('b')}}, @@ -293,7 +293,7 @@ void test_store_offsets() { // 'ab' -> 'ex' try_status(km_core_process_event(test_state, KM_CORE_VKEY_A, 0, 1, KM_CORE_EVENT_FLAG_DEFAULT)); - assert(debug_items(test_state, { + test_assert(debug_items(test_state, { km_core_state_debug_item{KM_CORE_DEBUG_BEGIN, KM_CORE_DEBUG_FLAG_UNICODE, {KM_CORE_VKEY_A, 0, 'a'}}, km_core_state_debug_item{KM_CORE_DEBUG_GROUP_ENTER, 0, {}, {u"", &gp}}, @@ -304,7 +304,7 @@ void test_store_offsets() { km_core_state_debug_item{KM_CORE_DEBUG_END, 0, {}, {u"", nullptr, nullptr, {}, 4}}, // action item will emit a 'exay' })); - assert(action_items(test_state, { + test_assert(action_items(test_state, { {KM_CORE_IT_CHAR, {0,}, {km_core_usv('e')}}, {KM_CORE_IT_CHAR, {0,}, {km_core_usv('x')}}, {KM_CORE_IT_CHAR, {0,}, {km_core_usv('a')}}, @@ -313,7 +313,7 @@ void test_store_offsets() { })); try_status(km_core_process_event(test_state, KM_CORE_VKEY_B, 0, 1, KM_CORE_EVENT_FLAG_DEFAULT)); - assert(debug_items(test_state, { + test_assert(debug_items(test_state, { km_core_state_debug_item{KM_CORE_DEBUG_BEGIN, KM_CORE_DEBUG_FLAG_UNICODE, {KM_CORE_VKEY_B, 0, 'b'}}, km_core_state_debug_item{KM_CORE_DEBUG_GROUP_ENTER, 0, {}, {u"", &gp}}, @@ -342,7 +342,7 @@ void test_store_offsets() { bksp[2].backspace.expected_value = 'x'; bksp[3].backspace.expected_value = 'e'; - assert(action_items(test_state, { + test_assert(action_items(test_state, { bksp[0], bksp[1], bksp[2], @@ -367,7 +367,7 @@ void test_set_option() { // '1' -> set_option try_status(km_core_process_event(test_state, KM_CORE_VKEY_1, 0, 1, KM_CORE_EVENT_FLAG_DEFAULT)); - assert(debug_items(test_state, { + test_assert(debug_items(test_state, { km_core_state_debug_item{KM_CORE_DEBUG_BEGIN, KM_CORE_DEBUG_FLAG_UNICODE, {KM_CORE_VKEY_1, 0, '1'}}, km_core_state_debug_item{KM_CORE_DEBUG_GROUP_ENTER, 0, {}, {u"", &gp}}, @@ -395,7 +395,7 @@ void test_save_option() { // '2' -> save_option try_status(km_core_process_event(test_state, KM_CORE_VKEY_2, 0, 1, KM_CORE_EVENT_FLAG_DEFAULT)); - assert(debug_items(test_state, { + test_assert(debug_items(test_state, { km_core_state_debug_item{KM_CORE_DEBUG_BEGIN, KM_CORE_DEBUG_FLAG_UNICODE, {KM_CORE_VKEY_2, 0, '2'}}, km_core_state_debug_item{KM_CORE_DEBUG_GROUP_ENTER, 0, {}, {u"", &gp}}, @@ -409,7 +409,7 @@ void test_save_option() { km_core_action_item action = {KM_CORE_IT_PERSIST_OPT, {0,}, }; action.option = &opt; - assert(action_items(test_state, { + test_assert(action_items(test_state, { action, {KM_CORE_IT_END} })); @@ -437,7 +437,7 @@ void test_backspace_markers() { try_status(km_core_state_debug_set(test_state, 1)); try_status(km_core_process_event(test_state, KM_CORE_VKEY_BKSP, 0, 1, KM_CORE_EVENT_FLAG_DEFAULT)); - assert(debug_items(test_state, { + test_assert(debug_items(test_state, { km_core_state_debug_item{KM_CORE_DEBUG_BEGIN, KM_CORE_DEBUG_FLAG_UNICODE, {KM_CORE_VKEY_BKSP, 0, 0}}, km_core_state_debug_item{KM_CORE_DEBUG_GROUP_ENTER, 0, {}, {u"", &gp}}, km_core_state_debug_item{KM_CORE_DEBUG_GROUP_EXIT, 2, {}, {u"", &gp, nullptr, {}, 2}}, @@ -448,7 +448,7 @@ void test_backspace_markers() { bksp.backspace.expected_type = KM_CORE_BT_MARKER; bksp.backspace.expected_value = 1; - assert(action_items(test_state, { + test_assert(action_items(test_state, { bksp, bksp, {KM_CORE_IT_INVALIDATE_CONTEXT}, diff --git a/core/tests/unit/kmnkbd/debug_items.hpp b/core/tests/unit/kmnkbd/debug_items.hpp index ae5f0e8cbd5..9e281631f6b 100644 --- a/core/tests/unit/kmnkbd/debug_items.hpp +++ b/core/tests/unit/kmnkbd/debug_items.hpp @@ -121,20 +121,20 @@ bool operator==( case KM_CORE_DEBUG_MATCH_EXIT: case KM_CORE_DEBUG_NOMATCH_ENTER: case KM_CORE_DEBUG_NOMATCH_EXIT: - assert(lgp != nullptr); - assert(rgp != nullptr); - assert(lgp->dpName != nullptr); - assert(rgp->dpName != nullptr); + test_assert(lgp != nullptr); + test_assert(rgp != nullptr); + test_assert(lgp->dpName != nullptr); + test_assert(rgp->dpName != nullptr); result = u16cmp(lgp->dpName, rgp->dpName) == 0; break; case KM_CORE_DEBUG_RULE_ENTER: case KM_CORE_DEBUG_RULE_EXIT: - assert(lgp != nullptr); - assert(rgp != nullptr); - assert(lgp->dpName != nullptr); - assert(rgp->dpName != nullptr); - assert(lrule != nullptr); - assert(rrule != nullptr); + test_assert(lgp != nullptr); + test_assert(rgp != nullptr); + test_assert(lgp->dpName != nullptr); + test_assert(rgp->dpName != nullptr); + test_assert(lrule != nullptr); + test_assert(rrule != nullptr); result = u16cmp(lgp->dpName, rgp->dpName) == 0 && lrule->Line == rrule->Line && lrule->Key == rrule->Key && @@ -143,13 +143,13 @@ bool operator==( are_store_offsets_equal(lhs.kmx_info.store_offsets, rhs.kmx_info.store_offsets); break; case KM_CORE_DEBUG_SET_OPTION: - assert(loption_store != nullptr && roption_store != nullptr); + test_assert(loption_store != nullptr && roption_store != nullptr); result = u16cmp(loption_store->dpName, roption_store->dpName) == 0 && u16cmp(lhs.kmx_info.option.value, rhs.kmx_info.option.value) == 0; break; default: - assert(false); + test_assert(false); result = false; } } diff --git a/core/tests/unit/kmnkbd/keyboard_api.cpp b/core/tests/unit/kmnkbd/keyboard_api.tests.cpp similarity index 100% rename from core/tests/unit/kmnkbd/keyboard_api.cpp rename to core/tests/unit/kmnkbd/keyboard_api.tests.cpp diff --git a/core/tests/unit/kmnkbd/test_kmx_context.cpp b/core/tests/unit/kmnkbd/kmx_context.tests.cpp similarity index 64% rename from core/tests/unit/kmnkbd/test_kmx_context.cpp rename to core/tests/unit/kmnkbd/kmx_context.tests.cpp index e557daeb3cb..0679c34d1a5 100644 --- a/core/tests/unit/kmnkbd/test_kmx_context.cpp +++ b/core/tests/unit/kmnkbd/kmx_context.tests.cpp @@ -21,89 +21,89 @@ using namespace std; void test_CharIsDeadkey() { KMX_Context context; - assert(context.CharIsDeadkey() == FALSE); + test_assert(context.CharIsDeadkey() == FALSE); context.Reset(); context.Add(u'a'); context.Add(u'a'); context.Add(u'a'); - assert(context.CharIsDeadkey() == FALSE); + test_assert(context.CharIsDeadkey() == FALSE); context.Reset(); context.Add(u'\uffff'); context.Add(u'\u0008'); - assert(context.CharIsDeadkey() == FALSE); + test_assert(context.CharIsDeadkey() == FALSE); context.Reset(); context.Add(u'\uffff'); - assert(context.CharIsDeadkey() == FALSE); + test_assert(context.CharIsDeadkey() == FALSE); context.Reset(); context.Add(u'a'); context.Add(0xD801); context.Add(0xDC12); - assert(context.CharIsDeadkey() == FALSE); + test_assert(context.CharIsDeadkey() == FALSE); context.Reset(); context.Add(u'a'); context.Add(u'\uffff'); context.Add(u'\u0008'); - assert(context.CharIsDeadkey() == FALSE); + test_assert(context.CharIsDeadkey() == FALSE); context.Reset(); context.Add(u'a'); context.Add(u'\uffff'); context.Add(u'\u0014'); context.Add(u'\u0001'); - assert(context.CharIsDeadkey() == FALSE); + test_assert(context.CharIsDeadkey() == FALSE); context.Reset(); context.Add(u'\uffff'); context.Add(u'\u0008'); context.Add(u'\u0001'); - assert(context.CharIsDeadkey() == TRUE); + test_assert(context.CharIsDeadkey() == TRUE); context.Reset(); context.Add(u'a'); context.Add(u'\uffff'); context.Add(u'\u0008'); context.Add(u'\u0001'); - assert(context.CharIsDeadkey() == TRUE); + test_assert(context.CharIsDeadkey() == TRUE); } void test_CharIsSurrogatePair() { KMX_Context context; - assert(context.CharIsSurrogatePair() == FALSE); + test_assert(context.CharIsSurrogatePair() == FALSE); context.Reset(); context.Add(u'a'); - assert(context.CharIsSurrogatePair() == FALSE); + test_assert(context.CharIsSurrogatePair() == FALSE); context.Reset(); context.Add(u'a'); context.Add(u'a'); - assert(context.CharIsSurrogatePair() == FALSE); + test_assert(context.CharIsSurrogatePair() == FALSE); context.Reset(); context.Add(u'\uffff'); context.Add(u'\u0008'); context.Add(u'\u0001'); - assert(context.CharIsSurrogatePair() == FALSE); + test_assert(context.CharIsSurrogatePair() == FALSE); context.Reset(); context.Add(0xD801); - assert(context.CharIsSurrogatePair() == FALSE); + test_assert(context.CharIsSurrogatePair() == FALSE); // We don't support little endian surrogate pairs (cf #5111) context.Reset(); context.Add(0xDC12); context.Add(0xD801); - assert(context.CharIsSurrogatePair() == FALSE); + test_assert(context.CharIsSurrogatePair() == FALSE); context.Reset(); context.Add(0xD801); context.Add(0xDC12); - assert(context.CharIsSurrogatePair() == TRUE); + test_assert(context.CharIsSurrogatePair() == TRUE); } void @@ -114,54 +114,54 @@ test_Set() { context.Set(u"abc"); context.Get((KMX_WCHAR*)&buf, bufsize); - assert_string_equal(buf, u"abc"); + test_assert_string_equal(buf, u"abc"); context.Reset(); context.Set(u"\uFFFF\u0008\u0001abc"); context.Get((KMX_WCHAR *)&buf, bufsize); - assert_string_equal(buf, u"\uFFFF\u0008\u0001abc"); + test_assert_string_equal(buf, u"\uFFFF\u0008\u0001abc"); // test that we can set MAXCONTEXT-1 characters context.Reset(); auto text = u"\uFFFF\u0008\u0001abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefgh"; - assert_equal(u16len(text), MAXCONTEXT - 1); + test_assert_equal(u16len(text), MAXCONTEXT - 1); context.Set(text); context.Get((KMX_WCHAR *)&buf, bufsize); - assert_string_equal(buf, u"\uFFFF\u0008\u0001abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefgh"); + test_assert_string_equal(buf, u"\uFFFF\u0008\u0001abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefgh"); // test that setting > MAXCONTEXT-1 characters will only set the last MAXCONTEXT-1 characters context.Reset(); text = u"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl"; - assert_equal(u16len(text), MAXCONTEXT); + test_assert_equal(u16len(text), MAXCONTEXT); context.Set(text); context.Get((KMX_WCHAR *)&buf, bufsize); - assert_string_equal(buf, u"bcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl"); - assert_equal(u16len(buf), MAXCONTEXT - 1); + test_assert_string_equal(buf, u"bcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl"); + test_assert_equal(u16len(buf), MAXCONTEXT - 1); // test that setting > MAXCONTEXT-1 characters will set last characters and not split the deadkey context.Reset(); text = u"\uFFFF\u0008\u0001abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghi"; - assert_equal(u16len(text), MAXCONTEXT); + test_assert_equal(u16len(text), MAXCONTEXT); context.Set(text); context.Get((KMX_WCHAR *)&buf, bufsize); - assert_string_equal(buf, u"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghi"); - assert_equal(u16len(buf), MAXCONTEXT - 3); + test_assert_string_equal(buf, u"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghi"); + test_assert_equal(u16len(buf), MAXCONTEXT - 3); // test that setting the context replaces the previous context context.Reset(); context.Set(u"\uFFFF\u0008\u0001abc"); context.Set(u"def"); context.Get((KMX_WCHAR *)&buf, bufsize); - assert_string_equal(buf, u"def"); + test_assert_string_equal(buf, u"def"); // test that setting the context completely replaces the existing context context.Reset(); text = u"\uFFFF\u0008\u0001abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefgh"; - assert_equal(u16len(text), MAXCONTEXT-1); + test_assert_equal(u16len(text), MAXCONTEXT-1); context.Set(text); context.Set(u"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefgh1"); context.Get((KMX_WCHAR *)&buf, bufsize); - assert_string_equal(buf, u"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefgh1"); + test_assert_string_equal(buf, u"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefgh1"); } void @@ -172,19 +172,19 @@ test_Add() { context.Add(u'a'); context.Get((KMX_WCHAR *)&buf, bufsize); - assert_string_equal(buf, u"a"); + test_assert_string_equal(buf, u"a"); context.Reset(); context.Add(0xD801); context.Get((KMX_WCHAR *)&buf, bufsize); - assert_equal(u16len(buf), 1); - assert_equal(buf[0], 0xD801); + test_assert_equal(u16len(buf), 1); + test_assert_equal(buf[0], 0xD801); context.Reset(); context.Add(0xD801); context.Add(0xDC12); context.Get((KMX_WCHAR *)&buf, bufsize); - assert_string_equal(buf, u"\U00010412"); + test_assert_string_equal(buf, u"\U00010412"); context.Reset(); context.Add(u'\uFFFF'); @@ -192,25 +192,25 @@ test_Add() { context.Add(u'\u0001'); context.Add(u'a'); context.Get((KMX_WCHAR *)&buf, bufsize); - assert_string_equal(buf, u"\uFFFF\u0008\u0001a"); + test_assert_string_equal(buf, u"\uFFFF\u0008\u0001a"); context.Reset(); auto text = u"\uFFFF\u0008\u0001abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg"; - assert_equal(u16len(text), MAXCONTEXT - 2); + test_assert_equal(u16len(text), MAXCONTEXT - 2); context.Set(text); context.Add(u'1'); context.Get((KMX_WCHAR *)&buf, bufsize); - assert_string_equal(buf, u"\uFFFF\u0008\u0001abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg1"); - assert_equal(u16len(buf), MAXCONTEXT - 1); + test_assert_string_equal(buf, u"\uFFFF\u0008\u0001abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg1"); + test_assert_equal(u16len(buf), MAXCONTEXT - 1); context.Reset(); text = u"\uFFFF\u0008\u0001abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefgh"; - assert_equal(u16len(text), MAXCONTEXT - 1); + test_assert_equal(u16len(text), MAXCONTEXT - 1); context.Set(text); context.Add(u'1'); context.Get((KMX_WCHAR *)&buf, bufsize); - assert_string_equal(buf, u"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefgh1"); - assert_equal(u16len(buf), MAXCONTEXT - 3); + test_assert_string_equal(buf, u"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefgh1"); + test_assert_equal(u16len(buf), MAXCONTEXT - 3); } void @@ -222,25 +222,25 @@ test_Delete() { context.Reset(); context.Delete(); context.Get((KMX_WCHAR *)&buf, bufsize); - assert_string_equal(buf, u""); + test_assert_string_equal(buf, u""); context.Reset(); context.Set(u"abc"); context.Delete(); context.Get((KMX_WCHAR *)&buf, bufsize); - assert_string_equal(buf, u"ab"); + test_assert_string_equal(buf, u"ab"); context.Reset(); context.Set(u"ab\U00010412"); context.Delete(); context.Get((KMX_WCHAR *)&buf, bufsize); - assert_string_equal(buf, u"ab"); + test_assert_string_equal(buf, u"ab"); context.Reset(); context.Set(u"ab\uFFFF\u0008\u0001"); context.Delete(); context.Get((KMX_WCHAR *)&buf, bufsize); - assert_string_equal(buf, u"ab"); + test_assert_string_equal(buf, u"ab"); } void @@ -251,81 +251,81 @@ test_Buf() { context.Set(u"abc"); auto last = context.Buf(0); auto p = context.Buf(1); - assert_equal(p, last - 1); + test_assert_equal(p, last - 1); p = context.Buf(2); - assert_equal(p, last - 2); + test_assert_equal(p, last - 2); p = context.Buf(3); - assert_equal(p, last - 3); + test_assert_equal(p, last - 3); p = context.Buf(4); - assert(p == NULL); + test_assert(p == NULL); p = context.Buf(10); - assert(p == NULL); + test_assert(p == NULL); p = context.Buf(-1); - assert_equal(p, last); + test_assert_equal(p, last); context.Reset(); context.Set(u"ab\U00010412"); last = context.Buf(0); p = context.Buf(1); - assert_equal(p, last - 2); + test_assert_equal(p, last - 2); p = context.Buf(2); - assert_equal(p, last - 3); + test_assert_equal(p, last - 3); p = context.Buf(3); - assert_equal(p, last - 4); + test_assert_equal(p, last - 4); p = context.Buf(4); - assert(p == NULL); + test_assert(p == NULL); p = context.Buf(5); - assert(p == NULL); + test_assert(p == NULL); p = context.Buf(10); - assert(p == NULL); + test_assert(p == NULL); context.Reset(); context.Set(u"ab\uFFFF\u0008\u0001"); last = context.Buf(0); p = context.Buf(1); - assert_equal(p, last - 3); + test_assert_equal(p, last - 3); p = context.Buf(2); - assert_equal(p, last - 4); + test_assert_equal(p, last - 4); p = context.Buf(3); - assert_equal(p, last - 5); + test_assert_equal(p, last - 5); p = context.Buf(4); - assert(p == NULL); + test_assert(p == NULL); p = context.Buf(5); - assert(p == NULL); + test_assert(p == NULL); p = context.Buf(6); - assert(p == NULL); + test_assert(p == NULL); context.Reset(); auto text = u"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk"; - assert_equal(u16len(text), MAXCONTEXT - 1); + test_assert_equal(u16len(text), MAXCONTEXT - 1); context.Set(text); last = context.Buf(0); p = context.Buf(1); - assert_equal(p, last - 1); + test_assert_equal(p, last - 1); p = context.Buf(MAXCONTEXT - 1); - assert_equal(p, last - (MAXCONTEXT - 1)); + test_assert_equal(p, last - (MAXCONTEXT - 1)); p = context.Buf(MAXCONTEXT); - assert(p == NULL); + test_assert(p == NULL); p = context.Buf(MAXCONTEXT + 1); - assert(p == NULL); + test_assert(p == NULL); } void @@ -336,97 +336,97 @@ test_BufMax() { context.Set(u"abc"); auto last = context.Buf(0); auto p = context.BufMax(0); - assert_equal(p, last); + test_assert_equal(p, last); p = context.BufMax(1); - assert_equal(p, last - 1); + test_assert_equal(p, last - 1); p = context.BufMax(2); - assert_equal(p, last - 2); + test_assert_equal(p, last - 2); p = context.BufMax(3); - assert_equal(p, last - 3); + test_assert_equal(p, last - 3); p = context.BufMax(4); - assert_equal(p, last - 3); + test_assert_equal(p, last - 3); p = context.BufMax(5); - assert_equal(p, last - 3); + test_assert_equal(p, last - 3); p = context.BufMax(10); - assert_equal(p, last - 3); + test_assert_equal(p, last - 3); p = context.BufMax(-1); - assert_equal(p, last); + test_assert_equal(p, last); context.Reset(); context.Set(u"ab\U00010412"); last = context.Buf(0); p = context.BufMax(0); - assert_equal(p, last); + test_assert_equal(p, last); p = context.BufMax(1); - assert_equal(p, last); + test_assert_equal(p, last); p = context.BufMax(2); - assert_equal(p, last - 2); + test_assert_equal(p, last - 2); p = context.BufMax(3); - assert_equal(p, last - 3); + test_assert_equal(p, last - 3); p = context.BufMax(4); - assert_equal(p, last - 4); + test_assert_equal(p, last - 4); p = context.BufMax(5); - assert_equal(p, last - 4); + test_assert_equal(p, last - 4); p = context.BufMax(10); - assert_equal(p, last - 4); + test_assert_equal(p, last - 4); context.Reset(); context.Set(u"ab\uFFFF\u0008\u0001"); last = context.Buf(0); p = context.BufMax(0); - assert_equal(p, last); + test_assert_equal(p, last); p = context.BufMax(1); - assert_equal(p, last); + test_assert_equal(p, last); p = context.BufMax(2); - assert_equal(p, last); + test_assert_equal(p, last); p = context.BufMax(3); - assert_equal(p, last - 3); + test_assert_equal(p, last - 3); p = context.BufMax(4); - assert_equal(p, last - 4); + test_assert_equal(p, last - 4); p = context.BufMax(5); - assert_equal(p, last - 5); + test_assert_equal(p, last - 5); p = context.BufMax(6); - assert_equal(p, last - 5); + test_assert_equal(p, last - 5); p = context.BufMax(10); - assert_equal(p, last - 5); + test_assert_equal(p, last - 5); context.Reset(); auto text = u"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk"; - assert_equal(u16len(text), MAXCONTEXT - 1); + test_assert_equal(u16len(text), MAXCONTEXT - 1); context.Set(text); last = context.Buf(0); p = context.BufMax(1); - assert_equal(p, last - 1); + test_assert_equal(p, last - 1); p = context.BufMax(MAXCONTEXT - 1); - assert_equal(p, last - (MAXCONTEXT - 1)); + test_assert_equal(p, last - (MAXCONTEXT - 1)); p = context.BufMax(MAXCONTEXT); - assert_equal(p, last - MAXCONTEXT + 1); + test_assert_equal(p, last - MAXCONTEXT + 1); p = context.BufMax(MAXCONTEXT + 1); - assert_equal(p, last - MAXCONTEXT + 1); + test_assert_equal(p, last - MAXCONTEXT + 1); } constexpr const auto help_str = "\ diff --git a/core/tests/unit/kmnkbd/test_kmx_xstring.cpp b/core/tests/unit/kmnkbd/kmx_xstring.tests.cpp similarity index 83% rename from core/tests/unit/kmnkbd/test_kmx_xstring.cpp rename to core/tests/unit/kmnkbd/kmx_xstring.tests.cpp index 157a744ae72..529e2308103 100644 --- a/core/tests/unit/kmnkbd/test_kmx_xstring.cpp +++ b/core/tests/unit/kmnkbd/kmx_xstring.tests.cpp @@ -48,32 +48,32 @@ void test_decxstr() { p_start = (PKMX_WCHAR) C_CODE_ANY(u"\u0002"); p = p_start + 2; // \u0002 in the middle of the otherwise valid UC_SENTINEL CODE_ANY sequence q = decxstr(p, p_start); - assert(q == p - 1); + test_assert(q == p - 1); p_start = (PKMX_WCHAR)u"abc" C_CODE_ANY(u"\u0001"); p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p-1)); + test_assert(q == (p-1)); p_start = (PKMX_WCHAR) C_CODE_ANY(u"\u0001"); p = p_start + 3; // nul, i.e. at the end of the valid UC_SENTINEL CODE_ANY sequence q = decxstr(p, p_start); - assert(q == p - 3); + test_assert(q == p - 3); p_start = (PKMX_WCHAR)u"abc" C_CODE_ANY(u"\u0001") u"\u0014"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p-3)); + test_assert(q == (p-3)); p_start = (PKMX_WCHAR)u"abc" C_CODE_ANY(u"\u0001") U_1F609_WINKING_FACE; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p-1)); + test_assert(q == (p-1)); p_start = (PKMX_WCHAR)u"abc" C_CODE_ANY(u"\u0001") U_1F609_WINKING_FACE; p = find_ptr_to_last_character(p_start)-1; q = decxstr(p, p_start); - assert(q == (p-3)); + test_assert(q == (p-3)); // ------------------------------------------------------------------------------------------------------------------------------------------------------- // even more tests: check for use UC_SENTINEL with F000 @@ -82,47 +82,47 @@ void test_decxstr() { p_start = (PKMX_WCHAR)u"abc" U_UC_SENTINEL u"\uF000"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p-1)); + test_assert(q == (p-1)); p_start = (PKMX_WCHAR)u"abc" U_UC_SENTINEL u"\uF000d"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 1)); + test_assert(q == (p - 1)); p_start = (PKMX_WCHAR)u"abc" U_UC_SENTINEL u"\uF000\u0001"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 1)); + test_assert(q == (p - 1)); p_start = (PKMX_WCHAR)u"abc" U_UC_SENTINEL u"\uF000\u0002"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 1)); + test_assert(q == (p - 1)); p_start = (PKMX_WCHAR)u"abc" U_UC_SENTINEL u"\uF000\u0001\u0001"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 1)); + test_assert(q == (p - 1)); p_start = (PKMX_WCHAR)u"abc" U_UC_SENTINEL u"\uF000\u0002\u0001"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 1)); + test_assert(q == (p - 1)); p_start = (PKMX_WCHAR)u"abc" U_UC_SENTINEL u"\uF000\u0001\u0001d"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 1)); + test_assert(q == (p - 1)); p_start = (PKMX_WCHAR)u"abc" U_UC_SENTINEL u"\uF000\u0002\u0001\u0001"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 1)); + test_assert(q == (p - 1)); p_start = (PKMX_WCHAR)u"abc" U_UC_SENTINEL u"\uF000\u0002\u0001\u0001d"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 1)); + test_assert(q == (p - 1)); // ------------------------------------------------------------------------------------------------------------------------------------------------------- // more tests: check if we might end up left of pstart @@ -131,96 +131,96 @@ void test_decxstr() { p_start = (PKMX_WCHAR)u"\u0001"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (NULL )); + test_assert(q == (NULL )); p_start = (PKMX_WCHAR)u"\u0001\u0001"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 1)); + test_assert(q == (p - 1)); p_start = (PKMX_WCHAR)u"\u0001\u0001\u0001"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 1)); + test_assert(q == (p - 1)); p_start = (PKMX_WCHAR) U_UC_SENTINEL U_CODE_ANY; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 1)); + test_assert(q == (p - 1)); // Note: this test puts the pointer into the middle of a valid `UC_SENTINEL CODE_ANY ` // so we should expect it to not be properly understood. p_start = (PKMX_WCHAR) C_CODE_ANY(u"\u0001"); p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 1)); + test_assert(q == (p - 1)); p_start = (PKMX_WCHAR) C_CODE_ANY(u"\u0001") u"\u0001"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 3)); + test_assert(q == (p - 3)); p_start = (PKMX_WCHAR)u"\u0014"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (NULL)); + test_assert(q == (NULL)); p_start = (PKMX_WCHAR)u"\u0014\u0014"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 1)); + test_assert(q == (p - 1)); p_start = (PKMX_WCHAR)u"\u0014\u0014\u0014"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 1)); + test_assert(q == (p - 1)); p_start = (PKMX_WCHAR)u"\u0014\u0014\u0014\u0014"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 1)); + test_assert(q == (p - 1)); p_start = (PKMX_WCHAR)u"\u0014\u0014\u0014\u0014\u0014"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 1)); + test_assert(q == (p - 1)); p_start = (PKMX_WCHAR)u"\u0014\u0014\u0014\u0014\u0014\u0014"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 1)); + test_assert(q == (p - 1)); p_start = (PKMX_WCHAR) U_UC_SENTINEL u"\u0014"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 1)); + test_assert(q == (p - 1)); // 0x14 = CODE_IFOPT which has 3 parameters, so this is an invalid, so // go back only one char p_start = (PKMX_WCHAR) U_UC_SENTINEL u"\u0014\u0014"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 1)); + test_assert(q == (p - 1)); p_start = (PKMX_WCHAR) U_UC_SENTINEL u"\u0014\u0014\u0014"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 1)); + test_assert(q == (p - 1)); p_start = (PKMX_WCHAR) C_CODE_IFOPT(u"\u0014", u"\u0014", u"\u0014"); p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 1)); + test_assert(q == (p - 1)); p_start = (PKMX_WCHAR) C_CODE_IFOPT(u"\u0014", u"\u0014", u"\u0014") u"\u0014"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 5)); + test_assert(q == (p - 5)); p_start = (PKMX_WCHAR) C_CODE_IFOPT(u"\u0014", u"\u0014", u"\u0014") u"\u0014\u0014"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 1)); + test_assert(q == (p - 1)); // ------------------------------------------------------------------------------------------------------------------------------------------------------- // -- differences in pointer movement for new decxstr ---------------------------------------------------------------------------------------------------- @@ -232,25 +232,25 @@ void test_decxstr() { p_start = (PKMX_WCHAR)u"abc" U_UC_SENTINEL U_CODE_EXTENDED u"\u0001" u"\u0001" u"d"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 4) ); + test_assert(q == (p - 4) ); //runs OK with NEW version of decxstr (with CODE_SWITCH pointer moves 2 ( 3 altogether) p_start = (PKMX_WCHAR)u"abc" C_CODE_SWITCH(u"\u0001") u"d"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 3) ); + test_assert(q == (p - 3) ); // runs OK with NEW version of decxstr (with CODE_CLEARCONTEXT pointer moves 0 ( 1 altogether) p_start = (PKMX_WCHAR)u"abc" C_CODE_CLEARCONTEXT() u"\u0001d"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 1) ); + test_assert(q == (p - 1) ); // runs OK with OLD version and NEW version of decxstr p_start = (PKMX_WCHAR)u"abc" C_CODE_CLEARCONTEXT() u"\u0001"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 2) ); + test_assert(q == (p - 2) ); // --------------------------------------------------------------------------------------- // ---- character @@ -260,7 +260,7 @@ void test_decxstr() { p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 1) ); + test_assert(q == (p - 1) ); // --------------------------------------------------------------------------------------- // ---- p <= pstart @@ -269,12 +269,12 @@ void test_decxstr() { p_start = (PKMX_WCHAR)u"abc"; p = find_ptr_to_last_character(p_start)-5; q = decxstr(p, p_start); - assert(q == (NULL) ); + test_assert(q == (NULL) ); p_start = (PKMX_WCHAR)u"a"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (NULL) ); + test_assert(q == (NULL) ); // --------------------------------------------------------------------------------------- // ---- p= UC_SENTINEL_EXTENDED @@ -283,22 +283,22 @@ void test_decxstr() { p_start = (PKMX_WCHAR)u"abc" C_CODE_EXTENDED(u"\u0001" u"\u0002" u"\u0003" u"\u0004" U_CODE_EXTENDEDEND); p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 1) ); + test_assert(q == (p - 1) ); p_start = (PKMX_WCHAR)u"abc" C_CODE_EXTENDED(u"\u0001" u"\u0002" u"\u0003" u"\u0004" u"\u0005" u"\u0006" u"\u0007" u"\u0008" U_CODE_EXTENDEDEND); p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 1) ); + test_assert(q == (p - 1) ); p_start = (PKMX_WCHAR)u"abc" C_CODE_EXTENDED(u"\u0001" u"\u0002" u"\u0003" u"\u0004" u"\u0005" U_CODE_EXTENDEDEND) u"d"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 8) ); + test_assert(q == (p - 8) ); p_start = (PKMX_WCHAR)u"abc" C_CODE_EXTENDED(u"\u0001" u"\u0002" u"\u0003" u"\u0004" u"\u0005" u"\u0006" u"\u0007" u"\u0008" U_CODE_EXTENDEDEND) u"d"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 11) ); + test_assert(q == (p - 11) ); // --------------------------------------------------------------------------------------- // ---- Surrogate Pair @@ -307,32 +307,32 @@ void test_decxstr() { p_start = (PKMX_WCHAR)u"abc" U_1F609_WINKING_FACE; p = find_ptr_to_last_character(p_start)-1; q = decxstr(p, p_start); - assert(q == (p - 1) ); + test_assert(q == (p - 1) ); p_start = (PKMX_WCHAR)u"abc" U_1F609_WINKING_FACE; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 1) ); + test_assert(q == (p - 1) ); p_start = (PKMX_WCHAR)u"abc" U_1F609_WINKING_FACE u"d"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 2) ); + test_assert(q == (p - 2) ); p_start = (PKMX_WCHAR)u"abc" U_UC_SENTINEL U_1F609_WINKING_FACE; p = find_ptr_to_last_character(p_start)-1; q = decxstr(p, p_start); - assert(q == (p-1)); + test_assert(q == (p-1)); p_start = (PKMX_WCHAR)u"abc" U_UC_SENTINEL U_1F609_WINKING_FACE; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p-1)); + test_assert(q == (p-1)); p_start = (PKMX_WCHAR)u"abc" U_UC_SENTINEL U_1F609_WINKING_FACE u"d"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p-2)); + test_assert(q == (p-2)); // --------------------------------------------------------------------------------------- // ---- CODE_ // --------------------------------------------------------------------------------------- @@ -351,16 +351,16 @@ void test_decxstr() { p_start = (PKMX_WCHAR) str.c_str(); p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 1)); // this is in the middle of the sequence so it should always go back a single unit + test_assert(q == (p - 1)); // this is in the middle of the sequence so it should always go back a single unit str.append(u"a"); p_start = (PKMX_WCHAR)str.c_str(); p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); if (size < 0) { - assert(q == (p - 1)); // this is in the middle of the sequence so it should always go back a single unit + test_assert(q == (p - 1)); // this is in the middle of the sequence so it should always go back a single unit } else { - assert(q == (p - size - 2)); /* UC_SENTINEL + code + (CODE__SIZE = number of params) */ + test_assert(q == (p - size - 2)); /* UC_SENTINEL + code + (CODE__SIZE = number of params) */ } } @@ -371,87 +371,87 @@ void test_decxstr() { p_start = (PKMX_WCHAR)u"abc" C_CODE_ANY(u"\u0001") u"d"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 3) ); + test_assert(q == (p - 3) ); p_start = (PKMX_WCHAR)u"abc" C_CODE_INDEX(u"\u0001", u"\u0001d"); p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 4) ); + test_assert(q == (p - 4) ); p_start = (PKMX_WCHAR)u"abc" C_CODE_CONTEXT() u"\u0001d"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 1) ); + test_assert(q == (p - 1) ); p_start = (PKMX_WCHAR)u"abc" C_CODE_NUL() u"\u0001d"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 1) ); + test_assert(q == (p - 1) ); p_start = (PKMX_WCHAR)u"abc" C_CODE_USE(u"\u0001") u"d"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 3) ); + test_assert(q == (p - 3) ); p_start = (PKMX_WCHAR)u"abc" C_CODE_RETURN() u"\u0001d"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 1) ); + test_assert(q == (p - 1) ); p_start = (PKMX_WCHAR)u"abc" C_CODE_BEEP() u"\u0001d"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 1) ); + test_assert(q == (p - 1) ); p_start = (PKMX_WCHAR)u"abc" C_CODE_DEADKEY(u"\u0001") u"d"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 3) ); + test_assert(q == (p - 3) ); p_start = (PKMX_WCHAR)u"abc" C_CODE_CALL(u"\u0001") u"d"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 3) ); + test_assert(q == (p - 3) ); p_start = (PKMX_WCHAR)u"abc" C_CODE_CONTEXTEX(u"\u0001") u"d"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 3) ); + test_assert(q == (p - 3) ); p_start = (PKMX_WCHAR)u"abc" C_CODE_NOTANY(u"\u0001") u"d"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 3) ); + test_assert(q == (p - 3) ); p_start = (PKMX_WCHAR)u"abc" C_CODE_SETOPT(u"\u0001", u"\u0001") u"d"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 4) ); + test_assert(q == (p - 4) ); p_start = (PKMX_WCHAR)u"abc" C_CODE_IFOPT(u"\u0001", u"\u0001", u"\u0001") u"d"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 5) ); + test_assert(q == (p - 5) ); p_start = (PKMX_WCHAR)u"abc" C_CODE_SAVEOPT(u"\u0001") u"d"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 3) ); + test_assert(q == (p - 3) ); p_start = (PKMX_WCHAR)u"abc" C_CODE_RESETOPT(u"\u0001") u"d"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 3) ); + test_assert(q == (p - 3) ); p_start = (PKMX_WCHAR)u"abc" C_CODE_IFSYSTEMSTORE(u"\u0001", u"\u0001", u"\u0001") u"d"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 5) ); + test_assert(q == (p - 5) ); p_start = (PKMX_WCHAR)u"abc" C_CODE_SETSYSTEMSTORE(u"\u0001", u"\u0001") u"d"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 4) ); + test_assert(q == (p - 4) ); // --------------------------------------------------------------------------------------- // ---- other @@ -460,38 +460,38 @@ void test_decxstr() { p_start = (PKMX_WCHAR)u"abc" C_CODE_INDEX(u"d", u"e") u"f\u0001"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 1) ); + test_assert(q == (p - 1) ); p_start = (PKMX_WCHAR)u"abc" U_UC_SENTINEL; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 1) ); + test_assert(q == (p - 1) ); // pointer in the middle of a surrogate pair, so beware! p_start = (PKMX_WCHAR) U_UC_SENTINEL U_1F609_WINKING_FACE; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 1) ); + test_assert(q == (p - 1) ); p_start = (PKMX_WCHAR)u"\u0014d"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 1) ); + test_assert(q == (p - 1) ); p_start = (PKMX_WCHAR) U_UC_SENTINEL; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == NULL ); + test_assert(q == NULL ); p_start = (PKMX_WCHAR) U_UC_SENTINEL u"d"; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == (p - 1) ); + test_assert(q == (p - 1) ); p_start = (PKMX_WCHAR) U_UC_SENTINEL U_UC_SENTINEL; p = find_ptr_to_last_character(p_start); q = decxstr(p, p_start); - assert(q == p - 1 ); + test_assert(q == p - 1 ); } @@ -508,27 +508,27 @@ void test_decxstr() { // --- Test for empty string ------------------------------------------------------------------------------------------------------------------------ p = (PKMX_WCHAR) u"\0"; q = incxstr(p); - assert(q == p); + test_assert(q == p); // --- Test for character --------------------------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) u"\u1234"; q = incxstr(p); - assert(q == p+1); + test_assert(q == p+1); // --- Test for surrogate pair ---------------------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p+2); + test_assert(q == p+2); // --- Test for one ----------------------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR)u"\u0012"; q = incxstr(p); - assert(q == p + 1); + test_assert(q == p + 1); // --- Test for FFFF only ------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) U_UC_SENTINEL; q = incxstr(p); - assert(q == p + 1); + test_assert(q == p + 1); // -------------------------------------------------------------------------------------------------------------------------------------------------- // ---- UC_SENTINEL WITHOUT \0 ---------------------------------------------------------------------------------------------------------------------- @@ -537,102 +537,102 @@ void test_decxstr() { // --- Test for FFFF +CODE_INDEX -------------------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_INDEX(u"\u0002", u"\u0001"); q = incxstr(p); - assert(q == p + 4); + test_assert(q == p + 4); // --- Test for FFFF +CODE_USE ---------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_USE(u"\u0001"); q = incxstr(p); - assert(q == p + 3); + test_assert(q == p + 3); // --- Test for FFFF +CODE_DEADKEY ------------------------------------------------------------------------------------------------------------------ p = (PKMX_WCHAR) C_CODE_DEADKEY(u"\u0001"); q = incxstr(p); - assert(q == p + 3); + test_assert(q == p + 3); // --- Test for FFFF CODE_EXTENDED -------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_EXTENDED(u"\u0001" u"\u0002" u"\u0003" u"\u0004" u"\u0005" u"\u0006" U_CODE_EXTENDEDEND); q = incxstr(p); - assert(q == p + 9); + test_assert(q == p + 9); // --- Test for FFFF +CODE_CLEARCONTEXT ------------------------------------------------------------------------------------------------------------ p = (PKMX_WCHAR) C_CODE_CLEARCONTEXT() u"\u0001"; q = incxstr(p); - assert(q == p + 2); + test_assert(q == p + 2); // --- Test for FFFF +CODE_CALL ---------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_CALL(u"\u0001"); q = incxstr(p); - assert(q == p + 3); + test_assert(q == p + 3); // --- Test for FFFF +CODE_CONTEXTEX --------------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_CONTEXTEX(u"\u0001"); q = incxstr(p); - assert(q == p + 3); + test_assert(q == p + 3); // --- Test for FFFF +CODE_IFOPT ------------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_IFOPT(u"\u0002", u"\u0002", u"\u0001"); q = incxstr(p); - assert(q == p + 5); + test_assert(q == p + 5); // --- Test for FFFF +CODE_IFSYSTEMSTORE ------------------------------------------------------------------------------------------ p = (PKMX_WCHAR) C_CODE_IFSYSTEMSTORE(u"\u0002", u"\u0002", u"\u0001"); q = incxstr(p); - assert(q == p + 5); + test_assert(q == p + 5); // --- Test for FFFF +CODE_SETOPT ---------------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_SETOPT(u"\u0002", u"\u0001"); q = incxstr(p); - assert(q == p + 4); + test_assert(q == p + 4); // --- Test for FFFF +CODE_SETSYSTEMRESTORE --------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_SETSYSTEMSTORE(u"\u0002", u"\u0001"); q = incxstr(p); - assert(q == p + 4); + test_assert(q == p + 4); // --- Test for FFFF +CODE_RESETOPT ----------------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_RESETOPT(u"\u0001"); q = incxstr(p); - assert(q == p + 3); + test_assert(q == p + 3); // --- Test for FFFF +CODE_SAVEOPT ----------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_SAVEOPT(u"\u0001"); q = incxstr(p); - assert(q == p + 3 ); + test_assert(q == p + 3 ); // --- Test for FFFF +default ---------------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_NUL(); q = incxstr(p); - assert(q == p + 2); + test_assert(q == p + 2); // --- Test for FFFF + CODE_ANY ----------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_ANY(u"\u0001"); q = incxstr(p); - assert(q == p + 3 ); + test_assert(q == p + 3 ); // --- Test for FFFF + CODE_CONTEXT ----------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_CONTEXT() u"\u0001"; q = incxstr(p); - assert(q == p + 2 ); + test_assert(q == p + 2 ); // --- Test for FFFF + CODE_RETURN ----------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_RETURN() u"\u0001"; q = incxstr(p); - assert(q == p + 2 ); + test_assert(q == p + 2 ); // --- Test for FFFF + CODE_BEEP ----------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_BEEP() u"\u0001"; q = incxstr(p); - assert(q == p + 2 ); + test_assert(q == p + 2 ); // --- Test for FFFF + CODE_SWITCH ----------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_SWITCH(u"\u0001"); q = incxstr(p); - assert(q == p + 3 ); + test_assert(q == p + 3 ); // --- Test for FFFF + NOTANY ----------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_NOTANY(u"\u0001"); q = incxstr(p); - assert(q == p + 3 ); + test_assert(q == p + 3 ); // -------------------------------------------------------------------------------------------------------------------------------------------------- // ---- UC_SENTINEL WITH \0 AT DIFFERENT POSITIONS -------------------------------------------------------------------------------------------------- @@ -641,52 +641,52 @@ void test_decxstr() { // --- Test for FFFF + control (earlier p+1) with \0 after first position --------------- unit test failed with old version of incxstr() ----- p = (PKMX_WCHAR) U_UC_SENTINEL u"\0\u0008\u0001"; q = incxstr(p); - assert(q == p+1); + test_assert(q == p+1); // --- Test for FFFF +control (earlier p+1) with \0 after second position --------- unit test failed with old version of incxstr() ----- p = (PKMX_WCHAR) C_CODE_DEADKEY(u"\0") u"\u0001"; q = incxstr(p); - assert(q == p+2); + test_assert(q == p+2); // --- Test for FFFF +control (earlier p+1) with \0 after third position ----- unit test failed with old version of incxstr() ----- p = (PKMX_WCHAR) C_CODE_DEADKEY(u"\u0001") u"\0"; q = incxstr(p); - assert(q == p+3) + test_assert(q == p+3) // --- Test for FFFF +control (earlier p+2) with \0 after fourth position ----- unit test failed with old version of incxstr() ---- p = (PKMX_WCHAR) C_CODE_INDEX(u"\u0001", u"\u0001") u"\0"; q = incxstr(p); - assert(q == p+4); + test_assert(q == p+4); // --- Test for FFFF +control (earlier p+3) with \0 after fifth position ----- unit test failed with old version of incxstr() --------- p = (PKMX_WCHAR) C_CODE_IFOPT(u"\u0001", u"\u0001", u"\u0001") u"\0"; q = incxstr(p); - assert(q == p+5); + test_assert(q == p+5); // --- Test for FFFF +control CODE_EXTENDED ----- (earlier p+n) with \0 after 6. position ----- unit test failed with old version of incxstr() ----- p = (PKMX_WCHAR) C_CODE_EXTENDED(u"\u0001" u"\u0002" u"\u0003" u"\u0004" u"\0" u"\u0005" u"\u0006" u"\u0007" U_CODE_EXTENDEDEND); q = incxstr(p); - assert(q == p + 6); + test_assert(q == p + 6); // --- Test for FFFF +control CODE_EXTENDED ----- (earlier p+n) with \0 after 7. position ----- unit test failed with old version of incxstr() p = (PKMX_WCHAR) C_CODE_EXTENDED(u"\u0001" u"\u0002" u"\u0003" u"\u0004" u"\u0005" u"\0" u"\u0006" u"\u0007" U_CODE_EXTENDEDEND); q = incxstr(p); - assert(q == p + 7); + test_assert(q == p + 7); // --- Test for FFFF +control CODE_EXTENDED ----- (earlier p+n) with \0 after 8. position ----- unit test failed with old version of incxstr() ---------- p = (PKMX_WCHAR) C_CODE_EXTENDED(u"\u0001" u"\u0002" u"\u0003" u"\u0004" u"\u0005" u"\u0006" u"\0" u"\u0007" U_CODE_EXTENDEDEND); q = incxstr(p); - assert(q == p + 8); + test_assert(q == p + 8); // --- Test for FFFF +control CODE_EXTENDED ----- (earlier p+n) with \0 after 9. position ----- unit test failed with old version of incxstr() --- p = (PKMX_WCHAR) C_CODE_EXTENDED(u"\u0001" u"\u0002" u"\u0003" u"\u0004" u"\u0005" u"\u0006" u"\u0007" u"\0" U_CODE_EXTENDEDEND); q = incxstr(p); - assert(q == p + 9); + test_assert(q == p + 9); // --- Test for FFFF +control CODE_EXTENDED ----- (earlier p+n) with \0 after 10. position ----- unit test failed with old version of incxstr() ----------- p = (PKMX_WCHAR) C_CODE_EXTENDED(u"\u0001" u"\u0002" u"\u0003" u"\u0004" u"\u0005" u"\u0006" u"\u0007" U_CODE_EXTENDEDEND) u"\0"; q = incxstr(p); - assert(q == p + 10); + test_assert(q == p + 10); // -------------------------------------------------------------------------------------------------------------------------------------------------- // ---- UC_SENTINEL, INCOMPLETE & UNUSUAL SEQUENCES-------------------------------------------------------------------------------------------------- @@ -695,22 +695,22 @@ void test_decxstr() { // --- Test for FFFF + \0 -------------------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) U_UC_SENTINEL u"\0"; q = incxstr(p); - assert(q == p + 1); + test_assert(q == p + 1); // --- Test for FFFF +one character ------------------------------------------------------------------------------------------------------------ p = (PKMX_WCHAR) U_UC_SENTINEL u"\u0062"; q = incxstr(p); - assert(q == p + 1); + test_assert(q == p + 1); // --- Test for FFFF +one ----------------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_NUL(); q = incxstr(p); - assert(q == p + 2); + test_assert(q == p + 2); // --- Test for FFFF + one + character ------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_NUL() u"\u0062"; q = incxstr(p); - assert(q == p + 2); + test_assert(q == p + 2); //------------------------------------------------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------------------------------------------------- @@ -725,31 +725,31 @@ void test_decxstr() { //--------------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) u"\0\u1234\u2468"; q = incxstr(p); - assert(q == p); + test_assert(q == p); // --- Test for character // --------------------------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR)u"\u1234\u1234\u2468"; q = incxstr(p); - assert(q == p + 1);; + test_assert(q == p + 1);; // --- Test for surrogate pair // ---------------------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) U_1F609_WINKING_FACE u"\u1234\u2468"; q = incxstr(p); - assert(q == p + 2); + test_assert(q == p + 2); // --- Test for one // ----------------------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR)u"\u0012\u1234\u2468"; q = incxstr(p); - assert(q == p + 1); + test_assert(q == p + 1); // --- Test for FFFF only // ------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) U_UC_SENTINEL u"\u1234\u2468"; q = incxstr(p); - assert(q == p + 1); + test_assert(q == p + 1); // -------------------------------------------------------------------------------------------------------------------------------------------------- // ---- UC_SENTINEL WITHOUT \0 @@ -760,115 +760,115 @@ void test_decxstr() { // -------------------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_INDEX(u"\u0002", u"\u0001") u"\u1234\u2468"; q = incxstr(p); - assert(q == p + 4); + test_assert(q == p + 4); // --- Test for FFFF +CODE_USE // ---------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_USE(u"\u0001") u"\u1234\u2468"; q = incxstr(p); - assert(q == p + 3); + test_assert(q == p + 3); // --- Test for FFFF +CODE_DEADKEY // ------------------------------------------------------------------------------------------------------------------ p = (PKMX_WCHAR) C_CODE_DEADKEY(u"\u0001") u"\u1234\u2468"; q = incxstr(p); - assert(q == p + 3); + test_assert(q == p + 3); // --- Test for FFFF CODE_EXTENDED // -------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_EXTENDED(u"\u0001" u"\u0002" u"\u0003" u"\u0004" u"\u0005" u"\u0006" U_CODE_EXTENDEDEND) u"\u1234\u2468"; q = incxstr(p); - assert(q == p + 9); + test_assert(q == p + 9); // --- Test for FFFF +CODE_CLEARCONTEXT // ------------------------------------------------------------------------------------------------------------ p = (PKMX_WCHAR) C_CODE_CLEARCONTEXT() u"\u0001\u1234\u2468"; q = incxstr(p); - assert(q == p + 2); + test_assert(q == p + 2); // --- Test for FFFF +CODE_CALL // ---------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_CALL(u"\u0001") u"\u1234\u2468"; q = incxstr(p); - assert(q == p + 3); + test_assert(q == p + 3); // --- Test for FFFF +CODE_CONTEXTEX // --------------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_CONTEXTEX(u"\u0001") u"\u1234\u2468"; q = incxstr(p); - assert(q == p + 3); + test_assert(q == p + 3); // --- Test for FFFF +CODE_IFOPT // ------------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_IFOPT(u"\u0002", u"\u0002", u"\u0001") u"\u1234\u2468"; q = incxstr(p); - assert(q == p + 5); + test_assert(q == p + 5); // --- Test for FFFF +CODE_IFSYSTEMSTORE // ------------------------------------------------------------------------------------------ p = (PKMX_WCHAR) C_CODE_IFSYSTEMSTORE(u"\u0002", u"\u0002", u"\u0001") u"\u1234\u2468"; q = incxstr(p); - assert(q == p + 5); + test_assert(q == p + 5); // --- Test for FFFF +CODE_SETOPT // ---------------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_SETOPT(u"\u0002", u"\u0001") u"\u1234\u2468"; q = incxstr(p); - assert(q == p + 4); + test_assert(q == p + 4); // --- Test for FFFF +CODE_SETSYSTEMRESTORE // --------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_SETSYSTEMSTORE(u"\u0002", u"\u0001") u"\u1234\u2468"; q = incxstr(p); - assert(q == p + 4); + test_assert(q == p + 4); // --- Test for FFFF +CODE_RESETOPT // ----------------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_RESETOPT(u"\u0001") u"\u1234\u2468"; q = incxstr(p); - assert(q == p + 3); + test_assert(q == p + 3); // --- Test for FFFF +CODE_SAVEOPT // ----------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_SAVEOPT(u"\u0001") u"\u1234\u2468"; q = incxstr(p); - assert(q == p + 3); + test_assert(q == p + 3); // --- Test for FFFF +default // ---------------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_NUL() u"\u1234\u2468"; q = incxstr(p); - assert(q == p + 2); + test_assert(q == p + 2); // --- Test for FFFF + CODE_ANY ----------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_ANY(u"\u0001") u"\u1234\u2468"; q = incxstr(p); - assert(q == p + 3 ); + test_assert(q == p + 3 ); // --- Test for FFFF + CODE_CONTEXT ----------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_CONTEXT() u"\u0001\u1234\u2468"; q = incxstr(p); - assert(q == p + 2 ); + test_assert(q == p + 2 ); // --- Test for FFFF + CODE_RETURN ----------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_RETURN() u"\u0001\u1234\u2468"; q = incxstr(p); - assert(q == p + 2 ); + test_assert(q == p + 2 ); // --- Test for FFFF + CODE_BEEP ----------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_BEEP() u"\u0001\u1234\u2468"; q = incxstr(p); - assert(q == p + 2 ); + test_assert(q == p + 2 ); // --- Test for FFFF + CODE_SWITCH ----------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_SWITCH(u"\u0001") u"\u1234\u2468"; q = incxstr(p); - assert(q == p + 3 ); + test_assert(q == p + 3 ); // --- Test for FFFF + NOTANY ----------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_NOTANY(u"\u0001") u"\u1234\u2468"; q = incxstr(p); - assert(q == p + 3 ); + test_assert(q == p + 3 ); // -------------------------------------------------------------------------------------------------------------------------------------------------- // ---- UC_SENTINEL WITH \0 AT DIFFERENT POSITIONS @@ -879,61 +879,61 @@ void test_decxstr() { // incxstr() ----- p = (PKMX_WCHAR) U_UC_SENTINEL u"\0\u0008\u0001\u1234\u2468"; q = incxstr(p); - assert(q == p + 1); + test_assert(q == p + 1); // --- Test for FFFF +control (earlier p+1) with \0 after second position --------- unit test failed with old version of // incxstr() ----- p = (PKMX_WCHAR) C_CODE_DEADKEY(u"\0") u"\u0001\u1234\u2468"; q = incxstr(p); - assert(q == p + 2); + test_assert(q == p + 2); // --- Test for FFFF +control (earlier p+1) with \0 after third position ----- unit test failed with old version of incxstr() // ----- p = (PKMX_WCHAR) C_CODE_DEADKEY(u"\u0001") u"\0\u1234\u2468"; q = incxstr(p); - assert(q == p + 3) + test_assert(q == p + 3) // --- Test for FFFF +control (earlier p+2) with \0 after fourth position ----- unit test failed with old version of // incxstr() ---- p = (PKMX_WCHAR) C_CODE_INDEX(u"\u0001", u"\u0001") u"\0\u1234\u2468"; q = incxstr(p); - assert(q == p + 4); + test_assert(q == p + 4); // --- Test for FFFF +control (earlier p+3) with \0 after fifth position ----- unit test failed with old version of incxstr() // --------- p = (PKMX_WCHAR) C_CODE_IFOPT(u"\u0001", u"\u0001", u"\u0001") u"\0\u1234\u2468"; q = incxstr(p); - assert(q == p + 5); + test_assert(q == p + 5); // --- Test for FFFF +control CODE_EXTENDED ----- (earlier p+n) with \0 after 6. position ----- unit test failed with old // version of incxstr() ----- p = (PKMX_WCHAR) C_CODE_EXTENDED(u"\u0001" u"\u0002" u"\u0003" u"\u0004" u"\0" u"\u0005" u"\u0006" u"\u0007" U_CODE_EXTENDEDEND) u"\u1234\u2468"; q = incxstr(p); - assert(q == p + 6); + test_assert(q == p + 6); // --- Test for FFFF +control CODE_EXTENDED ----- (earlier p+n) with \0 after 7. position ----- unit test failed with old // version of incxstr() p = (PKMX_WCHAR) C_CODE_EXTENDED(u"\u0001" u"\u0002" u"\u0003" u"\u0004" u"\u0005" u"\0" u"\u0006" u"\u0007" U_CODE_EXTENDEDEND) u"\u1234\u2468"; q = incxstr(p); - assert(q == p + 7); + test_assert(q == p + 7); // --- Test for FFFF +control CODE_EXTENDED ----- (earlier p+n) with \0 after 8. position ----- unit test failed with old // version of incxstr() ---------- p = (PKMX_WCHAR) C_CODE_EXTENDED(u"\u0001" u"\u0002" u"\u0003" u"\u0004" u"\u0005" u"\u0006" u"\0" u"\u0007" U_CODE_EXTENDEDEND) u"\u1234\u2468"; q = incxstr(p); - assert(q == p + 8); + test_assert(q == p + 8); // --- Test for FFFF +control CODE_EXTENDED ----- (earlier p+n) with \0 after 9. position ----- unit test failed with old // version of incxstr() --- p = (PKMX_WCHAR) C_CODE_EXTENDED(u"\u0001" u"\u0002" u"\u0003" u"\u0004" u"\u0005" u"\u0006" u"\u0007" u"\0" U_CODE_EXTENDEDEND) u"\u1234\u2468"; q = incxstr(p); - assert(q == p + 9); + test_assert(q == p + 9); // --- Test for FFFF +control CODE_EXTENDED ----- (earlier p+n) with \0 after 10. position ----- unit test failed with old // version of incxstr() ----------- p = (PKMX_WCHAR) C_CODE_EXTENDED(u"\u0001" u"\u0002" u"\u0003" u"\u0004" u"\u0005" u"\u0006" u"\u0007" U_CODE_EXTENDEDEND) u"\0\u1234\u2468"; q = incxstr(p); - assert(q == p + 10); + test_assert(q == p + 10); // -------------------------------------------------------------------------------------------------------------------------------------------------- // ---- UC_SENTINEL, INCOMPLETE & UNUSUAL SEQUENCES-------------------------------------------------------------------------------------------------- @@ -943,25 +943,25 @@ void test_decxstr() { // -------------------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) U_UC_SENTINEL u"\0\u1234\u2468"; q = incxstr(p); - assert(q == p + 1); + test_assert(q == p + 1); // --- Test for FFFF +one character // ------------------------------------------------------------------------------------------------------------ p = (PKMX_WCHAR) U_UC_SENTINEL u"\u0062\u1234\u2468"; q = incxstr(p); - assert(q == p + 1); + test_assert(q == p + 1); // --- Test for FFFF +one // ----------------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_NUL() u"\u1234\u2468"; q = incxstr(p); - assert(q == p + 2); + test_assert(q == p + 2); // --- Test for FFFF + one + character // ------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_NUL() u"\u0062\u1234\u2468"; q = incxstr(p); - assert(q == p + 2); + test_assert(q == p + 2); //------------------------------------------------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------------------------------------------------- @@ -976,31 +976,31 @@ void test_decxstr() { //------------------------------------------------------------------------------------------------------------------------ p = (PKMX_WCHAR)u"\0" U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p); + test_assert(q == p); // --- Test for character // --------------------------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR)u"\u1234" U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p + 1); + test_assert(q == p + 1); // --- Test for surrogate pair // ---------------------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) U_1F609_WINKING_FACE U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p + 2); + test_assert(q == p + 2); // --- Test for one // ----------------------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR)u"\u0012" U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p + 1); + test_assert(q == p + 1); // --- Test for FFFF only // ------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) U_UC_SENTINEL U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p + 1); + test_assert(q == p + 1); // -------------------------------------------------------------------------------------------------------------------------------------------------- // ---- UC_SENTINEL WITHOUT \0 @@ -1011,115 +1011,115 @@ void test_decxstr() { // -------------------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_INDEX(u"\u0002", u"\u0001") U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p + 4); + test_assert(q == p + 4); // --- Test for FFFF +CODE_USE // ---------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_USE(u"\u0001") U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p + 3); + test_assert(q == p + 3); // --- Test for FFFF +CODE_DEADKEY // ------------------------------------------------------------------------------------------------------------------ p = (PKMX_WCHAR) C_CODE_DEADKEY(u"\u0001") U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p + 3); + test_assert(q == p + 3); // --- Test for FFFF CODE_EXTENDED // -------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_EXTENDED(u"\u0001" u"\u0002" u"\u0003" u"\u0004" u"\u0005" u"\u0006" U_CODE_EXTENDEDEND) U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p + 9); + test_assert(q == p + 9); // --- Test for FFFF +CODE_CLEARCONTEXT // ------------------------------------------------------------------------------------------------------------ p = (PKMX_WCHAR) C_CODE_CLEARCONTEXT() u"\u0001" U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p + 2); + test_assert(q == p + 2); // --- Test for FFFF +CODE_CALL // ---------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_CALL(u"\u0001") U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p + 3); + test_assert(q == p + 3); // --- Test for FFFF +CODE_CONTEXTEX // --------------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_CONTEXTEX(u"\u0001") U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p + 3); + test_assert(q == p + 3); // --- Test for FFFF +CODE_IFOPT // ------------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_IFOPT(u"\u0002", u"\u0002", u"\u0001") U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p + 5); + test_assert(q == p + 5); // --- Test for FFFF +CODE_IFSYSTEMSTORE // ------------------------------------------------------------------------------------------ p = (PKMX_WCHAR) C_CODE_IFSYSTEMSTORE(u"\u0002", u"\u0002", u"\u0001") U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p + 5); + test_assert(q == p + 5); // --- Test for FFFF +CODE_SETOPT // ---------------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_SETOPT(u"\u0002", u"\u0001") U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p + 4); + test_assert(q == p + 4); // --- Test for FFFF +CODE_SETSYSTEMRESTORE // --------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_SETSYSTEMSTORE(u"\u0002", u"\u0001") U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p + 4); + test_assert(q == p + 4); // --- Test for FFFF +CODE_RESETOPT // ----------------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_RESETOPT(u"\u0001") U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p + 3); + test_assert(q == p + 3); // --- Test for FFFF +CODE_SAVEOPT // ----------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_SAVEOPT(u"\u0001") U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p + 3); + test_assert(q == p + 3); // --- Test for FFFF +default // ---------------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_NUL() U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p + 2); + test_assert(q == p + 2); // --- Test for FFFF + CODE_ANY ----------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_ANY(u"\u0001") U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p + 3 ); + test_assert(q == p + 3 ); // --- Test for FFFF + CODE_CONTEXT ----------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_CONTEXT() u"\u0001" U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p + 2 ); + test_assert(q == p + 2 ); // --- Test for FFFF + CODE_RETURN ----------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_RETURN() u"\u0001" U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p + 2 ); + test_assert(q == p + 2 ); // --- Test for FFFF + CODE_BEEP ----------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_BEEP() u"\u0001" U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p + 2 ); + test_assert(q == p + 2 ); // --- Test for FFFF + CODE_SWITCH ----------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_SWITCH(u"\u0001") U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p + 3 ); + test_assert(q == p + 3 ); // --- Test for FFFF + NOTANY ----------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_NOTANY(u"\u0001") U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p + 3 ); + test_assert(q == p + 3 ); // -------------------------------------------------------------------------------------------------------------------------------------------------- // ---- UC_SENTINEL WITH \0 AT DIFFERENT POSITIONS @@ -1130,61 +1130,61 @@ void test_decxstr() { // with old version of incxstr() ----- p = (PKMX_WCHAR) U_UC_SENTINEL u"\0\u0008\u0001" U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p + 1); + test_assert(q == p + 1); // --- Test for FFFF +control (earlier p+1) with \0 after second position --------- unit test failed with // old version of incxstr() ----- p = (PKMX_WCHAR) C_CODE_DEADKEY(u"\0") u"\u0001" U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p + 2); + test_assert(q == p + 2); // --- Test for FFFF +control (earlier p+1) with \0 after third position ----- unit test failed with old // version of incxstr() ----- p = (PKMX_WCHAR) C_CODE_DEADKEY(u"\u0001") u"\0" U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p + 3) + test_assert(q == p + 3) // --- Test for FFFF +control (earlier p+2) with \0 after fourth position ----- unit test failed with // old version of incxstr() ---- p = (PKMX_WCHAR) C_CODE_INDEX(u"\u0001", u"\u0001") u"\0" U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p + 4); + test_assert(q == p + 4); // --- Test for FFFF +control (earlier p+3) with \0 after fifth position ----- unit test failed with old // version of incxstr() --------- p = (PKMX_WCHAR) C_CODE_IFOPT(u"\u0001", u"\u0001", u"\u0001") u"\0" U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p + 5); + test_assert(q == p + 5); // --- Test for FFFF +control CODE_EXTENDED ----- (earlier p+n) with \0 after 6. position ----- unit test // failed with old version of incxstr() ----- p = (PKMX_WCHAR) C_CODE_EXTENDED(u"\u0001" u"\u0002" u"\u0003" u"\u0004" u"\0" u"\u0005" u"\u0006" u"\u0007" U_CODE_EXTENDEDEND) U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p + 6); + test_assert(q == p + 6); // --- Test for FFFF +control CODE_EXTENDED ----- (earlier p+n) with \0 after 7. position ----- unit test // failed with old version of incxstr() p = (PKMX_WCHAR) C_CODE_EXTENDED(u"\u0001" u"\u0002" u"\u0003" u"\u0004" u"\u0005" u"\0" u"\u0006" u"\u0007" U_CODE_EXTENDEDEND) U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p + 7); + test_assert(q == p + 7); // --- Test for FFFF +control CODE_EXTENDED ----- (earlier p+n) with \0 after 8. position ----- unit test // failed with old version of incxstr() ---------- p = (PKMX_WCHAR) C_CODE_EXTENDED(u"\u0001" u"\u0002" u"\u0003" u"\u0004" u"\u0005" u"\u0006" u"\0" u"\u0007" U_CODE_EXTENDEDEND) U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p + 8); + test_assert(q == p + 8); // --- Test for FFFF +control CODE_EXTENDED ----- (earlier p+n) with \0 after 9. position ----- unit test // failed with old version of incxstr() --- p = (PKMX_WCHAR) C_CODE_EXTENDED(u"\u0001" u"\u0002" u"\u0003" u"\u0004" u"\u0005" u"\u0006" u"\u0007" u"\0" U_CODE_EXTENDEDEND) U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p + 9); + test_assert(q == p + 9); // --- Test for FFFF +control CODE_EXTENDED ----- (earlier p+n) with \0 after 10. position ----- unit test // failed with old version of incxstr() ----------- p = (PKMX_WCHAR) C_CODE_EXTENDED(u"\u0001" u"\u0002" u"\u0003" u"\u0004" u"\u0005" u"\u0006" u"\u0007" U_CODE_EXTENDEDEND) u"\0" U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p + 10); + test_assert(q == p + 10); // -------------------------------------------------------------------------------------------------------------------------------------------------- // ---- UC_SENTINEL, INCOMPLETE & UNUSUAL SEQUENCES-------------------------------------------------------------------------------------------------- @@ -1194,46 +1194,46 @@ void test_decxstr() { // -------------------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) U_UC_SENTINEL u"\0" U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p + 1); + test_assert(q == p + 1); // --- Test for FFFF +one character // ------------------------------------------------------------------------------------------------------------ p = (PKMX_WCHAR) U_UC_SENTINEL u"\u0062" U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p + 1); + test_assert(q == p + 1); // --- Test for FFFF +one // ----------------------------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_NUL() U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p + 2); + test_assert(q == p + 2); // --- Test for FFFF + one + character // ------------------------------------------------------------------------------------------- p = (PKMX_WCHAR) C_CODE_NUL() u"\u0062" U_1F609_WINKING_FACE; q = incxstr(p); - assert(q == p + 2); + test_assert(q == p + 2); } void test_xstrlen() { - assert_equal(xstrlen((PKMX_WCHAR)u""), 0); - assert_equal(xstrlen((PKMX_WCHAR)u"1"), 1); - assert_equal(xstrlen((PKMX_WCHAR)u"1234567890"), 10); - assert_equal(xstrlen((PKMX_WCHAR) C_CODE_DEADKEY(u"\u0001") u"a"), 2); - assert_equal(xstrlen((PKMX_WCHAR) C_CODE_IFOPT(u"\u0001", u"\u0002", u"\u0003") u"a"), 2); - assert_equal(xstrlen((PKMX_WCHAR) C_CODE_IFSYSTEMSTORE(u"\u0001", u"\u0002", u"\u0003") u"a"), 2); - assert_equal(xstrlen((PKMX_WCHAR) U_1F609_WINKING_FACE u"a"), 2); + test_assert_equal(xstrlen((PKMX_WCHAR)u""), 0); + test_assert_equal(xstrlen((PKMX_WCHAR)u"1"), 1); + test_assert_equal(xstrlen((PKMX_WCHAR)u"1234567890"), 10); + test_assert_equal(xstrlen((PKMX_WCHAR) C_CODE_DEADKEY(u"\u0001") u"a"), 2); + test_assert_equal(xstrlen((PKMX_WCHAR) C_CODE_IFOPT(u"\u0001", u"\u0002", u"\u0003") u"a"), 2); + test_assert_equal(xstrlen((PKMX_WCHAR) C_CODE_IFSYSTEMSTORE(u"\u0001", u"\u0002", u"\u0003") u"a"), 2); + test_assert_equal(xstrlen((PKMX_WCHAR) U_1F609_WINKING_FACE u"a"), 2); } void test_xstrlen_ignoreifopt() { - assert_equal(xstrlen_ignoreifopt((PKMX_WCHAR)u""), 0); - assert_equal(xstrlen_ignoreifopt((PKMX_WCHAR)u"1"), 1); - assert_equal(xstrlen_ignoreifopt((PKMX_WCHAR)u"1234567890"), 10); - assert_equal(xstrlen_ignoreifopt((PKMX_WCHAR) C_CODE_DEADKEY(u"\u0001") u"a"), 2); - assert_equal(xstrlen_ignoreifopt((PKMX_WCHAR) C_CODE_IFOPT(u"\u0001", u"\u0002", u"\u0003") u"a"), 1); - assert_equal(xstrlen_ignoreifopt((PKMX_WCHAR) C_CODE_IFSYSTEMSTORE(u"\u0001", u"\u0002", u"\u0003") u"a"), 1); - assert_equal(xstrlen_ignoreifopt((PKMX_WCHAR) U_1F609_WINKING_FACE u"a"), 2); + test_assert_equal(xstrlen_ignoreifopt((PKMX_WCHAR)u""), 0); + test_assert_equal(xstrlen_ignoreifopt((PKMX_WCHAR)u"1"), 1); + test_assert_equal(xstrlen_ignoreifopt((PKMX_WCHAR)u"1234567890"), 10); + test_assert_equal(xstrlen_ignoreifopt((PKMX_WCHAR) C_CODE_DEADKEY(u"\u0001") u"a"), 2); + test_assert_equal(xstrlen_ignoreifopt((PKMX_WCHAR) C_CODE_IFOPT(u"\u0001", u"\u0002", u"\u0003") u"a"), 1); + test_assert_equal(xstrlen_ignoreifopt((PKMX_WCHAR) C_CODE_IFSYSTEMSTORE(u"\u0001", u"\u0002", u"\u0003") u"a"), 1); + test_assert_equal(xstrlen_ignoreifopt((PKMX_WCHAR) U_1F609_WINKING_FACE u"a"), 2); } void @@ -1241,32 +1241,32 @@ test_utf32() { std::cout << "== " << __FUNCTION__ << std::endl; const KMX_DWORD u295 = 0x0127; // ħ - assert(Uni_IsBMP(u295)); + test_assert(Uni_IsBMP(u295)); const char16_t hmaqtugha = Uni_UTF32BMPToUTF16(u295); - assert(hmaqtugha == 0x0127); + test_assert(hmaqtugha == 0x0127); char16_single c0; int l0 = Utf32CharToUtf16(u295, c0); - assert(l0 == 1); - assert(c0.ch[0] == 0x0127); - assert(c0.ch[1] == 0); + test_assert(l0 == 1); + test_assert(c0.ch[0] == 0x0127); + test_assert(c0.ch[1] == 0); std::u16string s0 = std::u16string(c0.ch, l0); - assert(s0 == std::u16string(u"ħ")); - assert_equal(s0.at(0), 0x0127); + test_assert(s0 == std::u16string(u"ħ")); + test_assert_equal(s0.at(0), 0x0127); const KMX_DWORD scat = 0x0001F640; // 🙀 - assert(!Uni_IsBMP(scat)); + test_assert(!Uni_IsBMP(scat)); char16_single c1; int l1 = Utf32CharToUtf16(scat, c1); - assert(l1 == 2); - assert_equal(c1.ch[0], 0xD83D); - assert_equal(c1.ch[1], 0xDE40); - assert_equal(c1.ch[2], 0); + test_assert(l1 == 2); + test_assert_equal(c1.ch[0], 0xD83D); + test_assert_equal(c1.ch[1], 0xDE40); + test_assert_equal(c1.ch[2], 0); std::u16string s1 = std::u16string(c1.ch, l1); - assert_equal(s1.at(0), 0xD83D); - assert_equal(s1.at(1), 0xDE40); - assert(s1 == std::u16string(u"🙀")); + test_assert_equal(s1.at(0), 0xD83D); + test_assert_equal(s1.at(1), 0xDE40); + test_assert(s1 == std::u16string(u"🙀")); } void @@ -1275,23 +1275,23 @@ test_u16string_to_u32string() { // normal cases { const std::u32string str = u16string_to_u32string(u""); - assert_equal(str.length(), 0); + test_assert_equal(str.length(), 0); } { const std::u32string str = u16string_to_u32string(u"e"); - assert_equal(str.length(), 1); - assert_equal(str.at(0), 0x0065); + test_assert_equal(str.length(), 1); + test_assert_equal(str.at(0), 0x0065); } { const std::u32string str = u16string_to_u32string(u"🙀"); - assert_equal(str.length(), 1); - assert_equal(str.at(0), 0x0001F640); + test_assert_equal(str.length(), 1); + test_assert_equal(str.at(0), 0x0001F640); } { const std::u32string str = u16string_to_u32string(u"Ω🙀"); - assert_equal(str.length(), 2); - assert_equal(str.at(0), u'Ω'); - assert_equal(str.at(1), 0x0001F640); + test_assert_equal(str.length(), 2); + test_assert_equal(str.at(0), u'Ω'); + test_assert_equal(str.at(1), 0x0001F640); } // error cases @@ -1299,33 +1299,33 @@ test_u16string_to_u32string() { std::u16string half_cat; half_cat.push_back(0xD83D); // mismatched lead surrogate const std::u32string str = u16string_to_u32string(half_cat); - assert_equal(str.length(), 1); - assert_equal(str.at(0), 0xFFFD); + test_assert_equal(str.length(), 1); + test_assert_equal(str.at(0), 0xFFFD); } { std::u16string half_cat; half_cat.push_back(0xD83D); // mismatched lead surrogate half_cat.push_back(u'Ω'); // with following text const std::u32string str = u16string_to_u32string(half_cat); - assert_equal(str.length(), 2); - assert_equal(str.at(0), 0xFFFD); - assert_equal(str.at(1), u'Ω'); + test_assert_equal(str.length(), 2); + test_assert_equal(str.at(0), 0xFFFD); + test_assert_equal(str.at(1), u'Ω'); } { std::u16string half_cat; half_cat.push_back(0xDE40); // mismatched trail surrogate const std::u32string str = u16string_to_u32string(half_cat); - assert_equal(str.length(), 1); - assert_equal(str.at(0), 0xFFFD); + test_assert_equal(str.length(), 1); + test_assert_equal(str.at(0), 0xFFFD); } { std::u16string no_cat; no_cat.push_back(0xDE40); no_cat.push_back(0xD83D); const std::u32string str = u16string_to_u32string(no_cat); - assert_equal(str.length(), 2); - assert_equal(str.at(0), 0xFFFD); - assert_equal(str.at(1), 0xFFFD); + test_assert_equal(str.length(), 2); + test_assert_equal(str.at(0), 0xFFFD); + test_assert_equal(str.at(1), 0xFFFD); } } @@ -1336,75 +1336,75 @@ test_u32string_to_u16string() { // normal cases { const auto str = u32string_to_u16string(U""); - assert_equal(str.length(), 0); + test_assert_equal(str.length(), 0); } { const auto str = u32string_to_u16string(U"e"); - assert_equal(str.length(), 1); - assert_equal(str.at(0), 0x0065); + test_assert_equal(str.length(), 1); + test_assert_equal(str.at(0), 0x0065); } { const auto str = u32string_to_u16string(U"🙀"); - assert_equal(str.length(), 2); - assert_equal(str.at(0), 0xD83D); - assert_equal(str.at(1), 0xDE40); + test_assert_equal(str.length(), 2); + test_assert_equal(str.at(0), 0xD83D); + test_assert_equal(str.at(1), 0xDE40); } { const auto str = u32string_to_u16string(U"Ω🙀"); - assert_equal(str.length(), 3); - assert_equal(str.at(0), u'Ω'); - assert_equal(str.at(1), 0xD83D); - assert_equal(str.at(2), 0xDE40); + test_assert_equal(str.length(), 3); + test_assert_equal(str.at(0), u'Ω'); + test_assert_equal(str.at(1), 0xD83D); + test_assert_equal(str.at(2), 0xDE40); } } void test_is_valid() { std::cout << "== " << __FUNCTION__ << std::endl; // valid - assert_equal(Uni_IsValid(0x0000), true); - assert_equal(Uni_IsValid(0x0127), true); - assert_equal(Uni_IsValid(U'🙀'), true); + test_assert_equal(Uni_IsValid(0x0000), true); + test_assert_equal(Uni_IsValid(0x0127), true); + test_assert_equal(Uni_IsValid(U'🙀'), true); // invalid - assert_equal(Uni_IsValid(0xDECAFBAD), false); // out of range - assert_equal(Uni_IsValid(0x566D4128), false); - assert_equal(Uni_IsValid(0xFFFF), false); // nonchar - assert_equal(Uni_IsValid(0xFFFE), false); // nonchar - assert_equal(Uni_IsValid(0x10FFFF), false); // nonchar - assert_equal(Uni_IsValid(0x10FFFE), false); // nonchar - assert_equal(Uni_IsValid(0x01FFFF), false); // nonchar - assert_equal(Uni_IsValid(0x01FFFE), false); // nonchar - assert_equal(Uni_IsValid(0x02FFFF), false); // nonchar - assert_equal(Uni_IsValid(0x02FFFE), false); // nonchar - assert_equal(Uni_IsValid(0xFDD1), false); // nonchar - assert_equal(Uni_IsValid(0xFDD0), false); // nonchar + test_assert_equal(Uni_IsValid(0xDECAFBAD), false); // out of range + test_assert_equal(Uni_IsValid(0x566D4128), false); + test_assert_equal(Uni_IsValid(0xFFFF), false); // nonchar + test_assert_equal(Uni_IsValid(0xFFFE), false); // nonchar + test_assert_equal(Uni_IsValid(0x10FFFF), false); // nonchar + test_assert_equal(Uni_IsValid(0x10FFFE), false); // nonchar + test_assert_equal(Uni_IsValid(0x01FFFF), false); // nonchar + test_assert_equal(Uni_IsValid(0x01FFFE), false); // nonchar + test_assert_equal(Uni_IsValid(0x02FFFF), false); // nonchar + test_assert_equal(Uni_IsValid(0x02FFFE), false); // nonchar + test_assert_equal(Uni_IsValid(0xFDD1), false); // nonchar + test_assert_equal(Uni_IsValid(0xFDD0), false); // nonchar // positive range test - assert_equal(Uni_IsValid(0x100000, 0x10FFFD), true); - assert_equal(Uni_IsValid(0x10, 0x20), true); - assert_equal(Uni_IsValid(0x100000, 0x10FFFD), true); + test_assert_equal(Uni_IsValid(0x100000, 0x10FFFD), true); + test_assert_equal(Uni_IsValid(0x10, 0x20), true); + test_assert_equal(Uni_IsValid(0x100000, 0x10FFFD), true); // all valid ranges in BMP - assert_equal(Uni_IsValid(0x0000, 0xD7FF), true); - assert_equal(Uni_IsValid(0xD800, 0xDFFF), false); - assert_equal(Uni_IsValid(0xE000, 0xFDCF), true); - assert_equal(Uni_IsValid(0xFDD0, 0xFDEF), false); - assert_equal(Uni_IsValid(0xFDF0, 0xFDFF), true); - assert_equal(Uni_IsValid(0xFDF0, 0xFFFD), true); + test_assert_equal(Uni_IsValid(0x0000, 0xD7FF), true); + test_assert_equal(Uni_IsValid(0xD800, 0xDFFF), false); + test_assert_equal(Uni_IsValid(0xE000, 0xFDCF), true); + test_assert_equal(Uni_IsValid(0xFDD0, 0xFDEF), false); + test_assert_equal(Uni_IsValid(0xFDF0, 0xFDFF), true); + test_assert_equal(Uni_IsValid(0xFDF0, 0xFFFD), true); // negative range test - assert_equal(Uni_IsValid(0, 0x10FFFF), false); // ends with nonchar - assert_equal(Uni_IsValid(0, 0x10FFFD), false); // contains lots o' nonchars - assert_equal(Uni_IsValid(0x20, 0x10), false); // swapped - assert_equal(Uni_IsValid(0xFDEF, 0xFDF0), false); // just outside range - assert_equal(Uni_IsValid(0x0000, 0x010000), false); // crosses noncharacter plane boundary and other stuff - assert_equal(Uni_IsValid(0x010000, 0x020000), false); // crosses noncharacter plane boundary - assert_equal(Uni_IsValid(0x0000, 0xFFFF), false); // crosses other BMP prohibited and plane boundary - assert_equal(Uni_IsValid(0x0000, 0xFFFD), false); // crosses other BMP prohibited - assert_equal(Uni_IsValid(0x0000, 0xE000), false); // crosses surrogate space - assert_equal(Uni_IsValid(0x0000, 0x20FFFF), false); // out of bounds - assert_equal(Uni_IsValid(0x10FFFD, 0x20FFFF), false); // out of bounds + test_assert_equal(Uni_IsValid(0, 0x10FFFF), false); // ends with nonchar + test_assert_equal(Uni_IsValid(0, 0x10FFFD), false); // contains lots o' nonchars + test_assert_equal(Uni_IsValid(0x20, 0x10), false); // swapped + test_assert_equal(Uni_IsValid(0xFDEF, 0xFDF0), false); // just outside range + test_assert_equal(Uni_IsValid(0x0000, 0x010000), false); // crosses noncharacter plane boundary and other stuff + test_assert_equal(Uni_IsValid(0x010000, 0x020000), false); // crosses noncharacter plane boundary + test_assert_equal(Uni_IsValid(0x0000, 0xFFFF), false); // crosses other BMP prohibited and plane boundary + test_assert_equal(Uni_IsValid(0x0000, 0xFFFD), false); // crosses other BMP prohibited + test_assert_equal(Uni_IsValid(0x0000, 0xE000), false); // crosses surrogate space + test_assert_equal(Uni_IsValid(0x0000, 0x20FFFF), false); // out of bounds + test_assert_equal(Uni_IsValid(0x10FFFD, 0x20FFFF), false); // out of bounds } diff --git a/core/tests/unit/kmnkbd/meson.build b/core/tests/unit/kmnkbd/meson.build index 7285b9bf117..c108ae5b83d 100644 --- a/core/tests/unit/kmnkbd/meson.build +++ b/core/tests/unit/kmnkbd/meson.build @@ -16,18 +16,18 @@ endif local_defns = ['-DKM_CORE_LIBRARY_STATIC'] tests = [ - ['action-api', 'action_api.cpp'], - ['action-set-api', 'action_set_api.cpp'], - ['context-api', 'context_api.cpp'], - ['keyboard-api', 'keyboard_api.cpp'], - ['options-api', 'options_api.cpp'], - ['state-api', 'state_api.cpp'], - ['state-context-api', 'state_context_api.cpp'], - ['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_actions_get_api', 'test_actions_get_api.cpp'], + ['action-api-tests', 'action_api.tests.cpp'], + ['action-set-api-tests', 'action_set_api.tests.cpp'], + ['context-api-tests', 'context_api.tests.cpp'], + ['keyboard-api-tests', 'keyboard_api.tests.cpp'], + ['options-api-tests', 'options_api.tests.cpp'], + ['state-api-tests', 'state_api.tests.cpp'], + ['state-context-api-tests', 'state_context_api.tests.cpp'], + ['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_get_api-tests', 'actions_get_api.tests.cpp'], ] test_path = join_paths(meson.current_build_dir(), '..', 'kmx') diff --git a/core/tests/unit/kmnkbd/options_api.cpp b/core/tests/unit/kmnkbd/options_api.tests.cpp similarity index 100% rename from core/tests/unit/kmnkbd/options_api.cpp rename to core/tests/unit/kmnkbd/options_api.tests.cpp diff --git a/core/tests/unit/kmnkbd/state_api.cpp b/core/tests/unit/kmnkbd/state_api.tests.cpp similarity index 90% rename from core/tests/unit/kmnkbd/state_api.cpp rename to core/tests/unit/kmnkbd/state_api.tests.cpp index f13f03d536e..70dcce31335 100644 --- a/core/tests/unit/kmnkbd/state_api.cpp +++ b/core/tests/unit/kmnkbd/state_api.tests.cpp @@ -156,23 +156,23 @@ int main(int argc, char * argv[]) try_status(km_core_process_event(test_state, KM_CORE_VKEY_S, KM_CORE_MODIFIER_SHIFT, 1, KM_CORE_EVENT_FLAG_DEFAULT)); - assert(action_items(test_state, {{KM_CORE_IT_CHAR, {0,}, {km_core_usv('S')}}, {KM_CORE_IT_END}})); + test_assert(action_items(test_state, {{KM_CORE_IT_CHAR, {0,}, {km_core_usv('S')}}, {KM_CORE_IT_END}})); try_status(km_core_process_event(test_state, KM_CORE_VKEY_I, KM_CORE_MODIFIER_SHIFT, 1, KM_CORE_EVENT_FLAG_DEFAULT)); - assert(action_items(test_state, {{KM_CORE_IT_CHAR, {0,}, {km_core_usv('I')}}, {KM_CORE_IT_END}})); + test_assert(action_items(test_state, {{KM_CORE_IT_CHAR, {0,}, {km_core_usv('I')}}, {KM_CORE_IT_END}})); try_status(km_core_process_event(test_state, KM_CORE_VKEY_L, 0, 1, KM_CORE_EVENT_FLAG_DEFAULT)); - assert(action_items(test_state, {{KM_CORE_IT_CHAR, {0,}, {km_core_usv('l')}}, {KM_CORE_IT_END}})); + test_assert(action_items(test_state, {{KM_CORE_IT_CHAR, {0,}, {km_core_usv('l')}}, {KM_CORE_IT_END}})); try_status(km_core_process_event(test_state, KM_CORE_VKEY_BKSP, 0, 1, KM_CORE_EVENT_FLAG_DEFAULT)); - assert(action_items(test_state, {{KM_CORE_IT_BACK, {0,}, {0}}, {KM_CORE_IT_END}})); + test_assert(action_items(test_state, {{KM_CORE_IT_BACK, {0,}, {0}}, {KM_CORE_IT_END}})); try_status(km_core_process_event(test_state, KM_CORE_VKEY_L, KM_CORE_MODIFIER_SHIFT, 1, KM_CORE_EVENT_FLAG_DEFAULT)); - assert(action_items(test_state, {{KM_CORE_IT_CHAR, {0,}, {km_core_usv('L')}}, {KM_CORE_IT_END}})); + test_assert(action_items(test_state, {{KM_CORE_IT_CHAR, {0,}, {km_core_usv('L')}}, {KM_CORE_IT_END}})); try_status(km_core_process_event(test_state, KM_CORE_VKEY_F2, 0, 1, KM_CORE_EVENT_FLAG_DEFAULT)); km_core_action_item action = {KM_CORE_IT_PERSIST_OPT, {0,}, }; action.option = &expected_persist_opt; - assert(action_items(test_state, {action, {KM_CORE_IT_END}})); + test_assert(action_items(test_state, {action, {KM_CORE_IT_END}})); // Test debug dump auto doc1 = get_json_doc(*test_state), diff --git a/core/tests/unit/kmnkbd/state_context_api.cpp b/core/tests/unit/kmnkbd/state_context_api.tests.cpp similarity index 95% rename from core/tests/unit/kmnkbd/state_context_api.cpp rename to core/tests/unit/kmnkbd/state_context_api.tests.cpp index b7f4efbcc2a..34de27cd944 100644 --- a/core/tests/unit/kmnkbd/state_context_api.cpp +++ b/core/tests/unit/kmnkbd/state_context_api.tests.cpp @@ -135,7 +135,7 @@ test_context_set_if_needed__identical_context() { km_core_cu const *new_app_context = u"This is a test"; setup("k_000___null_keyboard.kmx", cached_context, false); assert_equal_status(km_core_state_context_set_if_needed(test_state, new_app_context), KM_CORE_CONTEXT_STATUS_UNCHANGED); - assert(is_identical_context(cached_context)); + test_assert(is_identical_context(cached_context)); teardown(); } @@ -145,8 +145,8 @@ test_context_set_if_needed__different_context() { km_core_cu const *new_app_context = u"This is a test"; setup("k_000___null_keyboard.kmx", cached_context); assert_equal_status(km_core_state_context_set_if_needed(test_state, new_app_context), KM_CORE_CONTEXT_STATUS_UPDATED); - assert(!is_identical_context(cached_context)); - assert(is_identical_context(new_app_context)); + test_assert(!is_identical_context(cached_context)); + test_assert(is_identical_context(new_app_context)); teardown(); } @@ -157,8 +157,8 @@ test_context_set_if_needed__cached_context_cleared() { setup("k_000___null_keyboard.kmx", cached_context); km_core_state_context_clear(test_state); assert_equal_status(km_core_state_context_set_if_needed(test_state, new_app_context), KM_CORE_CONTEXT_STATUS_UPDATED); - assert(!is_identical_context(cached_context)); - assert(is_identical_context(new_app_context)); + test_assert(!is_identical_context(cached_context)); + test_assert(is_identical_context(new_app_context)); teardown(); } @@ -168,8 +168,8 @@ test_context_set_if_needed__application_context_empty() { km_core_cu const *new_app_context = u""; setup("k_000___null_keyboard.kmx", cached_context); assert_equal_status(km_core_state_context_set_if_needed(test_state, new_app_context), KM_CORE_CONTEXT_STATUS_UPDATED); - assert(!is_identical_context(cached_context)); - assert(is_identical_context(new_app_context)); + test_assert(!is_identical_context(cached_context)); + test_assert(is_identical_context(new_app_context)); teardown(); } @@ -179,8 +179,8 @@ test_context_set_if_needed__app_context_is_longer() { km_core_cu const *new_app_context = u"Longer This is a test"; setup("k_000___null_keyboard.kmx", cached_context); assert_equal_status(km_core_state_context_set_if_needed(test_state, new_app_context), KM_CORE_CONTEXT_STATUS_UPDATED); - assert(!is_identical_context(cached_context)); - assert(is_identical_context(new_app_context)); + test_assert(!is_identical_context(cached_context)); + test_assert(is_identical_context(new_app_context)); teardown(); } @@ -190,8 +190,8 @@ test_context_set_if_needed__app_context_is_shorter() { km_core_cu const *new_app_context = u"is a test"; setup("k_000___null_keyboard.kmx", cached_context); assert_equal_status(km_core_state_context_set_if_needed(test_state, new_app_context), KM_CORE_CONTEXT_STATUS_UPDATED); - assert(!is_identical_context(cached_context)); - assert(is_identical_context(new_app_context)); + test_assert(!is_identical_context(cached_context)); + test_assert(is_identical_context(new_app_context)); teardown(); } @@ -237,7 +237,7 @@ test_context_set_if_needed__cached_context_shorter_and_markers() { {KM_CORE_CT_MARKER, {0}, {3}}, {KM_CORE_CT_MARKER, {0}, {4}}, KM_CORE_CONTEXT_ITEM_END}; assert_identical_context_with_markers(km_core_state_context(test_state), expected_citems); assert_identical_context_without_markers(km_core_state_app_context(test_state), expected_citems); - assert(is_identical_context(new_app_context)); + test_assert(is_identical_context(new_app_context)); teardown(); } @@ -339,7 +339,7 @@ test_context_set_if_needed__surrogate_pairs_unchanged() { km_core_cu const *new_app_context = u"a\U00010100"; setup("k_000___null_keyboard.kmx", cached_context); assert_equal_status(km_core_state_context_set_if_needed(test_state, new_app_context), KM_CORE_CONTEXT_STATUS_UNCHANGED); - assert(is_identical_context(new_app_context)); + test_assert(is_identical_context(new_app_context)); teardown(); } @@ -349,7 +349,7 @@ test_context_set_if_needed__surrogate_pairs_app_context_longer() { km_core_cu const *new_app_context = u"xa\U00010100"; setup("k_000___null_keyboard.kmx", cached_context); assert_equal_status(km_core_state_context_set_if_needed(test_state, new_app_context), KM_CORE_CONTEXT_STATUS_UPDATED); - assert(is_identical_context(new_app_context)); + test_assert(is_identical_context(new_app_context)); teardown(); } @@ -359,7 +359,7 @@ test_context_set_if_needed__surrogate_pairs_cached_context_longer() { km_core_cu const *new_app_context = u"a\U00010100"; setup("k_000___null_keyboard.kmx", cached_context); assert_equal_status(km_core_state_context_set_if_needed(test_state, new_app_context), KM_CORE_CONTEXT_STATUS_UPDATED); - assert(is_identical_context(new_app_context)); + test_assert(is_identical_context(new_app_context)); teardown(); } @@ -476,8 +476,8 @@ test_context_clear() { km_core_cu const *cached_context = u"This is a test"; setup("k_000___null_keyboard.kmx", cached_context); try_status(km_core_state_context_clear(test_state)); - assert(!is_identical_context(cached_context)); - assert(is_identical_context(u"")); + test_assert(!is_identical_context(cached_context)); + test_assert(is_identical_context(u"")); teardown(); } @@ -488,7 +488,7 @@ void test_context_debug_empty() { setup("k_000___null_keyboard.kmx", cached_context); auto str = km_core_state_context_debug(test_state, KM_CORE_DEBUG_CONTEXT_CACHED); // std::cout << str << std::endl; - assert(std::u16string(str) == u"|| (len: 0) [ ]"); + test_assert(std::u16string(str) == u"|| (len: 0) [ ]"); km_core_cu_dispose(str); } @@ -513,7 +513,7 @@ void test_context_debug_various() { auto str = km_core_state_context_debug(test_state, KM_CORE_DEBUG_CONTEXT_CACHED); // std::cout << str << std::endl; - assert(std::u16string(str) == u"|123🤣| (len: 9) [ M(5) U+0031 M(1) U+0032 M(2) U+0033 M(3) M(4) U+1f923 ]"); + test_assert(std::u16string(str) == u"|123🤣| (len: 9) [ M(5) U+0031 M(1) U+0032 M(2) U+0033 M(3) M(4) U+1f923 ]"); km_core_cu_dispose(str); } diff --git a/core/tests/unit/kmx/kmx.cpp b/core/tests/unit/kmx/kmx.cpp index 6dc3d69d68d..9eac21494a1 100644 --- a/core/tests/unit/kmx/kmx.cpp +++ b/core/tests/unit/kmx/kmx.cpp @@ -71,7 +71,7 @@ apply_action( ) { switch (act.type) { case KM_CORE_IT_END: - assert(false); + test_assert(false); break; case KM_CORE_IT_ALERT: g_beep_found = true; @@ -110,11 +110,11 @@ apply_action( // in a table. Or, if Keyman has a cached context, then there may be // additional text in the text store that Keyman can't see. if (act.backspace.expected_type == KM_CORE_BT_MARKER) { - assert(!context.empty()); - assert(context.back().type == KM_CORE_CT_MARKER); + test_assert(!context.empty()); + test_assert(context.back().type == KM_CORE_CT_MARKER); context.pop_back(); } else if (text_store.length() > 0) { - assert(!context.empty() && !text_store.empty()); + test_assert(!context.empty() && !text_store.empty()); km_core_usv ch = text_store.back(); text_store.pop_back(); if (text_store.length() > 0 && Uni_IsSurrogate2(ch)) { @@ -126,10 +126,10 @@ apply_action( text_store.pop_back(); } } - assert(ch == act.backspace.expected_value); + test_assert(ch == act.backspace.expected_value); - assert(context.back().type == KM_CORE_CT_CHAR); - assert(context.back().character == ch); + test_assert(context.back().type == KM_CORE_CT_CHAR); + test_assert(context.back().character == ch); context.pop_back(); } break; @@ -164,7 +164,7 @@ apply_action( test_source.set_caps_lock_on(act.capsLock); break; default: - assert(false); // NOT SUPPORTED + test_assert(false); // NOT SUPPORTED break; } } @@ -255,15 +255,15 @@ run_test(const km::core::path &source, const km::core::path &compiled) { // not diverged auto ci = citems; for(auto test_ci = test_context.begin(); ci->type != KM_CORE_CT_END || test_ci != test_context.end(); ci++, test_ci++) { - assert(ci->type != KM_CORE_CT_END && test_ci != test_context.end()); // Verify that both lists are same length - assert(test_ci->type == ci->type && test_ci->marker == ci->marker); + test_assert(ci->type != KM_CORE_CT_END && test_ci != test_context.end()); // Verify that both lists are same length + test_assert(test_ci->type == ci->type && test_ci->marker == ci->marker); } km_core_context_items_dispose(citems); if ((!context_invalidated) && (text_store != core_context_str)) { std::cerr << "text store has unexpectedly diverged from core_context" << std::endl; std::cerr << "text store : " << string_to_hex(text_store) << " [" << text_store << "]" << std::endl; std::cerr << "core context: " << string_to_hex(core_context_str) << " [" << core_context_str << "]" << std::endl; - assert(false); + test_assert(false); } } @@ -282,8 +282,8 @@ run_test(const km::core::path &source, const km::core::path &compiled) { // not diverged auto ci = citems; for(auto test_ci = test_context.begin(); ci->type != KM_CORE_CT_END || test_ci != test_context.end(); ci++, test_ci++) { - assert(ci->type != KM_CORE_CT_END && test_ci != test_context.end()); // Verify that both lists are same length - assert(test_ci->type == ci->type && test_ci->marker == ci->marker); + test_assert(ci->type != KM_CORE_CT_END && test_ci != test_context.end()); // Verify that both lists are same length + test_assert(test_ci->type == ci->type && test_ci->marker == ci->marker); } km_core_context_items_dispose(citems); diff --git a/core/tests/unit/kmx/kmx_external_event.cpp b/core/tests/unit/kmx/kmx_external_event.tests.cpp similarity index 96% rename from core/tests/unit/kmx/kmx_external_event.cpp rename to core/tests/unit/kmx/kmx_external_event.tests.cpp index a7ad4d750ab..15f2d284dfb 100644 --- a/core/tests/unit/kmx/kmx_external_event.cpp +++ b/core/tests/unit/kmx/kmx_external_event.tests.cpp @@ -58,7 +58,7 @@ void test_external_event(const km::core::path &source_file){ try_status(km_core_event(test_state, event, nullptr)); // The action to turn capslock off must be in the actions list. - assert(action_items(test_state, {{KM_CORE_IT_CAPSLOCK, {0,}, {0}}, {KM_CORE_IT_END}})); + test_assert(action_items(test_state, {{KM_CORE_IT_CAPSLOCK, {0,}, {0}}, {KM_CORE_IT_END}})); km_core_state_dispose(test_state); km_core_keyboard_dispose(test_kb); diff --git a/core/tests/unit/kmx/kmx_imx.cpp b/core/tests/unit/kmx/kmx_imx.tests.cpp similarity index 93% rename from core/tests/unit/kmx/kmx_imx.cpp rename to core/tests/unit/kmx/kmx_imx.tests.cpp index 698bbb8fe55..ab2bbb372b8 100644 --- a/core/tests/unit/kmx/kmx_imx.cpp +++ b/core/tests/unit/kmx/kmx_imx.tests.cpp @@ -181,14 +181,14 @@ void test_imx_list(const km::core::path &source_file){ str.append(u":"); str.append(imx_rule_it->function_name); auto extracted_library_function = convert(str); - assert(extracted_library_function == expected_imx_map[imx_rule_it->imx_id] ); + test_assert(extracted_library_function == expected_imx_map[imx_rule_it->imx_id] ); g_extract_imx_map[imx_rule_it->imx_id] = extracted_library_function; ++x; } std::cout << " X Value is " << x << std::endl; - assert(x==4); + test_assert(x==4); km_core_keyboard_imx_list_dispose(kb_imx_list); km_core_state_dispose(test_state); @@ -223,13 +223,13 @@ void test_queue_actions (const km::core::path &source_keyboard) { // Key Press that doesn't trigger a call back try_status(km_core_process_event(test_state, KM_CORE_VKEY_S,KM_CORE_MODIFIER_SHIFT, 1, KM_CORE_EVENT_FLAG_DEFAULT)); - assert(action_items(test_state, {{KM_CORE_IT_CHAR, {0,}, {km_core_usv('S')}}, {KM_CORE_IT_END}})); + test_assert(action_items(test_state, {{KM_CORE_IT_CHAR, {0,}, {km_core_usv('S')}}, {KM_CORE_IT_END}})); try_status(km_core_process_event(test_state, KM_CORE_VKEY_BKSP, 0, 1, KM_CORE_EVENT_FLAG_DEFAULT)); - assert(action_items(test_state, {{KM_CORE_IT_CHAR, {0,}, {km_core_usv('X')}}, {KM_CORE_IT_ALERT, {0,}, {0}}, {KM_CORE_IT_END}})); + test_assert(action_items(test_state, {{KM_CORE_IT_CHAR, {0,}, {km_core_usv('X')}}, {KM_CORE_IT_ALERT, {0,}, {0}}, {KM_CORE_IT_END}})); try_status(km_core_process_event(test_state, KM_CORE_VKEY_ESC, 0, 1, KM_CORE_EVENT_FLAG_DEFAULT)); - assert(action_items(test_state, { {KM_CORE_IT_CHAR, {0,}, {km_core_usv('Y')}}, + test_assert(action_items(test_state, { {KM_CORE_IT_CHAR, {0,}, {km_core_usv('Y')}}, {KM_CORE_IT_MARKER, {0,}, {1}}, {KM_CORE_IT_CHAR, {0,}, {km_core_usv('A')}}, {KM_CORE_IT_END}})); @@ -239,10 +239,10 @@ void test_queue_actions (const km::core::path &source_keyboard) { km_core_action_item bksp_a = {KM_CORE_IT_BACK}; bksp_a.backspace.expected_type = KM_CORE_BT_CHAR; bksp_a.backspace.expected_value = 'A'; - assert(action_items(test_state, {bksp_a,{KM_CORE_IT_CHAR, {0,}, {km_core_usv('Z')}}, {KM_CORE_IT_END}})); + test_assert(action_items(test_state, {bksp_a,{KM_CORE_IT_CHAR, {0,}, {km_core_usv('Z')}}, {KM_CORE_IT_END}})); try_status(km_core_process_event(test_state, KM_CORE_VKEY_2, 0, 1, KM_CORE_EVENT_FLAG_DEFAULT)); - assert(action_items(test_state, {{KM_CORE_IT_INVALIDATE_CONTEXT, {0,}, {0}}, {KM_CORE_IT_END}})); + test_assert(action_items(test_state, {{KM_CORE_IT_INVALIDATE_CONTEXT, {0,}, {0}}, {KM_CORE_IT_END}})); km_core_state_imx_deregister_callback(test_state); km_core_keyboard_imx_list_dispose(kb_imx_list); diff --git a/core/tests/unit/kmx/kmx_key_list.cpp b/core/tests/unit/kmx/kmx_key_list.tests.cpp similarity index 97% rename from core/tests/unit/kmx/kmx_key_list.cpp rename to core/tests/unit/kmx/kmx_key_list.tests.cpp index d4aa9b4e93f..7b811bd0b1a 100644 --- a/core/tests/unit/kmx/kmx_key_list.cpp +++ b/core/tests/unit/kmx/kmx_key_list.tests.cpp @@ -77,14 +77,14 @@ void test_key_list(const km::core::path &source_file){ map_key_list[std::make_pair(key_rule_it->key, key_rule_it->modifier_flag)] = key_rule_it->modifier_flag; ++n; } - assert(n==7); + test_assert(n==7); std::map, uint32_t>::iterator it_expected; std::map, uint32_t>::iterator it_key_list = map_key_list.begin(); while (it_key_list != map_key_list.end()){ it_expected = kb_key_expected_key_list.find(it_key_list->first); - assert (it_expected != kb_key_expected_key_list.end()); + test_assert (it_expected != kb_key_expected_key_list.end()); it_key_list++; } diff --git a/core/tests/unit/kmx/meson.build b/core/tests/unit/kmx/meson.build index 548ab895229..a7a69079e4a 100644 --- a/core/tests/unit/kmx/meson.build +++ b/core/tests/unit/kmx/meson.build @@ -174,7 +174,7 @@ subdir('fixtures') # should work for Linux, macOS, and WASM. test_path = source_path -key_e = executable('key_list', ['kmx_key_list.cpp', common_test_files], +key_e = executable('key_list_tests', ['kmx_key_list.tests.cpp', common_test_files], cpp_args: defns + warns, include_directories: [inc, libsrc], link_args: links + tests_flags, @@ -193,7 +193,7 @@ test('key_list', key_e, depends: kbd_log, args: [kbd_obj] ) # test for imx list -imx_e = executable('imx_list', ['kmx_imx.cpp', common_test_files], +imx_e = executable('imx_list_tests', ['kmx_imx.tests.cpp', common_test_files], cpp_args: defns + warns, include_directories: [inc, libsrc], link_args: links + tests_flags, @@ -211,7 +211,7 @@ kbd_log = custom_target(test_kbd + '.kmx'.underscorify(), ) test('imx_list', imx_e, depends: kbd_log, args: [kbd_obj] ) -external_e = executable('ext_event', ['kmx_external_event.cpp', common_test_files], +external_e = executable('ext_event_tests', ['kmx_external_event.tests.cpp', common_test_files], cpp_args: defns + warns, include_directories: [inc, libsrc], link_args: links + tests_flags, diff --git a/core/tests/unit/ldml/test_context_normalization.cpp b/core/tests/unit/ldml/context_normalization.tests.cpp similarity index 78% rename from core/tests/unit/ldml/test_context_normalization.cpp rename to core/tests/unit/ldml/context_normalization.tests.cpp index cda91cbf4df..ea9d635ab23 100644 --- a/core/tests/unit/ldml/test_context_normalization.cpp +++ b/core/tests/unit/ldml/context_normalization.tests.cpp @@ -83,9 +83,9 @@ bool is_identical_context(km_core_cu const *cached_context, km_core_debug_contex void test_context_normalization_already_nfd() { km_core_cu const *app_context_nfd = u"A\u0300"; setup("k_001_tiny.kmx"); - assert(km_core_state_context_set_if_needed(test_state, app_context_nfd) == KM_CORE_CONTEXT_STATUS_UPDATED); - assert(is_identical_context(app_context_nfd, KM_CORE_DEBUG_CONTEXT_APP)); - assert(is_identical_context(app_context_nfd, KM_CORE_DEBUG_CONTEXT_CACHED)); + test_assert(km_core_state_context_set_if_needed(test_state, app_context_nfd) == KM_CORE_CONTEXT_STATUS_UPDATED); + test_assert(is_identical_context(app_context_nfd, KM_CORE_DEBUG_CONTEXT_APP)); + test_assert(is_identical_context(app_context_nfd, KM_CORE_DEBUG_CONTEXT_CACHED)); teardown(); } @@ -93,9 +93,9 @@ void test_context_normalization_basic() { km_core_cu const *application_context = u"This is a test À"; km_core_cu const *cached_context = u"This is a test A\u0300"; setup("k_001_tiny.kmx"); - assert(km_core_state_context_set_if_needed(test_state, application_context) == KM_CORE_CONTEXT_STATUS_UPDATED); - assert(is_identical_context(application_context, KM_CORE_DEBUG_CONTEXT_APP)); - assert(is_identical_context(cached_context, KM_CORE_DEBUG_CONTEXT_CACHED)); + test_assert(km_core_state_context_set_if_needed(test_state, application_context) == KM_CORE_CONTEXT_STATUS_UPDATED); + test_assert(is_identical_context(application_context, KM_CORE_DEBUG_CONTEXT_APP)); + test_assert(is_identical_context(cached_context, KM_CORE_DEBUG_CONTEXT_CACHED)); teardown(); } @@ -104,9 +104,9 @@ void test_context_normalization_hefty() { km_core_cu const *application_context = u"À" u"é̖" u"\u1e69" u"\u212b" u"\U000114BC"; km_core_cu const *cached_context = u"A\u0300" u"e\u0316\u0301" u"\u0073\u0323\u0307" u"\u0041\u030a" u"\U000114B9\U000114B0"; setup("k_001_tiny.kmx"); - assert(km_core_state_context_set_if_needed(test_state, application_context) == KM_CORE_CONTEXT_STATUS_UPDATED); - assert(is_identical_context(application_context, KM_CORE_DEBUG_CONTEXT_APP)); - assert(is_identical_context(cached_context, KM_CORE_DEBUG_CONTEXT_CACHED)); + test_assert(km_core_state_context_set_if_needed(test_state, application_context) == KM_CORE_CONTEXT_STATUS_UPDATED); + test_assert(is_identical_context(application_context, KM_CORE_DEBUG_CONTEXT_APP)); + test_assert(is_identical_context(cached_context, KM_CORE_DEBUG_CONTEXT_CACHED)); teardown(); } @@ -115,9 +115,9 @@ void test_context_normalization_invalid_unicode() { km_core_cu const application_context[] = { 0xDC01, 0x0020, 0x0020, 0xFFFF, 0x0000 }; km_core_cu const cached_context[] = { 0xDC01, 0x0020, 0x0020, 0xFFFF, 0x0000 }; setup("k_001_tiny.kmx"); - assert(km_core_state_context_set_if_needed(test_state, application_context) == KM_CORE_CONTEXT_STATUS_UPDATED); - assert(is_identical_context(application_context, KM_CORE_DEBUG_CONTEXT_APP)); - assert(is_identical_context(cached_context, KM_CORE_DEBUG_CONTEXT_CACHED)); + test_assert(km_core_state_context_set_if_needed(test_state, application_context) == KM_CORE_CONTEXT_STATUS_UPDATED); + test_assert(is_identical_context(application_context, KM_CORE_DEBUG_CONTEXT_APP)); + test_assert(is_identical_context(cached_context, KM_CORE_DEBUG_CONTEXT_CACHED)); teardown(); } @@ -126,9 +126,9 @@ void test_context_normalization_lone_trailing_surrogate() { km_core_cu const application_context[] = { 0xDC01, 0x0020, 0x0020, 0x0000 }; km_core_cu const cached_context[] = /* skipped*/ { 0x0020, 0x0020, 0x0000 }; setup("k_001_tiny.kmx"); - assert(km_core_state_context_set_if_needed(test_state, application_context) == KM_CORE_CONTEXT_STATUS_UPDATED); - assert(is_identical_context(application_context+1, KM_CORE_DEBUG_CONTEXT_APP)); // first code unit is skipped - assert(is_identical_context(cached_context, KM_CORE_DEBUG_CONTEXT_CACHED)); + test_assert(km_core_state_context_set_if_needed(test_state, application_context) == KM_CORE_CONTEXT_STATUS_UPDATED); + test_assert(is_identical_context(application_context+1, KM_CORE_DEBUG_CONTEXT_APP)); // first code unit is skipped + test_assert(is_identical_context(cached_context, KM_CORE_DEBUG_CONTEXT_CACHED)); teardown(); } diff --git a/core/tests/unit/ldml/core_ldml_min.cpp b/core/tests/unit/ldml/core_ldml_min.tests.cpp similarity index 73% rename from core/tests/unit/ldml/core_ldml_min.cpp rename to core/tests/unit/ldml/core_ldml_min.tests.cpp index 72090263a61..fadd62a2a45 100644 --- a/core/tests/unit/ldml/core_ldml_min.cpp +++ b/core/tests/unit/ldml/core_ldml_min.tests.cpp @@ -11,7 +11,7 @@ */ #include -#include +#include #include "keyman_core.h" #include "../load_kmx_file.hpp" @@ -27,15 +27,17 @@ int main(int argc, const char *argv[]) { status = km_core_keyboard_load_from_blob(nowhere, blob.data(), blob.size(), &test_kb); std::cerr << "null km_core_keyboard_load = " << status << std::endl; - assert(status == KM_CORE_STATUS_INVALID_ARGUMENT); - assert(test_kb == nullptr); + test_assert(status == KM_CORE_STATUS_INVALID_ARGUMENT); + test_assert(test_kb == nullptr); km_core_keyboard_dispose(test_kb); km_core_state_dispose(nullptr); km_core_cu_dispose(nullptr); status = km_core_process_event(nullptr, 0, 0, 0, 0); - /* NOTREACHED - assertion fails above. */ - assert(status == KM_CORE_STATUS_INVALID_ARGUMENT); + /* Note: an assertion fails in km_core_process_event on debug builds, + but we will fail on the line below on release builds (as assertions + are disabled); actual return value is KM_CORE_STATUS_INVALID_ARGUMENT */ + test_assert(status == KM_CORE_STATUS_OK); return 0; } diff --git a/core/tests/unit/ldml/test_kmx_plus.cpp b/core/tests/unit/ldml/kmx_plus.tests.cpp similarity index 65% rename from core/tests/unit/ldml/test_kmx_plus.cpp rename to core/tests/unit/ldml/kmx_plus.tests.cpp index 5b14043b742..eed021664c0 100644 --- a/core/tests/unit/ldml/test_kmx_plus.cpp +++ b/core/tests/unit/ldml/kmx_plus.tests.cpp @@ -34,27 +34,27 @@ int test_COMP_KMXPLUS_KEYS_KEY() { 0x00000000 // flags: CHAR }}; std::u16string s0 = e[0].get_to_string(); - assert_equal(s0.length(), 1); - assert_equal(s0.at(0), 0x0127); - assert(s0 == std::u16string(u"ħ")); + test_assert_equal(s0.length(), 1); + test_assert_equal(s0.at(0), 0x0127); + test_assert(s0 == std::u16string(u"ħ")); std::u16string s1 = e[1].get_to_string(); - assert_equal(s1.length(), 2); - assert_equal(s1.at(0), 0xD83D); - assert_equal(s1.at(1), 0xDE40); - assert(s1 == std::u16string(u"🙀")); + test_assert_equal(s1.length(), 2); + test_assert_equal(s1.at(0), 0xD83D); + test_assert_equal(s1.at(1), 0xDE40); + test_assert(s1 == std::u16string(u"🙀")); // now, elems. Parallel. std::u16string es0 = elems[0].get_element_string(); - assert_equal(es0.length(), 1); - assert_equal(es0.at(0), 0x0127); - assert(es0 == std::u16string(u"ħ")); + test_assert_equal(es0.length(), 1); + test_assert_equal(es0.at(0), 0x0127); + test_assert(es0 == std::u16string(u"ħ")); std::u16string es1 = elems[1].get_element_string(); - assert_equal(es1.length(), 2); - assert_equal(es1.at(0), 0xD83D); - assert_equal(es1.at(1), 0xDE40); - assert(es1 == std::u16string(u"🙀")); + test_assert_equal(es1.length(), 2); + test_assert_equal(es1.at(0), 0xD83D); + test_assert_equal(es1.at(1), 0xDE40); + test_assert(es1 == std::u16string(u"🙀")); return EXIT_SUCCESS; } @@ -89,67 +89,67 @@ int test_ldml_vkeys() { vk.add(km::tests::get_vk("K_F"), 0, u""); // K_F as a 'gap' key bool found = false; - assert_equal(vk.lookup(km::tests::get_vk( + test_assert_equal(vk.lookup(km::tests::get_vk( "K_F"), 0, found), u""); - assert_equal(found, true); // K_F found, but empty string (gap) - assert_equal(vk.lookup(km::tests::get_vk( + test_assert_equal(found, true); // K_F found, but empty string (gap) + test_assert_equal(vk.lookup(km::tests::get_vk( "K_ENTER"), 0, found), u""); - assert_equal(found, false); // K_ENTER not found, empty string - assert_equal(vk.lookup(km::tests::get_vk( + test_assert_equal(found, false); // K_ENTER not found, empty string + test_assert_equal(vk.lookup(km::tests::get_vk( "K_A"), 0, found), u"K_A-0"); - assert_equal(found, true); // expect - assert_equal(vk.lookup(km::tests::get_vk( + test_assert_equal(found, true); // expect + test_assert_equal(vk.lookup(km::tests::get_vk( "K_A"), LCTRLFLAG, found), u"K_A-LCTRLFLAG"); - assert_equal(vk.lookup(km::tests::get_vk( + test_assert_equal(vk.lookup(km::tests::get_vk( "K_A"), RCTRLFLAG, found), u"K_A-RCTRLFLAG"); - assert_equal(vk.lookup(km::tests::get_vk( + test_assert_equal(vk.lookup(km::tests::get_vk( "K_A"), LALTFLAG, found), u"K_A-LALTFLAG"); - assert_equal(vk.lookup(km::tests::get_vk( + test_assert_equal(vk.lookup(km::tests::get_vk( "K_A"), RALTFLAG, found), u"K_A-RALTFLAG"); // now try either-side keys :should get the same result with either or both - assert_equal(vk.lookup(km::tests::get_vk( + test_assert_equal(vk.lookup(km::tests::get_vk( "K_B"), LCTRLFLAG, found), u"K_B-K_CTRLFLAG"); - assert_equal(vk.lookup(km::tests::get_vk( + test_assert_equal(vk.lookup(km::tests::get_vk( "K_B"), RCTRLFLAG, found), u"K_B-K_CTRLFLAG"); - assert_equal(vk.lookup(km::tests::get_vk( + test_assert_equal(vk.lookup(km::tests::get_vk( "K_B"), LCTRLFLAG|RCTRLFLAG, found), u"K_B-K_CTRLFLAG"); - assert_equal(vk.lookup(km::tests::get_vk( + test_assert_equal(vk.lookup(km::tests::get_vk( "K_B"), LALTFLAG, found), u"K_B-K_ALTFLAG"); - assert_equal(vk.lookup(km::tests::get_vk( + test_assert_equal(vk.lookup(km::tests::get_vk( "K_B"), RALTFLAG, found), u"K_B-K_ALTFLAG"); - assert_equal(vk.lookup(km::tests::get_vk( + test_assert_equal(vk.lookup(km::tests::get_vk( "K_B"), LALTFLAG|RALTFLAG, found), u"K_B-K_ALTFLAG"); // OOOkay now try BOTH side - assert_equal(vk.lookup(km::tests::get_vk( + test_assert_equal(vk.lookup(km::tests::get_vk( "K_C"), LCTRLFLAG|LALTFLAG, found), u"K_C-K_ALTFLAG|K_CTRLFLAG"); - assert_equal(vk.lookup(km::tests::get_vk( + test_assert_equal(vk.lookup(km::tests::get_vk( "K_C"), LCTRLFLAG|RALTFLAG, found), u"K_C-K_ALTFLAG|K_CTRLFLAG"); - assert_equal(vk.lookup(km::tests::get_vk( + test_assert_equal(vk.lookup(km::tests::get_vk( "K_C"), RCTRLFLAG|LALTFLAG, found), u"K_C-K_ALTFLAG|K_CTRLFLAG"); - assert_equal(vk.lookup(km::tests::get_vk( + test_assert_equal(vk.lookup(km::tests::get_vk( "K_C"), RCTRLFLAG|RALTFLAG, found), u"K_C-K_ALTFLAG|K_CTRLFLAG"); // OOOkay now try either alt - assert_equal(vk.lookup(km::tests::get_vk( + test_assert_equal(vk.lookup(km::tests::get_vk( "K_D"), LCTRLFLAG|LALTFLAG, found), u"K_D-LALTFLAG|K_CTRLFLAG"); - assert_equal(vk.lookup(km::tests::get_vk( + test_assert_equal(vk.lookup(km::tests::get_vk( "K_D"), LCTRLFLAG|RALTFLAG, found), u"K_D-RALTFLAG|K_CTRLFLAG"); - assert_equal(vk.lookup(km::tests::get_vk( + test_assert_equal(vk.lookup(km::tests::get_vk( "K_D"), RCTRLFLAG|LALTFLAG, found), u"K_D-LALTFLAG|K_CTRLFLAG"); - assert_equal(vk.lookup(km::tests::get_vk( + test_assert_equal(vk.lookup(km::tests::get_vk( "K_D"), RCTRLFLAG|RALTFLAG, found), u"K_D-RALTFLAG|K_CTRLFLAG"); // OOOkay now try either ctrl - assert_equal(vk.lookup(km::tests::get_vk( + test_assert_equal(vk.lookup(km::tests::get_vk( "K_E"), LCTRLFLAG|LALTFLAG, found), u"K_E-K_ALTFLAG|LCTRLFLAG"); - assert_equal(vk.lookup(km::tests::get_vk( + test_assert_equal(vk.lookup(km::tests::get_vk( "K_E"), LCTRLFLAG|RALTFLAG, found), u"K_E-K_ALTFLAG|LCTRLFLAG"); - assert_equal(vk.lookup(km::tests::get_vk( + test_assert_equal(vk.lookup(km::tests::get_vk( "K_E"), RCTRLFLAG|LALTFLAG, found), u"K_E-K_ALTFLAG|RCTRLFLAG"); - assert_equal(vk.lookup(km::tests::get_vk( + test_assert_equal(vk.lookup(km::tests::get_vk( "K_E"), RCTRLFLAG|RALTFLAG, found), u"K_E-K_ALTFLAG|RCTRLFLAG"); return EXIT_SUCCESS; @@ -164,13 +164,13 @@ int test_uset() { }; SimpleUSet u0(&r[0], 2); - assert_equal(u0.contains(0x62), true); // b - assert_equal(u0.contains(0x41), false); // A - assert_equal(u0.contains(0x127), true); // ħ + test_assert_equal(u0.contains(0x62), true); // b + test_assert_equal(u0.contains(0x41), false); // A + test_assert_equal(u0.contains(0x127), true); // ħ SimpleUSet uempty; - assert_equal(uempty.contains(0x62), false); - assert_equal(uempty.contains(0x127), false); + test_assert_equal(uempty.contains(0x62), false); + test_assert_equal(uempty.contains(0x127), false); return EXIT_SUCCESS; } diff --git a/core/tests/unit/ldml/ldml.cpp b/core/tests/unit/ldml/ldml.cpp index 339b1f0dc19..78e0aacebac 100644 --- a/core/tests/unit/ldml/ldml.cpp +++ b/core/tests/unit/ldml/ldml.cpp @@ -83,7 +83,7 @@ apply_action( std::vector &test_context) { switch (act.type) { case KM_CORE_IT_END: - assert(false); + test_assert(false); break; case KM_CORE_IT_ALERT: g_beep_found = true; @@ -120,8 +120,8 @@ apply_action( km_core_usv ch = 0; bool matched_text = false; // assume the backspace came from set_action() and there's no further info. - assert(act.backspace.expected_type == KM_CORE_BT_CHAR); - assert(act.backspace.expected_value == 0); + test_assert(act.backspace.expected_type == KM_CORE_BT_CHAR); + test_assert(act.backspace.expected_value == 0); // It is valid for a backspace to be received with an empty text store // as the user can press backspace with no text in the store and Keyman // will pass that back to the client, as the client may do additional @@ -130,7 +130,7 @@ apply_action( // additional text in the text store that Keyman can't see. // If there's anything in the text store, pop it off. Two if a pair. if (text_store.length() > 0) { - assert(!context.empty() && !text_store.empty()); + test_assert(!context.empty() && !text_store.empty()); const auto ch1 = text_store.back(); text_store.pop_back(); if (text_store.length() > 0 && Uni_IsSurrogate2(ch1)) { @@ -153,16 +153,16 @@ apply_action( auto end = context.rbegin(); while (end != context.rend()) { if (end->type == KM_CORE_CT_CHAR) { - assert(!matched_text); - assert_equal(end->character, ch); // expect popped char to be same as what's in context + test_assert(!matched_text); + test_assert_equal(end->character, ch); // expect popped char to be same as what's in context matched_text = true; context.pop_back(); break; // exit on first real char } - assert(end->type != KM_CORE_CT_END); // inappropriate here. + test_assert(end->type != KM_CORE_CT_END); // inappropriate here. context.pop_back(); } - assert(matched_text); + test_assert(matched_text); } break; case KM_CORE_IT_PERSIST_OPT: @@ -175,7 +175,7 @@ apply_action( km_core_context_item* new_context_items = nullptr; // We replace the cached context with the current application context km_core_status status = context_items_from_utf16(text_store.c_str(), &new_context_items); - assert(status == KM_CORE_STATUS_OK); + test_assert(status == KM_CORE_STATUS_OK); copy_context_items_to_vector(new_context_items, context); // also update the test context copy_context_items_to_vector(new_context_items, test_context); @@ -193,7 +193,7 @@ apply_action( test_source.set_caps_lock_on(act.capsLock); break; default: - assert(false); // NOT SUPPORTED + test_assert(false); // NOT SUPPORTED break; } } @@ -254,16 +254,16 @@ verify_context(std::u16string &text_store, km_core_state *&test_state, std::vect break; // success } // fail if only ONE is at end - assert(ci->type != KM_CORE_CT_END && test_ci != test_context.end()); + test_assert(ci->type != KM_CORE_CT_END && test_ci != test_context.end()); // fail if type and marker don't match. - assert(test_ci->type == ci->type && test_ci->marker == ci->marker); + test_assert(test_ci->type == ci->type && test_ci->marker == ci->marker); } km_core_context_items_dispose(citems); if (text_store != buf) { std::cerr << "text store has diverged from buf" << std::endl; std::cerr << "text store: " << string_to_hex(text_store) << " [" << text_store << "]" << std::endl; - assert(false); + test_assert(false); } delete[] buf; } @@ -275,7 +275,7 @@ run_test(const km::core::path &source, const km::core::path &compiled, km::tests const km_core_status expect_load_status = test_source.get_expected_load_status(); auto blob = km::tests::load_kmx_file(compiled.native().c_str()); - assert_equal(km_core_keyboard_load_from_blob(compiled.stem().c_str(), blob.data(), blob.size(), &test_kb), expect_load_status); + test_assert_equal(km_core_keyboard_load_from_blob(compiled.stem().c_str(), blob.data(), blob.size(), &test_kb), expect_load_status); if (expect_load_status != KM_CORE_STATUS_OK) { std::cout << "Keyboard was expected to be invalid, so exiting " << std::endl; @@ -364,7 +364,7 @@ run_test(const km::core::path &source, const km::core::path &compiled, km::tests } break; case km::tests::LDML_ACTION_CHECK_EXPECTED: { if (!normalization_disabled) { - assert(km::core::util::normalize_nfd(action.string)); // TODO-LDML: should be NFC + test_assert(km::core::util::normalize_nfd(action.string)); // TODO-LDML: should be NFC } std::cout << "- check expected" << std::endl; std::cout << "expected : " << string_to_hex(action.string) << " [" << action.string << "]" << std::endl; @@ -453,7 +453,7 @@ int run_all_tests(const km::core::path &source, const km::core::path &compiled, const km::tests::JsonTestMap& json_tests = json_factory.get_tests(); size_t skip_count = 0; - assert(json_tests.size() > 0); + test_assert(json_tests.size() > 0); // Loop over all tests for (const auto& n : json_tests) { const auto test_name = n.first; diff --git a/core/tests/unit/ldml/ldml_test_source.cpp b/core/tests/unit/ldml/ldml_test_source.cpp index beabee6a6f2..94e10e7ac43 100644 --- a/core/tests/unit/ldml/ldml_test_source.cpp +++ b/core/tests/unit/ldml/ldml_test_source.cpp @@ -41,6 +41,8 @@ #include "unicode/usetiter.h" #include "../load_kmx_file.hpp" + +#include #include #define assert_or_return(expr) if(!(expr)) { \ @@ -161,20 +163,20 @@ LdmlTestSource::parse_source_string(std::string const &s) { p++; km_core_usv v; bool had_open_curly = false; - assert(p != s.end()); + test_assert(p != s.end()); if (*p == 'u' || *p == 'U') { // Unicode value p++; if (*p == '{') { p++; - assert(p != s.end()); + test_assert(p != s.end()); had_open_curly = true; } size_t n; std::string s1 = s.substr(p - s.begin(), 8); v = std::stoul(s1, &n, 16); // Allow deadkey_number (U+0001) characters and onward - assert(v >= 0x0001 && v <= 0x10FFFF); + test_assert(v >= 0x0001 && v <= 0x10FFFF); p += n - 1; if (v < 0x10000) { t += km_core_cu(v); @@ -185,13 +187,13 @@ LdmlTestSource::parse_source_string(std::string const &s) { if (had_open_curly) { p++; // close what you opened - assert(*p == '}'); // close curly - assert(p != s.end()); + test_assert(*p == '}'); // close curly + test_assert(p != s.end()); } } else if (*p == 'd') { // Deadkey // TODO, not yet supported - assert(false); + test_assert(false); } } else { t += *p; @@ -210,13 +212,13 @@ LdmlTestSource::parse_u8_source_string(std::string const &u8s) { p++; km_core_usv v; bool had_open_curly = false; - assert(p != s.end()); + test_assert(p != s.end()); if (*p == 'u' || *p == 'U') { // Unicode value p++; if (*p == '{') { p++; - assert(p != s.end()); + test_assert(p != s.end()); had_open_curly = true; } size_t n; @@ -225,7 +227,7 @@ LdmlTestSource::parse_u8_source_string(std::string const &u8s) { std::string s1b = convert(s1); v = std::stoul(s1b, &n, 16); // Allow deadkey_number (U+0001) characters and onward - assert(v >= 0x0001 && v <= 0x10FFFF); + test_assert(v >= 0x0001 && v <= 0x10FFFF); p += n - 1; if (v < 0x10000) { t += km_core_cu(v); @@ -236,13 +238,13 @@ LdmlTestSource::parse_u8_source_string(std::string const &u8s) { if (had_open_curly) { p++; // close what you opened - assert(*p == '}'); // close curly - assert(p != s.end()); + test_assert(*p == '}'); // close curly + test_assert(p != s.end()); } } else if (*p == 'd') { // Deadkey // TODO, not yet supported - assert(false); + test_assert(false); } } else { t += *p; @@ -348,7 +350,7 @@ LdmlTestSource::set_caps_lock_on(bool caps_lock_on) { key_event LdmlTestSource::char_to_event(char ch) { - assert(ch >= 32); + test_assert(ch >= 32); return { km::core::kmx::s_char_to_vkey[(int)ch - 32].vk, (uint16_t)(km::core::kmx::s_char_to_vkey[(int)ch - 32].shifted ? KM_CORE_MODIFIER_SHIFT : 0)}; @@ -382,7 +384,7 @@ LdmlEmbeddedTestSource::vkey_to_event(std::string const &vk_event) { if (vk == 0) { std::cerr << "Error parsing [" << vk_event << "] - could not find vkey or modifier: " << s << std::endl; } - assert(vk != 0); + test_assert(vk != 0); break; // only one vkey allowed } } @@ -390,9 +392,9 @@ LdmlEmbeddedTestSource::vkey_to_event(std::string const &vk_event) { // The string should be empty at this point if (std::getline(f, s, ' ')) { std::cerr << "Error parsing vkey ["<key2 != nullptr); + test_assert(kmxplus->key2 != nullptr); - assert(kmxplus->key2Helper.valid()); + test_assert(kmxplus->key2Helper.valid()); // First, find the string KMX_DWORD strId = kmxplus->strs->find(id); if (strId == 0) { @@ -503,7 +505,7 @@ bool LdmlJsonTestSource::set_key_from_id(key_event& k, const std::u16string& id) // Now, look for the _first_ candidate vkey match in the kmap. for (KMX_DWORD kmapIndex = 0; kmapIndex < kmxplus->key2->kmapCount; kmapIndex++) { auto *kmap = kmxplus->key2Helper.getKmap(kmapIndex); - assert(kmap != nullptr); + test_assert(kmap != nullptr); if (kmap->key == keyIndex) { k = {(km_core_virtual_key)kmap->vkey, (uint16_t)kmap->mod}; return true; @@ -535,7 +537,7 @@ LdmlJsonTestSource::next_action(ldml_action &fillin) { fillin.type = LDML_ACTION_CHECK_EXPECTED; fillin.string = LdmlTestSource::parse_u8_source_string(result.get()); if (!get_normalization_disabled()) { - assert(km::core::util::normalize_nfd(fillin.string)); // TODO-LDML: will be NFC when core is normalizing to NFC + test_assert(km::core::util::normalize_nfd(fillin.string)); // TODO-LDML: will be NFC when core is normalizing to NFC } return; } else if (type == "keystroke") { @@ -550,7 +552,7 @@ LdmlJsonTestSource::next_action(ldml_action &fillin) { fillin.type = LDML_ACTION_EMIT_STRING; fillin.string = LdmlTestSource::parse_u8_source_string(to.get()); if (!get_normalization_disabled()) { - assert(km::core::util::normalize_nfd(fillin.string)); // TODO-LDML: will be NFC when core is normalizing to NFC + test_assert(km::core::util::normalize_nfd(fillin.string)); // TODO-LDML: will be NFC when core is normalizing to NFC } return; } else if (type == "backspace") { @@ -577,7 +579,7 @@ LdmlJsonTestSource::get_context() { auto startContext = data["/startContext/to"_json_pointer]; context = LdmlTestSource::parse_u8_source_string(startContext); if (!get_normalization_disabled()) { - assert(km::core::util::normalize_nfd(context)); // TODO-LDML: should be NFC + test_assert(km::core::util::normalize_nfd(context)); // TODO-LDML: should be NFC } } loaded_context = true; @@ -648,7 +650,7 @@ LdmlJsonRepertoireTestSource::next_action(ldml_action &fillin) { std::size_t len = km::core::kmx::Utf32CharToUtf16(ch, ch16); std::u16string chstr = std::u16string(ch16.ch, len); if (!get_normalization_disabled()) { - assert(km::core::util::normalize_nfd(chstr)); // TODO-LDML: will be NFC when core is normalizing to NFC + test_assert(km::core::util::normalize_nfd(chstr)); // TODO-LDML: will be NFC when core is normalizing to NFC } // append to expected expected.append(chstr); @@ -659,14 +661,14 @@ LdmlJsonRepertoireTestSource::next_action(ldml_action &fillin) { // TODO-LDML: no transforms yet. // TODO-LDML: looking for an exact single key for now - assert(kmxplus != nullptr); + test_assert(kmxplus != nullptr); // lookup the id - assert(kmxplus->strs != nullptr); - assert(kmxplus->key2 != nullptr); - assert(kmxplus->layr != nullptr); + test_assert(kmxplus->strs != nullptr); + test_assert(kmxplus->key2 != nullptr); + test_assert(kmxplus->layr != nullptr); - assert(kmxplus->key2Helper.valid()); - assert(kmxplus->layrHelper.valid()); + test_assert(kmxplus->key2Helper.valid()); + test_assert(kmxplus->layrHelper.valid()); // First, find the string as an id // TODO-LDML: will not work for multi string cases @@ -683,7 +685,7 @@ LdmlJsonRepertoireTestSource::next_action(ldml_action &fillin) { // Now, look for the _first_ candidate vkey match in the kmap. for (KMX_DWORD kmapIndex = 0; kmapIndex < kmxplus->key2->kmapCount; kmapIndex++) { auto *kmap = kmxplus->key2Helper.getKmap(kmapIndex); - assert(kmap != nullptr); + test_assert(kmap != nullptr); if (kmap->key == keyIndex) { fillin.k = {(km_core_virtual_key)kmap->vkey, (uint16_t)kmap->mod}; std::cout << "found vkey " << fillin.k.vk << ":" << fillin.k.modifier_state << std::endl; diff --git a/core/tests/unit/ldml/ldml_test_source.hpp b/core/tests/unit/ldml/ldml_test_source.hpp index 4637af9bd44..8d2b05159a9 100644 --- a/core/tests/unit/ldml/ldml_test_source.hpp +++ b/core/tests/unit/ldml/ldml_test_source.hpp @@ -8,6 +8,9 @@ #include "kmx/kmx_plus.h" +#include +#include + namespace km { namespace tests { @@ -92,7 +95,7 @@ class LdmlTestSource { } bool get_normalization_disabled() const { - assert(setup); // make sure set_ was called first + test_assert(setup); // make sure set_ was called first return normalization_disabled; } diff --git a/core/tests/unit/ldml/meson.build b/core/tests/unit/ldml/meson.build index 71fcf2fe1df..08512bd5500 100644 --- a/core/tests/unit/ldml/meson.build +++ b/core/tests/unit/ldml/meson.build @@ -4,16 +4,6 @@ # Authors: Marc Durdin # -# TODO -- why are these differing from the standard.meson.build flags? -if cpp_compiler.get_id() == 'gcc' or cpp_compiler.get_id() == 'clang' or cpp_compiler.get_id() == 'emscripten' - warns = [ - '-Wno-missing-field-initializers', - '-Wno-unused-parameter' - ] -else - warns = [] -endif - # Build all keyboards in output folder; these are defined here and used in the # keyboards subdir @@ -82,10 +72,10 @@ ldml = executable('ldml', objects: lib.extract_all_objects(recursive: false), ) -core_ldml_min = executable('core_ldml_min', +core_ldml_min = executable('core_ldml_min_tests', [ - 'core_ldml_min.cpp', - meson.current_source_dir() / '../load_kmx_file.cpp', + 'core_ldml_min.tests.cpp', + common_test_files, ], cpp_args: defns + warns, include_directories: [inc, libsrc], @@ -94,12 +84,12 @@ core_ldml_min = executable('core_ldml_min', link_with: [lib], # objects: lib.extract_all_objects(recursive: false), ) -test('core_ldml_min', core_ldml_min, suite: 'ldml', should_fail: true) +test('core_ldml_min_tests', core_ldml_min, suite: 'ldml', should_fail: true) # Build and run additional test_kmx_plus test -e = executable('test_kmx_plus', 'test_kmx_plus.cpp', +e = executable('kmx_plus_tests', 'kmx_plus.tests.cpp', 'ldml_test_utils.cpp', common_test_files, cpp_args: defns + warns, @@ -107,18 +97,18 @@ e = executable('test_kmx_plus', 'test_kmx_plus.cpp', link_args: links + tests_flags, dependencies: [icu_uc, icu_i18n], objects: lib.extract_all_objects(recursive: false)) -test('test_kmx_plus', e, suite: 'ldml') +test('kmx_plus_tests', e, suite: 'ldml') # run transforms / ldml utilities unit test -t = executable('test_transforms', 'test_transforms.cpp', +t = executable('transforms_tests', 'transforms.tests.cpp', common_test_files, cpp_args: defns + warns, include_directories: [inc, libsrc, '../../../../developer/src/ext/json'], link_args: links + tests_flags, dependencies: [icu_uc, icu_i18n], objects: lib.extract_all_objects(recursive: false)) -test('test_transforms', t, suite: 'ldml') +test('transforms_tests', t, suite: 'ldml') # run test_context_normalization ldml unit test @@ -128,19 +118,19 @@ if cpp_compiler.get_id() == 'emscripten' normalization_tests_flags += ['-lnodefs.js', wasm_exported_runtime_methods] endif -test_context_normalization = executable('test_context_normalization', - ['test_context_normalization.cpp', common_test_files], +test_context_normalization = executable('context_normalization_tests', + ['context_normalization.tests.cpp', common_test_files], cpp_args: defns + warns, include_directories: [inc, libsrc, '../../../../developer/src/ext/json'], link_args: links + normalization_tests_flags, dependencies: [icu_uc, icu_i18n], objects: lib.extract_all_objects(recursive: false)) -test('test_context_normalization', test_context_normalization, suite: 'ldml') +test('context_normalization_tests', test_context_normalization, suite: 'ldml') # Build and run additional test_unicode test -test_unicode = executable('test_unicode', 'test_unicode.cpp', - ['test_unicode.cpp', common_test_files, generated_headers], +test_unicode = executable('unicode_tests', 'unicode.tests.cpp', + ['unicode.tests.cpp', common_test_files, generated_headers], cpp_args: defns + warns, include_directories: [inc, libsrc, '../../../../developer/src/ext/json'], link_args: links + tests_flags, @@ -149,7 +139,7 @@ test_unicode = executable('test_unicode', 'test_unicode.cpp', ) -test('test_unicode', test_unicode, suite: 'ldml', +test('unicode_tests', test_unicode, suite: 'ldml', args: [ test_unicode_path / 'nodeversions.json', test_unicode_path / 'package.json', diff --git a/core/tests/unit/ldml/test_transforms.cpp b/core/tests/unit/ldml/transforms.tests.cpp similarity index 88% rename from core/tests/unit/ldml/test_transforms.cpp rename to core/tests/unit/ldml/transforms.tests.cpp index fa909516bc9..411d9410476 100644 --- a/core/tests/unit/ldml/test_transforms.cpp +++ b/core/tests/unit/ldml/transforms.tests.cpp @@ -227,14 +227,14 @@ test_reorder_standalone() { element es(U'a', 0xF4500000 | LDML_ELEM_FLAGS_PREBASE | LDML_ELEM_FLAGS_TERTIARY_BASE); // tertiary -12, primary 80 std::cout << "es flags" << std::hex << es.get_flags() << std::dec << std::endl; // verify element metadata - assert_equal(es.is_uset(), false); - assert_equal(es.get_order(), 0x50); - assert_equal(es.get_tertiary(), -12); - assert_equal(es.is_prebase(), true); - assert_equal(es.is_tertiary_base(), true); + test_assert_equal(es.is_uset(), false); + test_assert_equal(es.get_order(), 0x50); + test_assert_equal(es.get_tertiary(), -12); + test_assert_equal(es.is_prebase(), true); + test_assert_equal(es.is_tertiary_base(), true); // verify element matching - assert_equal(es.matches(U'a'), true); - assert_equal(es.matches(U'b'), false); + test_assert_equal(es.matches(U'a'), true); + test_assert_equal(es.matches(U'b'), false); } std::cout << __FILE__ << ":" << __LINE__ << " - nod-Lana " << std::endl; @@ -255,8 +255,8 @@ test_reorder_standalone() { const COMP_KMXPLUS_USET_USET &toneMarksUset = usets[0]; const SimpleUSet toneMarks(&ranges[toneMarksUset.range], toneMarksUset.count); // validate that the range [1A75, 1A79] matches - assert_equal(toneMarks.contains(0x1A76), true); - assert_equal(toneMarks.contains(0x1A60), false); + test_assert_equal(toneMarks.contains(0x1A76), true); + test_assert_equal(toneMarks.contains(0x1A60), false); std::cout << __FILE__ << ":" << __LINE__ << " - element API test " << std::endl; // element test @@ -264,40 +264,40 @@ test_reorder_standalone() { element es(U'a', (80 << LDML_ELEM_FLAGS_ORDER_BITSHIFT) | LDML_ELEM_FLAGS_PREBASE); // tertiary -12, primary 80 std::cout << "es flags" << std::hex << es.get_flags() << std::dec << std::endl; // verify element metadata - assert_equal(es.is_uset(), false); - assert_equal(es.get_order(), 0x50); - assert_equal(es.get_tertiary(), 0); - assert_equal(es.is_prebase(), true); - assert_equal(es.is_tertiary_base(), false); + test_assert_equal(es.is_uset(), false); + test_assert_equal(es.get_order(), 0x50); + test_assert_equal(es.get_tertiary(), 0); + test_assert_equal(es.is_prebase(), true); + test_assert_equal(es.is_tertiary_base(), false); // verify element matching - assert_equal(es.matches(U'a'), true); - assert_equal(es.matches(U'b'), false); + test_assert_equal(es.matches(U'a'), true); + test_assert_equal(es.matches(U'b'), false); element eu(toneMarks, 0x37F40000); // element metadata std::cout << "eu flags" << std::hex << eu.get_flags() << std::dec << std::endl; - assert_equal(eu.is_uset(), true); + test_assert_equal(eu.is_uset(), true); std::cout << "order" << (int)eu.get_order() << std::endl; - assert_equal(eu.get_order(), -12); - assert_equal(eu.get_tertiary(), 55); - assert_equal(eu.is_prebase(), false); - assert_equal(eu.is_tertiary_base(), false); + test_assert_equal(eu.get_order(), -12); + test_assert_equal(eu.get_tertiary(), 55); + test_assert_equal(eu.is_prebase(), false); + test_assert_equal(eu.is_tertiary_base(), false); // element matching - assert_equal(eu.matches(U'a'), false); - assert_equal(eu.matches(U'\u1A76'), true); - assert_equal(eu.matches(U'\u1A75'), true); + test_assert_equal(eu.matches(U'a'), false); + test_assert_equal(eu.matches(U'\u1A76'), true); + test_assert_equal(eu.matches(U'\u1A75'), true); element_list l; // '[tones]a' l.emplace_back(es); l.emplace_back(eu); std::cout << __FILE__ << ":" << __LINE__ << " - list test " << std::endl; - assert_equal(l.match_end(U"asdfasdf"), 0); // no match - assert_equal(l.match_end(U"a"), 0); // partial substring, fastpath because it's short - assert_equal(l.match_end(U"\u1A76"), 0); // partial substring, fastpath because it's short - assert_equal(l.match_end(U"a\u1A76"), 2); // Match - assert_equal(l.match_end(U"a\u1A75"), 2); // Match - assert_equal(l.match_end(U"SomethingSomethingSomethinga\u1A76"), 2); // Sub-Match + test_assert_equal(l.match_end(U"asdfasdf"), 0); // no match + test_assert_equal(l.match_end(U"a"), 0); // partial substring, fastpath because it's short + test_assert_equal(l.match_end(U"\u1A76"), 0); // partial substring, fastpath because it's short + test_assert_equal(l.match_end(U"a\u1A76"), 2); // Match + test_assert_equal(l.match_end(U"a\u1A75"), 2); // Match + test_assert_equal(l.match_end(U"SomethingSomethingSomethinga\u1A76"), 2); // Sub-Match // generate sort keys std::cout << __FILE__ << ":" << __LINE__ << " - get_sort_key test " << std::endl; @@ -309,24 +309,24 @@ test_reorder_standalone() { i->dump(); } // make sure it matches - assert_equal(l.match_end(str), 2); + test_assert_equal(l.match_end(str), 2); // update the keylist with these elements. l.update_sort_key(0, keylist); std::cout << __FILE__ << ":" << __LINE__ << " updated sortkey" << std::endl; - assert_equal(keylist.size(), 2); + test_assert_equal(keylist.size(), 2); reorder_weight secondary = 0; for (auto i = keylist.begin(); i < keylist.end(); i++) { i->dump(); - assert_equal(i->secondary, secondary); - assert_equal(i->quaternary, secondary); + test_assert_equal(i->secondary, secondary); + test_assert_equal(i->quaternary, secondary); secondary++; } std::cout << std::endl; // spot check first sortkey - assert_equal(keylist.begin()->primary, 80); - assert_equal(keylist.begin()->tertiary, 0); - assert_equal(keylist.begin()->ch, 0x61); + test_assert_equal(keylist.begin()->primary, 80); + test_assert_equal(keylist.begin()->tertiary, 0); + test_assert_equal(keylist.begin()->ch, 0x61); std::cout << __FILE__ << ":" << __LINE__ << " sorted sortkey" << std::endl; // now sort them @@ -336,9 +336,9 @@ test_reorder_standalone() { } std::cout << std::endl; // spot check first sort key - assert_equal(keylist.begin()->primary, -12); - assert_equal(keylist.begin()->tertiary, 55); - assert_equal(keylist.begin()->ch, 0x1A78); + test_assert_equal(keylist.begin()->primary, -12); + test_assert_equal(keylist.begin()->tertiary, 55); + test_assert_equal(keylist.begin()->ch, 0x1A78); } std::cout << __FILE__ << ":" << __LINE__ << " - key test " << std::endl; @@ -486,7 +486,7 @@ test_reorder_standalone() { std::u32string output; size_t len = tr.apply(text, output); zassert_string_equal(output, U""); - assert_equal(len, 0); + test_assert_equal(len, 0); } } } @@ -626,16 +626,16 @@ test_map() { std::cout << __FILE__ << ":" << __LINE__ << " transform_entry::findIndex" << std::endl; { std::deque list; - assert_equal(km::core::util::km_regex::findIndex(U"Does Not Exist", list), -1); + test_assert_equal(km::core::util::km_regex::findIndex(U"Does Not Exist", list), -1); list.emplace_back(U"0th"); list.emplace_back(U"First"); list.emplace_back(U"Second"); - assert_equal(km::core::util::km_regex::findIndex(U"First", list), 1); - assert_equal(km::core::util::km_regex::findIndex(U"0th", list), 0); - assert_equal(km::core::util::km_regex::findIndex(U"Second", list), 2); - assert_equal(km::core::util::km_regex::findIndex(U"Nowhere", list), -1); + test_assert_equal(km::core::util::km_regex::findIndex(U"First", list), 1); + test_assert_equal(km::core::util::km_regex::findIndex(U"0th", list), 0); + test_assert_equal(km::core::util::km_regex::findIndex(U"Second", list), 2); + test_assert_equal(km::core::util::km_regex::findIndex(U"Nowhere", list), -1); } return EXIT_SUCCESS; @@ -659,7 +659,7 @@ test_strutils() { const std::u32string src = U"abc"; const std::u32string dst = remove_markers(src, map); zassert_string_equal(dst, src); // unchanged - assert_equal(count_markers(map), 0); + test_assert_equal(count_markers(map), 0); } { marker_map map; @@ -670,7 +670,7 @@ test_strutils() { zassert_string_equal(dst, expect); marker_map expm = {{U'e', 0x1L}}; assert_marker_map_equal(map, expm); // marker 1 @ e - assert_equal(count_markers(map), 1); + test_assert_equal(count_markers(map), 1); } { marker_map map; @@ -679,7 +679,7 @@ test_strutils() { const std::u32string dst = remove_markers(src, map); const std::u32string expect = src; zassert_string_equal(dst, expect); - assert_equal(count_markers(map), 0); + test_assert_equal(count_markers(map), 0); } { marker_map map; @@ -688,7 +688,7 @@ test_strutils() { const std::u32string dst = remove_markers(src, map); const std::u32string expect = src; // 'q' removed zassert_string_equal(dst, expect); - assert_equal(count_markers(map), 0); + test_assert_equal(count_markers(map), 0); } { marker_map map; @@ -697,7 +697,7 @@ test_strutils() { const std::u32string dst = remove_markers(src, map); const std::u32string expect = src; zassert_string_equal(dst, expect); - assert_equal(count_markers(map), 0); + test_assert_equal(count_markers(map), 0); } { marker_map map; @@ -706,7 +706,7 @@ test_strutils() { const std::u32string dst = remove_markers(src, map); const std::u32string expect = src; zassert_string_equal(dst, expect); - assert_equal(count_markers(map), 0); + test_assert_equal(count_markers(map), 0); } { marker_map map; @@ -717,7 +717,7 @@ test_strutils() { zassert_string_equal(dst, expect); marker_map expm({{MARKER_BEFORE_EOT, 0x1L}}); assert_marker_map_equal(map, expm); - assert_equal(count_markers(map), 1); + test_assert_equal(count_markers(map), 1); } { marker_map map; @@ -730,7 +730,7 @@ test_strutils() { zassert_string_equal(dst, expect); marker_map expm({{U'e', 0x1L}, {0x0320, 0x2L}, {0x0300, 0x3L}, {MARKER_BEFORE_EOT, 0x4L}}); assert_marker_map_equal(map, expm); - assert_equal(count_markers(map), 4); + test_assert_equal(count_markers(map), 4); } { std::cout << __FILE__ << ":" << __LINE__ << " - prepend hex quad" << std::endl; @@ -752,11 +752,11 @@ test_strutils() { } { std::cout << __FILE__ << ":" << __LINE__ << " - parse hex quad" << std::endl; - assert_equal(parse_hex_quad(U"0001"), 0x0001); - assert_equal(parse_hex_quad(U"CAFE"), 0xCAFE); - assert_equal(parse_hex_quad(U"D00d"), 0xD00D); - assert_equal(parse_hex_quad(U"FFFF"), 0xFFFF); - assert_equal(parse_hex_quad(U"zzzz"), 0); // err + test_assert_equal(parse_hex_quad(U"0001"), 0x0001); + test_assert_equal(parse_hex_quad(U"CAFE"), 0xCAFE); + test_assert_equal(parse_hex_quad(U"D00d"), 0xD00D); + test_assert_equal(parse_hex_quad(U"FFFF"), 0xFFFF); + test_assert_equal(parse_hex_quad(U"zzzz"), 0); // err } return EXIT_SUCCESS; } @@ -773,9 +773,9 @@ test_normalize() { const std::u32string src = U"6e\U00000320\U00000300"; // already NFD const std::u32string expect = src; std::u32string dst = src; - assert(normalize_nfd_markers_segment(dst, map)); + test_assert(normalize_nfd_markers_segment(dst, map)); zassert_string_equal(dst, expect); - assert_equal(count_markers(map), 0); + test_assert_equal(count_markers(map), 0); } { marker_map map; @@ -783,9 +783,9 @@ test_normalize() { const std::u32string src = U"6e\U00000300\U00000320"; // swapped const std::u32string expect = U"6e\U00000320\U00000300"; // correct NFD std::u32string dst = src; - assert(normalize_nfd_markers_segment(dst, map)); + test_assert(normalize_nfd_markers_segment(dst, map)); zassert_string_equal(dst, expect); - assert_equal(count_markers(map), 0); + test_assert_equal(count_markers(map), 0); } { @@ -796,11 +796,11 @@ test_normalize() { U"\U0000ffff\U00000008\U00000004"; const std::u32string expect = src; std::u32string dst = src; - assert(normalize_nfd_markers_segment(dst, map)); + test_assert(normalize_nfd_markers_segment(dst, map)); zassert_string_equal(dst, expect); marker_map expm({{U'e', 0x1L}, {0x320, 0x2L}, {0x300, 0x3L}, {MARKER_BEFORE_EOT, 0x4L}}); assert_marker_map_equal(map, expm); - assert_equal(count_markers(map), 4); + test_assert_equal(count_markers(map), 4); } { @@ -811,11 +811,11 @@ test_normalize() { U"\U0000ffff\U00000008\U00000004"; const std::u32string expect = src; std::u32string dst = src; - assert(normalize_nfd_markers_segment(dst, map)); + test_assert(normalize_nfd_markers_segment(dst, map)); zassert_string_equal(dst, expect); marker_map expm({{U'e', 0x1L}, {0x320, 0x2L}, {0x300, 0x3L}, {MARKER_BEFORE_EOT, 0x4L}}); assert_marker_map_equal(map, expm); - assert_equal(count_markers(map), 4); + test_assert_equal(count_markers(map), 4); } { marker_map map; @@ -827,7 +827,7 @@ test_normalize() { U"6\U0000ffff\U00000008\U00000001e\U0000ffff\U00000008\U00000003\U00000320\U0000ffff\U00000008\U00000002\U00000300" U"\U0000ffff\U00000008\U00000004"; std::u32string dst = src; - assert(normalize_nfd_markers_segment(dst, map)); + test_assert(normalize_nfd_markers_segment(dst, map)); if (dst != expect) { std::cout << "dst: " << Debug_UnicodeString(dst) << std::endl; std::cout << "exp: " << Debug_UnicodeString(expect) << std::endl; @@ -835,7 +835,7 @@ test_normalize() { zassert_string_equal(dst, expect); marker_map expm({{U'e', 0x1L}, {0x300, 0x2L}, {0x320, 0x3L}, {MARKER_BEFORE_EOT, 0x4L}}); assert_marker_map_equal(map, expm); - assert_equal(count_markers(map), 4); + test_assert_equal(count_markers(map), 4); } { @@ -845,7 +845,7 @@ test_normalize() { const std::u32string src = U"4e\u0300\uFFFF\u0008\u0001\u0320"; const std::u32string expect = U"4e\uFFFF\u0008\u0001\u0320\u0300"; std::u32string dst = src; - assert(normalize_nfd_markers_segment(dst, map)); + test_assert(normalize_nfd_markers_segment(dst, map)); if (dst != expect) { std::cout << "dst: " << Debug_UnicodeString(dst) << std::endl; std::cout << "exp: " << Debug_UnicodeString(expect) << std::endl; @@ -853,7 +853,7 @@ test_normalize() { zassert_string_equal(dst, expect); marker_map expm({{0x320, 0x1L}}); assert_marker_map_equal(map, expm); - assert_equal(count_markers(map), 1); + test_assert_equal(count_markers(map), 1); } { @@ -863,7 +863,7 @@ test_normalize() { const std::u32string src = U"9ce\u0300\uFFFF\u0008\u0002\u0320\uFFFF\u0008\u0001"; const std::u32string expect = U"9ce\uFFFF\u0008\u0002\u0320\u0300\uFFFF\u0008\u0001"; std::u32string dst = src; - assert(normalize_nfd_markers_segment(dst, map)); + test_assert(normalize_nfd_markers_segment(dst, map)); if (dst != expect) { std::cout << "dst: " << Debug_UnicodeString(dst) << std::endl; std::cout << "exp: " << Debug_UnicodeString(expect) << std::endl; @@ -871,7 +871,7 @@ test_normalize() { zassert_string_equal(dst, expect); marker_map expm({{0x320, 0x2L}, {MARKER_BEFORE_EOT, 0x1L}}); assert_marker_map_equal(map, expm); - assert_equal(count_markers(map), 2); + test_assert_equal(count_markers(map), 2); } { @@ -881,7 +881,7 @@ test_normalize() { const std::u32string src = U"9ce\u0300\\uffff\\u0008\\u0002\u0320\\uffff\\u0008\\u0001"; const std::u32string expect = U"9ce\\uffff\\u0008\\u0002\u0320\u0300\\uffff\\u0008\\u0001"; std::u32string dst = src; - assert(normalize_nfd_markers_segment(dst, map, regex_sentinel)); + test_assert(normalize_nfd_markers_segment(dst, map, regex_sentinel)); if (dst != expect) { std::cout << "dst: " << Debug_UnicodeString(dst) << std::endl; std::cout << " " << dst << std::endl; @@ -891,7 +891,7 @@ test_normalize() { zassert_string_equal(dst, expect); marker_map expm({{0x320, 0x2L}, {MARKER_BEFORE_EOT, 0x1L}}); assert_marker_map_equal(map, expm); - assert_equal(count_markers(map), 2); + test_assert_equal(count_markers(map), 2); } { // from tests - regex edition @@ -900,7 +900,7 @@ test_normalize() { const std::u32string src = U"9ce\u0300\\uffff\\u0008[\\u0001-\\ud7fe]\u0320\\uffff\\u0008\\u0001"; const std::u32string expect = U"9ce\\uffff\\u0008[\\u0001-\\ud7fe]\u0320\u0300\\uffff\\u0008\\u0001"; std::u32string dst = src; - assert(normalize_nfd_markers_segment(dst, map, regex_sentinel)); + test_assert(normalize_nfd_markers_segment(dst, map, regex_sentinel)); if (dst != expect) { std::cout << "dst: " << Debug_UnicodeString(dst) << std::endl; std::cout << "exp: " << Debug_UnicodeString(expect) << std::endl; @@ -908,7 +908,7 @@ test_normalize() { zassert_string_equal(dst, expect); marker_map expm({{0x320, LDML_MARKER_ANY_INDEX}, {MARKER_BEFORE_EOT, 0x1L}}); assert_marker_map_equal(map, expm); - assert_equal(count_markers(map), 2); + test_assert_equal(count_markers(map), 2); } { @@ -918,7 +918,7 @@ test_normalize() { const std::u32string src = U"9ce\u0300\uFFFF\u0008\u0002\uFFFF\u0008\u0002\u0320"; const std::u32string expect = U"9ce\uFFFF\u0008\u0002\uFFFF\u0008\u0002\u0320\u0300"; std::u32string dst = src; - assert(normalize_nfd_markers_segment(dst, map)); + test_assert(normalize_nfd_markers_segment(dst, map)); if (dst != expect) { std::cout << "dst: " << Debug_UnicodeString(dst) << std::endl; std::cout << "exp: " << Debug_UnicodeString(expect) << std::endl; @@ -926,7 +926,7 @@ test_normalize() { zassert_string_equal(dst, expect); marker_map expm({{0x320, 0x2L}, {0x320, 0x2L}}); assert_marker_map_equal(map, expm); - assert_equal(count_markers(map), 2); + test_assert_equal(count_markers(map), 2); } { @@ -936,7 +936,7 @@ test_normalize() { const std::u32string src = U"9ce\u0300\uFFFF\u0008\u0002\uFFFF\u0008\u0001\uFFFF\u0008\u0003\u0320"; const std::u32string expect = U"9ce\uFFFF\u0008\u0002\uFFFF\u0008\u0001\uFFFF\u0008\u0003\u0320\u0300"; std::u32string dst = src; - assert(normalize_nfd_markers_segment(dst, map)); + test_assert(normalize_nfd_markers_segment(dst, map)); if (dst != expect) { std::cout << "dst: " << Debug_UnicodeString(dst) << std::endl; std::cout << "exp: " << Debug_UnicodeString(expect) << std::endl; @@ -972,7 +972,7 @@ test_normalize() { assert_marker_map_equal(map, expm); zassert_string_equal(dst_rem, expect_rem); std::u32string dst_nfd = src; - assert(normalize_nfd_markers(dst_nfd)); + test_assert(normalize_nfd_markers(dst_nfd)); if (dst_nfd != expect_nfd) { std::cout << "dst: " << Debug_UnicodeString(dst_nfd) << std::endl; std::cout << "exp: " << Debug_UnicodeString(expect_nfd) << std::endl; @@ -990,7 +990,7 @@ test_normalize() { marker_map expm({{0x09C7, 0x1L}}); zassert_string_equal(dst_rem, expect_rem); std::u32string dst_nfd = src; - assert(normalize_nfd_markers(dst_nfd)); + test_assert(normalize_nfd_markers(dst_nfd)); if (dst_nfd != expect_nfd) { std::cout << "dst: " << Debug_UnicodeString(dst_nfd) << std::endl; std::cout << "exp: " << Debug_UnicodeString(expect_nfd) << std::endl; @@ -1008,7 +1008,7 @@ test_normalize() { marker_map expm({{0x09C7, 0x1L}}); zassert_string_equal(dst_rem, expect_rem); std::u32string dst_nfd = src; - assert(normalize_nfd_markers(dst_nfd)); + test_assert(normalize_nfd_markers(dst_nfd)); if (dst_nfd != expect_nfd) { std::cout << "dst: " << Debug_UnicodeString(dst_nfd) << std::endl; std::cout << "exp: " << Debug_UnicodeString(expect_nfd) << std::endl; @@ -1026,7 +1026,7 @@ test_normalize() { marker_map expm({{0x09C7, 0x1L}}); zassert_string_equal(dst_rem, expect_rem); std::u32string dst_nfd = src; - assert(normalize_nfd_markers(dst_nfd)); + test_assert(normalize_nfd_markers(dst_nfd)); if (dst_nfd != expect_nfd) { std::cout << "dst: " << Debug_UnicodeString(dst_nfd) << std::endl; std::cout << "exp: " << Debug_UnicodeString(expect_nfd) << std::endl; @@ -1044,7 +1044,7 @@ test_normalize() { marker_map expm({{0x0308, 0x1L}}); zassert_string_equal(dst_rem, expect_rem); std::u32string dst_nfd = src; - assert(normalize_nfd_markers(dst_nfd)); + test_assert(normalize_nfd_markers(dst_nfd)); if (dst_nfd != expect_nfd) { std::cout << "dst: " << Debug_UnicodeString(dst_nfd) << std::endl; std::cout << "exp: " << Debug_UnicodeString(expect_nfd) << std::endl; @@ -1064,7 +1064,7 @@ test_normalize() { marker_map expm({{0x0300, 0x1L}}); zassert_string_equal(dst_rem, expect_rem); std::u32string dst_nfd = src; - assert(normalize_nfd_markers(dst_nfd)); + test_assert(normalize_nfd_markers(dst_nfd)); if (dst_nfd != expect_nfd) { std::cout << "dst: " << Debug_UnicodeString(dst_nfd) << std::endl; std::cout << "exp: " << Debug_UnicodeString(expect_nfd) << std::endl; @@ -1082,7 +1082,7 @@ test_normalize() { marker_map expm({{0x300, 0x1L}}); zassert_string_equal(dst_rem, expect_rem); std::u32string dst_nfd = src; - assert(normalize_nfd_markers(dst_nfd)); + test_assert(normalize_nfd_markers(dst_nfd)); if (dst_nfd != expect_nfd) { std::cout << "dst: " << Debug_UnicodeString(dst_nfd) << std::endl; std::cout << "exp: " << Debug_UnicodeString(expect_nfd) << std::endl; @@ -1100,7 +1100,7 @@ test_normalize() { marker_map expm({{0x0308, 0x1L},{0x0308, 0x2L},{MARKER_BEFORE_EOT, 0x3L}}); zassert_string_equal(dst_rem, expect_rem); std::u32string dst_nfd = src; - assert(normalize_nfd_markers(dst_nfd)); + test_assert(normalize_nfd_markers(dst_nfd)); if (dst_nfd != expect_nfd) { std::cout << "dst: " << Debug_UnicodeString(dst_nfd) << std::endl; std::cout << "exp: " << Debug_UnicodeString(expect_nfd) << std::endl; @@ -1117,7 +1117,7 @@ test_normalize() { const std::u32string src = x; \ const std::u32string expect_nfd = y; \ std::u32string dst_nfd = src; \ - assert(normalize_nfd_markers(dst_nfd)); \ + test_assert(normalize_nfd_markers(dst_nfd)); \ if (dst_nfd != expect_nfd) { \ std::cout << "dst: " << Debug_UnicodeString(dst_nfd) << std::endl; \ std::cout << "exp: " << Debug_UnicodeString(expect_nfd) << std::endl; \ @@ -1145,43 +1145,43 @@ test_util_regex() { { std::cout << __FILE__ << ":" << __LINE__ << " * util_regex.hpp null tests" << std::endl; km::core::util::km_regex r; - assert(!r.valid()); // not valid because of an empty string + test_assert(!r.valid()); // not valid because of an empty string } { std::cout << __FILE__ << ":" << __LINE__ << " * util_regex.hpp simple tests" << std::endl; km::core::util::km_regex r(U"ion"); - assert(r.valid()); + test_assert(r.valid()); const std::u32string to(U"ivity"); const std::deque fromList; const std::deque toList; std::u32string output; auto apply0 = r.apply(U"not present", output, to, fromList, toList); - assert_equal(apply0, 0); // not found + test_assert_equal(apply0, 0); // not found const std::u32string input(U"action"); auto apply1 = r.apply(input, output, to, fromList, toList); - assert_equal(apply1, 3); // matched last 3 codepoints + test_assert_equal(apply1, 3); // matched last 3 codepoints std::u32string expect(U"ivity"); zassert_string_equal(output, expect) } { std::cout << __FILE__ << ":" << __LINE__ << " * util_regex.hpp wide tests" << std::endl; km::core::util::km_regex r(U"e𐒻"); - assert(r.valid()); + test_assert(r.valid()); const std::u32string to(U"𐓏"); const std::deque fromList; const std::deque toList; std::u32string output; const std::u32string input(U":e𐒻"); auto apply1 = r.apply(input, output, to, fromList, toList); - assert_equal(apply1, 2); // matched last 2 codepoints + test_assert_equal(apply1, 2); // matched last 2 codepoints std::u32string expect(U"𐓏"); zassert_string_equal(output, expect) } { std::cout << __FILE__ << ":" << __LINE__ << " * util_regex.hpp simple map tests" << std::endl; km::core::util::km_regex r(U"(A|B|C)"); - assert(r.valid()); + test_assert(r.valid()); const std::u32string to(U"$[1:alpha2]"); // ignored std::deque fromList; fromList.emplace_back(U"A"); @@ -1193,18 +1193,18 @@ test_util_regex() { toList.emplace_back(U"P"); std::u32string output; auto apply0 = r.apply(U"not present", output, to, fromList, toList); - assert_equal(apply0, 0); // not found + test_assert_equal(apply0, 0); // not found const std::u32string input(U"WHOA"); auto apply1 = r.apply(input, output, to, fromList, toList); - assert_equal(apply1, 1); // matched last 1 codepoint + test_assert_equal(apply1, 1); // matched last 1 codepoint std::u32string expect(U"N"); zassert_string_equal(output, expect) } { std::cout << __FILE__ << ":" << __LINE__ << " * util_regex.hpp wide map tests" << std::endl; km::core::util::km_regex r(U"(𐒷|𐒻|𐓏𐓏|x)"); - assert(r.valid()); + test_assert(r.valid()); const std::u32string to(U"$[1:alpha2]"); // ignored std::deque fromList; fromList.emplace_back(U"𐒷"); @@ -1218,15 +1218,15 @@ test_util_regex() { toList.emplace_back(U"𐓏"); std::u32string output; auto apply0 = r.apply(U"not present", output, to, fromList, toList); - assert_equal(apply0, 0); // not found + test_assert_equal(apply0, 0); // not found - assert_equal(r.apply(U"WHO𐓏𐒷", output, to, fromList, toList), 1); + test_assert_equal(r.apply(U"WHO𐓏𐒷", output, to, fromList, toList), 1); zassert_string_equal(output, U"x"); - assert_equal(r.apply(U"WHO𐓏x", output, to, fromList, toList), 1); + test_assert_equal(r.apply(U"WHO𐓏x", output, to, fromList, toList), 1); zassert_string_equal(output, U"𐓏"); - assert_equal(r.apply(U"WHO𐓏𐓏", output, to, fromList, toList), 2); // 2 codepoints + test_assert_equal(r.apply(U"WHO𐓏𐓏", output, to, fromList, toList), 2); // 2 codepoints zassert_string_equal(output, U"𐒻"); } diff --git a/core/tests/unit/ldml/test_unicode.cpp b/core/tests/unit/ldml/unicode.tests.cpp similarity index 95% rename from core/tests/unit/ldml/test_unicode.cpp rename to core/tests/unit/ldml/unicode.tests.cpp index 937125d1727..f9d95893dca 100644 --- a/core/tests/unit/ldml/test_unicode.cpp +++ b/core/tests/unit/ldml/unicode.tests.cpp @@ -66,7 +66,7 @@ nlohmann::json load_json(const km::core::path &jsonpath) { std::ifstream json_file(jsonpath.native()); if (!json_file) { std::cerr << "ERROR Could not load: " << jsonpath << std::endl; - assert (json_file); + test_assert (json_file); } nlohmann::json data = nlohmann::json::parse(json_file); return data; @@ -74,7 +74,7 @@ nlohmann::json load_json(const km::core::path &jsonpath) { /** @returns the major version of 'ver', skipping initial '^'. empty on err */ std::string get_major(const std::string& ver) { - assert(!ver.empty()); + test_assert(!ver.empty()); auto start = 0; // skip leading '^' if (ver[start] == '^') { @@ -82,7 +82,7 @@ std::string get_major(const std::string& ver) { } // find first '.' auto end = ver.find('.', start); - assert(end != std::string::npos); + test_assert(end != std::string::npos); return ver.substr(start, end - start); } @@ -94,9 +94,9 @@ std::string get_block_unicode_ver(const char *blocks_path) { // open Blocks.txt std::ifstream blocks_file( km::core::path(blocks_path).native()); - assert(blocks_file.good()); + test_assert(blocks_file.good()); std::string block_line; - assert(std::getline(blocks_file, block_line)); // first line + test_assert(std::getline(blocks_file, block_line)); // first line // The first line is something such as '# Blocks-15.1.0.txt' // We skip the prefix, and then stop before the suffix @@ -105,12 +105,12 @@ std::string get_block_unicode_ver(const char *blocks_path) { const std::string txt_suffix = ".txt"; // find and skip the prefix - "15.1.0.txt" - assert(block_line.length() > prefix.length()); + test_assert(block_line.length() > prefix.length()); std::string result = block_line.substr(prefix.length()); // "15.1.0" // find and trim before the suffix auto txt_pos = result.find(txt_suffix, 0); - assert(txt_pos != std::string::npos); + test_assert(txt_pos != std::string::npos); result.resize(txt_pos); return result; @@ -167,7 +167,7 @@ const std::string &block_unicode_ver) { // allow the Node.js version to be >= required auto node_engine_num = std::atoi(node_engine_major.c_str()); auto node_num = std::atoi(node_major.c_str()); - assert(node_num >= node_engine_num); + test_assert(node_num >= node_engine_num); // the cxx_icu can come from the Ubuntu environment, so do not depend on it // for now. @@ -213,7 +213,7 @@ void test_has_boundary_before() { std::cerr << "Error: util_normalize_table.h said " << boolstr(km_hbb) << " but ICU said " << boolstr(icu_hbb) << " for " << "has_nfd_boundary_before(0x" << std::hex << cp << std::dec << ")" << std::endl; } - assert(km_hbb == icu_hbb); + test_assert(km_hbb == icu_hbb); } std::cout << "All OK!" << std::endl; } @@ -224,11 +224,11 @@ int test_all(const char *jsonpath, const char *packagepath, const char *blockspa // load the dump of node's process.versions which the meson.build file generated auto versions = load_json(km::core::path(jsonpath)); - assert(!versions.empty()); + test_assert(!versions.empty()); // load our top level package.json auto package = load_json(km::core::path(packagepath)); - assert(!package.empty()); + test_assert(!package.empty()); const auto block_unicode_ver = get_block_unicode_ver(blockspath); diff --git a/core/tests/unit/meson.build b/core/tests/unit/meson.build index ea8b74ea97a..0637ace96e5 100644 --- a/core/tests/unit/meson.build +++ b/core/tests/unit/meson.build @@ -4,6 +4,17 @@ gtest = subproject('gtest') gtest_dep = gtest.get_variable('gtest_dep') gmock_dep = gtest.get_variable('gmock_dep') +# TODO -- why are these differing from the standard.meson.build flags? +# -Wno-unused-parameter --> test_color.h +if cpp_compiler.get_id() == 'gcc' or cpp_compiler.get_id() == 'clang' or cpp_compiler.get_id() == 'emscripten' + warns = [ + '-Wno-missing-field-initializers', + '-Wno-unused-parameter' + ] +else + warns = [] +endif + test_util_files = [ meson.current_source_dir() / 'emscripten_filesystem.cpp', meson.current_source_dir() / 'load_kmx_file.cpp', @@ -26,9 +37,10 @@ endif kmcorekeyboardapitests = executable('km_core_keyboard_api.tests', [ 'km_core_keyboard_api.tests.cpp', - test_util_files, + common_test_files, ], include_directories: [inc, libsrc], + cpp_args: defns + warns, link_args: [ links, extra_link_args ], dependencies: [icu_uc, icu_i18n, gtest_dep, gmock_dep], objects: lib.extract_all_objects(recursive: false), diff --git a/core/tests/unit/utftest/meson.build b/core/tests/unit/utftest/meson.build index 35ad47fed05..70253739b37 100644 --- a/core/tests/unit/utftest/meson.build +++ b/core/tests/unit/utftest/meson.build @@ -4,7 +4,7 @@ # Authors: Tim Eves (TSE) # -e = executable('utftest', 'utftest.cpp', +e = executable('utftest', 'utftest.tests.cpp', objects: lib.extract_objects('../../common/cpp/utfcodec.cpp'), include_directories: [inc, libsrc]) test('utftest', e) diff --git a/core/tests/unit/utftest/utftest.cpp b/core/tests/unit/utftest/utftest.tests.cpp similarity index 100% rename from core/tests/unit/utftest/utftest.cpp rename to core/tests/unit/utftest/utftest.tests.cpp diff --git a/developer/docs/help/reference/kmc/cli/reference.md b/developer/docs/help/reference/kmc/cli/reference.md index e15fa344b27..1de0b64c76d 100644 --- a/developer/docs/help/reference/kmc/cli/reference.md +++ b/developer/docs/help/reference/kmc/cli/reference.md @@ -59,6 +59,18 @@ The following parameters are available: : Rewrites On Screen Keyboard files from source mapping +`kmc generate keyman-keyboard [options] ` + +: Generate a .kmn keyboard project + +`kmc generate ldml-keyboard [options] ` + +: Generate an LDML .xml keyboard project + +`kmc generate lexical-model [options] ` + +: Generate a wordlist lexical model project + `kmc copy origin -o target` : Copy and rename a keyboard project @@ -306,6 +318,164 @@ For more information on the purpose of `analyze osk-char-use` and `analyze rewrite-osk-from-char-use`, see [`&displayMap`](/developer/language/reference/displaymap). +## `kmc generate keyman-keyboard` options + +Generates a new keyboard project with .kmn format keyboard. An ID must be +specified for the output of the project, and an output folder (`-o`). A new +folder with the keyboard ID as its name will be created under the output folder, +and the files in that folder will follow the +[standard file layout](../../file-layout). + +`-t, --target ` + +: Target platforms for the project. Use the values from + [`&targets`](/developer/language/reference/targets). Multiple targets may be + specified, each prefixed with `-t`, or space-separated, surrounded by + quotation marks (e.g. `-t windows -t linux` or `-t "windows linux"`) (default: + `any`) + +`-o, --out-path ` + +: Specifies the parent folder for the project; the folder may already exist. The + project will be generated in a new folder named with the ID of the project + under this path, and that project folder must not exist. + +`-n, --name ` + +: Keyboard descriptive name, used in the + [`&name` store](/developer/language/reference/name) (default: the ID of the + project) + +`-c, --copyright ` + +: [`©right`](/developer/language/reference/copyright) holder for the + project. Do not include the '(C)' or '©' prefixes (default: the author + of the keyboard) + +`-v, --version ` + +: [`&version`](/developer/language/reference/version) of the keyboard, (default: + "1.0"). + +`-L, --language-tag ` + +: A BCP-47 language tag with which the keyboard is associated. More than one + tag may be specified, with each tag prefixed with `-L` (default: no languages). + The tags are referenced in the package metadata. + +`-a, --author ` + +: The name of keyboard author (default: blank) + +`-i, --icon` + +: Include a generated icon. The icon will be a 16x16 pixel box with the first + letters of the first language tag (default: true, include an icon) + +`-d, --description ` + +: A short description of the project, in Markdown. (default: keyboard name) + +## `kmc generate ldml-keyboard` options + +Generates a new keyboard project with LDML .xml format keyboard. An ID must be +specified for the output of the project, and an output folder (`-o`). A new +folder with the keyboard ID as its name will be created under the output folder, +and the files in that folder will follow the +[standard file layout](../../file-layout). + +`-t, --target ` + +: Target platforms for the project. Use the values from + [`&targets`](/developer/language/reference/targets). Multiple targets may be + specified, each prefixed with `-t`, or space-separated, surrounded by + quotation marks (e.g. `-t windows -t linux` or `-t "windows linux"`) (default: + `any`) + +`-o, --out-path ` + +: Specifies the parent folder for the project; the folder may already exist. The + project will be generated in a new folder named with the ID of the project + under this path, and that project folder must not exist. + +`-n, --name ` + +: Keyboard descriptive name, referenced in the keyboard `` + +: Copyright holder for the project. Do not include the '(C)' or '©' + prefixes (default: the author of the keyboard) + +`-v, --version ` + +: Version of the keyboard, referenced in the keyboard `` + +: A BCP-47 language tag with which the keyboard is associated. More than one + tag may be specified, with each tag prefixed with `-L` (default: no languages). + The first tag is referenced in the keyboard `` + +: The name of keyboard author, referenced in `` + +: A short description of the project, in Markdown. (default: keyboard name) + +## `kmc generate lexical-model` options + +Generates a new lexical model project with a TSV wordlist. An ID must be +specified for the output of the project, and an output folder (`-o`). The ID +must match the [`author.bcp47.uniq`](/developer/lexical-models) naming pattern. +A new folder with the model ID as its name will be created under the output +folder, and the files in that folder will follow the +[standard file layout](../../file-layout). + +`-o, --out-path ` + +: Specifies the parent folder for the project; the folder may already exist. The + project will be generated in a new folder named with the ID of the project + under this path, and that project folder must not exist. + +`-n, --name ` + +: Lexical model descriptive name, referenced in the package metadata (default: + the ID of the project) + +`-c, --copyright ` + +: Copyright holder for the project. Do not include the '(C)' or '©' + prefixes (default: the author of the model) + +`-v, --version ` + +: Version of the lexical model, referenced in the package metadata (defaults to + "1.0") + +`-L, --language-tag ` + +: A BCP-47 language tag with which the model is associated. More than one + tag may be specified, with each tag prefixed with `-L` (default: no languages). + The tags are referenced in the package metadata. + +`-a, --author ` + +: The name of model author, referenced in package metadata (default: blank) + +`-d, --description ` + +: A short description of the project, in Markdown. (default: lexical model name) + ## `kmc copy` options Copies a keyboard or lexical model project, renaming files matching the original diff --git a/developer/src/common/include/kmn_compiler_errors.h b/developer/src/common/include/kmn_compiler_errors.h index 4955df5e738..f2410f03b06 100644 --- a/developer/src/common/include/kmn_compiler_errors.h +++ b/developer/src/common/include/kmn_compiler_errors.h @@ -90,16 +90,16 @@ namespace KmnCompilerMessages { ERROR_ZeroLengthString = SevError | 0x017, ERROR_TooManyIndexToKeyRefs = SevError | 0x018, ERROR_UnterminatedString = SevError | 0x019, - ERROR_StringInVirtualKeySection = SevError | 0x01A, - ERROR_AnyInVirtualKeySection = SevError | 0x01B, +// ERROR_StringInVirtualKeySection = SevError | 0x01A, no longer used, see #12612 +// ERROR_AnyInVirtualKeySection = SevError | 0x01B, no longer used, see #12612 ERROR_InvalidAny = SevError | 0x01C, ERROR_StoreDoesNotExist = SevError | 0x01D, - ERROR_BeepInVirtualKeySection = SevError | 0x01E, - ERROR_IndexInVirtualKeySection = SevError | 0x01F, +// ERROR_BeepInVirtualKeySection = SevError | 0x01E, no longer used, see #12612 +// ERROR_IndexInVirtualKeySection = SevError | 0x01F, no longer used, see #12612 ERROR_InvalidIndex = SevError | 0x020, - ERROR_OutsInVirtualKeySection = SevError | 0x021, +// ERROR_OutsInVirtualKeySection = SevError | 0x021, no longer used, see #12612 ERROR_InvalidOuts = SevError | 0x022, - ERROR_ContextInVirtualKeySection = SevError | 0x024, +// ERROR_ContextInVirtualKeySection = SevError | 0x024, no longer used, see #12612 ERROR_InvalidUse = SevError | 0x025, ERROR_GroupDoesNotExist = SevError | 0x026, ERROR_VirtualKeyNotAllowedHere = SevError | 0x027, @@ -117,7 +117,7 @@ namespace KmnCompilerMessages { ERROR_ReservedCharacter = SevError | 0x033, ERROR_InvalidCharacter = SevError | 0x034, ERROR_InvalidCall = SevError | 0x035, - ERROR_CallInVirtualKeySection = SevError | 0x036, +// ERROR_CallInVirtualKeySection = SevError | 0x036, no longer used, see #12612 ERROR_CodeInvalidInKeyStore = SevError | 0x037, ERROR_CannotLoadIncludeFile = SevError | 0x038, @@ -138,7 +138,7 @@ namespace KmnCompilerMessages { ERROR_70FeatureOnly = SevError | 0x046, ERROR_80FeatureOnly = SevError | 0x047, - ERROR_InvalidInVirtualKeySection = SevError | 0x048, +// ERROR_InvalidInVirtualKeySection = SevError | 0x048, no longer used, see #12612 ERROR_InvalidIf = SevError | 0x049, ERROR_InvalidReset = SevError | 0x04A, ERROR_InvalidSet = SevError | 0x04B, diff --git a/developer/src/common/web/utils/build.sh b/developer/src/common/web/utils/build.sh index ddc66549937..f7433cb2faf 100755 --- a/developer/src/common/web/utils/build.sh +++ b/developer/src/common/web/utils/build.sh @@ -49,15 +49,5 @@ function do_build() { builder_run_action clean rm -rf ./build/ builder_run_action configure verify_npm_setup builder_run_action build do_build - -if builder_start_action test; then - eslint . - tsc --build test - readonly C8_THRESHOLD=50 - c8 --reporter=lcov --reporter=text --exclude-after-remap --lines $C8_THRESHOLD --statements $C8_THRESHOLD --branches $C8_THRESHOLD --functions $C8_THRESHOLD mocha - builder_echo warning "Coverage thresholds are currently $C8_THRESHOLD%, which is lower than ideal." - builder_echo warning "Please increase threshold in build.sh as test coverage improves." - builder_finish_action success test -fi - -builder_run_action publish builder_publish_npm +builder_run_action test builder_do_typescript_tests 50 +builder_run_action publish builder_publish_npm diff --git a/developer/src/common/web/utils/package.json b/developer/src/common/web/utils/package.json index 7500db9259d..4f066313f6d 100644 --- a/developer/src/common/web/utils/package.json +++ b/developer/src/common/web/utils/package.json @@ -33,7 +33,7 @@ "build": "tsc -b" }, "mocha": { - "spec": "build/test/**/test-*.js", + "spec": "build/test/**/*.tests.js", "require": [ "source-map-support/register" ] diff --git a/developer/src/common/web/utils/src/types/kmx/kmx-plus-builder/build-elem.ts b/developer/src/common/web/utils/src/types/kmx/kmx-plus-builder/build-elem.ts index 8dafccced21..8e352d191f5 100644 --- a/developer/src/common/web/utils/src/types/kmx/kmx-plus-builder/build-elem.ts +++ b/developer/src/common/web/utils/src/types/kmx/kmx-plus-builder/build-elem.ts @@ -1,5 +1,5 @@ import { constants } from "@keymanapp/ldml-keyboard-constants"; -import { KMXPlus, ElementString } from "@keymanapp/common-types"; +import { KMXPlus, LdmlKeyboardTypes } from "@keymanapp/common-types"; import { build_strs_index, BUILDER_STR_REF, BUILDER_STRS } from "./build-strs.js"; import { BUILDER_SECTION, BUILDER_U32CHAR } from "./builder-section.js"; import { build_uset_index, BUILDER_USET, BUILDER_USET_REF } from "./build-uset.js"; @@ -23,7 +23,7 @@ interface BUILDER_ELEM_STRING { offset: number; length: number; items: BUILDER_ELEM_ELEMENT[]; - _value: ElementString; + _value: LdmlKeyboardTypes.ElementString; }; /** @@ -102,8 +102,8 @@ export function build_elem(source_elem: Elem, sect_strs: BUILDER_STRS, sect_uset return result; } -export function build_elem_index(sect_elem: BUILDER_ELEM, value: ElementString) : BUILDER_ELEM_REF{ - if(!(value instanceof ElementString)) { +export function build_elem_index(sect_elem: BUILDER_ELEM, value: LdmlKeyboardTypes.ElementString) : BUILDER_ELEM_REF{ + if(!(value instanceof LdmlKeyboardTypes.ElementString)) { throw new Error('unexpected value '+value); } diff --git a/developer/src/common/web/utils/src/types/kps/kps-file-reader.ts b/developer/src/common/web/utils/src/types/kps/kps-file-reader.ts index 214a9343f90..73f2280ebc6 100644 --- a/developer/src/common/web/utils/src/types/kps/kps-file-reader.ts +++ b/developer/src/common/web/utils/src/types/kps/kps-file-reader.ts @@ -66,6 +66,17 @@ export class KpsFileReader { boxXmlArray(data.Package?.StartMenu?.Items, 'Item'); boxXmlArray(data.Package?.Strings, 'String'); + if(data.Package?.Info) { + // If no properties are defined on an subitem, then it will be a + // string, and needs to be boxed into a KpsInfoItem object + const info: any = data.Package.Info; + for(const k of Object.keys(info)) { + if(typeof info[k] == 'string') { + info[k] = { _: info[k], $: { URL: '' } }; + } + } + } + return data; } }; diff --git a/developer/src/common/web/utils/src/types/kps/kps-file.ts b/developer/src/common/web/utils/src/types/kps/kps-file.ts index 7724f4a6490..aac583e11f3 100644 --- a/developer/src/common/web/utils/src/types/kps/kps-file.ts +++ b/developer/src/common/web/utils/src/types/kps/kps-file.ts @@ -72,11 +72,11 @@ export interface KpsFileContentFiles { export interface KpsFileContentFile { Name: string; /** @deprecated */ - Description: string; + Description?: string; /** @deprecated */ - CopyLocation: string; + CopyLocation?: string; /** @deprecated */ - FileType: string; + FileType?: string; } export interface KpsFileLexicalModel { diff --git a/developer/src/common/web/utils/test/test-is-valid-email.ts b/developer/src/common/web/utils/test/is-valid-email.tests.ts similarity index 100% rename from developer/src/common/web/utils/test/test-is-valid-email.ts rename to developer/src/common/web/utils/test/is-valid-email.tests.ts diff --git a/developer/src/common/web/utils/test/keyman-touch-layout/test-keyman-touch-layout-file-reader.ts b/developer/src/common/web/utils/test/keyman-touch-layout/keyman-touch-layout-file-reader.tests.ts similarity index 100% rename from developer/src/common/web/utils/test/keyman-touch-layout/test-keyman-touch-layout-file-reader.ts rename to developer/src/common/web/utils/test/keyman-touch-layout/keyman-touch-layout-file-reader.tests.ts diff --git a/developer/src/common/web/utils/test/keyman-touch-layout/test-keyman-touch-layout-round-trip.ts b/developer/src/common/web/utils/test/keyman-touch-layout/keyman-touch-layout-round-trip.tests.ts similarity index 100% rename from developer/src/common/web/utils/test/keyman-touch-layout/test-keyman-touch-layout-round-trip.ts rename to developer/src/common/web/utils/test/keyman-touch-layout/keyman-touch-layout-round-trip.tests.ts diff --git a/developer/src/common/web/utils/test/kmx/test-ldml-keyboard-testdata-reader.ts b/developer/src/common/web/utils/test/kmx/ldml-keyboard-testdata-reader.tests.ts similarity index 100% rename from developer/src/common/web/utils/test/kmx/test-ldml-keyboard-testdata-reader.ts rename to developer/src/common/web/utils/test/kmx/ldml-keyboard-testdata-reader.tests.ts diff --git a/developer/src/common/web/utils/test/kmx/test-ldml-keyboard-xml-reader.ts b/developer/src/common/web/utils/test/kmx/ldml-keyboard-xml-reader.tests.ts similarity index 100% rename from developer/src/common/web/utils/test/kmx/test-ldml-keyboard-xml-reader.ts rename to developer/src/common/web/utils/test/kmx/ldml-keyboard-xml-reader.tests.ts diff --git a/developer/src/common/web/utils/test/kpj/test-kpj-file-reader.ts b/developer/src/common/web/utils/test/kpj/kpj-file-reader.tests.ts similarity index 100% rename from developer/src/common/web/utils/test/kpj/test-kpj-file-reader.ts rename to developer/src/common/web/utils/test/kpj/kpj-file-reader.tests.ts diff --git a/developer/src/common/web/utils/test/kpj/test-kpj-file-writer.ts b/developer/src/common/web/utils/test/kpj/kpj-file-writer.tests.ts similarity index 100% rename from developer/src/common/web/utils/test/kpj/test-kpj-file-writer.ts rename to developer/src/common/web/utils/test/kpj/kpj-file-writer.tests.ts diff --git a/developer/src/common/web/utils/test/kps/test-kps-file-reader.ts b/developer/src/common/web/utils/test/kps/kps-file-reader.tests.ts similarity index 100% rename from developer/src/common/web/utils/test/kps/test-kps-file-reader.ts rename to developer/src/common/web/utils/test/kps/kps-file-reader.tests.ts diff --git a/developer/src/common/web/utils/test/kvks/test-kvk-round-trip.ts b/developer/src/common/web/utils/test/kvks/kvk-round-trip.tests.ts similarity index 100% rename from developer/src/common/web/utils/test/kvks/test-kvk-round-trip.ts rename to developer/src/common/web/utils/test/kvks/kvk-round-trip.tests.ts diff --git a/developer/src/common/web/utils/test/kvks/test-kvk-utils.ts b/developer/src/common/web/utils/test/kvks/kvk-utils.tests.ts similarity index 100% rename from developer/src/common/web/utils/test/kvks/test-kvk-utils.ts rename to developer/src/common/web/utils/test/kvks/kvk-utils.tests.ts diff --git a/developer/src/common/web/utils/test/kvks/test-kvks-file.ts b/developer/src/common/web/utils/test/kvks/kvks-file.tests.ts similarity index 96% rename from developer/src/common/web/utils/test/kvks/test-kvks-file.ts rename to developer/src/common/web/utils/test/kvks/kvks-file.tests.ts index 80851647bd1..4c009e9d5c8 100644 --- a/developer/src/common/web/utils/test/kvks/test-kvks-file.ts +++ b/developer/src/common/web/utils/test/kvks/kvks-file.tests.ts @@ -3,7 +3,7 @@ import 'mocha'; import { makePathToFixture } from '../helpers/index.js'; import KvksFileReader from "../../src/types/kvks/kvks-file-reader.js"; import KvksFileWriter from "../../src/types/kvks/kvks-file-writer.js"; -import { verify_khmer_angkor, verify_balochi_inpage } from './test-kvk-utils.js'; +import { verify_khmer_angkor, verify_balochi_inpage } from './kvk-utils.tests.js'; import { assert } from 'chai'; describe('kvks-file-reader', function() { diff --git a/developer/src/common/web/utils/test/test-license.ts b/developer/src/common/web/utils/test/license.tests.ts similarity index 100% rename from developer/src/common/web/utils/test/test-license.ts rename to developer/src/common/web/utils/test/license.tests.ts diff --git a/developer/src/common/web/utils/test/tsconfig.json b/developer/src/common/web/utils/test/tsconfig.json index fdf5fd474f9..8ba9ac76686 100644 --- a/developer/src/common/web/utils/test/tsconfig.json +++ b/developer/src/common/web/utils/test/tsconfig.json @@ -11,11 +11,11 @@ "baseUrl": ".", }, "include": [ - "**/test-*.ts", + "**/*.tests.ts", "helpers/*.ts", ], "references": [ { "path": "../" }, { "path": "../../test-helpers/" }, ] -} \ No newline at end of file +} diff --git a/developer/src/common/web/utils/test/test-xml-utils.ts b/developer/src/common/web/utils/test/xml-utils.tests.ts similarity index 100% rename from developer/src/common/web/utils/test/test-xml-utils.ts rename to developer/src/common/web/utils/test/xml-utils.tests.ts diff --git a/developer/src/kmc-analyze/build.sh b/developer/src/kmc-analyze/build.sh index a4844c6afc9..ace83ffbbe4 100755 --- a/developer/src/kmc-analyze/build.sh +++ b/developer/src/kmc-analyze/build.sh @@ -25,18 +25,9 @@ builder_parse "$@" #------------------------------------------------------------------------------------------------------------------- -function do_test() { - eslint . - cd test - tsc --build - cd .. - readonly C8_THRESHOLD=70 - c8 --reporter=lcov --reporter=text --lines $C8_THRESHOLD --statements $C8_THRESHOLD --branches $C8_THRESHOLD --functions $C8_THRESHOLD mocha -} - builder_run_action clean rm -rf ./build/ builder_run_action configure verify_npm_setup builder_run_action build tsc --build builder_run_action api api-extractor run --local --verbose -builder_run_action test do_test +builder_run_action test builder_do_typescript_tests 70 builder_run_action publish builder_publish_npm diff --git a/developer/src/kmc-analyze/package.json b/developer/src/kmc-analyze/package.json index 6299bf3a58c..3d31dc04dde 100644 --- a/developer/src/kmc-analyze/package.json +++ b/developer/src/kmc-analyze/package.json @@ -37,7 +37,7 @@ "typescript": "^5.4.5" }, "mocha": { - "spec": "build/test/**/test-*.js", + "spec": "build/test/**/*.tests.js", "require": [ "source-map-support/register" ] diff --git a/developer/src/kmc-analyze/test/test-analyzer-messages.ts b/developer/src/kmc-analyze/test/analyzer-messages.tests.ts similarity index 100% rename from developer/src/kmc-analyze/test/test-analyzer-messages.ts rename to developer/src/kmc-analyze/test/analyzer-messages.tests.ts diff --git a/developer/src/kmc-analyze/test/test-osk-character-use.ts b/developer/src/kmc-analyze/test/osk-character-use.tests.ts similarity index 100% rename from developer/src/kmc-analyze/test/test-osk-character-use.ts rename to developer/src/kmc-analyze/test/osk-character-use.tests.ts diff --git a/developer/src/kmc-analyze/test/tsconfig.json b/developer/src/kmc-analyze/test/tsconfig.json index 01cc026dc10..9a452068536 100644 --- a/developer/src/kmc-analyze/test/tsconfig.json +++ b/developer/src/kmc-analyze/test/tsconfig.json @@ -8,11 +8,11 @@ "baseUrl": ".", }, "include": [ - "**/test-*.ts", + "**/*.tests.ts", "helpers/*.ts", ], "references": [ { "path": "../" }, { "path": "../../common/web/test-helpers/" }, ] -} \ No newline at end of file +} diff --git a/developer/src/kmc-copy/build.sh b/developer/src/kmc-copy/build.sh index 023f0c73bf8..ee8615fc44a 100755 --- a/developer/src/kmc-copy/build.sh +++ b/developer/src/kmc-copy/build.sh @@ -29,22 +29,16 @@ builder_parse "$@" #------------------------------------------------------------------------------------------------------------------- -do_test() { - # note: `export TEST_SAVE_ARTIFACTS=1` to save a copy of artifacts to temp path - # note: `export TEST_SAVE_FIXTURES=1` to get a copy of cloud-based fixtures saved to online/ - eslint . - cd test - tsc --build - cd .. - readonly C8_THRESHOLD=70 - c8 -skip-full --reporter=lcov --reporter=text --lines $C8_THRESHOLD --statements $C8_THRESHOLD --branches $C8_THRESHOLD --functions $C8_THRESHOLD mocha "${builder_extra_params[@]}" - builder_echo warning "Coverage thresholds are currently $C8_THRESHOLD%, which is lower than ideal." - builder_echo warning "Please increase threshold in build.sh as test coverage improves." -} + builder_run_action clean rm -rf ./build/ builder_run_action configure verify_npm_setup builder_run_action build tsc --build builder_run_action api api-extractor run --local --verbose -builder_run_action test do_test + +# note: `export TEST_SAVE_ARTIFACTS=1` to save a copy of artifacts to temp path +# note: `export TEST_SAVE_FIXTURES=1` to get a copy of cloud-based fixtures saved to online/ +# TODO: -skip-full +builder_run_action test builder_do_typescript_tests 70 + builder_run_action publish builder_publish_npm diff --git a/developer/src/kmc-copy/package.json b/developer/src/kmc-copy/package.json index 9c90b345c71..35e587b5a3b 100644 --- a/developer/src/kmc-copy/package.json +++ b/developer/src/kmc-copy/package.json @@ -41,7 +41,7 @@ "typescript": "^5.4.5" }, "mocha": { - "spec": "build/test/**/test-*.js", + "spec": "build/test/**/*.tests.js", "require": [ "source-map-support/register" ] diff --git a/developer/src/kmc-copy/test/test-copier.ts b/developer/src/kmc-copy/test/copier.tests.ts similarity index 100% rename from developer/src/kmc-copy/test/test-copier.ts rename to developer/src/kmc-copy/test/copier.tests.ts diff --git a/developer/src/kmc-copy/test/fixtures/expected/gff.ti_er.gff_tigrinya_eritrea/sil.ti_er.my_version.model.kps b/developer/src/kmc-copy/test/fixtures/expected/gff.ti_er.gff_tigrinya_eritrea/sil.ti_er.my_version.model.kps index 07a430f1ad0..81410bf0641 100644 --- a/developer/src/kmc-copy/test/fixtures/expected/gff.ti_er.gff_tigrinya_eritrea/sil.ti_er.my_version.model.kps +++ b/developer/src/kmc-copy/test/fixtures/expected/gff.ti_er.gff_tigrinya_eritrea/sil.ti_er.my_version.model.kps @@ -20,7 +20,7 @@ © 2023 Geʾez Frontier Foundation Geʾez Frontier Foundation 1.0.1 - The Tigrinya-Eritrea lexical model is based on the content found from 131 issues of the Haddas Eritrea (ሓዳስ ኤርትራ) newspaper. + The Tigrinya-Eritrea lexical model is based on the content found from 131 issues of the Haddas Eritrea (ሓዳስ ኤርትራ) newspaper. diff --git a/developer/src/kmc-copy/test/fixtures/expected/kmhmu_2008/kmhmu_2024.kps b/developer/src/kmc-copy/test/fixtures/expected/kmhmu_2008/kmhmu_2024.kps index 4e352d885ca..f2fbce7c92e 100644 --- a/developer/src/kmc-copy/test/fixtures/expected/kmhmu_2008/kmhmu_2024.kps +++ b/developer/src/kmc-copy/test/fixtures/expected/kmhmu_2008/kmhmu_2024.kps @@ -20,7 +20,7 @@ Kmhmu 2008 © 2008-2018 John Durdin - Lao-script Kmhmu language keyboard + Lao-script Kmhmu language keyboard diff --git a/developer/src/kmc-copy/test/fixtures/projects/gff.ti_er.gff_tigrinya_eritrea/source/gff.ti_er.gff_tigrinya_eritrea.model.kps b/developer/src/kmc-copy/test/fixtures/projects/gff.ti_er.gff_tigrinya_eritrea/source/gff.ti_er.gff_tigrinya_eritrea.model.kps index 5e01595a251..6630ce927f5 100644 --- a/developer/src/kmc-copy/test/fixtures/projects/gff.ti_er.gff_tigrinya_eritrea/source/gff.ti_er.gff_tigrinya_eritrea.model.kps +++ b/developer/src/kmc-copy/test/fixtures/projects/gff.ti_er.gff_tigrinya_eritrea/source/gff.ti_er.gff_tigrinya_eritrea.model.kps @@ -20,7 +20,7 @@ © 2023 Geʾez Frontier Foundation Geʾez Frontier Foundation 1.0.1 - The Tigrinya-Eritrea lexical model is based on the content found from 131 issues of the Haddas Eritrea (ሓዳስ ኤርትራ) newspaper. + The Tigrinya-Eritrea lexical model is based on the content found from 131 issues of the Haddas Eritrea (ሓዳስ ኤርትራ) newspaper. diff --git a/developer/src/kmc-copy/test/fixtures/projects/kmhmu_2008/source/kmhmu_2008.kps b/developer/src/kmc-copy/test/fixtures/projects/kmhmu_2008/source/kmhmu_2008.kps index 5c47f473211..1b2688d1002 100644 --- a/developer/src/kmc-copy/test/fixtures/projects/kmhmu_2008/source/kmhmu_2008.kps +++ b/developer/src/kmc-copy/test/fixtures/projects/kmhmu_2008/source/kmhmu_2008.kps @@ -20,7 +20,7 @@ Kmhmu 2008 © 2008-2018 John Durdin - Lao-script Kmhmu language keyboard + Lao-script Kmhmu language keyboard diff --git a/developer/src/kmc-copy/test/test-messages.ts b/developer/src/kmc-copy/test/messages.tests.ts similarity index 100% rename from developer/src/kmc-copy/test/test-messages.ts rename to developer/src/kmc-copy/test/messages.tests.ts diff --git a/developer/src/kmc-copy/test/tsconfig.json b/developer/src/kmc-copy/test/tsconfig.json index 145099305d2..40f1dcb8cdc 100644 --- a/developer/src/kmc-copy/test/tsconfig.json +++ b/developer/src/kmc-copy/test/tsconfig.json @@ -15,7 +15,7 @@ }, }, "include": [ - "**/test-*.ts", + "**/*.tests.ts", "./shared-options.ts", "./helpers/index.ts" ], @@ -25,4 +25,4 @@ { "path": "../../common/web/test-helpers/" }, { "path": "../" } ] -} \ No newline at end of file +} diff --git a/developer/src/kmc-generate/build.sh b/developer/src/kmc-generate/build.sh index 6a86a9339fe..e99e8288c26 100755 --- a/developer/src/kmc-generate/build.sh +++ b/developer/src/kmc-generate/build.sh @@ -36,17 +36,9 @@ do_build() { cp -R ./src/template/ ./build/src/ } -do_test() { - eslint . - cd test - tsc --build - cd .. - c8 --reporter=lcov --reporter=text mocha "${builder_extra_params[@]}" -} - builder_run_action clean rm -rf ./build/ ./tsconfig.tsbuildinfo builder_run_action configure verify_npm_setup builder_run_action build do_build builder_run_action api api-extractor run --local --verbose -builder_run_action test do_test +builder_run_action test builder_do_typescript_tests builder_run_action publish builder_publish_npm diff --git a/developer/src/kmc-generate/package.json b/developer/src/kmc-generate/package.json index 34eb2b4ebeb..a8e0810338f 100644 --- a/developer/src/kmc-generate/package.json +++ b/developer/src/kmc-generate/package.json @@ -41,7 +41,7 @@ "typescript": "^5.4.5" }, "mocha": { - "spec": "build/test/**/test-*.js", + "spec": "build/test/**/*.tests.js", "require": [ "source-map-support/register" ] diff --git a/developer/src/kmc-generate/test/test-abstract-generator.ts b/developer/src/kmc-generate/test/abstract-generator.tests.ts similarity index 100% rename from developer/src/kmc-generate/test/test-abstract-generator.ts rename to developer/src/kmc-generate/test/abstract-generator.tests.ts diff --git a/developer/src/kmc-generate/test/test-basic-generator.ts b/developer/src/kmc-generate/test/basic-generator.tests.ts similarity index 100% rename from developer/src/kmc-generate/test/test-basic-generator.ts rename to developer/src/kmc-generate/test/basic-generator.tests.ts diff --git a/developer/src/kmc-generate/test/test-keyman-keyboard-generator.ts b/developer/src/kmc-generate/test/keyman-keyboard-generator.tests.ts similarity index 100% rename from developer/src/kmc-generate/test/test-keyman-keyboard-generator.ts rename to developer/src/kmc-generate/test/keyman-keyboard-generator.tests.ts diff --git a/developer/src/kmc-generate/test/test-ldml-keyboard-generator.ts b/developer/src/kmc-generate/test/ldml-keyboard-generator.tests.ts similarity index 100% rename from developer/src/kmc-generate/test/test-ldml-keyboard-generator.ts rename to developer/src/kmc-generate/test/ldml-keyboard-generator.tests.ts diff --git a/developer/src/kmc-generate/test/test-lexical-model-generator.ts b/developer/src/kmc-generate/test/lexical-model-generator.tests.ts similarity index 100% rename from developer/src/kmc-generate/test/test-lexical-model-generator.ts rename to developer/src/kmc-generate/test/lexical-model-generator.tests.ts diff --git a/developer/src/kmc-generate/test/test-messages.ts b/developer/src/kmc-generate/test/messages.tests.ts similarity index 100% rename from developer/src/kmc-generate/test/test-messages.ts rename to developer/src/kmc-generate/test/messages.tests.ts diff --git a/developer/src/kmc-generate/test/tsconfig.json b/developer/src/kmc-generate/test/tsconfig.json index 6cbb24ae0ff..122255b8241 100644 --- a/developer/src/kmc-generate/test/tsconfig.json +++ b/developer/src/kmc-generate/test/tsconfig.json @@ -15,7 +15,7 @@ }, }, "include": [ - "**/test-*.ts", + "**/*.tests.ts", "./shared-options.ts", "./helpers/index.ts" ], @@ -25,4 +25,4 @@ { "path": "../../common/web/test-helpers/" }, { "path": "../" } ] -} \ No newline at end of file +} diff --git a/developer/src/kmc-keyboard-info/build.sh b/developer/src/kmc-keyboard-info/build.sh index c85d76db015..acd6bd65deb 100755 --- a/developer/src/kmc-keyboard-info/build.sh +++ b/developer/src/kmc-keyboard-info/build.sh @@ -32,23 +32,15 @@ function do_configure() { mkdir -p src/imports echo 'export default ' > src/imports/langtags.js cat "$KEYMAN_ROOT/resources/standards-data/langtags/langtags.json" >> src/imports/langtags.js - } + #------------------------------------------------------------------------------------------------------------------- builder_run_action clean rm -rf ./build/ ./tsconfig.tsbuildinfo builder_run_action configure do_configure builder_run_action build tsc --build builder_run_action api api-extractor run --local --verbose - -#------------------------------------------------------------------------------------------------------------------- - -if builder_start_action test; then - eslint . - tsc --build test - c8 --reporter=lcov --reporter=text --exclude-after-remap mocha - builder_finish_action success test -fi +builder_run_action test builder_do_typescript_tests #------------------------------------------------------------------------------------------------------------------- diff --git a/developer/src/kmc-keyboard-info/package.json b/developer/src/kmc-keyboard-info/package.json index 4d4a4210257..45e1001501c 100644 --- a/developer/src/kmc-keyboard-info/package.json +++ b/developer/src/kmc-keyboard-info/package.json @@ -36,7 +36,7 @@ "typescript": "^5.4.5" }, "mocha": { - "spec": "build/test/**/test-*.js", + "spec": "build/test/**/*.tests.js", "require": [ "source-map-support/register" ] diff --git a/developer/src/kmc-keyboard-info/src/keyboard-info-compiler-messages.ts b/developer/src/kmc-keyboard-info/src/keyboard-info-compiler-messages.ts index bf5d989718b..ddf0f2bcb28 100644 --- a/developer/src/kmc-keyboard-info/src/keyboard-info-compiler-messages.ts +++ b/developer/src/kmc-keyboard-info/src/keyboard-info-compiler-messages.ts @@ -2,7 +2,7 @@ import { CompilerErrorNamespace, CompilerErrorSeverity, CompilerMessageSpec as m const Namespace = CompilerErrorNamespace.KeyboardInfoCompiler; // const SevInfo = CompilerErrorSeverity.Info | Namespace; -// const SevHint = CompilerErrorSeverity.Hint | Namespace; +const SevHint = CompilerErrorSeverity.Hint | Namespace; // const SevWarn = CompilerErrorSeverity.Warn | Namespace; const SevError = CompilerErrorSeverity.Error | Namespace; const SevFatal = CompilerErrorSeverity.Fatal | Namespace; @@ -61,5 +61,10 @@ export class KeyboardInfoCompilerMessages { static Error_DescriptionIsMissing = (o:{filename:string}) => m( this.ERROR_DescriptionIsMissing, `The Info.Description field in the package ${def(o.filename)} is required, but is missing or empty.`); + + static HINT_ScriptDoesNotMatch = SevHint | 0x0011; + static Hint_ScriptDoesNotMatch = (o:{script: string, bcp47:string, commonScript: string}) => m( + this.HINT_ScriptDoesNotMatch, + `The script '${def(o.script)}' associated with language tag '${def(o.bcp47)}' does not match the script '${def(o.commonScript)}' for the first language in the package.`); } diff --git a/developer/src/kmc-keyboard-info/src/keyboard-info-compiler.ts b/developer/src/kmc-keyboard-info/src/keyboard-info-compiler.ts index 8e89bb81646..74c06d5d129 100644 --- a/developer/src/kmc-keyboard-info/src/keyboard-info-compiler.ts +++ b/developer/src/kmc-keyboard-info/src/keyboard-info-compiler.ts @@ -502,6 +502,8 @@ export class KeyboardInfoCompiler implements KeymanCompiler { const fontSource = [].concat(...kmpJsonData.keyboards.map(e => e.displayFont ? [e.displayFont] : []), ...kmpJsonData.keyboards.map(e => e.webDisplayFonts ?? [])); const oskFontSource = [].concat(...kmpJsonData.keyboards.map(e => e.oskFont ? [e.oskFont] : []), ...kmpJsonData.keyboards.map(e => e.webOskFonts ?? [])); + let commonScript = null; + for(const bcp47 of Object.keys(keyboard_info.languages)) { const language = keyboard_info.languages[bcp47]; @@ -572,6 +574,15 @@ export class KeyboardInfoCompiler implements KeymanCompiler { ` (${language.regionName})` : '' ); + + const resolvedScript = locale.script ?? langtagsByTag[bcp47]?.script ?? langtagsByTag[locale.language]?.script ?? undefined; + if(commonScript === null) { + commonScript = resolvedScript; + } else { + if(resolvedScript !== commonScript) { + this.callbacks.reportMessage(KeyboardInfoCompilerMessages.Hint_ScriptDoesNotMatch({commonScript, bcp47, script: resolvedScript})) + } + } } return true; } diff --git a/developer/src/kmc-keyboard-info/test/fixtures/hint_script_does_not_match/LICENSE.md b/developer/src/kmc-keyboard-info/test/fixtures/hint_script_does_not_match/LICENSE.md new file mode 100644 index 00000000000..0a8c9054319 --- /dev/null +++ b/developer/src/kmc-keyboard-info/test/fixtures/hint_script_does_not_match/LICENSE.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015-2022 SIL International + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/developer/src/kmc-keyboard-info/test/fixtures/hint_script_does_not_match/build/.gitattributes b/developer/src/kmc-keyboard-info/test/fixtures/hint_script_does_not_match/build/.gitattributes new file mode 100644 index 00000000000..7e3549570d7 --- /dev/null +++ b/developer/src/kmc-keyboard-info/test/fixtures/hint_script_does_not_match/build/.gitattributes @@ -0,0 +1 @@ +khmer_angkor.js -text \ No newline at end of file diff --git a/developer/src/kmc-keyboard-info/test/fixtures/hint_script_does_not_match/build/khmer_angkor.js b/developer/src/kmc-keyboard-info/test/fixtures/hint_script_does_not_match/build/khmer_angkor.js new file mode 100644 index 00000000000..f95f54848cf --- /dev/null +++ b/developer/src/kmc-keyboard-info/test/fixtures/hint_script_does_not_match/build/khmer_angkor.js @@ -0,0 +1,5462 @@ +if(typeof keyman === 'undefined') { + console.log('Keyboard requires KeymanWeb 10.0 or later'); + if(typeof tavultesoft !== 'undefined') tavultesoft.keymanweb.util.alert("This keyboard requires KeymanWeb 10.0 or later"); +} else { +KeymanWeb.KR(new Keyboard_khmer_angkor()); +} +function Keyboard_khmer_angkor() +{ + var modCodes = keyman.osk.modifierCodes; + var keyCodes = keyman.osk.keyCodes; + + this._v=(typeof keyman!="undefined"&&typeof keyman.version=="string")?parseInt(keyman.version,10):9; + this.KI="Keyboard_khmer_angkor"; + this.KN="Khmer Angkor"; + this.KMINVER="10.0"; + this.KV={F:' 1em "Khmer Busra Kbd"',K102:0}; + this.KV.KLS={ + "rightalt": ["‍","‌","@","","$","€","៙","៚","*","{","}","≈","","","","","ៜ","","ឯ","ឫ","ឨ","[","]","ឦ","ឱ","ឰ","ឩ","ឳ","\\","","","","+","-","×","÷",":","‘","’","ឝ","៘","៖","ៈ","","","","","","","<",">","#","&","ឞ",";","",",",".","/","","","","",""," "], + "rightalt-shift": ["","៱","៲","៳","៴","៵","៶","៷","៸","៹","៰","","","","","","᧠","᧡","᧢","᧣","᧤","᧥","᧦","᧧","᧨","᧩","᧪","᧫","","","","","᧬","᧭","᧮","᧯","᧰","᧱","᧲","᧳","᧴","᧵","᧶","","","","","","","᧷","᧸","᧹","᧺","᧻","᧼","᧽","᧾","᧿","","","","","","",""], + "default": ["«","១","២","៣","៤","៥","៦","៧","៨","៩","០","ឥ","ឲ","","","","ឆ","","","រ","ត","យ","","","","ផ","","ឪ","ឮ","","","","","ស","ដ","ថ","ង","ហ","","ក","ល","","","","","","","","","ឋ","ខ","ច","វ","ប","ន","ម","","។","","","","","","","​"], + "shift": ["»","!","ៗ","\"","៛","%","","","","(",")","","=","","","","ឈ","","","ឬ","ទ","","","","","ភ","","ឧ","ឭ","","","","","","ឌ","ធ","អ","ះ","ញ","គ","ឡ","","","","","","","","","ឍ","ឃ","ជ","","ព","ណ","","","៕","?","","","","","",""] + }; + this.KV.BK=(function(x){ + var + empty=Array.apply(null, Array(65)).map(String.prototype.valueOf,""), + result=[], v, i, + modifiers=['default','shift','ctrl','shift-ctrl','alt','shift-alt','ctrl-alt','shift-ctrl-alt']; + for(i=modifiers.length-1;i>=0;i--) { + v = x[modifiers[i]]; + if(v || result.length > 0) { + result=(v ? v : empty).slice().concat(result); + } + } + return result; + })(this.KV.KLS); + this.KDU=0; + this.KH=''; + this.KM=0; + this.KBVER="1.3"; + this.KMBM=modCodes.RALT | modCodes.SHIFT /* 0x0018 */; + this.KVKD="T_17D2_1780 T_17D2_1781 T_17D2_1782 T_17D2_1783 T_17D2_1784 T_17D2_1785 T_17D2_1786 T_17D2_1787 T_17D2_1788 T_17D2_1789 T_17D2_178A T_17D2_178B T_17D2_178C T_17D2_178D T_17D2_178E T_17D2_178F T_17D2_1790 T_17D2_1791 T_17D2_1792 T_17D2_1793 T_17D2_1794 T_17D2_1795 T_17D2_1796 T_17D2_1797 T_17D2_1798 T_17D2_1799 T_17D2_179A T_17D2_179B T_17D2_179C T_17D2_179D T_17D2_179E T_17D2_179F T_17D2_17A0 T_17D2_17A1 T_17D2_17A2 U_0030 U_0031 U_0032 U_0033 U_0034 U_0035 U_0036 U_0037 U_0038 U_0039"; + this.KVKL={ + "tablet": { + "displayUnderlying": false, + "layer": [ + { + "id": "default", + "row": [ + { + "id": "1", + "key": [ + { + "id": "K_1", + "text": "១" + }, + { + "id": "K_2", + "text": "២" + }, + { + "id": "K_3", + "text": "៣" + }, + { + "id": "K_4", + "text": "៤" + }, + { + "id": "K_5", + "text": "៥" + }, + { + "id": "K_6", + "text": "៦" + }, + { + "id": "K_7", + "text": "៧" + }, + { + "id": "K_8", + "text": "៨" + }, + { + "id": "K_9", + "text": "៩" + }, + { + "id": "K_0", + "text": "០" + }, + { + "id": "K_HYPHEN", + "text": "ឥ" + }, + { + "id": "K_EQUAL", + "text": "ឲ" + }, + { + "id": "K_BKSP", + "text": "*BkSp*", + "width": "100", + "sp": "1" + } + ] + }, + { + "id": "2", + "key": [ + { + "id": "K_Q", + "text": "ឆ", + "pad": "75" + }, + { + "id": "K_W", + "text": "" + }, + { + "id": "K_E", + "text": "" + }, + { + "id": "K_R", + "text": "រ" + }, + { + "id": "K_T", + "text": "ត" + }, + { + "id": "K_Y", + "text": "យ" + }, + { + "id": "K_U", + "text": "" + }, + { + "id": "K_I", + "text": "" + }, + { + "id": "K_O", + "text": "" + }, + { + "id": "K_P", + "text": "ផ" + }, + { + "id": "K_LBRKT", + "text": "" + }, + { + "id": "K_RBRKT", + "text": "ឪ" + }, + { + "id": "T_new_138", + "width": "10", + "sp": "10" + } + ] + }, + { + "id": "3", + "key": [ + { + "id": "K_BKQUOTE", + "text": "«" + }, + { + "id": "K_A", + "text": "" + }, + { + "id": "K_S", + "text": "ស" + }, + { + "id": "K_D", + "text": "ដ" + }, + { + "id": "K_F", + "text": "ថ" + }, + { + "id": "K_G", + "text": "ង" + }, + { + "id": "K_H", + "text": "ហ" + }, + { + "id": "K_J", + "text": "" + }, + { + "id": "K_K", + "text": "ក" + }, + { + "id": "K_L", + "text": "ល" + }, + { + "id": "K_COLON", + "text": "" + }, + { + "id": "K_QUOTE", + "text": "" + }, + { + "id": "K_BKSLASH", + "text": "ឮ" + } + ] + }, + { + "id": "4", + "key": [ + { + "id": "K_SHIFT", + "text": "*Shift*", + "width": "160", + "sp": "1", + "nextlayer": "shift" + }, + { + "id": "K_oE2" + }, + { + "id": "K_Z", + "text": "ឋ" + }, + { + "id": "K_X", + "text": "ខ" + }, + { + "id": "K_C", + "text": "ច" + }, + { + "id": "K_V", + "text": "វ" + }, + { + "id": "K_B", + "text": "ប" + }, + { + "id": "K_N", + "text": "ន" + }, + { + "id": "K_M", + "text": "ម" + }, + { + "id": "K_COMMA", + "text": "" + }, + { + "id": "K_PERIOD", + "text": "។" + }, + { + "id": "K_SLASH", + "text": "" + }, + { + "id": "T_new_164", + "width": "10", + "sp": "10" + } + ] + }, + { + "id": "5", + "key": [ + { + "id": "K_LCONTROL", + "text": "*AltGr*", + "width": "160", + "sp": "1", + "nextlayer": "rightalt" + }, + { + "id": "K_LOPT", + "text": "*Menu*", + "width": "160", + "sp": "1" + }, + { + "id": "K_SPACE", + "text": "​", + "width": "930" + }, + { + "id": "K_ENTER", + "text": "*Enter*", + "width": "160", + "sp": "1" + } + ] + } + ] + }, + { + "id": "rightalt", + "row": [ + { + "id": "1", + "key": [ + { + "id": "K_1", + "text": "‌" + }, + { + "id": "K_2", + "text": "@" + }, + { + "id": "K_3", + "text": "" + }, + { + "id": "K_4", + "text": "$" + }, + { + "id": "K_5", + "text": "€" + }, + { + "id": "K_6", + "text": "៙" + }, + { + "id": "K_7", + "text": "៚" + }, + { + "id": "K_8", + "text": "*" + }, + { + "id": "K_9", + "text": "{" + }, + { + "id": "K_0", + "text": "}" + }, + { + "id": "K_HYPHEN", + "text": "≈" + }, + { + "id": "K_EQUAL", + "text": "" + }, + { + "id": "K_BKSP", + "text": "*BkSp*", + "width": "100", + "sp": "1" + } + ] + }, + { + "id": "2", + "key": [ + { + "id": "K_Q", + "text": "ៜ", + "pad": "75" + }, + { + "id": "K_W", + "text": "" + }, + { + "id": "K_E", + "text": "ឯ" + }, + { + "id": "K_R", + "text": "ឫ" + }, + { + "id": "K_T", + "text": "ឨ" + }, + { + "id": "K_Y", + "text": "[" + }, + { + "id": "K_U", + "text": "]" + }, + { + "id": "K_I", + "text": "ឦ" + }, + { + "id": "K_O", + "text": "ឱ" + }, + { + "id": "K_P", + "text": "ឰ" + }, + { + "id": "K_LBRKT", + "text": "ឩ" + }, + { + "id": "K_RBRKT", + "text": "ឳ" + }, + { + "id": "T_new_307", + "width": "10", + "sp": "10" + } + ] + }, + { + "id": "3", + "key": [ + { + "id": "K_BKQUOTE", + "text": "‍" + }, + { + "id": "K_A", + "text": "+" + }, + { + "id": "K_S", + "text": "-" + }, + { + "id": "K_D", + "text": "×" + }, + { + "id": "K_F", + "text": "÷" + }, + { + "id": "K_G", + "text": ":" + }, + { + "id": "K_H", + "text": "‘" + }, + { + "id": "K_J", + "text": "’" + }, + { + "id": "K_K", + "text": "ឝ" + }, + { + "id": "K_L", + "text": "៘" + }, + { + "id": "K_COLON", + "text": "៖" + }, + { + "id": "K_QUOTE", + "text": "ៈ" + }, + { + "id": "K_BKSLASH", + "text": "\\" + } + ] + }, + { + "id": "4", + "key": [ + { + "id": "K_SHIFT", + "text": "*Shift*", + "width": "160", + "sp": "1", + "nextlayer": "shift" + }, + { + "id": "K_oE2" + }, + { + "id": "K_Z", + "text": "<" + }, + { + "id": "K_X", + "text": ">" + }, + { + "id": "K_C", + "text": "#" + }, + { + "id": "K_V", + "text": "&" + }, + { + "id": "K_B", + "text": "ឞ" + }, + { + "id": "K_N", + "text": ";" + }, + { + "id": "K_M", + "text": "" + }, + { + "id": "K_COMMA", + "text": "," + }, + { + "id": "K_PERIOD", + "text": "." + }, + { + "id": "K_SLASH", + "text": "/" + }, + { + "id": "T_new_333", + "width": "10", + "sp": "10" + } + ] + }, + { + "id": "5", + "key": [ + { + "id": "K_LCONTROL", + "text": "*AltGr*", + "width": "160", + "sp": "2", + "nextlayer": "default" + }, + { + "id": "K_LOPT", + "text": "*Menu*", + "width": "160", + "sp": "1" + }, + { + "id": "K_SPACE", + "text": " ", + "width": "930" + }, + { + "id": "K_ENTER", + "text": "*Enter*", + "width": "160", + "sp": "1" + } + ] + } + ] + }, + { + "id": "shift", + "row": [ + { + "id": "1", + "key": [ + { + "id": "K_1", + "text": "!" + }, + { + "id": "K_2", + "text": "ៗ" + }, + { + "id": "K_3", + "text": "\"" + }, + { + "id": "K_4", + "text": "៛" + }, + { + "id": "K_5", + "text": "%" + }, + { + "id": "K_6", + "text": "" + }, + { + "id": "K_7", + "text": "" + }, + { + "id": "K_8", + "text": "" + }, + { + "id": "K_9", + "text": "(" + }, + { + "id": "K_0", + "text": ")" + }, + { + "id": "K_HYPHEN", + "text": "" + }, + { + "id": "K_EQUAL", + "text": "=" + }, + { + "id": "K_BKSP", + "text": "*BkSp*", + "width": "100", + "sp": "1" + } + ] + }, + { + "id": "2", + "key": [ + { + "id": "K_Q", + "text": "ឈ", + "pad": "75" + }, + { + "id": "K_W", + "text": "" + }, + { + "id": "K_E", + "text": "" + }, + { + "id": "K_R", + "text": "ឬ" + }, + { + "id": "K_T", + "text": "ទ" + }, + { + "id": "K_Y", + "text": "" + }, + { + "id": "K_U", + "text": "" + }, + { + "id": "K_I", + "text": "" + }, + { + "id": "K_O", + "text": "" + }, + { + "id": "K_P", + "text": "ភ" + }, + { + "id": "K_LBRKT", + "text": "" + }, + { + "id": "K_RBRKT", + "text": "ឧ" + }, + { + "id": "T_new_364", + "width": "10", + "sp": "10" + } + ] + }, + { + "id": "3", + "key": [ + { + "id": "K_BKQUOTE", + "text": "»" + }, + { + "id": "K_A", + "text": "" + }, + { + "id": "K_S", + "text": "" + }, + { + "id": "K_D", + "text": "ឌ" + }, + { + "id": "K_F", + "text": "ធ" + }, + { + "id": "K_G", + "text": "អ" + }, + { + "id": "K_H", + "text": "ះ" + }, + { + "id": "K_J", + "text": "ញ" + }, + { + "id": "K_K", + "text": "គ" + }, + { + "id": "K_L", + "text": "ឡ" + }, + { + "id": "K_COLON", + "text": "" + }, + { + "id": "K_QUOTE", + "text": "" + }, + { + "id": "K_BKSLASH", + "text": "ឭ" + } + ] + }, + { + "id": "4", + "key": [ + { + "id": "K_SHIFT", + "text": "*Shift*", + "width": "160", + "sp": "2", + "nextlayer": "default" + }, + { + "id": "K_oE2" + }, + { + "id": "K_Z", + "text": "ឍ" + }, + { + "id": "K_X", + "text": "ឃ" + }, + { + "id": "K_C", + "text": "ជ" + }, + { + "id": "K_V", + "text": "" + }, + { + "id": "K_B", + "text": "ព" + }, + { + "id": "K_N", + "text": "ណ" + }, + { + "id": "K_M", + "text": "" + }, + { + "id": "K_COMMA", + "text": "" + }, + { + "id": "K_PERIOD", + "text": "៕" + }, + { + "id": "K_SLASH", + "text": "?" + }, + { + "id": "T_new_390", + "width": "10", + "sp": "10" + } + ] + }, + { + "id": "5", + "key": [ + { + "id": "K_LCONTROL", + "text": "*AltGr*", + "width": "160", + "sp": "1", + "nextlayer": "rightalt" + }, + { + "id": "K_LOPT", + "text": "*Menu*", + "width": "160", + "sp": "1" + }, + { + "id": "K_SPACE", + "width": "930" + }, + { + "id": "K_ENTER", + "text": "*Enter*", + "width": "160", + "sp": "1" + } + ] + } + ] + } + ], + "font": "Khmer Busra Kbd", + "fontsize": "0.8em" + }, + "phone": { + "layer": [ + { + "id": "default", + "row": [ + { + "id": "1", + "key": [ + { + "id": "K_Q", + "text": "ឆ", + "sk": [ + { + "text": "ឈ", + "id": "K_Q", + "layer": "shift" + }, + { + "text": "", + "id": "T_17D2_1786" + }, + { + "text": "", + "id": "T_17D2_1788" + } + ] + }, + { + "id": "K_W", + "text": "", + "sk": [ + { + "text": "", + "id": "K_W", + "layer": "shift" + } + ] + }, + { + "id": "K_E", + "text": "", + "sk": [ + { + "text": "", + "id": "K_E", + "layer": "shift" + }, + { + "text": "", + "id": "K_S", + "layer": "shift" + }, + { + "text": "", + "id": "K_V", + "layer": "shift" + }, + { + "text": "ឯ", + "id": "U_17AF" + }, + { + "text": "ឰ", + "id": "U_17B0" + } + ] + }, + { + "id": "K_R", + "text": "រ", + "sk": [ + { + "text": "", + "id": "T_17D2_179A" + }, + { + "text": "ឫ", + "id": "U_17AB" + }, + { + "text": "ឬ", + "id": "U_17AC" + } + ] + }, + { + "id": "K_T", + "text": "ត", + "sk": [ + { + "text": "ទ", + "id": "K_T", + "layer": "shift" + }, + { + "text": "", + "id": "T_17D2_178F" + }, + { + "text": "", + "id": "T_17D2_1791", + "layer": "default" + } + ] + }, + { + "id": "K_Y", + "text": "យ", + "sk": [ + { + "text": "", + "id": "T_17D2_1799" + } + ] + }, + { + "id": "K_U", + "text": "", + "sk": [ + { + "text": "", + "id": "K_U", + "layer": "shift" + }, + { + "text": "", + "id": "K_Y", + "layer": "shift" + }, + { + "text": "ឧ", + "id": "U_17A7" + }, + { + "text": "ឪ", + "id": "U_17AA", + "layer": "shift" + }, + { + "text": "ឩ", + "id": "U_17A9", + "layer": "shift" + }, + { + "text": "ឨ", + "id": "U_17A8" + } + ] + }, + { + "id": "K_I", + "text": "", + "sk": [ + { + "text": "", + "id": "K_I", + "layer": "shift" + }, + { + "text": "ឥ", + "id": "U_17A5" + }, + { + "text": "ឦ", + "id": "U_17A6", + "layer": "shift" + } + ] + }, + { + "id": "K_O", + "text": "", + "sk": [ + { + "text": "", + "id": "K_O", + "layer": "shift" + }, + { + "text": "", + "id": "K_LBRKT" + }, + { + "text": "", + "id": "K_LBRKT", + "layer": "shift" + }, + { + "text": "", + "id": "K_COLON", + "layer": "shift" + }, + { + "text": "ឱ", + "id": "U_17B1" + }, + { + "text": "ឲ", + "id": "U_17B2" + }, + { + "text": "ឳ", + "id": "U_17B3", + "layer": "shift" + } + ] + }, + { + "id": "K_P", + "text": "ផ", + "sk": [ + { + "text": "ភ", + "id": "K_P", + "layer": "shift" + }, + { + "text": "", + "id": "T_17D2_1795" + }, + { + "text": "", + "id": "T_17D2_1797", + "layer": "default" + } + ] + } + ] + }, + { + "id": "2", + "key": [ + { + "id": "K_A", + "text": "", + "width": "100", + "sk": [ + { + "text": "", + "id": "K_A", + "layer": "shift" + } + ] + }, + { + "id": "K_S", + "text": "ស", + "sk": [ + { + "text": "", + "id": "T_17D2_179F" + }, + { + "text": "ឝ", + "id": "U_179D" + }, + { + "text": "ឞ", + "id": "U_179E" + } + ] + }, + { + "id": "K_D", + "text": "ដ", + "sk": [ + { + "text": "ឌ", + "id": "K_D", + "layer": "shift" + }, + { + "text": "", + "id": "T_17D2_178A" + }, + { + "text": "", + "id": "T_17D2_178C", + "layer": "default" + } + ] + }, + { + "id": "K_F", + "text": "ថ", + "sk": [ + { + "text": "ធ", + "id": "K_F", + "layer": "shift" + }, + { + "text": "", + "id": "T_17D2_1790" + }, + { + "text": "", + "id": "T_17D2_1792", + "layer": "default" + } + ] + }, + { + "id": "K_G", + "text": "ង", + "sk": [ + { + "text": "អ", + "id": "K_G", + "layer": "shift" + }, + { + "text": "", + "id": "T_17D2_1784" + }, + { + "text": "", + "id": "T_17D2_17A2", + "layer": "default" + } + ] + }, + { + "id": "K_H", + "text": "ហ", + "sk": [ + { + "text": "", + "id": "T_17D2_17A0" + }, + { + "text": "ះ", + "id": "K_H", + "layer": "shift" + }, + { + "text": "ៈ", + "id": "U_17C8" + } + ] + }, + { + "id": "K_J", + "text": "ញ", + "layer": "shift", + "sk": [ + { + "text": "", + "id": "T_17D2_1789" + } + ] + }, + { + "id": "K_K", + "text": "ក", + "sk": [ + { + "text": "គ", + "id": "K_K", + "layer": "shift" + }, + { + "text": "", + "id": "T_17D2_1780" + }, + { + "text": "", + "id": "T_17D2_1782" + } + ] + }, + { + "id": "K_L", + "text": "ល", + "sk": [ + { + "text": "ឡ", + "id": "K_L", + "layer": "shift" + }, + { + "text": "", + "id": "T_17D2_179B" + }, + { + "text": "ឭ", + "id": "U_17AD" + }, + { + "text": "ឮ", + "id": "U_17AE" + } + ] + }, + { + "id": "K_COLON", + "text": "" + } + ] + }, + { + "id": "3", + "key": [ + { + "id": "K_Z", + "text": "ឋ", + "sk": [ + { + "text": "ឍ", + "id": "K_Z", + "layer": "shift" + }, + { + "text": "", + "id": "T_17D2_178B" + }, + { + "text": "", + "id": "T_17D2_178D", + "layer": "default" + } + ] + }, + { + "id": "K_X", + "text": "ខ", + "sk": [ + { + "text": "ឃ", + "id": "K_X", + "layer": "shift" + }, + { + "text": "", + "id": "T_17D2_1781" + }, + { + "text": "", + "id": "T_17D2_1783", + "layer": "default" + } + ] + }, + { + "id": "K_C", + "text": "ច", + "sk": [ + { + "text": "ជ", + "id": "K_C", + "layer": "shift" + }, + { + "text": "", + "id": "T_17D2_1785" + }, + { + "text": "", + "id": "T_17D2_1787", + "layer": "default" + } + ] + }, + { + "id": "K_V", + "text": "វ", + "sk": [ + { + "text": "", + "id": "T_17D2_179C" + } + ] + }, + { + "id": "K_B", + "text": "ប", + "sk": [ + { + "text": "ព", + "id": "K_B", + "layer": "shift" + }, + { + "text": "", + "id": "T_17D2_1794" + }, + { + "text": "", + "id": "T_17D2_1796", + "layer": "default" + } + ] + }, + { + "id": "K_N", + "text": "ន", + "sk": [ + { + "text": "ណ", + "id": "K_N", + "layer": "shift" + }, + { + "text": "", + "id": "T_17D2_1793" + }, + { + "text": "", + "id": "T_17D2_178E", + "layer": "default" + } + ] + }, + { + "id": "K_M", + "text": "ម", + "sk": [ + { + "text": "", + "id": "T_17D2_1798" + }, + { + "text": "", + "id": "K_M", + "layer": "shift" + } + ] + }, + { + "id": "K_COMMA", + "text": "", + "sk": [ + { + "text": "", + "id": "K_COMMA", + "layer": "shift" + }, + { + "text": "", + "id": "K_6", + "layer": "shift" + }, + { + "text": "", + "id": "K_7", + "layer": "shift" + }, + { + "text": "", + "id": "K_8", + "layer": "shift" + }, + { + "text": "", + "id": "K_HYPHEN", + "layer": "shift" + }, + { + "text": "", + "id": "U_17D1", + "layer": "shift" + }, + { + "text": "", + "id": "U_17DD", + "layer": "shift" + }, + { + "text": "", + "id": "U_17CE", + "layer": "shift" + } + ] + }, + { + "id": "K_QUOTE", + "text": "", + "width": "100", + "sk": [ + { + "text": "", + "id": "K_QUOTE", + "layer": "shift" + }, + { + "text": "", + "id": "K_SLASH" + } + ] + }, + { + "id": "K_BKSP", + "text": "*BkSp*", + "width": "100", + "sp": "1" + } + ] + }, + { + "id": "4", + "key": [ + { + "id": "K_NUMLOCK", + "text": "១២៣", + "width": "140", + "sp": "1", + "nextlayer": "numeric" + }, + { + "id": "K_LOPT", + "text": "*Menu*", + "width": "120", + "sp": "1" + }, + { + "id": "K_SPACE", + "text": "​", + "width": "555", + "sk": [ + { + "text": " ", + "id": "U_0020", + "layer": "default" + } + ] + }, + { + "id": "K_PERIOD", + "text": "។", + "width": "120", + "sk": [ + { + "text": "៕", + "id": "K_PERIOD", + "layer": "shift" + }, + { + "text": "!", + "id": "U_0021" + }, + { + "text": "?", + "id": "U_003F" + } + ] + }, + { + "id": "K_ENTER", + "text": "*Enter*", + "width": "140", + "sp": "1" + } + ] + } + ] + }, + { + "id": "numeric", + "row": [ + { + "id": "1", + "key": [ + { + "id": "K_1", + "text": "១", + "sk": [ + { + "text": "1", + "id": "U_0031" + } + ] + }, + { + "id": "K_2", + "text": "២", + "sk": [ + { + "text": "2", + "id": "U_0032" + } + ] + }, + { + "id": "K_3", + "text": "៣", + "sk": [ + { + "text": "3", + "id": "U_0033" + } + ] + }, + { + "id": "K_4", + "text": "៤", + "sk": [ + { + "text": "4", + "id": "U_0034" + } + ] + }, + { + "id": "K_5", + "text": "៥", + "sk": [ + { + "text": "5", + "id": "U_0035" + } + ] + }, + { + "id": "K_6", + "text": "៦", + "sk": [ + { + "text": "6", + "id": "U_0036" + } + ] + }, + { + "id": "K_7", + "text": "៧", + "sk": [ + { + "text": "7", + "id": "U_0037" + } + ] + }, + { + "id": "K_8", + "text": "៨", + "sk": [ + { + "text": "8", + "id": "U_0038" + } + ] + }, + { + "id": "K_9", + "text": "៩", + "sk": [ + { + "text": "9", + "id": "U_0039" + } + ] + }, + { + "id": "K_0", + "text": "០", + "sk": [ + { + "text": "0", + "id": "U_0030" + }, + { + "text": "", + "id": "U_17D3" + } + ] + } + ] + }, + { + "id": "2", + "key": [ + { + "id": "U_0040", + "text": "@", + "sk": [ + { + "text": "©", + "id": "U_00A9" + }, + { + "text": "®", + "id": "U_00AE" + } + ] + }, + { + "id": "U_0023", + "text": "#", + "sk": [ + { + "text": "№", + "id": "U_2116" + }, + { + "text": "~", + "id": "U_007E" + } + ] + }, + { + "id": "U_17DB", + "text": "៛", + "sk": [ + { + "text": "$", + "id": "U_0024" + }, + { + "text": "฿", + "id": "U_0E3F" + }, + { + "text": "¢", + "id": "U_00A2" + }, + { + "text": "£", + "id": "U_00A3" + }, + { + "text": "¥", + "id": "U_00A5" + } + ] + }, + { + "id": "U_0026", + "text": "&" + }, + { + "id": "U_0025", + "text": "%", + "sk": [ + { + "text": "‰", + "id": "U_2030" + }, + { + "text": "‱", + "id": "U_2031" + } + ] + }, + { + "id": "U_002B", + "text": "+", + "sk": [ + { + "text": "-", + "id": "U_002D" + }, + { + "text": "×", + "id": "U_00D7" + }, + { + "text": "÷", + "id": "U_00F7" + }, + { + "text": "±", + "id": "U_00B1" + } + ] + }, + { + "id": "U_003D", + "text": "=", + "sk": [ + { + "text": "_", + "id": "U_005F" + }, + { + "text": "≠", + "id": "U_2260" + } + ] + }, + { + "id": "U_002A", + "text": "*", + "sk": [ + { + "text": "^", + "id": "U_005E" + } + ] + }, + { + "id": "U_003F", + "text": "?", + "sk": [ + { + "text": "¿", + "id": "U_00BF" + } + ] + }, + { + "id": "U_0021", + "text": "!", + "sk": [ + { + "text": "¡", + "id": "U_00A1" + } + ] + } + ] + }, + { + "id": "3", + "key": [ + { + "id": "U_2018", + "text": "‘", + "sk": [ + { + "text": "’", + "id": "U_2019" + } + ] + }, + { + "id": "U_201C", + "text": "“", + "sk": [ + { + "text": "”", + "id": "U_201D" + } + ] + }, + { + "id": "U_00AB", + "text": "«", + "sk": [ + { + "text": "»", + "id": "U_00BB" + } + ] + }, + { + "id": "U_002F", + "text": "/", + "sk": [ + { + "text": "\\", + "id": "U_005C" + }, + { + "text": "|", + "id": "U_007C" + }, + { + "text": "¦", + "id": "U_00A6" + } + ] + }, + { + "id": "U_0028", + "text": "(", + "sk": [ + { + "text": ")", + "id": "U_0029" + }, + { + "text": "[", + "id": "U_005B" + }, + { + "text": "]", + "id": "U_005D" + }, + { + "text": "{", + "id": "U_007B" + }, + { + "text": "}", + "id": "U_007D" + } + ] + }, + { + "id": "U_17D9", + "text": "៙", + "sk": [ + { + "text": "៚", + "id": "U_17DA" + }, + { + "text": "ៜ", + "id": "U_17DC" + }, + { + "text": "§", + "id": "U_00A7" + }, + { + "text": "Ø", + "id": "U_00D8" + } + ] + }, + { + "id": "U_17D7", + "text": "ៗ" + }, + { + "id": "U_003C", + "text": "<", + "sk": [ + { + "text": "≤", + "id": "U_2264" + }, + { + "text": ">", + "id": "U_003E" + }, + { + "text": "≥", + "id": "U_2265" + } + ] + }, + { + "id": "U_17D6", + "text": "៖", + "sk": [ + { + "text": ":", + "id": "U_003A" + }, + { + "text": ";", + "id": "U_003B" + }, + { + "text": "…", + "id": "U_2026" + } + ] + }, + { + "id": "K_BKSP", + "text": "*BkSp*", + "sp": "1" + } + ] + }, + { + "id": "4", + "key": [ + { + "id": "K_LCONTROL", + "text": "១២៣", + "width": "140", + "sp": "2", + "nextlayer": "default" + }, + { + "id": "K_LOPT", + "text": "*Menu*", + "width": "120", + "sp": "1" + }, + { + "id": "K_SPACE", + "text": "​", + "width": "555", + "layer": "shift" + }, + { + "id": "K_PERIOD", + "text": "។", + "width": "120", + "sk": [ + { + "text": "៕", + "id": "K_PERIOD", + "layer": "shift" + }, + { + "text": "!", + "id": "U_0021" + }, + { + "text": "?", + "id": "U_003F" + } + ] + }, + { + "id": "K_ENTER", + "text": "*Enter*", + "width": "140", + "sp": "1" + } + ] + } + ] + } + ], + "displayUnderlying": false, + "font": "Khmer Busra Kbd", + "fontsize": "0.8em" + } +}; + this.s_c_key_11=['','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','']; + this.s_c_out_12="កខគឃងចឆជឈញដឋឌឍណតថទធនបផពភមយរលវសហឡអឝឞ"; + this.s_v_gen_key_13=['','','','','','','','','','','','','','','','']; + this.s_v_gen_14="ាិីឹឺុូួើឿៀេែៃោៅ"; + this.s_v_pseudo_key_15=['','','']; + this.s_v_pseudo_16="ំះៈ"; + this.s_v_key_17=['','','','','','','','','','','','','','','','','','','']; + this.s_v_out_18="ាិីឹឺុូួើឿៀេែៃោៅំះៈ"; + this.s_v_any_19="ាិីឹឺុូួើឿៀេែៃោៅំះៈ"; + this.s_v_combo_R_20="េោុិីឹែ"; + this.s_v_combo_N_21="ាុ"; + this.s_v_combo_22="េោុិីឹែាុ"; + this.s_ind_v_key_23=['','','','','','','','','','','','','','','']; + this.s_ind_v_out_24="ឥឦឧឨឩឪឫឬឭឮឯឰឱឲឳ"; + this.s_diacritic_key_25=['','','','','','','','','','','']; + this.s_diacritic_out_26="់័៌៏៍ៈ៎៑៝ៜ្"; + this.s_c_shifter_key_27=['','']; + this.s_c_shifter_28="៉៊"; + this.s_punct_key_29=['','','','','','','','']; + this.s_punct_out_30="។៕៖ៗ៘៙៚៓"; + this.s_latin_punct_key_31=['','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','']; + this.s_latin_punct_out_32="«»()!\"%=?{}\\@*,×./[]‍‌+-÷:≈‘’;<>#&"; + this.s_spaces_key_33=['','','']; + this.s_spaces_out_34="​  "; + this.s_currency_key_35=['','','']; + this.s_currency_out_36="៛$€"; + this.s_digit_key_37=['','','','','','','','','','']; + this.s_digit_out_38="០១២៣៤៥៦៧៨៩"; + this.s_lek_attak_key_39=['','','','','','','','','','']; + this.s_lek_attak_out_40="៰៱៲៳៴៵៶៷៸៹"; + this.s_lunar_date_key_41=['','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','']; + this.s_lunar_date_out_42="᧬᧻᧹᧮᧢᧯᧰᧱᧧᧲᧳᧴᧽᧼᧨᧩᧠᧣᧭᧤᧦᧺᧡᧸᧥᧷᧵᧾᧿᧪᧫᧶"; + this.s_input_subcons_43=['','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','']; + this.s_subcons_44="កខគឃងចឆជឈញដឋឌឍណតថទធនបផពភមយរលវឝឞសហឡអ"; + this.s_arabic_digit_key_45=['','','','','','','','','','']; + this.s_arabic_digit_out_46="0123456789"; + this.s_v_above_47="ិីឹឺើ័"; + this.s_shiftable_c_1st_48="សហអ"; + this.s_shiftable_BA_49="ប"; + this.s_shiftable_c_2nd_50="ងញមយរវនល"; + this.s_shiftable_c_2nd_with_BA_51="ងញមយរវនលប"; + this.s_c_2nd_combo_LO_52="យមងបវ"; + this.s_c_2nd_combo_MO_53="យលងរ"; + this.s_c_1st_combo_LO_54="បហអ"; + this.s_c_1st_combo_MO_55="ហសអ"; + this.s_c_combo_SA_56="បយលមនញងរវអ"; + this.s_c_combo_QA_57="ឆឈបផតទ"; + this.s_c_combo_HA_58="វឣ"; + this.s62="touch"; + this.KVS=[]; + this.gs=function(t,e) { + return this.g_main_0(t,e); + }; + this.gs=function(t,e) { + return this.g_main_0(t,e); + }; + this.g_main_0=function(t,e) { + var k=KeymanWeb,r=0,m=0; + if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_BKSP /* 0x08 */)) { + if(k.KFCM(2,t,['្',{t:'a',a:this.s_c_out_12}])&&k.KIFS(31,this.s62,t)){ + r=m=1; // Line 266 + k.KDC(2,t); + } + else if(k.KFCM(2,t,[{t:'a',a:this.s_v_combo_N_21},'ំ'])){ + r=m=1; // Line 229 + k.KDC(2,t); + } + else if(k.KFCM(2,t,[{t:'a',a:this.s_v_combo_R_20},'ះ'])){ + r=m=1; // Line 230 + k.KDC(2,t); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_B /* 0x42 */)) { + if(1){ + r=m=1; // Line 188 + k.KDC(0,t); + k.KO(-1,t,"ឞ"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_K /* 0x4B */)) { + if(1){ + r=m=1; // Line 188 + k.KDC(0,t); + k.KO(-1,t,"ឝ"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_QUOTE /* 0xDE */)) { + if(1){ + r=m=1; // Line 189 + k.KDC(0,t); + k.KO(-1,t,"ៈ"); + } + else if(1){ + r=m=1; // Line 191 + k.KDC(0,t); + k.KO(-1,t,"ៈ"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_E /* 0x45 */)) { + if(1){ + r=m=1; // Line 190 + k.KDC(0,t); + k.KO(-1,t,"ឯ"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_I /* 0x49 */)) { + if(1){ + r=m=1; // Line 190 + k.KDC(0,t); + k.KO(-1,t,"ឦ"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_O /* 0x4F */)) { + if(1){ + r=m=1; // Line 190 + k.KDC(0,t); + k.KO(-1,t,"ឱ"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_P /* 0x50 */)) { + if(1){ + r=m=1; // Line 190 + k.KDC(0,t); + k.KO(-1,t,"ឰ"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_R /* 0x52 */)) { + if(1){ + r=m=1; // Line 190 + k.KDC(0,t); + k.KO(-1,t,"ឫ"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_T /* 0x54 */)) { + if(1){ + r=m=1; // Line 190 + k.KDC(0,t); + k.KO(-1,t,"ឨ"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_LBRKT /* 0xDB */)) { + if(1){ + r=m=1; // Line 190 + k.KDC(0,t); + k.KO(-1,t,"ឩ"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_RBRKT /* 0xDD */)) { + if(1){ + r=m=1; // Line 190 + k.KDC(0,t); + k.KO(-1,t,"ឳ"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_3 /* 0x33 */)) { + if(1){ + r=m=1; // Line 191 + k.KDC(0,t); + k.KO(-1,t,"៑"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_Q /* 0x51 */)) { + if(1){ + r=m=1; // Line 191 + k.KDC(0,t); + k.KO(-1,t,"ៜ"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_W /* 0x57 */)) { + if(1){ + r=m=1; // Line 191 + k.KDC(0,t); + k.KO(-1,t,"៝"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_EQUAL /* 0xBB */)) { + if(1){ + r=m=1; // Line 191 + k.KDC(0,t); + k.KO(-1,t,"៎"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_6 /* 0x36 */)) { + if(1){ + r=m=1; // Line 193 + k.KDC(0,t); + k.KO(-1,t,"៙"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_7 /* 0x37 */)) { + if(1){ + r=m=1; // Line 193 + k.KDC(0,t); + k.KO(-1,t,"៚"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_L /* 0x4C */)) { + if(1){ + r=m=1; // Line 193 + k.KDC(0,t); + k.KO(-1,t,"៘"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_M /* 0x4D */)) { + if(1){ + r=m=1; // Line 193 + k.KDC(0,t); + k.KO(-1,t,"៓"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_COLON /* 0xBA */)) { + if(1){ + r=m=1; // Line 193 + k.KDC(0,t); + k.KO(-1,t,"៖"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_0 /* 0x30 */)) { + if(1){ + r=m=1; // Line 194 + k.KDC(0,t); + k.KO(-1,t,"}"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_1 /* 0x31 */)) { + if(1){ + r=m=1; // Line 194 + k.KDC(0,t); + k.KO(-1,t,"‌"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_2 /* 0x32 */)) { + if(1){ + r=m=1; // Line 194 + k.KDC(0,t); + k.KO(-1,t,"@"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_8 /* 0x38 */)) { + if(1){ + r=m=1; // Line 194 + k.KDC(0,t); + k.KO(-1,t,"*"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_9 /* 0x39 */)) { + if(1){ + r=m=1; // Line 194 + k.KDC(0,t); + k.KO(-1,t,"{"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_A /* 0x41 */)) { + if(1){ + r=m=1; // Line 194 + k.KDC(0,t); + k.KO(-1,t,"+"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_C /* 0x43 */)) { + if(1){ + r=m=1; // Line 194 + k.KDC(0,t); + k.KO(-1,t,"#"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_D /* 0x44 */)) { + if(1){ + r=m=1; // Line 194 + k.KDC(0,t); + k.KO(-1,t,"×"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_F /* 0x46 */)) { + if(1){ + r=m=1; // Line 194 + k.KDC(0,t); + k.KO(-1,t,"÷"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_G /* 0x47 */)) { + if(1){ + r=m=1; // Line 194 + k.KDC(0,t); + k.KO(-1,t,":"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_H /* 0x48 */)) { + if(1){ + r=m=1; // Line 194 + k.KDC(0,t); + k.KO(-1,t,"‘"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_J /* 0x4A */)) { + if(1){ + r=m=1; // Line 194 + k.KDC(0,t); + k.KO(-1,t,"’"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_N /* 0x4E */)) { + if(1){ + r=m=1; // Line 194 + k.KDC(0,t); + k.KO(-1,t,";"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_S /* 0x53 */)) { + if(1){ + r=m=1; // Line 194 + k.KDC(0,t); + k.KO(-1,t,"-"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_U /* 0x55 */)) { + if(1){ + r=m=1; // Line 194 + k.KDC(0,t); + k.KO(-1,t,"]"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_V /* 0x56 */)) { + if(1){ + r=m=1; // Line 194 + k.KDC(0,t); + k.KO(-1,t,"&"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_X /* 0x58 */)) { + if(1){ + r=m=1; // Line 194 + k.KDC(0,t); + k.KO(-1,t,">"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_Y /* 0x59 */)) { + if(1){ + r=m=1; // Line 194 + k.KDC(0,t); + k.KO(-1,t,"["); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_Z /* 0x5A */)) { + if(1){ + r=m=1; // Line 194 + k.KDC(0,t); + k.KO(-1,t,"<"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_COMMA /* 0xBC */)) { + if(1){ + r=m=1; // Line 194 + k.KDC(0,t); + k.KO(-1,t,","); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_HYPHEN /* 0xBD */)) { + if(1){ + r=m=1; // Line 194 + k.KDC(0,t); + k.KO(-1,t,"≈"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_PERIOD /* 0xBE */)) { + if(1){ + r=m=1; // Line 194 + k.KDC(0,t); + k.KO(-1,t,"."); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_SLASH /* 0xBF */)) { + if(1){ + r=m=1; // Line 194 + k.KDC(0,t); + k.KO(-1,t,"/"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_BKQUOTE /* 0xC0 */)) { + if(1){ + r=m=1; // Line 194 + k.KDC(0,t); + k.KO(-1,t,"‍"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_BKSLASH /* 0xDC */)) { + if(1){ + r=m=1; // Line 194 + k.KDC(0,t); + k.KO(-1,t,"\\"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_4 /* 0x34 */)) { + if(1){ + r=m=1; // Line 195 + k.KDC(0,t); + k.KO(-1,t,"$"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_5 /* 0x35 */)) { + if(1){ + r=m=1; // Line 195 + k.KDC(0,t); + k.KO(-1,t,"€"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_0 /* 0x30 */)) { + if(1){ + r=m=1; // Line 197 + k.KDC(0,t); + k.KO(-1,t,"៰"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_1 /* 0x31 */)) { + if(1){ + r=m=1; // Line 197 + k.KDC(0,t); + k.KO(-1,t,"៱"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_2 /* 0x32 */)) { + if(1){ + r=m=1; // Line 197 + k.KDC(0,t); + k.KO(-1,t,"៲"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_3 /* 0x33 */)) { + if(1){ + r=m=1; // Line 197 + k.KDC(0,t); + k.KO(-1,t,"៳"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_4 /* 0x34 */)) { + if(1){ + r=m=1; // Line 197 + k.KDC(0,t); + k.KO(-1,t,"៴"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_5 /* 0x35 */)) { + if(1){ + r=m=1; // Line 197 + k.KDC(0,t); + k.KO(-1,t,"៵"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_6 /* 0x36 */)) { + if(1){ + r=m=1; // Line 197 + k.KDC(0,t); + k.KO(-1,t,"៶"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_7 /* 0x37 */)) { + if(1){ + r=m=1; // Line 197 + k.KDC(0,t); + k.KO(-1,t,"៷"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_8 /* 0x38 */)) { + if(1){ + r=m=1; // Line 197 + k.KDC(0,t); + k.KO(-1,t,"៸"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_9 /* 0x39 */)) { + if(1){ + r=m=1; // Line 197 + k.KDC(0,t); + k.KO(-1,t,"៹"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_A /* 0x41 */)) { + if(1){ + r=m=1; // Line 198 + k.KDC(0,t); + k.KO(-1,t,"᧬"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_B /* 0x42 */)) { + if(1){ + r=m=1; // Line 198 + k.KDC(0,t); + k.KO(-1,t,"᧻"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_C /* 0x43 */)) { + if(1){ + r=m=1; // Line 198 + k.KDC(0,t); + k.KO(-1,t,"᧹"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_D /* 0x44 */)) { + if(1){ + r=m=1; // Line 198 + k.KDC(0,t); + k.KO(-1,t,"᧮"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_E /* 0x45 */)) { + if(1){ + r=m=1; // Line 198 + k.KDC(0,t); + k.KO(-1,t,"᧢"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_F /* 0x46 */)) { + if(1){ + r=m=1; // Line 198 + k.KDC(0,t); + k.KO(-1,t,"᧯"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_G /* 0x47 */)) { + if(1){ + r=m=1; // Line 198 + k.KDC(0,t); + k.KO(-1,t,"᧰"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_H /* 0x48 */)) { + if(1){ + r=m=1; // Line 198 + k.KDC(0,t); + k.KO(-1,t,"᧱"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_I /* 0x49 */)) { + if(1){ + r=m=1; // Line 198 + k.KDC(0,t); + k.KO(-1,t,"᧧"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_J /* 0x4A */)) { + if(1){ + r=m=1; // Line 198 + k.KDC(0,t); + k.KO(-1,t,"᧲"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_K /* 0x4B */)) { + if(1){ + r=m=1; // Line 198 + k.KDC(0,t); + k.KO(-1,t,"᧳"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_L /* 0x4C */)) { + if(1){ + r=m=1; // Line 198 + k.KDC(0,t); + k.KO(-1,t,"᧴"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_M /* 0x4D */)) { + if(1){ + r=m=1; // Line 198 + k.KDC(0,t); + k.KO(-1,t,"᧽"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_N /* 0x4E */)) { + if(1){ + r=m=1; // Line 198 + k.KDC(0,t); + k.KO(-1,t,"᧼"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_O /* 0x4F */)) { + if(1){ + r=m=1; // Line 198 + k.KDC(0,t); + k.KO(-1,t,"᧨"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_P /* 0x50 */)) { + if(1){ + r=m=1; // Line 198 + k.KDC(0,t); + k.KO(-1,t,"᧩"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_Q /* 0x51 */)) { + if(1){ + r=m=1; // Line 198 + k.KDC(0,t); + k.KO(-1,t,"᧠"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_R /* 0x52 */)) { + if(1){ + r=m=1; // Line 198 + k.KDC(0,t); + k.KO(-1,t,"᧣"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_S /* 0x53 */)) { + if(1){ + r=m=1; // Line 198 + k.KDC(0,t); + k.KO(-1,t,"᧭"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_T /* 0x54 */)) { + if(1){ + r=m=1; // Line 198 + k.KDC(0,t); + k.KO(-1,t,"᧤"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_U /* 0x55 */)) { + if(1){ + r=m=1; // Line 198 + k.KDC(0,t); + k.KO(-1,t,"᧦"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_V /* 0x56 */)) { + if(1){ + r=m=1; // Line 198 + k.KDC(0,t); + k.KO(-1,t,"᧺"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_W /* 0x57 */)) { + if(1){ + r=m=1; // Line 198 + k.KDC(0,t); + k.KO(-1,t,"᧡"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_X /* 0x58 */)) { + if(1){ + r=m=1; // Line 198 + k.KDC(0,t); + k.KO(-1,t,"᧸"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_Y /* 0x59 */)) { + if(1){ + r=m=1; // Line 198 + k.KDC(0,t); + k.KO(-1,t,"᧥"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_Z /* 0x5A */)) { + if(1){ + r=m=1; // Line 198 + k.KDC(0,t); + k.KO(-1,t,"᧷"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_COLON /* 0xBA */)) { + if(1){ + r=m=1; // Line 198 + k.KDC(0,t); + k.KO(-1,t,"᧵"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_COMMA /* 0xBC */)) { + if(1){ + r=m=1; // Line 198 + k.KDC(0,t); + k.KO(-1,t,"᧾"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_PERIOD /* 0xBE */)) { + if(1){ + r=m=1; // Line 198 + k.KDC(0,t); + k.KO(-1,t,"᧿"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_LBRKT /* 0xDB */)) { + if(1){ + r=m=1; // Line 198 + k.KDC(0,t); + k.KO(-1,t,"᧪"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_RBRKT /* 0xDD */)) { + if(1){ + r=m=1; // Line 198 + k.KDC(0,t); + k.KO(-1,t,"᧫"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4018 */, keyCodes.K_QUOTE /* 0xDE */)) { + if(1){ + r=m=1; // Line 198 + k.KDC(0,t); + k.KO(-1,t,"᧶"); + } + } + else if(k.KKM(e, modCodes.RALT | modCodes.VIRTUAL_KEY /* 0x4008 */, keyCodes.K_SPACE /* 0x20 */)) { + if(1){ + r=m=1; // Line 199 + k.KDC(0,t); + k.KO(-1,t," "); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, 0x100)) { + if(1){ + r=m=1; // Line 262 + k.KDC(0,t); + k.KO(-1,t,"្ក"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, 0x101)) { + if(1){ + r=m=1; // Line 262 + k.KDC(0,t); + k.KO(-1,t,"្ខ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, 0x102)) { + if(1){ + r=m=1; // Line 262 + k.KDC(0,t); + k.KO(-1,t,"្គ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, 0x103)) { + if(1){ + r=m=1; // Line 262 + k.KDC(0,t); + k.KO(-1,t,"្ឃ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, 0x104)) { + if(1){ + r=m=1; // Line 262 + k.KDC(0,t); + k.KO(-1,t,"្ង"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, 0x105)) { + if(1){ + r=m=1; // Line 262 + k.KDC(0,t); + k.KO(-1,t,"្ច"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, 0x106)) { + if(1){ + r=m=1; // Line 262 + k.KDC(0,t); + k.KO(-1,t,"្ឆ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, 0x107)) { + if(1){ + r=m=1; // Line 262 + k.KDC(0,t); + k.KO(-1,t,"្ជ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, 0x108)) { + if(1){ + r=m=1; // Line 262 + k.KDC(0,t); + k.KO(-1,t,"្ឈ"); + } + } + if(m) {} + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, 0x109)) { + if(1){ + r=m=1; // Line 262 + k.KDC(0,t); + k.KO(-1,t,"្ញ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, 0x10A)) { + if(1){ + r=m=1; // Line 262 + k.KDC(0,t); + k.KO(-1,t,"្ដ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, 0x10B)) { + if(1){ + r=m=1; // Line 262 + k.KDC(0,t); + k.KO(-1,t,"្ឋ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, 0x10C)) { + if(1){ + r=m=1; // Line 262 + k.KDC(0,t); + k.KO(-1,t,"្ឌ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, 0x10D)) { + if(1){ + r=m=1; // Line 262 + k.KDC(0,t); + k.KO(-1,t,"្ឍ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, 0x10E)) { + if(1){ + r=m=1; // Line 262 + k.KDC(0,t); + k.KO(-1,t,"្ណ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, 0x10F)) { + if(1){ + r=m=1; // Line 262 + k.KDC(0,t); + k.KO(-1,t,"្ត"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, 0x110)) { + if(1){ + r=m=1; // Line 262 + k.KDC(0,t); + k.KO(-1,t,"្ថ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, 0x111)) { + if(1){ + r=m=1; // Line 262 + k.KDC(0,t); + k.KO(-1,t,"្ទ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, 0x112)) { + if(1){ + r=m=1; // Line 262 + k.KDC(0,t); + k.KO(-1,t,"្ធ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, 0x113)) { + if(1){ + r=m=1; // Line 262 + k.KDC(0,t); + k.KO(-1,t,"្ន"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, 0x114)) { + if(1){ + r=m=1; // Line 262 + k.KDC(0,t); + k.KO(-1,t,"្ប"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, 0x115)) { + if(1){ + r=m=1; // Line 262 + k.KDC(0,t); + k.KO(-1,t,"្ផ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, 0x116)) { + if(1){ + r=m=1; // Line 262 + k.KDC(0,t); + k.KO(-1,t,"្ព"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, 0x117)) { + if(1){ + r=m=1; // Line 262 + k.KDC(0,t); + k.KO(-1,t,"្ភ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, 0x118)) { + if(1){ + r=m=1; // Line 262 + k.KDC(0,t); + k.KO(-1,t,"្ម"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, 0x119)) { + if(1){ + r=m=1; // Line 262 + k.KDC(0,t); + k.KO(-1,t,"្យ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, 0x11A)) { + if(1){ + r=m=1; // Line 262 + k.KDC(0,t); + k.KO(-1,t,"្រ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, 0x11B)) { + if(1){ + r=m=1; // Line 262 + k.KDC(0,t); + k.KO(-1,t,"្ល"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, 0x11C)) { + if(1){ + r=m=1; // Line 262 + k.KDC(0,t); + k.KO(-1,t,"្វ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, 0x11D)) { + if(1){ + r=m=1; // Line 262 + k.KDC(0,t); + k.KO(-1,t,"្ឝ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, 0x11E)) { + if(1){ + r=m=1; // Line 262 + k.KDC(0,t); + k.KO(-1,t,"្ឞ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, 0x11F)) { + if(1){ + r=m=1; // Line 262 + k.KDC(0,t); + k.KO(-1,t,"្ស"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, 0x120)) { + if(1){ + r=m=1; // Line 262 + k.KDC(0,t); + k.KO(-1,t,"្ហ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, 0x121)) { + if(1){ + r=m=1; // Line 262 + k.KDC(0,t); + k.KO(-1,t,"្ឡ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, 0x122)) { + if(1){ + r=m=1; // Line 262 + k.KDC(0,t); + k.KO(-1,t,"្អ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_NPSTAR /* 0x6A */)) { + if(1){ + r=m=1; // Line 268 + k.KDC(0,t); + k.KO(-1,t,"*"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_NPSTAR /* 0x6A */)) { + if(1){ + r=m=1; // Line 269 + k.KDC(0,t); + k.KO(-1,t,"*"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_NPPLUS /* 0x6B */)) { + if(1){ + r=m=1; // Line 270 + k.KDC(0,t); + k.KO(-1,t,"+"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_NPPLUS /* 0x6B */)) { + if(1){ + r=m=1; // Line 271 + k.KDC(0,t); + k.KO(-1,t,"+"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_NPMINUS /* 0x6D */)) { + if(1){ + r=m=1; // Line 272 + k.KDC(0,t); + k.KO(-1,t,"-"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_NPMINUS /* 0x6D */)) { + if(1){ + r=m=1; // Line 273 + k.KDC(0,t); + k.KO(-1,t,"-"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_NPDOT /* 0x6E */)) { + if(1){ + r=m=1; // Line 274 + k.KDC(0,t); + k.KO(-1,t,"."); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_NPDOT /* 0x6E */)) { + if(1){ + r=m=1; // Line 275 + k.KDC(0,t); + k.KO(-1,t,"."); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_NPSLASH /* 0x6F */)) { + if(1){ + r=m=1; // Line 276 + k.KDC(0,t); + k.KO(-1,t,"/"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_NPSLASH /* 0x6F */)) { + if(1){ + r=m=1; // Line 277 + k.KDC(0,t); + k.KO(-1,t,"/"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_SPACE /* 0x20 */)) { + if(k.KFCM(1,t,['​'])){ + r=m=1; // Line 225 + k.KDC(1,t); + k.KO(-1,t," "); + } + else if(1){ + r=m=1; // Line 199 + k.KDC(0,t); + k.KO(-1,t,"​"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_SPACE /* 0x20 */)) { + if(1){ + r=m=1; // Line 199 + k.KDC(0,t); + k.KO(-1,t," "); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_1 /* 0x31 */)) { + if(1){ + r=m=1; // Line 194 + k.KDC(0,t); + k.KO(-1,t,"!"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_QUOTE /* 0xDE */)) { + if(k.KFCM(3,t,[{t:'a',a:this.s_c_combo_QA_57},'្','អ'])){ + r=m=1; // Line 244 + k.KDC(3,t); + k.KIO(-1,this.s_c_combo_QA_57,1,t); + k.KO(-1,t,"្អ៉"); + k.KB(t); + } + else if(k.KFCM(3,t,['ល','្',{t:'a',a:this.s_c_1st_combo_LO_54}])){ + r=m=1; // Line 245 + k.KDC(3,t); + k.KO(-1,t,"ល្"); + k.KIO(-1,this.s_c_1st_combo_LO_54,3,t); + k.KO(-1,t,"៉"); + k.KB(t); + } + else if(k.KFCM(3,t,['ម','្',{t:'a',a:this.s_c_1st_combo_MO_55}])){ + r=m=1; // Line 246 + k.KDC(3,t); + k.KO(-1,t,"ម្"); + k.KIO(-1,this.s_c_1st_combo_MO_55,3,t); + k.KO(-1,t,"៉"); + k.KB(t); + } + else if(k.KFCM(3,t,['ស','្',{t:'a',a:this.s_c_combo_SA_56}])){ + r=m=1; // Line 247 + k.KDC(3,t); + k.KO(-1,t,"ស្"); + k.KIO(-1,this.s_c_combo_SA_56,3,t); + k.KO(-1,t,"៉"); + k.KB(t); + } + else if(k.KFCM(3,t,[{t:'a',a:this.s_c_combo_HA_58},'្','ហ'])){ + r=m=1; // Line 248 + k.KDC(3,t); + k.KIO(-1,this.s_c_combo_HA_58,1,t); + k.KO(-1,t,"្ហ៉"); + k.KB(t); + } + else if(k.KFCM(3,t,['អ','្','ង'])){ + r=m=1; // Line 249 + k.KDC(3,t); + k.KO(-1,t,"អ្ង៉"); + k.KB(t); + } + else if(k.KFCM(3,t,['អ','្','វ'])){ + r=m=1; // Line 250 + k.KDC(3,t); + k.KO(-1,t,"អ្វ៉"); + k.KB(t); + } + else if(k.KFCM(1,t,[{t:'a',a:this.s_c_shifter_28}])){ + r=m=1; // Line 215 + k.KDC(1,t); + k.KIO(-1,this.s_c_shifter_28,1,t); + k.KB(t); + } + else if(k.KFCM(1,t,[{t:'a',a:this.s_shiftable_c_1st_48}])){ + r=m=1; // Line 239 + k.KDC(1,t); + k.KIO(-1,this.s_shiftable_c_1st_48,1,t); + k.KO(-1,t,"៉"); + k.KB(t); + } + else if(1){ + r=m=1; // Line 192 + k.KDC(0,t); + k.KO(-1,t,"៉"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_3 /* 0x33 */)) { + if(1){ + r=m=1; // Line 194 + k.KDC(0,t); + k.KO(-1,t,"\""); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_4 /* 0x34 */)) { + if(1){ + r=m=1; // Line 195 + k.KDC(0,t); + k.KO(-1,t,"៛"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_5 /* 0x35 */)) { + if(1){ + r=m=1; // Line 194 + k.KDC(0,t); + k.KO(-1,t,"%"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_7 /* 0x37 */)) { + if(1){ + r=m=1; // Line 191 + k.KDC(0,t); + k.KO(-1,t,"័"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_QUOTE /* 0xDE */)) { + if(k.KFCM(2,t,['្',{t:'a',a:this.s_c_out_12}])){ + r=m=1; // Line 214 + k.KDC(2,t); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_out_12,2,t); + k.KB(t); + } + else if(k.KFCM(1,t,[{t:'a',a:this.s_v_gen_14}])){ + r=m=1; // Line 211 + k.KDC(1,t); + k.KIO(-1,this.s_v_gen_14,1,t); + k.KB(t); + } + else if(k.KFCM(1,t,[{t:'a',a:this.s_v_pseudo_16}])){ + r=m=1; // Line 212 + k.KDC(1,t); + k.KIO(-1,this.s_v_pseudo_16,1,t); + k.KB(t); + } + else if(k.KFCM(1,t,[{t:'a',a:this.s_c_shifter_28}])){ + r=m=1; // Line 213 + k.KDC(1,t); + k.KIO(-1,this.s_c_shifter_28,1,t); + k.KB(t); + } + else if(1){ + r=m=1; // Line 191 + k.KDC(0,t); + k.KO(-1,t,"់"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_9 /* 0x39 */)) { + if(1){ + r=m=1; // Line 194 + k.KDC(0,t); + k.KO(-1,t,"("); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_0 /* 0x30 */)) { + if(1){ + r=m=1; // Line 194 + k.KDC(0,t); + k.KO(-1,t,")"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_8 /* 0x38 */)) { + if(1){ + r=m=1; // Line 191 + k.KDC(0,t); + k.KO(-1,t,"៏"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_EQUAL /* 0xBB */)) { + if(1){ + r=m=1; // Line 194 + k.KDC(0,t); + k.KO(-1,t,"="); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_COMMA /* 0xBC */)) { + if(1){ + r=m=1; // Line 206 + k.KDC(0,t); + k.KO(-1,t,"ុំ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_HYPHEN /* 0xBD */)) { + if(1){ + r=m=1; // Line 190 + k.KDC(0,t); + k.KO(-1,t,"ឥ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_PERIOD /* 0xBE */)) { + if(1){ + r=m=1; // Line 193 + k.KDC(0,t); + k.KO(-1,t,"។"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_SLASH /* 0xBF */)) { + if(k.KFCM(3,t,['ល','្',{t:'a',a:this.s_c_2nd_combo_LO_52}])){ + r=m=1; // Line 254 + k.KDC(3,t); + k.KO(-1,t,"ល្"); + k.KIO(-1,this.s_c_2nd_combo_LO_52,3,t); + k.KO(-1,t,"៊"); + k.KB(t); + } + else if(k.KFCM(3,t,['ម','្',{t:'a',a:this.s_c_2nd_combo_MO_53}])){ + r=m=1; // Line 255 + k.KDC(3,t); + k.KO(-1,t,"ម្"); + k.KIO(-1,this.s_c_2nd_combo_MO_53,3,t); + k.KO(-1,t,"៊"); + k.KB(t); + } + else if(k.KFCM(1,t,[{t:'a',a:this.s_c_shifter_28}])){ + r=m=1; // Line 215 + k.KDC(1,t); + k.KIO(-1,this.s_c_shifter_28,1,t); + k.KB(t); + } + else if(k.KFCM(1,t,[{t:'a',a:this.s_shiftable_c_2nd_with_BA_51}])){ + r=m=1; // Line 240 + k.KDC(1,t); + k.KIO(-1,this.s_shiftable_c_2nd_with_BA_51,1,t); + k.KO(-1,t,"៊"); + k.KB(t); + } + else if(1){ + r=m=1; // Line 192 + k.KDC(0,t); + k.KO(-1,t,"៊"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_0 /* 0x30 */)) { + if(1){ + r=m=1; // Line 196 + k.KDC(0,t); + k.KO(-1,t,"០"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_1 /* 0x31 */)) { + if(1){ + r=m=1; // Line 196 + k.KDC(0,t); + k.KO(-1,t,"១"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_2 /* 0x32 */)) { + if(1){ + r=m=1; // Line 196 + k.KDC(0,t); + k.KO(-1,t,"២"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_3 /* 0x33 */)) { + if(1){ + r=m=1; // Line 196 + k.KDC(0,t); + k.KO(-1,t,"៣"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_4 /* 0x34 */)) { + if(1){ + r=m=1; // Line 196 + k.KDC(0,t); + k.KO(-1,t,"៤"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_5 /* 0x35 */)) { + if(1){ + r=m=1; // Line 196 + k.KDC(0,t); + k.KO(-1,t,"៥"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_6 /* 0x36 */)) { + if(1){ + r=m=1; // Line 196 + k.KDC(0,t); + k.KO(-1,t,"៦"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_7 /* 0x37 */)) { + if(1){ + r=m=1; // Line 196 + k.KDC(0,t); + k.KO(-1,t,"៧"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_8 /* 0x38 */)) { + if(1){ + r=m=1; // Line 196 + k.KDC(0,t); + k.KO(-1,t,"៨"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_9 /* 0x39 */)) { + if(1){ + r=m=1; // Line 196 + k.KDC(0,t); + k.KO(-1,t,"៩"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_COLON /* 0xBA */)) { + if(1){ + r=m=1; // Line 205 + k.KDC(0,t); + k.KO(-1,t,"ោះ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_COLON /* 0xBA */)) { + if(1){ + r=m=1; // Line 189 + k.KDC(0,t); + k.KO(-1,t,"ើ"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_COMMA /* 0xBC */)) { + if(1){ + r=m=1; // Line 207 + k.KDC(0,t); + k.KO(-1,t,"ុះ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_EQUAL /* 0xBB */)) { + if(1){ + r=m=1; // Line 190 + k.KDC(0,t); + k.KO(-1,t,"ឲ"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_PERIOD /* 0xBE */)) { + if(1){ + r=m=1; // Line 193 + k.KDC(0,t); + k.KO(-1,t,"៕"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_SLASH /* 0xBF */)) { + if(1){ + r=m=1; // Line 194 + k.KDC(0,t); + k.KO(-1,t,"?"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_2 /* 0x32 */)) { + if(1){ + r=m=1; // Line 193 + k.KDC(0,t); + k.KO(-1,t,"ៗ"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_A /* 0x41 */)) { + if(1){ + r=m=1; // Line 203 + k.KDC(0,t); + k.KO(-1,t,"ាំ"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_B /* 0x42 */)) { + if(1){ + r=m=1; // Line 188 + k.KDC(0,t); + k.KO(-1,t,"ព"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_C /* 0x43 */)) { + if(1){ + r=m=1; // Line 188 + k.KDC(0,t); + k.KO(-1,t,"ជ"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_D /* 0x44 */)) { + if(1){ + r=m=1; // Line 188 + k.KDC(0,t); + k.KO(-1,t,"ឌ"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_E /* 0x45 */)) { + if(1){ + r=m=1; // Line 189 + k.KDC(0,t); + k.KO(-1,t,"ែ"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_F /* 0x46 */)) { + if(1){ + r=m=1; // Line 188 + k.KDC(0,t); + k.KO(-1,t,"ធ"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_G /* 0x47 */)) { + if(1){ + r=m=1; // Line 188 + k.KDC(0,t); + k.KO(-1,t,"អ"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_H /* 0x48 */)) { + if(k.KFCM(1,t,['ះ'])){ + r=m=1; // Line 219 + k.KDC(1,t); + k.KO(-1,t,"ៈ"); + } + else if(k.KFCM(1,t,['ៈ'])){ + r=m=1; // Line 220 + k.KDC(1,t); + k.KO(-1,t,"ះ"); + } + else if(1){ + r=m=1; // Line 189 + k.KDC(0,t); + k.KO(-1,t,"ះ"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_I /* 0x49 */)) { + if(1){ + r=m=1; // Line 189 + k.KDC(0,t); + k.KO(-1,t,"ី"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_J /* 0x4A */)) { + if(1){ + r=m=1; // Line 188 + k.KDC(0,t); + k.KO(-1,t,"ញ"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_K /* 0x4B */)) { + if(1){ + r=m=1; // Line 188 + k.KDC(0,t); + k.KO(-1,t,"គ"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_L /* 0x4C */)) { + if(1){ + r=m=1; // Line 188 + k.KDC(0,t); + k.KO(-1,t,"ឡ"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_M /* 0x4D */)) { + if(1){ + r=m=1; // Line 189 + k.KDC(0,t); + k.KO(-1,t,"ំ"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_N /* 0x4E */)) { + if(1){ + r=m=1; // Line 188 + k.KDC(0,t); + k.KO(-1,t,"ណ"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_O /* 0x4F */)) { + if(1){ + r=m=1; // Line 189 + k.KDC(0,t); + k.KO(-1,t,"ៅ"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_P /* 0x50 */)) { + if(1){ + r=m=1; // Line 188 + k.KDC(0,t); + k.KO(-1,t,"ភ"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_Q /* 0x51 */)) { + if(1){ + r=m=1; // Line 188 + k.KDC(0,t); + k.KO(-1,t,"ឈ"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_R /* 0x52 */)) { + if(1){ + r=m=1; // Line 190 + k.KDC(0,t); + k.KO(-1,t,"ឬ"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_S /* 0x53 */)) { + if(1){ + r=m=1; // Line 189 + k.KDC(0,t); + k.KO(-1,t,"ៃ"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_T /* 0x54 */)) { + if(1){ + r=m=1; // Line 188 + k.KDC(0,t); + k.KO(-1,t,"ទ"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_U /* 0x55 */)) { + if(1){ + r=m=1; // Line 189 + k.KDC(0,t); + k.KO(-1,t,"ូ"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_V /* 0x56 */)) { + if(1){ + r=m=1; // Line 204 + k.KDC(0,t); + k.KO(-1,t,"េះ"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_W /* 0x57 */)) { + if(1){ + r=m=1; // Line 189 + k.KDC(0,t); + k.KO(-1,t,"ឺ"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_X /* 0x58 */)) { + if(1){ + r=m=1; // Line 188 + k.KDC(0,t); + k.KO(-1,t,"ឃ"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_Y /* 0x59 */)) { + if(1){ + r=m=1; // Line 189 + k.KDC(0,t); + k.KO(-1,t,"ួ"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_Z /* 0x5A */)) { + if(1){ + r=m=1; // Line 188 + k.KDC(0,t); + k.KO(-1,t,"ឍ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_LBRKT /* 0xDB */)) { + if(1){ + r=m=1; // Line 189 + k.KDC(0,t); + k.KO(-1,t,"ៀ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_BKSLASH /* 0xDC */)) { + if(1){ + r=m=1; // Line 190 + k.KDC(0,t); + k.KO(-1,t,"ឮ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_RBRKT /* 0xDD */)) { + if(1){ + r=m=1; // Line 190 + k.KDC(0,t); + k.KO(-1,t,"ឪ"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_6 /* 0x36 */)) { + if(1){ + r=m=1; // Line 191 + k.KDC(0,t); + k.KO(-1,t,"៍"); + } + } + if(m) {} + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_HYPHEN /* 0xBD */)) { + if(1){ + r=m=1; // Line 191 + k.KDC(0,t); + k.KO(-1,t,"៌"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_BKQUOTE /* 0xC0 */)) { + if(1){ + r=m=1; // Line 194 + k.KDC(0,t); + k.KO(-1,t,"«"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_A /* 0x41 */)) { + if(1){ + r=m=1; // Line 189 + k.KDC(0,t); + k.KO(-1,t,"ា"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_B /* 0x42 */)) { + if(1){ + r=m=1; // Line 188 + k.KDC(0,t); + k.KO(-1,t,"ប"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_C /* 0x43 */)) { + if(1){ + r=m=1; // Line 188 + k.KDC(0,t); + k.KO(-1,t,"ច"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_D /* 0x44 */)) { + if(1){ + r=m=1; // Line 188 + k.KDC(0,t); + k.KO(-1,t,"ដ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_E /* 0x45 */)) { + if(1){ + r=m=1; // Line 189 + k.KDC(0,t); + k.KO(-1,t,"េ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_F /* 0x46 */)) { + if(1){ + r=m=1; // Line 188 + k.KDC(0,t); + k.KO(-1,t,"ថ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_G /* 0x47 */)) { + if(1){ + r=m=1; // Line 188 + k.KDC(0,t); + k.KO(-1,t,"ង"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_H /* 0x48 */)) { + if(1){ + r=m=1; // Line 188 + k.KDC(0,t); + k.KO(-1,t,"ហ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_I /* 0x49 */)) { + if(1){ + r=m=1; // Line 189 + k.KDC(0,t); + k.KO(-1,t,"ិ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_J /* 0x4A */)) { + if(1){ + r=m=1; // Line 191 + k.KDC(0,t); + k.KO(-1,t,"្"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_K /* 0x4B */)) { + if(1){ + r=m=1; // Line 188 + k.KDC(0,t); + k.KO(-1,t,"ក"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_L /* 0x4C */)) { + if(1){ + r=m=1; // Line 188 + k.KDC(0,t); + k.KO(-1,t,"ល"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_M /* 0x4D */)) { + if(1){ + r=m=1; // Line 188 + k.KDC(0,t); + k.KO(-1,t,"ម"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_N /* 0x4E */)) { + if(1){ + r=m=1; // Line 188 + k.KDC(0,t); + k.KO(-1,t,"ន"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_O /* 0x4F */)) { + if(1){ + r=m=1; // Line 189 + k.KDC(0,t); + k.KO(-1,t,"ោ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_P /* 0x50 */)) { + if(1){ + r=m=1; // Line 188 + k.KDC(0,t); + k.KO(-1,t,"ផ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_Q /* 0x51 */)) { + if(1){ + r=m=1; // Line 188 + k.KDC(0,t); + k.KO(-1,t,"ឆ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_R /* 0x52 */)) { + if(1){ + r=m=1; // Line 188 + k.KDC(0,t); + k.KO(-1,t,"រ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_S /* 0x53 */)) { + if(1){ + r=m=1; // Line 188 + k.KDC(0,t); + k.KO(-1,t,"ស"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_T /* 0x54 */)) { + if(1){ + r=m=1; // Line 188 + k.KDC(0,t); + k.KO(-1,t,"ត"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_U /* 0x55 */)) { + if(k.KFCM(3,t,[{t:'a',a:this.s_shiftable_c_1st_48},'ា','ំ'])){ + r=m=1; // Line 234 + k.KDC(3,t); + k.KIO(-1,this.s_shiftable_c_1st_48,1,t); + k.KO(-1,t,"៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(3,t,[{t:'a',a:this.s_shiftable_c_2nd_with_BA_51},'ា','ំ'])){ + r=m=1; // Line 235 + k.KDC(3,t); + k.KIO(-1,this.s_shiftable_c_2nd_with_BA_51,1,t); + k.KO(-1,t,"៉"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(1){ + r=m=1; // Line 189 + k.KDC(0,t); + k.KO(-1,t,"ុ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_V /* 0x56 */)) { + if(1){ + r=m=1; // Line 188 + k.KDC(0,t); + k.KO(-1,t,"វ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_W /* 0x57 */)) { + if(1){ + r=m=1; // Line 189 + k.KDC(0,t); + k.KO(-1,t,"ឹ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_X /* 0x58 */)) { + if(1){ + r=m=1; // Line 188 + k.KDC(0,t); + k.KO(-1,t,"ខ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_Y /* 0x59 */)) { + if(1){ + r=m=1; // Line 188 + k.KDC(0,t); + k.KO(-1,t,"យ"); + } + } + else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_Z /* 0x5A */)) { + if(1){ + r=m=1; // Line 188 + k.KDC(0,t); + k.KO(-1,t,"ឋ"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_LBRKT /* 0xDB */)) { + if(1){ + r=m=1; // Line 189 + k.KDC(0,t); + k.KO(-1,t,"ឿ"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_BKSLASH /* 0xDC */)) { + if(1){ + r=m=1; // Line 190 + k.KDC(0,t); + k.KO(-1,t,"ឭ"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_RBRKT /* 0xDD */)) { + if(1){ + r=m=1; // Line 190 + k.KDC(0,t); + k.KO(-1,t,"ឧ"); + } + } + else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_BKQUOTE /* 0xC0 */)) { + if(1){ + r=m=1; // Line 194 + k.KDC(0,t); + k.KO(-1,t,"»"); + } + } + if(m==1) { + + k.KDC(-1,t); + r=this.g_normalise_1(t,e); + m=2; + } + return r; + }; + this.g_normalise_1=function(t,e) { + var k=KeymanWeb,r=1,m=0; + if(k.KFCM(7,t,[{t:'a',a:this.s_c_combo_QA_57},'្','អ','ុ','ំ','ា','ំ'])){ + m=1; // Line 376 + k.KDC(7,t); + k.KIO(-1,this.s_c_combo_QA_57,1,t); + k.KO(-1,t,"្"); + k.KO(-1,t,"អ៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(7,t,['ល','្',{t:'a',a:this.s_c_1st_combo_LO_54},'ុ','ំ','ា','ំ'])){ + m=1; // Line 381 + k.KDC(7,t); + k.KO(-1,t,"ល"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_1st_combo_LO_54,3,t); + k.KO(-1,t,"៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(7,t,['ម','្',{t:'a',a:this.s_c_1st_combo_MO_55},'ុ','ំ','ា','ំ'])){ + m=1; // Line 386 + k.KDC(7,t); + k.KO(-1,t,"ម"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_1st_combo_MO_55,3,t); + k.KO(-1,t,"៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(7,t,['ស','្','ប','ុ','ំ','ា','ំ'])){ + m=1; // Line 391 + k.KDC(7,t); + k.KO(-1,t,"ស"); + k.KO(-1,t,"្"); + k.KO(-1,t,"ប៉"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(7,t,['ស','្',{t:'a',a:this.s_c_combo_SA_56},'ុ','ំ','ា','ំ'])){ + m=1; // Line 396 + k.KDC(7,t); + k.KO(-1,t,"ស"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_combo_SA_56,3,t); + k.KO(-1,t,"៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(7,t,[{t:'a',a:this.s_c_combo_HA_58},'្','ហ','ុ','ំ','ា','ំ'])){ + m=1; // Line 401 + k.KDC(7,t); + k.KIO(-1,this.s_c_combo_HA_58,1,t); + k.KO(-1,t,"្"); + k.KO(-1,t,"ហ៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(7,t,['អ','្','ង','ុ','ំ','ា','ំ'])){ + m=1; // Line 406 + k.KDC(7,t); + k.KO(-1,t,"អ"); + k.KO(-1,t,"្"); + k.KO(-1,t,"ង៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(7,t,['អ','្','វ','ុ','ំ','ា','ំ'])){ + m=1; // Line 411 + k.KDC(7,t); + k.KO(-1,t,"អ"); + k.KO(-1,t,"្"); + k.KO(-1,t,"វ៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(7,t,['ហ','្','ប','ុ','ំ','ា','ំ'])){ + m=1; // Line 416 + k.KDC(7,t); + k.KO(-1,t,"ហ"); + k.KO(-1,t,"្"); + k.KO(-1,t,"ប៉"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(7,t,['ហ','្',{t:'a',a:this.s_shiftable_c_2nd_with_BA_51},'ុ','ំ','ា','ំ'])){ + m=1; // Line 422 + k.KDC(7,t); + k.KO(-1,t,"ហ"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_shiftable_c_2nd_with_BA_51,3,t); + k.KO(-1,t,"៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(7,t,['ល','្',{t:'a',a:this.s_c_2nd_combo_LO_52},'ុ','ំ','ា','ំ'])){ + m=1; // Line 429 + k.KDC(7,t); + k.KO(-1,t,"ល"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_2nd_combo_LO_52,3,t); + k.KO(-1,t,"៉"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(7,t,['ម','្',{t:'a',a:this.s_c_2nd_combo_MO_53},'ុ','ំ','ា','ំ'])){ + m=1; // Line 434 + k.KDC(7,t); + k.KO(-1,t,"ម"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_2nd_combo_MO_53,3,t); + k.KO(-1,t,"៉"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,['្','ដ',{t:'a',a:this.s_v_combo_N_21},'ំ','្','រ'])){ + m=1; // Line 340 + k.KDC(6,t); + k.KO(-1,t,"្ត"); + k.KO(-1,t,"្"); + k.KO(-1,t,"រ"); + k.KIO(-1,this.s_v_combo_N_21,3,t); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,['្','ដ',{t:'a',a:this.s_v_combo_R_20},'ះ','្','រ'])){ + m=1; // Line 341 + k.KDC(6,t); + k.KO(-1,t,"្ត"); + k.KO(-1,t,"្"); + k.KO(-1,t,"រ"); + k.KIO(-1,this.s_v_combo_R_20,3,t); + k.KO(-1,t,"ះ"); + } + else if(k.KFCM(6,t,['្','រ',{t:'a',a:this.s_v_combo_N_21},'ំ','្','ដ'])){ + m=1; // Line 344 + k.KDC(6,t); + k.KO(-1,t,"្ត"); + k.KO(-1,t,"្"); + k.KO(-1,t,"រ"); + k.KIO(-1,this.s_v_combo_N_21,3,t); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,['្','រ',{t:'a',a:this.s_v_combo_R_20},'ះ','្','ដ'])){ + m=1; // Line 345 + k.KDC(6,t); + k.KO(-1,t,"្ត"); + k.KO(-1,t,"្"); + k.KO(-1,t,"រ"); + k.KIO(-1,this.s_v_combo_R_20,3,t); + k.KO(-1,t,"ះ"); + } + else if(k.KFCM(6,t,['្','រ',{t:'a',a:this.s_v_combo_N_21},'ំ','្',{t:'a',a:this.s_subcons_44}])){ + m=1; // Line 350 + k.KDC(6,t); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_subcons_44,6,t); + k.KO(-1,t,"្"); + k.KO(-1,t,"រ"); + k.KIO(-1,this.s_v_combo_N_21,3,t); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,['្','រ',{t:'a',a:this.s_v_combo_R_20},'ះ','្',{t:'a',a:this.s_subcons_44}])){ + m=1; // Line 351 + k.KDC(6,t); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_subcons_44,6,t); + k.KO(-1,t,"្"); + k.KO(-1,t,"រ"); + k.KIO(-1,this.s_v_combo_R_20,3,t); + k.KO(-1,t,"ះ"); + } + else if(k.KFCM(6,t,[{t:'a',a:this.s_c_combo_QA_57},'្','អ','ុ','ា','ំ'])){ + m=1; // Line 374 + k.KDC(6,t); + k.KIO(-1,this.s_c_combo_QA_57,1,t); + k.KO(-1,t,"្"); + k.KO(-1,t,"អ៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,['ល','្',{t:'a',a:this.s_c_1st_combo_LO_54},'ុ','ា','ំ'])){ + m=1; // Line 379 + k.KDC(6,t); + k.KO(-1,t,"ល"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_1st_combo_LO_54,3,t); + k.KO(-1,t,"៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,['ម','្',{t:'a',a:this.s_c_1st_combo_MO_55},'ុ','ា','ំ'])){ + m=1; // Line 384 + k.KDC(6,t); + k.KO(-1,t,"ម"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_1st_combo_MO_55,3,t); + k.KO(-1,t,"៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,['ស','្','ប','ុ','ា','ំ'])){ + m=1; // Line 389 + k.KDC(6,t); + k.KO(-1,t,"ស"); + k.KO(-1,t,"្"); + k.KO(-1,t,"ប៉"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,['ស','្',{t:'a',a:this.s_c_combo_SA_56},'ុ','ា','ំ'])){ + m=1; // Line 394 + k.KDC(6,t); + k.KO(-1,t,"ស"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_combo_SA_56,3,t); + k.KO(-1,t,"៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,[{t:'a',a:this.s_c_combo_HA_58},'្','ហ','ុ','ា','ំ'])){ + m=1; // Line 399 + k.KDC(6,t); + k.KIO(-1,this.s_c_combo_HA_58,1,t); + k.KO(-1,t,"្"); + k.KO(-1,t,"ហ៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,['អ','្','ង','ុ','ា','ំ'])){ + m=1; // Line 404 + k.KDC(6,t); + k.KO(-1,t,"អ"); + k.KO(-1,t,"្"); + k.KO(-1,t,"ង៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,['អ','្','វ','ុ','ា','ំ'])){ + m=1; // Line 409 + k.KDC(6,t); + k.KO(-1,t,"អ"); + k.KO(-1,t,"្"); + k.KO(-1,t,"វ៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,['ហ','្','ប','ុ','ា','ំ'])){ + m=1; // Line 414 + k.KDC(6,t); + k.KO(-1,t,"ហ"); + k.KO(-1,t,"្"); + k.KO(-1,t,"ប៉"); + k.KO(-1,t,"ប"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,['ហ','្',{t:'a',a:this.s_shiftable_c_2nd_with_BA_51},'ុ','ា','ំ'])){ + m=1; // Line 420 + k.KDC(6,t); + k.KO(-1,t,"ហ"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_shiftable_c_2nd_with_BA_51,3,t); + k.KO(-1,t,"៊"); + k.KIO(-1,this.s_shiftable_c_2nd_with_BA_51,3,t); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,['ល','្',{t:'a',a:this.s_c_2nd_combo_LO_52},'ុ','ា','ំ'])){ + m=1; // Line 427 + k.KDC(6,t); + k.KO(-1,t,"ល"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_2nd_combo_LO_52,3,t); + k.KO(-1,t,"៉"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,['ម','្',{t:'a',a:this.s_c_2nd_combo_MO_53},'ុ','ា','ំ'])){ + m=1; // Line 432 + k.KDC(6,t); + k.KO(-1,t,"ម"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_2nd_combo_MO_53,3,t); + k.KO(-1,t,"៉"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,['ល','្',{t:'a',a:this.s_c_2nd_combo_LO_52},'៊',{t:'a',a:this.s_v_gen_14},{t:'a',a:this.s_v_pseudo_16}])){ + m=1; // Line 454 + k.KDC(6,t); + k.KO(-1,t,"ល"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_2nd_combo_LO_52,3,t); + k.KO(-1,t,"៉"); + k.KIO(-1,this.s_v_gen_14,5,t); + k.KIO(-1,this.s_v_pseudo_16,6,t); + } + else if(k.KFCM(6,t,['ម','្',{t:'a',a:this.s_c_2nd_combo_MO_53},'៊',{t:'a',a:this.s_v_gen_14},{t:'a',a:this.s_v_pseudo_16}])){ + m=1; // Line 455 + k.KDC(6,t); + k.KO(-1,t,"ម"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_2nd_combo_MO_53,3,t); + k.KO(-1,t,"៉"); + k.KIO(-1,this.s_v_gen_14,5,t); + k.KIO(-1,this.s_v_pseudo_16,6,t); + } + else if(k.KFCM(6,t,[{t:'a',a:this.s_c_combo_QA_57},'្','អ','៉','ា','ំ'])){ + m=1; // Line 489 + k.KDC(6,t); + k.KIO(-1,this.s_c_combo_QA_57,1,t); + k.KO(-1,t,"្"); + k.KO(-1,t,"អ៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,['ល','្',{t:'a',a:this.s_c_1st_combo_LO_54},'៉','ា','ំ'])){ + m=1; // Line 490 + k.KDC(6,t); + k.KO(-1,t,"ល"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_1st_combo_LO_54,3,t); + k.KO(-1,t,"៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,['ម','្',{t:'a',a:this.s_c_1st_combo_MO_55},'៉','ា','ំ'])){ + m=1; // Line 491 + k.KDC(6,t); + k.KO(-1,t,"ម"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_1st_combo_MO_55,3,t); + k.KO(-1,t,"៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,['ស','្','ប','៉','ា','ំ'])){ + m=1; // Line 492 + k.KDC(6,t); + k.KO(-1,t,"ស"); + k.KO(-1,t,"្"); + k.KO(-1,t,"ប៉"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,['ស','្',{t:'a',a:this.s_c_combo_SA_56},'៉','ា','ំ'])){ + m=1; // Line 493 + k.KDC(6,t); + k.KO(-1,t,"ស"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_combo_SA_56,3,t); + k.KO(-1,t,"៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,[{t:'a',a:this.s_c_combo_HA_58},'្','ហ','៉','ា','ំ'])){ + m=1; // Line 494 + k.KDC(6,t); + k.KIO(-1,this.s_c_combo_HA_58,1,t); + k.KO(-1,t,"្"); + k.KO(-1,t,"ហ៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,['អ','្','ង','៉','ា','ំ'])){ + m=1; // Line 495 + k.KDC(6,t); + k.KO(-1,t,"អ"); + k.KO(-1,t,"្"); + k.KO(-1,t,"ង៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,['អ','្','វ','៉','ា','ំ'])){ + m=1; // Line 496 + k.KDC(6,t); + k.KO(-1,t,"អ"); + k.KO(-1,t,"្"); + k.KO(-1,t,"វ៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,[{t:'a',a:this.s_c_combo_QA_57},'្','អ','ា','ុ','ំ'])){ + m=1; // Line 503 + k.KDC(6,t); + k.KIO(-1,this.s_c_combo_QA_57,1,t); + k.KO(-1,t,"្"); + k.KO(-1,t,"អ៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,[{t:'a',a:this.s_c_combo_QA_57},'្','អ','ុ','ំ','ា'])){ + m=1; // Line 504 + k.KDC(6,t); + k.KIO(-1,this.s_c_combo_QA_57,1,t); + k.KO(-1,t,"្"); + k.KO(-1,t,"អ៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,['ល','្',{t:'a',a:this.s_c_1st_combo_LO_54},'ា','ុ','ំ'])){ + m=1; // Line 506 + k.KDC(6,t); + k.KO(-1,t,"ល"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_1st_combo_LO_54,3,t); + k.KO(-1,t,"៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,['ល','្',{t:'a',a:this.s_c_1st_combo_LO_54},'ុ','ំ','ា'])){ + m=1; // Line 507 + k.KDC(6,t); + k.KO(-1,t,"ល"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_1st_combo_LO_54,3,t); + k.KO(-1,t,"៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,['ម','្',{t:'a',a:this.s_c_1st_combo_MO_55},'ា','ុ','ំ'])){ + m=1; // Line 509 + k.KDC(6,t); + k.KO(-1,t,"ម"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_1st_combo_MO_55,3,t); + k.KO(-1,t,"៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,['ម','្',{t:'a',a:this.s_c_1st_combo_MO_55},'ុ','ំ','ា'])){ + m=1; // Line 510 + k.KDC(6,t); + k.KO(-1,t,"ម"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_1st_combo_MO_55,3,t); + k.KO(-1,t,"៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,['ស','្',{t:'a',a:this.s_c_combo_SA_56},'ា','ុ','ំ'])){ + m=1; // Line 512 + k.KDC(6,t); + k.KO(-1,t,"ស"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_combo_SA_56,3,t); + k.KO(-1,t,"៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,['ស','្',{t:'a',a:this.s_c_combo_SA_56},'ុ','ំ','ា'])){ + m=1; // Line 513 + k.KDC(6,t); + k.KO(-1,t,"ស"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_combo_SA_56,3,t); + k.KO(-1,t,"៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,[{t:'a',a:this.s_c_combo_HA_58},'្','ហ','ា','ុ','ំ'])){ + m=1; // Line 515 + k.KDC(6,t); + k.KIO(-1,this.s_c_combo_HA_58,1,t); + k.KO(-1,t,"្"); + k.KO(-1,t,"ហ៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,[{t:'a',a:this.s_c_combo_HA_58},'្','ហ','ុ','ំ','ា'])){ + m=1; // Line 516 + k.KDC(6,t); + k.KIO(-1,this.s_c_combo_HA_58,1,t); + k.KO(-1,t,"្"); + k.KO(-1,t,"ហ៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,['អ','្','ង','ា','ុ','ំ'])){ + m=1; // Line 518 + k.KDC(6,t); + k.KO(-1,t,"អ"); + k.KO(-1,t,"្"); + k.KO(-1,t,"ង៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,['អ','្','ង','ុ','ំ','ា'])){ + m=1; // Line 519 + k.KDC(6,t); + k.KO(-1,t,"អ"); + k.KO(-1,t,"្"); + k.KO(-1,t,"ង៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,['អ','្','វ','ា','ុ','ំ'])){ + m=1; // Line 521 + k.KDC(6,t); + k.KO(-1,t,"អ"); + k.KO(-1,t,"្"); + k.KO(-1,t,"វ៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,['អ','្','វ','ុ','ំ','ា'])){ + m=1; // Line 522 + k.KDC(6,t); + k.KO(-1,t,"អ"); + k.KO(-1,t,"្"); + k.KO(-1,t,"វ៊"); + k.KO(-1,t,"ុ"); + k.KO(-1,t,"ា"); + } + else if(k.KFCM(6,t,['ល','្',{t:'a',a:this.s_c_2nd_combo_LO_52},'ា','ុ','ំ'])){ + m=1; // Line 529 + k.KDC(6,t); + k.KO(-1,t,"ល"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_2nd_combo_LO_52,3,t); + k.KO(-1,t,"៉"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,['ល','្',{t:'a',a:this.s_c_2nd_combo_LO_52},'ុ','ំ','ា'])){ + m=1; // Line 530 + k.KDC(6,t); + k.KO(-1,t,"ល"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_2nd_combo_LO_52,3,t); + k.KO(-1,t,"៉"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,['ម','្',{t:'a',a:this.s_c_2nd_combo_MO_53},'ា','ុ','ំ'])){ + m=1; // Line 532 + k.KDC(6,t); + k.KO(-1,t,"ម"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_2nd_combo_MO_53,3,t); + k.KO(-1,t,"៉"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,['ម','្',{t:'a',a:this.s_c_2nd_combo_MO_53},'ុ','ំ','ា'])){ + m=1; // Line 533 + k.KDC(6,t); + k.KO(-1,t,"ម"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_2nd_combo_MO_53,3,t); + k.KO(-1,t,"៉"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(6,t,[{t:'a',a:this.s_c_combo_QA_57},'្','អ','េ','ុ','ី'])){ + m=1; // Line 541 + k.KDC(6,t); + k.KIO(-1,this.s_c_combo_QA_57,1,t); + k.KO(-1,t,"្"); + k.KO(-1,t,"អ៊ើ"); + } + else if(k.KFCM(6,t,[{t:'a',a:this.s_c_combo_QA_57},'្','អ','ុ','េ','ី'])){ + m=1; // Line 542 + k.KDC(6,t); + k.KIO(-1,this.s_c_combo_QA_57,1,t); + k.KO(-1,t,"្"); + k.KO(-1,t,"អ៊ើ"); + } + else if(k.KFCM(6,t,[{t:'a',a:this.s_c_combo_QA_57},'្','អ','៉','េ','ី'])){ + m=1; // Line 543 + k.KDC(6,t); + k.KIO(-1,this.s_c_combo_QA_57,1,t); + k.KO(-1,t,"្"); + k.KO(-1,t,"អ៊ើ"); + } + else if(k.KFCM(6,t,['ល','្',{t:'a',a:this.s_c_1st_combo_LO_54},'េ','ុ','ី'])){ + m=1; // Line 545 + k.KDC(6,t); + k.KO(-1,t,"ល"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_1st_combo_LO_54,3,t); + k.KO(-1,t,"៊ើ"); + } + else if(k.KFCM(6,t,['ល','្',{t:'a',a:this.s_c_1st_combo_LO_54},'ុ','េ','ី'])){ + m=1; // Line 546 + k.KDC(6,t); + k.KO(-1,t,"ល"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_1st_combo_LO_54,3,t); + k.KO(-1,t,"៊ើ"); + } + else if(k.KFCM(6,t,['ល','្',{t:'a',a:this.s_c_1st_combo_LO_54},'៉','េ','ី'])){ + m=1; // Line 547 + k.KDC(6,t); + k.KO(-1,t,"ល"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_1st_combo_LO_54,3,t); + k.KO(-1,t,"៊ើ"); + } + else if(k.KFCM(6,t,['ម','្',{t:'a',a:this.s_c_1st_combo_MO_55},'េ','ុ','ី'])){ + m=1; // Line 549 + k.KDC(6,t); + k.KO(-1,t,"ម"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_1st_combo_MO_55,3,t); + k.KO(-1,t,"៊ើ"); + } + else if(k.KFCM(6,t,['ម','្',{t:'a',a:this.s_c_1st_combo_MO_55},'ុ','េ','ី'])){ + m=1; // Line 550 + k.KDC(6,t); + k.KO(-1,t,"ម"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_1st_combo_MO_55,3,t); + k.KO(-1,t,"៊ើ"); + } + else if(k.KFCM(6,t,['ម','្',{t:'a',a:this.s_c_1st_combo_MO_55},'៉','េ','ី'])){ + m=1; // Line 551 + k.KDC(6,t); + k.KO(-1,t,"ម"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_1st_combo_MO_55,3,t); + k.KO(-1,t,"៊ើ"); + } + else if(k.KFCM(6,t,['ស','្',{t:'a',a:this.s_c_combo_SA_56},'េ','ុ','ី'])){ + m=1; // Line 553 + k.KDC(6,t); + k.KO(-1,t,"ស"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_combo_SA_56,3,t); + k.KO(-1,t,"៊ើ"); + } + else if(k.KFCM(6,t,['ស','្',{t:'a',a:this.s_c_combo_SA_56},'ុ','េ','ី'])){ + m=1; // Line 554 + k.KDC(6,t); + k.KO(-1,t,"ស"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_combo_SA_56,3,t); + k.KO(-1,t,"៊ើ"); + } + else if(k.KFCM(6,t,['ស','្',{t:'a',a:this.s_c_combo_SA_56},'៉','េ','ី'])){ + m=1; // Line 555 + k.KDC(6,t); + k.KO(-1,t,"ស"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_combo_SA_56,3,t); + k.KO(-1,t,"៊ើ"); + } + else if(k.KFCM(6,t,[{t:'a',a:this.s_c_combo_HA_58},'្','ហ','េ','ុ','ី'])){ + m=1; // Line 557 + k.KDC(6,t); + k.KIO(-1,this.s_c_combo_HA_58,1,t); + k.KO(-1,t,"្"); + k.KO(-1,t,"ហ៊ើ"); + } + else if(k.KFCM(6,t,[{t:'a',a:this.s_c_combo_HA_58},'្','ហ','ុ','េ','ី'])){ + m=1; // Line 558 + k.KDC(6,t); + k.KIO(-1,this.s_c_combo_HA_58,1,t); + k.KO(-1,t,"្"); + k.KO(-1,t,"ហ៊ើ"); + } + else if(k.KFCM(6,t,[{t:'a',a:this.s_c_combo_HA_58},'្','ហ','៉','េ','ី'])){ + m=1; // Line 559 + k.KDC(6,t); + k.KIO(-1,this.s_c_combo_HA_58,1,t); + k.KO(-1,t,"្"); + k.KO(-1,t,"ហ៊ើ"); + } + else if(k.KFCM(6,t,['អ','្','ង','េ','ុ','ី'])){ + m=1; // Line 561 + k.KDC(6,t); + k.KO(-1,t,"អ"); + k.KO(-1,t,"្"); + k.KO(-1,t,"ង៊ើ"); + } + else if(k.KFCM(6,t,['អ','្','ង','ុ','េ','ី'])){ + m=1; // Line 562 + k.KDC(6,t); + k.KO(-1,t,"អ"); + k.KO(-1,t,"្"); + k.KO(-1,t,"ង៊ើ"); + } + else if(k.KFCM(6,t,['អ','្','ង','៉','េ','ី'])){ + m=1; // Line 563 + k.KDC(6,t); + k.KO(-1,t,"អ"); + k.KO(-1,t,"្"); + k.KO(-1,t,"ង៊ើ"); + } + else if(k.KFCM(6,t,['អ','្','វ','េ','ុ','ី'])){ + m=1; // Line 565 + k.KDC(6,t); + k.KO(-1,t,"អ"); + k.KO(-1,t,"្"); + k.KO(-1,t,"វ៊ើ"); + } + else if(k.KFCM(6,t,['អ','្','វ','ុ','េ','ី'])){ + m=1; // Line 566 + k.KDC(6,t); + k.KO(-1,t,"អ"); + k.KO(-1,t,"្"); + k.KO(-1,t,"វ៊ើ"); + } + else if(k.KFCM(6,t,['អ','្','វ','៉','េ','ី'])){ + m=1; // Line 567 + k.KDC(6,t); + k.KO(-1,t,"អ"); + k.KO(-1,t,"្"); + k.KO(-1,t,"វ៊ើ"); + } + else if(k.KFCM(6,t,['ល','្',{t:'a',a:this.s_c_2nd_combo_LO_52},'េ','ុ','ី'])){ + m=1; // Line 575 + k.KDC(6,t); + k.KO(-1,t,"ល"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_2nd_combo_LO_52,3,t); + k.KO(-1,t,"៉ើ"); + } + else if(k.KFCM(6,t,['ល','្',{t:'a',a:this.s_c_2nd_combo_LO_52},'ុ','េ','ី'])){ + m=1; // Line 576 + k.KDC(6,t); + k.KO(-1,t,"ល"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_2nd_combo_LO_52,3,t); + k.KO(-1,t,"៉ើ"); + } + else if(k.KFCM(6,t,['ល','្',{t:'a',a:this.s_c_2nd_combo_LO_52},'៊','េ','ី'])){ + m=1; // Line 577 + k.KDC(6,t); + k.KO(-1,t,"ល"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_2nd_combo_LO_52,3,t); + k.KO(-1,t,"៉ើ"); + } + else if(k.KFCM(6,t,['ម','្',{t:'a',a:this.s_c_2nd_combo_MO_53},'េ','ុ','ី'])){ + m=1; // Line 579 + k.KDC(6,t); + k.KO(-1,t,"ម"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_2nd_combo_MO_53,3,t); + k.KO(-1,t,"៉ើ"); + } + else if(k.KFCM(6,t,['ម','្',{t:'a',a:this.s_c_2nd_combo_MO_53},'ុ','េ','ី'])){ + m=1; // Line 580 + k.KDC(6,t); + k.KO(-1,t,"ម"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_2nd_combo_MO_53,3,t); + k.KO(-1,t,"៉ើ"); + } + else if(k.KFCM(6,t,['ម','្',{t:'a',a:this.s_c_2nd_combo_MO_53},'៊','េ','ី'])){ + m=1; // Line 581 + k.KDC(6,t); + k.KO(-1,t,"ម"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_2nd_combo_MO_53,3,t); + k.KO(-1,t,"៉ើ"); + } + else if(k.KFCM(6,t,['្','យ','្',{t:'a',a:this.s_c_out_12},'េ','ឺ'])){ + m=1; // Line 631 + k.KDC(6,t); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_out_12,4,t); + k.KO(-1,t,"ឿ"); + } + else if(k.KFCM(6,t,['្','យ','្',{t:'a',a:this.s_c_out_12},'េ','ឹ'])){ + m=1; // Line 632 + k.KDC(6,t); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_out_12,4,t); + k.KO(-1,t,"ឿ"); + } + else if(k.KFCM(6,t,['្','យ','្',{t:'a',a:this.s_c_out_12},'េ','ី'])){ + m=1; // Line 633 + k.KDC(6,t); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_out_12,4,t); + k.KO(-1,t,"ឿ"); + } + else if(k.KFCM(5,t,[{t:'a',a:this.s_c_shifter_28},{t:'a',a:this.s_v_combo_N_21},'ំ','្',{t:'a',a:this.s_subcons_44}])){ + m=1; // Line 331 + k.KDC(5,t); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_subcons_44,5,t); + k.KIO(-1,this.s_c_shifter_28,1,t); + k.KIO(-1,this.s_v_combo_N_21,2,t); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(5,t,[{t:'a',a:this.s_c_shifter_28},{t:'a',a:this.s_v_combo_R_20},'ះ','្',{t:'a',a:this.s_subcons_44}])){ + m=1; // Line 332 + k.KDC(5,t); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_subcons_44,5,t); + k.KIO(-1,this.s_c_shifter_28,1,t); + k.KIO(-1,this.s_v_combo_R_20,2,t); + k.KO(-1,t,"ះ"); + } + else if(k.KFCM(5,t,['្','ដ',{t:'a',a:this.s_v_any_19},'្','រ'])){ + m=1; // Line 339 + k.KDC(5,t); + k.KO(-1,t,"្ត"); + k.KO(-1,t,"្"); + k.KO(-1,t,"រ"); + k.KIO(-1,this.s_v_any_19,3,t); + } + else if(k.KFCM(5,t,['្','រ',{t:'a',a:this.s_v_any_19},'្','ដ'])){ + m=1; // Line 343 + k.KDC(5,t); + k.KO(-1,t,"្ត"); + k.KO(-1,t,"្"); + k.KO(-1,t,"រ"); + k.KIO(-1,this.s_v_any_19,3,t); + } + else if(k.KFCM(5,t,['្','រ',{t:'a',a:this.s_c_shifter_28},'្',{t:'a',a:this.s_subcons_44}])){ + m=1; // Line 347 + k.KDC(5,t); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_subcons_44,5,t); + k.KO(-1,t,"្"); + k.KO(-1,t,"រ"); + k.KIO(-1,this.s_c_shifter_28,3,t); + } + else if(k.KFCM(5,t,['្','រ',{t:'a',a:this.s_v_any_19},'្',{t:'a',a:this.s_subcons_44}])){ + m=1; // Line 349 + k.KDC(5,t); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_subcons_44,5,t); + k.KO(-1,t,"្"); + k.KO(-1,t,"រ"); + k.KIO(-1,this.s_v_any_19,3,t); + } + else if(k.KFCM(5,t,[{t:'a',a:this.s_c_combo_QA_57},'្','អ','ុ',{t:'a',a:this.s_v_above_47}])){ + m=1; // Line 373 + k.KDC(5,t); + k.KIO(-1,this.s_c_combo_QA_57,1,t); + k.KO(-1,t,"្"); + k.KO(-1,t,"អ៊"); + k.KIO(-1,this.s_v_above_47,5,t); + } + else if(k.KFCM(5,t,[{t:'a',a:this.s_c_combo_QA_57},'្','អ',{t:'a',a:this.s_v_above_47},'ុ'])){ + m=1; // Line 375 + k.KDC(5,t); + k.KIO(-1,this.s_c_combo_QA_57,1,t); + k.KO(-1,t,"្"); + k.KO(-1,t,"អ៊"); + k.KIO(-1,this.s_v_above_47,4,t); + } + else if(k.KFCM(5,t,['ល','្',{t:'a',a:this.s_c_1st_combo_LO_54},'ុ',{t:'a',a:this.s_v_above_47}])){ + m=1; // Line 378 + k.KDC(5,t); + k.KO(-1,t,"ល"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_1st_combo_LO_54,3,t); + k.KO(-1,t,"៊"); + k.KIO(-1,this.s_v_above_47,5,t); + } + else if(k.KFCM(5,t,['ល','្',{t:'a',a:this.s_c_1st_combo_LO_54},{t:'a',a:this.s_v_above_47},'ុ'])){ + m=1; // Line 380 + k.KDC(5,t); + k.KO(-1,t,"ល"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_1st_combo_LO_54,3,t); + k.KO(-1,t,"៊"); + k.KIO(-1,this.s_v_above_47,4,t); + } + else if(k.KFCM(5,t,['ម','្',{t:'a',a:this.s_c_1st_combo_MO_55},'ុ',{t:'a',a:this.s_v_above_47}])){ + m=1; // Line 383 + k.KDC(5,t); + k.KO(-1,t,"ម"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_1st_combo_MO_55,3,t); + k.KO(-1,t,"៊"); + k.KIO(-1,this.s_v_above_47,5,t); + } + else if(k.KFCM(5,t,['ម','្',{t:'a',a:this.s_c_1st_combo_MO_55},{t:'a',a:this.s_v_above_47},'ុ'])){ + m=1; // Line 385 + k.KDC(5,t); + k.KO(-1,t,"ម"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_1st_combo_MO_55,3,t); + k.KO(-1,t,"៊"); + k.KIO(-1,this.s_v_above_47,4,t); + } + if(m) {} + else if(k.KFCM(5,t,['ស','្','ប','ុ',{t:'a',a:this.s_v_above_47}])){ + m=1; // Line 388 + k.KDC(5,t); + k.KO(-1,t,"ស"); + k.KO(-1,t,"្"); + k.KO(-1,t,"ប៉"); + k.KIO(-1,this.s_v_above_47,5,t); + } + else if(k.KFCM(5,t,['ស','្','ប',{t:'a',a:this.s_v_above_47},'ុ'])){ + m=1; // Line 390 + k.KDC(5,t); + k.KO(-1,t,"ស"); + k.KO(-1,t,"្"); + k.KO(-1,t,"ប៉"); + k.KIO(-1,this.s_v_above_47,4,t); + } + else if(k.KFCM(5,t,['ស','្',{t:'a',a:this.s_c_combo_SA_56},'ុ',{t:'a',a:this.s_v_above_47}])){ + m=1; // Line 393 + k.KDC(5,t); + k.KO(-1,t,"ស"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_combo_SA_56,3,t); + k.KO(-1,t,"៊"); + k.KIO(-1,this.s_v_above_47,5,t); + } + else if(k.KFCM(5,t,['ស','្',{t:'a',a:this.s_c_combo_SA_56},{t:'a',a:this.s_v_above_47},'ុ'])){ + m=1; // Line 395 + k.KDC(5,t); + k.KO(-1,t,"ស"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_combo_SA_56,3,t); + k.KO(-1,t,"៊"); + k.KIO(-1,this.s_v_above_47,4,t); + } + else if(k.KFCM(5,t,[{t:'a',a:this.s_c_combo_HA_58},'្','ហ','ុ',{t:'a',a:this.s_v_above_47}])){ + m=1; // Line 398 + k.KDC(5,t); + k.KIO(-1,this.s_c_combo_HA_58,1,t); + k.KO(-1,t,"្"); + k.KO(-1,t,"ហ៊"); + k.KIO(-1,this.s_v_above_47,5,t); + } + else if(k.KFCM(5,t,[{t:'a',a:this.s_c_combo_HA_58},'្','ហ',{t:'a',a:this.s_v_above_47},'ុ'])){ + m=1; // Line 400 + k.KDC(5,t); + k.KIO(-1,this.s_c_combo_HA_58,1,t); + k.KO(-1,t,"្"); + k.KO(-1,t,"ហ៊"); + k.KIO(-1,this.s_v_above_47,4,t); + } + else if(k.KFCM(5,t,['អ','្','ង','ុ',{t:'a',a:this.s_v_above_47}])){ + m=1; // Line 403 + k.KDC(5,t); + k.KO(-1,t,"អ"); + k.KO(-1,t,"្"); + k.KO(-1,t,"ង៊"); + k.KIO(-1,this.s_v_above_47,5,t); + } + else if(k.KFCM(5,t,['អ','្','ង',{t:'a',a:this.s_v_above_47},'ុ'])){ + m=1; // Line 405 + k.KDC(5,t); + k.KO(-1,t,"អ"); + k.KO(-1,t,"្"); + k.KO(-1,t,"ង៊"); + k.KIO(-1,this.s_v_above_47,4,t); + } + else if(k.KFCM(5,t,['អ','្','វ','ុ',{t:'a',a:this.s_v_above_47}])){ + m=1; // Line 408 + k.KDC(5,t); + k.KO(-1,t,"អ"); + k.KO(-1,t,"្"); + k.KO(-1,t,"វ៊"); + k.KIO(-1,this.s_v_above_47,5,t); + } + else if(k.KFCM(5,t,['អ','្','វ',{t:'a',a:this.s_v_above_47},'ុ'])){ + m=1; // Line 410 + k.KDC(5,t); + k.KO(-1,t,"អ"); + k.KO(-1,t,"្"); + k.KO(-1,t,"វ៊"); + k.KIO(-1,this.s_v_above_47,4,t); + } + else if(k.KFCM(5,t,['ហ','្','ប','ុ',{t:'a',a:this.s_v_above_47}])){ + m=1; // Line 413 + k.KDC(5,t); + k.KO(-1,t,"ហ"); + k.KO(-1,t,"្"); + k.KO(-1,t,"ប៉"); + k.KIO(-1,this.s_v_above_47,5,t); + } + else if(k.KFCM(5,t,['ហ','្','ប',{t:'a',a:this.s_v_above_47},'ុ'])){ + m=1; // Line 415 + k.KDC(5,t); + k.KO(-1,t,"ហ"); + k.KO(-1,t,"្"); + k.KO(-1,t,"ប៉"); + k.KIO(-1,this.s_v_above_47,4,t); + } + else if(k.KFCM(5,t,['ហ','្',{t:'a',a:this.s_shiftable_c_2nd_with_BA_51},'ុ',{t:'a',a:this.s_v_above_47}])){ + m=1; // Line 419 + k.KDC(5,t); + k.KO(-1,t,"ហ"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_shiftable_c_2nd_with_BA_51,3,t); + k.KO(-1,t,"៊"); + k.KIO(-1,this.s_v_above_47,5,t); + } + else if(k.KFCM(5,t,['ហ','្',{t:'a',a:this.s_shiftable_c_2nd_with_BA_51},{t:'a',a:this.s_v_above_47},'ុ'])){ + m=1; // Line 421 + k.KDC(5,t); + k.KO(-1,t,"ហ"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_shiftable_c_2nd_with_BA_51,3,t); + k.KO(-1,t,"៊"); + k.KIO(-1,this.s_v_above_47,4,t); + } + else if(k.KFCM(5,t,['ល','្',{t:'a',a:this.s_c_2nd_combo_LO_52},'ុ',{t:'a',a:this.s_v_above_47}])){ + m=1; // Line 426 + k.KDC(5,t); + k.KO(-1,t,"ល"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_2nd_combo_LO_52,3,t); + k.KO(-1,t,"៉"); + k.KIO(-1,this.s_v_above_47,5,t); + } + else if(k.KFCM(5,t,['ល','្',{t:'a',a:this.s_c_2nd_combo_LO_52},{t:'a',a:this.s_v_above_47},'ុ'])){ + m=1; // Line 428 + k.KDC(5,t); + k.KO(-1,t,"ល"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_2nd_combo_LO_52,3,t); + k.KO(-1,t,"៉"); + k.KIO(-1,this.s_v_above_47,4,t); + } + else if(k.KFCM(5,t,['ម','្',{t:'a',a:this.s_c_2nd_combo_MO_53},'ុ',{t:'a',a:this.s_v_above_47}])){ + m=1; // Line 431 + k.KDC(5,t); + k.KO(-1,t,"ម"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_2nd_combo_MO_53,3,t); + k.KO(-1,t,"៉"); + k.KIO(-1,this.s_v_above_47,5,t); + } + else if(k.KFCM(5,t,['ម','្',{t:'a',a:this.s_c_2nd_combo_MO_53},{t:'a',a:this.s_v_above_47},'ុ'])){ + m=1; // Line 433 + k.KDC(5,t); + k.KO(-1,t,"ម"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_2nd_combo_MO_53,3,t); + k.KO(-1,t,"៉"); + k.KIO(-1,this.s_v_above_47,4,t); + } + else if(k.KFCM(5,t,[{t:'a',a:this.s_shiftable_c_1st_48},'ុ','ំ','ា','ំ'])){ + m=1; // Line 441 + k.KDC(5,t); + k.KIO(-1,this.s_shiftable_c_1st_48,1,t); + k.KO(-1,t,"៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(5,t,[{t:'a',a:this.s_shiftable_c_2nd_with_BA_51},'ុ','ំ','ា','ំ'])){ + m=1; // Line 448 + k.KDC(5,t); + k.KIO(-1,this.s_shiftable_c_2nd_with_BA_51,1,t); + k.KO(-1,t,"៉"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(5,t,['ល','្',{t:'a',a:this.s_c_2nd_combo_LO_52},'៊',{t:'a',a:this.s_v_above_47}])){ + m=1; // Line 452 + k.KDC(5,t); + k.KO(-1,t,"ល"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_2nd_combo_LO_52,3,t); + k.KO(-1,t,"៉"); + k.KIO(-1,this.s_v_above_47,5,t); + } + else if(k.KFCM(5,t,['ម','្',{t:'a',a:this.s_c_2nd_combo_MO_53},'៊',{t:'a',a:this.s_v_above_47}])){ + m=1; // Line 453 + k.KDC(5,t); + k.KO(-1,t,"ម"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_2nd_combo_MO_53,3,t); + k.KO(-1,t,"៉"); + k.KIO(-1,this.s_v_above_47,5,t); + } + else if(k.KFCM(5,t,['្',{t:'a',a:this.s_shiftable_c_2nd_50},'៊',{t:'a',a:this.s_v_gen_14},{t:'a',a:this.s_v_pseudo_16}])){ + m=1; // Line 463 + k.KDC(5,t); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_shiftable_c_2nd_50,2,t); + k.KO(-1,t,"៊"); + k.KIO(-1,this.s_v_gen_14,4,t); + k.KIO(-1,this.s_v_pseudo_16,5,t); + } + else if(k.KFCM(5,t,[{t:'a',a:this.s_c_combo_QA_57},'្','អ','៉',{t:'a',a:this.s_v_above_47}])){ + m=1; // Line 481 + k.KDC(5,t); + k.KIO(-1,this.s_c_combo_QA_57,1,t); + k.KO(-1,t,"្"); + k.KO(-1,t,"អ៊"); + k.KIO(-1,this.s_v_above_47,5,t); + } + else if(k.KFCM(5,t,['ល','្',{t:'a',a:this.s_c_1st_combo_LO_54},'៉',{t:'a',a:this.s_v_above_47}])){ + m=1; // Line 482 + k.KDC(5,t); + k.KO(-1,t,"ល"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_1st_combo_LO_54,3,t); + k.KO(-1,t,"៊"); + k.KIO(-1,this.s_v_above_47,5,t); + } + else if(k.KFCM(5,t,['ម','្',{t:'a',a:this.s_c_1st_combo_MO_55},'៉',{t:'a',a:this.s_v_above_47}])){ + m=1; // Line 483 + k.KDC(5,t); + k.KO(-1,t,"ម"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_1st_combo_MO_55,3,t); + k.KO(-1,t,"៊"); + k.KIO(-1,this.s_v_above_47,5,t); + } + else if(k.KFCM(5,t,['ស','្','ប','៉',{t:'a',a:this.s_v_above_47}])){ + m=1; // Line 484 + k.KDC(5,t); + k.KO(-1,t,"ស"); + k.KO(-1,t,"្"); + k.KO(-1,t,"ប៉"); + k.KIO(-1,this.s_v_above_47,5,t); + } + else if(k.KFCM(5,t,['ស','្',{t:'a',a:this.s_c_combo_SA_56},'៉',{t:'a',a:this.s_v_above_47}])){ + m=1; // Line 485 + k.KDC(5,t); + k.KO(-1,t,"ស"); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_c_combo_SA_56,3,t); + k.KO(-1,t,"៊"); + k.KIO(-1,this.s_v_above_47,5,t); + } + else if(k.KFCM(5,t,[{t:'a',a:this.s_c_combo_HA_58},'្','ហ','៉',{t:'a',a:this.s_v_above_47}])){ + m=1; // Line 486 + k.KDC(5,t); + k.KIO(-1,this.s_c_combo_HA_58,1,t); + k.KO(-1,t,"្"); + k.KO(-1,t,"ហ៊"); + k.KIO(-1,this.s_v_above_47,5,t); + } + else if(k.KFCM(5,t,['អ','្','ង','៉',{t:'a',a:this.s_v_above_47}])){ + m=1; // Line 487 + k.KDC(5,t); + k.KO(-1,t,"អ"); + k.KO(-1,t,"្"); + k.KO(-1,t,"ង៊"); + k.KIO(-1,this.s_v_above_47,5,t); + } + else if(k.KFCM(5,t,['អ','្','វ','៉',{t:'a',a:this.s_v_above_47}])){ + m=1; // Line 488 + k.KDC(5,t); + k.KO(-1,t,"អ"); + k.KO(-1,t,"្"); + k.KO(-1,t,"វ៊"); + k.KIO(-1,this.s_v_above_47,5,t); + } + else if(k.KFCM(5,t,['ព','័','ន','្','ឋ'])){ + m=1; // Line 619 + k.KDC(5,t); + k.KO(-1,t,"ព"); + k.KO(-1,t,"័"); + k.KO(-1,t,"ន"); + k.KO(-1,t,"្ធ"); + } + else if(k.KFCM(4,t,[{t:'a',a:this.s_v_gen_14},{t:'a',a:this.s_v_pseudo_16},{t:'a',a:this.s_v_gen_14},{t:'a',a:this.s_v_pseudo_16}])){ + m=1; // Line 312 + k.KDC(4,t); + k.KIO(-1,this.s_v_gen_14,3,t); + k.KIO(-1,this.s_v_pseudo_16,4,t); + } + else if(k.KFCM(4,t,[{t:'a',a:this.s_v_combo_N_21},'ំ','្',{t:'a',a:this.s_subcons_44}])){ + m=1; // Line 325 + k.KDC(4,t); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_subcons_44,4,t); + k.KIO(-1,this.s_v_combo_N_21,1,t); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(4,t,[{t:'a',a:this.s_v_combo_R_20},'ះ','្',{t:'a',a:this.s_subcons_44}])){ + m=1; // Line 326 + k.KDC(4,t); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_subcons_44,4,t); + k.KIO(-1,this.s_v_combo_R_20,1,t); + k.KO(-1,t,"ះ"); + } + else if(k.KFCM(4,t,[{t:'a',a:this.s_c_shifter_28},{t:'a',a:this.s_v_any_19},'្',{t:'a',a:this.s_subcons_44}])){ + m=1; // Line 330 + k.KDC(4,t); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_subcons_44,4,t); + k.KIO(-1,this.s_c_shifter_28,1,t); + k.KIO(-1,this.s_v_any_19,2,t); + } + else if(k.KFCM(4,t,['្','ដ','្','រ'])){ + m=1; // Line 336 + k.KDC(4,t); + k.KO(-1,t,"្ត"); + k.KO(-1,t,"្"); + k.KO(-1,t,"រ"); + } + else if(k.KFCM(4,t,['្','រ','្','ដ'])){ + m=1; // Line 337 + k.KDC(4,t); + k.KO(-1,t,"្ត"); + k.KO(-1,t,"្"); + k.KO(-1,t,"រ"); + } + else if(k.KFCM(4,t,['្','រ','្',{t:'a',a:this.s_subcons_44}])){ + m=1; // Line 348 + k.KDC(4,t); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_subcons_44,4,t); + k.KO(-1,t,"្"); + k.KO(-1,t,"រ"); + } + else if(k.KFCM(4,t,[{t:'a',a:this.s_c_shifter_28},{t:'a',a:this.s_v_gen_14},{t:'a',a:this.s_v_pseudo_16},{t:'a',a:this.s_c_shifter_28}])){ + m=1; // Line 362 + k.KDC(4,t); + k.KIO(-1,this.s_v_gen_14,2,t); + k.KIO(-1,this.s_v_pseudo_16,3,t); + k.KIO(-1,this.s_c_shifter_28,4,t); + } + else if(k.KFCM(4,t,[{t:'a',a:this.s_shiftable_c_1st_48},'ុ','ា','ំ'])){ + m=1; // Line 439 + k.KDC(4,t); + k.KIO(-1,this.s_shiftable_c_1st_48,1,t); + k.KO(-1,t,"៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(4,t,[{t:'a',a:this.s_shiftable_c_2nd_with_BA_51},'ុ','ា','ំ'])){ + m=1; // Line 446 + k.KDC(4,t); + k.KIO(-1,this.s_shiftable_c_2nd_with_BA_51,1,t); + k.KO(-1,t,"៉"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(4,t,[{t:'a',a:this.s_shiftable_c_2nd_50},'៊',{t:'a',a:this.s_v_gen_14},{t:'a',a:this.s_v_pseudo_16}])){ + m=1; // Line 460 + k.KDC(4,t); + k.KIO(-1,this.s_shiftable_c_2nd_50,1,t); + k.KO(-1,t,"៉"); + k.KIO(-1,this.s_v_gen_14,3,t); + k.KIO(-1,this.s_v_pseudo_16,4,t); + } + else if(k.KFCM(4,t,['្',{t:'a',a:this.s_shiftable_c_2nd_50},'៊',{t:'a',a:this.s_v_above_47}])){ + m=1; // Line 462 + k.KDC(4,t); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_shiftable_c_2nd_50,2,t); + k.KO(-1,t,"៊"); + k.KIO(-1,this.s_v_above_47,4,t); + } + else if(k.KFCM(4,t,['ប','្','យ',{t:'a',a:this.s_c_shifter_28}])){ + m=1; // Line 467 + k.KDC(4,t); + k.KO(-1,t,"ប្យ"); + k.KIO(-1,this.s_c_shifter_28,4,t); + } + else if(k.KFCM(4,t,['ស','្','ប',{t:'a',a:this.s_c_shifter_28}])){ + m=1; // Line 468 + k.KDC(4,t); + k.KO(-1,t,"ស្ប"); + k.KIO(-1,this.s_c_shifter_28,4,t); + } + else if(k.KFCM(4,t,['ឆ','្','ប',{t:'a',a:this.s_c_shifter_28}])){ + m=1; // Line 469 + k.KDC(4,t); + k.KO(-1,t,"ឆ្ប"); + k.KIO(-1,this.s_c_shifter_28,4,t); + } + else if(k.KFCM(4,t,['ប','្','យ',{t:'a',a:this.s_c_shifter_28}])){ + m=1; // Line 470 + k.KDC(4,t); + k.KO(-1,t,"ប្យ"); + k.KIO(-1,this.s_c_shifter_28,4,t); + } + else if(k.KFCM(4,t,['ស','្','ប',{t:'a',a:this.s_c_shifter_28}])){ + m=1; // Line 471 + k.KDC(4,t); + k.KO(-1,t,"ស្ប"); + k.KIO(-1,this.s_c_shifter_28,4,t); + } + else if(k.KFCM(4,t,['ឆ','្','ប',{t:'a',a:this.s_c_shifter_28}])){ + m=1; // Line 472 + k.KDC(4,t); + k.KO(-1,t,"ឆ្ប"); + k.KIO(-1,this.s_c_shifter_28,4,t); + } + else if(k.KFCM(4,t,[{t:'a',a:this.s_shiftable_c_1st_48},'៉',{t:'a',a:this.s_v_gen_14},{t:'a',a:this.s_v_pseudo_16}])){ + m=1; // Line 477 + k.KDC(4,t); + k.KIO(-1,this.s_shiftable_c_1st_48,1,t); + k.KO(-1,t,"៊"); + k.KIO(-1,this.s_v_gen_14,3,t); + k.KIO(-1,this.s_v_pseudo_16,4,t); + } + else if(k.KFCM(4,t,[{t:'a',a:this.s_shiftable_c_1st_48},'ា','ុ','ំ'])){ + m=1; // Line 500 + k.KDC(4,t); + k.KIO(-1,this.s_shiftable_c_1st_48,1,t); + k.KO(-1,t,"៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(4,t,[{t:'a',a:this.s_shiftable_c_1st_48},'ុ','ំ','ា'])){ + m=1; // Line 501 + k.KDC(4,t); + k.KIO(-1,this.s_shiftable_c_1st_48,1,t); + k.KO(-1,t,"៊"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(4,t,[{t:'a',a:this.s_shiftable_c_2nd_with_BA_51},'ា','ុ','ំ'])){ + m=1; // Line 526 + k.KDC(4,t); + k.KIO(-1,this.s_shiftable_c_2nd_with_BA_51,1,t); + k.KO(-1,t,"៉"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(4,t,[{t:'a',a:this.s_shiftable_c_2nd_with_BA_51},'ុ','ំ','ា'])){ + m=1; // Line 527 + k.KDC(4,t); + k.KIO(-1,this.s_shiftable_c_2nd_with_BA_51,1,t); + k.KO(-1,t,"៉"); + k.KO(-1,t,"ា"); + k.KO(-1,t,"ំ"); + } + else if(k.KFCM(4,t,[{t:'a',a:this.s_shiftable_c_1st_48},'េ','ុ','ី'])){ + m=1; // Line 537 + k.KDC(4,t); + k.KIO(-1,this.s_shiftable_c_1st_48,1,t); + k.KO(-1,t,"៊ើ"); + } + else if(k.KFCM(4,t,[{t:'a',a:this.s_shiftable_c_1st_48},'ុ','េ','ី'])){ + m=1; // Line 538 + k.KDC(4,t); + k.KIO(-1,this.s_shiftable_c_1st_48,1,t); + k.KO(-1,t,"៊ើ"); + } + else if(k.KFCM(4,t,[{t:'a',a:this.s_shiftable_c_1st_48},'៉','េ','ី'])){ + m=1; // Line 539 + k.KDC(4,t); + k.KIO(-1,this.s_shiftable_c_1st_48,1,t); + k.KO(-1,t,"៊ើ"); + } + else if(k.KFCM(4,t,[{t:'a',a:this.s_shiftable_c_2nd_50},'េ','ុ','ី'])){ + m=1; // Line 571 + k.KDC(4,t); + k.KIO(-1,this.s_shiftable_c_2nd_50,1,t); + k.KO(-1,t,"៉ើ"); + } + else if(k.KFCM(4,t,[{t:'a',a:this.s_shiftable_c_2nd_50},'ុ','េ','ី'])){ + m=1; // Line 572 + k.KDC(4,t); + k.KIO(-1,this.s_shiftable_c_2nd_50,1,t); + k.KO(-1,t,"៉ើ"); + } + else if(k.KFCM(4,t,[{t:'a',a:this.s_shiftable_c_2nd_50},'៊','េ','ី'])){ + m=1; // Line 573 + k.KDC(4,t); + k.KIO(-1,this.s_shiftable_c_2nd_50,1,t); + k.KO(-1,t,"៉ើ"); + } + else if(k.KFCM(4,t,['ព','ន','្','ឋ'])){ + m=1; // Line 618 + k.KDC(4,t); + k.KO(-1,t,"ព"); + k.KO(-1,t,"ន"); + k.KO(-1,t,"្ធ"); + } + else if(k.KFCM(4,t,['្','យ','េ','ឺ'])){ + m=1; // Line 627 + k.KDC(4,t); + k.KO(-1,t,"ឿ"); + } + else if(k.KFCM(4,t,['្','យ','េ','ឹ'])){ + m=1; // Line 628 + k.KDC(4,t); + k.KO(-1,t,"ឿ"); + } + else if(k.KFCM(4,t,['្','យ','េ','ី'])){ + m=1; // Line 629 + k.KDC(4,t); + k.KO(-1,t,"ឿ"); + } + else if(k.KFCM(3,t,[{t:'a',a:this.s_v_gen_14},{t:'a',a:this.s_v_pseudo_16},{t:'a',a:this.s_v_gen_14}])){ + m=1; // Line 308 + k.KDC(3,t); + k.KIO(-1,this.s_v_gen_14,3,t); + } + else if(k.KFCM(3,t,[{t:'a',a:this.s_v_gen_14},{t:'a',a:this.s_v_pseudo_16},{t:'a',a:this.s_v_pseudo_16}])){ + m=1; // Line 309 + k.KDC(3,t); + k.KIO(-1,this.s_v_pseudo_16,3,t); + } + else if(k.KFCM(3,t,[{t:'a',a:this.s_v_gen_14},{t:'a',a:this.s_v_gen_14},{t:'a',a:this.s_v_pseudo_16}])){ + m=1; // Line 310 + k.KDC(3,t); + k.KIO(-1,this.s_v_gen_14,2,t); + k.KIO(-1,this.s_v_pseudo_16,3,t); + } + else if(k.KFCM(3,t,[{t:'a',a:this.s_v_pseudo_16},{t:'a',a:this.s_v_gen_14},{t:'a',a:this.s_v_pseudo_16}])){ + m=1; // Line 311 + k.KDC(3,t); + k.KIO(-1,this.s_v_gen_14,2,t); + k.KIO(-1,this.s_v_pseudo_16,3,t); + } + else if(k.KFCM(3,t,['្',{t:'a',a:this.s_v_gen_14},{t:'a',a:this.s_v_pseudo_16}])){ + m=1; // Line 320 + k.KDC(3,t); + k.KIO(-1,this.s_v_gen_14,2,t); + k.KIO(-1,this.s_v_pseudo_16,3,t); + } + else if(k.KFCM(3,t,[{t:'a',a:this.s_v_any_19},'្',{t:'a',a:this.s_subcons_44}])){ + m=1; // Line 324 + k.KDC(3,t); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_subcons_44,3,t); + k.KIO(-1,this.s_v_any_19,1,t); + } + else if(k.KFCM(3,t,[{t:'a',a:this.s_c_shifter_28},'្',{t:'a',a:this.s_subcons_44}])){ + m=1; // Line 355 + k.KDC(3,t); + k.KO(-1,t,"្"); + k.KIO(-1,this.s_subcons_44,3,t); + k.KIO(-1,this.s_c_shifter_28,1,t); + } + else if(k.KFCM(3,t,[{t:'a',a:this.s_v_gen_14},{t:'a',a:this.s_v_pseudo_16},{t:'a',a:this.s_c_shifter_28}])){ + m=1; // Line 360 + k.KDC(3,t); + k.KIO(-1,this.s_c_shifter_28,3,t); + k.KIO(-1,this.s_v_gen_14,1,t); + k.KIO(-1,this.s_v_pseudo_16,2,t); + } + else if(k.KFCM(3,t,[{t:'a',a:this.s_c_shifter_28},{t:'a',a:this.s_v_any_19},{t:'a',a:this.s_c_shifter_28}])){ + m=1; // Line 361 + k.KDC(3,t); + k.KIO(-1,this.s_c_shifter_28,3,t); + k.KIO(-1,this.s_v_any_19,2,t); + } + else if(k.KFCM(3,t,[{t:'a',a:this.s_shiftable_c_1st_48},'ុ',{t:'a',a:this.s_v_above_47}])){ + m=1; // Line 438 + k.KDC(3,t); + k.KIO(-1,this.s_shiftable_c_1st_48,1,t); + k.KO(-1,t,"៊"); + k.KIO(-1,this.s_v_above_47,3,t); + } + else if(k.KFCM(3,t,[{t:'a',a:this.s_shiftable_c_1st_48},{t:'a',a:this.s_v_above_47},'ុ'])){ + m=1; // Line 440 + k.KDC(3,t); + k.KIO(-1,this.s_shiftable_c_1st_48,1,t); + k.KO(-1,t,"៊"); + k.KIO(-1,this.s_v_above_47,2,t); + } + else if(k.KFCM(3,t,[{t:'a',a:this.s_shiftable_c_2nd_with_BA_51},'ុ',{t:'a',a:this.s_v_above_47}])){ + m=1; // Line 445 + k.KDC(3,t); + k.KIO(-1,this.s_shiftable_c_2nd_with_BA_51,1,t); + k.KO(-1,t,"៉"); + k.KIO(-1,this.s_v_above_47,3,t); + } + else if(k.KFCM(3,t,[{t:'a',a:this.s_shiftable_c_2nd_with_BA_51},{t:'a',a:this.s_v_above_47},'ុ'])){ + m=1; // Line 447 + k.KDC(3,t); + k.KIO(-1,this.s_shiftable_c_2nd_with_BA_51,1,t); + k.KO(-1,t,"៉"); + k.KIO(-1,this.s_v_above_47,2,t); + } + else if(k.KFCM(3,t,[{t:'a',a:this.s_shiftable_c_2nd_50},'៊',{t:'a',a:this.s_v_above_47}])){ + m=1; // Line 459 + k.KDC(3,t); + k.KIO(-1,this.s_shiftable_c_2nd_50,1,t); + k.KO(-1,t,"៉"); + k.KIO(-1,this.s_v_above_47,3,t); + } + else if(k.KFCM(3,t,[{t:'a',a:this.s_shiftable_c_1st_48},'៉',{t:'a',a:this.s_v_above_47}])){ + m=1; // Line 476 + k.KDC(3,t); + k.KIO(-1,this.s_shiftable_c_1st_48,1,t); + k.KO(-1,t,"៊"); + k.KIO(-1,this.s_v_above_47,3,t); + } + else if(k.KFCM(3,t,[{t:'a',a:this.s_c_out_12},{t:'a',a:this.s_v_gen_14},'៌'])){ + m=1; // Line 585 + k.KDC(3,t); + k.KIO(-1,this.s_c_out_12,1,t); + k.KO(-1,t,"៌"); + k.KIO(-1,this.s_v_gen_14,2,t); + } + else if(k.KFCM(3,t,['ណ','្','ត'])){ + m=1; // Line 589 + k.KDC(3,t); + k.KO(-1,t,"ណ"); + k.KO(-1,t,"្ដ"); + } + else if(k.KFCM(3,t,['ន','្','ដ'])){ + m=1; // Line 590 + k.KDC(3,t); + k.KO(-1,t,"ន"); + k.KO(-1,t,"្ត"); + } + else if(k.KFCM(3,t,['ទ','្','ប'])){ + m=1; // Line 594 + k.KDC(3,t); + k.KO(-1,t,"ឡ"); + } + else if(k.KFCM(3,t,['ប','្','ញ'])){ + m=1; // Line 596 + k.KDC(3,t); + k.KO(-1,t,"ឫ"); + } + else if(k.KFCM(3,t,['ព','្','ញ'])){ + m=1; // Line 602 + k.KDC(3,t); + k.KO(-1,t,"ឭ"); + } + else if(k.KFCM(3,t,['ព','្','ឋ'])){ + m=1; // Line 605 + k.KDC(3,t); + k.KO(-1,t,"ឰ"); + } + else if(k.KFCM(3,t,['ដ','្','ធ'])){ + m=1; // Line 613 + k.KDC(3,t); + k.KO(-1,t,"ដ្ឋ"); + } + else if(k.KFCM(3,t,['ទ','្','ឋ'])){ + m=1; // Line 614 + k.KDC(3,t); + k.KO(-1,t,"ទ្ធ"); + } + else if(k.KFCM(3,t,['ឪ','្','យ'])){ + m=1; // Line 622 + k.KDC(3,t); + k.KO(-1,t,"ឱ"); + k.KO(-1,t,"្"); + k.KO(-1,t,"យ"); + } + else if(k.KFCM(3,t,['ឳ','្','យ'])){ + m=1; // Line 623 + k.KDC(3,t); + k.KO(-1,t,"ឱ"); + k.KO(-1,t,"្"); + k.KO(-1,t,"យ"); + } + else if(k.KFCM(3,t,['ញ','្','វ'])){ + m=1; // Line 625 + k.KDC(3,t); + k.KO(-1,t,"ព"); + k.KO(-1,t,"្"); + k.KO(-1,t,"វា"); + } + else if(k.KFCM(2,t,['េ','ា'])){ + m=1; // Line 291 + k.KDC(2,t); + k.KO(-1,t,"ោ"); + } + else if(k.KFCM(2,t,['ា','េ'])){ + m=1; // Line 292 + k.KDC(2,t); + k.KO(-1,t,"ោ"); + } + else if(k.KFCM(2,t,['េ','ី'])){ + m=1; // Line 293 + k.KDC(2,t); + k.KO(-1,t,"ើ"); + } + else if(k.KFCM(2,t,['ី','េ'])){ + m=1; // Line 294 + k.KDC(2,t); + k.KO(-1,t,"ើ"); + } + else if(k.KFCM(2,t,['ំ','ុ'])){ + m=1; // Line 298 + k.KDC(2,t); + k.KO(-1,t,"ុំ"); + } + else if(k.KFCM(2,t,['ំ','ា'])){ + m=1; // Line 299 + k.KDC(2,t); + k.KO(-1,t,"ាំ"); + } + else if(k.KFCM(2,t,[{t:'a',a:this.s_v_gen_14},{t:'a',a:this.s_v_gen_14}])){ + m=1; // Line 304 + k.KDC(2,t); + k.KIO(-1,this.s_v_gen_14,2,t); + } + else if(k.KFCM(2,t,[{t:'a',a:this.s_v_pseudo_16},{t:'a',a:this.s_v_pseudo_16}])){ + m=1; // Line 313 + k.KDC(2,t); + k.KIO(-1,this.s_v_pseudo_16,2,t); + } + if(m) {} + else if(k.KFCM(2,t,['្','្'])){ + m=1; // Line 318 + k.KDC(2,t); + k.KO(-1,t,"្"); + } + else if(k.KFCM(2,t,['្',{t:'a',a:this.s_v_any_19}])){ + m=1; // Line 319 + k.KDC(2,t); + k.KIO(-1,this.s_v_any_19,2,t); + } + else if(k.KFCM(2,t,[{t:'a',a:this.s_v_any_19},{t:'a',a:this.s_c_shifter_28}])){ + m=1; // Line 359 + k.KDC(2,t); + k.KIO(-1,this.s_c_shifter_28,2,t); + k.KIO(-1,this.s_v_any_19,1,t); + } + else if(k.KFCM(2,t,['ឫ','ុ'])){ + m=1; // Line 597 + k.KDC(2,t); + k.KO(-1,t,"ឬ"); + } + else if(k.KFCM(2,t,['ឭ','ា'])){ + m=1; // Line 599 + k.KDC(2,t); + k.KO(-1,t,"ញ"); + } + else if(k.KFCM(2,t,['ឮ','ា'])){ + m=1; // Line 600 + k.KDC(2,t); + k.KO(-1,t,"ញ"); + } + else if(k.KFCM(2,t,['ឭ','ុ'])){ + m=1; // Line 603 + k.KDC(2,t); + k.KO(-1,t,"ឮ"); + } + else if(k.KFCM(2,t,['ឧ','ិ'])){ + m=1; // Line 607 + k.KDC(2,t); + k.KO(-1,t,"ឱ"); + } + else if(k.KFCM(2,t,['ឧ','៌'])){ + m=1; // Line 608 + k.KDC(2,t); + k.KO(-1,t,"ឱ"); + } + else if(k.KFCM(2,t,['ឧ','៍'])){ + m=1; // Line 609 + k.KDC(2,t); + k.KO(-1,t,"ឱ"); + } + return r; + }; +} diff --git a/developer/src/kmc-keyboard-info/test/fixtures/hint_script_does_not_match/build/khmer_angkor.kmp b/developer/src/kmc-keyboard-info/test/fixtures/hint_script_does_not_match/build/khmer_angkor.kmp new file mode 100644 index 00000000000..c3449523e39 Binary files /dev/null and b/developer/src/kmc-keyboard-info/test/fixtures/hint_script_does_not_match/build/khmer_angkor.kmp differ diff --git a/developer/src/kmc-keyboard-info/test/fixtures/hint_script_does_not_match/build/khmer_angkor.kmx b/developer/src/kmc-keyboard-info/test/fixtures/hint_script_does_not_match/build/khmer_angkor.kmx new file mode 100644 index 00000000000..d8495d187c4 Binary files /dev/null and b/developer/src/kmc-keyboard-info/test/fixtures/hint_script_does_not_match/build/khmer_angkor.kmx differ diff --git a/developer/src/kmc-keyboard-info/test/fixtures/hint_script_does_not_match/khmer_angkor.kpj b/developer/src/kmc-keyboard-info/test/fixtures/hint_script_does_not_match/khmer_angkor.kpj new file mode 100644 index 00000000000..4b239df20ce --- /dev/null +++ b/developer/src/kmc-keyboard-info/test/fixtures/hint_script_does_not_match/khmer_angkor.kpj @@ -0,0 +1,187 @@ + + + + $PROJECTPATH\build + True + True + False + keyboard + + + + id_f347675c33d2e6b1c705c787fad4941a + khmer_angkor.kmn + source\khmer_angkor.kmn + 1.3 + .kmn +
+ Khmer Angkor + © 2015-2022 SIL International + More than just a Khmer Unicode keyboard. +
+
+ + id_8d4eb765f80c9f2b0f769cf4e4aaa456 + khmer_angkor.kps + source\khmer_angkor.kps + + .kps +
+ Khmer Angkor + © 2015-2022 SIL International +
+
+ + id_8a1efc7c4ab7cfece8aedd847679ca27 + khmer_angkor.ico + source\khmer_angkor.ico + + .ico + id_f347675c33d2e6b1c705c787fad4941a + + + id_8dc195db32d1fd0514de0ad51fff5df0 + khmer_angkor.js + source\..\build\khmer_angkor.js + + .js + id_8d4eb765f80c9f2b0f769cf4e4aaa456 + + + id_10596632fcbf4138d24bcccf53e6ae01 + khmer_angkor.kvk + source\..\build\khmer_angkor.kvk + + .kvk + id_8d4eb765f80c9f2b0f769cf4e4aaa456 + + + id_0a851f95ce553ecd62cbee6c32ced68f + khmer_angkor.kmx + source\..\build\khmer_angkor.kmx + + .kmx + id_8d4eb765f80c9f2b0f769cf4e4aaa456 + + + id_d8b6eb05f4b7e2945c10e04c1f49e4c8 + keyboard_layout.png + source\welcome\keyboard_layout.png + + .png + id_8d4eb765f80c9f2b0f769cf4e4aaa456 + + + id_724e5b4c63f10bc0abf7077f7c3172fc + welcome.htm + source\welcome\welcome.htm + + .htm + id_8d4eb765f80c9f2b0f769cf4e4aaa456 + + + id_35857cb2b54f123612735ec948400082 + FONTLOG.txt + source\..\..\..\shared\fonts\khmer\mondulkiri\FONTLOG.txt + + .txt + id_8d4eb765f80c9f2b0f769cf4e4aaa456 + + + id_7e3afe5bb59b888b08b48cd5817d8de4 + Mondulkiri-B.ttf + source\..\..\..\shared\fonts\khmer\mondulkiri\Mondulkiri-B.ttf + + .ttf + id_8d4eb765f80c9f2b0f769cf4e4aaa456 + + + id_b9734e80f86c69ea5ae4dfa9f0083d09 + Mondulkiri-BI.ttf + source\..\..\..\shared\fonts\khmer\mondulkiri\Mondulkiri-BI.ttf + + .ttf + id_8d4eb765f80c9f2b0f769cf4e4aaa456 + + + id_25abe4d2b0abc03a5be5b666a8de776e + Mondulkiri-I.ttf + source\..\..\..\shared\fonts\khmer\mondulkiri\Mondulkiri-I.ttf + + .ttf + id_8d4eb765f80c9f2b0f769cf4e4aaa456 + + + id_b766568498108eee46ed1601ff69c47d + Mondulkiri-R.ttf + source\..\..\..\shared\fonts\khmer\mondulkiri\Mondulkiri-R.ttf + + .ttf + id_8d4eb765f80c9f2b0f769cf4e4aaa456 + + + id_84544d04133cab3dbfc86b91ad1a4e17 + OFL.txt + source\..\..\..\shared\fonts\khmer\mondulkiri\OFL.txt + + .txt + id_8d4eb765f80c9f2b0f769cf4e4aaa456 + + + id_0c33fbefd1c20f487b1bea2343b3bb2c + OFL-FAQ.txt + source\..\..\..\shared\fonts\khmer\mondulkiri\OFL-FAQ.txt + + .txt + id_8d4eb765f80c9f2b0f769cf4e4aaa456 + + + id_a59d89fca36a310147645fa2604e521b + KAK_Documentation_EN.pdf + source\welcome\KAK_Documentation_EN.pdf + + .pdf + id_8d4eb765f80c9f2b0f769cf4e4aaa456 + + + id_5643c4cd3933b3ada0b4af6579305ec4 + KAK_Documentation_KH.pdf + source\welcome\KAK_Documentation_KH.pdf + + .pdf + id_8d4eb765f80c9f2b0f769cf4e4aaa456 + + + id_8da344c4cea6f467013357fe099006f5 + readme.htm + source\readme.htm + + .htm + id_8d4eb765f80c9f2b0f769cf4e4aaa456 + + + id_acb0dd94c60e345d999670e999cbd159 + image002.png + source\welcome\image002.png + + .png + id_8d4eb765f80c9f2b0f769cf4e4aaa456 + + + id_4edf70bc019f05b5ad39a2ea727ad547 + khmer_busra_kbd.ttf + source\..\..\..\shared\fonts\khmer\busrakbd\khmer_busra_kbd.ttf + + .ttf + id_8d4eb765f80c9f2b0f769cf4e4aaa456 + + + id_bc823844e4399751e1867016801f7327 + splash.gif + source\splash.gif + + .gif + id_8d4eb765f80c9f2b0f769cf4e4aaa456 + +
+
diff --git a/developer/src/kmc-keyboard-info/test/fixtures/hint_script_does_not_match/source/khmer_angkor.kps b/developer/src/kmc-keyboard-info/test/fixtures/hint_script_does_not_match/source/khmer_angkor.kps new file mode 100644 index 00000000000..2aa2a6f400f --- /dev/null +++ b/developer/src/kmc-keyboard-info/test/fixtures/hint_script_does_not_match/source/khmer_angkor.kps @@ -0,0 +1,51 @@ + + + + 15.0.266.0 + 7.0 + + + ..\LICENSE.md + + + + Khmer Angkor + © 2015-2022 SIL International + Makara Sok + + https://keyman.com/keyboards/khmer_angkor + Khmer Unicode keyboard layout based on the NiDA keyboard layout. Automatically corrects many common keying errors. + + + + ..\LICENSE.md + File LICENSE.md + 0 + .md + + + ..\build\khmer_angkor.kmx + Keyboard Khmer Angkor + 0 + .kmx + + + ..\build\khmer_angkor.js + Keyboard Khmer Angkor + 0 + .js + + + + + Khmer Angkor + khmer_angkor + 1.3 + + English + German + Dai Zhuang + + + + diff --git a/developer/src/kmc-keyboard-info/test/test-font-family.ts b/developer/src/kmc-keyboard-info/test/font-family.tests.ts similarity index 100% rename from developer/src/kmc-keyboard-info/test/test-font-family.ts rename to developer/src/kmc-keyboard-info/test/font-family.tests.ts diff --git a/developer/src/kmc-keyboard-info/test/test-keyboard-info-compiler-messages.ts b/developer/src/kmc-keyboard-info/test/keyboard-info-compiler-messages.tests.ts similarity index 90% rename from developer/src/kmc-keyboard-info/test/test-keyboard-info-compiler-messages.ts rename to developer/src/kmc-keyboard-info/test/keyboard-info-compiler-messages.tests.ts index 2bf73b7dd31..379583944c0 100644 --- a/developer/src/kmc-keyboard-info/test/test-keyboard-info-compiler-messages.ts +++ b/developer/src/kmc-keyboard-info/test/keyboard-info-compiler-messages.tests.ts @@ -5,15 +5,11 @@ import { TestCompilerCallbacks, verifyCompilerMessagesObject } from '@keymanapp/ import { KmpJsonFile, KeymanFileTypes } from '@keymanapp/common-types'; import { CompilerErrorNamespace } from '@keymanapp/developer-utils'; import { makePathToFixture } from './helpers/index.js'; -import { KeyboardInfoCompiler, KeyboardInfoCompilerResult } from '../src/keyboard-info-compiler.js'; +import { KeyboardInfoCompiler } from '../src/keyboard-info-compiler.js'; import { KeyboardInfoFile } from '../src/keyboard-info-file.js'; const callbacks = new TestCompilerCallbacks(); -beforeEach(function() { - callbacks.clear(); -}); - const KHMER_ANGKOR_JS = makePathToFixture('khmer_angkor', 'build', 'khmer_angkor.js'); const KHMER_ANGKOR_KPS = makePathToFixture('khmer_angkor', 'source', 'khmer_angkor.kps'); const KHMER_ANGKOR_KMP = makePathToFixture('khmer_angkor', 'build', 'khmer_angkor.kmp'); @@ -27,6 +23,17 @@ const KHMER_ANGKOR_SOURCES = { }; describe('KeyboardInfoCompilerMessages', function () { + + this.beforeEach(function() { + callbacks.clear(); + }); + + this.afterEach(function() { + if(this.currentTest?.isFailed()) { + callbacks.printMessages(); + } + }) + it('should have a valid KeyboardInfoCompilerMessages object', function() { return verifyCompilerMessagesObject(KeyboardInfoCompilerMessages, CompilerErrorNamespace.KeyboardInfoCompiler); }); @@ -43,13 +50,7 @@ describe('KeyboardInfoCompilerMessages', function () { const compiler = new KeyboardInfoCompiler(); assert.isTrue(await compiler.init(callbacks, {sources})); - let result: KeyboardInfoCompilerResult = null; - try { - result = await compiler.run(KHMER_ANGKOR_KMP, null); - } catch(e) { - callbacks.printMessages(); - throw e; - } + const result = await compiler.run(KHMER_ANGKOR_KMP, null); assert.isNull(result); assert.isTrue(callbacks.hasMessage(KeyboardInfoCompilerMessages.ERROR_FileDoesNotExist), @@ -77,13 +78,7 @@ describe('KeyboardInfoCompilerMessages', function () { assert.isTrue(await compiler.init(callbacks, {sources})); // stubbing fillLanguages internal function to avoid pulling in font resources in fixture compiler['fillLanguages'] = async (_kpsFilename: string, _keyboard_info: KeyboardInfoFile, _kmpJsonData: KmpJsonFile.KmpJsonFile): Promise => true; - let result: KeyboardInfoCompilerResult = null; - try { - result = await compiler.run(kmpFilename, null); - } catch(e) { - callbacks.printMessages(); - throw e; - } + const result = await compiler.run(kmpFilename, null); assert.isNull(result); assert.isTrue(callbacks.hasMessage(KeyboardInfoCompilerMessages.ERROR_FileDoesNotExist), @@ -216,13 +211,7 @@ describe('KeyboardInfoCompilerMessages', function () { const compiler = new KeyboardInfoCompiler(); assert.isTrue(await compiler.init(callbacks, {sources})); - let result: KeyboardInfoCompilerResult = null; - try { - result = await compiler.run(kmpFilename, null); - } catch(e) { - callbacks.printMessages(); - throw e; - } + const result = await compiler.run(kmpFilename, null); assert.isNull(result); assert.isTrue(callbacks.hasMessage(KeyboardInfoCompilerMessages.ERROR_CannotBuildWithoutKmpFile), @@ -246,13 +235,7 @@ describe('KeyboardInfoCompilerMessages', function () { const compiler = new KeyboardInfoCompiler(); assert.isTrue(await compiler.init(callbacks, {sources})); - let result: KeyboardInfoCompilerResult = null; - try { - result = await compiler.run(kmpFilename, null); - } catch(e) { - callbacks.printMessages(); - throw e; - } + const result = await compiler.run(kmpFilename, null); assert.isNull(result); assert.isTrue(callbacks.hasMessage(KeyboardInfoCompilerMessages.ERROR_NoLicenseFound), @@ -305,19 +288,35 @@ describe('KeyboardInfoCompilerMessages', function () { const compiler = new KeyboardInfoCompiler(); assert.isTrue(await compiler.init(callbacks, {sources})); - let result: KeyboardInfoCompilerResult = null; - try { - result = await compiler.run(kmpFilename, null); - } catch(e) { - callbacks.printMessages(); - throw e; - } + const result = await compiler.run(kmpFilename, null); assert.isNull(result); assert.isTrue(callbacks.hasMessage(KeyboardInfoCompilerMessages.ERROR_InvalidAuthorEmail), `ERROR_InvalidAuthorEmail not generated, instead got: `+JSON.stringify(callbacks.messages,null,2)); }); + // HINT_ScriptDoesNotMatch + + it('should generate HINT_ScriptDoesNotMatch if there is a mismatching language script in .kps', async function() { + const jsFilename = makePathToFixture('hint_script_does_not_match', 'build', 'khmer_angkor.js'); + const kpsFilename = makePathToFixture('hint_script_does_not_match', 'source', 'khmer_angkor.kps'); + const kmpFilename = makePathToFixture('hint_script_does_not_match', 'build', 'khmer_angkor.kmp'); + + const sources = { + kmpFilename, + sourcePath: 'release/h/hint_script_does_not_match', + kpsFilename, + jsFilename: jsFilename, + forPublishing: true, + }; + + const compiler = new KeyboardInfoCompiler(); + assert.isTrue(await compiler.init(callbacks, {sources})); + const result = await compiler.run(kmpFilename, null); + assert.isNotNull(result); + + assert.isTrue(callbacks.hasMessage(KeyboardInfoCompilerMessages.HINT_ScriptDoesNotMatch)); + }); }); function nodeCompilerMessage(ncb: TestCompilerCallbacks, code: number): string { diff --git a/developer/src/kmc-keyboard-info/test/test-keyboard-info-compiler.ts b/developer/src/kmc-keyboard-info/test/keyboard-info-compiler.tests.ts similarity index 100% rename from developer/src/kmc-keyboard-info/test/test-keyboard-info-compiler.ts rename to developer/src/kmc-keyboard-info/test/keyboard-info-compiler.tests.ts diff --git a/developer/src/kmc-keyboard-info/test/tsconfig.json b/developer/src/kmc-keyboard-info/test/tsconfig.json index e16b935aa47..2d85e0fcbdb 100644 --- a/developer/src/kmc-keyboard-info/test/tsconfig.json +++ b/developer/src/kmc-keyboard-info/test/tsconfig.json @@ -10,7 +10,7 @@ "baseUrl": ".", }, "include": [ - "**/test-*.ts", + "**/*.tests.ts", "helpers/*.ts", ], "references": [ @@ -18,4 +18,4 @@ { "path": "../../common/web/test-helpers/" }, { "path": "../../kmc-package/" }, ] -} \ No newline at end of file +} diff --git a/developer/src/kmc-kmn/build.sh b/developer/src/kmc-kmn/build.sh index a0732414758..c6ed29b6f94 100755 --- a/developer/src/kmc-kmn/build.sh +++ b/developer/src/kmc-kmn/build.sh @@ -56,27 +56,19 @@ function copy_deps() { cp ../kmcmplib/build/wasm/$BUILDER_CONFIGURATION/src/wasm-host.wasm ./build/src/import/kmcmplib/wasm-host.wasm } -if builder_start_action build; then +function do_build() { copy_deps tsc --build - builder_finish_action success build -fi - -builder_run_action api api-extractor run --local --verbose - -#------------------------------------------------------------------------------------------------------------------- +} -if builder_start_action test; then +function do_test() { copy_deps - tsc --build test/ - npm run lint - readonly C8_THRESHOLD=80 - c8 --reporter=lcov --reporter=text --lines $C8_THRESHOLD --statements $C8_THRESHOLD --branches $C8_THRESHOLD --functions $C8_THRESHOLD mocha - builder_echo warning "Coverage thresholds are currently $C8_THRESHOLD%, which is lower than ideal." - builder_echo warning "Please increase threshold in build.sh as test coverage improves." + builder_do_typescript_tests 80 +} - builder_finish_action success test -fi +builder_run_action build do_build +builder_run_action api api-extractor run --local --verbose +builder_run_action test do_test #------------------------------------------------------------------------------------------------------------------- diff --git a/developer/src/kmc-kmn/package.json b/developer/src/kmc-kmn/package.json index fc9470a6bce..1f5b8bbe9ba 100644 --- a/developer/src/kmc-kmn/package.json +++ b/developer/src/kmc-kmn/package.json @@ -44,7 +44,7 @@ "typescript": "^5.4.5" }, "mocha": { - "spec": "build/test/**/test-*.js", + "spec": "build/test/**/*.tests.js", "require": [ "source-map-support/register" ] diff --git a/developer/src/kmc-kmn/src/compiler/compiler.ts b/developer/src/kmc-kmn/src/compiler/compiler.ts index 1914a022b12..9859483fb26 100644 --- a/developer/src/kmc-kmn/src/compiler/compiler.ts +++ b/developer/src/kmc-kmn/src/compiler/compiler.ts @@ -6,7 +6,7 @@ TODO: implement additional interfaces: */ // TODO: rename wasm-host? -import { VisualKeyboard, KvkFileReader, UnicodeSetParser, UnicodeSet, KeymanFileTypes, KvkFileWriter } from '@keymanapp/common-types'; +import { VisualKeyboard, KvkFileReader, LdmlKeyboardTypes, KeymanFileTypes, KvkFileWriter } from '@keymanapp/common-types'; import { CompilerCallbacks, CompilerEvent, CompilerOptions, KeymanCompiler, KeymanCompilerArtifacts, KeymanCompilerArtifactOptional, KeymanCompilerResult, KeymanCompilerArtifact, KvksFileReader @@ -140,7 +140,7 @@ let * or write from filesystem or network directly, but relies on callbacks for all * external IO. */ -export class KmnCompiler implements KeymanCompiler, UnicodeSetParser { +export class KmnCompiler implements KeymanCompiler, LdmlKeyboardTypes.UnicodeSetParser { private callbacks: CompilerCallbacks; private wasmExports: MallocAndFree; private options: KmnCompilerOptions; @@ -529,7 +529,7 @@ export class KmnCompiler implements KeymanCompiler, UnicodeSetParser { * @param rangeCount - number of ranges to allocate * @returns UnicodeSet accessor object, or null on failure */ - public parseUnicodeSet(pattern: string, rangeCount: number) : UnicodeSet | null { + public parseUnicodeSet(pattern: string, rangeCount: number) : LdmlKeyboardTypes.UnicodeSet | null { if(!this.verifyInitialized()) { /* c8 ignore next 2 */ // verifyInitialized will set a callback if needed @@ -557,7 +557,7 @@ export class KmnCompiler implements KeymanCompiler, UnicodeSetParser { ranges.push([start, end]); } this.wasmExports.free(buf); - return new UnicodeSet(pattern, ranges); + return new LdmlKeyboardTypes.UnicodeSet(pattern, ranges); } else { // rc is negative: it's an error code. this.wasmExports.free(buf); diff --git a/developer/src/kmc-kmn/src/compiler/kmn-compiler-messages.ts b/developer/src/kmc-kmn/src/compiler/kmn-compiler-messages.ts index f4b8693812a..2e9ec068f3e 100644 --- a/developer/src/kmc-kmn/src/compiler/kmn-compiler-messages.ts +++ b/developer/src/kmc-kmn/src/compiler/kmn-compiler-messages.ts @@ -274,11 +274,11 @@ export class KmnCompilerMessages { static ERROR_UnterminatedString = SevError | 0x019; static Error_UnterminatedString = () => m(this.ERROR_UnterminatedString, `Unterminated string in line`); - static ERROR_StringInVirtualKeySection = SevError | 0x01A; - static Error_StringInVirtualKeySection = () => m(this.ERROR_StringInVirtualKeySection, `extend string illegal in virtual key section`); + // static ERROR_StringInVirtualKeySection = SevError | 0x01A; // no longer used, see #12612 + // static Error_StringInVirtualKeySection = () => m(this.ERROR_StringInVirtualKeySection, `extend string illegal in virtual key section`); - static ERROR_AnyInVirtualKeySection = SevError | 0x01B; - static Error_AnyInVirtualKeySection = () => m(this.ERROR_AnyInVirtualKeySection, `'any' command is illegal in virtual key section`); + // static ERROR_AnyInVirtualKeySection = SevError | 0x01B; // no longer used, see #12612 + // static Error_AnyInVirtualKeySection = () => m(this.ERROR_AnyInVirtualKeySection, `'any' command is illegal in virtual key section`); static ERROR_InvalidAny = SevError | 0x01C; static Error_InvalidAny = () => m(this.ERROR_InvalidAny, `Invalid 'any' command`); @@ -286,23 +286,23 @@ export class KmnCompilerMessages { static ERROR_StoreDoesNotExist = SevError | 0x01D; static Error_StoreDoesNotExist = () => m(this.ERROR_StoreDoesNotExist, `Store referenced does not exist`); - static ERROR_BeepInVirtualKeySection = SevError | 0x01E; - static Error_BeepInVirtualKeySection = () => m(this.ERROR_BeepInVirtualKeySection, `'beep' command is illegal in virtual key section`); + // static ERROR_BeepInVirtualKeySection = SevError | 0x01E; // no longer used, see #12612 + // static Error_BeepInVirtualKeySection = () => m(this.ERROR_BeepInVirtualKeySection, `'beep' command is illegal in virtual key section`); - static ERROR_IndexInVirtualKeySection = SevError | 0x01F; - static Error_IndexInVirtualKeySection = () => m(this.ERROR_IndexInVirtualKeySection, `'index' command is illegal in virtual key section`); + // static ERROR_IndexInVirtualKeySection = SevError | 0x01F; // no longer used, see #12612 + // static Error_IndexInVirtualKeySection = () => m(this.ERROR_IndexInVirtualKeySection, `'index' command is illegal in virtual key section`); static ERROR_InvalidIndex = SevError | 0x020; static Error_InvalidIndex = () => m(this.ERROR_InvalidIndex, `Invalid 'index' command`); - static ERROR_OutsInVirtualKeySection = SevError | 0x021; - static Error_OutsInVirtualKeySection = () => m(this.ERROR_OutsInVirtualKeySection, `'outs' command is illegal in virtual key section`); + // static ERROR_OutsInVirtualKeySection = SevError | 0x021; // no longer used, see #12612 + // static Error_OutsInVirtualKeySection = () => m(this.ERROR_OutsInVirtualKeySection, `'outs' command is illegal in virtual key section`); static ERROR_InvalidOuts = SevError | 0x022; static Error_InvalidOuts = () => m(this.ERROR_InvalidOuts, `Invalid 'outs' command`); - static ERROR_ContextInVirtualKeySection = SevError | 0x024; - static Error_ContextInVirtualKeySection = () => m(this.ERROR_ContextInVirtualKeySection, `'context' command is illegal in virtual key section`); + // static ERROR_ContextInVirtualKeySection = SevError | 0x024; // no longer used, see #12612 + // static Error_ContextInVirtualKeySection = () => m(this.ERROR_ContextInVirtualKeySection, `'context' command is illegal in virtual key section`); static ERROR_InvalidUse = SevError | 0x025; static Error_InvalidUse = () => m(this.ERROR_InvalidUse, `Invalid 'use' command`); @@ -355,8 +355,8 @@ export class KmnCompilerMessages { static ERROR_InvalidCall = SevError | 0x035; static Error_InvalidCall = () => m(this.ERROR_InvalidCall, `The 'call' command is invalid`); - static ERROR_CallInVirtualKeySection = SevError | 0x036; - static Error_CallInVirtualKeySection = () => m(this.ERROR_CallInVirtualKeySection, `'call' command is illegal in virtual key section`); + // static ERROR_CallInVirtualKeySection = SevError | 0x036; // no longer used, see #12612 + // static Error_CallInVirtualKeySection = () => m(this.ERROR_CallInVirtualKeySection, `'call' command is illegal in virtual key section`); static ERROR_CodeInvalidInKeyStore = SevError | 0x037; static Error_CodeInvalidInKeyStore = () => m(this.ERROR_CodeInvalidInKeyStore, `The command is invalid inside a store that is used in a key part of the rule`); @@ -401,8 +401,8 @@ export class KmnCompilerMessages { static ERROR_80FeatureOnly = SevError | 0x047; static Error_80FeatureOnly = () => m(this.ERROR_80FeatureOnly, `This feature requires store(version) '8.0' or higher`); - static ERROR_InvalidInVirtualKeySection = SevError | 0x048; - static Error_InvalidInVirtualKeySection = () => m(this.ERROR_InvalidInVirtualKeySection, `This statement is not valid in a virtual key section`); + // static ERROR_InvalidInVirtualKeySection = SevError | 0x048; // no longer used, see #12612 + // static Error_InvalidInVirtualKeySection = () => m(this.ERROR_InvalidInVirtualKeySection, `This statement is not valid in a virtual key section`); static ERROR_InvalidIf = SevError | 0x049; static Error_InvalidIf = () => m(this.ERROR_InvalidIf, `The if() statement is not valid`); diff --git a/developer/src/kmc-kmn/test/test-compiler.ts b/developer/src/kmc-kmn/test/compiler.tests.ts similarity index 100% rename from developer/src/kmc-kmn/test/test-compiler.ts rename to developer/src/kmc-kmn/test/compiler.tests.ts diff --git a/developer/src/kmc-kmn/test/test-features.ts b/developer/src/kmc-kmn/test/features.tests.ts similarity index 100% rename from developer/src/kmc-kmn/test/test-features.ts rename to developer/src/kmc-kmn/test/features.tests.ts diff --git a/developer/src/kmc-kmn/test/kmw/test-kmw-compiler.ts b/developer/src/kmc-kmn/test/kmw/kmw-compiler.tests.ts similarity index 100% rename from developer/src/kmc-kmn/test/kmw/test-kmw-compiler.ts rename to developer/src/kmc-kmn/test/kmw/kmw-compiler.tests.ts diff --git a/developer/src/kmc-kmn/test/kmw/test-kmw-messages.ts b/developer/src/kmc-kmn/test/kmw/kmw-messages.tests.ts similarity index 100% rename from developer/src/kmc-kmn/test/kmw/test-kmw-messages.ts rename to developer/src/kmc-kmn/test/kmw/kmw-messages.tests.ts diff --git a/developer/src/kmc-kmn/test/test-messages.ts b/developer/src/kmc-kmn/test/messages.tests.ts similarity index 100% rename from developer/src/kmc-kmn/test/test-messages.ts rename to developer/src/kmc-kmn/test/messages.tests.ts diff --git a/developer/src/kmc-kmn/test/tsconfig.json b/developer/src/kmc-kmn/test/tsconfig.json index 3737f8d2ac6..dee653dfac4 100644 --- a/developer/src/kmc-kmn/test/tsconfig.json +++ b/developer/src/kmc-kmn/test/tsconfig.json @@ -9,7 +9,7 @@ "allowSyntheticDefaultImports": true, // for chai }, "include": [ - "**/test-*.ts", + "**/*.tests.ts", "./helpers/index.ts", "./kmw/util.ts" ], @@ -20,4 +20,4 @@ { "path": "../../common/web/test-helpers/" }, { "path": "../" } ] -} \ No newline at end of file +} diff --git a/developer/src/kmc-kmn/test/test-wasm-uset.ts b/developer/src/kmc-kmn/test/wasm-uset.tests.ts similarity index 100% rename from developer/src/kmc-kmn/test/test-wasm-uset.ts rename to developer/src/kmc-kmn/test/wasm-uset.tests.ts diff --git a/developer/src/kmc-ldml/build.sh b/developer/src/kmc-ldml/build.sh index 73a40c79d75..a961fea6fdc 100755 --- a/developer/src/kmc-ldml/build.sh +++ b/developer/src/kmc-ldml/build.sh @@ -33,30 +33,19 @@ builder_describe_outputs \ builder_parse "$@" -#------------------------------------------------------------------------------------------------------------------- - -if builder_start_action clean; then +function do_clean() { rm -rf ./build/ ./tsconfig.tsbuildinfo - builder_finish_action success clean -fi - -#------------------------------------------------------------------------------------------------------------------- +} -if builder_start_action configure; then +function do_configure() { verify_npm_setup - builder_finish_action success configure -fi +} -#------------------------------------------------------------------------------------------------------------------- - -if builder_start_action build; then +function do_build() { npm run build - builder_finish_action success build -fi +} -#------------------------------------------------------------------------------------------------------------------- - -if builder_start_action build-fixtures; then +function do_build_fixtures() { # Build basic.kmx and emit its checksum mkdir -p ./build/test/fixtures node ../kmc build ./test/fixtures/basic.xml --no-compiler-version --debug --out-file ./build/test/fixtures/basic-xml.kmx @@ -65,22 +54,14 @@ if builder_start_action build-fixtures; then # Generate a binary file from basic.txt for comparison purposes node ../../../common/tools/hextobin/build/hextobin.js ./test/fixtures/basic.txt ./build/test/fixtures/basic-txt.kmx - - builder_finish_action success build-fixtures -fi - -builder_run_action api api-extractor run --local --verbose - -#------------------------------------------------------------------------------------------------------------------- - -if builder_start_action test; then - eslint . - cd test - tsc -b - cd .. - c8 --reporter=lcov --reporter=text mocha "${builder_extra_params[@]}" - builder_finish_action success test -fi +} + +builder_run_action clean do_clean +builder_run_action configure do_configure +builder_run_action build do_build +builder_run_action build-fixtures do_build_fixtures +builder_run_action api api-extractor run --local --verbose +builder_run_action test builder_do_typescript_tests #------------------------------------------------------------------------------------------------------------------- diff --git a/developer/src/kmc-ldml/package.json b/developer/src/kmc-ldml/package.json index 11d7c07b880..cecbc8e15b8 100644 --- a/developer/src/kmc-ldml/package.json +++ b/developer/src/kmc-ldml/package.json @@ -45,7 +45,7 @@ "typescript": "^5.4.5" }, "mocha": { - "spec": "build/test/**/test-*.js", + "spec": "build/test/**/*.tests.js", "require": [ "source-map-support/register" ] diff --git a/developer/src/kmc-ldml/src/compiler/compiler.ts b/developer/src/kmc-ldml/src/compiler/compiler.ts index 388a64de69b..e8b38184e9f 100644 --- a/developer/src/kmc-ldml/src/compiler/compiler.ts +++ b/developer/src/kmc-ldml/src/compiler/compiler.ts @@ -3,7 +3,7 @@ * * Compiles a LDML XML keyboard file into a Keyman KMXPlus file */ -import { KMXPlus, UnicodeSetParser, KvkFileWriter, KMX } from '@keymanapp/common-types'; +import { KMXPlus, LdmlKeyboardTypes, KvkFileWriter, KMX } from '@keymanapp/common-types'; import { CompilerCallbacks, KeymanCompiler, KeymanCompilerResult, KeymanCompilerArtifacts, defaultCompilerOptions, LDMLKeyboardXMLSourceFileReader, LDMLKeyboard, @@ -93,7 +93,7 @@ export class LdmlKeyboardCompiler implements KeymanCompiler { private options: LdmlCompilerOptions; // uset parser - private usetparser?: UnicodeSetParser = undefined; + private usetparser?: LdmlKeyboardTypes.UnicodeSetParser = undefined; /** * Initialize the compiler, including loading the WASM host for uset parsing. @@ -211,7 +211,7 @@ export class LdmlKeyboardCompiler implements KeymanCompiler { * Construct or return a UnicodeSetParser, aka KmnCompiler * @returns the held UnicodeSetParser */ - async getUsetParser(): Promise { + async getUsetParser(): Promise { if (this.usetparser === undefined) { // initialize const compiler = new KmnCompiler(); diff --git a/developer/src/kmc-ldml/src/compiler/empty-compiler.ts b/developer/src/kmc-ldml/src/compiler/empty-compiler.ts index 44b04182a3f..4b9aec76133 100644 --- a/developer/src/kmc-ldml/src/compiler/empty-compiler.ts +++ b/developer/src/kmc-ldml/src/compiler/empty-compiler.ts @@ -1,6 +1,6 @@ import { SectionIdent, constants } from '@keymanapp/ldml-keyboard-constants'; import { SectionCompiler } from "./section-compiler.js"; -import { util, KMXPlus, MarkerParser } from "@keymanapp/common-types"; +import { util, KMXPlus, LdmlKeyboardTypes } from "@keymanapp/common-types"; import { CompilerCallbacks, LDMLKeyboard } from "@keymanapp/developer-utils"; import { VarsCompiler } from './vars.js'; import { LdmlCompilerMessages } from './ldml-compiler-messages.js'; @@ -35,8 +35,12 @@ export class StrsCompiler extends EmptyCompiler { if (strs) { const badStringAnalyzer = new util.BadStringAnalyzer(); - const CONTAINS_MARKER_REGEX = new RegExp(MarkerParser.ANY_MARKER_MATCH); + const CONTAINS_MARKER_REGEX = new RegExp(LdmlKeyboardTypes.MarkerParser.ANY_MARKER_MATCH); for (let s of strs.allProcessedStrings.values()) { + // stop at the first denormalized string + if (!util.isNormalized(s)) { + this.callbacks.reportMessage(LdmlCompilerMessages.Warn_StringDenorm({s})); + } // replace all \\uXXXX with the actual code point. // this lets us analyze whether there are PUA, unassigned, etc. // the results might not be valid regex of course. @@ -47,7 +51,7 @@ export class StrsCompiler extends EmptyCompiler { if (CONTAINS_MARKER_REGEX.test(s)) { // it had a marker, take out all marker strings, as the sentinel is illegal // need a new regex to match - const REPLACE_MARKER_REGEX = new RegExp(MarkerParser.ANY_MARKER_MATCH, 'g'); + const REPLACE_MARKER_REGEX = new RegExp(LdmlKeyboardTypes.MarkerParser.ANY_MARKER_MATCH, 'g'); s = s.replaceAll(REPLACE_MARKER_REGEX, ''); // remove markers. } badStringAnalyzer.add(s); diff --git a/developer/src/kmc-ldml/src/compiler/ldml-compiler-messages.ts b/developer/src/kmc-ldml/src/compiler/ldml-compiler-messages.ts index 1445b40036a..5df0da4b73a 100644 --- a/developer/src/kmc-ldml/src/compiler/ldml-compiler-messages.ts +++ b/developer/src/kmc-ldml/src/compiler/ldml-compiler-messages.ts @@ -199,7 +199,11 @@ export class LdmlCompilerMessages { `Invalid marker identifier "\m{${def(o.id)}}". Identifiers must be between 1 and 32 characters, and can use A-Z, a-z, 0-9, and _.`, ); - // Available: 0x02B-0x2F + static WARN_StringDenorm = SevWarn | 0x002B; + static Warn_StringDenorm = (o: { s: string }) => + m(this.WARN_StringDenorm, `File contains string "${def(o.s)}" that is neither NFC nor NFD.`); + + // Available: 0x02C-0x2F static ERROR_InvalidQuadEscape = SevError | 0x0030; static Error_InvalidQuadEscape = (o: { cp: number }) => diff --git a/developer/src/kmc-ldml/src/compiler/linter-keycaps.ts b/developer/src/kmc-ldml/src/compiler/linter-keycaps.ts index eb6710952f6..8f1006c54ac 100644 --- a/developer/src/kmc-ldml/src/compiler/linter-keycaps.ts +++ b/developer/src/kmc-ldml/src/compiler/linter-keycaps.ts @@ -1,4 +1,4 @@ -import { MarkerParser } from "@keymanapp/common-types"; +import { LdmlKeyboardTypes } from "@keymanapp/common-types"; import { Linter } from "./linter.js"; import { LdmlCompilerMessages } from "./ldml-compiler-messages.js"; @@ -20,7 +20,7 @@ export class LinterKeycaps extends Linter { } public async lint(): Promise { - const ANY_MARKER_REGEX = new RegExp(MarkerParser.ANY_MARKER_MATCH,'g'); + const ANY_MARKER_REGEX = new RegExp(LdmlKeyboardTypes.MarkerParser.ANY_MARKER_MATCH,'g'); // Are there any keys which: // 0. Are present in the layout, flicks or gestures, AND // 1. Consist entirely of marker output, AND diff --git a/developer/src/kmc-ldml/src/compiler/substitution-tracker.ts b/developer/src/kmc-ldml/src/compiler/substitution-tracker.ts index a03918da979..6f07475490f 100644 --- a/developer/src/kmc-ldml/src/compiler/substitution-tracker.ts +++ b/developer/src/kmc-ldml/src/compiler/substitution-tracker.ts @@ -1,4 +1,4 @@ -import { MarkerParser, VariableParser } from "@keymanapp/common-types"; +import { LdmlKeyboardTypes } from "@keymanapp/common-types"; /** * Verb for SubstitutionTracker.add() @@ -76,7 +76,7 @@ export class SubstitutionTracker { /** rollup of several substitution types */ export class Substitutions { addSetAndStringSubtitution(verb: SubstitutionUse, str?: string) { - this.set.add(verb, VariableParser.allSetReferences(str)); + this.set.add(verb, LdmlKeyboardTypes.VariableParser.allSetReferences(str)); this.addStringAndMarkerSubstitution(verb, str); } /** add a string that can have string var substitutions or markers */ @@ -85,12 +85,12 @@ export class Substitutions { this.addStringSubstitution(verb, str); } addStringSubstitution(verb: SubstitutionUse, str?: string) { - this.string.add(verb, VariableParser.allStringReferences(str)); + this.string.add(verb, LdmlKeyboardTypes.VariableParser.allStringReferences(str)); } /** add a string that's just markers */ addMarkers(verb: SubstitutionUse, str?: string) { - this.markers.add(verb, MarkerParser.allReferences(str)); - MarkerParser.allBrokenReferences(str).forEach(m => this.badMarkers.add(m)); + this.markers.add(verb, LdmlKeyboardTypes.MarkerParser.allReferences(str)); + LdmlKeyboardTypes.MarkerParser.allBrokenReferences(str).forEach(m => this.badMarkers.add(m)); } // all valid markers markers: SubstitutionTracker; diff --git a/developer/src/kmc-ldml/src/compiler/tran.ts b/developer/src/kmc-ldml/src/compiler/tran.ts index cf99159aaf1..e8d7b9eb370 100644 --- a/developer/src/kmc-ldml/src/compiler/tran.ts +++ b/developer/src/kmc-ldml/src/compiler/tran.ts @@ -1,5 +1,5 @@ import { constants, SectionIdent } from "@keymanapp/ldml-keyboard-constants"; -import { KMXPlus, VariableParser, MarkerParser, util } from '@keymanapp/common-types'; +import { KMXPlus, LdmlKeyboardTypes, util } from '@keymanapp/common-types'; import { CompilerCallbacks, LDMLKeyboard } from "@keymanapp/developer-utils"; import { SectionCompiler } from "./section-compiler.js"; @@ -28,8 +28,8 @@ export abstract class TransformCompiler { st.addSetAndStringSubtitution(SubstitutionUse.consume, from); st.addSetAndStringSubtitution(SubstitutionUse.emit, to); - const mapFrom = VariableParser.CAPTURE_SET_REFERENCE.exec(from); - const mapTo = VariableParser.MAPPED_SET_REFERENCE.exec(to || ''); + const mapFrom = LdmlKeyboardTypes.VariableParser.CAPTURE_SET_REFERENCE.exec(from); + const mapTo = LdmlKeyboardTypes.VariableParser.MAPPED_SET_REFERENCE.exec(to || ''); if (mapFrom) { // add the 'from' as a match st.set.add(SubstitutionUse.consume, [mapFrom[1]]); @@ -144,8 +144,8 @@ export abstract class TransformCompiler DTD + if(!id.match(LdmlKeyboardTypes.VariableParser.ID)) { // From DTD this.callbacks.reportMessage(LdmlCompilerMessages.Error_InvalidVariableIdentifier({id})); return false; } @@ -80,7 +80,7 @@ export class VarsCompiler extends SectionCompiler { continue; } addId(id); - const stringrefs = VariableParser.allStringReferences(value); + const stringrefs = LdmlKeyboardTypes.VariableParser.allStringReferences(value); for(const ref of stringrefs) { if(!allStrings.has(ref)) { valid = false; @@ -101,13 +101,13 @@ export class VarsCompiler extends SectionCompiler { addId(id); allSets.add(id); // check for illegal references, here. - const stringrefs = VariableParser.allStringReferences(value); + const stringrefs = LdmlKeyboardTypes.VariableParser.allStringReferences(value); st.string.add(SubstitutionUse.variable, stringrefs); // Now split into spaces. - const items: string[] = VariableParser.setSplitter(value); + const items: string[] = LdmlKeyboardTypes.VariableParser.setSplitter(value); for (const item of items) { - const setrefs = VariableParser.allSetReferences(item); + const setrefs = LdmlKeyboardTypes.VariableParser.allSetReferences(item); if (setrefs.length > 1) { // this is the form $[seta]$[setb] valid = false; @@ -126,9 +126,9 @@ export class VarsCompiler extends SectionCompiler { } addId(id); allUnicodeSets.add(id); - const stringrefs = VariableParser.allStringReferences(value); + const stringrefs = LdmlKeyboardTypes.VariableParser.allStringReferences(value); st.string.add(SubstitutionUse.variable, stringrefs); - const setrefs = VariableParser.allSetReferences(value); + const setrefs = LdmlKeyboardTypes.VariableParser.allSetReferences(value); for (const id2 of setrefs) { if (!allUnicodeSets.has(id2)) { valid = false; @@ -193,13 +193,13 @@ export class VarsCompiler extends SectionCompiler { const matchedNotEmitted : Set = new Set(); const mt = st.markers; for (const m of mt.matched.values()) { - if (m === MarkerParser.ANY_MARKER_ID) continue; // match-all marker + if (m === LdmlKeyboardTypes.MarkerParser.ANY_MARKER_ID) continue; // match-all marker if (!mt.emitted.has(m)) { matchedNotEmitted.add(m); } } for (const m of mt.consumed.values()) { - if (m === MarkerParser.ANY_MARKER_ID) continue; // match-all marker + if (m === LdmlKeyboardTypes.MarkerParser.ANY_MARKER_ID) continue; // match-all marker if (!mt.emitted.has(m)) { matchedNotEmitted.add(m); } @@ -225,10 +225,10 @@ export class VarsCompiler extends SectionCompiler { validateSubstitutions(keyboard: LDMLKeyboard.LKKeyboard, st : Substitutions) : boolean { keyboard?.variables?.string?.forEach(({value}) => - st.markers.add(SubstitutionUse.variable, MarkerParser.allReferences(value))); + st.markers.add(SubstitutionUse.variable, LdmlKeyboardTypes.MarkerParser.allReferences(value))); // get markers mentioned in a set keyboard?.variables?.set?.forEach(({ value }) => - VariableParser.setSplitter(value).forEach(v => st.markers.add(SubstitutionUse.match, MarkerParser.allReferences(v)))); + LdmlKeyboardTypes.VariableParser.setSplitter(value).forEach(v => st.markers.add(SubstitutionUse.match, LdmlKeyboardTypes.MarkerParser.allReferences(v)))); return true; } @@ -254,7 +254,7 @@ export class VarsCompiler extends SectionCompiler { const mt = st.markers; // collect all markers, excluding the match-all - const allMarkers : string[] = Array.from(mt.all).filter(m => m !== MarkerParser.ANY_MARKER_ID).sort(); + const allMarkers : string[] = Array.from(mt.all).filter(m => m !== LdmlKeyboardTypes.MarkerParser.ANY_MARKER_ID).sort(); result.markers = sections.list.allocList(allMarkers, {}, sections); // sets need to be added late, because they can refer to markers @@ -280,7 +280,7 @@ export class VarsCompiler extends SectionCompiler { // OK to do this as a substitute, because we've already validated the set above. value = result.substituteSets(value, sections); // raw items - without marker substitution - const rawItems: string[] = VariableParser.setSplitter(value); + const rawItems: string[] = LdmlKeyboardTypes.VariableParser.setSplitter(value); // cooked items - has substutition of markers // this is not 'forMatch', all variables are to be assumed as string literals, not regex // content. diff --git a/developer/src/kmc-ldml/test/test-compiler-e2e.ts b/developer/src/kmc-ldml/test/compiler-e2e.tests.ts similarity index 100% rename from developer/src/kmc-ldml/test/test-compiler-e2e.ts rename to developer/src/kmc-ldml/test/compiler-e2e.tests.ts diff --git a/developer/src/kmc-ldml/test/test-dependencies.ts b/developer/src/kmc-ldml/test/dependencies.tests.ts similarity index 100% rename from developer/src/kmc-ldml/test/test-dependencies.ts rename to developer/src/kmc-ldml/test/dependencies.tests.ts diff --git a/developer/src/kmc-ldml/test/test-disp.ts b/developer/src/kmc-ldml/test/disp.tests.ts similarity index 100% rename from developer/src/kmc-ldml/test/test-disp.ts rename to developer/src/kmc-ldml/test/disp.tests.ts diff --git a/developer/src/kmc-ldml/test/fixtures/sections/strs/warn-denorm-1.xml b/developer/src/kmc-ldml/test/fixtures/sections/strs/warn-denorm-1.xml new file mode 100644 index 00000000000..49cd61d358a --- /dev/null +++ b/developer/src/kmc-ldml/test/fixtures/sections/strs/warn-denorm-1.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/developer/src/kmc-ldml/test/fixtures/sections/strs/warn-denorm-2.xml b/developer/src/kmc-ldml/test/fixtures/sections/strs/warn-denorm-2.xml new file mode 100644 index 00000000000..ec001db7684 --- /dev/null +++ b/developer/src/kmc-ldml/test/fixtures/sections/strs/warn-denorm-2.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/developer/src/kmc-ldml/test/fixtures/sections/strs/warn-denorm-3.xml b/developer/src/kmc-ldml/test/fixtures/sections/strs/warn-denorm-3.xml new file mode 100644 index 00000000000..a40c119099c --- /dev/null +++ b/developer/src/kmc-ldml/test/fixtures/sections/strs/warn-denorm-3.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/developer/src/kmc-ldml/test/fixtures/sections/strs/warn-denorm-4.xml b/developer/src/kmc-ldml/test/fixtures/sections/strs/warn-denorm-4.xml new file mode 100644 index 00000000000..cf443c61fe5 --- /dev/null +++ b/developer/src/kmc-ldml/test/fixtures/sections/strs/warn-denorm-4.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/developer/src/kmc-ldml/test/test-helpers.ts b/developer/src/kmc-ldml/test/helpers.tests.ts similarity index 100% rename from developer/src/kmc-ldml/test/test-helpers.ts rename to developer/src/kmc-ldml/test/helpers.tests.ts diff --git a/developer/src/kmc-ldml/test/helpers/index.ts b/developer/src/kmc-ldml/test/helpers/index.ts index e1463e81169..3bb67278fbe 100644 --- a/developer/src/kmc-ldml/test/helpers/index.ts +++ b/developer/src/kmc-ldml/test/helpers/index.ts @@ -7,7 +7,7 @@ import 'mocha'; import * as path from 'path'; import { fileURLToPath } from 'url'; import { SectionCompiler, SectionCompilerNew } from '../../src/compiler/section-compiler.js'; -import { util, KMXPlus, UnicodeSetParser } from '@keymanapp/common-types'; +import { util, KMXPlus, LdmlKeyboardTypes } from '@keymanapp/common-types'; import { CompilerEvent, compilerEventFormat, CompilerCallbacks, LDMLKeyboardXMLSourceFileReader, LDMLKeyboardTestDataXMLSourceFile, LDMLKeyboard, } from "@keymanapp/developer-utils"; import { LdmlKeyboardCompiler } from '../../src/main.js'; // make sure main.js compiles import { assert } from 'chai'; @@ -297,7 +297,7 @@ export function testCompilationCases(compiler: SectionCompilerNew, cases : Compi }); } } -async function getTestUnicodeSetParser(callbacks: CompilerCallbacks): Promise { +async function getTestUnicodeSetParser(callbacks: CompilerCallbacks): Promise { // for tests, just create a new one // see LdmlKeyboardCompiler.getUsetParser() const compiler = new KmnCompiler(); diff --git a/developer/src/kmc-ldml/test/test-keys.ts b/developer/src/kmc-ldml/test/keys.tests.ts similarity index 97% rename from developer/src/kmc-ldml/test/test-keys.ts rename to developer/src/kmc-ldml/test/keys.tests.ts index 8c0a47bebb3..b639c194cc3 100644 --- a/developer/src/kmc-ldml/test/test-keys.ts +++ b/developer/src/kmc-ldml/test/keys.tests.ts @@ -2,7 +2,7 @@ import 'mocha'; import { assert } from 'chai'; import { KeysCompiler } from '../src/compiler/keys.js'; import { assertCodePoints, compilerTestCallbacks, loadSectionFixture, testCompilationCases } from './helpers/index.js'; -import { KMXPlus, Constants, MarkerParser } from '@keymanapp/common-types'; +import { KMXPlus, Constants, LdmlKeyboardTypes } from '@keymanapp/common-types'; import { LdmlCompilerMessages } from '../src/compiler/ldml-compiler-messages.js'; import { constants } from '@keymanapp/ldml-keyboard-constants'; import { MetaCompiler } from '../src/compiler/meta.js'; @@ -69,7 +69,7 @@ describe('keys', function () { // normalization w markers const [amarker] = keys.keys.filter(({ id }) => id.value === 'amarker'); - assertCodePoints(amarker.to.value, `a${MarkerParser.markerOutput(1, false)}\u{0320}\u{0301}`); + assertCodePoints(amarker.to.value, `a${LdmlKeyboardTypes.MarkerParser.markerOutput(1, false)}\u{0320}\u{0301}`); // normalization const [aacute] = keys.keys.filter(({ id }) => id.value === 'a-acute'); @@ -112,7 +112,7 @@ describe('keys', function () { // normalization w markers const [amarker] = keys.keys.filter(({ id }) => id.value === 'amarker'); - assertCodePoints(amarker.to.value, `á${MarkerParser.markerOutput(1, false)}\u{0320}`); + assertCodePoints(amarker.to.value, `á${LdmlKeyboardTypes.MarkerParser.markerOutput(1, false)}\u{0320}`); // normalization const [aacute] = keys.keys.filter(({ id }) => id.value === 'a-acute'); @@ -189,7 +189,7 @@ describe('keys', function () { const ww = keys.keys.find(({ id }) => id.value === 'ww'); assert.ok(ww); - const MARKER_5 = MarkerParser.markerOutput(5); + const MARKER_5 = LdmlKeyboardTypes.MarkerParser.markerOutput(5); assert.equal(ww.to.value, MARKER_5); assert.equal(ww.longPressDefault.value, 'bb'); assert.equal(ww.longPress[0].value.value, 'aa'); diff --git a/developer/src/kmc-ldml/test/test-layr.ts b/developer/src/kmc-ldml/test/layr.tests.ts similarity index 100% rename from developer/src/kmc-ldml/test/test-layr.ts rename to developer/src/kmc-ldml/test/layr.tests.ts diff --git a/developer/src/kmc-ldml/test/test-linter.ts b/developer/src/kmc-ldml/test/linter.tests.ts similarity index 100% rename from developer/src/kmc-ldml/test/test-linter.ts rename to developer/src/kmc-ldml/test/linter.tests.ts diff --git a/developer/src/kmc-ldml/test/test-loca.ts b/developer/src/kmc-ldml/test/loca.tests.ts similarity index 100% rename from developer/src/kmc-ldml/test/test-loca.ts rename to developer/src/kmc-ldml/test/loca.tests.ts diff --git a/developer/src/kmc-ldml/test/test-messages.ts b/developer/src/kmc-ldml/test/messages.tests.ts similarity index 100% rename from developer/src/kmc-ldml/test/test-messages.ts rename to developer/src/kmc-ldml/test/messages.tests.ts diff --git a/developer/src/kmc-ldml/test/test-meta.ts b/developer/src/kmc-ldml/test/meta.tests.ts similarity index 100% rename from developer/src/kmc-ldml/test/test-meta.ts rename to developer/src/kmc-ldml/test/meta.tests.ts diff --git a/developer/src/kmc-ldml/test/test-metadata-compiler.ts b/developer/src/kmc-ldml/test/metadata-compiler.tests.ts similarity index 100% rename from developer/src/kmc-ldml/test/test-metadata-compiler.ts rename to developer/src/kmc-ldml/test/metadata-compiler.tests.ts diff --git a/developer/src/kmc-ldml/test/test-strs.ts b/developer/src/kmc-ldml/test/strs.tests.ts similarity index 80% rename from developer/src/kmc-ldml/test/test-strs.ts rename to developer/src/kmc-ldml/test/strs.tests.ts index a5f7e89e35c..24e8ff4c1ed 100644 --- a/developer/src/kmc-ldml/test/test-strs.ts +++ b/developer/src/kmc-ldml/test/strs.tests.ts @@ -71,4 +71,25 @@ describe('strs', function () { ]); assert.isNull(kmx); // should fail post-validate }); + describe('should warn on denorm strings', async function () { + for (const num of [1, 2, 3, 4]) { + const path = `sections/strs/warn-denorm-${num}.xml`; + it(path, async function () { + const inputFilename = makePathToFixture(path); + const s = 's\u0307\u0323'; // ṩ + // Compile the keyboard + const kmx = await compileKeyboard(inputFilename, { ...compilerTestOptions, saveDebug: true, shouldAddCompilerVersion: false }, + [ + // validation messages + LdmlCompilerMessages.Warn_StringDenorm({s}), + ], + false, // validation should pass + [ + // same messages + LdmlCompilerMessages.Warn_StringDenorm({s}), + ]); + assert.isNotNull(kmx); // not failing + }); + } + }); }); diff --git a/developer/src/kmc-ldml/test/test-testdata-e2e.ts b/developer/src/kmc-ldml/test/testdata-e2e.tests.ts similarity index 100% rename from developer/src/kmc-ldml/test/test-testdata-e2e.ts rename to developer/src/kmc-ldml/test/testdata-e2e.tests.ts diff --git a/developer/src/kmc-ldml/test/test-tran.ts b/developer/src/kmc-ldml/test/tran.tests.ts similarity index 97% rename from developer/src/kmc-ldml/test/test-tran.ts rename to developer/src/kmc-ldml/test/tran.tests.ts index 0099c1f1029..2fc401e66b6 100644 --- a/developer/src/kmc-ldml/test/test-tran.ts +++ b/developer/src/kmc-ldml/test/tran.tests.ts @@ -5,7 +5,7 @@ import { BASIC_DEPENDENCIES, UsetCompiler } from '../src/compiler/empty-compiler import { LdmlCompilerMessages } from '../src/compiler/ldml-compiler-messages.js'; import { KmnCompilerMessages } from '@keymanapp/kmc-kmn'; import { assertCodePoints, compilerTestCallbacks, testCompilationCases } from './helpers/index.js'; -import { KMXPlus, MarkerParser } from '@keymanapp/common-types'; +import { KMXPlus, LdmlKeyboardTypes } from '@keymanapp/common-types'; import Tran = KMXPlus.Tran;// for tests… import Bksp = KMXPlus.Bksp;// for tests… @@ -43,7 +43,7 @@ describe('tran', function () { { subpath: 'sections/tran/tran-vars.xml', callback(sect) { - const m = MarkerParser.markerOutput; + const m = LdmlKeyboardTypes.MarkerParser.markerOutput; const tran = sect; assert.ok(tran); assert.lengthOf(compilerTestCallbacks.messages, 0); @@ -75,7 +75,7 @@ describe('tran', function () { `\u{03b9}\u{0313}\u{301}`); assertCodePoints(g0t5.from.value, - `\u{03b9}${MarkerParser.ANY_MARKER_MATCH}\u{033c}\u{0301}`); + `\u{03b9}${LdmlKeyboardTypes.MarkerParser.ANY_MARKER_MATCH}\u{033c}\u{0301}`); assertCodePoints(g0t5.to.value, `\u{03b9}${m(1,false)}\u{033c}\u{0300}`); } @@ -83,7 +83,7 @@ describe('tran', function () { { subpath: 'sections/tran/tran-vars-nfc.xml', callback(sect) { - const m = MarkerParser.markerOutput; + const m = LdmlKeyboardTypes.MarkerParser.markerOutput; const tran = sect; assert.ok(tran); assert.lengthOf(compilerTestCallbacks.messages, 0); @@ -115,7 +115,7 @@ describe('tran', function () { `\u{1f34}`); assertCodePoints(g0t5.from.value, - `\u{03af}${MarkerParser.ANY_MARKER_MATCH}\u{033c}`); + `\u{03af}${LdmlKeyboardTypes.MarkerParser.ANY_MARKER_MATCH}\u{033c}`); assertCodePoints(g0t5.to.value, `\u{1f76}${m(1,false)}\u{033c}`); }, diff --git a/developer/src/kmc-ldml/test/tsconfig.json b/developer/src/kmc-ldml/test/tsconfig.json index cda71853604..354f5235f1b 100644 --- a/developer/src/kmc-ldml/test/tsconfig.json +++ b/developer/src/kmc-ldml/test/tsconfig.json @@ -9,7 +9,7 @@ "strictNullChecks": false, // TODO: get rid of this as some point }, "include": [ - "**/test-*.ts", + "**/*.tests.ts", "./helpers/index.ts" ], "references": [ @@ -19,4 +19,4 @@ { "path": "../../common/web/test-helpers/" }, { "path": "../" } ] -} \ No newline at end of file +} diff --git a/developer/src/kmc-ldml/test/test-utils.ts b/developer/src/kmc-ldml/test/utils.tests.ts similarity index 100% rename from developer/src/kmc-ldml/test/test-utils.ts rename to developer/src/kmc-ldml/test/utils.tests.ts diff --git a/developer/src/kmc-ldml/test/test-vars.ts b/developer/src/kmc-ldml/test/vars.tests.ts similarity index 100% rename from developer/src/kmc-ldml/test/test-vars.ts rename to developer/src/kmc-ldml/test/vars.tests.ts diff --git a/developer/src/kmc-ldml/test/test-visual-keyboard-compiler.ts b/developer/src/kmc-ldml/test/visual-keyboard-compiler.tests.ts similarity index 100% rename from developer/src/kmc-ldml/test/test-visual-keyboard-compiler.ts rename to developer/src/kmc-ldml/test/visual-keyboard-compiler.tests.ts diff --git a/developer/src/kmc-model-info/build.sh b/developer/src/kmc-model-info/build.sh index b1ba95c34b8..153c3567369 100755 --- a/developer/src/kmc-model-info/build.sh +++ b/developer/src/kmc-model-info/build.sh @@ -27,36 +27,11 @@ builder_parse "$@" #------------------------------------------------------------------------------------------------------------------- -if builder_start_action clean; then - rm -rf ./build/ ./tsconfig.tsbuildinfo - builder_finish_action success clean -fi - -#------------------------------------------------------------------------------------------------------------------- - -if builder_start_action configure; then - verify_npm_setup - builder_finish_action success configure -fi - -#------------------------------------------------------------------------------------------------------------------- - -if builder_start_action build; then - npm run build - builder_finish_action success build -fi - -builder_run_action api api-extractor run --local --verbose - -#------------------------------------------------------------------------------------------------------------------- - -if builder_start_action test; then - eslint . - tsc --build test - c8 --reporter=lcov --reporter=text --exclude-after-remap --lines 80 mocha - # TODO: remove --lines 80 and improve coverage - builder_finish_action success test -fi +builder_run_action clean rm -rf ./build/ ./tsconfig.tsbuildinfo +builder_run_action configure verify_npm_setup +builder_run_action build tsc --build +builder_run_action api api-extractor run --local --verbose +builder_run_action test builder_do_typescript_tests 80 #------------------------------------------------------------------------------------------------------------------- diff --git a/developer/src/kmc-model-info/package.json b/developer/src/kmc-model-info/package.json index 20be72d1899..3a07f49ba14 100644 --- a/developer/src/kmc-model-info/package.json +++ b/developer/src/kmc-model-info/package.json @@ -30,7 +30,6 @@ "url": "https://github.com/keymanapp/keyman/issues" }, "dependencies": { - "@keymanapp/common-types": "*", "@keymanapp/common-types": "*", "@keymanapp/developer-utils": "*" }, @@ -43,7 +42,7 @@ "typescript": "^5.4.5" }, "mocha": { - "spec": "build/test/**/test-*.js", + "spec": "build/test/**/*.tests.js", "require": [ "source-map-support/register" ] diff --git a/developer/src/kmc-model-info/test/test-model-info-compiler-messages.ts b/developer/src/kmc-model-info/test/model-info-compiler-messages.tests.ts similarity index 100% rename from developer/src/kmc-model-info/test/test-model-info-compiler-messages.ts rename to developer/src/kmc-model-info/test/model-info-compiler-messages.tests.ts diff --git a/developer/src/kmc-model-info/test/test-model-info-compiler.ts b/developer/src/kmc-model-info/test/model-info-compiler.tests.ts similarity index 100% rename from developer/src/kmc-model-info/test/test-model-info-compiler.ts rename to developer/src/kmc-model-info/test/model-info-compiler.tests.ts diff --git a/developer/src/kmc-model-info/test/tsconfig.json b/developer/src/kmc-model-info/test/tsconfig.json index e16b935aa47..2d85e0fcbdb 100644 --- a/developer/src/kmc-model-info/test/tsconfig.json +++ b/developer/src/kmc-model-info/test/tsconfig.json @@ -10,7 +10,7 @@ "baseUrl": ".", }, "include": [ - "**/test-*.ts", + "**/*.tests.ts", "helpers/*.ts", ], "references": [ @@ -18,4 +18,4 @@ { "path": "../../common/web/test-helpers/" }, { "path": "../../kmc-package/" }, ] -} \ No newline at end of file +} diff --git a/developer/src/kmc-model/build.sh b/developer/src/kmc-model/build.sh index 372a145312a..9e7166f8b74 100755 --- a/developer/src/kmc-model/build.sh +++ b/developer/src/kmc-model/build.sh @@ -32,13 +32,13 @@ builder_parse "$@" function do_build() { tsc -b ./tools/tsconfig.json - npm run build + tsc -b } builder_run_action clean rm -rf ./build/ ./tsconfig.tsbuildinfo builder_run_action configure verify_npm_setup builder_run_action build do_build builder_run_action api api-extractor run --local --verbose -builder_run_action test npm test +builder_run_action test builder_do_typescript_tests builder_run_action publish builder_publish_npm diff --git a/developer/src/kmc-model/package.json b/developer/src/kmc-model/package.json index 9f95de51f8d..f17e7cec0e4 100644 --- a/developer/src/kmc-model/package.json +++ b/developer/src/kmc-model/package.json @@ -18,7 +18,7 @@ "scripts": { "build": "tsc -b", "lint": "eslint .", - "test": "npm run lint && cd test && tsc -b && cd .. && c8 --reporter=lcov --reporter=text mocha" + "test": "./build.sh test" }, "author": "Marc Durdin (https://github.com/mcdurdin)", "contributors": [ @@ -32,7 +32,6 @@ "dependencies": { "@keymanapp/common-types": "*", "@keymanapp/keyman-version": "*", - "@keymanapp/common-types": "*", "typescript": "^5.4.5" }, "devDependencies": { @@ -46,7 +45,7 @@ "mocha": "^10.0.0" }, "mocha": { - "spec": "build/test/**/test-*.js", + "spec": "build/test/**/*.tests.js", "require": [ "source-map-support/register" ] diff --git a/developer/src/kmc-model/src/join-word-breaker-decorator.ts b/developer/src/kmc-model/src/join-word-breaker-decorator.ts index dec58d583ab..add997d9c74 100644 --- a/developer/src/kmc-model/src/join-word-breaker-decorator.ts +++ b/developer/src/kmc-model/src/join-word-breaker-decorator.ts @@ -1,4 +1,6 @@ -import { Span, WordBreakingFunction } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; +import Span = LexicalModelTypes.Span; +import WordBreakingFunction = LexicalModelTypes.WordBreakingFunction; /** * Returns a word breaker that joins spans of an existing word breaker. diff --git a/developer/src/kmc-model/src/lexical-model.ts b/developer/src/kmc-model/src/lexical-model.ts index f0fd95c19e6..e174309e0d7 100644 --- a/developer/src/kmc-model/src/lexical-model.ts +++ b/developer/src/kmc-model/src/lexical-model.ts @@ -3,7 +3,10 @@ * the LMLayer's internal worker code, so we provide those definitions too. */ -import { CasingFunction, LexicalModelPunctuation, WordBreakingFunction } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; +import CasingFunction = LexicalModelTypes.CasingFunction; +import LexicalModelPunctuation = LexicalModelTypes.LexicalModelPunctuation; +import WordBreakingFunction = LexicalModelTypes.WordBreakingFunction; export interface LexicalModelDeclaration { readonly format: 'trie-1.0'|'fst-foma-1.0'|'custom-1.0', diff --git a/developer/src/kmc-model/src/model-defaults.ts b/developer/src/kmc-model/src/model-defaults.ts index 4d6c40d3a11..374d7688d75 100644 --- a/developer/src/kmc-model/src/model-defaults.ts +++ b/developer/src/kmc-model/src/model-defaults.ts @@ -1,4 +1,6 @@ -import { CasingForm, CasingFunction } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; +import CasingForm = LexicalModelTypes.CasingForm; +import CasingFunction = LexicalModelTypes.CasingFunction; /** * Converts wordforms into an indexable form. It does this by diff --git a/developer/src/kmc-model/src/model-definitions.ts b/developer/src/kmc-model/src/model-definitions.ts index ccef469c91e..9525233d82e 100644 --- a/developer/src/kmc-model/src/model-definitions.ts +++ b/developer/src/kmc-model/src/model-definitions.ts @@ -5,7 +5,9 @@ import { defaultApplyCasing, import KEYMAN_VERSION from "@keymanapp/keyman-version"; import { LexicalModelSource, WordformToKeySpec } from "./lexical-model.js"; -import { CasingForm, CasingFunction } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; +import CasingForm = LexicalModelTypes.CasingForm; +import CasingFunction = LexicalModelTypes.CasingFunction; /** * Processes certain defined model behaviors in such a way that the needed closures diff --git a/developer/src/kmc-model/src/script-overrides-decorator.ts b/developer/src/kmc-model/src/script-overrides-decorator.ts index ebf08b819e2..c1216fa9604 100644 --- a/developer/src/kmc-model/src/script-overrides-decorator.ts +++ b/developer/src/kmc-model/src/script-overrides-decorator.ts @@ -1,4 +1,6 @@ -import { Span, WordBreakingFunction } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; +import Span = LexicalModelTypes.Span; +import WordBreakingFunction = LexicalModelTypes.WordBreakingFunction; import { OverrideScriptDefaults } from "./lexical-model.js"; import { ModelCompilerError, ModelCompilerMessages } from "./model-compiler-messages.js"; diff --git a/developer/src/kmc-model/test/test-compile-model-with-pseudoclosure.ts b/developer/src/kmc-model/test/compile-model-with-pseudoclosure.tests.ts similarity index 96% rename from developer/src/kmc-model/test/test-compile-model-with-pseudoclosure.ts rename to developer/src/kmc-model/test/compile-model-with-pseudoclosure.tests.ts index 049776ec201..b243b51f9c8 100644 --- a/developer/src/kmc-model/test/test-compile-model-with-pseudoclosure.ts +++ b/developer/src/kmc-model/test/compile-model-with-pseudoclosure.tests.ts @@ -4,7 +4,7 @@ import 'mocha'; import { makePathToFixture, compileModelSourceCode } from './helpers/index.js'; import { TestCompilerCallbacks } from '@keymanapp/developer-test-helpers'; -import { CasingForm, CasingFunction } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; describe('LexicalModelCompiler - pseudoclosure compilation + use', function () { const callbacks = new TestCompilerCallbacks(); @@ -13,7 +13,7 @@ describe('LexicalModelCompiler - pseudoclosure compilation + use', function () { const PATH = makePathToFixture(MODEL_ID); describe('specifying custom methods: applyCasing and searchTermToKey', function () { - let casingWithPrependedSymbols: CasingFunction = function(casingName: CasingForm, text: string, defaultApplyCasing: CasingFunction) { + let casingWithPrependedSymbols: LexicalModelTypes.CasingFunction = function(casingName: LexicalModelTypes.CasingForm, text: string, defaultApplyCasing: LexicalModelTypes.CasingFunction) { switch(casingName) { // Use of symbols, and of the `casingName` name, exist to serve as regex targets. case 'lower': @@ -36,7 +36,7 @@ describe('LexicalModelCompiler - pseudoclosure compilation + use', function () { languageUsesCasing: true, // applyCasing won't appear without this! applyCasing: casingWithPrependedSymbols, // Parameter name `rawSearchTerm` selected for uniqueness, regex matching test target. - searchTermToKey: function(rawSearchTerm: string, applyCasing: CasingFunction) { + searchTermToKey: function(rawSearchTerm: string, applyCasing: LexicalModelTypes.CasingFunction) { // Strips any applyCasing symbols ('-', '+', '^') out of the compiled Trie. // We should be able to test that they do _not_ occur within internal nodes of the Trie. return applyCasing('lower', rawSearchTerm) @@ -91,7 +91,7 @@ describe('LexicalModelCompiler - pseudoclosure compilation + use', function () { languageUsesCasing: true, // applyCasing won't appear without this! applyCasing: casingWithPrependedSymbols, // Parameter name `rawSearchTerm` selected for uniqueness, regex matching test target. - searchTermToKey: function(rawSearchTerm: string, applyCasing: CasingFunction) { + searchTermToKey: function(rawSearchTerm: string, applyCasing: LexicalModelTypes.CasingFunction) { // Strips any applyCasing symbols ('-', '+', '^') out of the compiled Trie. // We should be able to test that they do _not_ occur within internal nodes of the Trie. return applyCasing('lower', rawSearchTerm); diff --git a/developer/src/kmc-model/test/test-compile-model.ts b/developer/src/kmc-model/test/compile-model.tests.ts similarity index 100% rename from developer/src/kmc-model/test/test-compile-model.ts rename to developer/src/kmc-model/test/compile-model.tests.ts diff --git a/developer/src/kmc-model/test/test-compile-trie.ts b/developer/src/kmc-model/test/compile-trie.tests.ts similarity index 98% rename from developer/src/kmc-model/test/test-compile-trie.ts rename to developer/src/kmc-model/test/compile-trie.tests.ts index 845022cef5c..d36df694f43 100644 --- a/developer/src/kmc-model/test/test-compile-trie.ts +++ b/developer/src/kmc-model/test/compile-trie.tests.ts @@ -8,7 +8,7 @@ import { createTrieDataStructure } from '../src/build-trie.js'; import { ModelCompilerError } from '../src/model-compiler-messages.js'; import { TestCompilerCallbacks } from '@keymanapp/developer-test-helpers'; import { TrieModel } from '@keymanapp/models-templates'; -import { Span } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; describe('LexicalModelCompiler', function () { const callbacks = new TestCompilerCallbacks(); @@ -73,7 +73,7 @@ describe('LexicalModelCompiler', function () { format: 'trie-1.0', sources: ['wordlist.tsv'], // This is a possible word breaking function: - wordBreaker(phrase: string): Span[] { + wordBreaker(phrase: string): LexicalModelTypes.Span[] { return []; } }, PATH) as string; diff --git a/developer/src/kmc-model/test/test-default-apply-case.ts b/developer/src/kmc-model/test/default-apply-case.tests.ts similarity index 100% rename from developer/src/kmc-model/test/test-default-apply-case.ts rename to developer/src/kmc-model/test/default-apply-case.tests.ts diff --git a/developer/src/kmc-model/test/test-default-search-term-to-key.ts b/developer/src/kmc-model/test/default-search-term-to-key.tests.ts similarity index 94% rename from developer/src/kmc-model/test/test-default-search-term-to-key.ts rename to developer/src/kmc-model/test/default-search-term-to-key.tests.ts index 0f8120e6bae..48cf2ef1f5a 100644 --- a/developer/src/kmc-model/test/test-default-search-term-to-key.ts +++ b/developer/src/kmc-model/test/default-search-term-to-key.tests.ts @@ -4,7 +4,7 @@ import {assert} from 'chai'; import { defaultSearchTermToKey, defaultCasedSearchTermToKey, defaultApplyCasing } from '../src/model-defaults.js'; -import { CasingForm, CasingFunction } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; describe('The default searchTermToKey() function', function () { @@ -102,9 +102,9 @@ describe('The default searchTermToKey() function', function () { // as U+0130's default handling is... not ideal in Turkish. // // Instead, we can get a simple-enough test with inverted casing. - let customCasing = function(caseToApply: CasingForm, + let customCasing = function(caseToApply: LexicalModelTypes.CasingForm, text: string, - defaultApplyCasing: CasingFunction): string { + defaultApplyCasing: LexicalModelTypes.CasingFunction): string { switch(caseToApply) { case 'lower': return text.toUpperCase(); @@ -117,13 +117,13 @@ describe('The default searchTermToKey() function', function () { } } - let customCasingClosure = function(caseToApply: CasingForm, text: string): string { + let customCasingClosure = function(caseToApply: LexicalModelTypes.CasingForm, text: string): string { return customCasing(caseToApply, text, defaultApplyCasing); } for (let [input, expected] of testCases) { it(`should normalize '${input}' to '${expected}'`, function() { - assert.equal(defaultCasedSearchTermToKey(input, customCasingClosure as CasingFunction), expected); + assert.equal(defaultCasedSearchTermToKey(input, customCasingClosure as LexicalModelTypes.CasingFunction), expected); }); } }); diff --git a/developer/src/kmc-model/test/test-join-word-breaker.ts b/developer/src/kmc-model/test/join-word-breaker.tests.ts similarity index 96% rename from developer/src/kmc-model/test/test-join-word-breaker.ts rename to developer/src/kmc-model/test/join-word-breaker.tests.ts index ff220088f5c..e40d2ccdc0d 100644 --- a/developer/src/kmc-model/test/test-join-word-breaker.ts +++ b/developer/src/kmc-model/test/join-word-breaker.tests.ts @@ -1,7 +1,7 @@ import { assert } from "chai"; import defaultWordBreaker from '@keymanapp/models-wordbreakers'; import {decorateWithJoin} from '../src/join-word-breaker-decorator.js'; -import { Span } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; describe('The join word breaker decorator', function () { it('should decorate an existing word breaker', function () { @@ -92,7 +92,7 @@ describe('The join word breaker decorator', function () { /** * Get just the text from a span. */ - function onlyText(span: Span) { + function onlyText(span: LexicalModelTypes.Span) { return span.text; } }); diff --git a/developer/src/kmc-model/test/test-messages.ts b/developer/src/kmc-model/test/messages.tests.ts similarity index 100% rename from developer/src/kmc-model/test/test-messages.ts rename to developer/src/kmc-model/test/messages.tests.ts diff --git a/developer/src/kmc-model/test/test-model-definitions.ts b/developer/src/kmc-model/test/model-definitions.tests.ts similarity index 95% rename from developer/src/kmc-model/test/test-model-definitions.ts rename to developer/src/kmc-model/test/model-definitions.tests.ts index ee569a01b1a..4eaccfb792c 100644 --- a/developer/src/kmc-model/test/test-model-definitions.ts +++ b/developer/src/kmc-model/test/model-definitions.tests.ts @@ -2,7 +2,7 @@ import 'mocha'; import { assert } from 'chai'; import { ModelDefinitions } from '../src/model-definitions.js'; import { LexicalModelSource } from '../src/lexical-model.js'; -import { CasingForm, CasingFunction } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; describe('Model definition pseudoclosures', function () { describe('14.0 defaults', function() { @@ -139,7 +139,7 @@ describe('Model definition pseudoclosures', function () { describe('Model-defined applyCasing + (dependent) searchTermToKey', function() { // Note: this test only implements enough Turkish-related stuff to facilitate // a functional test. Not guaranteed to be sufficient for actual Turkish use. - let turkishCasing = function(form: CasingForm, text: string, defaultApplyCasing: (form: CasingForm, text: string) => string): string { + let turkishCasing = function(form: LexicalModelTypes.CasingForm, text: string, defaultApplyCasing: (form: LexicalModelTypes.CasingForm, text: string) => string): string { switch(form) { case 'lower': return defaultApplyCasing(form, text @@ -159,7 +159,7 @@ describe('Model definition pseudoclosures', function () { let modelSource: LexicalModelSource = { languageUsesCasing: true, applyCasing: turkishCasing, - searchTermToKey: function(wordform: string, applyCasing: CasingFunction): string { + searchTermToKey: function(wordform: string, applyCasing: LexicalModelTypes.CasingFunction): string { return Array.from(wordform .normalize('NFC') // Mostly to avoid decomposing 'İ' ) // end of `Array.from` diff --git a/developer/src/kmc-model/test/test-override-script-defaults.ts b/developer/src/kmc-model/test/override-script-defaults.tests.ts similarity index 92% rename from developer/src/kmc-model/test/test-override-script-defaults.ts rename to developer/src/kmc-model/test/override-script-defaults.tests.ts index b8afb18900b..5c325e4da16 100644 --- a/developer/src/kmc-model/test/test-override-script-defaults.ts +++ b/developer/src/kmc-model/test/override-script-defaults.tests.ts @@ -1,7 +1,7 @@ import { assert } from "chai"; import defaultWordBreaker from '@keymanapp/models-wordbreakers'; import {decorateWithScriptOverrides} from '../src/script-overrides-decorator.js'; -import { Span } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; const THIN_SPACE = "\u2009"; @@ -28,7 +28,7 @@ describe('The script overrides word breaker decorator', function () { assert.deepEqual(actualResult.map(grabText), phraseSpans); }); - function grabText(span: Span) { + function grabText(span: LexicalModelTypes.Span) { return span.text; } }); diff --git a/developer/src/kmc-model/test/test-parse-wordlist.ts b/developer/src/kmc-model/test/parse-wordlist.tests.ts similarity index 100% rename from developer/src/kmc-model/test/test-parse-wordlist.ts rename to developer/src/kmc-model/test/parse-wordlist.tests.ts diff --git a/developer/src/kmc-model/test/test-punctuation.ts b/developer/src/kmc-model/test/punctuation.tests.ts similarity index 100% rename from developer/src/kmc-model/test/test-punctuation.ts rename to developer/src/kmc-model/test/punctuation.tests.ts diff --git a/developer/src/kmc-model/test/tsconfig.json b/developer/src/kmc-model/test/tsconfig.json index 1b1ca1668f6..e30096ba96a 100644 --- a/developer/src/kmc-model/test/tsconfig.json +++ b/developer/src/kmc-model/test/tsconfig.json @@ -10,7 +10,7 @@ "baseUrl": ".", }, "include": [ - "**/test-*.ts", + "**/*.tests.ts", "*.ts", "helpers/*.ts", "wordbreakers/*.ts" @@ -19,4 +19,4 @@ { "path": "../" }, { "path": "../../common/web/test-helpers/" }, ] -} \ No newline at end of file +} diff --git a/developer/src/kmc-package/build.sh b/developer/src/kmc-package/build.sh index 0b2d7bda9b9..81f8b928c70 100755 --- a/developer/src/kmc-package/build.sh +++ b/developer/src/kmc-package/build.sh @@ -36,14 +36,5 @@ builder_run_action clean rm -rf ./build/ ./tsconfig.tsbuildinfo builder_run_action configure verify_npm_setup builder_run_action build tsc --build builder_run_action api api-extractor run --local --verbose - -if builder_start_action test; then - eslint . - cd test - tsc --build - cd .. - c8 --reporter=lcov --reporter=text mocha - builder_finish_action success test -fi - +builder_run_action test builder_do_typescript_tests builder_run_action publish builder_publish_npm diff --git a/developer/src/kmc-package/package.json b/developer/src/kmc-package/package.json index 521ae02e44b..93525e73303 100644 --- a/developer/src/kmc-package/package.json +++ b/developer/src/kmc-package/package.json @@ -44,7 +44,7 @@ "typescript": "^5.4.5" }, "mocha": { - "spec": "build/test/**/test-*.js", + "spec": "build/test/**/*.tests.js", "require": [ "source-map-support/register" ] diff --git a/developer/src/kmc-package/src/compiler/kmp-compiler.ts b/developer/src/kmc-package/src/compiler/kmp-compiler.ts index 3b50ee7ca39..607823c7dd7 100644 --- a/developer/src/kmc-package/src/compiler/kmp-compiler.ts +++ b/developer/src/kmc-package/src/compiler/kmp-compiler.ts @@ -247,8 +247,8 @@ export class KmpCompiler implements KeymanCompiler { kmp.files = kps.Files.File.map((file: KpsFile.KpsFileContentFile) => { return { name: this.normalizePath(file.Name), - description: (file.Description ?? '').trim(), - copyLocation: parseInt(file.CopyLocation, 10) || undefined + description: '', // kmp.json still requires description, but we ignore the input Description field + // note: we no longer emit copyLocation as of 18.0; it was always optional // note: we don't emit fileType as that is not permitted in kmp.json }; }); @@ -270,14 +270,14 @@ export class KmpCompiler implements KeymanCompiler { if(kps.Keyboards && kps.Keyboards.Keyboard) { kmp.files.push({ name: KMP_INF_FILENAME, - description: "Package information" + description: "" }); } // Add the standard kmp.json self-referential to match existing implementations kmp.files.push({ name: KMP_JSON_FILENAME, - description: "Package information (JSON)" + description: "" }); // @@ -415,9 +415,9 @@ export class KmpCompiler implements KeymanCompiler { ]; for (let [src,dst,isMarkdown] of keys) { - if (kpsInfo[src]) { + if (kpsInfo[src]?._ && (kpsInfo[src]._.trim() || kpsInfo[src].$?.URL)) { kmpInfo[dst] = { - description: (kpsInfo[src]._ ?? (typeof kpsInfo[src] == 'string' ? kpsInfo[src].toString() : '')).trim() + description: (kpsInfo[src]._ ?? '').trim() }; if(isMarkdown) { kmpInfo[dst].description = markdownToHTML(kmpInfo[dst].description, false).trim(); diff --git a/developer/src/kmc-package/src/compiler/kmp-inf-writer.ts b/developer/src/kmc-package/src/compiler/kmp-inf-writer.ts index 48499e4ac89..037f34f4aee 100644 --- a/developer/src/kmc-package/src/compiler/kmp-inf-writer.ts +++ b/developer/src/kmc-package/src/compiler/kmp-inf-writer.ts @@ -44,7 +44,7 @@ export class KmpInfWriter { for(let i = 0; i < this.data.files.length; i++) { const file = this.data.files[i]; - this.addString(i.toString(), `"${file.description}","${file.name}",${file.copyLocation??0}`); + this.addString(i.toString(), `"${file.description??''}","${file.name}",${file.copyLocation??0}`); } } diff --git a/developer/src/kmc-package/test/fixtures/example.qaa.sencoten/example.qaa.sencoten.model.kmp.intermediate.json b/developer/src/kmc-package/test/fixtures/example.qaa.sencoten/example.qaa.sencoten.model.kmp.intermediate.json index 3a683626fa3..7c9d139bd48 100644 --- a/developer/src/kmc-package/test/fixtures/example.qaa.sencoten/example.qaa.sencoten.model.kmp.intermediate.json +++ b/developer/src/kmc-package/test/fixtures/example.qaa.sencoten/example.qaa.sencoten.model.kmp.intermediate.json @@ -22,10 +22,10 @@ "files": [ { "name": "example.qaa.sencoten.model.js", - "description": "Lexical model example.qaa.sencoten.model.js" + "description": "" }, { - "description": "Package information (JSON)", + "description": "", "name": "kmp.json" } ], diff --git a/developer/src/kmc-package/test/fixtures/khmer_angkor/ref/kmp.json b/developer/src/kmc-package/test/fixtures/khmer_angkor/ref/kmp.json index 1fd94b374ef..93c02734797 100644 --- a/developer/src/kmc-package/test/fixtures/khmer_angkor/ref/kmp.json +++ b/developer/src/kmc-package/test/fixtures/khmer_angkor/ref/kmp.json @@ -30,71 +30,71 @@ "files": [ { "name": "khmer_angkor.js", - "description": "File khmer_angkor.js" + "description": "" }, { "name": "khmer_angkor.kvk", - "description": "File khmer_angkor.kvk" + "description": "" }, { "name": "khmer_angkor.kmx", - "description": "Keyboard Khmer Angkor" + "description": "" }, { "name": "keyboard_layout.png", - "description": "File keyboard_layout.png" + "description": "" }, { "name": "welcome.htm", - "description": "File welcome.htm" + "description": "" }, { "name": "FONTLOG.txt", - "description": "File FONTLOG.txt" + "description": "" }, { "name": "Mondulkiri-R.ttf", - "description": "Font Khmer Mondulkiri" + "description": "" }, { "name": "OFL.txt", - "description": "File OFL.txt" + "description": "" }, { "name": "OFL-FAQ.txt", - "description": "File OFL-FAQ.txt" + "description": "" }, { "name": "KAK_Documentation_EN.pdf", - "description": "File KAK_Documentation_EN.pdf" + "description": "" }, { "name": "KAK_Documentation_KH.pdf", - "description": "File KAK_Documentation_KH.pdf" + "description": "" }, { "name": "readme.htm", - "description": "File readme.htm" + "description": "" }, { "name": "image002.png", - "description": "File image002.png" + "description": "" }, { "name": "khmer_busra_kbd.ttf", - "description": "Font KhmerBusraKbd" + "description": "" }, { "name": "splash.gif", - "description": "File splash.gif" + "description": "" }, { "name": "kmp.inf", - "description": "Package information" + "description": "" }, { "name": "kmp.json", - "description": "Package information (JSON)" + "description": "" } ], "keyboards": [ diff --git a/developer/src/kmc-package/test/fixtures/kmp.json/kmp.json b/developer/src/kmc-package/test/fixtures/kmp.json/kmp.json index 3cff482c0e5..614af5794eb 100644 --- a/developer/src/kmc-package/test/fixtures/kmp.json/kmp.json +++ b/developer/src/kmc-package/test/fixtures/kmp.json/kmp.json @@ -40,59 +40,59 @@ "files": [ { "name": "ahom_star.kvk", - "description": "File ahom_star.kvk" + "description": "" }, { "name": "ahom_star.kmx", - "description": "Keyboard ahom_star" + "description": "" }, { "name": "ahom_star.js", - "description": "File ahom_star.js" + "description": "" }, { "name": "welcome.htm", - "description": "File welcome.htm" + "description": "" }, { "name": "desktop_layout_default.png", - "description": "File desktop_layout_default.png" + "description": "" }, { "name": "desktop_layout_shift.png", - "description": "File desktop_layout_shift.png" + "description": "" }, { "name": "phone_default.png", - "description": "File phone_default.png" + "description": "" }, { "name": "phone_longpress.png", - "description": "File phone_longpress.png" + "description": "" }, { "name": "phone_numeric.png", - "description": "File phone_numeric.png" + "description": "" }, { "name": "phone_shift.png", - "description": "File phone_shift.png" + "description": "" }, { "name": "readme.htm", - "description": "File readme.htm" + "description": "" }, { "name": "NotoSerifAhom-Regular.ttf", - "description": "Font Noto Serif Ahom Regular" + "description": "" }, { "name": "kmp.inf", - "description": "Package information" + "description": "" }, { "name": "kmp.json", - "description": "Package information (JSON)" + "description": "" } ], "keyboards": [ diff --git a/developer/src/kmc-package/test/fixtures/kmp_2.0/kmp.json b/developer/src/kmc-package/test/fixtures/kmp_2.0/kmp.json index 8cc2f03cd69..0fb814ca6d2 100644 --- a/developer/src/kmc-package/test/fixtures/kmp_2.0/kmp.json +++ b/developer/src/kmc-package/test/fixtures/kmp_2.0/kmp.json @@ -32,75 +32,75 @@ "files": [ { "name": "khmer_angkor.js", - "description": "File khmer_angkor.js" + "description": "" }, { "name": "khmer_angkor.kvk", - "description": "File khmer_angkor.kvk" + "description": "" }, { "name": "khmer_angkor.kmx", - "description": "Keyboard Khmer Angkor" + "description": "" }, { "name": "keyboard_layout.png", - "description": "File keyboard_layout.png" + "description": "" }, { "name": "welcome.htm", - "description": "File welcome.htm" + "description": "" }, { "name": "FONTLOG.txt", - "description": "File FONTLOG.txt" + "description": "" }, { "name": "Mondulkiri-R.ttf", - "description": "Font Khmer Mondulkiri" + "description": "" }, { "name": "OFL.txt", - "description": "File OFL.txt" + "description": "" }, { "name": "OFL-FAQ.txt", - "description": "File OFL-FAQ.txt" + "description": "" }, { "name": "KAK_Documentation_EN.pdf", - "description": "File KAK_Documentation_EN.pdf" + "description": "" }, { "name": "KAK_Documentation_KH.pdf", - "description": "File KAK_Documentation_KH.pdf" + "description": "" }, { "name": "readme.htm", - "description": "File readme.htm" + "description": "" }, { "name": "image002.png", - "description": "File image002.png" + "description": "" }, { "name": "khmer_busra_kbd.ttf", - "description": "Font KhmerBusraKbd" + "description": "" }, { - "description": "Font DejaVuSans", + "description": "", "name": "DejaVuSans.ttf" }, { "name": "splash.gif", - "description": "File splash.gif" + "description": "" }, { "name": "kmp.inf", - "description": "Package information" + "description": "" }, { "name": "kmp.json", - "description": "Package information (JSON)" + "description": "" } ], "keyboards": [ diff --git a/developer/src/kmc-package/test/fixtures/withfolders.qaa.sencoten/withfolders.qaa.sencoten.model.kmp.intermediate.json b/developer/src/kmc-package/test/fixtures/withfolders.qaa.sencoten/withfolders.qaa.sencoten.model.kmp.intermediate.json index 9d3de2aa64b..160c7e74b42 100644 --- a/developer/src/kmc-package/test/fixtures/withfolders.qaa.sencoten/withfolders.qaa.sencoten.model.kmp.intermediate.json +++ b/developer/src/kmc-package/test/fixtures/withfolders.qaa.sencoten/withfolders.qaa.sencoten.model.kmp.intermediate.json @@ -22,14 +22,14 @@ "files": [ { "name": "../build/withfolders.qaa.sencoten.model.js", - "description": "Lexical model withfolders.qaa.sencoten.model.js" + "description": "" }, { - "description": "Welcome file", + "description": "", "name": "welcome.htm" }, { - "description": "Package information (JSON)", + "description": "", "name": "kmp.json" } ], diff --git a/developer/src/kmc-package/test/test-kmp-inf-writer.ts b/developer/src/kmc-package/test/kmp-inf-writer.tests.ts similarity index 100% rename from developer/src/kmc-package/test/test-kmp-inf-writer.ts rename to developer/src/kmc-package/test/kmp-inf-writer.tests.ts diff --git a/developer/src/kmc-package/test/test-markdown.ts b/developer/src/kmc-package/test/markdown.tests.ts similarity index 100% rename from developer/src/kmc-package/test/test-markdown.ts rename to developer/src/kmc-package/test/markdown.tests.ts diff --git a/developer/src/kmc-package/test/test-messages.ts b/developer/src/kmc-package/test/messages.tests.ts similarity index 100% rename from developer/src/kmc-package/test/test-messages.ts rename to developer/src/kmc-package/test/messages.tests.ts diff --git a/developer/src/kmc-package/test/test-package-compiler.ts b/developer/src/kmc-package/test/package-compiler.tests.ts similarity index 100% rename from developer/src/kmc-package/test/test-package-compiler.ts rename to developer/src/kmc-package/test/package-compiler.tests.ts diff --git a/developer/src/kmc-package/test/tsconfig.json b/developer/src/kmc-package/test/tsconfig.json index 62904114c8b..fe3f8f22eaa 100644 --- a/developer/src/kmc-package/test/tsconfig.json +++ b/developer/src/kmc-package/test/tsconfig.json @@ -9,7 +9,7 @@ "allowSyntheticDefaultImports": true, // for jszip }, "include": [ - "**/test-*.ts", + "**/*.tests.ts", "helpers/*.ts" ], "references": [ @@ -18,4 +18,4 @@ { "path": "../../../../common/web/keyman-version" }, { "path": "../../common/web/test-helpers/" }, ] -} \ No newline at end of file +} diff --git a/developer/src/kmc-package/test/test-versioning.ts b/developer/src/kmc-package/test/versioning.tests.ts similarity index 100% rename from developer/src/kmc-package/test/test-versioning.ts rename to developer/src/kmc-package/test/versioning.tests.ts diff --git a/developer/src/kmc-package/test/test-web-keyboard-metadata.ts b/developer/src/kmc-package/test/web-keyboard-metadata.tests.ts similarity index 100% rename from developer/src/kmc-package/test/test-web-keyboard-metadata.ts rename to developer/src/kmc-package/test/web-keyboard-metadata.tests.ts diff --git a/developer/src/kmc-package/test/test-windows-package-installer-compiler.ts b/developer/src/kmc-package/test/windows-package-installer-compiler.tests.ts similarity index 100% rename from developer/src/kmc-package/test/test-windows-package-installer-compiler.ts rename to developer/src/kmc-package/test/windows-package-installer-compiler.tests.ts diff --git a/developer/src/kmc/build.sh b/developer/src/kmc/build.sh index 6c3dfa17bd0..684a9acbeaf 100755 --- a/developer/src/kmc/build.sh +++ b/developer/src/kmc/build.sh @@ -61,17 +61,6 @@ function do_api() { #------------------------------------------------------------------------------------------------------------------- -function do_test() { - eslint . - tsc --build test/ - readonly C8_THRESHOLD=50 - c8 --reporter=lcov --reporter=text --lines $C8_THRESHOLD --statements $C8_THRESHOLD --branches $C8_THRESHOLD --functions $C8_THRESHOLD mocha - builder_echo warning "Coverage thresholds are currently $C8_THRESHOLD%, which is lower than ideal." - builder_echo warning "Please increase threshold in build.sh as test coverage improves." -} - -#------------------------------------------------------------------------------------------------------------------- - function do_bundle() { SOURCEMAP_PATHS=( "${PACKAGES[@]}" ) SOURCEMAP_PATHS=( "${SOURCEMAP_PATHS[@]/%//build}" ) @@ -110,7 +99,7 @@ function do_bundle() { builder_run_action clean rm -rf ./build/ ./tsconfig.tsbuildinfo builder_run_action configure verify_npm_setup builder_run_action build do_build -builder_run_action test do_test +builder_run_action test builder_do_typescript_tests 50 builder_run_action api do_api builder_run_action bundle do_bundle builder_run_action publish builder_publish_npm diff --git a/developer/src/kmc/package.json b/developer/src/kmc/package.json index ccc4e950d8c..1a1a3e0e953 100644 --- a/developer/src/kmc/package.json +++ b/developer/src/kmc/package.json @@ -65,7 +65,7 @@ "typescript": "^5.4.5" }, "mocha": { - "spec": "build/test/**/test-*.js", + "spec": "build/test/**/*.tests.js", "require": [ "source-map-support/register" ] diff --git a/developer/src/kmc/test/test-build.ts b/developer/src/kmc/test/build.tests.ts similarity index 100% rename from developer/src/kmc/test/test-build.ts rename to developer/src/kmc/test/build.tests.ts diff --git a/developer/src/kmc/test/test-extendedCompilerOptions.ts b/developer/src/kmc/test/extendedCompilerOptions.tests.ts similarity index 100% rename from developer/src/kmc/test/test-extendedCompilerOptions.ts rename to developer/src/kmc/test/extendedCompilerOptions.tests.ts diff --git a/developer/src/kmc/test/test-fileLists.ts b/developer/src/kmc/test/fileLists.tests.ts similarity index 100% rename from developer/src/kmc/test/test-fileLists.ts rename to developer/src/kmc/test/fileLists.tests.ts diff --git a/developer/src/kmc/test/test-generateKmnKeyboard.ts b/developer/src/kmc/test/generateKmnKeyboard.tests.ts similarity index 100% rename from developer/src/kmc/test/test-generateKmnKeyboard.ts rename to developer/src/kmc/test/generateKmnKeyboard.tests.ts diff --git a/developer/src/kmc/test/test-generateLdmlKeyboard.ts b/developer/src/kmc/test/generateLdmlKeyboard.tests.ts similarity index 100% rename from developer/src/kmc/test/test-generateLdmlKeyboard.ts rename to developer/src/kmc/test/generateLdmlKeyboard.tests.ts diff --git a/developer/src/kmc/test/test-generateLexicalModel.ts b/developer/src/kmc/test/generateLexicalModel.tests.ts similarity index 100% rename from developer/src/kmc/test/test-generateLexicalModel.ts rename to developer/src/kmc/test/generateLexicalModel.tests.ts diff --git a/developer/src/kmc/test/test-getLastGitCommitDate.ts b/developer/src/kmc/test/getLastGitCommitDate.tests.ts similarity index 100% rename from developer/src/kmc/test/test-getLastGitCommitDate.ts rename to developer/src/kmc/test/getLastGitCommitDate.tests.ts diff --git a/developer/src/kmc/test/test-infrastructureMessages.ts b/developer/src/kmc/test/infrastructureMessages.tests.ts similarity index 100% rename from developer/src/kmc/test/test-infrastructureMessages.ts rename to developer/src/kmc/test/infrastructureMessages.tests.ts diff --git a/developer/src/kmc/test/test-project-build.ts b/developer/src/kmc/test/project-build.tests.ts similarity index 100% rename from developer/src/kmc/test/test-project-build.ts rename to developer/src/kmc/test/project-build.tests.ts diff --git a/developer/src/kmc/test/tsconfig.json b/developer/src/kmc/test/tsconfig.json index 3d0d6eb4f6c..32419a8e57c 100644 --- a/developer/src/kmc/test/tsconfig.json +++ b/developer/src/kmc/test/tsconfig.json @@ -8,7 +8,7 @@ "baseUrl": ".", }, "include": [ - "**/test-*.ts", + "**/*.tests.ts", "./helpers/index.ts", ], "references": [ @@ -16,4 +16,4 @@ { "path": "../../common/web/test-helpers/" }, { "path": "../" } ] -} \ No newline at end of file +} diff --git a/developer/src/kmcmplib/build.bat b/developer/src/kmcmplib/build.bat index 7b5dcf110d8..fd6aa7308d4 100644 --- a/developer/src/kmcmplib/build.bat +++ b/developer/src/kmcmplib/build.bat @@ -80,7 +80,11 @@ shift if "!COMMAND!" == "configure" ( echo === Configuring Keyman KMX Compiler for Windows !ARCH! !BUILDTYPE! === if exist build\!ARCH!\!BUILDTYPE! rd /s/q build\!ARCH!\!BUILDTYPE! - meson setup build\!ARCH!\!BUILDTYPE! !STATIC_LIBRARY! --buildtype !BUILDTYPE! --werror %1 %2 %3 %4 %5 %6 %7 %8 %9 || exit !errorlevel! + if "%1"=="--full-test" ( + meson setup build\!ARCH!\!BUILDTYPE! !STATIC_LIBRARY! --buildtype !BUILDTYPE! --werror -D full_test=true %2 %3 %4 %5 %6 %7 %8 %9 || exit !errorlevel! + ) else ( + meson setup build\!ARCH!\!BUILDTYPE! !STATIC_LIBRARY! --buildtype !BUILDTYPE! --werror %1 %2 %3 %4 %5 %6 %7 %8 %9 || exit !errorlevel! + ) shift ) diff --git a/developer/src/kmcmplib/build.sh b/developer/src/kmcmplib/build.sh index bba19d35558..aaf71846763 100755 --- a/developer/src/kmcmplib/build.sh +++ b/developer/src/kmcmplib/build.sh @@ -7,6 +7,7 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" ## END STANDARD BUILD SCRIPT INCLUDE . "$KEYMAN_ROOT/resources/shellHelperFunctions.sh" +. "$KEYMAN_ROOT/resources/build/build-utils-ci.inc.sh" . "$THIS_SCRIPT_PATH/checkout-keyboards.inc.sh" . "$THIS_SCRIPT_PATH/commands.inc.sh" @@ -78,7 +79,7 @@ do_action() { done } -if builder_has_option --full-test; then +if should_do_full_test; then locate_keyboards_repo fi @@ -101,7 +102,7 @@ if builder_start_action configure; then # We have to checkout the keyboards repo in a 'configure' action because # otherwise meson will not get the right list of keyboard source files, # even though we only use it in the 'test' action - if builder_has_option --full-test; then + if should_do_full_test; then checkout_keyboards fi diff --git a/developer/src/kmcmplib/commands.inc.sh b/developer/src/kmcmplib/commands.inc.sh index d3647c41dd5..280343853c3 100644 --- a/developer/src/kmcmplib/commands.inc.sh +++ b/developer/src/kmcmplib/commands.inc.sh @@ -33,12 +33,19 @@ do_configure() { STANDARD_MESON_ARGS="--cross-file wasm.defs.build --cross-file wasm.build --default-library static" fi + local FULL_TEST= + local FULL_TEST_WIN= + if should_do_full_test; then + FULL_TEST="-D full_test=true" + FULL_TEST_WIN=--full-test + fi + if [[ $target =~ ^(x86|x64)$ ]]; then - cmd //C build.bat $target $BUILDER_CONFIGURATION configure "${builder_extra_params[@]}" + cmd //C build.bat $target $BUILDER_CONFIGURATION configure $FULL_TEST_WIN "${builder_extra_params[@]}" else pushd "$THIS_SCRIPT_PATH" > /dev/null # Additional arguments are used by Linux build, e.g. -Dprefix=${INSTALLDIR} - meson setup "$MESON_PATH" --werror --buildtype $BUILDER_CONFIGURATION $STANDARD_MESON_ARGS "${builder_extra_params[@]}" + meson setup "$MESON_PATH" --werror --buildtype $BUILDER_CONFIGURATION $STANDARD_MESON_ARGS $FULL_TEST "${builder_extra_params[@]}" popd > /dev/null fi builder_finish_action success configure:$target @@ -78,7 +85,7 @@ do_test() { # Works on a local clone of keyboards repository, to avoid clobbering # user's existing keyboards repo, if present - if builder_has_option --full-test; then + if should_do_full_test; then checkout_keyboards fi @@ -125,4 +132,12 @@ build_meson_cross_file_for_wasm() { local R=$(echo $EMSCRIPTEN_BASE | sed 's_/_\\/_g') fi sed -e "s/\$EMSCRIPTEN_BASE/$R/g" wasm.build.$BUILDER_OS.in > wasm.build +} + +should_do_full_test() { + if builder_has_option --full-test || builder_is_ci_test_build; then + return 0 + fi + + return 1 } \ No newline at end of file diff --git a/developer/src/kmcmplib/src/Compiler.cpp b/developer/src/kmcmplib/src/Compiler.cpp index 57702ee1f0f..ff4ab560a52 100644 --- a/developer/src/kmcmplib/src/Compiler.cpp +++ b/developer/src/kmcmplib/src/Compiler.cpp @@ -2031,9 +2031,8 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX ) { KMX_DWORD err; PKMX_WCHAR p = str, q, r; - int type, mx = 0, n, n1, n2, tokenFound = FALSE, z, sFlag = 0, j; + int type, mx = 0, n, n1, n2, tokenFound = FALSE, z, j; KMX_DWORD i; - KMX_BOOL finished = FALSE; KMX_WCHAR c; *tstr = 0; @@ -2126,7 +2125,6 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX q = (PKMX_WCHAR) u16chr(p + 1, '\"'); if (!q) return KmnCompilerMessages::ERROR_UnterminatedString; if ((int)(q - p) - 1 + mx > max) return KmnCompilerMessages::ERROR_ExtendedStringTooLong; - if (sFlag) return KmnCompilerMessages::ERROR_StringInVirtualKeySection; u16ncat(tstr, p + 1, (int)(q - p) - 1); // I3481 mx += (int)(q - p) - 1; tstr[mx] = 0; @@ -2136,7 +2134,6 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX q = (PKMX_WCHAR) u16chr(p + 1, '\''); if (!q) return KmnCompilerMessages::ERROR_UnterminatedString; if ((int)(q - p) - 1 + mx > max) return KmnCompilerMessages::ERROR_ExtendedStringTooLong; - if (sFlag) return KmnCompilerMessages::ERROR_StringInVirtualKeySection; u16ncat(tstr, p + 1, (int)(q - p) - 1); // I3481 mx += (int)(q - p) - 1; tstr[mx] = 0; @@ -2144,7 +2141,6 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX continue; case 3: if (u16nicmp(p, u"any", 3) != 0) return KmnCompilerMessages::ERROR_InvalidToken; - if (sFlag) return KmnCompilerMessages::ERROR_AnyInVirtualKeySection; p += 3; q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); if (!q || !*q) return KmnCompilerMessages::ERROR_InvalidAny; @@ -2166,7 +2162,6 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX case 4: if (u16nicmp(p, u"beep", 4) == 0) { - if (sFlag) return KmnCompilerMessages::ERROR_BeepInVirtualKeySection; p += 4; tstr[mx++] = UC_SENTINEL; tstr[mx++] = CODE_BEEP; @@ -2177,7 +2172,6 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX if(!VerifyKeyboardVersion(fk, VERSION_90)) { return KmnCompilerMessages::ERROR_90FeatureOnly_IfSystemStores; } - if (sFlag) return KmnCompilerMessages::ERROR_InvalidInVirtualKeySection; p += 10; q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); if (!q || !*q) return KmnCompilerMessages::ERROR_InvalidToken; @@ -2194,7 +2188,6 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX if(!VerifyKeyboardVersion(fk, VERSION_80)) { return KmnCompilerMessages::ERROR_80FeatureOnly; } - if (sFlag) return KmnCompilerMessages::ERROR_InvalidInVirtualKeySection; p += 2; q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); if (!q || !*q) return KmnCompilerMessages::ERROR_InvalidIf; @@ -2205,7 +2198,6 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX else { if (u16nicmp(p, u"index", 5) != 0) return KmnCompilerMessages::ERROR_InvalidToken; - if (sFlag) return KmnCompilerMessages::ERROR_IndexInVirtualKeySection; p += 5; q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); @@ -2240,7 +2232,6 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX continue; case 6: if (u16nicmp(p, u"outs", 4) != 0) return KmnCompilerMessages::ERROR_InvalidToken; - if (sFlag) return KmnCompilerMessages::ERROR_OutsInVirtualKeySection; p += 4; q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); if (!q || !*q) return KmnCompilerMessages::ERROR_InvalidOuts; @@ -2266,7 +2257,6 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX if (iswspace(*(p + 1))) break; // is a comment -- pre-stripped - so why this test? if (u16nicmp(p, u"context", 7) == 0) { - if (sFlag) return KmnCompilerMessages::ERROR_ContextInVirtualKeySection; p += 7; q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); @@ -2302,7 +2292,6 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX if(!VerifyKeyboardVersion(fk, VERSION_501)) { return KmnCompilerMessages::ERROR_501FeatureOnly_Call; } - if (sFlag) return KmnCompilerMessages::ERROR_CallInVirtualKeySection; p += 4; q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); if (!q || !*q) return KmnCompilerMessages::ERROR_InvalidCall; @@ -2332,7 +2321,6 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX if(!VerifyKeyboardVersion(fk, VERSION_70)) { return KmnCompilerMessages::ERROR_70FeatureOnly; } - if (sFlag) return KmnCompilerMessages::ERROR_AnyInVirtualKeySection; p += 6; q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); if (!q || !*q) return KmnCompilerMessages::ERROR_InvalidAny; @@ -2390,7 +2378,6 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX if(!VerifyKeyboardVersion(fk, VERSION_80)) { return KmnCompilerMessages::ERROR_80FeatureOnly; } - if (sFlag) return KmnCompilerMessages::ERROR_InvalidInVirtualKeySection; p += 5; q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); if (!q || !*q) return KmnCompilerMessages::ERROR_InvalidReset; @@ -2412,163 +2399,170 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX } continue; case 11: - p++; sFlag = ISVIRTUALKEY /* 0 */; finished = FALSE; + { + int sFlag = ISVIRTUALKEY /* 0 */; + KMX_BOOL finished = FALSE; + KMX_BOOL wsRequired = FALSE; - //printf("--EXTENDEDSTRING--\n"); + p++; - do - { - while (iswspace(*p)) p++; + //printf("--EXTENDEDSTRING--\n"); - switch (towupper(*p)) + do { - case 'N': - if (u16nicmp(p, u"NCAPS", 5) == 0) - sFlag |= NOTCAPITALFLAG, p += 5; - else finished = TRUE; - break; - case 'L': - if (u16nicmp(p, u"LALT", 4) == 0) - sFlag |= LALTFLAG, p += 4; - else if (u16nicmp(p, u"LCTRL", 5) == 0) - sFlag |= LCTRLFLAG, p += 5; - else finished = TRUE; - break; - case 'R': - if (u16nicmp(p, u"RALT", 4) == 0) - sFlag |= RALTFLAG, p += 4; - else if (u16nicmp(p, u"RCTRL", 5) == 0) - sFlag |= RCTRLFLAG, p += 5; - else finished = TRUE; - break; - case 'A': - if (u16nicmp(p, u"ALT", 3) == 0) - sFlag |= K_ALTFLAG, p += 3; - else finished = TRUE; - break; - case 'C': - if (u16nicmp(p, u"CTRL", 4) == 0) - sFlag |= K_CTRLFLAG, p += 4; - else if (u16nicmp(p, u"CAPS", 4) == 0) - sFlag |= CAPITALFLAG, p += 4; - else finished = TRUE; - break; - case 'S': - if (u16nicmp(p, u"SHIFT", 5) == 0) - sFlag |= K_SHIFTFLAG, p += 5; - else finished = TRUE; - break; - default: - finished = TRUE; - break; - } - } while (!finished); + if (wsRequired && !iswspace(*p)) + return KmnCompilerMessages::ERROR_InvalidToken; // #12307 - if ((sFlag & (LCTRLFLAG | LALTFLAG)) && (sFlag & (RCTRLFLAG | RALTFLAG))) { - ReportCompilerMessage(KmnCompilerMessages::WARN_MixingLeftAndRightModifiers); - } + while (iswspace(*p)) p++; + + switch (towupper(*p)) + { + case 'N': + if (u16nicmp(p, u"NCAPS", 5) == 0) + sFlag |= NOTCAPITALFLAG, wsRequired = TRUE, p += 5; + else finished = TRUE; + break; + case 'L': + if (u16nicmp(p, u"LALT", 4) == 0) + sFlag |= LALTFLAG, wsRequired = TRUE, p += 4; + else if (u16nicmp(p, u"LCTRL", 5) == 0) + sFlag |= LCTRLFLAG, wsRequired = TRUE, p += 5; + else finished = TRUE; + break; + case 'R': + if (u16nicmp(p, u"RALT", 4) == 0) + sFlag |= RALTFLAG, wsRequired = TRUE, p += 4; + else if (u16nicmp(p, u"RCTRL", 5) == 0) + sFlag |= RCTRLFLAG, wsRequired = TRUE, p += 5; + else finished = TRUE; + break; + case 'A': + if (u16nicmp(p, u"ALT", 3) == 0) + sFlag |= K_ALTFLAG, wsRequired = TRUE, p += 3; + else finished = TRUE; + break; + case 'C': + if (u16nicmp(p, u"CTRL", 4) == 0) + sFlag |= K_CTRLFLAG, wsRequired = TRUE, p += 4; + else if (u16nicmp(p, u"CAPS", 4) == 0) + sFlag |= CAPITALFLAG, wsRequired = TRUE, p += 4; + else finished = TRUE; + break; + case 'S': + if (u16nicmp(p, u"SHIFT", 5) == 0) + sFlag |= K_SHIFTFLAG, wsRequired = TRUE, p += 5; + else finished = TRUE; + break; + default: + finished = TRUE; + break; + } + } while (!finished); - // If we use chiral modifiers, or we use state keys, and we target web in - // the keyboard, and we don't manually specify a keyboard version, bump - // the minimum version to 10.0. This makes an assumption that if we are - // using these features in a keyboard and it has no version specified, - // that we want to use the features in the web target platform, even if - // there are platform() rules excluding this possibility. In that (rare) - // situation, the keyboard developer should simply specify the &version to - // be 9.0 or whatever to avoid this behaviour. - if (sFlag & (LCTRLFLAG | LALTFLAG | RCTRLFLAG | RALTFLAG | CAPITALFLAG | NOTCAPITALFLAG | NUMLOCKFLAG | NOTNUMLOCKFLAG | SCROLLFLAG | NOTSCROLLFLAG) && - kmcmp::CompileTarget == CKF_KEYMANWEB && - fk->dwFlags & KF_AUTOMATICVERSION) { - if(!VerifyKeyboardVersion(fk, VERSION_100)) { - return STATUS_Success; + if ((sFlag & (LCTRLFLAG | LALTFLAG)) && (sFlag & (RCTRLFLAG | RALTFLAG))) { + ReportCompilerMessage(KmnCompilerMessages::WARN_MixingLeftAndRightModifiers); } - } - //printf("sFlag: %x\n", sFlag); - tstr[mx++] = UC_SENTINEL; - tstr[mx++] = CODE_EXTENDED; - tstr[mx++] = sFlag; + // If we use chiral modifiers, or we use state keys, and we target web in + // the keyboard, and we don't manually specify a keyboard version, bump + // the minimum version to 10.0. This makes an assumption that if we are + // using these features in a keyboard and it has no version specified, + // that we want to use the features in the web target platform, even if + // there are platform() rules excluding this possibility. In that (rare) + // situation, the keyboard developer should simply specify the &version to + // be 9.0 or whatever to avoid this behaviour. + if (sFlag & (LCTRLFLAG | LALTFLAG | RCTRLFLAG | RALTFLAG | CAPITALFLAG | NOTCAPITALFLAG | NUMLOCKFLAG | NOTNUMLOCKFLAG | SCROLLFLAG | NOTSCROLLFLAG) && + kmcmp::CompileTarget == CKF_KEYMANWEB && + fk->dwFlags & KF_AUTOMATICVERSION) { + if(!VerifyKeyboardVersion(fk, VERSION_100)) { + return STATUS_Success; + } + } + //printf("sFlag: %x\n", sFlag); - while (iswspace(*p)) p++; + tstr[mx++] = UC_SENTINEL; + tstr[mx++] = CODE_EXTENDED; + tstr[mx++] = sFlag; - q = p; + q = p; - if (*q == ']') - { - return KmnCompilerMessages::ERROR_InvalidToken; // I3137 - key portion of VK is missing e.g. "[CTRL ALT]", this generates invalid kmx file that can crash Keyman or compiler later on // I3511 - } + if (*q == ']') { + return KmnCompilerMessages::ERROR_InvalidToken; // I3137 - key portion of VK is missing e.g. "[CTRL ALT]", this generates invalid kmx file that can crash Keyman or compiler later on // I3511 + } - while (*q != ']') - { - if (*q == '\'' || *q == '"') - { + if (*q == '\'' || *q == '"') { if(!VerifyKeyboardVersion(fk, VERSION_60)) { return KmnCompilerMessages::ERROR_60FeatureOnly_VirtualCharKey; } + if (!kmcmp::FMnemonicLayout) { ReportCompilerMessage(KmnCompilerMessages::WARN_VirtualCharKeyWithPositionalLayout); } + KMX_WCHAR chQuote = *q; - q++; if (*q == chQuote || *q == '\n' || *q == 0) return KmnCompilerMessages::ERROR_InvalidToken; + + q++; // skip quote + if (*q == chQuote || *q == '\n' || *q == 0) + return KmnCompilerMessages::ERROR_InvalidToken; + tstr[mx - 1] |= VIRTUALCHARKEY; tstr[mx++] = *q; - q++; if (*q != chQuote) return KmnCompilerMessages::ERROR_InvalidToken; - q++; - while (iswspace(*q)) q++; - if (*q != ']') return KmnCompilerMessages::ERROR_InvalidToken; - break; /* out of while loop */ - } - for (j = 0; !iswspace(*q) && *q != ']' && *q != 0; q++, j++); - - if (*q == 0) return KmnCompilerMessages::ERROR_InvalidToken; + q++; // skip key + if (*q != chQuote) + return KmnCompilerMessages::ERROR_InvalidToken; + q++; // skip quote + } else { + for (j = 0; !iswspace(*q) && *q != ']' && *q != 0; q++, j++); - KMX_WCHAR vkname[SZMAX_VKDICTIONARYNAME]; // I3438 + if (*q == 0) + return KmnCompilerMessages::ERROR_InvalidToken; - if (j >= SZMAX_VKDICTIONARYNAME) return KmnCompilerMessages::ERROR_InvalidToken; + KMX_WCHAR vkname[SZMAX_VKDICTIONARYNAME]; // I3438 - u16ncpy(vkname, p, j); // I3481 - vkname[j] = 0; + if (j >= SZMAX_VKDICTIONARYNAME) + return KmnCompilerMessages::ERROR_InvalidToken; - if (u16icmp(vkname, u"K_NPENTER") == 0) - i = 5; // I649 - K_NPENTER hack - else - { - for (i = 0; i <= VK__MAX; i++) - { - if (u16icmp(vkname, VKeyNames[i]) == 0 || u16icmp(vkname, VKeyISO9995Names[i]) == 0) - break; - } - } + u16ncpy(vkname, p, j); // I3481 + vkname[j] = 0; - if (i == VK__MAX + 1) - { - if(!VerifyKeyboardVersion(fk, VERSION_90)) { - return KmnCompilerMessages::ERROR_InvalidToken; + if (u16icmp(vkname, u"K_NPENTER") == 0) + i = 5; // I649 - K_NPENTER hack + else { + for (i = 0; i <= VK__MAX; i++) { + if (u16icmp(vkname, VKeyNames[i]) == 0 || u16icmp(vkname, VKeyISO9995Names[i]) == 0) + break; + } } - i = GetVKCode(fk, vkname); // I3438 - if (i == 0) - return KmnCompilerMessages::ERROR_InvalidToken; - } + if (i == VK__MAX + 1) { + if(!VerifyKeyboardVersion(fk, VERSION_90)) { + return KmnCompilerMessages::ERROR_InvalidToken; + } - p = q; + i = GetVKCode(fk, vkname); // I3438 + if (i == 0) + return KmnCompilerMessages::ERROR_InvalidToken; + } - tstr[mx++] = (int)i; + tstr[mx++] = (int)i; - if (kmcmp::FMnemonicLayout && (i <= VK__MAX) && VKeyMayBeVCKey[i]) { - ReportCompilerMessage(KmnCompilerMessages::WARN_VirtualKeyWithMnemonicLayout); // I3438 + if (kmcmp::FMnemonicLayout && (i <= VK__MAX) && VKeyMayBeVCKey[i]) { + ReportCompilerMessage(KmnCompilerMessages::WARN_VirtualKeyWithMnemonicLayout); // I3438 + } } while (iswspace(*q)) q++; - } - tstr[mx++] = UC_SENTINEL_EXTENDEDEND; - tstr[mx] = 0; - //printf("--EXTENDEDEND--\n"); - p = q + 1; + if (*q != ']') + return KmnCompilerMessages::ERROR_InvalidToken; - sFlag = 0; + tstr[mx++] = UC_SENTINEL_EXTENDEDEND; + tstr[mx] = 0; + //printf("--EXTENDEDEND--\n"); + + p = q + 1; + } continue; case 14: @@ -2645,7 +2639,6 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX if(!VerifyKeyboardVersion(fk, VERSION_90)) { return KmnCompilerMessages::ERROR_90FeatureOnly_IfSystemStores; } - if (sFlag) return KmnCompilerMessages::ERROR_InvalidInVirtualKeySection; p += 8; q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); if (!q || !*q) return KmnCompilerMessages::ERROR_InvalidToken; @@ -2657,7 +2650,6 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX if(!VerifyKeyboardVersion(fk, VERSION_90)) { return KmnCompilerMessages::ERROR_90FeatureOnly_SetSystemStores; } - if (sFlag) return KmnCompilerMessages::ERROR_InvalidInVirtualKeySection; p += 5; q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); if (!q || !*q) return KmnCompilerMessages::ERROR_InvalidToken; @@ -2666,7 +2658,6 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX continue; case 19: // #2241 if (*(p + 1) != '.') return KmnCompilerMessages::ERROR_InvalidToken; - if (sFlag) return KmnCompilerMessages::ERROR_InvalidInVirtualKeySection; p += 2; err = process_expansion(fk, p, tstr, &mx, max); if (err != STATUS_Success) return err; diff --git a/developer/src/kmcmplib/src/CompilerInterfaces.cpp b/developer/src/kmcmplib/src/CompilerInterfaces.cpp index ba368028322..0e424c93b00 100644 --- a/developer/src/kmcmplib/src/CompilerInterfaces.cpp +++ b/developer/src/kmcmplib/src/CompilerInterfaces.cpp @@ -13,7 +13,6 @@ EXTERN bool kmcmp_CompileKeyboard( const void* procContext, KMCMP_COMPILER_RESULT& result ) { - FILE_KEYBOARD fk; fk.extra = new KMCMP_COMPILER_RESULT_EXTRA; fk.extra->kmnFilename = pszInfile; diff --git a/developer/src/kmcmplib/tests/api-test.cpp b/developer/src/kmcmplib/tests/api-test.cpp deleted file mode 100644 index 52769f2b042..00000000000 --- a/developer/src/kmcmplib/tests/api-test.cpp +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Keyman is copyright (C) SIL International. MIT License. - * - * API endpoint unit tests for kmcmplib - */ - -#include - -#ifdef _MSC_VER -#include -#else -#include -#endif - -#include -#include -#include -#include -#include "../src/compfile.h" -#include -#include "util_filesystem.h" -#include "util_callbacks.h" - -void setup(); -void test_kmcmp_CompileKeyboard(char *kmn_file); -void test_GetCompileTargetsFromTargetsStore(); - -int main(int argc, char *argv[]) { - if(argc < 1) { - puts("Usage: api-test "); - puts("Warning: blank_keyboard will be overwritten"); - return 1; - } - setup(); - test_kmcmp_CompileKeyboard(argv[1]); - - setup(); - test_GetCompileTargetsFromTargetsStore(); - - return 0; -} - -void setup() { - error_vec.clear(); -} - -/* - TODO: tests to run: - 4. ANSI (no BOM of course) #8884 - 8. file without blank last line (cannot compare with fixture due to bug in kmcmpdll...) - Hint to add: k004_ansi.kmn: Hint: 10A6 Keyman Developer has detected that the file has ANSI encoding. Consider converting this file to UTF-8 -*/ - -void test_kmcmp_CompileKeyboard(char *kmn_file) { - // Create an empty file - FILE *fp = Open_File(kmn_file, "wb"); - fclose(fp); - - // It should fail when a zero-byte file is passed in - KMCMP_COMPILER_RESULT result; - KMCMP_COMPILER_OPTIONS options; - options.saveDebug = true; - options.compilerWarningsAsErrors = false; - options.warnDeprecatedCode = true; - options.shouldAddCompilerVersion = false; - options.target = CKF_KEYMAN; - assert(!kmcmp_CompileKeyboard(kmn_file, options, msgproc, loadfileProc, nullptr, result)); - assert(error_vec.size() == 1); - assert(error_vec[0] == KmnCompilerMessages::ERROR_InfileNotExist); // zero byte no longer gives us KmnCompilerMessages::ERROR_CannotReadInfile - - unlink(kmn_file); -} - -extern KMX_BOOL GetCompileTargetsFromTargetsStore(const KMX_WCHAR* store, int &targets); - -void test_GetCompileTargetsFromTargetsStore() { - int targets = 0; - - setup(); - assert(GetCompileTargetsFromTargetsStore(u"any", targets)); - assert(error_vec.size() == 0); - assert(targets == (COMPILETARGETS_KMX | COMPILETARGETS_JS)); - - setup(); - assert(GetCompileTargetsFromTargetsStore(u"windows", targets)); - assert(error_vec.size() == 0); - assert(targets == COMPILETARGETS_KMX); - - setup(); - assert(GetCompileTargetsFromTargetsStore(u"desktop", targets)); - assert(error_vec.size() == 0); - assert(targets == COMPILETARGETS_KMX); - - setup(); - assert(GetCompileTargetsFromTargetsStore(u"mobile", targets)); - assert(error_vec.size() == 0); - assert(targets == COMPILETARGETS_JS); - - setup(); - assert(GetCompileTargetsFromTargetsStore(u"web", targets)); - assert(error_vec.size() == 0); - assert(targets == COMPILETARGETS_JS); - - setup(); - assert(GetCompileTargetsFromTargetsStore(u"desktop mobile", targets)); - assert(error_vec.size() == 0); - assert(targets == (COMPILETARGETS_KMX | COMPILETARGETS_JS)); - - setup(); - assert(GetCompileTargetsFromTargetsStore(u"desktop tablet", targets)); - assert(error_vec.size() == 0); - assert(targets == (COMPILETARGETS_KMX | COMPILETARGETS_JS)); - - setup(); - assert(!GetCompileTargetsFromTargetsStore(u"foo bar baz", targets)); - assert(error_vec.size() == 1); - assert(error_vec[0] == KmnCompilerMessages::ERROR_InvalidTarget); - assert(targets == 0); - - setup(); - assert(!GetCompileTargetsFromTargetsStore(u"windows chromeos", targets)); - assert(error_vec.size() == 1); - assert(error_vec[0] == KmnCompilerMessages::ERROR_InvalidTarget); - assert(targets == 0); - - setup(); - assert(!GetCompileTargetsFromTargetsStore(u" ", targets)); - assert(error_vec.size() == 1); - assert(error_vec[0] == KmnCompilerMessages::ERROR_NoTargetsSpecified); - assert(targets == 0); - - setup(); - assert(!GetCompileTargetsFromTargetsStore(u"", targets)); - assert(error_vec.size() == 1); - assert(error_vec[0] == KmnCompilerMessages::ERROR_NoTargetsSpecified); - assert(targets == 0); -} diff --git a/developer/src/kmcmplib/tests/api.tests.cpp b/developer/src/kmcmplib/tests/api.tests.cpp new file mode 100644 index 00000000000..ea44e3fade0 --- /dev/null +++ b/developer/src/kmcmplib/tests/api.tests.cpp @@ -0,0 +1,137 @@ +/* + * Keyman is copyright (C) SIL International. MIT License. + * + * API endpoint unit tests for kmcmplib + */ + +#include + +#ifdef _MSC_VER +#include +#else +#include +#endif + +#include +#include +#include +#include +#include "../src/compfile.h" +#include +#include "util_filesystem.h" +#include "util_callbacks.h" + +void setup(); +void test_kmcmp_CompileKeyboard(char *kmn_file); +void test_GetCompileTargetsFromTargetsStore(); + +int main(int argc, char *argv[]) { + if(argc < 1) { + puts("Usage: api-test "); + puts("Warning: blank_keyboard will be overwritten"); + return 1; + } + setup(); + test_kmcmp_CompileKeyboard(argv[1]); + + setup(); + test_GetCompileTargetsFromTargetsStore(); + + return 0; +} + +void setup() { + error_vec.clear(); +} + +/* + TODO: tests to run: + 4. ANSI (no BOM of course) #8884 + 8. file without blank last line (cannot compare with fixture due to bug in kmcmpdll...) + Hint to add: k004_ansi.kmn: Hint: 10A6 Keyman Developer has detected that the file has ANSI encoding. Consider converting this file to UTF-8 +*/ + +void test_kmcmp_CompileKeyboard(char *kmn_file) { + // Create an empty file + FILE *fp = Open_File(kmn_file, "wb"); + fclose(fp); + + // It should fail when a zero-byte file is passed in + KMCMP_COMPILER_RESULT result; + KMCMP_COMPILER_OPTIONS options; + options.saveDebug = true; + options.compilerWarningsAsErrors = false; + options.warnDeprecatedCode = true; + options.shouldAddCompilerVersion = false; + options.target = CKF_KEYMAN; + test_assert(!kmcmp_CompileKeyboard(kmn_file, options, msgproc, loadfileProc, nullptr, result)); + test_assert(error_vec.size() == 1); + test_assert(error_vec[0] == KmnCompilerMessages::ERROR_InfileNotExist); // zero byte no longer gives us KmnCompilerMessages::ERROR_CannotReadInfile + + unlink(kmn_file); +} + +extern KMX_BOOL GetCompileTargetsFromTargetsStore(const KMX_WCHAR* store, int &targets); + +void test_GetCompileTargetsFromTargetsStore() { + int targets = 0; + + setup(); + test_assert(GetCompileTargetsFromTargetsStore(u"any", targets)); + test_assert(error_vec.size() == 0); + test_assert(targets == (COMPILETARGETS_KMX | COMPILETARGETS_JS)); + + setup(); + test_assert(GetCompileTargetsFromTargetsStore(u"windows", targets)); + test_assert(error_vec.size() == 0); + test_assert(targets == COMPILETARGETS_KMX); + + setup(); + test_assert(GetCompileTargetsFromTargetsStore(u"desktop", targets)); + test_assert(error_vec.size() == 0); + test_assert(targets == COMPILETARGETS_KMX); + + setup(); + test_assert(GetCompileTargetsFromTargetsStore(u"mobile", targets)); + test_assert(error_vec.size() == 0); + test_assert(targets == COMPILETARGETS_JS); + + setup(); + test_assert(GetCompileTargetsFromTargetsStore(u"web", targets)); + test_assert(error_vec.size() == 0); + test_assert(targets == COMPILETARGETS_JS); + + setup(); + test_assert(GetCompileTargetsFromTargetsStore(u"desktop mobile", targets)); + test_assert(error_vec.size() == 0); + test_assert(targets == (COMPILETARGETS_KMX | COMPILETARGETS_JS)); + + setup(); + test_assert(GetCompileTargetsFromTargetsStore(u"desktop tablet", targets)); + test_assert(error_vec.size() == 0); + test_assert(targets == (COMPILETARGETS_KMX | COMPILETARGETS_JS)); + + setup(); + test_assert(!GetCompileTargetsFromTargetsStore(u"foo bar baz", targets)); + test_assert(error_vec.size() == 1); + test_assert(error_vec[0] == KmnCompilerMessages::ERROR_InvalidTarget); + test_assert(targets == 0); + + setup(); + test_assert(!GetCompileTargetsFromTargetsStore(u"windows chromeos", targets)); + test_assert(error_vec.size() == 1); + test_assert(error_vec[0] == KmnCompilerMessages::ERROR_InvalidTarget); + test_assert(targets == 0); + + setup(); + test_assert(!GetCompileTargetsFromTargetsStore(u" ", targets)); + test_assert(error_vec.size() == 1); + test_assert(error_vec[0] == KmnCompilerMessages::ERROR_NoTargetsSpecified); + test_assert(targets == 0); + + setup(); + test_assert(!GetCompileTargetsFromTargetsStore(u"", targets)); + test_assert(error_vec.size() == 1); + test_assert(error_vec[0] == KmnCompilerMessages::ERROR_NoTargetsSpecified); + test_assert(targets == 0); +} diff --git a/developer/src/kmcmplib/tests/get-test-source.sh b/developer/src/kmcmplib/tests/get-test-source.sh index beebce3aca3..fe6cded2f19 100755 --- a/developer/src/kmcmplib/tests/get-test-source.sh +++ b/developer/src/kmcmplib/tests/get-test-source.sh @@ -9,5 +9,10 @@ set -eu find "$1" -name '*.kmn' | \ grep -E '(release|experimental)/([a-z0-9_]+)/([a-z0-9_]+)/source/\3\.kmn$' | \ - grep -v masaram_gondi + grep -vE 'masaram_gondi|anii|sil_kmhmu|fv_statimcets|fv_nuucaanul|basic_kbdcherp|basic_kbdolch' # #12623: exclude masaram_gondi due to #11806 +# #12631: exclude anii, sil_kmhmu as ico references have mismatching case +# #12631: exclude fv_statimcets, fv_nuucaanul as these include U+2002 which is not +# treated as whitespace on mac arch +# #12604: exclude basic_kbdcherp, basic_kbdolch as these do not include now necessary +# whitespace, see also issue #12307 diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler.tests.cpp similarity index 97% rename from developer/src/kmcmplib/tests/gtest-compiler-test.cpp rename to developer/src/kmcmplib/tests/gtest-compiler.tests.cpp index e6a5a0f513f..ca8f40f6d81 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler.tests.cpp @@ -786,8 +786,6 @@ TEST_F(CompilerTest, GetXStringImpl_type_double_quote_test) { // KmnCompilerMessages::ERROR_ExtendedStringTooLong u16cpy(str, u"\"abc\""); EXPECT_EQ(KmnCompilerMessages::ERROR_ExtendedStringTooLong, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 2, 0, &newp, FALSE)); // max reduced to force error - - // KmnCompilerMessages::ERROR_StringInVirtualKeySection *** TODO *** } // tests strings starting with single quote @@ -809,8 +807,6 @@ TEST_F(CompilerTest, GetXStringImpl_type_single_quote_test) { // KmnCompilerMessages::ERROR_ExtendedStringTooLong u16cpy(str, u"\'abc\'"); EXPECT_EQ(KmnCompilerMessages::ERROR_ExtendedStringTooLong, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 2, 0, &newp, FALSE)); // max reduced to force error - - // KmnCompilerMessages::ERROR_StringInVirtualKeySection *** TODO *** } // tests strings starting with 'a' @@ -825,8 +821,6 @@ TEST_F(CompilerTest, GetXStringImpl_type_a_test) { u16cpy(str, u"abc"); EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidToken, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // KmnCompilerMessages::ERROR_AnyInVirtualKeySection *** TODO *** - // KmnCompilerMessages::ERROR_InvalidAny, no delimiters => NULL u16cpy(str, u"any"); EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidAny, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); @@ -892,8 +886,6 @@ TEST_F(CompilerTest, GetXStringImpl_type_b_test) { u16cpy(str, u"bcd"); EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidToken, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // beep, KmnCompilerMessages::ERROR_BeepInVirtualKeySection *** TODO *** - // beep, valid u16cpy(str, u"beep"); EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); @@ -907,8 +899,6 @@ TEST_F(CompilerTest, GetXStringImpl_type_b_test) { EXPECT_EQ(KmnCompilerMessages::ERROR_90FeatureOnly_IfSystemStores, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); fileKeyboard.version = VERSION_90; - // baselayout, KmnCompilerMessages::ERROR_InvalidInVirtualKeySection *** TODO *** - // baselayout, no delimiters => NULL fileKeyboard.version = VERSION_90; u16cpy(str, u"baselayout"); @@ -980,8 +970,6 @@ TEST_F(CompilerTest, GetXStringImpl_type_i_test) { EXPECT_EQ(KmnCompilerMessages::ERROR_80FeatureOnly, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); fileKeyboard.version = VERSION_80; - // if, KmnCompilerMessages::ERROR_InvalidInVirtualKeySection *** TODO *** - // if, no delimiters => NULL fileKeyboard.version = VERSION_80; u16cpy(str, u"if"); @@ -1077,8 +1065,6 @@ TEST_F(CompilerTest, GetXStringImpl_type_i_test) { initFileStoreArray(fileKeyboard, {u"a", u"b", u"c"}); fileKeyboard.dpStoreArray[1].fIsStore = TRUE; - // index, KmnCompilerMessages::ERROR_InvalidInVirtualKeySection *** TODO *** - // index, no delimiters => NULL u16cpy(str, u"index"); EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidIndex, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); @@ -1190,8 +1176,6 @@ TEST_F(CompilerTest, GetXStringImpl_type_o_test) { u16cpy(str, u"opq"); EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidToken, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // outs, KmnCompilerMessages::ERROR_OutsInVirtualKeySection *** TODO *** - // outs, no delimiters => NULL u16cpy(str, u"outs"); EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidOuts, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); @@ -1266,8 +1250,6 @@ TEST_F(CompilerTest, GetXStringImpl_type_c_test) { u16cpy(str, u"cde"); EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidToken, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // context, KmnCompilerMessages::ERROR_ContextInVirtualKeySection *** TODO *** - // context, no offset, valid fileKeyboard.version = VERSION_60; u16cpy(str, u"context"); @@ -1352,8 +1334,6 @@ TEST_F(CompilerTest, GetXStringImpl_type_c_test) { u16cpy(str, u"call"); EXPECT_EQ(KmnCompilerMessages::ERROR_501FeatureOnly_Call, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // call, KmnCompilerMessages::ERROR_CallInVirtualKeySection *** TODO *** - // call, no delimiters => NULL fileKeyboard.version = VERSION_501; u16cpy(str, u"call"); @@ -1443,8 +1423,6 @@ TEST_F(CompilerTest, GetXStringImpl_type_n_test) { u16cpy(str, u"notany"); EXPECT_EQ(KmnCompilerMessages::ERROR_70FeatureOnly, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // notany, KmnCompilerMessages::ERROR_AnyInVirtualKeySection *** TODO *** - // notany, no delimiters => NULL fileKeyboard.version = VERSION_70; u16cpy(str, u"notany"); @@ -1629,8 +1607,6 @@ TEST_F(CompilerTest, GetXStringImpl_type_r_test) { u16cpy(str, u"reset"); EXPECT_EQ(KmnCompilerMessages::ERROR_80FeatureOnly, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // reset, KmnCompilerMessages::ERROR_InvalidInVirtualKeySection *** TODO *** - // reset, no delimiters => NULL fileKeyboard.version = VERSION_80; u16cpy(str, u"reset"); @@ -1807,25 +1783,25 @@ TEST_F(CompilerTest, GetXStringImpl_type_osb_test) { u16cpy(str, u"[CTRL ALT]"); EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidToken, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + // virtual key, modifiers only (no key portion), space after, KmnCompilerMessages::ERROR_InvalidToken + fileKeyboard.version = VERSION_90; + u16cpy(str, u"[CTRL ALT ]"); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidToken, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + // virtual key, in VKeyNames, no space between modifier and key portion, ERROR_InvalidToken (see #12307) - // fileKeyboard.version = VERSION_90; - // u16cpy(str, u"[CTRLK_A]"); - // EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidToken, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + fileKeyboard.version = VERSION_90; + u16cpy(str, u"[CTRLK_A]"); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidToken, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); // virtual key, in VKeyNames, no space between modifiers, ERROR_InvalidToken (see #12307) - // fileKeyboard.version = VERSION_90; - // u16cpy(str, u"[CTRLALT K_A]"); - // EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidToken, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + fileKeyboard.version = VERSION_90; + u16cpy(str, u"[CTRLALT K_A]"); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidToken, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); // virtual key, '_' between modifier and key portion', ERROR_InvalidToken (see #12307) - // fileKeyboard.version = VERSION_90; - // u16cpy(str, u"[CTRL_K_A]"); - // EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // tstr_virtual_key_valid[2] = ISVIRTUALKEY | K_CTRLFLAG; - // tstr_virtual_key_valid[3] = 259; // VK__MAX + 4 - // EXPECT_EQ(0, u16cmp(tstr_virtual_key_valid, tstr)); - // EXPECT_EQ(0, msgproc_errors.size()); - // tstr_virtual_key_valid[3] = 65; + fileKeyboard.version = VERSION_90; + u16cpy(str, u"[CTRL_K_A]"); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidToken, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); // virtual char key, single quote, ERROR_60FeatureOnly_VirtualCharKey fileKeyboard.version = VERSION_50; @@ -2029,13 +2005,10 @@ TEST_F(CompilerTest, GetXStringImpl_type_osb_test) { EXPECT_EQ(KmnCompilerMessages::WARN_VirtualKeyWithMnemonicLayout, msgproc_errors[0].errorCode); msgproc_errors.clear(); - // virtual key, in VKeyNames, multiple keys, valid (see #12307) - // fileKeyboard.version = VERSION_90; - // u16cpy(str, u"[K_A K_B K_C]"); - // EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // sFlag = ISVIRTUALKEY; - // KMX_WCHAR tstr_virtual_key_multi_valid[] = { UC_SENTINEL, CODE_EXTENDED, sFlag, 65, 66, 67, UC_SENTINEL_EXTENDEDEND, 0 }; - // EXPECT_EQ(0, u16cmp(tstr_virtual_key_multi_valid, tstr)); + // virtual key, in VKeyNames, multiple keys, KmnCompilerMessages::ERROR_InvalidToken (see #12307) + fileKeyboard.version = VERSION_90; + u16cpy(str, u"[K_A K_B]"); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidToken, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); } // KMX_DWORD process_baselayout(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) diff --git a/developer/src/kmcmplib/tests/gtest-km_u16-test.cpp b/developer/src/kmcmplib/tests/gtest-km_u16.tests.cpp similarity index 100% rename from developer/src/kmcmplib/tests/gtest-km_u16-test.cpp rename to developer/src/kmcmplib/tests/gtest-km_u16.tests.cpp diff --git a/developer/src/kmcmplib/tests/kmcompxtest.cpp b/developer/src/kmcmplib/tests/kmcompx.tests.cpp similarity index 100% rename from developer/src/kmcmplib/tests/kmcompxtest.cpp rename to developer/src/kmcmplib/tests/kmcompx.tests.cpp diff --git a/developer/src/kmcmplib/tests/meson.build b/developer/src/kmcmplib/tests/meson.build index 65915d1e9d9..da2ac61a37d 100644 --- a/developer/src/kmcmplib/tests/meson.build +++ b/developer/src/kmcmplib/tests/meson.build @@ -6,6 +6,8 @@ fs = import('fs') +common_test_files = [ meson.global_source_root() / '../../../common/include/test_color.cpp' ] + tests_links = [] if cpp_compiler.get_id() == 'emscripten' @@ -15,7 +17,7 @@ endif input_path = meson.current_source_dir() / '../../../../common/test/keyboards/baseline' output_path = meson.current_build_dir() -kmcompxtest = executable('kmcompxtest', ['kmcompxtest.cpp','util_filesystem.cpp','util_callbacks.cpp'], +kmcompxtest = executable('kmcompxtests', ['kmcompx.tests.cpp','util_filesystem.cpp','util_callbacks.cpp',common_test_files], cpp_args: defns + flags, include_directories: inc, name_suffix: name_suffix, @@ -129,11 +131,9 @@ if get_option('full_test') endif -common_test_files = [ meson.global_source_root() / '../../../common/include/test_color.cpp' ] - # Test the API endpoints -apitest = executable('api-test', ['api-test.cpp','util_filesystem.cpp','util_callbacks.cpp', common_test_files], +apitest = executable('api-tests', ['api.tests.cpp','util_filesystem.cpp','util_callbacks.cpp', common_test_files], cpp_args: defns + flags, include_directories: inc, name_suffix: name_suffix, @@ -142,9 +142,9 @@ apitest = executable('api-test', ['api-test.cpp','util_filesystem.cpp','util_cal dependencies: icuuc_dep ) -test('api-test', apitest, args: [output_path / 'blank_keyboard.kmx']) +test('api-tests', apitest, args: [output_path / 'blank_keyboard.kmx']) -usetapitest = executable('uset-api-test', 'uset-api-test.cpp', common_test_files, +usetapitest = executable('uset-api-tests', 'uset-api.tests.cpp', common_test_files, cpp_args: defns + flags, include_directories: inc, name_suffix: name_suffix, @@ -153,11 +153,11 @@ usetapitest = executable('uset-api-test', 'uset-api-test.cpp', common_test_files dependencies: icuuc_dep, ) -test('uset-api-test', usetapitest) +test('uset-api-tests', usetapitest) # Google Test -gtestcompilertest = executable('gtest-compiler-test', 'gtest-compiler-test.cpp', +gtestcompilertest = executable('gtest-compiler-tests', 'gtest-compiler.tests.cpp', cpp_args: defns + flags, include_directories: inc, name_suffix: name_suffix, @@ -166,9 +166,9 @@ gtestcompilertest = executable('gtest-compiler-test', 'gtest-compiler-test.cpp', dependencies: [ icuuc_dep, gtest_dep, gmock_dep ], ) -test('gtest-compiler-test', gtestcompilertest) +test('gtest-compiler-tests', gtestcompilertest) -gtest_km_u16_test = executable('gtest-km_u16-test', 'gtest-km_u16-test.cpp', +gtest_km_u16_test = executable('gtest-km_u16-tests', 'gtest-km_u16.tests.cpp', cpp_args: defns + flags, include_directories: inc, name_suffix: name_suffix, @@ -177,4 +177,4 @@ gtest_km_u16_test = executable('gtest-km_u16-test', 'gtest-km_u16-test.cpp', dependencies: [ icuuc_dep, gtest_dep, gmock_dep ], ) -test('gtest-km_u16-test', gtest_km_u16_test) +test('gtest-km_u16-tests', gtest_km_u16_test) diff --git a/developer/src/kmcmplib/tests/uset-api-test.cpp b/developer/src/kmcmplib/tests/uset-api.tests.cpp similarity index 77% rename from developer/src/kmcmplib/tests/uset-api-test.cpp rename to developer/src/kmcmplib/tests/uset-api.tests.cpp index 7a24f5cd4a5..ce83e012eb9 100644 --- a/developer/src/kmcmplib/tests/uset-api-test.cpp +++ b/developer/src/kmcmplib/tests/uset-api.tests.cpp @@ -37,14 +37,14 @@ void test_kmcmp_parseUnicodeSet() { uint32_t buf[bufsiz]; uintptr_t buf_ = reinterpret_cast(buf); int rc = kmcmp_parseUnicodeSet(u8"[]", buf_, bufsiz); - assert(rc == KMCMP_USET_OK); + test_assert(rc == KMCMP_USET_OK); } { // preflight null test const auto bufsiz = 0; uintptr_t buf_ = 0L; int rc = kmcmp_parseUnicodeSet(u8"[]", buf_, bufsiz); - assert(rc == KMCMP_USET_OK); // == 0 + test_assert(rc == KMCMP_USET_OK); // == 0 } { // basic test @@ -52,17 +52,17 @@ void test_kmcmp_parseUnicodeSet() { uint32_t buf[bufsiz]; uintptr_t buf_ = reinterpret_cast(buf); int rc = kmcmp_parseUnicodeSet(u8"[x A-C]", buf_, bufsiz); - assert(rc == 2); - assert(buf[0] == 0x41); - assert(buf[1] == 0x43); - assert(buf[2] == 0x78); - assert(buf[3] == 0x78); + test_assert(rc == 2); + test_assert(buf[0] == 0x41); + test_assert(buf[1] == 0x43); + test_assert(buf[2] == 0x78); + test_assert(buf[3] == 0x78); } { uintptr_t buf_ = 0L; const auto bufsiz = 0; int rc = kmcmp_parseUnicodeSet(u8"[x A-C]", buf_, bufsiz); // preflight - assert(rc == 2); // 2 ranges + test_assert(rc == 2); // 2 ranges } { // bigger test @@ -70,11 +70,11 @@ void test_kmcmp_parseUnicodeSet() { uint32_t buf[bufsiz]; uintptr_t buf_ = reinterpret_cast(buf); int rc = kmcmp_parseUnicodeSet(u8"[[🙀A-C]-[CB]]", buf_, bufsiz); - assert(rc == 2); - assert(buf[0] == 0x41); - assert(buf[1] == 0x41); - assert(buf[2] == 0x1F640); - assert(buf[3] == 0x1F640); + test_assert(rc == 2); + test_assert(buf[0] == 0x41); + test_assert(buf[1] == 0x41); + test_assert(buf[2] == 0x1F640); + test_assert(buf[3] == 0x1F640); } { // overflow test @@ -82,7 +82,7 @@ void test_kmcmp_parseUnicodeSet() { uint32_t buf[bufsiz]; uintptr_t buf_ = reinterpret_cast(buf); int rc = kmcmp_parseUnicodeSet(u8"[x A-C]", buf_, bufsiz); - assert(rc == KMCMP_FATAL_OUT_OF_RANGE); + test_assert(rc == KMCMP_FATAL_OUT_OF_RANGE); } { // err test @@ -90,7 +90,7 @@ void test_kmcmp_parseUnicodeSet() { uint32_t buf[bufsiz]; uintptr_t buf_ = reinterpret_cast(buf); int rc = kmcmp_parseUnicodeSet(u8"[:Adlm:]", buf_, bufsiz); - assert(rc == KMCMP_ERROR_UNSUPPORTED_PROPERTY); + test_assert(rc == KMCMP_ERROR_UNSUPPORTED_PROPERTY); } { // err test @@ -98,7 +98,7 @@ void test_kmcmp_parseUnicodeSet() { uint32_t buf[bufsiz]; uintptr_t buf_ = reinterpret_cast(buf); int rc = kmcmp_parseUnicodeSet(u8"[[\\p{Mn}]&[A-Z]]", buf_, bufsiz); - assert(rc == KMCMP_ERROR_UNSUPPORTED_PROPERTY); + test_assert(rc == KMCMP_ERROR_UNSUPPORTED_PROPERTY); } { // err test @@ -106,7 +106,7 @@ void test_kmcmp_parseUnicodeSet() { uint32_t buf[bufsiz]; uintptr_t buf_ = reinterpret_cast(buf); int rc = kmcmp_parseUnicodeSet(u8"[abc{def}]", buf_, bufsiz); - assert(rc == KMCMP_ERROR_HAS_STRINGS); + test_assert(rc == KMCMP_ERROR_HAS_STRINGS); } { // err test @@ -114,34 +114,34 @@ void test_kmcmp_parseUnicodeSet() { uint32_t buf[bufsiz]; uintptr_t buf_ = reinterpret_cast(buf); int rc = kmcmp_parseUnicodeSet(u8"[[]", buf_, bufsiz); - assert(rc == KMCMP_ERROR_SYNTAX_ERR); + test_assert(rc == KMCMP_ERROR_SYNTAX_ERR); } { // preflight err test const auto bufsiz = 0; // preflight uintptr_t buf_ = 0L; int rc = kmcmp_parseUnicodeSet(u8"[:Adlm:]", buf_, bufsiz); - assert(rc == KMCMP_ERROR_UNSUPPORTED_PROPERTY); + test_assert(rc == KMCMP_ERROR_UNSUPPORTED_PROPERTY); } { // preflight err test const auto bufsiz = 0; // preflight uintptr_t buf_ = 0L; int rc = kmcmp_parseUnicodeSet(u8"[[\\p{Mn}]&[A-Z]]", buf_, bufsiz); - assert(rc == KMCMP_ERROR_UNSUPPORTED_PROPERTY); + test_assert(rc == KMCMP_ERROR_UNSUPPORTED_PROPERTY); } { // preflight err test const auto bufsiz = 0; // preflight uintptr_t buf_ = 0L; int rc = kmcmp_parseUnicodeSet(u8"[abc{def}]", buf_, bufsiz); - assert(rc == KMCMP_ERROR_HAS_STRINGS); + test_assert(rc == KMCMP_ERROR_HAS_STRINGS); } { // preflight err test const auto bufsiz = 0; // preflight uintptr_t buf_ = 0L; int rc = kmcmp_parseUnicodeSet(u8"[[]", buf_, bufsiz); - assert(rc == KMCMP_ERROR_SYNTAX_ERR); + test_assert(rc == KMCMP_ERROR_SYNTAX_ERR); } } diff --git a/developer/src/kmcmplib/tests/util_callbacks.cpp b/developer/src/kmcmplib/tests/util_callbacks.cpp index d512463a0b4..47d22b0bb27 100644 --- a/developer/src/kmcmplib/tests/util_callbacks.cpp +++ b/developer/src/kmcmplib/tests/util_callbacks.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include "util_filesystem.h" #include "../src/compfile.h" @@ -29,6 +30,14 @@ void msgproc(const KMCMP_COMPILER_RESULT_MESSAGE &message, void* context) { printf(")\n"); } +void normalizeSlashes(std::string& s) { +#ifdef _WIN32 + std::replace(s.begin(), s.end(), '/', '\\'); +#else + std::replace(s.begin(), s.end(), '\\', '/'); +#endif +} + const std::vector loadfileProc(const std::string& filename, const std::string& baseFilename) { std::string resolvedFilename = filename; if(baseFilename.length() && IsRelativePath(filename.c_str())) { @@ -40,6 +49,8 @@ const std::vector loadfileProc(const std::string& filename, const std:: } } + normalizeSlashes(resolvedFilename); + std::vector buf; FILE* fp = Open_File(resolvedFilename.c_str(), "rb"); diff --git a/developer/src/kmcmplib/tests/util_filesystem.cpp b/developer/src/kmcmplib/tests/util_filesystem.cpp index 0873ff13288..0a45e29876a 100644 --- a/developer/src/kmcmplib/tests/util_filesystem.cpp +++ b/developer/src/kmcmplib/tests/util_filesystem.cpp @@ -1,10 +1,8 @@ - #ifdef __EMSCRIPTEN__ #include #include #endif -#include #include #include #include "util_filesystem.h" @@ -15,6 +13,8 @@ #include #endif +#include + //#define _DEBUG_FOPEN 1 #ifdef __EMSCRIPTEN__ @@ -26,13 +26,13 @@ const std::string get_wasm_file_path(const std::string& filename) { std::cout << "get_wasm_file_path ENTER (" << filename << ")" << std::endl; #endif - assert( + test_assert( (filename.length() > 0 && filename.at(0) == '/') || (filename.length() > 1 && filename.at(1) == ':') ); #if _DEBUG_FOPEN - std::cout << "get_wasm_file_path assert passed " << std::endl; + std::cout << "get_wasm_file_path test_assert passed " << std::endl; #endif EM_ASM_({ diff --git a/developer/src/server/src/win32/trayicon/addon-src/package-lock.json b/developer/src/server/src/win32/trayicon/addon-src/package-lock.json index d16aad04aa6..09ab72cd159 100644 --- a/developer/src/server/src/win32/trayicon/addon-src/package-lock.json +++ b/developer/src/server/src/win32/trayicon/addon-src/package-lock.json @@ -198,9 +198,9 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -1241,9 +1241,9 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "requires": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", diff --git a/developer/src/server/test/tsconfig.json b/developer/src/server/test/tsconfig.json index fa377b0fde1..b56cbcfa245 100644 --- a/developer/src/server/test/tsconfig.json +++ b/developer/src/server/test/tsconfig.json @@ -8,9 +8,9 @@ "baseUrl": ".", }, "include": [ - "**/*.test.ts" + "**/*.tests.ts" ], "references": [ { "path": "../" }, ] -} \ No newline at end of file +} diff --git a/developer/src/server/test/version-data.test.ts b/developer/src/server/test/version-data.tests.ts similarity index 100% rename from developer/src/server/test/version-data.test.ts rename to developer/src/server/test/version-data.tests.ts diff --git a/docs/CODEOWNERS b/docs/CODEOWNERS index dcf54ce78cc..3316073d520 100644 --- a/docs/CODEOWNERS +++ b/docs/CODEOWNERS @@ -1,18 +1,19 @@ # # Code owners - this lists first the primary dev, then second, the platform advocate for each area +# - in addition, it lists additional reviewers # # @darcywong00 @mcdurdin @ermshiperete @rc-swag @SabineSIL @sgschantz /android/ @darcywong00 @sgschantz -/common/ @mcdurdin @rc-swag -/core/ @mcdurdin @rc-swag +/common/ @mcdurdin @rc-swag @srl295 +/core/ @mcdurdin @rc-swag @srl295 /common/lexical-model-types/ @jahorton @mcdurdin /common/schemas/ @mcdurdin @jahorton /common/test/ @mcdurdin @ermshiperete /common/web/ @jahorton @mcdurdin -/developer/ @mcdurdin @darcywong00 +/developer/ @mcdurdin @darcywong00 @SabineSIL @markcsinclair @srl295 /docs/ @mcdurdin @jahorton /ios/ @sgschantz @jahorton /linux/ @ermshiperete @darcywong00 @@ -22,7 +23,7 @@ /oem/firstvoices/common/ @mcdurdin @rc-swag /oem/firstvoices/ios/ @sgschantz @jahorton /oem/firstvoices/windows/ @rc-swag @ermshiperete -/resources/ @mcdurdin @jahorton +/resources/ @mcdurdin @jahorton @srl295 # Web is currently shared between Eberhard and Joshua: /web/ @ermshiperete @jahorton diff --git a/docs/build/linux-ubuntu.md b/docs/build/linux-ubuntu.md index a45d9390ba5..37b2aafa1ab 100644 --- a/docs/build/linux-ubuntu.md +++ b/docs/build/linux-ubuntu.md @@ -70,10 +70,23 @@ git clone https://github.com/emscripten-core/emsdk.git cd emsdk ./emsdk install 3.1.58 ./emsdk activate 3.1.58 -export EMSCRIPTEN_BASE="$(pwd)/upstream/emscripten" +cd upstream/emscripten +npm install +export EMSCRIPTEN_BASE="$(pwd)" echo "export EMSCRIPTEN_BASE=\"$EMSCRIPTEN_BASE\"" >> .bashrc ``` +If you are updating an existing install of Emscripten: + +```bash +cd emsdk +git pull +./emsdk install 3.1.58 +./emsdk activate 3.1.58 +cd upstream/emscripten +npm install +``` + > ![WARNING] > Don't put EMSDK on the path, i.e. don't source `emsdk_env.sh`. > diff --git a/docs/build/macos.md b/docs/build/macos.md index 25b0c1f82ae..f961942070b 100644 --- a/docs/build/macos.md +++ b/docs/build/macos.md @@ -101,10 +101,23 @@ git clone https://github.com/emscripten-core/emsdk cd emsdk emsdk install 3.1.58 emsdk activate 3.1.58 -export EMSCRIPTEN_BASE="$(pwd)/upstream/emscripten" +cd upstream/emscripten +npm install +export EMSCRIPTEN_BASE="$(pwd)" echo "export EMSCRIPTEN_BASE=\"$EMSCRIPTEN_BASE\"" >> .bashrc ``` +If you are updating an existing install of Emscripten: + +```bash +cd emsdk +git pull +emsdk install 3.1.58 +emsdk activate 3.1.58 +cd upstream/emscripten +npm install +``` + You will want to add `EMSCRIPTEN_BASE` to your .bashrc. > ![WARNING] diff --git a/docs/build/windows.md b/docs/build/windows.md index 3168bcd0ae0..63a77d1c41a 100644 --- a/docs/build/windows.md +++ b/docs/build/windows.md @@ -137,7 +137,7 @@ SETX KEYMAN_ROOT "c:\Projects\keyman\keyman" ``` > [!NOTE] -> The `SETX` command will set persistent environment variables but they do not +> The `SETX` command will set persistent environment variables but they do not > impact the current shell environment. Start a new shell to see the variables. > [!TIP] @@ -147,7 +147,7 @@ SETX KEYMAN_ROOT "c:\Projects\keyman\keyman" > > You can alternatively use Windows Settings to add these environment variables > permanently: -> +> > 1. In Windows Search, type "environment" and select "Edit System Environment > Variables" > 2. Click `Environment Variables...` @@ -175,6 +175,19 @@ git clone https://github.com/emscripten-core/emsdk cd emsdk emsdk install 3.1.58 emsdk activate 3.1.58 +cd upstream/emscripten +npm install +``` + +If you are updating an existing install of Emscripten: + +```bash +cd emsdk +git pull +emsdk install 3.1.58 +emsdk activate 3.1.58 +cd upstream/emscripten +npm install ``` > ![WARNING] @@ -185,7 +198,7 @@ emsdk activate 3.1.58 There is no need to add emscripten to the path in order to build Keyman. However, you should set the `EMSCRIPTEN_BASE` variable to the path where `emcc` -can be found, in the `upstream\emscripten` subdirectory of where you installed +can be found, in the `upstream\emscripten` subdirectory of where you installed emsdk. **Environment variables**: @@ -196,7 +209,7 @@ SETX EMSCRIPTEN_BASE "\upstream\emscripten" **Optional environment variables**: -To let the Keyman build scripts control the version of Emscripten +To let the Keyman build scripts control the version of Emscripten installed on your computer: ```bat @@ -259,7 +272,7 @@ of appropriate node versions during builds. ```ps1 choco install visualstudio2019community visualstudio2019-workload-nativedesktop visualstudio2019buildtools ``` - + * Verify required build tools are installed * Run `Visual Studio Installer` * Check the `Individual components` tab diff --git a/docs/linux/README.md b/docs/linux/README.md index fe29b0d623a..80c1a78434c 100644 --- a/docs/linux/README.md +++ b/docs/linux/README.md @@ -64,6 +64,10 @@ To just run the unit tests without integration tests, add the It's also possible to only run the tests for one of the subprojects. You can use `build.sh` in the subdirectory for that. +Unit tests should be named after the file/class they are testing and +follow the pattern `*.tests.` (e.g. `keymanutil.tests.c`) or +for Python `*_tests.py`. + ### ibus-keyman If you want to run the ibus-keyman tests with Wayland, you'll have to diff --git a/docs/linux/keyman-config.md b/docs/linux/keyman-config.md index 93ed3ffd8bf..1a039d0f5e0 100644 --- a/docs/linux/keyman-config.md +++ b/docs/linux/keyman-config.md @@ -200,7 +200,7 @@ LANGUAGE=de ./km-config "python.testing.unittestArgs": [ "-v", "-s", "linux/keyman-config/tests", - "-p", "test_*.py" + "-p", "*_tests.py" ], "python.testing.unittestEnabled": true, ``` diff --git a/docs/settings/linux/launch.json b/docs/settings/linux/launch.json index e29c16fa451..fec5afe0ade 100644 --- a/docs/settings/linux/launch.json +++ b/docs/settings/linux/launch.json @@ -62,7 +62,7 @@ "request": "launch", "name": "Launch ibus-keyman unit tests", "target": "./keymanutil_tests", - "cwd": "${workspaceFolder}/linux/build/x86_64/debug/src/test", + "cwd": "${workspaceFolder}/linux/build/x86_64/debug/src/tests", "valuesFormatting": "parseText", "internalConsoleOptions": "openOnSessionStart", "env": { diff --git a/docs/settings/linux/settings.json b/docs/settings/linux/settings.json index 482630bdec7..3fd13430d1b 100644 --- a/docs/settings/linux/settings.json +++ b/docs/settings/linux/settings.json @@ -5,7 +5,7 @@ "python.testing.unittestArgs": [ "-v", "-s", "linux/keyman-config/tests", - "-p", "test_*.py" + "-p", "*_tests.py" ], "python.testing.unittestEnabled": true, "python.testing.pytestEnabled": false, diff --git a/linux/.gitignore b/linux/.gitignore index f85acc0f35d..a67e991b302 100644 --- a/linux/.gitignore +++ b/linux/.gitignore @@ -31,7 +31,7 @@ debianpackage/ *.tar.xz *.tar.gz *.dsc -help/reference/ +docs/help/reference/ # Cached/auto-compiled Python bytecode *.pyc diff --git a/linux/debian/libkeymancore2.symbols b/linux/debian/libkeymancore2.symbols index a820e59c599..968f155551b 100644 --- a/linux/debian/libkeymancore2.symbols +++ b/linux/debian/libkeymancore2.symbols @@ -2,7 +2,7 @@ libkeymancore.so.2 libkeymancore2 #MINVER# * Build-Depends-Package: libkeymancore-dev (c++|optional)"typeinfo name for std::codecvt_utf8_utf16@Base" 17.0.244 - (c++|optional)std::piecewise_construct@Base 18.0.118 + (c++|optional)std::piecewise_construct@Base 18.0.145 km_core_context_clear@Base 17.0.195 km_core_context_get@Base 17.0.195 km_core_context_item_list_size@Base 17.0.195 @@ -19,7 +19,7 @@ libkeymancore.so.2 libkeymancore2 #MINVER# km_core_keyboard_imx_list_dispose@Base 17.0.195 km_core_keyboard_key_list_dispose@Base 17.0.195 km_core_keyboard_load@Base 17.0.195 - km_core_keyboard_load_from_blob@Base 18.0.123 + km_core_keyboard_load_from_blob@Base 18.0.101 km_core_options_list_size@Base 17.0.195 km_core_process_event@Base 17.0.195 km_core_process_queued_actions@Base 17.0.195 diff --git a/linux/ibus-keyman/meson.build b/linux/ibus-keyman/meson.build index 763a121245f..98281849e82 100644 --- a/linux/ibus-keyman/meson.build +++ b/linux/ibus-keyman/meson.build @@ -8,6 +8,11 @@ project('ibus-keyman', 'c', 'cpp', # meson doesn't allow us to reference a file outside its root subdir('resources') +if get_option('buildtype') != 'debug' + # Disable assertions on release builds + defns += ['-DG_DISABLE_ASSERT'] +endif + conf = configuration_data() ibus = dependency('ibus-1.0', version: '>= 1.2.0') diff --git a/linux/ibus-keyman/src/meson.build b/linux/ibus-keyman/src/meson.build index 2b436caef60..13b3caafc09 100644 --- a/linux/ibus-keyman/src/meson.build +++ b/linux/ibus-keyman/src/meson.build @@ -40,6 +40,8 @@ configure_file( exe = executable( 'ibus-engine-keyman', + c_args: defns, + cpp_args: defns, sources: [engine_files, util_files], dependencies: deps, include_directories: include_dirs, diff --git a/linux/ibus-keyman/src/test/bcp47util_tests.c b/linux/ibus-keyman/src/test/bcp47util.tests.c similarity index 100% rename from linux/ibus-keyman/src/test/bcp47util_tests.c rename to linux/ibus-keyman/src/test/bcp47util.tests.c diff --git a/linux/ibus-keyman/src/test/keymanutil_tests.c b/linux/ibus-keyman/src/test/keymanutil.tests.c similarity index 100% rename from linux/ibus-keyman/src/test/keymanutil_tests.c rename to linux/ibus-keyman/src/test/keymanutil.tests.c diff --git a/linux/ibus-keyman/src/test/meson.build b/linux/ibus-keyman/src/test/meson.build index 333f05c212a..f1f34a63c5b 100644 --- a/linux/ibus-keyman/src/test/meson.build +++ b/linux/ibus-keyman/src/test/meson.build @@ -1,5 +1,5 @@ keymanutil_sources = [ - 'keymanutil_tests.c', + 'keymanutil.tests.c', util_files, ] @@ -55,7 +55,7 @@ print_kmp_test = executable( bcp47_util_tests = executable( 'bcp47-util-tests', sources: [ - 'bcp47util_tests.c', + 'bcp47util.tests.c', '../bcp47util.c' ], dependencies: [ gtk, icu ], diff --git a/linux/ibus-keyman/tests/meson.build b/linux/ibus-keyman/tests/meson.build index 40d8b9713af..a1c51a35aee 100644 --- a/linux/ibus-keyman/tests/meson.build +++ b/linux/ibus-keyman/tests/meson.build @@ -5,6 +5,8 @@ test_files = [ '../src/KeymanSystemServiceClient.cpp', ] +common_test_files = [ meson.global_source_root() / '../../common/include/test_color.cpp' ] + keymancore_tests_lib = c_compiler.find_library( 'keymancore-tests', # meson will prefix 'lib' dirs: [ core_dir / 'build/arch' / get_option('buildtype') / 'tests/kmx_test_source' ] @@ -27,7 +29,7 @@ test_include_dirs = [ test_exe = executable( 'ibus-keyman-tests', - test_files, util_files, + test_files, util_files, common_test_files, dependencies: test_deps, include_directories: test_include_dirs, ) diff --git a/linux/keyman-config/run-tests.sh b/linux/keyman-config/run-tests.sh index de99c55e8f2..41904e4cf31 100755 --- a/linux/keyman-config/run-tests.sh +++ b/linux/keyman-config/run-tests.sh @@ -1,18 +1,18 @@ #!/bin/bash -PYTHONPATH=.:$PYTHONPATH +PYTHONPATH=.:${PYTHONPATH} XDG_CONFIG_HOME=$(mktemp --directory) export XDG_CONFIG_HOME -if [ -f /usr/libexec/ibus-memconf ]; then +if [[ -f /usr/libexec/ibus-memconf ]]; then export GSETTINGS_BACKEND=keyfile fi -if [ "$1" == "--coverage" ]; then +if [[ "$1" == "--coverage" ]]; then coverage="-m coverage run --source=. --data-file=build/.coverage" fi -if [ -n "$TEAMCITY_VERSION" ]; then +if [[ -n "${TEAMCITY_VERSION}" ]]; then if ! pip3 list --format=columns | grep -q teamcity-messages; then pip3 install teamcity-messages fi @@ -23,6 +23,6 @@ else fi # shellcheck disable=SC2086 -python3 ${coverage:-} -m ${test_module:-} discover ${extra_opts:-} -s tests -p test_*.py +python3 ${coverage:-} -m "${test_module:-}" discover ${extra_opts:-} -s tests/ -p "*_tests.py" -rm -rf "$XDG_CONFIG_HOME" +rm -rf "${XDG_CONFIG_HOME}" diff --git a/linux/keyman-config/tests/test_bcp47tag.py b/linux/keyman-config/tests/bcp47tag_tests.py similarity index 100% rename from linux/keyman-config/tests/test_bcp47tag.py rename to linux/keyman-config/tests/bcp47tag_tests.py diff --git a/linux/keyman-config/tests/test_canonical_language_code_utils.py b/linux/keyman-config/tests/canonical_language_code_utils_tests.py similarity index 100% rename from linux/keyman-config/tests/test_canonical_language_code_utils.py rename to linux/keyman-config/tests/canonical_language_code_utils_tests.py diff --git a/linux/keyman-config/tests/test_custom_keyboards.py b/linux/keyman-config/tests/custom_keyboards_tests.py similarity index 100% rename from linux/keyman-config/tests/test_custom_keyboards.py rename to linux/keyman-config/tests/custom_keyboards_tests.py diff --git a/linux/keyman-config/tests/test_dconf_util.py b/linux/keyman-config/tests/dconf_util_tests.py similarity index 100% rename from linux/keyman-config/tests/test_dconf_util.py rename to linux/keyman-config/tests/dconf_util_tests.py diff --git a/linux/keyman-config/tests/test_get_kmp.py b/linux/keyman-config/tests/get_kmp_tests.py similarity index 100% rename from linux/keyman-config/tests/test_get_kmp.py rename to linux/keyman-config/tests/get_kmp_tests.py diff --git a/linux/keyman-config/tests/test_gnome_keyboards_util.py b/linux/keyman-config/tests/gnome_keyboards_util_tests.py similarity index 100% rename from linux/keyman-config/tests/test_gnome_keyboards_util.py rename to linux/keyman-config/tests/gnome_keyboards_util_tests.py diff --git a/linux/keyman-config/tests/test_gsettings.py b/linux/keyman-config/tests/gsettings_tests.py similarity index 100% rename from linux/keyman-config/tests/test_gsettings.py rename to linux/keyman-config/tests/gsettings_tests.py diff --git a/linux/keyman-config/tests/test_handle_install.py b/linux/keyman-config/tests/handle_install_tests.py similarity index 100% rename from linux/keyman-config/tests/test_handle_install.py rename to linux/keyman-config/tests/handle_install_tests.py diff --git a/linux/keyman-config/tests/test_ibus_util.py b/linux/keyman-config/tests/ibus_util_tests.py similarity index 100% rename from linux/keyman-config/tests/test_ibus_util.py rename to linux/keyman-config/tests/ibus_util_tests.py diff --git a/linux/keyman-config/tests/test_install_kmp.py b/linux/keyman-config/tests/install_kmp_tests.py similarity index 100% rename from linux/keyman-config/tests/test_install_kmp.py rename to linux/keyman-config/tests/install_kmp_tests.py diff --git a/linux/keyman-config/tests/test_kvk2ldml.py b/linux/keyman-config/tests/kvk2ldml_tests.py similarity index 100% rename from linux/keyman-config/tests/test_kvk2ldml.py rename to linux/keyman-config/tests/kvk2ldml_tests.py diff --git a/linux/keyman-config/tests/test_lang_tags_map.py b/linux/keyman-config/tests/lang_tags_map_tests.py similarity index 100% rename from linux/keyman-config/tests/test_lang_tags_map.py rename to linux/keyman-config/tests/lang_tags_map_tests.py diff --git a/linux/keyman-config/tests/test_package_install_completion.py b/linux/keyman-config/tests/package_install_completion_tests.py similarity index 100% rename from linux/keyman-config/tests/test_package_install_completion.py rename to linux/keyman-config/tests/package_install_completion_tests.py diff --git a/linux/keyman-config/tests/test_uninstall_kmp.py b/linux/keyman-config/tests/uninstall_kmp_tests.py similarity index 100% rename from linux/keyman-config/tests/test_uninstall_kmp.py rename to linux/keyman-config/tests/uninstall_kmp_tests.py diff --git a/mac/KeymanEngine4Mac/KeymanEngine4Mac/CoreWrapper/CoreWrapper.m b/mac/KeymanEngine4Mac/KeymanEngine4Mac/CoreWrapper/CoreWrapper.m index c1cd9b81f85..ed2227f318e 100644 --- a/mac/KeymanEngine4Mac/KeymanEngine4Mac/CoreWrapper/CoreWrapper.m +++ b/mac/KeymanEngine4Mac/KeymanEngine4Mac/CoreWrapper/CoreWrapper.m @@ -110,11 +110,23 @@ -(void) dealloc{ -(void)loadKeyboardUsingCore:(NSString*) path { km_core_path_name keyboardPath = [path UTF8String]; - km_core_status result = km_core_keyboard_load(keyboardPath, &_coreKeyboard); + NSError* dataError = nil; + NSData *data = [NSData dataWithContentsOfFile:path options:0 error:&dataError]; - if (result != KM_CORE_STATUS_OK) { - NSString *message = [NSString stringWithFormat:@"Unexpected Keyman Core result: %u", result]; - [NSException raise:@"LoadKeyboardException" format:@"%@", message]; + if (dataError != nil) { + os_log_error([KMELogs coreLog], "loadKeyboardUsingCore, path: %{public}@\n dataError: %{public}@", path, dataError); + [NSException raise:@"LoadKeyboardException" format:@"%@", dataError]; + } else { + NSUInteger dataLength = data.length; + os_log_info([KMELogs coreLog], "loadKeyboardUsingCore, path: %{public}@\n dataLength: %lu", path, dataLength); + + km_core_status result = km_core_keyboard_load_from_blob(keyboardPath, + data.bytes, dataLength, &_coreKeyboard); + if (result != KM_CORE_STATUS_OK) { + NSString *message = [NSString stringWithFormat:@"Unexpected Keyman Core result: %u", result]; + os_log_error([KMELogs coreLog], "loadKeyboardUsingCore, path: %{public}@\n core result: %{public}@", path, message); + [NSException raise:@"LoadKeyboardException" format:@"%@", message]; + } } } @@ -126,7 +138,7 @@ -(void)readKeyboardAttributesUsingCore { if (result==KM_CORE_STATUS_OK) { _keyboardVersion = [self.coreHelper createNSStringFromUnicharString:keyboardAttributes->version_string]; _keyboardId = [self.coreHelper createNSStringFromUnicharString:keyboardAttributes->id]; - os_log_debug([KMELogs coreLog], "readKeyboardAttributesUsingCore, keyboardVersion: %{public}@\n, keyboardId: %{public}@\n", _keyboardVersion, _keyboardId); + os_log_debug([KMELogs coreLog], "readKeyboardAttributesUsingCore, keyboardVersion: %{public}@, keyboardId: %{public}@\n", _keyboardVersion, _keyboardId); } else { os_log_error([KMELogs coreLog], "km_core_keyboard_get_attrs() failed with result = %u\n", result); } diff --git a/oem/firstvoices/android/app/src/main/java/com/firstvoices/keyboards/SystemKeyboard.java b/oem/firstvoices/android/app/src/main/java/com/firstvoices/keyboards/SystemKeyboard.java index f047bc6c781..0e2cffd68ec 100644 --- a/oem/firstvoices/android/app/src/main/java/com/firstvoices/keyboards/SystemKeyboard.java +++ b/oem/firstvoices/android/app/src/main/java/com/firstvoices/keyboards/SystemKeyboard.java @@ -150,6 +150,10 @@ public void onStartInput(EditorInfo attribute, boolean restarting) { KMManager.setBannerOptions(mayPredict); } } + + // Determine special handling for ENTER key + KMManager.setEnterMode(attribute.imeOptions, inputType); + // User switched to a new input field so we should extract the text from input field // and pass it to Keyman Engine together with selection range InputConnection ic = getCurrentInputConnection(); diff --git a/package-lock.json b/package-lock.json index 75f9a9d1db3..808dbc52572 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7124,9 +7124,10 @@ "peer": true }, "node_modules/cross-spawn": { - "version": "7.0.3", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, - "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -8687,8 +8688,9 @@ } }, "node_modules/execa/node_modules/cross-spawn": { - "version": "6.0.5", - "license": "MIT", + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", + "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", "dependencies": { "nice-try": "^1.0.4", "path-key": "^2.0.1", diff --git a/resources/build/_builder_nvm.sh b/resources/build/_builder_nvm.sh index cccbb6b0556..a1bb9a4cc1b 100755 --- a/resources/build/_builder_nvm.sh +++ b/resources/build/_builder_nvm.sh @@ -41,8 +41,8 @@ type -t nvm >/dev/null || { } } -nvm install "$REQUIRED_NODE_VERSION" -nvm use "$REQUIRED_NODE_VERSION" +nvm use "$REQUIRED_NODE_VERSION" || \ + (nvm install "$REQUIRED_NODE_VERSION" && nvm use "$REQUIRED_NODE_VERSION") # Beware the hardcoded path below -- it should already be in the system PATH diff --git a/resources/build/build-utils-ci.inc.sh b/resources/build/build-utils-ci.inc.sh index fd9b25e52aa..a67f285254b 100644 --- a/resources/build/build-utils-ci.inc.sh +++ b/resources/build/build-utils-ci.inc.sh @@ -7,6 +7,38 @@ . "$KEYMAN_ROOT/resources/build/jq.inc.sh" +# +# Returns 0 if current build is running in CI, as a pull request test, or as a +# mainline branch test, or as a release build +# +builder_is_ci_build() { + if builder_is_ci_release_build || builder_is_ci_test_build; then + return 0 + fi + return 1 +} + +# +# Returns 0 if current build is running as a release build in CI +# +builder_is_ci_release_build() { + if [[ "$VERSION_ENVIRONMENT" =~ ^alpha|beta|stable$ ]]; then + return 0 + fi + return 1 +} + +# +# Returns 0 if current build is running in CI, as a pull request test, or as a +# mainline branch test +# +builder_is_ci_test_build() { + if [[ "$VERSION_ENVIRONMENT" == test ]]; then + return 0 + fi + return 1 +} + # # Returns 0 if current build is in CI and triggered from a pull request. If it # returns 0, then a call is made to GitHub to get pull request details, and the diff --git a/resources/build/builder.md b/resources/build/builder.md index dd52318810d..b1accd5c8a4 100644 --- a/resources/build/builder.md +++ b/resources/build/builder.md @@ -1055,6 +1055,26 @@ fi -------------------------------------------------------------------------------- +## `builder_do_typescript_tests` function + +Runs eslint, builds tests, and then runs tests with mocha + c8 (coverage) + +**Note:** this is currently hosted in shellHelperFunctions.sh, but will +be moved to builder.typescript.inc.sh in the future. + +### Usage + +```bash +builder_run_action test builder_do_typescript_tests [coverage_threshold] +``` + +### Parameters + +* **coverage_threshold** optional, minimum coverage for c8 to pass tests, + defaults to 90 (percent) + +-------------------------------------------------------------------------------- + ## Formatting variables These helper variables define ANSI color escapes when running in color mode, and diff --git a/resources/build/meson/standard.meson.build b/resources/build/meson/standard.meson.build index 87efed5ab55..d039080172c 100644 --- a/resources/build/meson/standard.meson.build +++ b/resources/build/meson/standard.meson.build @@ -84,3 +84,10 @@ if cpp_compiler.get_id() == 'emscripten' links += ['-O2'] endif endif + +# Disable assertions on release builds +if get_option('buildtype') != 'debug' + defns += [ + '-DNDEBUG' + ] +endif diff --git a/resources/locate_emscripten.inc.sh b/resources/locate_emscripten.inc.sh index 1d185f55525..57ed0cd559b 100644 --- a/resources/locate_emscripten.inc.sh +++ b/resources/locate_emscripten.inc.sh @@ -66,10 +66,20 @@ _select_emscripten_version_with_emsdk() { fi export EMSDK_KEEP_DOWNLOADS=1 - git pull - ./emsdk install "$KEYMAN_MIN_VERSION_EMSCRIPTEN" - ./emsdk activate "$KEYMAN_MIN_VERSION_EMSCRIPTEN" - cd upstream/emscripten - npm install + if builder_try_offline; then + if [[ ! -f ./emsdk_env.sh ]]; then + builder_die "emsdk_env.sh not found - emsdk not installed?" + fi + . ./emsdk_env.sh + if ! emcc --version | grep -q "$KEYMAN_MIN_VERSION_EMSCRIPTEN"; then + builder_die "Wrong emsdk version installed" + fi + else + git pull + ./emsdk install "$KEYMAN_MIN_VERSION_EMSCRIPTEN" + ./emsdk activate "$KEYMAN_MIN_VERSION_EMSCRIPTEN" + cd upstream/emscripten + npm install + fi popd > /dev/null } diff --git a/resources/shellHelperFunctions.sh b/resources/shellHelperFunctions.sh index 6f8e1b52681..eaa369b0304 100755 --- a/resources/shellHelperFunctions.sh +++ b/resources/shellHelperFunctions.sh @@ -304,4 +304,42 @@ _select_node_version_with_nvm() { check-markdown() { node "$KEYMAN_ROOT/resources/tools/check-markdown" --root "$1" +} + +# +# Runs eslint, builds tests, and then runs tests with mocha + c8 (coverage) +# +# Usage: +# builder_run_action test builder_do_typescript_tests [coverage_threshold] +# Parameters: +# 1: coverage_threshold optional, minimum coverage for c8 to pass tests, +# defaults to 90 (percent) +# +# Todo: +# Move to builder.typescript.inc.sh when this is established +# +builder_do_typescript_tests() { + local MOCHA_FLAGS= + + if [[ "${TEAMCITY_GIT_PATH:-}" != "" ]]; then + # we're running in TeamCity + MOCHA_FLAGS="-reporter mocha-teamcity-reporter" + fi + + eslint . + tsc --build test/ + + local THRESHOLD_PARAMS= + local C8_THRESHOLD= + if [[ $# -gt 0 ]]; then + C8_THRESHOLD=$1 + THRESHOLD_PARAMS="--lines $C8_THRESHOLD --statements $C8_THRESHOLD --branches $C8_THRESHOLD --functions $C8_THRESHOLD" + fi + + c8 --reporter=lcov --reporter=text --exclude-after-remap --check-coverage=false $THRESHOLD_PARAMS mocha ${MOCHA_FLAGS} "${builder_extra_params[@]}" + + if [[ ! -z "$C8_THRESHOLD" ]]; then + builder_echo warning "Coverage thresholds are currently $C8_THRESHOLD%, which is lower than ideal." + builder_echo warning "Please increase threshold in build.sh as test coverage improves." + fi } \ No newline at end of file diff --git a/web/build.sh b/web/build.sh index 5c67d868e0b..1fb06436e33 100755 --- a/web/build.sh +++ b/web/build.sh @@ -57,7 +57,7 @@ fi builder_describe_outputs \ configure "/node_modules" \ - build "/web/build/test/dom/cases/attachment/outputTargetForElement.spec.html" \ + build "/web/build/test/dom/cases/attachment/outputTargetForElement.tests.html" \ build:app/browser "/web/build/app/browser/lib/index.mjs" \ build:app/webview "/web/build/app/webview/${config}/keymanweb-webview.js" \ build:app/ui "/web/build/app/ui/${config}/kmwuitoggle.js" \ @@ -130,7 +130,7 @@ build_action() { precompile "${dir}" done - cp "${KEYMAN_ROOT}/web/src/test/auto/dom/cases/attachment/outputTargetForElement.spec.html" \ + cp "${KEYMAN_ROOT}/web/src/test/auto/dom/cases/attachment/outputTargetForElement.tests.html" \ "${KEYMAN_ROOT}/web/build/test/dom/cases/attachment/" } diff --git a/web/src/app/webview/src/configuration.ts b/web/src/app/webview/src/configuration.ts index aa48301caed..d5b7079e6da 100644 --- a/web/src/app/webview/src/configuration.ts +++ b/web/src/app/webview/src/configuration.ts @@ -3,14 +3,14 @@ import { EngineConfiguration, InitOptionSpec, InitOptionDefaults } from "keyman/ import { buildMergedTransform } from '@keymanapp/models-templates'; import { type OnInsertTextFunc } from "./contextManager.js"; -import { Transform } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; export class WebviewConfiguration extends EngineConfiguration { private _embeddingApp: string; private _oninserttext: OnInsertTextFunc; private _hostInsert: OnInsertTextFunc; - private pendingInserts: Transform[] = []; + private pendingInserts: LexicalModelTypes.Transform[] = []; initialize(options: Required) { super.initialize(options); diff --git a/web/src/app/webview/src/contextManager.ts b/web/src/app/webview/src/contextManager.ts index ca3be54eca2..4507f44f551 100644 --- a/web/src/app/webview/src/contextManager.ts +++ b/web/src/app/webview/src/contextManager.ts @@ -3,7 +3,7 @@ import { Mock, OutputTarget, Transcription, findCommonSubstringEndIndex, isEmpty import { KeyboardStub } from 'keyman/engine/keyboard-storage'; import { ContextManagerBase } from 'keyman/engine/main'; import { WebviewConfiguration } from './configuration.js'; -import { Transform } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; export type OnInsertTextFunc = (deleteLeft: number, text: string, deleteRight: number) => void; @@ -17,7 +17,7 @@ export class ContextHost extends Mock { this.saveState(); } - apply(transform: Transform): void { + apply(transform: LexicalModelTypes.Transform): void { super.apply(transform); this.updateHost(); } diff --git a/web/src/engine/common/web-utils/.c8rc.json b/web/src/engine/common/web-utils/.c8rc.json index d9074b62f31..16a4e93b9c0 100644 --- a/web/src/engine/common/web-utils/.c8rc.json +++ b/web/src/engine/common/web-utils/.c8rc.json @@ -6,7 +6,7 @@ "src/deviceSpec.ts", "src/globalObject.ts", "node_modules/*", - "src/test" + "src/tests/*" ], "exclude-after-remap": true, "reporter": ["text", "text-summary"], diff --git a/web/src/engine/common/web-utils/.gitignore b/web/src/engine/common/web-utils/.gitignore index a9e0c255148..56baafc8225 100644 --- a/web/src/engine/common/web-utils/.gitignore +++ b/web/src/engine/common/web-utils/.gitignore @@ -11,7 +11,6 @@ dist/ # Other local files. node_modules/ -unit_tests/modernizr.js source/environment.inc.ts **/.idea/**/*.xml **/*.iml diff --git a/web/src/engine/common/web-utils/build.sh b/web/src/engine/common/web-utils/build.sh index 303bd2664b0..ac18e2984cf 100755 --- a/web/src/engine/common/web-utils/build.sh +++ b/web/src/engine/common/web-utils/build.sh @@ -54,7 +54,7 @@ function do_test() { FLAGS="$FLAGS --reporter mocha-teamcity-reporter" fi - c8 mocha --recursive $FLAGS ./src/test/ + c8 mocha --recursive $FLAGS ./src/tests/ } builder_run_action configure verify_npm_setup diff --git a/web/src/engine/common/web-utils/src/test/deepCopy.js b/web/src/engine/common/web-utils/src/tests/deepCopy.tests.js similarity index 100% rename from web/src/engine/common/web-utils/src/test/deepCopy.js rename to web/src/engine/common/web-utils/src/tests/deepCopy.tests.js diff --git a/web/src/engine/common/web-utils/src/test/managedPromise.js b/web/src/engine/common/web-utils/src/tests/managedPromise.tests.js similarity index 100% rename from web/src/engine/common/web-utils/src/test/managedPromise.js rename to web/src/engine/common/web-utils/src/tests/managedPromise.tests.js diff --git a/web/src/engine/common/web-utils/src/test/priorityQueue.js b/web/src/engine/common/web-utils/src/tests/priorityQueue.tests.js similarity index 100% rename from web/src/engine/common/web-utils/src/test/priorityQueue.js rename to web/src/engine/common/web-utils/src/tests/priorityQueue.tests.js diff --git a/web/src/engine/common/web-utils/src/test/timeoutPromise.js b/web/src/engine/common/web-utils/src/tests/timeoutPromise.tests.js similarity index 100% rename from web/src/engine/common/web-utils/src/test/timeoutPromise.js rename to web/src/engine/common/web-utils/src/tests/timeoutPromise.tests.js diff --git a/web/src/engine/common/web-utils/src/test/versions.js b/web/src/engine/common/web-utils/src/tests/versions.tests.js similarity index 100% rename from web/src/engine/common/web-utils/src/test/versions.js rename to web/src/engine/common/web-utils/src/tests/versions.tests.js diff --git a/web/src/engine/common/web-utils/tsconfig.json b/web/src/engine/common/web-utils/tsconfig.json index a4d2e57702d..1747a622743 100644 --- a/web/src/engine/common/web-utils/tsconfig.json +++ b/web/src/engine/common/web-utils/tsconfig.json @@ -13,6 +13,6 @@ "src/*.ts" ], "exclude": [ - "src/test/**/*.js" + "src/tests/**/*.js" ] } diff --git a/web/src/engine/interfaces/src/prediction/languageProcessor.interface.ts b/web/src/engine/interfaces/src/prediction/languageProcessor.interface.ts index 303fa99fc3d..b26125982e4 100644 --- a/web/src/engine/interfaces/src/prediction/languageProcessor.interface.ts +++ b/web/src/engine/interfaces/src/prediction/languageProcessor.interface.ts @@ -1,12 +1,12 @@ -import { Suggestion, Reversion } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; import { EventEmitter } from "eventemitter3"; import { OutputTarget } from "keyman/engine/keyboard"; export class ReadySuggestions { - suggestions: Suggestion[]; + suggestions: LexicalModelTypes.Suggestion[]; transcriptionID: number; - constructor(suggestions: Suggestion[], id: number) { + constructor(suggestions: LexicalModelTypes.Suggestion[], id: number) { this.suggestions = suggestions; this.transcriptionID = id; } @@ -56,7 +56,7 @@ export interface LanguageProcessorSpec extends EventEmitter; + invalidateContext(outputTarget: OutputTarget, layerId: string): Promise; /** * @@ -66,9 +66,9 @@ export interface LanguageProcessorSpec extends EventEmitter string): Promise; + applySuggestion(suggestion: LexicalModelTypes.Suggestion, outputTarget: OutputTarget, getLayerId: () => string): Promise; - applyReversion(reversion: Reversion, outputTarget: OutputTarget): Promise; + applyReversion(reversion: LexicalModelTypes.Reversion, outputTarget: OutputTarget): Promise; get wordbreaksAfterSuggestions(): boolean; } diff --git a/web/src/engine/interfaces/src/prediction/predictionContext.ts b/web/src/engine/interfaces/src/prediction/predictionContext.ts index 758ef8f46b2..b131752d96d 100644 --- a/web/src/engine/interfaces/src/prediction/predictionContext.ts +++ b/web/src/engine/interfaces/src/prediction/predictionContext.ts @@ -1,5 +1,8 @@ import { EventEmitter } from "eventemitter3"; -import { Keep, Reversion, Suggestion } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; +import Keep = LexicalModelTypes.Keep; +import Reversion = LexicalModelTypes.Reversion; +import Suggestion = LexicalModelTypes.Suggestion; import { type LanguageProcessorSpec , ReadySuggestions, type InvalidateSourceEnum, StateChangeHandler } from './languageProcessor.interface.js'; import { type OutputTarget } from "keyman/engine/keyboard"; diff --git a/web/src/engine/js-processor/src/outputTarget.ts b/web/src/engine/js-processor/src/outputTarget.ts index c055e47602e..4b6aac6af67 100644 --- a/web/src/engine/js-processor/src/outputTarget.ts +++ b/web/src/engine/js-processor/src/outputTarget.ts @@ -8,18 +8,18 @@ extendString(); // Defines deadkey management in a manner attachable to each element interface. import { type KeyEvent } from 'keyman/engine/keyboard'; import { Deadkey, DeadkeyTracker } from "./deadkeys.js"; -import { ProbabilityMass, Transform } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; // Also relies on string-extensions provided by the web-utils package. -export function isEmptyTransform(transform: Transform) { +export function isEmptyTransform(transform: LexicalModelTypes.Transform) { if(!transform) { return true; } return transform.insert === '' && transform.deleteLeft === 0 && (transform.deleteRight ?? 0) === 0; } -export class TextTransform implements Transform { +export class TextTransform implements LexicalModelTypes.Transform { readonly insert: string; readonly deleteLeft: number; readonly deleteRight: number; @@ -64,7 +64,7 @@ export class Transcription { } } -export type Alternate = ProbabilityMass; +export type Alternate = LexicalModelTypes.ProbabilityMass; export default abstract class OutputTarget implements OutputTargetInterface { private _dks: DeadkeyTracker; @@ -173,7 +173,7 @@ export default abstract class OutputTarget implements OutputTargetInterface { this._dks = original._dks.clone(); } - apply(transform: Transform) { + apply(transform: LexicalModelTypes.Transform) { // Selected text should disappear on any text edit; application of a transform // certainly qualifies. this.clearSelection(); diff --git a/web/src/engine/js-processor/src/ruleBehavior.ts b/web/src/engine/js-processor/src/ruleBehavior.ts index 29234506221..fd736f0fd82 100644 --- a/web/src/engine/js-processor/src/ruleBehavior.ts +++ b/web/src/engine/js-processor/src/ruleBehavior.ts @@ -3,7 +3,7 @@ import { VariableStoreDictionary } from "keyman/engine/keyboard"; import OutputTarget, { type Transcription } from './outputTarget.js'; import { Mock } from "./mock.js"; import { type VariableStore } from "./systemStores.js"; -import { Suggestion } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; /** * Represents the commands and state changes that result from a matched keyboard rule. @@ -53,7 +53,7 @@ export default class RuleBehavior { /** * If predictive text is active, contains a Promise returning predictive Suggestions. */ - predictionPromise?: Promise; + predictionPromise?: Promise; /** * In reference to https://github.com/keymanapp/keyman/pull/4350#issuecomment-768753852: diff --git a/web/src/engine/main/src/headless/contextWindow.ts b/web/src/engine/main/src/headless/contextWindow.ts index fd8385f45ef..85baa603bd6 100644 --- a/web/src/engine/main/src/headless/contextWindow.ts +++ b/web/src/engine/main/src/headless/contextWindow.ts @@ -1,10 +1,10 @@ -import { CasingForm, Configuration, Context } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; import { Mock } from "keyman/engine/js-processor"; -export default class ContextWindow implements Context { +export default class ContextWindow implements LexicalModelTypes.Context { // Used to limit the range of context replicated for use of keyboard rules within // the engine, as used for fat-finger prep / `Alternate` generation. - public static readonly ENGINE_RULE_WINDOW: Configuration = { + public static readonly ENGINE_RULE_WINDOW: LexicalModelTypes.Configuration = { leftContextCodePoints: 64, rightContextCodePoints: 32 }; @@ -15,9 +15,9 @@ export default class ContextWindow implements Context { startOfBuffer: boolean; endOfBuffer: boolean; - casingForm?: CasingForm; + casingForm?: LexicalModelTypes.CasingForm; - constructor(mock: Mock, config: Configuration, layerId: string) { + constructor(mock: Mock, config: LexicalModelTypes.Configuration, layerId: string) { this.left = mock.getTextBeforeCaret(); this.startOfBuffer = this.left._kmwLength() <= config.leftContextCodePoints; if(!this.startOfBuffer) { diff --git a/web/src/engine/main/src/headless/inputProcessor.ts b/web/src/engine/main/src/headless/inputProcessor.ts index 2b3a992390f..c367405af95 100644 --- a/web/src/engine/main/src/headless/inputProcessor.ts +++ b/web/src/engine/main/src/headless/inputProcessor.ts @@ -20,7 +20,7 @@ import { } from 'keyman/engine/js-processor'; import { TranscriptionCache } from "./transcriptionCache.js"; -import { Transform } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; export class InputProcessor { public static readonly DEFAULT_OPTIONS: ProcessorInitOptions = { @@ -362,7 +362,7 @@ export class InputProcessor { // // Also possible that this set of conditions fail for all evaluated alternates. if(alternateBehavior && !alternateBehavior.beep && pair.p > 0) { - let transform: Transform = alternateBehavior.transcription.transform; + let transform: LexicalModelTypes.Transform = alternateBehavior.transcription.transform; // Ensure that the alternate's token id matches that of the current keystroke, as we only // record the matched rule's context (since they match) diff --git a/web/src/engine/main/src/headless/languageProcessor.ts b/web/src/engine/main/src/headless/languageProcessor.ts index ed82943565b..9cb73def58d 100644 --- a/web/src/engine/main/src/headless/languageProcessor.ts +++ b/web/src/engine/main/src/headless/languageProcessor.ts @@ -4,7 +4,11 @@ import { OutputTarget, Transcription, Mock } from "keyman/engine/js-processor"; import { LanguageProcessorEventMap, ModelSpec, StateChangeEnum, ReadySuggestions } from 'keyman/engine/interfaces'; import ContextWindow from "./contextWindow.js"; import { TranscriptionCache } from "./transcriptionCache.js"; -import { Capabilities, Configuration, Reversion, Suggestion } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; +import Capabilities = LexicalModelTypes.Capabilities; +import Configuration = LexicalModelTypes.Configuration; +import Reversion = LexicalModelTypes.Reversion; +import Suggestion = LexicalModelTypes.Suggestion; /* Is more like the model configuration engine */ export class LanguageProcessor extends EventEmitter { diff --git a/web/src/engine/osk/src/banner/suggestionBanner.ts b/web/src/engine/osk/src/banner/suggestionBanner.ts index f32cbdacd24..0c4ccb420a7 100644 --- a/web/src/engine/osk/src/banner/suggestionBanner.ts +++ b/web/src/engine/osk/src/banner/suggestionBanner.ts @@ -19,7 +19,7 @@ import { ParsedLengthStyle } from '../lengthStyle.js'; import { getFontSizeStyle } from '../fontSizeUtils.js'; import { getTextMetrics } from '../keyboard-layout/getTextMetrics.js'; import { BannerScrollState } from './bannerScrollState.js'; -import { Suggestion } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; const TOUCHED_CLASS: string = 'kmw-suggest-touched'; const BANNER_SCROLLER_CLASS = 'kmw-suggest-banner-scroller'; @@ -82,7 +82,7 @@ export class BannerSuggestion { public readonly rtl: boolean; - private _suggestion: Suggestion; + private _suggestion: LexicalModelTypes.Suggestion; private index: number; @@ -142,18 +142,18 @@ export class BannerSuggestion { } } - get suggestion(): Suggestion { + get suggestion(): LexicalModelTypes.Suggestion { return this._suggestion; } /** * Function update - * @param {Suggestion} suggestion Suggestion from the lexical model + * @param {LexicalModelTypes.Suggestion} suggestion Suggestion from the lexical model * @param {BannerSuggestionFormatSpec} format Formatting metadata to use for the Suggestion * * Update the ID and text of the BannerSuggestionSpec */ - public update(suggestion: Suggestion, format: BannerSuggestionFormatSpec) { + public update(suggestion: LexicalModelTypes.Suggestion, format: BannerSuggestionFormatSpec) { this._suggestion = suggestion; let display = this.generateSuggestionText(this.rtl); @@ -384,7 +384,7 @@ export class SuggestionBanner extends Banner { public readonly type = "suggestion"; - private currentSuggestions: Suggestion[] = []; + private currentSuggestions: LexicalModelTypes.Suggestion[] = []; private options : BannerSuggestion[] = []; private separators: HTMLElement[] = []; @@ -715,7 +715,7 @@ export class SuggestionBanner extends Banner { * suggestions, including optimization of the banner's layout. * @param suggestions */ - public onSuggestionUpdate = (suggestions: Suggestion[]): void => { + public onSuggestionUpdate = (suggestions: LexicalModelTypes.Suggestion[]): void => { this.currentSuggestions = suggestions; // Immediately stop all animations and reset options accordingly. this.highlightAnimation?.cancel(); diff --git a/web/src/engine/predictive-text/templates/.c8rc.json b/web/src/engine/predictive-text/templates/.c8rc.json index deaa1318eb2..d107a1cacb1 100644 --- a/web/src/engine/predictive-text/templates/.c8rc.json +++ b/web/src/engine/predictive-text/templates/.c8rc.json @@ -3,7 +3,7 @@ "clean": true, "exclude": [ "node_modules/**", - "test/**" + "tests/**" ], "exclude-after-remap": true, "reporter": ["text", "text-summary"], diff --git a/web/src/engine/predictive-text/templates/build.sh b/web/src/engine/predictive-text/templates/build.sh index e7aaaac1249..bf236229982 100755 --- a/web/src/engine/predictive-text/templates/build.sh +++ b/web/src/engine/predictive-text/templates/build.sh @@ -42,7 +42,7 @@ function do_test() { FLAGS="-reporter mocha-teamcity-reporter" fi - c8 mocha $FLAGS --require test/helpers.js --recursive test + c8 mocha $FLAGS --require tests/helpers.js --recursive tests } builder_run_action configure verify_npm_setup diff --git a/web/src/engine/predictive-text/templates/package.json b/web/src/engine/predictive-text/templates/package.json index c976bcdbe39..7b6604f7736 100644 --- a/web/src/engine/predictive-text/templates/package.json +++ b/web/src/engine/predictive-text/templates/package.json @@ -31,7 +31,7 @@ "type": "module", "directories": { - "test": "test" + "test": "tests" }, "files": [ "index.js" diff --git a/web/src/engine/predictive-text/templates/src/common.ts b/web/src/engine/predictive-text/templates/src/common.ts index 2524ac40fbd..5e1134dd8af 100644 --- a/web/src/engine/predictive-text/templates/src/common.ts +++ b/web/src/engine/predictive-text/templates/src/common.ts @@ -1,5 +1,11 @@ // Allows the kmwstring bindings to resolve. -import { CasingForm, Context, Outcome, Suggestion, Transform, WithOutcome } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; +import CasingForm = LexicalModelTypes.CasingForm; +import Context = LexicalModelTypes.Context; +import Outcome = LexicalModelTypes.Outcome; +import Suggestion = LexicalModelTypes.Suggestion; +import Transform = LexicalModelTypes.Transform; +import WithOutcome = LexicalModelTypes.WithOutcome; import { extendString } from "@keymanapp/web-utils"; extendString(); diff --git a/web/src/engine/predictive-text/templates/src/quote-behavior.ts b/web/src/engine/predictive-text/templates/src/quote-behavior.ts index cbf1a869f4a..25a886feef3 100644 --- a/web/src/engine/predictive-text/templates/src/quote-behavior.ts +++ b/web/src/engine/predictive-text/templates/src/quote-behavior.ts @@ -1,4 +1,4 @@ -import { LexicalModelPunctuation } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; export enum QuoteBehavior { noQuotes = "no-quotes", @@ -14,7 +14,7 @@ export namespace QuoteBehavior { * @param punctuation The active `LexicalModelPunctuation` settings * @param defaultTo The default quote behavior to use (in case the current value is `.default`) */ - export function apply(behavior: QuoteBehavior, text: string, punctuation: LexicalModelPunctuation, defaultTo: QuoteBehavior): string { + export function apply(behavior: QuoteBehavior, text: string, punctuation: LexicalModelTypes.LexicalModelPunctuation, defaultTo: QuoteBehavior): string { if(defaultTo == QuoteBehavior.default || !defaultTo) { throw "Specified quote behavior may be ambiguous - default behavior not specified (may not be .default)"; } diff --git a/web/src/engine/predictive-text/templates/src/tokenization.ts b/web/src/engine/predictive-text/templates/src/tokenization.ts index c5a1ac69cdf..a9bd03c5d3f 100644 --- a/web/src/engine/predictive-text/templates/src/tokenization.ts +++ b/web/src/engine/predictive-text/templates/src/tokenization.ts @@ -1,7 +1,7 @@ // While we _could_ define this within @keymanapp/models-wordbreakers instead, it's probably // better to leave that package as _just_ the wordbreakers. -import { WordBreakingFunction, USVString, Context } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; export interface Token { text: string, @@ -30,8 +30,8 @@ export interface Tokenization { } export function tokenize( - wordBreaker: WordBreakingFunction, - context: Partial, + wordBreaker: LexicalModelTypes.WordBreakingFunction, + context: Partial, options?: { /** Characters to rejoin to preceding tokens if found immediately pre-caret. */ rejoins?: string[] @@ -197,7 +197,7 @@ export function tokenize( * If the last 'token' before the caret is whitespace, returns `''`. * @param fullLeftContext the entire left context of the string. */ -export function getLastPreCaretToken(wordBreaker: WordBreakingFunction, context: Context): string { +export function getLastPreCaretToken(wordBreaker: LexicalModelTypes.WordBreakingFunction, context: LexicalModelTypes.Context): string { let tokenization = tokenize(wordBreaker, context); if (tokenization.left.length > 0) { const lastToken = tokenization.left.pop(); @@ -214,6 +214,6 @@ export function getLastPreCaretToken(wordBreaker: WordBreakingFunction, context: // While it is currently identical to getLastWord, this may change in the future. // It's best not to write ourselves into a corner on this one, as disambiguating later // would likely be pretty painful. -export function wordbreak(wordBreaker: WordBreakingFunction, context: Context): USVString { +export function wordbreak(wordBreaker: LexicalModelTypes.WordBreakingFunction, context: LexicalModelTypes.Context): LexicalModelTypes.USVString { return getLastPreCaretToken(wordBreaker, context); } diff --git a/web/src/engine/predictive-text/templates/src/trie-model.ts b/web/src/engine/predictive-text/templates/src/trie-model.ts index 527b7a36cbb..2c5e6a194e3 100644 --- a/web/src/engine/predictive-text/templates/src/trie-model.ts +++ b/web/src/engine/predictive-text/templates/src/trie-model.ts @@ -31,7 +31,21 @@ import { default as defaultWordBreaker } from "@keymanapp/models-wordbreakers"; import { applyTransform, isHighSurrogate, isSentinel, SENTINEL_CODE_UNIT, transformToSuggestion } from "./common.js"; import { getLastPreCaretToken } from "./tokenization.js"; -import { Capabilities, CasingFunction, Configuration, Context, Distribution, LexicalModel, LexicalModelPunctuation, LexiconTraversal, Suggestion, TextWithProbability, Transform, USVString, WithOutcome, WordBreakingFunction } from '@keymanapp/common-types'; +import { LexicalModelTypes } from "@keymanapp/common-types"; +import Capabilities = LexicalModelTypes.Capabilities; +import CasingFunction = LexicalModelTypes.CasingFunction; +import Configuration = LexicalModelTypes.Configuration; +import Context = LexicalModelTypes.Context; +import Distribution = LexicalModelTypes.Distribution; +import LexicalModel = LexicalModelTypes.LexicalModel; +import LexicalModelPunctuation = LexicalModelTypes.LexicalModelPunctuation; +import LexiconTraversal = LexicalModelTypes.LexiconTraversal; +import Suggestion = LexicalModelTypes.Suggestion; +import TextWithProbability = LexicalModelTypes.TextWithProbability; +import Transform = LexicalModelTypes.Transform; +import USVString = LexicalModelTypes.USVString; +import WithOutcome = LexicalModelTypes.WithOutcome; +import WordBreakingFunction = LexicalModelTypes.WordBreakingFunction; extendString(); diff --git a/web/src/engine/predictive-text/templates/test/test-common.js b/web/src/engine/predictive-text/templates/tests/common.tests.js similarity index 100% rename from web/src/engine/predictive-text/templates/test/test-common.js rename to web/src/engine/predictive-text/templates/tests/common.tests.js diff --git a/web/src/engine/predictive-text/templates/test/custom-breakers.def.js b/web/src/engine/predictive-text/templates/tests/custom-breakers.def.js similarity index 100% rename from web/src/engine/predictive-text/templates/test/custom-breakers.def.js rename to web/src/engine/predictive-text/templates/tests/custom-breakers.def.js diff --git a/web/src/engine/predictive-text/templates/test/fixtures/tries/accented.json b/web/src/engine/predictive-text/templates/tests/fixtures/tries/accented.json similarity index 100% rename from web/src/engine/predictive-text/templates/test/fixtures/tries/accented.json rename to web/src/engine/predictive-text/templates/tests/fixtures/tries/accented.json diff --git a/web/src/engine/predictive-text/templates/test/fixtures/tries/english-1000.json b/web/src/engine/predictive-text/templates/tests/fixtures/tries/english-1000.json similarity index 100% rename from web/src/engine/predictive-text/templates/test/fixtures/tries/english-1000.json rename to web/src/engine/predictive-text/templates/tests/fixtures/tries/english-1000.json diff --git a/web/src/engine/predictive-text/templates/test/fixtures/tries/smp-apple.json b/web/src/engine/predictive-text/templates/tests/fixtures/tries/smp-apple.json similarity index 100% rename from web/src/engine/predictive-text/templates/test/fixtures/tries/smp-apple.json rename to web/src/engine/predictive-text/templates/tests/fixtures/tries/smp-apple.json diff --git a/web/src/engine/predictive-text/templates/test/helpers.js b/web/src/engine/predictive-text/templates/tests/helpers.js similarity index 100% rename from web/src/engine/predictive-text/templates/test/helpers.js rename to web/src/engine/predictive-text/templates/tests/helpers.js diff --git a/web/src/engine/predictive-text/templates/test/test-quote-behavior.js b/web/src/engine/predictive-text/templates/tests/quote-behavior.tests.js similarity index 100% rename from web/src/engine/predictive-text/templates/test/test-quote-behavior.js rename to web/src/engine/predictive-text/templates/tests/quote-behavior.tests.js diff --git a/web/src/engine/predictive-text/templates/test/test-tokenization.js b/web/src/engine/predictive-text/templates/tests/tokenization.tests.js similarity index 100% rename from web/src/engine/predictive-text/templates/test/test-tokenization.js rename to web/src/engine/predictive-text/templates/tests/tokenization.tests.js diff --git a/web/src/engine/predictive-text/templates/test/test-trie-model.js b/web/src/engine/predictive-text/templates/tests/trie-model.tests.js similarity index 100% rename from web/src/engine/predictive-text/templates/test/test-trie-model.js rename to web/src/engine/predictive-text/templates/tests/trie-model.tests.js diff --git a/web/src/engine/predictive-text/templates/test/test-trie-traversal.js b/web/src/engine/predictive-text/templates/tests/trie-traversal.tests.js similarity index 100% rename from web/src/engine/predictive-text/templates/test/test-trie-traversal.js rename to web/src/engine/predictive-text/templates/tests/trie-traversal.tests.js diff --git a/web/src/engine/predictive-text/templates/tsconfig.json b/web/src/engine/predictive-text/templates/tsconfig.json index e8217e9ad9d..176530290da 100644 --- a/web/src/engine/predictive-text/templates/tsconfig.json +++ b/web/src/engine/predictive-text/templates/tsconfig.json @@ -16,6 +16,6 @@ "src/**/*.ts" ], "exclude": [ - "test" + "tests" ] } diff --git a/web/src/engine/predictive-text/types/message.d.ts b/web/src/engine/predictive-text/types/message.d.ts index c20bcc29e80..a0ca7c9cb7a 100644 --- a/web/src/engine/predictive-text/types/message.d.ts +++ b/web/src/engine/predictive-text/types/message.d.ts @@ -20,7 +20,11 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import { Configuration, Reversion, Suggestion, USVString } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; +import Configuration = LexicalModelTypes.Configuration; +import Reversion = LexicalModelTypes.Reversion; +import Suggestion = LexicalModelTypes.Suggestion; +import USVString = LexicalModelTypes.USVString; /** * Tokens are signed 31-bit integers! diff --git a/web/src/engine/predictive-text/wordbreakers/.c8rc.json b/web/src/engine/predictive-text/wordbreakers/.c8rc.json index e1de5a59991..6a0e2589da1 100644 --- a/web/src/engine/predictive-text/wordbreakers/.c8rc.json +++ b/web/src/engine/predictive-text/wordbreakers/.c8rc.json @@ -3,7 +3,7 @@ "clean": true, "exclude": [ "node_modules/*", - "test" + "tests" ], "exclude-after-remap": true, "reporter": ["text", "text-summary"], diff --git a/web/src/engine/predictive-text/wordbreakers/build.sh b/web/src/engine/predictive-text/wordbreakers/build.sh index 4591cc34e13..6505dfdd4f5 100755 --- a/web/src/engine/predictive-text/wordbreakers/build.sh +++ b/web/src/engine/predictive-text/wordbreakers/build.sh @@ -45,11 +45,13 @@ function do_build() { } function do_test() { + local FLAGS= + if builder_has_option --ci; then - c8 mocha -reporter mocha-teamcity-reporter - else - c8 mocha + FLAGS="-reporter mocha-teamcity-reporter" fi + + c8 mocha ${FLAGS} tests } builder_run_action configure do_configure diff --git a/web/src/engine/predictive-text/wordbreakers/package.json b/web/src/engine/predictive-text/wordbreakers/package.json index 5ac5fd4a28f..89c0469f303 100644 --- a/web/src/engine/predictive-text/wordbreakers/package.json +++ b/web/src/engine/predictive-text/wordbreakers/package.json @@ -34,7 +34,7 @@ }, "directories": { "lib": "lib", - "test": "test" + "test": "tests" }, "files": [ "lib" diff --git a/web/src/engine/predictive-text/wordbreakers/src/main/ascii.ts b/web/src/engine/predictive-text/wordbreakers/src/main/ascii.ts index 1b3a91a1459..7ed05e331f4 100644 --- a/web/src/engine/predictive-text/wordbreakers/src/main/ascii.ts +++ b/web/src/engine/predictive-text/wordbreakers/src/main/ascii.ts @@ -1,13 +1,13 @@ -import { Span } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; /** * Splits ASCII words. * * @param phrase */ -export default function ascii(phrase: string): Span[] { +export default function ascii(phrase: string): LexicalModelTypes.Span[] { let matchWord = /[A-Za-z0-9']+/g; - let words: Span[] = []; + let words: LexicalModelTypes.Span[] = []; let match: RegExpExecArray | null; while ((match = matchWord.exec(phrase)) !== null) { words.push(new RegExpDerivedSpan(match[0], match.index)); @@ -20,7 +20,7 @@ export default function ascii(phrase: string): Span[] { * A concrete span class that derives its properties from the result of * RegExp.exec() array. */ -class RegExpDerivedSpan implements Span { +class RegExpDerivedSpan implements LexicalModelTypes.Span { readonly text: string; readonly start: number; diff --git a/web/src/engine/predictive-text/wordbreakers/src/main/default/index.ts b/web/src/engine/predictive-text/wordbreakers/src/main/default/index.ts index bebed01cc44..390ba9806ac 100644 --- a/web/src/engine/predictive-text/wordbreakers/src/main/default/index.ts +++ b/web/src/engine/predictive-text/wordbreakers/src/main/default/index.ts @@ -1,4 +1,4 @@ -import { Span } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; import { WordBreakProperty, propertyMap } from "./data.inc.js"; import { searchForProperty } from "./searchForProperty.js"; @@ -38,7 +38,7 @@ export interface DefaultWordBreakerOptions { * @see http://unicode.org/reports/tr29/#Word_Boundaries * @see https://github.com/eddieantonio/unicode-default-word-boundary/tree/v12.0.0 */ -export default function default_(text: string, options?: DefaultWordBreakerOptions): Span[] { +export default function default_(text: string, options?: DefaultWordBreakerOptions): LexicalModelTypes.Span[] { let boundaries = findBoundaries(text, options); if (boundaries.length == 0) { return []; @@ -67,7 +67,7 @@ export default function default_(text: string, options?: DefaultWordBreakerOptio /** * A span that does not cut out the substring until it absolutely has to! */ -class LazySpan implements Span { +class LazySpan implements LexicalModelTypes.Span { private _source: string; readonly start: number; readonly end: number; diff --git a/web/src/engine/predictive-text/wordbreakers/src/main/placeholder.ts b/web/src/engine/predictive-text/wordbreakers/src/main/placeholder.ts index 1d6f55d9674..f1e44528b98 100644 --- a/web/src/engine/predictive-text/wordbreakers/src/main/placeholder.ts +++ b/web/src/engine/predictive-text/wordbreakers/src/main/placeholder.ts @@ -1,4 +1,4 @@ -import { Span } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; /** * A **VERY** dumb word breaker that simply splits at words. Do not use this @@ -7,7 +7,7 @@ import { Span } from '@keymanapp/common-types'; * @param phrase The phrase in which to break words. * @deprecated Use a word breaker tailored to your language instead! */ -export default function placeholder(phrase: string): Span[] { +export default function placeholder(phrase: string): LexicalModelTypes.Span[] { let nextStart = 0; return phrase.split(/\s+/).map(utterance => { // XXX: The indices are NOT accurate to the original phrase! diff --git a/web/src/engine/predictive-text/wordbreakers/test/test-ascii-word-breaker.js b/web/src/engine/predictive-text/wordbreakers/tests/ascii-word-breaker.tests.js similarity index 100% rename from web/src/engine/predictive-text/wordbreakers/test/test-ascii-word-breaker.js rename to web/src/engine/predictive-text/wordbreakers/tests/ascii-word-breaker.tests.js diff --git a/web/src/engine/predictive-text/wordbreakers/test/test-default-word-breaker.js b/web/src/engine/predictive-text/wordbreakers/tests/default-word-breaker.tests.js similarity index 100% rename from web/src/engine/predictive-text/wordbreakers/test/test-default-word-breaker.js rename to web/src/engine/predictive-text/wordbreakers/tests/default-word-breaker.tests.js diff --git a/web/src/engine/predictive-text/wordbreakers/test/test-placeholder-word-breaker.js b/web/src/engine/predictive-text/wordbreakers/tests/placeholder-word-breaker.tests.js similarity index 100% rename from web/src/engine/predictive-text/wordbreakers/test/test-placeholder-word-breaker.js rename to web/src/engine/predictive-text/wordbreakers/tests/placeholder-word-breaker.tests.js diff --git a/web/src/engine/predictive-text/wordbreakers/test/test-search-property.js b/web/src/engine/predictive-text/wordbreakers/tests/search-property.tests.js similarity index 100% rename from web/src/engine/predictive-text/wordbreakers/test/test-search-property.js rename to web/src/engine/predictive-text/wordbreakers/tests/search-property.tests.js diff --git a/web/src/engine/predictive-text/worker-main/src/lmlayer.ts b/web/src/engine/predictive-text/worker-main/src/lmlayer.ts index 9153c0ed64b..226795af3d5 100644 --- a/web/src/engine/predictive-text/worker-main/src/lmlayer.ts +++ b/web/src/engine/predictive-text/worker-main/src/lmlayer.ts @@ -20,7 +20,15 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import { Capabilities, Configuration, Context, Distribution, Reversion, Suggestion, Transform, USVString } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; +import Capabilities = LexicalModelTypes.Capabilities; +import Configuration = LexicalModelTypes.Configuration; +import Context = LexicalModelTypes.Context; +import Distribution = LexicalModelTypes.Distribution; +import Reversion = LexicalModelTypes.Reversion; +import Suggestion = LexicalModelTypes.Suggestion; +import Transform = LexicalModelTypes.Transform; +import USVString = LexicalModelTypes.USVString; import PromiseStore from "./promise-store.js"; import { OutgoingMessage } from '@keymanapp/lm-message-types'; diff --git a/web/src/engine/predictive-text/worker-main/unit_tests/headless/promise-store.js b/web/src/engine/predictive-text/worker-main/unit_tests/headless/promise-store.tests.js similarity index 100% rename from web/src/engine/predictive-text/worker-main/unit_tests/headless/promise-store.js rename to web/src/engine/predictive-text/worker-main/unit_tests/headless/promise-store.tests.js diff --git a/web/src/engine/predictive-text/worker-main/unit_tests/headless/top-level-lmlayer.js b/web/src/engine/predictive-text/worker-main/unit_tests/headless/top-level-lmlayer.tests.js similarity index 100% rename from web/src/engine/predictive-text/worker-main/unit_tests/headless/top-level-lmlayer.js rename to web/src/engine/predictive-text/worker-main/unit_tests/headless/top-level-lmlayer.tests.js diff --git a/web/src/engine/predictive-text/worker-main/unit_tests/headless/worker-dummy-integration.js b/web/src/engine/predictive-text/worker-main/unit_tests/headless/worker-dummy-integration.tests.js similarity index 100% rename from web/src/engine/predictive-text/worker-main/unit_tests/headless/worker-dummy-integration.js rename to web/src/engine/predictive-text/worker-main/unit_tests/headless/worker-dummy-integration.tests.js diff --git a/web/src/engine/predictive-text/worker-main/unit_tests/headless/worker-trie-integration.js b/web/src/engine/predictive-text/worker-main/unit_tests/headless/worker-trie-integration.tests.js similarity index 100% rename from web/src/engine/predictive-text/worker-main/unit_tests/headless/worker-trie-integration.js rename to web/src/engine/predictive-text/worker-main/unit_tests/headless/worker-trie-integration.tests.js diff --git a/web/src/engine/predictive-text/worker-main/unit_tests/in_browser/cases/top-level-lmlayer.spec.ts b/web/src/engine/predictive-text/worker-main/unit_tests/in_browser/cases/top-level-lmlayer.tests.ts similarity index 100% rename from web/src/engine/predictive-text/worker-main/unit_tests/in_browser/cases/top-level-lmlayer.spec.ts rename to web/src/engine/predictive-text/worker-main/unit_tests/in_browser/cases/top-level-lmlayer.tests.ts diff --git a/web/src/engine/predictive-text/worker-main/unit_tests/in_browser/cases/worker-dummy-integration.spec.ts b/web/src/engine/predictive-text/worker-main/unit_tests/in_browser/cases/worker-dummy-integration.tests.ts similarity index 100% rename from web/src/engine/predictive-text/worker-main/unit_tests/in_browser/cases/worker-dummy-integration.spec.ts rename to web/src/engine/predictive-text/worker-main/unit_tests/in_browser/cases/worker-dummy-integration.tests.ts diff --git a/web/src/engine/predictive-text/worker-main/unit_tests/in_browser/cases/worker-trie-integration.spec.ts b/web/src/engine/predictive-text/worker-main/unit_tests/in_browser/cases/worker-trie-integration.tests.ts similarity index 100% rename from web/src/engine/predictive-text/worker-main/unit_tests/in_browser/cases/worker-trie-integration.spec.ts rename to web/src/engine/predictive-text/worker-main/unit_tests/in_browser/cases/worker-trie-integration.tests.ts diff --git a/web/src/engine/predictive-text/worker-main/unit_tests/in_browser/web-test-runner.config.mjs b/web/src/engine/predictive-text/worker-main/unit_tests/in_browser/web-test-runner.config.mjs index 6f9df64ddbf..e094aebe46d 100644 --- a/web/src/engine/predictive-text/worker-main/unit_tests/in_browser/web-test-runner.config.mjs +++ b/web/src/engine/predictive-text/worker-main/unit_tests/in_browser/web-test-runner.config.mjs @@ -19,7 +19,7 @@ export default { concurrency: 10, nodeResolve: true, files: [ - '**/*.spec.ts' + '**/*.tests.ts' ], middleware: [ // Rewrites short-hand paths for test resources, making them fully relative to the repo root. diff --git a/web/src/engine/predictive-text/worker-thread/.c8rc.json b/web/src/engine/predictive-text/worker-thread/.c8rc.json index 56bc01f350e..b66bb5b1061 100644 --- a/web/src/engine/predictive-text/worker-thread/.c8rc.json +++ b/web/src/engine/predictive-text/worker-thread/.c8rc.json @@ -2,7 +2,7 @@ "check-coverage": false, "clean": true, "exclude": [ - "src/test/**", + "src/tests/**", "node_modules/*" ], "exclude-after-remap": true, diff --git a/web/src/engine/predictive-text/worker-thread/build.sh b/web/src/engine/predictive-text/worker-thread/build.sh index 05c7326cd05..ddf332e90d2 100755 --- a/web/src/engine/predictive-text/worker-thread/build.sh +++ b/web/src/engine/predictive-text/worker-thread/build.sh @@ -107,9 +107,9 @@ function do_test() { WTR_DEBUG=" --manual" fi - c8 mocha --recursive $MOCHA_FLAGS ./src/test/mocha/cases/ + c8 mocha --recursive $MOCHA_FLAGS ./src/tests/mocha/cases/ - web-test-runner --config ./src/test/test-runner/web-test-runner${WTR_CONFIG}.config.mjs ${WTR_DEBUG} + web-test-runner --config ./src/tests/test-runner/web-test-runner${WTR_CONFIG}.config.mjs ${WTR_DEBUG} } builder_run_action configure do_configure diff --git a/web/src/engine/predictive-text/worker-thread/src/main/correction/context-tracker.ts b/web/src/engine/predictive-text/worker-thread/src/main/correction/context-tracker.ts index 69472bf02ba..fa2cc6bdb46 100644 --- a/web/src/engine/predictive-text/worker-thread/src/main/correction/context-tracker.ts +++ b/web/src/engine/predictive-text/worker-thread/src/main/correction/context-tracker.ts @@ -5,7 +5,13 @@ import { SearchSpace } from './distance-modeler.js'; import TransformUtils from '../transformUtils.js'; import { determineModelTokenizer } from '../model-helpers.js'; import { tokenizeTransform, tokenizeTransformDistribution } from './transform-tokenization.js'; -import { Context, Distribution, LexicalModel, Suggestion, Transform, USVString } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; +import Context = LexicalModelTypes.Context; +import Distribution = LexicalModelTypes.Distribution; +import LexicalModel = LexicalModelTypes.LexicalModel; +import Suggestion = LexicalModelTypes.Suggestion; +import Transform = LexicalModelTypes.Transform; +import USVString = LexicalModelTypes.USVString; function textToCharTransforms(text: string, transformId?: number) { let perCharTransforms: Transform[] = []; diff --git a/web/src/engine/predictive-text/worker-thread/src/main/correction/distance-modeler.ts b/web/src/engine/predictive-text/worker-thread/src/main/correction/distance-modeler.ts index c102af9eef1..c21533d90be 100644 --- a/web/src/engine/predictive-text/worker-thread/src/main/correction/distance-modeler.ts +++ b/web/src/engine/predictive-text/worker-thread/src/main/correction/distance-modeler.ts @@ -3,7 +3,13 @@ import { QueueComparator as Comparator, PriorityQueue } from '@keymanapp/web-uti import { ClassicalDistanceCalculation, EditToken } from './classical-calculation.js'; import { ExecutionTimer, STANDARD_TIME_BETWEEN_DEFERS } from './execution-timer.js'; -import { Distribution, LexicalModel, LexiconTraversal, ProbabilityMass, Transform, USVString } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; +import Distribution = LexicalModelTypes.Distribution; +import LexicalModel = LexicalModelTypes.LexicalModel; +import LexiconTraversal = LexicalModelTypes.LexiconTraversal; +import ProbabilityMass = LexicalModelTypes.ProbabilityMass; +import Transform = LexicalModelTypes.Transform; +import USVString = LexicalModelTypes.USVString; type RealizedInput = ProbabilityMass[]; // NOT Distribution - they're masses from separate distributions. diff --git a/web/src/engine/predictive-text/worker-thread/src/main/correction/transform-tokenization.ts b/web/src/engine/predictive-text/worker-thread/src/main/correction/transform-tokenization.ts index a5d3c1bf0ea..291245014c7 100644 --- a/web/src/engine/predictive-text/worker-thread/src/main/correction/transform-tokenization.ts +++ b/web/src/engine/predictive-text/worker-thread/src/main/correction/transform-tokenization.ts @@ -1,4 +1,7 @@ -import { Context, Distribution, Transform } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; +import Context = LexicalModelTypes.Context; +import Distribution = LexicalModelTypes.Distribution; +import Transform = LexicalModelTypes.Transform; import { applyTransform, type Tokenization } from "@keymanapp/models-templates"; /** diff --git a/web/src/engine/predictive-text/worker-thread/src/main/index.ts b/web/src/engine/predictive-text/worker-thread/src/main/index.ts index 3abc9ddcd09..d0676992e07 100644 --- a/web/src/engine/predictive-text/worker-thread/src/main/index.ts +++ b/web/src/engine/predictive-text/worker-thread/src/main/index.ts @@ -40,7 +40,9 @@ import * as wordBreakers from '@keymanapp/models-wordbreakers'; import ModelCompositor from './model-compositor.js'; import { ImportScripts, IncomingMessage, LMLayerWorkerState, LoadMessage, ModelEval, ModelFile, ModelSourceSpec, PostMessage } from './worker-interfaces.js'; -import { Capabilities, LexicalModel } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; +import Capabilities = LexicalModelTypes.Capabilities; +import LexicalModel = LexicalModelTypes.LexicalModel; import { OutgoingMessageKind } from '@keymanapp/lm-message-types'; /** diff --git a/web/src/engine/predictive-text/worker-thread/src/main/model-compositor.ts b/web/src/engine/predictive-text/worker-thread/src/main/model-compositor.ts index 2a8f67a5478..f8d94eef22a 100644 --- a/web/src/engine/predictive-text/worker-thread/src/main/model-compositor.ts +++ b/web/src/engine/predictive-text/worker-thread/src/main/model-compositor.ts @@ -4,7 +4,16 @@ import * as correction from './correction/index.js' import TransformUtils from './transformUtils.js'; import { correctAndEnumerate, dedupeSuggestions, finalizeSuggestions, predictionAutoSelect, processSimilarity, toAnnotatedSuggestion, tupleDisplayOrderSort } from './predict-helpers.js'; import { detectCurrentCasing, determineModelTokenizer, determineModelWordbreaker, determinePunctuationFromModel } from './model-helpers.js'; -import { CasingForm, Context, Distribution, LexicalModel, LexicalModelPunctuation, Reversion, Suggestion, Transform, USVString } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; +import CasingForm = LexicalModelTypes.CasingForm; +import Context = LexicalModelTypes.Context; +import Distribution = LexicalModelTypes.Distribution; +import LexicalModel = LexicalModelTypes.LexicalModel; +import LexicalModelPunctuation = LexicalModelTypes.LexicalModelPunctuation; +import Reversion = LexicalModelTypes.Reversion; +import Suggestion = LexicalModelTypes.Suggestion; +import Transform = LexicalModelTypes.Transform; +import USVString = LexicalModelTypes.USVString; export class ModelCompositor { private lexicalModel: LexicalModel; diff --git a/web/src/engine/predictive-text/worker-thread/src/main/model-helpers.ts b/web/src/engine/predictive-text/worker-thread/src/main/model-helpers.ts index 0f0fa02de62..d5f9b4397fe 100644 --- a/web/src/engine/predictive-text/worker-thread/src/main/model-helpers.ts +++ b/web/src/engine/predictive-text/worker-thread/src/main/model-helpers.ts @@ -1,4 +1,8 @@ -import { CasingForm, Context, LexicalModel, LexicalModelPunctuation } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; +import CasingForm = LexicalModelTypes.CasingForm; +import Context = LexicalModelTypes.Context; +import LexicalModel = LexicalModelTypes.LexicalModel; +import LexicalModelPunctuation = LexicalModelTypes.LexicalModelPunctuation; import * as models from '@keymanapp/models-templates'; import * as wordBreakers from '@keymanapp/models-wordbreakers'; diff --git a/web/src/engine/predictive-text/worker-thread/src/main/models/dummy-model.ts b/web/src/engine/predictive-text/worker-thread/src/main/models/dummy-model.ts index 254b881883c..40678312d30 100644 --- a/web/src/engine/predictive-text/worker-thread/src/main/models/dummy-model.ts +++ b/web/src/engine/predictive-text/worker-thread/src/main/models/dummy-model.ts @@ -1,6 +1,17 @@ /// -import { Capabilities, CasingForm, Configuration, Context, Distribution, LexicalModel, LexicalModelPunctuation, Outcome, Suggestion, Transform, WordBreakingFunction } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; +import Capabilities = LexicalModelTypes.Capabilities; +import CasingForm = LexicalModelTypes.CasingForm; +import Configuration = LexicalModelTypes.Configuration; +import Context = LexicalModelTypes.Context; +import Distribution = LexicalModelTypes.Distribution; +import LexicalModel = LexicalModelTypes.LexicalModel; +import LexicalModelPunctuation = LexicalModelTypes.LexicalModelPunctuation; +import Outcome = LexicalModelTypes.Outcome; +import Suggestion = LexicalModelTypes.Suggestion; +import Transform = LexicalModelTypes.Transform; +import WordBreakingFunction = LexicalModelTypes.WordBreakingFunction; /* * Copyright (c) 2018 National Research Council Canada (author: Eddie A. Santos) diff --git a/web/src/engine/predictive-text/worker-thread/src/main/predict-helpers.ts b/web/src/engine/predictive-text/worker-thread/src/main/predict-helpers.ts index bd7d19cd89e..a0b687b9bf2 100644 --- a/web/src/engine/predictive-text/worker-thread/src/main/predict-helpers.ts +++ b/web/src/engine/predictive-text/worker-thread/src/main/predict-helpers.ts @@ -5,7 +5,17 @@ import { determineModelTokenizer, determineModelWordbreaker, determinePunctuatio import { ContextTracker, TrackedContextState } from './correction/context-tracker.js'; import { ExecutionTimer } from './correction/execution-timer.js'; import ModelCompositor from './model-compositor.js'; -import { ProbabilityMass, Suggestion, LexicalModel, Distribution, Outcome, Keep, SuggestionTag, Reversion, Transform, Context } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; +import Context = LexicalModelTypes.Context; +import Distribution = LexicalModelTypes.Distribution; +import Keep = LexicalModelTypes.Keep; +import LexicalModel = LexicalModelTypes.LexicalModel; +import Outcome = LexicalModelTypes.Outcome; +import ProbabilityMass = LexicalModelTypes.ProbabilityMass; +import Reversion = LexicalModelTypes.Reversion; +import Suggestion = LexicalModelTypes.Suggestion; +import SuggestionTag = LexicalModelTypes.SuggestionTag; +import Transform = LexicalModelTypes.Transform; /* * The functions in this file exist to provide unit-testable stateless components for the diff --git a/web/src/engine/predictive-text/worker-thread/src/main/transformUtils.ts b/web/src/engine/predictive-text/worker-thread/src/main/transformUtils.ts index 5cbc6f2d0d3..08188934c62 100644 --- a/web/src/engine/predictive-text/worker-thread/src/main/transformUtils.ts +++ b/web/src/engine/predictive-text/worker-thread/src/main/transformUtils.ts @@ -1,17 +1,17 @@ -import { Transform } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; export default class TransformUtils { - static isWhitespace(transform: Transform): boolean { + static isWhitespace(transform: LexicalModelTypes.Transform): boolean { // Matches a string that is entirely one or more characters with Unicode general property Z* or the following: CR, LF, and Tab. const whitespaceRemover = /^[\u0009\u000A\u000D\u0020\u00a0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u202f\u205f\u3000]+$/i; return transform.insert.match(whitespaceRemover) != null; } - static isBackspace(transform: Transform): boolean { + static isBackspace(transform: LexicalModelTypes.Transform): boolean { return transform.insert == "" && transform.deleteLeft > 0 && !transform.deleteRight; } - static isEmpty(transform: Transform): boolean { + static isEmpty(transform: LexicalModelTypes.Transform): boolean { return transform.insert == '' && transform.deleteLeft == 0 && !transform.deleteRight; } } \ No newline at end of file diff --git a/web/src/engine/predictive-text/worker-thread/src/main/worker-interfaces.ts b/web/src/engine/predictive-text/worker-thread/src/main/worker-interfaces.ts index c57c1c09468..f627345cb93 100644 --- a/web/src/engine/predictive-text/worker-thread/src/main/worker-interfaces.ts +++ b/web/src/engine/predictive-text/worker-thread/src/main/worker-interfaces.ts @@ -28,7 +28,14 @@ /// -import { Capabilities, Context, Distribution, LexicalModel, Reversion, Suggestion, Transform } from '@keymanapp/common-types'; +import { LexicalModelTypes } from '@keymanapp/common-types'; +import Capabilities = LexicalModelTypes.Capabilities; +import Context = LexicalModelTypes.Context; +import Distribution = LexicalModelTypes.Distribution; +import LexicalModel = LexicalModelTypes.LexicalModel; +import Reversion = LexicalModelTypes.Reversion; +import Suggestion = LexicalModelTypes.Suggestion; +import Transform = LexicalModelTypes.Transform; import type ModelCompositor from './model-compositor.js'; import { Token } from '@keymanapp/models-templates'; diff --git a/web/src/engine/predictive-text/worker-thread/src/test/mocha/cases/auto-correct.js b/web/src/engine/predictive-text/worker-thread/src/tests/mocha/cases/auto-correct.js similarity index 100% rename from web/src/engine/predictive-text/worker-thread/src/test/mocha/cases/auto-correct.js rename to web/src/engine/predictive-text/worker-thread/src/tests/mocha/cases/auto-correct.js diff --git a/web/src/engine/predictive-text/worker-thread/src/test/mocha/cases/casing-detection.js b/web/src/engine/predictive-text/worker-thread/src/tests/mocha/cases/casing-detection.js similarity index 100% rename from web/src/engine/predictive-text/worker-thread/src/test/mocha/cases/casing-detection.js rename to web/src/engine/predictive-text/worker-thread/src/tests/mocha/cases/casing-detection.js diff --git a/web/src/engine/predictive-text/worker-thread/src/test/mocha/cases/early-correction-search-stopping.js b/web/src/engine/predictive-text/worker-thread/src/tests/mocha/cases/early-correction-search-stopping.js similarity index 100% rename from web/src/engine/predictive-text/worker-thread/src/test/mocha/cases/early-correction-search-stopping.js rename to web/src/engine/predictive-text/worker-thread/src/tests/mocha/cases/early-correction-search-stopping.js diff --git a/web/src/engine/predictive-text/worker-thread/src/test/mocha/cases/edit-distance/classical-calculation.js b/web/src/engine/predictive-text/worker-thread/src/tests/mocha/cases/edit-distance/classical-calculation.js similarity index 100% rename from web/src/engine/predictive-text/worker-thread/src/test/mocha/cases/edit-distance/classical-calculation.js rename to web/src/engine/predictive-text/worker-thread/src/tests/mocha/cases/edit-distance/classical-calculation.js diff --git a/web/src/engine/predictive-text/worker-thread/src/test/mocha/cases/edit-distance/context-tracker.js b/web/src/engine/predictive-text/worker-thread/src/tests/mocha/cases/edit-distance/context-tracker.js similarity index 100% rename from web/src/engine/predictive-text/worker-thread/src/test/mocha/cases/edit-distance/context-tracker.js rename to web/src/engine/predictive-text/worker-thread/src/tests/mocha/cases/edit-distance/context-tracker.js diff --git a/web/src/engine/predictive-text/worker-thread/src/test/mocha/cases/edit-distance/distance-modeler.js b/web/src/engine/predictive-text/worker-thread/src/tests/mocha/cases/edit-distance/distance-modeler.js similarity index 100% rename from web/src/engine/predictive-text/worker-thread/src/test/mocha/cases/edit-distance/distance-modeler.js rename to web/src/engine/predictive-text/worker-thread/src/tests/mocha/cases/edit-distance/distance-modeler.js diff --git a/web/src/engine/predictive-text/worker-thread/src/test/mocha/cases/edit-distance/execution-timer.js b/web/src/engine/predictive-text/worker-thread/src/tests/mocha/cases/edit-distance/execution-timer.js similarity index 100% rename from web/src/engine/predictive-text/worker-thread/src/test/mocha/cases/edit-distance/execution-timer.js rename to web/src/engine/predictive-text/worker-thread/src/tests/mocha/cases/edit-distance/execution-timer.js diff --git a/web/src/engine/predictive-text/worker-thread/src/test/mocha/cases/predict-from-corrections.js b/web/src/engine/predictive-text/worker-thread/src/tests/mocha/cases/predict-from-corrections.js similarity index 100% rename from web/src/engine/predictive-text/worker-thread/src/test/mocha/cases/predict-from-corrections.js rename to web/src/engine/predictive-text/worker-thread/src/tests/mocha/cases/predict-from-corrections.js diff --git a/web/src/engine/predictive-text/worker-thread/src/test/mocha/cases/suggestion-deduplication.js b/web/src/engine/predictive-text/worker-thread/src/tests/mocha/cases/suggestion-deduplication.js similarity index 100% rename from web/src/engine/predictive-text/worker-thread/src/test/mocha/cases/suggestion-deduplication.js rename to web/src/engine/predictive-text/worker-thread/src/tests/mocha/cases/suggestion-deduplication.js diff --git a/web/src/engine/predictive-text/worker-thread/src/test/mocha/cases/suggestion-finalization.js b/web/src/engine/predictive-text/worker-thread/src/tests/mocha/cases/suggestion-finalization.js similarity index 100% rename from web/src/engine/predictive-text/worker-thread/src/test/mocha/cases/suggestion-finalization.js rename to web/src/engine/predictive-text/worker-thread/src/tests/mocha/cases/suggestion-finalization.js diff --git a/web/src/engine/predictive-text/worker-thread/src/test/mocha/cases/suggestion-similarity.js b/web/src/engine/predictive-text/worker-thread/src/tests/mocha/cases/suggestion-similarity.js similarity index 100% rename from web/src/engine/predictive-text/worker-thread/src/test/mocha/cases/suggestion-similarity.js rename to web/src/engine/predictive-text/worker-thread/src/tests/mocha/cases/suggestion-similarity.js diff --git a/web/src/engine/predictive-text/worker-thread/src/test/mocha/cases/transform-tokenization.js b/web/src/engine/predictive-text/worker-thread/src/tests/mocha/cases/transform-tokenization.js similarity index 100% rename from web/src/engine/predictive-text/worker-thread/src/test/mocha/cases/transform-tokenization.js rename to web/src/engine/predictive-text/worker-thread/src/tests/mocha/cases/transform-tokenization.js diff --git a/web/src/engine/predictive-text/worker-thread/src/test/mocha/cases/transform-utils.js b/web/src/engine/predictive-text/worker-thread/src/tests/mocha/cases/transform-utils.js similarity index 100% rename from web/src/engine/predictive-text/worker-thread/src/test/mocha/cases/transform-utils.js rename to web/src/engine/predictive-text/worker-thread/src/tests/mocha/cases/transform-utils.js diff --git a/web/src/engine/predictive-text/worker-thread/src/test/mocha/cases/worker-custom-punctuation.js b/web/src/engine/predictive-text/worker-thread/src/tests/mocha/cases/worker-custom-punctuation.js similarity index 100% rename from web/src/engine/predictive-text/worker-thread/src/test/mocha/cases/worker-custom-punctuation.js rename to web/src/engine/predictive-text/worker-thread/src/tests/mocha/cases/worker-custom-punctuation.js diff --git a/web/src/engine/predictive-text/worker-thread/src/test/mocha/cases/worker-initialization.js b/web/src/engine/predictive-text/worker-thread/src/tests/mocha/cases/worker-initialization.js similarity index 100% rename from web/src/engine/predictive-text/worker-thread/src/test/mocha/cases/worker-initialization.js rename to web/src/engine/predictive-text/worker-thread/src/tests/mocha/cases/worker-initialization.js diff --git a/web/src/engine/predictive-text/worker-thread/src/test/mocha/cases/worker-model-compositor.js b/web/src/engine/predictive-text/worker-thread/src/tests/mocha/cases/worker-model-compositor.js similarity index 100% rename from web/src/engine/predictive-text/worker-thread/src/test/mocha/cases/worker-model-compositor.js rename to web/src/engine/predictive-text/worker-thread/src/tests/mocha/cases/worker-model-compositor.js diff --git a/web/src/engine/predictive-text/worker-thread/src/test/mocha/cases/worker-predict-dummy.js b/web/src/engine/predictive-text/worker-thread/src/tests/mocha/cases/worker-predict-dummy.js similarity index 100% rename from web/src/engine/predictive-text/worker-thread/src/test/mocha/cases/worker-predict-dummy.js rename to web/src/engine/predictive-text/worker-thread/src/tests/mocha/cases/worker-predict-dummy.js diff --git a/web/src/engine/predictive-text/worker-thread/src/test/mocha/cases/worker-predict.js b/web/src/engine/predictive-text/worker-thread/src/tests/mocha/cases/worker-predict.js similarity index 100% rename from web/src/engine/predictive-text/worker-thread/src/test/mocha/cases/worker-predict.js rename to web/src/engine/predictive-text/worker-thread/src/tests/mocha/cases/worker-predict.js diff --git a/web/src/engine/predictive-text/worker-thread/src/test/test-runner/cases/worker.spec.ts b/web/src/engine/predictive-text/worker-thread/src/tests/test-runner/cases/worker.tests.ts similarity index 100% rename from web/src/engine/predictive-text/worker-thread/src/test/test-runner/cases/worker.spec.ts rename to web/src/engine/predictive-text/worker-thread/src/tests/test-runner/cases/worker.tests.ts diff --git a/web/src/engine/predictive-text/worker-thread/src/test/test-runner/web-test-runner.CI.config.mjs b/web/src/engine/predictive-text/worker-thread/src/tests/test-runner/web-test-runner.CI.config.mjs similarity index 100% rename from web/src/engine/predictive-text/worker-thread/src/test/test-runner/web-test-runner.CI.config.mjs rename to web/src/engine/predictive-text/worker-thread/src/tests/test-runner/web-test-runner.CI.config.mjs diff --git a/web/src/engine/predictive-text/worker-thread/src/test/test-runner/web-test-runner.config.mjs b/web/src/engine/predictive-text/worker-thread/src/tests/test-runner/web-test-runner.config.mjs similarity index 99% rename from web/src/engine/predictive-text/worker-thread/src/test/test-runner/web-test-runner.config.mjs rename to web/src/engine/predictive-text/worker-thread/src/tests/test-runner/web-test-runner.config.mjs index 920efab464d..64ed2763db5 100644 --- a/web/src/engine/predictive-text/worker-thread/src/test/test-runner/web-test-runner.config.mjs +++ b/web/src/engine/predictive-text/worker-thread/src/tests/test-runner/web-test-runner.config.mjs @@ -27,7 +27,7 @@ export default { concurrency: 10, nodeResolve: true, files: [ - '**/*.spec.ts' + '**/*.tests.ts' ], middleware: [ // Rewrites short-hand paths for test resources, making them fully relative to the repo root. diff --git a/web/src/test/auto/dom/cases/attachment/outputTargetForElement.spec.html b/web/src/test/auto/dom/cases/attachment/outputTargetForElement.tests.html similarity index 100% rename from web/src/test/auto/dom/cases/attachment/outputTargetForElement.spec.html rename to web/src/test/auto/dom/cases/attachment/outputTargetForElement.tests.html diff --git a/web/src/test/auto/dom/cases/attachment/pageContextAttachment.spec.ts b/web/src/test/auto/dom/cases/attachment/pageContextAttachment.tests.ts similarity index 100% rename from web/src/test/auto/dom/cases/attachment/pageContextAttachment.spec.ts rename to web/src/test/auto/dom/cases/attachment/pageContextAttachment.tests.ts diff --git a/web/src/test/auto/dom/cases/browser/contextManager.spec.ts b/web/src/test/auto/dom/cases/browser/contextManager.tests.ts similarity index 100% rename from web/src/test/auto/dom/cases/browser/contextManager.spec.ts rename to web/src/test/auto/dom/cases/browser/contextManager.tests.ts diff --git a/web/src/test/auto/dom/cases/core-processor/basic.spec.ts b/web/src/test/auto/dom/cases/core-processor/basic.tests.ts similarity index 100% rename from web/src/test/auto/dom/cases/core-processor/basic.spec.ts rename to web/src/test/auto/dom/cases/core-processor/basic.tests.ts diff --git a/web/src/test/auto/dom/cases/dom-utils/cookies.spec.ts b/web/src/test/auto/dom/cases/dom-utils/cookies.tests.ts similarity index 100% rename from web/src/test/auto/dom/cases/dom-utils/cookies.spec.ts rename to web/src/test/auto/dom/cases/dom-utils/cookies.tests.ts diff --git a/web/src/test/auto/dom/cases/element-wrappers/element_interfaces.spec.ts b/web/src/test/auto/dom/cases/element-wrappers/element_interfaces.tests.ts similarity index 100% rename from web/src/test/auto/dom/cases/element-wrappers/element_interfaces.spec.ts rename to web/src/test/auto/dom/cases/element-wrappers/element_interfaces.tests.ts diff --git a/web/src/test/auto/dom/cases/element-wrappers/target_mocks.spec.ts b/web/src/test/auto/dom/cases/element-wrappers/target_mocks.tests.ts similarity index 100% rename from web/src/test/auto/dom/cases/element-wrappers/target_mocks.spec.ts rename to web/src/test/auto/dom/cases/element-wrappers/target_mocks.tests.ts diff --git a/web/src/test/auto/dom/cases/gesture-processor/canary.spec.ts b/web/src/test/auto/dom/cases/gesture-processor/canary.tests.ts similarity index 100% rename from web/src/test/auto/dom/cases/gesture-processor/canary.spec.ts rename to web/src/test/auto/dom/cases/gesture-processor/canary.tests.ts diff --git a/web/src/test/auto/dom/cases/gesture-processor/host-page.spec.html b/web/src/test/auto/dom/cases/gesture-processor/host-page.tests.html similarity index 92% rename from web/src/test/auto/dom/cases/gesture-processor/host-page.spec.html rename to web/src/test/auto/dom/cases/gesture-processor/host-page.tests.html index ce3aae6c484..cc83c5e6ef7 100644 --- a/web/src/test/auto/dom/cases/gesture-processor/host-page.spec.html +++ b/web/src/test/auto/dom/cases/gesture-processor/host-page.tests.html @@ -18,9 +18,9 @@ import { runTests } from '@web/test-runner-mocha'; runTests(async() => { - await import('./canary.spec.ts'); - await import('./ignoredInputs.spec.ts'); - await import('./recordedCoordSequences.spec.ts'); + await import('./canary.tests.ts'); + await import('./ignoredInputs.tests.ts'); + await import('./recordedCoordSequences.tests.ts'); }); diff --git a/web/src/test/auto/dom/cases/gesture-processor/ignoredInputs.spec.ts b/web/src/test/auto/dom/cases/gesture-processor/ignoredInputs.tests.ts similarity index 100% rename from web/src/test/auto/dom/cases/gesture-processor/ignoredInputs.spec.ts rename to web/src/test/auto/dom/cases/gesture-processor/ignoredInputs.tests.ts diff --git a/web/src/test/auto/dom/cases/gesture-processor/recordedCoordSequences.spec.ts b/web/src/test/auto/dom/cases/gesture-processor/recordedCoordSequences.tests.ts similarity index 100% rename from web/src/test/auto/dom/cases/gesture-processor/recordedCoordSequences.spec.ts rename to web/src/test/auto/dom/cases/gesture-processor/recordedCoordSequences.tests.ts diff --git a/web/src/test/auto/dom/cases/keyboard-storage/cloudQueries.spec.ts b/web/src/test/auto/dom/cases/keyboard-storage/cloudQueries.tests.ts similarity index 100% rename from web/src/test/auto/dom/cases/keyboard-storage/cloudQueries.spec.ts rename to web/src/test/auto/dom/cases/keyboard-storage/cloudQueries.tests.ts diff --git a/web/src/test/auto/dom/cases/keyboard-storage/domCloudRequester.spec.ts b/web/src/test/auto/dom/cases/keyboard-storage/domCloudRequester.tests.ts similarity index 100% rename from web/src/test/auto/dom/cases/keyboard-storage/domCloudRequester.spec.ts rename to web/src/test/auto/dom/cases/keyboard-storage/domCloudRequester.tests.ts diff --git a/web/src/test/auto/dom/cases/keyboard-storage/keyboardRequisitioner.spec.ts b/web/src/test/auto/dom/cases/keyboard-storage/keyboardRequisitioner.tests.ts similarity index 100% rename from web/src/test/auto/dom/cases/keyboard-storage/keyboardRequisitioner.spec.ts rename to web/src/test/auto/dom/cases/keyboard-storage/keyboardRequisitioner.tests.ts diff --git a/web/src/test/auto/dom/cases/osk/activation.spec.ts b/web/src/test/auto/dom/cases/osk/activation.tests.ts similarity index 100% rename from web/src/test/auto/dom/cases/osk/activation.spec.ts rename to web/src/test/auto/dom/cases/osk/activation.tests.ts diff --git a/web/src/test/auto/dom/cases/osk/events.spec.ts b/web/src/test/auto/dom/cases/osk/events.tests.ts similarity index 100% rename from web/src/test/auto/dom/cases/osk/events.spec.ts rename to web/src/test/auto/dom/cases/osk/events.tests.ts diff --git a/web/src/test/auto/dom/test_init_check.spec.ts b/web/src/test/auto/dom/init_check.tests.ts similarity index 100% rename from web/src/test/auto/dom/test_init_check.spec.ts rename to web/src/test/auto/dom/init_check.tests.ts diff --git a/web/src/test/auto/dom/web-test-runner.config.mjs b/web/src/test/auto/dom/web-test-runner.config.mjs index 5aa1d7c49e7..ec3d64ac8fd 100644 --- a/web/src/test/auto/dom/web-test-runner.config.mjs +++ b/web/src/test/auto/dom/web-test-runner.config.mjs @@ -33,43 +33,43 @@ export default { nodeResolve: true, // Top-level, implicit 'default' group files: [ - 'web/src/test/auto/dom/test_init_check.spec.ts', - // '**/*.spec.html' + 'web/src/test/auto/dom/init_check.tests.ts', + // '**/*.tests.html' ], groups: [ { name: 'engine/attachment', // Relative, from the containing package.json files: [ - 'web/build/test/dom/cases/attachment/**/*.spec.html', - 'web/build/test/dom/cases/attachment/**/*.spec.mjs' + 'web/build/test/dom/cases/attachment/**/*.tests.html', + 'web/build/test/dom/cases/attachment/**/*.tests.mjs' ] }, { name: 'app/browser', // Relative, from the containing package.json - files: ['web/build/test/dom/cases/browser/**/*.spec.mjs'] + files: ['web/build/test/dom/cases/browser/**/*.tests.mjs'] }, { name: 'engine/core-processor', // Relative, from the containing package.json - files: ['web/src/test/auto/dom/cases/core-processor/*.spec.ts'] + files: ['web/src/test/auto/dom/cases/core-processor/*.tests.ts'] }, { name: 'engine/dom-utils', // Relative, from the containing package.json - files: ['web/build/test/dom/cases/dom-utils/**/*.spec.mjs'] + files: ['web/build/test/dom/cases/dom-utils/**/*.tests.mjs'] }, { name: 'engine/element-wrappers', // Relative, from the containing package.json - files: ['web/build/test/dom/cases/element-wrappers/**/*.spec.mjs'] + files: ['web/build/test/dom/cases/element-wrappers/**/*.tests.mjs'] }, { name: 'engine/gesture-processor', // Relative, from the containing package.json - // Note: here we use the .spec.html file in the src directory! - files: ['web/src/test/auto/dom/cases/gesture-processor/**/*.spec.html'] + // Note: here we use the .tests.html file in the src directory! + files: ['web/src/test/auto/dom/cases/gesture-processor/**/*.tests.html'] }, { name: 'engine/keyboard', @@ -79,12 +79,12 @@ export default { { name: 'engine/keyboard-storage', // Relative, from the containing package.json - files: ['web/build/test/dom/cases/keyboard-storage/**/*.spec.mjs'] + files: ['web/build/test/dom/cases/keyboard-storage/**/*.tests.mjs'] }, { name: 'engine/osk', // Relative, from the containing package.json - files: ['web/build/test/dom/cases/osk/**/*.spec.mjs'] + files: ['web/build/test/dom/cases/osk/**/*.tests.mjs'] } ], middleware: [ diff --git a/web/src/test/auto/headless/engine/events/emitterListenerSpy.js b/web/src/test/auto/headless/engine/events/emitterListenerSpy.tests.js similarity index 100% rename from web/src/test/auto/headless/engine/events/emitterListenerSpy.js rename to web/src/test/auto/headless/engine/events/emitterListenerSpy.tests.js diff --git a/web/src/test/auto/headless/engine/events/legacyEventEmitter.js b/web/src/test/auto/headless/engine/events/legacyEventEmitter.tests.js similarity index 100% rename from web/src/test/auto/headless/engine/events/legacyEventEmitter.js rename to web/src/test/auto/headless/engine/events/legacyEventEmitter.tests.js diff --git a/web/src/test/auto/headless/engine/interfaces/pathConfiguration.js b/web/src/test/auto/headless/engine/interfaces/pathConfiguration.tests.js similarity index 100% rename from web/src/test/auto/headless/engine/interfaces/pathConfiguration.js rename to web/src/test/auto/headless/engine/interfaces/pathConfiguration.tests.js diff --git a/web/src/test/auto/headless/engine/interfaces/prediction/predictionContext.spec.js b/web/src/test/auto/headless/engine/interfaces/prediction/predictionContext.tests.js similarity index 100% rename from web/src/test/auto/headless/engine/interfaces/prediction/predictionContext.spec.js rename to web/src/test/auto/headless/engine/interfaces/prediction/predictionContext.tests.js diff --git a/web/src/test/auto/headless/engine/js-processor/basic-engine.js b/web/src/test/auto/headless/engine/js-processor/basic-engine.tests.js similarity index 100% rename from web/src/test/auto/headless/engine/js-processor/basic-engine.js rename to web/src/test/auto/headless/engine/js-processor/basic-engine.tests.js diff --git a/web/src/test/auto/headless/engine/js-processor/basic-init.js b/web/src/test/auto/headless/engine/js-processor/basic-init.tests.js similarity index 100% rename from web/src/test/auto/headless/engine/js-processor/basic-init.js rename to web/src/test/auto/headless/engine/js-processor/basic-init.tests.js diff --git a/web/src/test/auto/headless/engine/js-processor/bundled-module.js b/web/src/test/auto/headless/engine/js-processor/bundled-module.tests.js similarity index 100% rename from web/src/test/auto/headless/engine/js-processor/bundled-module.js rename to web/src/test/auto/headless/engine/js-processor/bundled-module.tests.js diff --git a/web/src/test/auto/headless/engine/js-processor/chirality.js b/web/src/test/auto/headless/engine/js-processor/chirality.tests.js similarity index 100% rename from web/src/test/auto/headless/engine/js-processor/chirality.js rename to web/src/test/auto/headless/engine/js-processor/chirality.tests.js diff --git a/web/src/test/auto/headless/engine/js-processor/deadkeys.js b/web/src/test/auto/headless/engine/js-processor/deadkeys.tests.js similarity index 100% rename from web/src/test/auto/headless/engine/js-processor/deadkeys.js rename to web/src/test/auto/headless/engine/js-processor/deadkeys.tests.js diff --git a/web/src/test/auto/headless/engine/js-processor/engine/context.js b/web/src/test/auto/headless/engine/js-processor/engine/context.tests.js similarity index 100% rename from web/src/test/auto/headless/engine/js-processor/engine/context.js rename to web/src/test/auto/headless/engine/js-processor/engine/context.tests.js diff --git a/web/src/test/auto/headless/engine/js-processor/engine/notany_context.js b/web/src/test/auto/headless/engine/js-processor/engine/notany_context.tests.js similarity index 100% rename from web/src/test/auto/headless/engine/js-processor/engine/notany_context.js rename to web/src/test/auto/headless/engine/js-processor/engine/notany_context.tests.js diff --git a/web/src/test/auto/headless/engine/js-processor/engine/stores.js b/web/src/test/auto/headless/engine/js-processor/engine/stores.tests.js similarity index 100% rename from web/src/test/auto/headless/engine/js-processor/engine/stores.js rename to web/src/test/auto/headless/engine/js-processor/engine/stores.tests.js diff --git a/web/src/test/auto/headless/engine/js-processor/engine/unmatched_final_group.js b/web/src/test/auto/headless/engine/js-processor/engine/unmatched_final_group.tests.js similarity index 100% rename from web/src/test/auto/headless/engine/js-processor/engine/unmatched_final_group.js rename to web/src/test/auto/headless/engine/js-processor/engine/unmatched_final_group.tests.js diff --git a/web/src/test/auto/headless/engine/js-processor/mocks.js b/web/src/test/auto/headless/engine/js-processor/mocks.tests.js similarity index 100% rename from web/src/test/auto/headless/engine/js-processor/mocks.js rename to web/src/test/auto/headless/engine/js-processor/mocks.tests.js diff --git a/web/src/test/auto/headless/engine/js-processor/non-positional-rules.js b/web/src/test/auto/headless/engine/js-processor/non-positional-rules.tests.js similarity index 100% rename from web/src/test/auto/headless/engine/js-processor/non-positional-rules.js rename to web/src/test/auto/headless/engine/js-processor/non-positional-rules.tests.js diff --git a/web/src/test/auto/headless/engine/js-processor/specialized-backspace.js b/web/src/test/auto/headless/engine/js-processor/specialized-backspace.tests.js similarity index 100% rename from web/src/test/auto/headless/engine/js-processor/specialized-backspace.js rename to web/src/test/auto/headless/engine/js-processor/specialized-backspace.tests.js diff --git a/web/src/test/auto/headless/engine/js-processor/transcriptions.js b/web/src/test/auto/headless/engine/js-processor/transcriptions.tests.js similarity index 100% rename from web/src/test/auto/headless/engine/js-processor/transcriptions.js rename to web/src/test/auto/headless/engine/js-processor/transcriptions.tests.js diff --git a/web/src/test/auto/headless/engine/keyboard-storage/cloudQueries.js b/web/src/test/auto/headless/engine/keyboard-storage/cloudQueries.tests.js similarity index 100% rename from web/src/test/auto/headless/engine/keyboard-storage/cloudQueries.js rename to web/src/test/auto/headless/engine/keyboard-storage/cloudQueries.tests.js diff --git a/web/src/test/auto/headless/engine/keyboard-storage/keyboardRequisitioner.js b/web/src/test/auto/headless/engine/keyboard-storage/keyboardRequisitioner.tests.js similarity index 100% rename from web/src/test/auto/headless/engine/keyboard-storage/keyboardRequisitioner.js rename to web/src/test/auto/headless/engine/keyboard-storage/keyboardRequisitioner.tests.js diff --git a/web/src/test/auto/headless/engine/keyboard-storage/keyboardStub.js b/web/src/test/auto/headless/engine/keyboard-storage/keyboardStub.tests.js similarity index 100% rename from web/src/test/auto/headless/engine/keyboard-storage/keyboardStub.js rename to web/src/test/auto/headless/engine/keyboard-storage/keyboardStub.tests.js diff --git a/web/src/test/auto/headless/engine/keyboard-storage/nodeCloudRequester.js b/web/src/test/auto/headless/engine/keyboard-storage/nodeCloudRequester.tests.js similarity index 100% rename from web/src/test/auto/headless/engine/keyboard-storage/nodeCloudRequester.js rename to web/src/test/auto/headless/engine/keyboard-storage/nodeCloudRequester.tests.js diff --git a/web/src/test/auto/headless/engine/keyboard-storage/stubAndKeyboardCache.js b/web/src/test/auto/headless/engine/keyboard-storage/stubAndKeyboardCache.tests.js similarity index 100% rename from web/src/test/auto/headless/engine/keyboard-storage/stubAndKeyboardCache.js rename to web/src/test/auto/headless/engine/keyboard-storage/stubAndKeyboardCache.tests.js diff --git a/web/src/test/auto/headless/engine/keyboard/keyboard-loading.tests.js b/web/src/test/auto/headless/engine/keyboard/keyboard-loading.tests.js new file mode 100644 index 00000000000..0dd89a36148 --- /dev/null +++ b/web/src/test/auto/headless/engine/keyboard/keyboard-loading.tests.js @@ -0,0 +1,94 @@ +import { assert } from 'chai'; + +import { createRequire } from 'module'; +const require = createRequire(import.meta.url); + +import { KeyboardHarness, MinimalKeymanGlobal } from 'keyman/engine/keyboard'; +import { KeyboardInterface, Mock } from 'keyman/engine/js-processor'; +import { NodeKeyboardLoader } from 'keyman/engine/keyboard/node-keyboard-loader'; + +describe('Headless keyboard loading', function() { + const laoPath = require.resolve('@keymanapp/common-test-resources/keyboards/lao_2008_basic.js'); + const khmerPath = require.resolve('@keymanapp/common-test-resources/keyboards/khmer_angkor.js'); + const nonKeyboardPath = require.resolve('@keymanapp/common-test-resources/index.mjs'); + const ipaPath = require.resolve('@keymanapp/common-test-resources/keyboards/sil_ipa.js'); + // Common test suite setup. + + let device = { + formFactor: 'desktop', + OS: 'windows', + browser: 'native' + } + + describe('Minimal harness loading', () => { + it('successfully loads', async function() { + // -- START: Standard Recorder-based unit test loading boilerplate -- + let harness = new KeyboardHarness({}, MinimalKeymanGlobal); + let keyboardLoader = new NodeKeyboardLoader(harness); + let keyboard = await keyboardLoader.loadKeyboardFromPath(laoPath); + // -- END: Standard Recorder-based unit test loading boilerplate -- + + // Asserts that the harness's loading field is cleared once the load is complete. + assert.isNotOk(harness.loadedKeyboard); + + // Asserts that the `activeKeyboard` field was not set by the operation. + assert.isNotOk(harness.activeKeyboard); + + // This part provides assurance that the keyboard properly loaded. + assert.equal(keyboard.id, "Keyboard_lao_2008_basic"); + }); + + it('successfully loads (has variable stores)', async () => { + // -- START: Standard Recorder-based unit test loading boilerplate -- + let harness = new KeyboardHarness({}, MinimalKeymanGlobal); + let keyboardLoader = new NodeKeyboardLoader(harness); + let keyboard = await keyboardLoader.loadKeyboardFromPath(ipaPath); + // -- END: Standard Recorder-based unit test loading boilerplate -- + + // This part provides extra assurance that the keyboard properly loaded. + assert.equal(keyboard.id, "Keyboard_sil_ipa"); + }); + + it('cannot evaluate rules', async function() { + // -- START: Standard Recorder-based unit test loading boilerplate -- + let harness = new KeyboardHarness({}, MinimalKeymanGlobal); + let keyboardLoader = new NodeKeyboardLoader(harness); + let keyboard = await keyboardLoader.loadKeyboardFromPath(laoPath); + // -- END: Standard Recorder-based unit test loading boilerplate -- + + // Runs a blank KeyEvent through the keyboard's rule processing... + // but via separate harness configured with a different captured global. + let ruleHarness = new KeyboardInterface({}, MinimalKeymanGlobal); + ruleHarness.activeKeyboard = keyboard; + try { + ruleHarness.processKeystroke(new Mock(), keyboard.constructNullKeyEvent(device)); + assert.fail(); + } catch (err) { + // Drives home an important detail: the 'global' object is effectively + // closure-captured. (Similar constraints may occur when experimenting with + // 'sandboxed' keyboard loading in the DOM!) + assert.equal(err.message, 'k.KKM is not a function'); + } + }); + + it('accurately determines supported gesture types', async () => { + // -- START: Standard Recorder-based unit test loading boilerplate -- + let harness = new KeyboardHarness({}, MinimalKeymanGlobal); + let keyboardLoader = new NodeKeyboardLoader(harness); + let km_keyboard = await keyboardLoader.loadKeyboardFromPath(khmerPath); + // -- END: Standard Recorder-based unit test loading boilerplate -- + + // `khmer_angkor` - supports longpresses, but not flicks or multitaps. + + const desktopLayout = km_keyboard.layout('desktop'); + assert.isFalse(desktopLayout.hasFlicks); + assert.isFalse(desktopLayout.hasLongpresses); + assert.isFalse(desktopLayout.hasMultitaps); + + const mobileLayout = km_keyboard.layout('phone'); + assert.isFalse(mobileLayout.hasFlicks); + assert.isTrue(mobileLayout.hasLongpresses); + assert.isFalse(mobileLayout.hasMultitaps); + }); + }); +}); diff --git a/web/src/test/auto/headless/engine/keyboard/keyboard-properties.js b/web/src/test/auto/headless/engine/keyboard/keyboard-properties.tests.js similarity index 100% rename from web/src/test/auto/headless/engine/keyboard/keyboard-properties.js rename to web/src/test/auto/headless/engine/keyboard/keyboard-properties.tests.js diff --git a/web/src/test/auto/headless/engine/main/headless/inputProcessor.spec.js b/web/src/test/auto/headless/engine/main/headless/inputProcessor.tests.js similarity index 100% rename from web/src/test/auto/headless/engine/main/headless/inputProcessor.spec.js rename to web/src/test/auto/headless/engine/main/headless/inputProcessor.tests.js diff --git a/web/src/test/auto/headless/engine/main/headless/languageProcessor.spec.js b/web/src/test/auto/headless/engine/main/headless/languageProcessor.tests.js similarity index 100% rename from web/src/test/auto/headless/engine/main/headless/languageProcessor.spec.js rename to web/src/test/auto/headless/engine/main/headless/languageProcessor.tests.js diff --git a/web/src/test/auto/integrated/cases/basics.spec.ts b/web/src/test/auto/integrated/cases/basics.tests.ts similarity index 100% rename from web/src/test/auto/integrated/cases/basics.spec.ts rename to web/src/test/auto/integrated/cases/basics.tests.ts diff --git a/web/src/test/auto/integrated/cases/engine.spec.ts b/web/src/test/auto/integrated/cases/engine.tests.ts similarity index 100% rename from web/src/test/auto/integrated/cases/engine.spec.ts rename to web/src/test/auto/integrated/cases/engine.tests.ts diff --git a/web/src/test/auto/integrated/cases/engine_chirality.spec.ts b/web/src/test/auto/integrated/cases/engine_chirality.tests.ts similarity index 100% rename from web/src/test/auto/integrated/cases/engine_chirality.spec.ts rename to web/src/test/auto/integrated/cases/engine_chirality.tests.ts diff --git a/web/src/test/auto/integrated/cases/events.spec.ts b/web/src/test/auto/integrated/cases/events.tests.ts similarity index 100% rename from web/src/test/auto/integrated/cases/events.spec.ts rename to web/src/test/auto/integrated/cases/events.tests.ts diff --git a/web/src/test/auto/integrated/cases/text_selection.spec.ts b/web/src/test/auto/integrated/cases/text_selection.tests.ts similarity index 100% rename from web/src/test/auto/integrated/cases/text_selection.spec.ts rename to web/src/test/auto/integrated/cases/text_selection.tests.ts diff --git a/web/src/test/auto/integrated/test_init_check.spec.ts b/web/src/test/auto/integrated/init_check.tests.ts similarity index 100% rename from web/src/test/auto/integrated/test_init_check.spec.ts rename to web/src/test/auto/integrated/init_check.tests.ts diff --git a/web/src/test/auto/integrated/web-test-runner.config.mjs b/web/src/test/auto/integrated/web-test-runner.config.mjs index 97985bf8e2b..5aa4c749220 100644 --- a/web/src/test/auto/integrated/web-test-runner.config.mjs +++ b/web/src/test/auto/integrated/web-test-runner.config.mjs @@ -17,15 +17,15 @@ export default { new LauncherWrapper(playwrightLauncher({ product: 'firefox' })), // Setting it higher makes things faster... but Webkit experiences stability // issues for some of the tests if this is set higher than 1. Notably, - // engine.spec.mjs, events.spec.mjs, and text_selection.spec.mjs. All the + // engine.tests.mjs, events.tests.mjs, and text_selection.tests.mjs. All the // text-simulation ones. new LauncherWrapper(playwrightLauncher({ product: 'webkit', concurrency: 1})) ], concurrency: 10, nodeResolve: true, files: [ - 'web/build/test/integrated//**/*.spec.mjs', - // '**/*.spec.html' + 'web/build/test/integrated//**/*.tests.mjs', + // '**/*.tests.html' ], middleware: [ // Rewrites short-hand paths for test resources, making them fully relative to the repo root. diff --git a/windows/src/engine/keyman/viskbd/UfrmVisualKeyboard.pas b/windows/src/engine/keyman/viskbd/UfrmVisualKeyboard.pas index 53b2990b907..c1d1dedaa0a 100644 --- a/windows/src/engine/keyman/viskbd/UfrmVisualKeyboard.pas +++ b/windows/src/engine/keyman/viskbd/UfrmVisualKeyboard.pas @@ -1,4 +1,4 @@ -(* +(* Name: UfrmVisualKeyboard Copyright: Copyright (C) SIL International. Documentation: @@ -638,10 +638,10 @@ function TfrmVisualKeyboard.FormHelp(Command: Word; Data: NativeInt; var CallHel if Command in [HELP_CONTEXT, HELP_CONTEXTPOPUP, HELP_INDEX, HELP_CONTENTS] then begin case ActivePage of - apKeyboard: TKeymanDesktopShell.OpenHelp('context_onscreenkeyboard'); - apCharacterMap: TKeymanDesktopShell.OpenHelp('context_charactermap'); - apFontHelper: TKeymanDesktopShell.OpenHelp('context_fonthelper'); - apEntryHelper: TKeymanDesktopShell.OpenHelp('context_entryhelper'); + apKeyboard: TKeymanDesktopShell.OpenHelp('context/toolbox-onscreenkeyboard'); + apCharacterMap: TKeymanDesktopShell.OpenHelp('context/toolbox-charactermap'); + apFontHelper: TKeymanDesktopShell.OpenHelp('context/toolbox-fonthelper'); + apEntryHelper: TKeymanDesktopShell.OpenHelp('index'); end; end; end; @@ -1546,7 +1546,12 @@ procedure TfrmVisualKeyboard.BtnShowHint(Sender: TObject); procedure TfrmVisualKeyboard.BtnHelpClick(Sender: TObject); begin - TKeymanDesktopShell.OpenHelpJump('context_onscreenkeyboard', frmKeyman7Main.ActiveKeyboard); + case ActivePage of + apKeyboard: TKeymanDesktopShell.OpenHelpJump('context/toolbox-onscreenkeyboard', frmKeyman7Main.ActiveKeyboard); + apCharacterMap: TKeymanDesktopShell.OpenHelpJump('context/toolbox-charactermap', frmKeyman7Main.ActiveKeyboard); + apFontHelper: TKeymanDesktopShell.OpenHelpJump('context/toolbox-fonthelper', frmKeyman7Main.ActiveKeyboard); + apEntryHelper: TKeymanDesktopShell.OpenHelpJump('index', frmKeyman7Main.ActiveKeyboard); + end; end; procedure TfrmVisualKeyboard.BtnHideHint(Sender: TObject);